☰
Agent工程化实战:从七要素到七个决策点的拆解框架
2026/10/8 4:59:33 网站建设 项目流程

1. 从“七要素”到“七个决策点”:为什么 Agent 工程化需要一套拆解框架

1.1 一个真实场景引出的问题

去年下半年我接手了一个内部知识库问答助手的改造项目。最初的需求听起来很简单:让模型能回答公司内部文档相关的问题。我当时的想法也很朴素——把文档切片、做向量检索、拼进提示词、调模型生成答案,一套标准的 RAG 流程走完就收工。上线第一周效果确实还行,但第二周开始,运营同事反馈的问题就变得五花八门:有人问“帮我查一下上季度的报销政策,顺便算一下我这种情况能报多少”,模型检索到了政策文档,却不会做那一步计算;有人问“这个流程走完之后下一步找谁”,模型答得头头是道,但引用的文档其实是两年前的旧版本;还有人连续追问三轮之后,模型把第一轮说过的结论完全忘了。

这些问题单独看都不难,但放在一起就暴露了一个本质:我做的那个东西,严格来说只是一个“检索增强的问答接口”,而不是一个 Agent。它没有决策能力,没有工具使用能力,没有记忆管理,也没有对自身行为的校验。后来我把这套系统推倒重做,引入了工具调用、状态管理和循环控制,才真正把它变成了一个能处理多步任务的智能体。

这段经历让我意识到一件事:Agent 的工程实现,难点从来不在“让模型说话”,而在于“让模型在正确的时机做正确的决策”。而要把这件事讲清楚,光靠“Agent = LLM + 记忆 + 工具 + 规划”这种公式是不够的,因为公式只告诉你组件有哪些,没告诉你这些组件在运行时是怎么协作的、每个环节要做哪些取舍。

1.2 七要素:Agent 的静态解剖

业内比较通用的一个拆解方式,是把 Agent 的构成归纳为七个要素。我把它整理成下面这张表,方便对照理解:

要素作用缺失后的典型症状
大模型(LLM)推理与决策核心系统退化为规则引擎,无法处理开放输入
提示词与角色设定定义行为边界与输出格式输出漂移,格式不稳定,角色混乱
记忆(短期/长期)维持上下文与跨会话知识多轮对话失忆,无法积累经验
工具/函数调用与外部世界交互只能“说”,不能“做”
规划与任务分解把复杂目标拆成可执行步骤面对多步任务直接卡死或乱答
执行循环驱动“思考-行动-观察”反复进行只能单轮响应,无法迭代逼近目标
校验与容错检查结果、纠正偏差错误一路传导,最终输出不可信

这七个要素里,前两个几乎所有做 LLM 应用的人都会碰,中间三个是区分“聊天机器人”和“Agent”的分水岭,最后两个则是决定一个 Agent 能不能上生产的关键。我见过太多项目,前五个要素做得像模像样,一到执行循环和容错就草草了事,结果 demo 惊艳、上线翻车。

1.3 七个决策点:Agent 的动态视角

但光有静态拆解还不够。真正写代码的时候你会发现,七要素是“名词”,而工程实现里你面对的全是“动词”——你要决定什么时候调工具、什么时候停止循环、记忆存什么丢什么、失败了重试几次。这些决策点才是代码里真正要写逻辑的地方。

我把它们归纳为七个决策点:

  1. 意图判定:这一轮输入到底是要闲聊、要检索、还是要执行一个多步任务?
  2. 工具选择:在当前上下文下,应该调用哪个工具、传什么参数?
  3. 循环控制:什么时候继续下一轮,什么时候终止?
  4. 记忆写入:哪些信息值得持久化,哪些用完即弃?
  5. 记忆读取:当前这一步需要召回哪些历史信息?
  6. 结果校验:工具返回或模型输出是否可信、是否需要重试?
  7. 失败降级:当重试也解决不了时,如何优雅地兜底?

七要素回答“系统由什么组成”,七个决策点回答“运行时怎么运转”。前者是架构图,后者是流程图。两者结合,才是一套能落地的工程认知。下面我就按这个框架,把每个环节的实现细节和踩坑经验展开讲。

2. 七要素的工程落地:每个组件到底该怎么写

2.1 大模型选型:不是越大越好,而是越“听话”越好

