☰
LLM Agent增强架构:工具、记忆、规划与协作实战
2026/10/21 5:36:28 网站建设 项目流程

1. 为什么单 Agent 跑不动了:一次线上事故逼出来的架构升级

"LLM Agent 增强架构"这个题目,我不是从技术方案文档里学来的,而是被一次线上事故逼着认真对待的。当时我们维护一个客服场景的智能工单助手,架构非常简单:一个底层模型、几个工具函数、一大段精心编写的系统提示词。上线前两周效果不错,简单查询、知识库问答都能应付,但随着接入的业务类型变多,问题开始密集爆发。

最明显的一次故障是这样的:同一批回归测试集,端到端正确率从最初的 88% 掉到 61%,日均 token 消耗翻了两倍多;用户只要连续追问三四轮,助手就会反复查询同一个订单号;更让人头疼的是,日志里甚至出现幻觉——它明明只调用过查询接口,却声称"已完成退款操作"。第一反应是换更强的模型,但对比测试发现模型版本没变、参数没动,问题依然存在。

接下来两天我们在逐条抓会话日志,才慢慢看明白:不是模型变笨了,是架构撑不住了。具体表现可以拆成五类:

  1. 上下文污染严重。系统提示词、历史对话、工具返回的完整 JSON 全部挤在上下文窗口里。有些工具一次返回几千行原始数据,模型真正能关注到的关键信息被稀释到只剩一星半点,注意力全被无关字段带走。
  2. 工具调用没有约束和状态。接口失败后模型会盲目重试,更糟的是没有统一的参数规范,它偶尔会把参数名拼错,接口报错后又自动"猜"一个参数再调一次。
  3. 完全没有记忆分层。所有信息都依赖"这一次会话窗口",跨会话一律丢失。用户说"我昨天刚查过那张工单",它只能礼貌地请用户重新描述一遍。
  4. 规划能力退化。任务链一旦超过三步,比如"查工单 -> 读历史 -> 匹配方案 -> 生成回执",模型就开始丢步骤,经常查完工单直接给结论,中间的关键校验动作被跳过。
  5. 链路不可观测。出问题只能翻底层日志,根本不知道它为什么在某个节点发起某次调用,不知道每一步花了多少 token,也无法把一次完整决策过程回放出来。

这些现象让我意识到一个重要结论:提示词工程的量已经做到头了。把系统提示词越写越长,只会让模型的注意力更加分散;手动截断工具返回结果,又会破坏下游任务需要的信息。单体助手的模式已经走到瓶颈,必须往"增强架构"方向走。

所谓增强架构,并不是给模型加更多魔法提示词,而是把 Agent 从"单次对话窗口里的即兴演员"改造成"有工具、有记忆、有规划、有分工的稳定团队"。模型仍然是大脑,但大脑需要一副好用的手、一套可靠的记忆系统、一个能列计划再执行的思维方式,以及在不同角色之间协作的通信机制。下面具体拆解这套增强架构的核心内容。

2. 增强架构的四根支柱:工具、记忆、规划、协作

这一章讲思路,也讲原理。整体目标只有一个:让模型在信息不完备、任务多步、外部环境动态变化时,依然能做出可靠决策。四根支柱分别是工具层、记忆层、规划层和协作层,缺一不可。

2.1 工具增强:函数调用协议的工程化

Agent 要真正干活,必须能调用外部系统。但模型不是普通程序,它可能产生幻觉参数、漏传必填字段、在失败后乱猜下一步。工具增强的核心,就是把"让模型看到函数列表并希望它用对"变成"强制按协议调用"。

第一是统一注册中心。所有可被 Agent 调用的能力都注册到一个工具清单里,每个工具声明自己的名字、功能描述、入参 JSON Schema、副作用类型和输出上限。模型看到的不是函数源码,而是一张经过整理的能力菜单。设计上大致是这样:

@dataclass class ToolSpec: name: str description: str input_schema: dict # 用 JSON Schema 描述参数结构 category: str = "read" # read / write / admin max_output_chars: int = 2000 @dataclass class ToolResult: ok: bool data: str token_estimate: int error: str = ""

第二是声明式校验。模型生成参数后,先按 schema 校验再放行。少传字段不给补,乱传字段直接拒绝,把"靠模型自觉"改成"靠校验兜底"。这里最容易被忽略的是枚举值约束。比如"工单状态"如果不限定枚举,模型可能传一个"处理中"而业务系统只认识"processing",白耗一轮调用;在 schema 里全部枚举化之后,非法值在进入上下文之前就被拦截。

第三是结果后处理。工具返回的原始数据不能直接倒进上下文。我当时的强制规则是:原文少于 2000 字符保留完整内容;原文较长则提取关键字段,压缩成结构化摘要;如果摘要仍然很长,就把摘要写入长期记忆,上下文里只放"摘要的摘要"和完整数据的存储地址。需要完整信息时再按地址取回,平时不占窗口。

