Skip to content

Agent 架构与工具调用

LLM 单独使用时,它只能"根据输入直接生成输出",不会查资料、不会算账、不会执行代码。Agent 的核心思想是给模型加上一个能力:在生成过程中调用外部工具,把工具返回的结果再喂回上下文,继续推理。这样模型擅长的事情(理解、规划、生成)由它做,它不擅长的事情(精确计算、检索、查询接口)交给确定性代码。

ReAct:思考—行动—观察的循环

大多数 Agent 都遵循 ReAct 模式,即"推理(Reason)+ 行动(Act)"交替进行:

text
思考: 用户要查上个月的销冠,我需要先查询销售数据库。
行动: 调用 querySales(month="上月", sort="desc", limit=1)
观察: { "name": "张三", "amount": 128000 }
思考: 拿到了结果,可以回答用户了。
回答: 上个月销冠是张三,销售额 12.8 万。

这个循环由三个部分组成:

环节谁来做内容
思考模型决定下一步做什么、调用哪个工具
行动框架/代码执行模型选定的工具,拿到结果
观察框架/代码把工具结果放进上下文,交还模型

循环需要一个终止条件:模型判断"已经能回答了"就输出最终答案;或者达到最大步数上限,强制停止。没有步数上限的 Agent 可能陷入无限循环,持续消耗 Token。

工具定义:函数调用

工具本质是一个有明确入参和返回值的函数,模型不需要看它的实现,只需要看它的"说明书":名字、用途、参数 schema。主流模型都支持结构化的函数调用(function calling),模型按 schema 输出参数,框架负责真正执行。

json
{
  "name": "queryOrder",
  "description": "按订单号查询订单状态和金额",
  "parameters": {
    "type": "object",
    "properties": {
      "orderId": { "type": "string", "description": "订单编号,如 ORD12345" }
    },
    "required": ["orderId"]
  }
}

定义工具有几个实践要点:

  • description 要写给模型看:说清什么时候该用、什么时候不该用。模型是根据 description 决定是否调用的,写不清楚就会乱调或漏调。
  • 参数要简单且可校验:能用枚举就用枚举,尽量让模型少出错。
  • 返回结构要稳定:工具返回的 JSON 结构要固定,方便模型解读,也方便程序兜底。
  • 工具要够少:给模型几十个工具,它选错的概率会上升。按场景拆分工具集,而不是一次全塞给它。

记忆与上下文管理

Agent 跑起来后,上下文会不断增长:系统指令、历史对话、每一次思考、每一次工具调用结果,全都会累积。一旦超出窗口,就会丢失关键信息或直接报错。

常见的处理策略:

策略做法适用
滑动窗口只保留最近 N 轮短对话、无状态任务
摘要压缩把早期对话总结成摘要长对话、需要保留主旨
外部记忆把历史存到数据库,按需检索需要长期记忆的助手

不要把"全量历史"无脑塞进上下文。很多任务只需要当前这一步的相关信息,过多的历史反而让模型分心,还增加成本。

何时该用、何时不该用 Agent

Agent 不是万能的,它的代价是:不可控、慢、贵、难调试。判断标准是——这个任务是否真的需要"动态决定下一步做什么"。

适合 Agent不适合 Agent
步骤无法预先确定,要根据中间结果分支步骤固定,只是串起来执行
需要理解自然语言意图再选工具输入结构固定,分支明确
任务开放式,可能需要多轮探索简单的数据提取或转换

很多看起来"需要 Agent"的场景,其实用一个固定流水线(先检索 → 再让模型总结)就够了。固定流水线可控、可测、便宜;Agent 应该作为"当流水线不够用时"的升级,而不是默认选择。

失败模式

Agent 会以几种典型方式失败,设计时要提前考虑:

  • 循环调用:反复调用同一个工具却拿不到想要的结果,空转直到步数上限。需要检测重复调用并强制终止。
  • 幻觉工具调用:模型编造一个不存在的工具,或给真实工具填了不合法的参数。框架必须校验工具名和参数,校验失败要反馈给模型而不是直接报错。
  • 过度行动:本该先确认就执行了有副作用的操作(发邮件、删数据)。有副作用的动作必须有人工确认或独立权限层。
  • 上下文污染:工具返回的结果里夹带了注入指令,影响模型后续判断。工具返回也应当作不可信数据处理。

务实的设计清单

  • 是否设定了最大步数和重复调用检测?
  • 每个工具的 description 是否说清了使用时机?
  • 有副作用的工具是否有人工确认或权限校验?
  • 上下文是否会无限增长,有没有压缩或清理策略?
  • 这个任务是否真的需要 Agent,还是固定流水线就够?

Agent 的价值在于把模型的"理解与规划"能力和外部系统的"确定性执行"能力组合起来。把它用在真正需要灵活性的地方,其余地方用更简单可控的方式,整体系统才会稳。

为复用而记录,为理解而整理。