选模型这件事,新手最容易犯的错是唯参数论。我早期也这样,觉得 70B 一定比 7B 强,闭源旗舰一定比开源强。但实际做 Agent 的时候,模型的核心能力要求跟做纯对话完全不一样。

Agent 对模型的要求,排在第一位的不是知识量,而是指令遵循能力和结构化输出稳定性。因为 Agent 的每一步输出都要被程序解析——你要从模型输出里提取出“调用哪个工具、参数是什么”,如果模型时不时给你加一句“好的,我来帮你查一下”,解析就崩了。

我实测下来的经验是:一个 7B 到 14B 级别、经过函数调用专项微调的模型,在 Agent 场景下的表现,往往比一个没做过工具调用对齐的大模型更稳。原因很简单,前者被训练成“该输出 JSON 就输出 JSON”,后者还保留着强烈的对话惯性。

具体选型时我会看三个指标:

  • 结构化输出成功率:连续跑 100 次工具调用请求,能正确解析的比例。低于 95% 的,基本不能上生产。
  • 首 token 延迟:Agent 是多轮循环,每轮延迟会累加。单轮 2 秒和单轮 5 秒,跑五轮就是 10 秒和 25 秒的差距。
  • 上下文窗口的实际可用性:标称 128K 不代表 128K 都好用,很多模型在超过 32K 之后注意力就明显涣散。我会用“大海捞针”测试实际有效窗口。

提示:不要用同一个模型干所有事。意图判定、工具选择这类结构化任务,用小模型;需要深度推理的规划任务,用大模型。这种“大小模型混用”的架构,成本和延迟都能降一大截。

2.2 提示词与角色设定:把“人设”写成“契约”

很多人写 Agent 的提示词,写的是角色描述:“你是一个专业的客服助手,要热情、耐心……”这种写法对聊天机器人够用,对 Agent 远远不够。Agent 的提示词本质上是一份行为契约,它要明确规定:你能做什么、不能做什么、输出什么格式、遇到什么情况走什么分支。

我习惯把 Agent 的系统提示词拆成五块:

  1. 身份与目标:一句话说清这个 Agent 存在的目的。
  2. 能力边界:明确列出可用工具,以及每个工具的适用场景。
  3. 输出格式规范:用 schema 或示例固定输出结构。
  4. 决策规则:什么情况下直接回答,什么情况下必须调工具,什么情况下要追问用户。
  5. 失败处理约定:工具报错时怎么表述,信息不足时怎么处理。

这里有个反直觉的经验:提示词里“不要做什么”比“要做什么”更重要。因为模型天生倾向于“帮忙”,你不明确禁止,它就会在信息不足时编造、在工具失败时假装成功。我通常会在提示词里硬性写几条禁令,比如“如果工具返回为空,必须如实告知,禁止基于猜测作答”。

2.3 记忆系统:短期靠上下文,长期靠检索

记忆这块,我踩过最大的坑是“什么都想记”。早期我设计了一个长期记忆模块,把每轮对话都摘要存进向量库,结果检索时召回一堆无关的旧信息,反而干扰了当前推理。

后来我调整了策略,把记忆分成两层:

  • 短期记忆:就是当前会话的上下文窗口。这里存的是原始对话和工具调用记录,不做摘要,保证信息无损。但要有窗口管理策略,超出长度就按“保留最近 N 轮 + 保留关键节点”的方式裁剪。
  • 长期记忆:只存三类东西——用户明确表达的偏好、已经确认的事实结论、跨会话需要延续的任务状态。其他一律不存。

判断一条信息该不该进长期记忆,我用一个简单的标准:这条信息在下一个会话里被用到的概率,是否大于它造成干扰的概率。如果拿不准,就不存。宁可少记,不可乱记。

2.4 工具调用:接口设计比模型能力更影响成功率

工具调用失败,很多人第一反应是“模型不行”。但我排查下来,相当一部分失败其实是工具接口设计的问题。

举个例子,我做过一个查询订单状态的工具,参数是order_id。模型经常传进来一个带前缀的字符串,比如 “订单号:12345”,导致查询失败。后来我在工具描述里明确写了参数格式,并且在服务端做了一层清洗,成功率立刻从 80% 出头涨到 98%。