第四是并行调用。当计划里的多个工具互不依赖时,放进同一个"并行组"一次发出,减少交互轮数。这要求注册中心能判断工具之间的依赖关系,也要求模型生成的计划里带parallel_group字段,否则默认按顺序执行。

顺带强调一个权限细节:写操作默认不放开。工具分类里的read / write / admin不是摆设。write类工具必须由调用方显式放行,admin类默认禁用,执行前还要经过一次人工或规则确认。这个规则在开发期有点烦,但上线后的安全收益非常大。

2.2 记忆增强:把上下文从"一次窗口"变成"分级存储"

模型上下文窗口再大也是有限资源,而且大部分业务信息是一次性的、会过时的。想让 Agent 具备连续性,必须设计三级记忆:

  • 工作记忆:当前任务内的短期上下文,包括计划、已执行步骤、当前状态,跟着任务走,任务结束即释放;
  • 长期向量记忆:历史任务结论、工具返回摘要、用户偏好等内容,向量化后存入检索库,按需检索注入;
  • 结构化状态:用户、订单、项目等业务实体的关键字段,以可校验的状态对象保存,任意时刻可查询、可恢复。

三类记忆的分工很明确:工作记忆负责"当下",长期记忆负责"经验",结构化状态负责"事实"。

写入策略比检索策略更容易被忽略。如果每轮对话都往长期记忆里写,检索噪声会越来越大。我后来总结出只有三类内容值得写入:

  1. 经过确认的结论,比如"该用户是 VIP,偏好电话沟通";
  2. 高价值工具返回的摘要,比如"最新工单状态为待审核";
  3. 反思阶段产出的修正结论。

写入时带上source和timestamp元数据,检索结果注入 prompt 时明确标注"以下信息来自历史记忆,可能已过时,请以实时查询为准"。这一步能有效防止模型把记忆当成实时数据,很多 Agent 回答过时信息的根源就在这里。

2.3 规划增强:从"边想边做"到"先计划再执行"

规划增强的核心是区分两种模式:ReAct 式边想边做和Plan-and-Execute 先计划再执行。

对于单工具、单步问答,ReAct 是最合适的,延迟最低,也不需要引入额外组件。但对于多步业务任务,比如"分析客户投诉规律 -> 查询相关工单 -> 匹配解决方案 -> 生成建议",边想边做的模式会出现问题——模型每一步都要重新阅读全部上下文,走三步丢一步是常态。

Plan-and-Execute 的思路更像人类做项目:先让规划器产出一份计划,执行器按计划逐步执行,反思器在关键节点对比预期和实际输出,必要时修正计划再继续。计划本身可以检查、可以回滚、可以计费、可以并行调度。核心结构是这个样子:

@dataclass class PlanStep: step_id: str intent: str # 这一步想达成什么 tool_calls: list[str] # 允许调用哪些工具 depends_on: list[str] # 依赖哪些前置步骤 status: str = "pending" # pending / running / done / failed

执行器每步只做一件事,完成一步就把结果写回工作记忆,更新结构化状态对象。遇到失败时,把具体错误信息原样抛给反思器,由反思器决定修正当前步骤还是回退到某个历史状态。这里有个重要原则:执行器不要让模型自己决定下一步跑什么,它只能按计划执行。计划的调整权在反思器手里,职责分离才能避免模型越跑越偏。

2.4 协作增强:多 Agent 编排与消息协议

单 Agent 能力有上限,尤其是"既要分析又要生成还要审查"这类任务,一个模型要切换多种角色,提示词互相干扰,输出质量很不稳定。多 Agent 的价值就是把不同能力拆成独立个体,每个个体只做一件事,提示词干净、职责单一,整体一致性由编排逻辑保证。

我在实践中用过三种编排模式,各有适用场景:

  1. 主管-执行者模式:一个主管 Agent 负责任务分配、汇总、最终裁决,多个执行者只负责某个子任务。适合任务边界清晰、需要并发处理的场景。
  2. 流水线模式:上游 Agent 的输出作为下游 Agent 的输入,比如"分析 -> 生成 -> 校验",适合有严格顺序依赖的处理链。
  3. 评审式模式:多个 Agent 分别产出方案,评审 Agent 综合选择最优方案。适合高风险决策,比如投诉升级处理。

比编排模式更容易踩坑的是通信机制。Agent 与 Agent 之间如果直接用自由文本聊天,很快就会变成"聊天风暴",互相踢皮球。我定义了一个基于消息信封的轻量协议:

@dataclass class AgentMessage: message_id: str task_id: str sender: str receiver: str content_type: str # "plan" / "tool_result" / "verdict" / "patch" payload: dict timestamp: int

