智能体(Agent)到底是个啥东西?我直接说结论:智能体不是一个神秘的技术黑盒,而是“大模型 + 记忆 + 工具 + 自主决策循环”的组合体。它跟普通的聊天机器人最大的区别就三个字——会做事。你问ChatGPT“明天深圳天气怎么样”,它给你一段文字;你问一个Agent同样的问题,它自己去查天气接口、比对数据、组织语言、甚至帮你把加衣提醒推到手机里。这一来一回的差异,就是Agent存在的意义。
这篇文章不堆概念,我会用一套完整的实操视角来拆解智能体:它跟普通AI程序的分界线在哪里、核心组件是什么、一个最小可用的Agent怎么搭起来、跑起来会踩哪些坑。适合刚开始接触AI开发、想搞清楚“Agent到底能不能落地”的人,也适合已经在做LLM应用、但总觉得“差点火候”的开发者。
1. 智能体和聊天机器人的本质区别在哪里
很多教程喜欢说“Agent = LLM + 记忆 + 工具”,这句话没错,但太粗了。真正决定一个东西是不是智能体的,不是它用了多大的模型,而是它有没有“行动”的能力。
1.1 从“说话”到“做事”的跨越
普通聊天机器人的工作流程是:输入 → 模型生成 → 输出文字。它是一个封闭回路,模型既看不到外界,也改变不了外界。你让它“帮我定个明天早上的闹钟”,它只能给你一段“好的,我记住了”的假话,因为它根本没有能力碰你手机里的时钟App。
开发者想要欺骗这种局限,最常见的做法是把功能硬编码进对话里,比如识别到“闹钟”关键词就弹个确认按钮。这就是一种伪智能——所有的“能力”都是预先写好的规则,模型只是在做关键词匹配。
Agent不一样。它把“生成文字”拆成了“思考”和“执行”两个环节。模型先分析你的意图,把它转成一个结构化的行动指令,比如“调用系统闹钟App,设定早上7:00响铃”。然后Agent框架接管,真正去执行这个指令,再把执行结果喂回给模型,让模型决定下一步怎么做。这个“行动—观察—再决策”的循环,才是智能体的核心,也是它和聊天机器人之间那堵看不见的墙。
1.2 自主性才是灵魂
刚才说的闹钟例子,其实还只是“工具调用”,很多框架不调用工具也能做。真正让Agent从“工具”升级为“智能体”的,是自主性。
我用一个生活里的场景来说。你去餐厅吃饭,跟服务员说“来一份招牌套餐”,服务员只需要把菜单递给后厨——这是工具调用型Agent。但如果你说“帮我安排一顿适合父母50岁寿宴的晚餐”,服务员要自己定预算、选菜系、考虑长辈口味、订座位、算时间——这是自主决策型Agent。
落到技术层面,自主性体现在Agent能自己拆解目标。它不会等你把每一步都告诉它,而是把一个大任务分解成若干子任务,然后为每个子任务选择合适的工具、合适的执行顺序,甚至在执行失败时自己换一套方案重试。这种能力来自大模型本身具备的规划能力,再加上Agent框架提供的“反思”和“修正”机制。
一句话总结:聊天机器人是“张嘴就来”,Agent是“想好了再干,干完回头看”。
2. 智能体的核心组件拆解
一个可用的Agent,最少需要五个部分。少一个,它就退化成聊天机器人或者一个普通脚本。我按重要程度逐个拆。
2.1 大脑:大模型的角色不只是“聊天”
Agent里的大模型,承担的是决策中枢的工作,而不是一个话痨。它要做的事情包括:理解用户请求、分析当前状态、选择合适的工具、生成行动参数、判断行动结果、决定是否继续。这个角色对模型的推理能力要求明显高于纯聊天场景——你在选型时,不能只看模型在排行榜上的分数,还要看它在“多轮工具调用”场景下的稳定性。
我拿一个实际案例来对比。某次我用一个轻量模型搭Agent,让它处理“帮我把这个表格里的重复数据清理掉”这个任务。它第一步对了,识别出需要打开表格工具,但在第二步就乱了——它输出了一个完全不存在的函数名,把“清理重复数据”错误地翻译成了“排序”。换成推理能力更强的模型,同一份数据、同一个框架,它就能正确调用“数据去重”并返回处理后的结果。这就是为什么Agent项目里,模型选型几乎决定了整个项目的上限。
2.2 记忆:短期记忆和长期记忆是两个存储
Agent的记忆机制分两层。
短期记忆相当于工作台。Agent在执行任务的过程中,需要不断把中间状态放进去:当前目标是什么、已经做了哪一步、下一步打算做什么、工具返回了什么结果。大多数Agent框架用“聊天历史”承载短期记忆,但这有个隐患,模型有上下文窗口上限,窗口满了之后,最早的信息会被挤掉,导致Agent“忘记”任务最初的约束条件。实操里我见过最典型的一个场景:用户让Agent“总结这份报告,控制在300字以内”,Agent执行到一半上下文溢出,等它回来写总结时,早把“300字以内”忘了,输出了2000字的全文摘要。
长期记忆则负责跨会话的持久化。比如一个Agent助手记住了用户的偏好(“我喜欢早上九点开会”)、历史任务的结论、甚至用户的说话风格。长期记忆的实现方式通常是向量数据库加Embedding,先把文本转成向量存进去,需要时再做相似度检索。这一层是智能体能不能“越用越懂你”的关键,也是最容易被新手忽略的部分——很多人搭的Agent只能处理单次对话,换个会话就失忆了。
2.3 工具:智能体的手和脚
工具是Agent连接外部世界的接口。工具可以是函数、API、数据库查询、浏览器操作脚本、命令行指令,甚至可以是另一个Agent。每一条工具定义通常包含三部分:工具名称、参数描述、执行逻辑。Agent框架会把这些描述塞进系统提示词里,让模型知道“你有什么工具可以用、分别怎么用”。
这里有个关键细节:工具描述的质量,直接影响调用准确率。我见过太多人随手写工具描述,比如“更新用户信息”,结果模型经常在需要更新用户地址的时候调用了别的工具。把描述改成“根据用户ID更新用户地址(address字段),只能用于修改收货地址”之后,调用准确率肉眼可见地提升。你完全可以把它理解为给工具写“上岗说明书”,说明书越精确,新员工(模型)犯错的概率就越低。
2.4 规划器:把大目标拆成小步骤
规划器负责把一个大目标拆成有序的子步骤。有的Agent用ReAct模式(Reasoning and Acting),边推理边行动,每一步都基于上一步的结果生成下一步的思考;有的用Plan-and-Execute模式,先一次性生成完整计划,再逐条执行;还有的更复杂,带任务队列和优先级调度。实际场景里,ReAct更适合任务步骤不明确、需要探索的场景,Plan-and-Execute更适合步骤固定、可预测的流水线任务。
这里要提一个实施细节:规划器不一定要用额外的代码模块实现。很多成熟的Agent框架直接靠大模型的提示词完成规划,模型在每一轮先输出“Thought(思考)、Action(行动)、Observation(观察结果)”,循环往复,直到任务完成。这种模式简单直接,但缺点也很明显——一旦模型陷入错误循环,它可能在一件错误的事情上反复尝试,烧掉大量Token。所以现在越来越多的方案会在外部加一层“硬校验”,比如规定最大步数、超时自动终止、每个工具调用的参数做Schema校验。外置校验和价值判断对稳定性很重要,别把安全托付给模型自觉。
2.5 反馈循环:把“做完了”变成“做好了”
闭环的最后一个环节是反馈循环。Agent每次调用工具后,会拿到一个结果,它不急着交答案,而是先“看一眼”结果是否符合预期。如果工具返回的数据格式不对、结果为空、或者明显不合理,Agent会重新调整参数再试一次,或者换一个工具。这个“观察—反思—调整”的过程,是Agent质量比普通脚本高一个档次的原因。
有一些比较讲究的落地项目,还会给Agent加一层“自我批评”,让模型对每一步的执行结果打分,低分就重跑。这种方式很耗Token,但对那些“一步错、步步错”的复合任务很有帮助。你可以在自己的项目里做成可配置项,让用户按需开关,而不是一刀切强制开启。
3. 从零搭建一个最小可用的智能体
理论说完了,直接上手。我尽量用最少的依赖做出一个能跑起来的Agent,你不需要任何高级的框架,一个支持Function Calling的模型API就够了。我们要做的事情是:搭一个能查天气、能算简单数学的Agent,让它具备“自主决策该调用哪个工具”的能力。
3.1 环境准备:选型逻辑
我这里选Python环境,因为生态最成熟。核心依赖只有一个openai官方SDK,因为它的Function Calling机制是最典型的Agent工具调用范式,其他平台也都兼容类似的能力。你本地需要配置一个环境变量存放API Key,不要硬编码进代码里。
pip install openai export OPENAI_API_KEY="你的密钥"有些人对“Function Calling”这个名称不理解,它其实就是:你在API请求里描述一批可用函数,模型根据用户的话决定调不调用其中一个,并且把调用参数以结构化JSON返回给你。真正的“调用动作”由你的代码执行,模型只负责决策。明白这层之后,Agent就不神秘了——它就是“模型决策 + 程序执行”的组合。
3.2 定义工具:给Agent准备“能力”
我们给Agent定义两个工具:get_weather和calculator。注意工具描述怎么写,直接影响模型的调用准确度。
tools = [ { "type": "function", "function": { "name": "get_weather", "description": "根据城市名查询当前天气情况,支持中文城市名,如:深圳、北京、上海", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名,例如:深圳" } }, "required": ["city"] } } }, { "type": "function", "function": { "name": "calculator", "description": "执行四则运算表达式,支持加、减、乘、除、括号,如:12 * 5 + 8", "parameters": { "type": "object", "properties": { "expression": { "type": "string", "description": "数学表达式,例如:(12 + 3) * 4" } }, "required": ["expression"] } } } ]这段代码会告诉大模型:“你有两个工具,一个查天气,一个算数学”。但注意一个细节:模型并不知道“get_weather这个函数应该去哪个网站查数据”,它只负责“根据用户意图返回city参数”。真正联网查询的代码是你要写的,模型不参与。这种职责分离是Agent落地时最需要注意的边界。
3.3 执行循环:Agent的心脏
工具定义好之后,核心的执行循环如下。这段逻辑是所有Agent框架的雏形,理解了它,你就能看懂任何复杂的Agent框架。
from openai import OpenAI import json client = OpenAI() def run_agent(user_message): messages = [{"role": "user", "content": user_message}] # 第一步:把用户问题 + 工具定义 一起发给模型 response = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=tools, tool_choice="auto" ) # 第二步:模型决定调用哪个工具 response_message = response.choices[0].message messages.append(response_message) # 把模型的“决策”加入对话历史 # 第三步:如果模型决定调用工具,就执行 if response_message.tool_calls: for tool_call in response_message.tool_calls: func_name = tool_call.function.name args = json.loads(tool_call.function.arguments) if func_name == "get_weather": # 这里是模拟查询,实际应接天气API result = f"{args['city']}今天晴,28度,微风" elif func_name == "calculator": result = eval(args["expression"]) # 把工具执行结果返回给模型 messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": str(result) }) # 第四步:模型拿到工具结果后,生成最终回答 final_response = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=tools ) return final_response.choices[0].message.content # 如果没有调用工具,直接返回模型回答 return response_message.content # 测试 print(run_agent("深圳天气怎么样?")) print(run_agent("12 * 5 + 8等于多少?")) print(run_agent("先算一下(12 + 3) * 4,然后告诉我深圳天气"))这个循环就是我前面说的“感知—决策—行动—观察”的具体实现。第一轮请求相当于“感知 + 决策”,模型的输出里带着工具调用指令;代码执行工具是“行动”;执行结果回传给模型是“观察”;模型基于观察结果组织最终回答。一个多步骤的Agent任务,无非就是把第四步的结果再次喂给模型,让它继续决策下一轮工具调用,直到模型认为任务完成、不再返回工具调用为止。
3.4 让Agent跑多轮任务
上面的例子只跑了一轮工具调用就收尾了。真实的Agent任务往往需要多轮:先查一个数据,再基于数据做计算,最后再生成报告。把上面的循环改造一下,让“判断是否还需要调用工具”变成一个while循环,就是最简版的多轮Agent。
def run_agent_multi(user_message, max_steps=5): messages = [{"role": "user", "content": user_message}] for step in range(max_steps): response = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=tools, tool_choice="auto" ) response_message = response.choices[0].message messages.append(response_message) if not response_message.tool_calls: return response_message.content for tool_call in response_message.tool_calls: func_name = tool_call.function.name args = json.loads(tool_call.function.arguments) if func_name == "get_weather": result = f"{args['city']}今天晴,28度,微风" elif func_name == "calculator": result = eval(args["expression"]) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": str(result) }) return "已达到最大轮次仍未完成,请调整任务描述或增加上限"这个max_steps限制非常重要。我第一次写Agent时没加这个限制,结果模型在“计算一个复杂表达式”时陷入了死循环:它反复调用计算器、看到结果、觉得不对、再换个方式调用,直到API账单飙升我才发现。加一个硬上限,既保护钱包,也避免框架挂死。
3.5 小型项目可直接配置:一份Agent调度源码(示例)
多轮循环本身也可拆成独立配置。如果你不想每次都在代码里写死“工具名称—函数名”的映射,可以做成一个按名称注册和分发的表格式调度结构,如下方示例所示:
# mini_agent.py # 用名称注册表管理工具调用,方便后续新增工具 TOOL_REGISTRY = {} def register(func): """把函数注册到工具表,函数docstring作为工具描述""" TOOL_REGISTRY[func.__name__] = func return func @register def get_weather(city: str) -> str: """ 根据城市名查询当前天气情况,支持中文城市名 """ # 实际场景替换为真实天气API调用 return f"{city}今天晴,28度,微风" @register def calculator(expression: str) -> str: """ 执行四则运算表达式,支持加、减、乘、除、括号 """ return str(eval(expression)) def run(user_message: str, max_steps: int = 5) -> str: tools = [ { "type": "function", "function": { "name": name, "description": fn.__doc__, "parameters": {...} } } for name, fn in TOOL_REGISTRY.items() ] # 循环逻辑略,和上文run_agent_multi一致这种写法在工具少的时候看不出优势,等工具数量上到十几个,你会发现“注册表模式”比一长串if-else好维护得多。新增工具只用写一个函数加注册装饰器,不用改动主循环代码。
4. 智能体能做什么?用场景说话
理解了原理,再看应用场景,你的视角会完全不一样。因为Agent的能力边界不是由“它能做什么”决定的,而是由“你给它接了什么工具”决定的。我给几个不同类型、已经可以落地的场景。
4.1 办公⽣产力:把重复劳动扔给Agent
最典型的应用是邮件和会议日程处理。一个Agent可以接入你的日历API、邮件API、通讯录API。你只需要对它说一句“帮我看看明天下午三点有没有空,如果有的话安排一个跟某同事的半小时沟通会,并把会议纪要模板准备好”,它会自己查日历、判断空闲时间、发起会议邀请、创建文档模板。这一步跨了三个系统,传统自动化脚本要做到这个程度,你需要写几百行胶水代码,而且每个系统接口一升级就要重新维护。Agent把“接口调用逻辑”藏在工具层之后,你用自然语言就能指挥它完成跨系统操作。
数据整理也是Agent的强项。之前我帮一个团队做销售周报的自动化,以前的流程是人手动从CRM里导出数据、用Excel做透视表、再写总结。改成Agent后,流程变成了:Agent定时触发→查询数据库→调用数据分析工具→生成图表→调用大模型把数据写成周报文案→推送消息到工作群。整套流程需要人的环节只剩下“审核”。
4.2 代码辅助:从补全代码到改Bug
代码补全工具已经普及了,但Agent级别的代码助手做的是另外一件事:理解整个仓库结构、定位问题、修改代码、运行测试、根据测试结果决定是否继续修改。
给你一个具体的例子。我让一个Agent处理“这个项目的前端控制台报错,提示某个接口返回了404,帮我排查”。Agent先调用代码搜索工具,找到调用这个接口的代码位置,再调用日志查询工具,看后端有没有对应路由,最后用调试工具在测试环境请求一遍接口,拿到404的具体原因——路由路径写错了,大小写不一致。整个过程它自己定位、自己验证、自己给出修改建议。人只负责最后点一下“确认修改”。
这类Agent落地速度最快的是独立开发者和中小团队,因为代码库规模小、结构相对清晰,Agent的上下文窗口Cover得住。
4.3 个人助理:让Agent真正“懂你”
个人助理类Agent是目前门槛最高的场景,原因在于它需要长期记忆,而且不能犯低级错误。一个合格的助理Agent至少要会:根据日程提醒你提前出发(要接地图API和航班动态)、一个月后主动问你是否需要续费某个会员(要接支付记录)、洞察到你说“最近好累”时自动把本周的晚间会议推迟(要接日历和情绪判断)。
这些功能单拆出来都不复杂,难的是状态管理,Agent要随时追踪“用户身处什么阶段、需要什么信息、上次聊过什么”。这也是为什么很多产品团队先从“垂直场景的单功能Agent”做起,比如只做一个日程管家、只做一个账单助理,而不是一上来就做全能管家。
4.4 行业落地:客服、运维、销售头部
企业级Agent落地最成熟的三个方向:智能客服、自动化运维、销售助手。
智能客服Agent已经不是早期的关键词回复了。现在的方案是:Agent理解用户问题→搜索知识库→调用订单系统查询用户订单状态→判断是否需要人工介入。整套流程里它可以同时处理好几万并发,遇到解决不了的问题再一键转人工,这个模式在零售和金融行业已经大规模验证过。
运维Agent现在的做法是:接到告警→查监控系统→分析日志→判断根因→执行预案操作(比如重启某服务、扩容某集群)。能不能真正自动执行操作,取决于企业的风险承受能力,但“辅助排查根因”这一步已经能用Agent跑得很稳。
5. 常见问题与排查技巧实录
Agent项目跟传统软件开发最大的不同是:失败路径极多,而且很多失败是概率性的,不是必现的。同一个输入,有时成功有时失败,这种不确定性让排查变得很头疼。我把我踩过的坑集中列一下,都是实战里反复出现的问题。
5.1 模型不爱调用工具怎么办
现象:Agent能正常对话,但用户说了“查一下天气”,模型却直接回答“我查不了,我只是一个语言模型”。
原因分析:要么是工具描述写得不清晰,模型不认识这个工具;要么是模型对工具的“信任度”不够,或者上下文里类似场景没出现过。还有一个常见原因:你在系统提示词里没明确告诉模型“你可以使用工具”。
排查手段:
- 把工具描述写得更具体,给出典型触发场景,比如“当用户询问天气、气温、降雨等信息时,必须使用get_weather工具并传入城市名”。
- 在系统提示词里加一句“你有充足的工具来回答用户问题,当用户请求涉及工具能力时请直接调用”。
- 测试时把
tool_choice从"auto"改成指定工具名,比如tool_choice={"type": "function", "function": {"name": "get_weather"}},强制模型走一次工具调用,排查是不是工具定义本身有问题。
5.2 Agent产生幻觉,自己编造工具结果
现象:Agent明明没调用工具,却在回答里写“根据天气API查询结果,深圳今天31度”。这是最危险的一种错误,因为回答看起来非常可信。
原因分析:模型在训练语料里见过类似的数据,当上下文没有明确约束时,它会“脑补”一个答案。这本质上是模型对“无法获得信息”这件事的容忍度太低,它宁可编一个,也不愿意承认自己不知道。
排查手段:
- 在系统提示词里强调“只有工具调用返回的数据才能作为事实依据,未经工具验证的信息必须声明为推测”。
- 在Agent框架里加一条校验规则:如果模型回答中包含数据性陈述,但本轮循环中没有任何工具调用记录,则判定为可疑回答,要求重写。
- 对于高正确率要求的场景(如金融、医疗),可以采用“拒绝回答”策略:当工具结果无法获取时,要求Agent明确回复“暂时无法获取该数据”,而不是猜测。
5.3 多轮任务中Agent“迷失方向”
现象:一个三步任务,Agent做完第一步之后,忘记最初的目标是什么,开始自由发挥。
原因分析:这是上下文窗口被中间工具结果填充导致的注意力稀释,尤其是工具返回的长文本会把关键约束挤出有效注意力范围。
排查手段:
- 把“原始目标”固定在系统提示词的前部,并重复强调。比如“本轮任务起点:用户在请求一份季度销售报告。你必须在生成最终回答前确保已经完成数据分析步骤”。
- 工具返回结果做摘要而非原样塞入。如果工具返回了5000行数据,不要让模型硬读,先用程序做统计摘要,再把摘要喂给模型。
- 在Agent里引入“目标检查点”:每执行完一个子任务,用一条程序日志记录“当前进度”,下一次循环把这条进度注入上下文,帮助Agent重新锚定目标。
5.4 工具参数格式反复出错
现象:需要传入JSON格式的参数,模型总是传错,要么字段名不对,要么类型不对。
原因分析:参数Schema描述不够严格,或者模型对类型定义理解不足,尤其在参数是嵌套结构时更容易出错。比如给“address”字段传了一个对象而不是字符串。
排查手段:
- 参数的
description写清楚“类型是什么、格式是什么、示例值是什么”。比如“date: string,格式YYYY-MM-DD,示例2025-06-01”。 - 在Schema里用
"enum"定义可选值范围,模型只能从枚举里选,基本上不会错。 - 在框架层加JSON Schema校验,校验不过就让模型重新生成一次参数。这比直接报错要友好,因为模型看到“格式错误,请修正为XX格式”往往能自己改对。
5.5 成本失控:Agent烧Token比预期凶
现象:一个简单问题,Agent内部调了好几次模型,账单数字吓人。
原因分析:每次工具调用的结果都会塞回对话历史,多轮之后,每发一次请求,Token消耗都是上一次的累加。另一个隐性成本是工具描述本身——每轮请求都要重新携带全部工具定义。
排查手段:
- 给Agent设定最大工具调用轮数,比如3轮,超过就强制终止。
- 对工具返回结果做截断,只保留前几百个字符,既节省Token又避免无效信息分散注意力。
- 工具数量多的项目,把工具做分组,按需加载。比如用户聊天气时只加载天气相关工具,不加载查数据库的工具。这个优化能让Token消耗直接减半。
6. 智能体项目的基本设计要点
最后把思路拉高一点,讲几个我在搭建Agent时反复用到的设计原则。这些原则不是通用的,但凡是能稳定上线的Agent,基本都会遵守其中至少三条。
6.1 “最小权限”原则也适用于Agent
给Agent接工具时,不要图方便把所有API都接上。比如一个只处理“读取”任务的Agent,就不要给它“删除”或“写入”的权限。一旦模型被注入恶意提示或者陷入错误循环,最小权限能避免发生不可逆的破坏。我在做运维Agent时,第一步就先做权限隔离:只允许Agent执行只读操作,所有变更类操作必须经过人工审批。
6.2 可观测性设计:Agent的“黑盒”要留观察窗
Agent决策过程对用户来说是个黑盒,但对开发者不能是。设计Agent时,每轮模型响应都应当记录:模型思考摘要、调用的工具、参数、返回结果、耗时、Token消耗。这些日志在测试阶段是唯一能帮你快速定位问题的线索。我自己的习惯是在开发阶段强制打印每一步的完整JSON,上线后再改为只记录关键字段。没有日志的Agent就是盲人摸象,问题复现不了,也就永远修不好。
6.3 把工具做薄,把描述做厚
传统开发里,函数职责越单一越好,这个原则在Agent的“工具”设计里同样成立,但有一个额外维度:描述信息的质量比实现逻辑更关键。一个工具哪怕实现逻辑很简单,只要描述清晰、参数定义精确,模型的调用准确率就会高很多。反过来,一个工具实现逻辑很复杂但是描述含糊,模型就不知道该什么时候用它,再强的能力也白搭。每一次工具定义,都值得像写接口文档一样对待。
6.4 兜底策略比聪明逻辑更可靠
Agent的失败模式太多了,你不可能预测所有场景。与其写一堆复杂的分支逻辑来应对特殊状况,不如做好三件事:最大轮次限制、异常重试机制、人工接管接口。关键操作一律要求人工确认,这不是对Agent能力的不信任,而是工程上的负责任。
7. 再分享两个实操里的小技巧
这个章节算是我个人实战的附带收获,不一定写得进正式文档,但确实好用。
第一个技巧是关于“冻结工具描述版本”。Agent跑在线上生产环境,工具描述稍微改动一个字,模型的行为就可能漂移。我遇到过一次小版本更新,只是把工具描述里的“城市名”改成了“城市中文名”,结果模型的调用准确率突然下降,因为新描述跟模型在预训练时见过的样例格式不匹配了。从那之后,我养成了一个习惯:工具描述改动后,必须跑一遍固定测试集对比准确率,再决定是否上线。
第二个技巧是把“观察”环节做实。默认的Agent循环里,模型把工具返回的结果直接拿过来用,不做质量判断。但实际上工具返回结果可能为空、可能格式异常、可能数据明显不合理。在有臻求的项目里,我会在代码里加一层经验判断程序,也就是简单的规则校验,比如“结果是否为空”“是否超时”“JSON是否能解析”。解析失败的结果先不进对话历史,先要求模型重新生成工具参数重试一次。这一步防住了很多因为工具自身偶发故障导致的连锁错误。
Agent这东西,说到底不是“造一个无所不能的仙灵”,而是把“人的意图”翻译成“一步步可执行的行动”,再把每一步行动的结果反馈给模型继续决策。它不会取代复杂系统设计,但确实把人与程序之间的交互方式往前推进了一大截。如果你手边正好有某个经常重复的任务,或者某个跨系统的协作流程,不妨像上面那样先写一个最简Agent试着跑起来。先把“感知—决策—行动”的闭环跑通,再往里加记忆、加规划、加反思,你的智能体会一步步长出你想要的样子。