工具设计我总结了几条原则:

  • 参数尽量少而明确:能用一个参数说清就别用三个,能枚举就别用自由文本。
  • 工具描述要写“什么时候用”:不只是写功能,还要写适用场景,帮模型做选择。
  • 返回值要结构化且精简:返回一大坨原始数据,既占上下文又干扰推理,最好在工具层就做裁剪。
  • 错误信息要可读:返回“参数 order_id 格式错误,应为纯数字”比返回一个 500 错误码有用得多,模型能据此自我纠正。

2.5 规划与任务分解:让模型“先想后做”

规划能力是 Agent 处理复杂任务的关键。我的做法是在正式执行前加一个规划阶段:让模型先把任务拆成步骤列表,再逐步执行。

但这里有个陷阱——不是所有任务都值得规划。简单任务强行规划,反而增加延迟和出错概率。我的判断标准是:如果这个任务需要调用两次以上工具,或者步骤之间有依赖关系,就值得规划;否则直接执行。

规划的输出我要求是结构化的步骤列表,每步包含“目标”和“预期使用的工具”。执行过程中,如果某一步的结果与预期偏差较大,允许回到规划阶段重新拆解。这种“规划-执行-再规划”的弹性,比一次性规划到底要稳得多。

2.6 执行循环:Agent 的心脏

执行循环是 Agent 区别于单轮问答的核心机制。它的基本形态是一个 while 循环:模型思考 → 决定行动 → 执行工具 → 观察结果 → 判断是否继续。

这个循环看起来简单,但工程上有几个必须处理的点:

  • 最大轮数限制:一定要设上限,否则模型可能陷入死循环。我一般设 8 到 10 轮。
  • 循环终止条件:不只是“模型说完成了”,还要有程序侧的判断,比如“连续两轮没有新的工具调用”就终止。
  • 每轮的状态记录:把每轮的思考、行动、观察都记下来,既用于下一轮上下文,也用于事后排查。

2.7 校验与容错:决定能不能上生产

这是最容易被忽视、但最重要的一环。校验分两层:输出格式校验和内容合理性校验。

格式校验好做,用 schema 验证就行。内容校验难一些,我的做法是引入一个轻量的“裁判”环节——用另一个模型调用(或者同一个模型的不同提示词)来判断当前结果是否回答了原始问题、是否与已知事实矛盾。这就是业内常说的 LLM as judge 思路。

容错则要设计重试和降级策略。我的默认配置是:工具调用失败重试 2 次,每次调整参数或换工具;重试仍失败则降级为“告知用户当前无法完成,并说明原因”。永远不要让 Agent 在失败时假装成功,这是信任的底线。

3. 七个决策点的实现细节:代码里真正要写逻辑的地方

3.1 意图判定:第一道分水岭

意图判定决定了后续走哪条路径。我的实现方式是用一次轻量模型调用做分类,把输入归到几个预定义类别:闲聊、知识问答、工具执行、多步任务、澄清追问。

这里的关键是分类粒度要适中。太粗,后续逻辑没法分支;太细,分类本身容易出错。我一般控制在 5 到 7 类。

还有一个实用技巧:把意图判定和路由合并。与其先分类再路由,不如让模型直接输出“应该走哪个处理函数”,减少一次信息转换的损耗。

3.2 工具选择:给模型一份“菜单”

工具选择本质是一个受限的选择题。我的做法是把所有可用工具整理成一份带描述的清单,放进提示词,让模型输出工具名和参数。

提升选择准确率的几个手段:

  • 工具数量控制在 10 个以内:超过之后选择准确率明显下降,需要做分组或分层。
  • 给每个工具写正例和反例:明确“这个工具适合什么、不适合什么”。
  • 允许模型输出“无需工具”:否则它会硬凑一个工具来调用。

3.3 循环控制:什么时候该停

循环控制有两个方向:该继续时别停,该停时别继续。

该继续的典型场景:任务还没完成、还有未处理的子目标、上一轮工具返回了需要进一步处理的数据。

该停的场景:任务完成、达到最大轮数、连续无进展、遇到无法恢复的错误。

我实现时会给每轮打一个“进展分”,如果连续两轮进展分为零,就强制终止并返回当前最佳结果。这个机制救过我好几次,避免了无限循环烧 token。

3.4 记忆写入与读取:两个独立的决策

写入和读取要分开设计,这是很多人会混淆的地方。