另外一个关键设计:不要设计成 Agent 之间互发大对象。我在实践中倾向于引入共享白板,所有中间产物统一写到任务状态存储里,Agent 只读写白板,不直接给对方发长文本;消息协议只承载控制信号,比如"步骤二已完成,可以开始步骤三"。这个设计大幅减少了 token 浪费,也让整个过程更方便审计。

3. 落地改造实录:从单体助手到可编排 Agent 系统的关键步骤

前面讲的是框架,这一章说落地。以我们团队实际改造的客服工单助手为例:用户描述工单现象,助手需要查历史工单、匹配解决方案、必要时生成回执。改造分四步推进,每一步都有明确的产出物。

3.1 第一步:盘点工具与副作用,先立规矩

改造第一件事不是写代码,而是把业务侧所有可能被 Agent 调用的能力列出来建清单。我们当时整理了 13 个接口,按风险分了三类:

类别典型例子风险等级默认策略
只读查工单详情、查历史记录、查知识库条目低放开
写操作更新工单状态、提交回执模板中需二次确认
高权限作废工单、修改客户关键信息高默认禁用

随后是为每个工具写 JSON Schema。这一步有几个容易遗漏的细节:必填项校验、枚举值约束、返回字段的裁剪。比如"工单状态"如果不限制枚举,模型可能传"处理中"而系统只认"processing",白耗一轮调用。把所有枚举值写清楚、非法值直接在入口拦截,连发回给模型的报错信息都整理成标准格式,这样模型不会因为一个模糊报错又去瞎猜参数。

只读工具全面放开,写工具一律走"人工确认"回调。开发阶段这个规则确实增加了一些操作成本,但换来的安全边界是值得的。高权限工具在测试环境验证了没问题,也没有放给模型直接调。

3.2 第二步:加入分级记忆,给 Agent 装上长期记忆

初始版本没有任何记忆模块,跨会话信息全部丢失。我们决定先做长期向量记忆加上结构化状态两个部分。

长期记忆的落地方式是:把历史任务中产生的"高价值结论"向量化,存进一个本地可部署的向量检索库,每条记录带元数据source=agent_history和timestamp。新会话进来时先做一次相似度检索,取 top 5 注入 prompt,注入时明确加一行引导语:"以下信息来自历史记忆,可能已过时,请以实时查询结果为准。"这行引导语看起来无关紧要,却能防止模型把昨天的结论当成今天的事实。

结构化状态方面,为每个任务维护一个独立的 JSON 状态对象:

{ "task_id": "T-2025-001", "order_id": "A100123", "current_stage": "matched_solution", "completed_steps": ["extract_order", "fetch_history", "query_solution"], "solution_id": "SOL-77", "need_confirm": true }

任何时刻外部系统都能知道 Agent"现在进行到哪一步"。更关键的是,这个状态对象不由模型自由发挥,统一由一个专门的 updater 函数负责更新。我的体会是:状态字段如果让模型"即兴发挥",用不了几轮就会越写越乱,最后变成第二个不可用的上下文。

3.3 第三步:引入 Planner-Executor-Reflector 循环

单体助手的处理流是"收到问题直接回答"。改造后我们在前面加了一层意图复杂度判定:

  • 单步任务,比如"查询某工单当前状态",走短路径,直接调用工具返回,不经过规划器,延迟最低;
  • 多步任务,比如"分析这个客户最近的投诉规律并生成回复建议",走长路径,规划器先生成 PlanStep 列表。

为什么这么区分?因为我踩过"所有任务都走规划器"的坑。有一段时间连简单查询都会先生成五步计划,又慢又笨。复杂度判定的逻辑其实可以很粗暴:只要任务里命中"分析 / 建议 / 比较 / 跟踪"这类动词组合,就走长路径;否则走短路径。大部分场景够用。

长路径的执行链路是:Planner 产出计划 -> Executor 按依赖顺序执行,每步只做一件事并更新状态对象 -> 工具失败时把具体错误抛给 Reflector -> Reflector 输出结构化反思 -> 修正计划或回退状态。

Reflector 的 prompt 设计是这次改造收益最大的部分。我踩过的坑是直接问"你做得对吗",模型永远会说"做得对"。后来改成强制输出三个字段:

  1. execution_score:0-100 的自我评分;
  2. gap_reason:指出实际结果与目标的差距;
  3. revision_action:给出明确的修正动作,比如"改查 A 工具"或"回退到步骤二"。

结构化反思的效果立竿见影。原因也很简单:开放式提问容易得到含糊回答,强制结构化的反思逼着模型把"哪里不对"和"下一步做什么"说清楚。

3.4 第四步:加上可观测与回放能力

增强架构组件变多之后,最怕变成黑盒。我们的做法是为每个请求记录完整 trace 对象:

@dataclass class TraceStep: step_id: str phase: str # plan / execute / reflect / call_tool tool_name: str = "" input_args: dict = field(default_factory=dict) output_summary: str = "" token_count: int = 0 latency_ms: int = 0 error: str = ""

trace 除了用来排障,还有一个更重要的工作:生成回归测试集。我们把历史真实会话存下来,每当提示词或计划逻辑有改动,离线回放一遍,对比新旧版本在"步骤级正确性"上的差异。这个习惯救了我很多次——prompt 微调不再靠运气,每次改动都能看到量化变化。

线上还加了三道熔断规则:

  • 同一工具连续调用超过 3 次,强制转人工;
  • 单任务总轮数超过 12 轮,强制降级为简单模式;
  • 反思修正超过 2 次仍未改善,停止自我修正并请求人工介入。

熔断不是为了解决所有问题,而是避免在错误的方向上花越来越多的 token 和时间。

4. 实测数据与避坑清单:增强不是越多越好

改造完成后,我们拿原本那批回归集和一周线上抽样数据做了对比。下面的表来自团队内部评估,针对的是"有明确结果可判定"的任务子集。不同业务场景差异会很大,仅供参考。

指标改造前改造后
端到端任务完成率61%84%
平均每任务 token 消耗9.8 万4.3 万
平均交互轮数14.66.2
工具调用有效率58%81%
人工介入率37%11%

几个指标里最值得说的是 token 消耗降了一半——这不是因为换了更便宜的模型,而是上下文不再被工具返回的原始 JSON 塞满。轮数变少则是规划器和并行调用带来的结果:之前模型要在上下文里反复"翻找"信息,现在它执行的是清晰步骤,每步产出都有明确去向。

4.1 避坑清单:这些坑我们花了大量时间才填平

坑一:工具结果全文入上下文。这个问题在改造初期最严重。我们的强制方案是max_output_chars=2000,超出部分先提取摘要,把摘要写入长期记忆。但要注意,摘要本身会有信息损失,所以重要数据要保留完整存储地址,需要时按地址取回,避免"为了省 token 丢了关键字段"。

坑二:反思循环变成重试风暴。引入 Reflector 之后一度出现"修正 -> 失败 -> 再修正 -> 再失败"的死循环,最夸张的一次同一个任务重试了七轮。后来加了两个硬性限制:反思修正次数上限 2 次;每次修正前先对比新旧计划,如果修正动作没有改变任何tool_calls,直接中止。这两个限制让重试风暴基本消失。

坑三:多 Agent 踢皮球。早期做主管-执行者模式时,执行者之间会互相质疑对方的结果,你来我往五六轮,看起来热闹,实际浪费 token。解决办法是规定:主管是唯一裁决者;worker 之间不直接交流,所有争议都写成白板条目,统一由主管在最终汇总时处理。

坑四:记忆写得太勤,检索噪声变大。有一段时间我们把几乎所有工具结果都写进向量库,结果 top 5 检索结果里全是互相矛盾的历史记录,Agent 答非所问。后来改成只写"结论类"内容,写入前做置信度判断,拿不准的不写;检索时增加时间衰减,让越新的记忆权重越高。

坑五:所有任务都走增强链路。前文提过这个坑。全量走 Planner 导致简单问题被复杂化,用户问"今天天气"都要等三秒才回复。最终方案是加前置复杂度分类,只有命中多步任务特征才切换长路径。

4.2 一个容易被忽略的点:评估与回归

增强架构组件多了以后,任何一点改动都可能牵一发动全身。最靠谱的做法不是靠肉眼观察几条对话,而是把历史 trace 转成有"标准答案"的评估集。我们为每类任务定义了步骤级检查点,比如"是否调用了知识库查询接口且参数正确""是否在给出建议前确认过工单状态"。只要改动后步骤级通过率下降,就说明这个改动有问题。

评估集不需要一开始就很大。我们最早只有一百多条,已经能拦住大部分明显退化。关键是持续更新:每两周从线上新 trace 里挑典型场景补充进去,让评估集慢慢从"防止退化"变成"驱动改进"。

最后分享一点个人体会。如果你也在做 LLM Agent,不要一上来就堆多 Agent。先把单个 Agent 的工具协议、分级记忆、规划反思做扎实,这个阶段的效果提升往往已经超过大部分华丽架构。多 Agent 是手段不是目的,我见过不少团队做了五个 Agent 互相聊天,最终效果还不如一个带向量记忆和固定计划的普通助手。另一个小技巧是给 Agent 的最终答复加一道"证据链自检"——让它在输出前先核对结论是否真的链到了工具返回或记忆来源。这个技巧成本很低,但对回答质量的提升非常明显,尤其适合需要追溯来源的业务场景。

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

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

立即咨询