去年秋天我接手了一个客户运营后台的改造,需求听起来极其朴素:把用户咨询自动识别后转成工单。团队里所有人最初的判断都是“接一个大模型接口就能搞定”。真正做完第一版,我才意识到自己把AI焊死在了流程里:模型只负责给文本打个标签,后面等着它的是一摞if-else,细分到连我都记不全。用户换个说法、字段漏一个、流程顺序微调,整条链路就崩。因为真正做决策的依然是那堆代码,模型只是个听话的输入输出工具,AI的能力完全没有释放出来。
后来我换了个思路,不再把AI当功能来加,而是把agent作为整个应用的运行内核。模型自己看状态、自己选工具、自己决定下一步,人在旁边定目标、定权限、盯异常。这个改法,就是我理解的agent-native。不整那些花哨的概念,从工程落地角度讲,agent-native是在架构层面围绕agent来设计系统:模型是决策核心,工具是它的手,记忆是上下文基础,权限和审计是安全边界。这篇文章复盘了我从踩坑到重构的全过程,包括选型取舍、最小可运行骨架的实现,以及几个非常容易翻车的细节,希望对正在评估agent架构、准备把自己的AI应用往这个方向整的同学能有帮助。
1. 先搞清楚agent-native到底在解决什么问题
1.1 一个让我下决心重写的项目现场
那个后台的原始逻辑长这样:用户提交一条咨询文本,模型先做分类,判断是退款、技术报障还是业务咨询;接着进入不同的规则分支,去调订单接口、报障接口或知识库检索;每个分支都有人工节点,要么等主管审批,要么等客服补充信息。
第一版上线后,线上反馈全是零星问题。某条分类阈值调低了,退款识别就变准了,但误把投诉当成退款推了出去;某次产品AB测试改了文案,模型分类没变,下游那层规则却开始大量误转。更尴尬的是,有个用户投诉带着图片和一段长语音转写,分类模型识别成“业务咨询”,但规则分支里根本没有针对图片附件的处理节点,工单直接卡死在一半。
这不是模型能力不行,而是架构模型的问题。我把模型当成一个静态功能节点,整个系统的行为完全由代码控制流决定。模型看到的输入是被裁剪过的,它能做的动作是被锁死的,它根本没有任何自主调整的空间。想解决这类问题,要么继续加规则补丁,把逻辑越堆越复杂;要么换一种系统组织方式,让模型自己驱动流程。我选了后者,不只是为了这一个后台,也是因为我相信这个方向能覆盖更多类似的业务系统。
1.2 agent-native与传统“AI+功能”的边界在哪里
要讲清楚agent-native,先得对比一下它和传统AI应用到底哪里不一样。很多团队做了几年的“AI应用”,本质上还是传统软件加了一层模型接口。模型在这个架构里就是一个组件,输入输出是固定的,流程由代码编排,模型只负责其中某一个环节。这种模式我称之为“AI增强”,它有价值,但不是agent-native。
agent-native的核心差异在于:模型成了系统行为的主体,它不再是被动响应请求的函数,而是主动解析目标、观察环境、尝试行动并不断修正的执行者。系统里有一个明确的运行循环,模型在这个循环里反复决策,直到目标达成或被安全机制拦停。工具不再是“代码里写好的一个接口”,而是可以被模型根据任务需求动态挑选和组合的能力集合。记忆也不再是一个会话窗口,而是分层的上下文系统,短期工作记忆管当下任务,长期记忆管跨任务的积累。
传统AI应用和agent-native应用的区别,我用一个表格来对比会更直观:
| 维度 | 传统AI应用 | agent-native应用 |
|---|---|---|
| 系统组织 | 代码编排流程,AI只处理单个节点 | 模型编排行动,代码提供工具和护栏 |
| 决策逻辑 | 规则、状态机、人工配置 | 模型根据目标和上下文动态决策 |
| 状态管理 | 请求级或会话级状态 | 分层记忆,支撑长时间多步骤任务 |
| 外部能力 | 每个功能单独对接接口 | 工具注册、动态选择、失败重试 |
| 异常处理 | 返回错误码,由外层代码兜底 | agent感知失败并自主规划备选路径 |
| 人机协同 | 人多步骤点击,模型出结果 | 人定目标加审查关键节点,agent执行闭环 |
从这个表格能看出来,agent-native不是简单地把更多环节交给模型,而是整个系统的控制流发生了转移。模型成了调度中枢,代码成了执行工具和安全边界。
1.3 关键判断:你的项目真的需要agent-native吗
不是所有系统都适合改成agent-native。这个判断做错了,后面会很痛苦。我自己总结了一个简单的评估清单,命中几条再上也不迟。
第一看任务是否天然多分支。如果你的业务逻辑存在大量“如果满足A就做X,否则看B再决定做Y”的嵌套规则,尤其这棵分支树还在持续生长,那用规则代码维护一定是灾难,agent帮你把分支决策交给模型是合理的。第二看输入是否高度不确定。用户可能会用几十种说法表达同一件事,还可能漏信息、带情绪、穿插无关内容,枚举法是覆盖不完的,模型的语义理解能力在这里有优势。第三看流程是否需要动态组合。比如数据分析场景,今天要查流失率,明天要做留存对比,后天要拉全链路漏斗,每个任务的工具组合都不一样,不适合写死。第四看目标是否有模糊地带。像“帮我排查这个订单为什么支付失败”,中间可能要查订单状态、查支付接口日志、查优惠券计算逻辑,路径是开放式的,只有agent才能真正跑完。
如果业务是高度确定、强合规、流程几乎不变,比如发短信验证码,或者固定步骤的数据清洗,那完全没必要上agent。老老实实用规则和脚本,成本低、可预期性强、出了问题好追责。agent-native适合的是那些“松散但需要自主性”的场景,张力和价值都在这。
2. 架构设计与工具选型的关键取舍
2.1 控制反转:agent-native的核心心法
业界做架构设计的都熟悉控制反转这个概念,在传统Java框架里叫IOC,在agent系统里同样适用。传统应用是代码拿到数据后调用模型,模型是末端执行者;agent-native是模型拿到目标后调用工具,代码变成被模型调度的资源。
这个反转带来的连锁反应很大。首先是接口设计方式变了,以前我们面向用户设计接口,现在要面向“模型的认知”设计接口。工具的参数名、描述、返回值结构,都必须让一个没有看过源码的模型能看明白。其次是异常处理策略变了,以前代码里用try-catch捕获异常然后返回给前端,现在要把异常本身变成一个可观察的信号,让模型看到这个信号后自己决定下一步是重试、换工具还是向用户确认。第三是系统治理方式变了,权限、审计、限流这些能力必须前置到agent的行动链路里,否则模型自由度一大,出事了都追不回来。
最关键的认知变化是:agent-native系统的可靠性,不再取决于把每个分支写得多细,而取决于你给模型提供的观察信息是否准确、可用工具是否覆盖了核心路径、安全护栏是否把危险动作挡在了外面。说白了,这不是一个从“写规则”到“写提示词”的替换,而是一个全新的工程体系。
2.2 编排模式:ReAct、Plan-and-Execute、Reflection怎么选
agent的核心运行循环有好几种经典范式,实际选型时不能盲目跟风,得看自己的任务特征。
ReAct是目前最主流的模式,核心思想是“思考-行动-观察”循环。模型每轮先根据当前状态生成一段推理,说明自己判断要做什么,然后调用一个工具,拿到工具返回结果后继续推理,直到给出最终答案。它的优势是简单、灵活、可解释性强,每一步都有迹可循,出了问题可以做轨迹回放。缺点是token消耗大,因为每一步都要把全部历史再交给模型,任务步骤一多,上下文容易膨胀。
Plan-and-Execute的思路更接近人类项目制:开局先让模型把大目标拆成几个子步骤,得到一个行动计划,然后逐个执行每个步骤,每步结果再反馈回计划层,必要时调整后续计划。这种模式适合任务边界相对清晰、需要较长多步骤才能完成的工作,比如数据处理流水线、月度报表生成。缺点是模型在计划阶段就可能犯错,一旦计划本身有漏洞,执行阶段再怎么纠都可能白跑。
Reflection是一种增强模式,它不改变主循环,而是额外引入一个评估环节。agent执行完某个步骤后,先让它自己评价一下结果质量,不满意就重来。这个机制在代码生成、文案修改这类“有明确质量标准”的任务上非常有效,但会增加两倍以上的模型调用成本,不适合高频低价值的操作。
我个人的选型建议是:先无脑用ReAct把闭环跑通,跑段时间如果发现计划性任务太多、步骤经常重复,再叠加Plan-and-Execute;如果生成质量始终差口气,再考虑给关键步骤加Reflection。一上来就把架构搭得很复杂,只会让你分不清问题出在模型、工具还是编排逻辑上。
2.3 工具即能力:从Function Calling到MCP
在agent-native架构里,模型的下限由大脑决定,上限由工具决定。工具定义的质量,直接决定agent能不能有效地解决任务。现在接工具的主流方式有三种:Function Calling、自定义脚本、MCP协议。
Function Calling是OpenAI等模型服务商提供的能力,模型在生成回复时可以直接输出结构化的工具调用请求,里面有工具名和参数JSON。这种方式接入最直接,平台本身帮你做了参数格式化,主流的模型服务都支持,适合起步阶段。缺点是工具和特定服务商的SDK绑得比较紧,一旦换模型服务商,代码要改一遍。
自定义脚本是最灵活但约束最弱的方式。你可以自己写Python脚本或HTTP接口,封装成agent能调用的服务,用正则或者prompt把参数提取出来。好处是不依赖平台,坏处是要自己处理大量边界情况:参数提取不准、返回格式不标准、失败信号不明确,都会快速烧掉token。
MCP是当前被讨论得很多的一套标准化协议。它把工具能力抽象成标准化的server和client,一次接入后可以被不同agent框架复用。整个思路很像当年的JDBC和ODBC:把数据库访问逻辑标准化后,上层应用就不用关心底层到底是MySQL还是Oracle。MCP目前很适合做中间件,比如统一对接内部系统、数据库、搜索服务、文件系统,让一套工具服务多个业务方。缺点是生态还在快速演进,某些基础能力还不够成熟,直接全员铺开有踩坑风险。
三个方式的实际选择建议:起步直接用Function Calling接三五个核心工具,跑通了验证可行性;然后逐步把稳定的、需要跨团队复用的能力用MCP包装起来;真正特殊的、一次性的事务,直接写Python脚本包一层就好,别为了抽象而抽象。
2.4 记忆分层的取舍
agent没有记忆就是“金鱼脑”,这句话听着不太严谨,却是工程现场最真实的痛点。会话里前一秒查的订单号,下一秒模型就忘了。要做复杂任务,记忆管理是绕不开的。
在agent-native架构里,一般把记忆分成三层。第一层是工作记忆,对应当前任务执行过程中的上下文,通常就是对话历史加工具执行结果的完整记录。这一层成本最高,token消耗也最大,需要做预算管理,用摘要压缩来降低冗余。第二层是情景记忆,存的是过去完成过的任务、当时的背景、关键步骤和结果。它适合放进数据库或向量索引里,当新任务跟历史任务相似时,agent可以主动检索参考。第三层是技能记忆,即长期不变的领域知识、工具使用技巧、用户偏好和规则约束,这部分可以预先写在system prompt里,也可以存在知识库中定期检索。
这三层记忆的取舍原则其实很朴素:能写到系统提示里的就别放在会话里,能压缩成摘要的就别原文携带,能检索后就丢掉的别一直挂在上下文里。很多团队一上来就给每个会话塞十几万token的静态资料,结果模型的注意力被分散,核心任务反而做不好。记忆不是越多越好,而是越精准越好。你跟一个老员工沟通也不用把公司规章制度全文复述一遍,你只需要在他需要的时候给他看对应章节。
2.5 上下文预算与模型选型
agent-native对模型的要求和传统AI应用不太一样。传统应用可以选大模型,承担高延迟高成本,因为模型只在一个环节工作;agent系统里模型要跑很多轮,每一轮都吃上下文,成本和延迟是叠乘放大的。所以我强烈建议在工作流里分层选型:主决策的agent用强模型,比如处理复杂推理、多工具组合;辅助角色比如摘要压缩、意图初筛、格式清洗,完全可以用小模型扛。
小模型还有一层价值是兜底。agent调用工具得到结果后,常需要一个“结果摘要器”把超长内容压缩成要点,这个任务用轻量模型实现广告比大模型划算得多,因为它不涉及深度推理,只是格式转换。把这类高频低智任务全部下沉到小模型,整体成本能下降一个数量级,agent主循环的响应速度也会明显提升。
上下文预算是另一个工程层面的主题。我常见的问题是一轮任务执行下来,历史消息里堆积了大量工具返回的原始数据,几份表格动不动就是几十万字符。开始做上下文管理之后,我定了一条硬规则:工具返回超过一定长度的结果,必须做结构化截断——只保留关键字段摘要和符合条件记录的ID,完整数据全部落到外部存储,agent需要详细内容时再按ID回查。这条规则让长期任务的失败率降低了很多,因为模型终于不会被无意义的长文本干扰了。
3. 落地实操:一个最少可用的agent-native引擎
3.1 第一步:划定边界、目标与工具清单
动手写代码之前,我会先做一件事:把系统的能力边界画出来。不要一开始就想做全能助理,先把目标收敛到一条业务主路径上,再逐步扩展。边界清楚了,后面做权限和评估才有依据。
以我的工单后台为例,改造后第一版只支持三个目标:识别咨询类型、查询用户订单、创建或更新工单。这三个目标分别对应两条工具调用路径。识别咨询类型用模型判断,查询订单号查订单系统,创建工单走工单系统。工具清单也不复杂,设计时就三张表:订单查询、订单详情、工单创建。复杂流程像退款操作、客户电话外呼,这一版统一不加,避免第一版就陷入多系统联调的大坑。
边界画完后,还要定义一个明确的终止条件。agent不是无限跑下去的,它要么给出最终答案,要么触发了最大步数被熔断。我习惯在系统提示里写清楚:只有用户的目标被明确解决,或者信息不足以继续执行,或者工具连续两次失败,才允许停止并汇报当前状态。没有终止条件的agent,就像一个没有下班概念的实习生,能在循环里耗到你怀疑人生。
3.2 第二步:把工具定义成可被agent消费的Schema
工具定义的质量是agent能不能干活的分水岭。我给工具下的定义是:工具是一份说明书,模型靠它理解整个世界。函数名、参数描述、返回值格式,每一条都要写得具体、准确、无歧义。
一个功能齐全的工具Schema,用OpenAI Function Calling的格式可以这样写:
{ "type": "function", "function": { "name": "query_order", "description": "根据用户提供的订单号查询订单基本信息。订单号通常以ORD开头,长度10位。", "parameters": { "type": "object", "properties": { "order_id": { "type": "string", "description": "完整的订单号,例如ORD20240901001" } }, "required": ["order_id"] } } }写这个Schema时有几个细节非常影响体验。参数描述一定要写清楚格式和示例,模型看到“订单号”,很多时候会直接拿原始输入的片段去填,没有示例和格式说明,调参全靠缘分。描述里要说明工具的边界,比如这个工具只查订单基础信息,不能查退款记录,避免模型拿同一个工具去干它干不了的活。返回值要设计成结构化的,能直接让模型继续用,不要返回一坨拼接好的文本,那只会增加模型解析的负担。
这里也顺带提一下实际接入时的一个经验:工具数量控制在五到八个左右时,模型选择准确率最高。工具太多,选择困难症会在模型身上重演,会有不必要的幻觉调用。再加新工具,优先看是不是真的高频且必要。很多团队工具堆到几十个,结果模型经常拿错工具,幻觉率直线上升,排查起来也特别酸爽。
3.3 第三步:实现核心运行循环
这里我直接给一个简化但功能完整的最小骨架实现,基于Python伪代码,不依赖特定框架,方便理解核心逻辑:
import traceback def run_agent(goal: str, tools: list[Tool], max_steps: int = 15) -> AgentResult: messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": goal} ] for step in range(max_steps): # 1. 调用模型,同时传入工具定义,让模型决定是否调用工具 response = llm.chat( messages=messages, tools=[t.schema() for t in tools] ) # 2. 模型返回的tool_calls为空,说明任务结束,返回最终答复 if not response.tool_calls: return AgentResult(status="done", final_answer=response.content) # 3. 模型要求调用工具,先把本次调用信息加入上下文 messages.append({ "role": "assistant", "content": response.content or "", "tool_calls": response.tool_calls }) # 4. 逐个执行工具调用,结果写回上下文 tool_results = [] for call in response.tool_calls: try: result = execute_tool(call.name, call.arguments) logger.info(f"step={step}, tool={call.name}, result={result}") tool_results.append(result) except Exception as exc: full_trace = traceback.format_exc() # 关键:不能吞掉错误,要把错误包装成结构化信号给模型 tool_results.append({ "error": str(exc), "traceback": full_trace, "message": f"工具{calls.name}执行失败,请根据错误信息决定重试或更换方案" }) # 5. 把工具执行结果组成tool消息,放回上下文,模型下一步就能看到 messages.append({ "role": "tool", "tool_call_id": call.id, "content": json.dumps(tool_results, ensure_ascii=False) }) # 6. 如果一直没有结束,达到最大步数则强制终止 return AgentResult(status="max_steps_exceeded", detail="执行步数超过限制,已熔断")这个循环是最小可用的agent运行时,里面有几个重要的工程决策。第一,工具失败时绝对不能把异常吞掉,要让模型看到完整的错误信息和堆栈,它才能做正确的后续决策。很多第一版代码在try-catch里只给模型返回一句“工具调用失败”,模型完全不知道原因,根本无从修复,只能反复尝试同一个错误,白白烧钱。第二,每轮的tool_calls必须完整地保留在上下文里,因为下一轮模型需要回顾自己上一轮做了什么、为什么做,信息链路不能断。第三,max_steps要设置,我一般从15开始,后续根据线上数据分析再调整,防止agent钻牛角尖逃不出来。
3.4 第四步:护栏、权限与审计
给agent开放工具接口,就像把保险柜密码交给一个新员工,一定得配一套安全管理体系。护栏做不好,不是小概率事故,而是必然事故。
我在实际项目里对工具分了三类:只读工具、业务操作工具、高风险工具。只读工具像订单查询、库存查询,agent可以自主调用;业务操作工具像创建工单、发起审批,agent可以执行,但必须走审批流,把关键动作挂起等待人工确认;高风险工具像批量退款、修改用户账户状态,agent默认禁止直接调用,除非有特定的授权token和审批记录。这个分级不是口号,是真的在工具Schema和执行层做了拦截,不是靠提示词“你小心一点”。
审计日志在这个架构里不是可选项,是核心基础设施。agent每一次工具调用、每一次模型决策、每一次权限判定,都要完整记录,包括当时使用的上下文摘要、传入的参数、返回值、耗时和token消耗。出了线上事故,靠这些日志才可以做轨迹回放和根因分析。没有这份审计,agent一旦在真实环境里干了出格的事,排查就像大海捞针。
另外,我还建议在agent行动前加一道“动作预览”机制。工具调用执行前,先生成一版人类可读的描述,比如“将查询订单号ORD20240901001的状态”,发给相关负责人确认。这个机制对写操作尤其重要,宁可多一步人工确认,也不要无人值守地在生产环境乱动数据。后面扩展到更多自动化时,这个设计可以按风险等级逐步关闭,但绝不能一开始就不做。
3.5 第五步:可观测性与回归评估
agent系统最难搞的是评估。传统软件有单元测试、有集成测试,场景是固定的,输入输出是确定的;agent系统是动态路径,同样的需求不同用户问出来,走的路完全不一样。没有有效的评估机制,你根本不知道今天改了一版prompt是变好了还是变坏了。
我在项目里搭了一套很轻的回归评估体系。首先准备一个固定的评测集,大概二十个覆盖主要业务场景的典型问题,包括正常场景、边界场景、异常场景。每次改动后,自动跑一遍评测集,把每个问题的最终回答、路径步数、工具调用序列、耗时、token消耗全部记录下来,然后人工打分。这个打分第一版就是看结果对不对,第二步再看路径是否有效率,有没有绕路。
评估集不能只做一次,要持续补充线上出现的bad case。跑一段时间之后,我养成了一个习惯:凡是线上出问题的case,一律扔进评测集里做回归基线。这个习惯让系统质量稳步提升,因为每一次修复都是“防复发”,而不是只针对单次事故临时打补丁。可观测平台也一样,我用的方案是给每条agent任务生成一个唯一task_id,所有日志、审计、耗时、token消耗都挂在task_id下面,排查的时候一条命令拉全链路,效率提升非常明显。
4. 实战中最常遇到的四个坑
4.1 工具失败时agent陷入自说自话
这是所有agent项目上线后第一个撞到的墙。表现是:agent调用工具拿不到有效结果,于是它自己编一个看起来合理的结果,继续往下推理。模型本身有续写倾向,你在上下文里塞了一段失败返回,它会顺着这个上下文往下编,产出“订单已查询成功,用户退款流程已启动”这种完全虚构的结论。
我后来的解法就三条。第一,工具返回失败信息时,要明确带上“ERROR”标记,并且在系统提示里写死规则:看到这个标记,禁止生成任何关于操作成功的描述。第二,把失败信息设计得更结构化,包括错误码、失败原因、可尝试的方向,让模型有据可依。第三,在终点判断上做拦截,最终答复生成后加一道“结果校验”步骤,利用规则或者一个小模型,检查agent声称已完成的动作是否真的在工具调用记录里出现过。这套组合下来,自说自话的问题基本被压住了。
4.2 上下文被历史垃圾挤爆
agent最贵的资源不是GPU,是上下文窗口。我见过一个同事的项目,跑了二十步以后上下文里堆积了六七万token的工具原始返回,模型完全被噪声淹没,回答质量断崖式下降。后来我们把所有工具调用做了三步改造:大结果强制落库,只返回摘要和记录的ID;会话历史隔几轮做一次摘要压缩,把已经完成的子任务浓缩成一段小结;进入新任务模块前清空不相关上下文。这三步做完,同样任务路径的token消耗降低了约六成,模型回答的准确性反而提升了,因为注意力不再被无效信息分散。
4.3 权限控制形同虚设
还有一个高发问题:把权限控制写在prompt里,而不是写在执行层。典型做法是给agent的system prompt写一句“你不能删除用户数据,不能执行危险操作”,然后就没有然后了。我实际测试过,这种做法对有一定对抗性的输入场景效果为零,模型很容易被绕过去,因为它本身没有“权限检查”这个能力层级。
真正的权限控制必须在工具执行层做硬拦截:agent可以请求调用,权限模块判断该动作是否在授权范围内,是则放行,否则直接返回“权限不足”。这个拦截是不可绕过的,无论模型prompt被怎么注入,都只能在授权范围内行动。权限模型可以做成角色基数,比如“客服助理”角色能查订单、创建工单;“运营管理员”角色能批量退款、看所有报表。每个角色对应一张明确的权限清单,工具Schema里再标注每个工具属于什么权限级别,两层叠加,才能真正兜住底。
4.4 多agent协作成了负优化
受近几年multi-agent概念流行的影响,很多团队一上来就整多个agent,有规划agent、执行agent、反思agent,再搞个协调agent统筹全局。结果系统跑起来以后,问题不是每个agent干不好自己的活,而是agent之间的上下文传递、任务调度、冲突仲裁成了新的复杂度来源。日志一看,一次简单查询,三个agent来回传了八轮还没结束,反而比单个agent直接处理慢了三倍。
我的经验是:先单agent跑通所有核心路径,确认单agent确实遇到瓶颈了,再考虑分层拆agent。拆的时候也不是按“角色好听的”去拆,而是按“专业能力边界”拆。比如客服场景:一个入口回复agent负责统一接客和分发,一个专业工单agent负责处理工单逻辑,一个风险审查agent负责高危操作的独立复查,三者之间只有清晰的接口协议,没有模糊的“谁说了算”问题。多agent的正确打开方式是并行分工,而不是串行表演。
5. 动手前的最后建议与我的真实体会
如果你正在考虑把一个系统改造成agent-native,我最想说的不是架构选型,也不是技术栈,而是想清楚你用它来换什么。对我来说,agent-native换来的是不确定性场景里的容错能力和迭代效率,代价是更高的token成本、更重的可观测性建设和更难预测的行为边界。如果你的业务价值不足以抵消这些代价,那这套架构就是在自找麻烦。
从踩坑经历里总结下来,最值得做的一步永远是“先小后大,边界先行”。不用一上来就追求完整的智能体平台,先挑三个核心工具,把ReAct循环跑起来,配好审计日志和权限拦截,让它在真实但低风险的场景里干一阵子。真的跑稳了,你自然知道下一步该加什么工具、拆什么模块。如果连最小闭环都跑不转,那问题往往不在架构,而在你对问题的定义还不够清楚。
最后再分享一个小技巧:在系统提示里,永远不会给agent太宽泛的目标描述。目标要具体、可验证、有明确的完成标准。你给agent交代任务的方式,决定了它怎么对待你的任务。这条经验,比我用过的任何一个框架都管用。