写入决策:这一步产生了什么值得记住的信息?我的规则是——用户偏好、确认的事实、任务状态三类写入长期记忆,其余只留在短期上下文。

读取决策:当前这一步需要哪些历史信息?我的做法是基于当前输入做一次检索,召回相关记忆,但限制召回数量(一般 3 到 5 条),避免上下文被稀释。

3.5 结果校验:三道防线

我通常设三道校验:

  1. 格式校验:schema 验证,不通过直接重试。
  2. 一致性校验:与已知事实、前序结论比对,矛盾则标记。
  3. 相关性校验:判断结果是否真的回答了问题,用 judge 模型打分。

三道都过,才进入下一轮或返回给用户。

3.6 失败降级:优雅地认输

降级策略我分三级:

  • 一级:重试,调整参数或换工具。
  • 二级:换策略,比如从工具执行降级为知识问答。
  • 三级:如实告知,说明卡在哪一步、需要用户提供什么。

第三级最重要,也最考验产品设计。一个好的失败提示,应该让用户知道“系统尽力了,但确实需要更多信息”,而不是一句冷冰冰的“抱歉,我无法处理”。

4. 常见问题与排查技巧实录

4.1 工具调用成功率低怎么办

先别急着换模型,按这个顺序排查:

排查项检查方法常见问题
工具描述读一遍描述,是否说清了适用场景描述太笼统,模型不知道何时用
参数格式看失败案例的参数格式不匹配,缺清洗层
工具数量数一下当前可用工具超过 10 个,选择困难
提示词是否有明确的调用规则缺少“何时必须调用”的约束
模型能力换一个做过函数调用微调的模型对比模型本身不擅长结构化输出

4.2 循环停不下来

这是最烧钱的问题。我的排查清单:

  • 最大轮数是否设置?没设就是无限循环。
  • 终止条件是否包含“无新工具调用”?只靠模型自述“完成”不可靠。
  • 是否有进展检测?连续无进展必须强制终止。
  • 工具是否返回了空结果导致模型反复重试?空结果要有明确处理。

4.3 多轮对话失忆

先确认是短期记忆还是长期记忆的问题。如果是同一会话内失忆,检查上下文裁剪策略是不是裁太狠了。如果是跨会话失忆,检查长期记忆的写入和召回是否正常工作。

我遇到过一个隐蔽的 bug:长期记忆写入了,但召回时用的相似度阈值太高,导致几乎召不回任何东西。把阈值调低之后立刻正常。

4.4 输出格式不稳定

这是结构化输出的经典问题。三个手段:一是用 schema 约束,二是给 few-shot 示例,三是加格式校验和重试。三者叠加,基本能压到 99% 以上。

注意:格式校验失败后的重试,要把失败原因一起喂回给模型,比如“上次输出缺少 tool_name 字段”,这样它才知道怎么改。

4.5 成本失控

Agent 的成本是乘法级的——多轮循环乘以每轮的模型调用。控制成本的核心是减少不必要的轮次和调用。我的几个做法:意图判定用小模型、简单任务不规划、工具返回精简、记忆召回限量、设置合理的最大轮数。

实测下来,这些优化叠加能把成本压到原来的三分之一左右,而效果几乎无损。

5. 一套可复用的 Agent 工程骨架

把上面的内容串起来,我给出一套我常用的工程骨架,你可以直接照着搭:

  • 入口层:接收输入,做意图判定和路由。
  • 规划层:判断是否需要规划,需要则生成步骤列表。
  • 执行层:循环执行“模型思考-工具调用-结果观察”。
  • 记忆层:负责短期上下文管理和长期记忆读写。
  • 校验层:格式、一致性、相关性三道校验。
  • 降级层:重试、换策略、如实告知三级降级。

每一层都可以独立替换和优化,层与层之间通过明确的数据结构通信。这样设计的好处是,当某个环节出问题时,你能快速定位是哪一层的责任,而不是在一坨耦合代码里大海捞针。

我在实际项目里用这套骨架改造过好几个系统,从知识库问答到自动化流程处理,适配性都还不错。核心不在于骨架本身多精妙,而在于它强迫你把每个决策点都想清楚——Agent 工程的本质,就是把一堆模糊的“让模型自己搞定”,翻译成一个个明确的、可测试的决策逻辑。这件事没有捷径,但一旦想通了,后面就是体力活了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询