最近在做项目重构时,我反复琢磨一件事:单个大模型Agent究竟能承担多少复杂任务?事实证明,一旦任务需要“收集信息、交叉验证、撰写方案、审核纠错”等多类工作并行,单体Agent很快就露怯了。我最初把一个内部调研工具做成单Agent方案,结果输出的内容要么结构漂亮但缺少事实支撑,要么细节堆砌但结论飘忽。后来我把它重构为多智能体协作系统,代号就叫“agency-agents”——字面意思是“代理事务所”,实际是一组各司其职的Agent以团队方式协同完成复杂任务。
这篇文章就是把我在设计这套系统时的思考、架构选择、踩坑过程和最终验证的方案写出来。如果你是做AI应用开发、想从单Agent往多Agent方向走,或者正在头疼“多个Agent怎么协作才不会乱”,这篇文章应该能给你一些可复用的经验。我会尽量讲清楚每一步背后的原因,而不是只扔出一堆配置。
1. 从单兵作战到组建Agent团队:为什么“代理事务所”模式更实际
1.1 单体智能体的天花板:角色冲突与上下文撕裂
单个Agent看似能用一套系统提示词应对所有问题,但实际跑下来你会发现,复杂任务对单Agent来说至少有三个难以逾越的障碍。
第一个障碍是“角色冲突”。当一个Agent既要扮演信息收集员、又要扮演数据分析师、还要扮演报告撰写人,它在同一段上下文里会反复切换立场。比如我让单Agent写市场调研摘要,要求它“先查数据再给结论”,它经常在前半段表现得像严谨的分析师,到后半段就开始用“综上所述”“业界普遍认为”这类空泛表达带过,因为没有独立角色去盯住“事实边界”。模型在长上下文里会逐渐遗忘最早的角色约束,越到后面越容易“放飞”。
第二个障碍是上下文撕裂。一次复杂任务往往要经过检索、筛选、归纳、推理、润色等多个步骤,每一步的中间结果都会堆积在上下文窗口里。单Agent从头到尾背着这些历史负担,不仅Token消耗大,早期信息还会被后续内容稀释。我实测过一个需要阅读十篇文章再输出的任务,单Agent跑到第三轮时已经记不清第一篇文章的结论,最后报告里居然出现了自相矛盾的数据。
第三个障碍是质量无法自校验。单Agent的反思机制——让模型自己检查自己的输出——在实践里效果有限。它很难发现自己在“假设”和“事实”之间划等号的问题,因为整个推理路径都在同一套内部表征里,缺少真正的外部视角。
这些障碍让我意识到,与其把一个Agent做成“全能选手”,不如把它拆成一组“专业岗位”,让每个Agent只负责一小块擅长的事,再通过流程把它们串起来。“agency-agents”这个项目的起点,就是一次彻底的角色拆分实验。
1.2 “代理事务所”的隐喻:把Agent当作有岗位说明书的员工
“agency-agents”在设计上借鉴了咨询事务所的组织方式:一个项目由项目经理牵头,下面有不同的分析师、资料员、审核员,每个人分工明确,产出物彼此衔接,最终由项目经理统一打包交付。
落到系统层面,我定义了三类基础角色:
- 协调者:负责拆解任务、给其他Agent派单、检查进度和汇总结果。它不做深度分析,只做流程管理和结果装配。
- 领域专家:负责具体环节,比如资料检索Agent、数据提取Agent、方案撰写Agent。每个专家只接受与自身领域相关的输入,输出被严格限定为结构化中间件。
- 质检员:负责审核专家产出,检查事实引用、数值一致性、输出格式等,发现问题就把任务打回重做。
这个隐喻最大的价值是让你在设计时不再问“怎么让一个Agent变聪明”,而是问“这个岗位的职责边界在哪里”“它需要哪些输入和工具”“它交付出什么才算是完成任务”。一旦想清楚这些问题,系统架构就清晰了大半。
2. 拆解“agency-agents”的系统骨架:角色、编排与通信
2.1 角色定义:岗位说明书比提示词更重要
很多人在多Agent系统里犯的第一个错,是给每个Agent写一大段语气词丰富的提示词,却没有明确“职责边界”和“禁止行为”。结果就是多个Agent都觉得“这事归我管”,互相抢活或互相推诿。
我在项目里给每个Agent配置的不只是系统提示词,而是一份结构化的“岗位说明书”,核心字段包括身份、职责范围、工具白名单、输入输出格式和红线禁止项。以资料检索Agent为例:
AGENT_SPEC = { "name": "info_retriever", "role": "资料检索与初步筛选", "responsibilities": [ "根据任务卡中的检索需求,从指定数据源获取资料", "对资料按主题进行粗分类", "输出检索结果清单,附来源标识" ], "forbidden": [ "不得对资料内容做价值判断", "不得撰写最终分析结论", "不得修改数据源数据" ], "tools": ["internal_search", "doc_parser", "url_reader"], "input": "任务卡 + 检索关键词列表", "output": "JSON 格式的结果清单,含来源与摘要字段" }这样做有两点好处:一是每个Agent的系统提示词简短清晰,模型不容易在长上下文里丢失自己的职责;二是“禁止行为”能在运行层面被拦截,即使模型“越权”产生了其他内容,协调者这一侧也能根据输出格式直接判定失败,而不是继续把错误结果往下游传。
还有一个经验是“岗位要窄而深,不要宽而浅”。初期我图省事,把一个Agent既当检索员又当审核员,结果它输出结果时经常顺手把自己检索到的错误信息“审核通过”。后来把职责完全拆开、让审核员看不到检索员的中间推理,质量问题明显收敛。
2.2 编排内核:固定流程做骨架,动态决策填分支
确定好角色之后,面临的第二个问题是:谁来决定Agent的执行顺序?
我把编排方式分成三种,并逐一做了验证。
第一种是固定管线。任务步骤预先写死:先检索,再提取,再分析,最后汇总。优点是执行过程可预测、容易调试;缺点是遇到边界情况时缺乏应变。比如某次检索阶段没有找到预期资料,固定管线依然会继续往下走,导致后续分析建立在空结果上。
第二种是完全自主协商。让协调者Agent自由决定派哪些Agent、按什么顺序协作,期待它能像人类项目经理一样随机应变。实测下来,这种模式在小规模、低风险任务上表现惊艳,但一旦任务步骤超过四五个,协调者很容易陷入“反复开会但不出结论”的死循环,Token消耗也会失控。
第三种是混合编排,也是我在agency-agents里最终采用的模式:用固定流程做骨架,在关键分流点插入动态决策。例如“检索阶段”必须顺序执行,但“检索结果是否满足任务需求”由协调者动态判断,不满足则触发补充检索分支,满足则进入下一环节。
混合编排的好处是:流程的主体结构可控,动态决策只发生在少数节点,既不像固定管线那样僵化,也不至于让系统完全失去约束。实现上也不复杂,本质上就是给协调者一套有限状态集合,它只能在预设状态之间切换,不能凭空创造新的流程。
2.3 消息与共享工作区:避免传话失真
Agent之间怎么交换信息,是决定协作质量的核心细节。我最早采用“直接对话”的方式:协调者把上游Agent的输出文本,原封不动塞进下游Agent的消息里。结果很快发现了问题——Agent之间的“对话”并不是逐字传递,而是在每次调用时重新编码,经过两三轮之后,信息就开始变形。
举个具体例子:资料检索Agent输出“2023年市场规模约120亿元,来源是某行业报告”,但这段文本经过协调者重新拼接给分析Agent时,被改写成了“2023年市场规模约120亿,某报告指出”,等到最终报告里就变成了“市场规模达120亿”。单位、限定词、来源标识都在“传话”过程中丢失了。
后来我引入了“共享工作区”机制:所有Agent的中间产物都按照固定Schema写入一个统一的工作区,下游Agent不依赖上游的对话消息,而是直接读取工作区里的事实记录。Agent之间传递的不是整段答案,而是“任务卡”和“引用指针”。
以任务卡为例:
{ "task_id": "T-2026-0042", "current_stage": "extraction", "input_refs": ["workspace/retrieval/2026-03-12/result_a.json"], "output_schema": "fact_table", "quality_rules": ["数值需带单位", "每条记录附来源"] }这样做之后,信息传递从“自然语言重述”变成了“结构化引用”,各Agent只会读取它需要的字段,不会把无关内容带进自己的上下文。这是整个系统稳定性提升最大的一步改造。
3. 让Agent真正“干活”的关键设计:工具、记忆与校验
3.1 工具调用标准化:把API变成Agent的“手”
一个只会“聊天”的Agent不是好的团队成员。真实工作中,Agent必须能调用搜索引擎、读取文档、查询数据库、写入结果。我在项目里定义的接入规范是“JSON调用”方式,每个工具暴露一个标准化接口,模型通过结构化参数发起调用。
举个例子,内部资料库查询工具的接口长这样:
{ "tool_name": "internal_search", "input_schema": { "query": "string", "filters": {"date_from": "string", "date_to": "string"}, "limit": "number" }, "output_schema": { "results": [{"title": "string", "url": "string", "snippet": "string", "date": "string"}] } }工具调用标准化带来的直接收益是“可审计”。每个Agent用了哪些工具、传入了什么参数、拿到什么结果,都能被记录下来。后续做错误排查时,不需要猜模型脑子里在想什么,直接看调用日志就能还原链路。
还需要给每个工具加上“权限最小化”约束。资料检索Agent只能调用查询类工具,没有写入权限;方案撰写Agent只能读取分析结果库,不能直接改原始数据。这不是因为Agent“不可信”,而是为了限制出错时的爆炸半径——一旦某个Agent行为异常,它最多污染一块局部数据,不会把整个工作区弄乱。
3.2 共享记忆与上下文压缩:不让Agent“选择性失忆”
多Agent系统的另一大痛点是上下文管理。每个Agent在处理任务时,既需要了解自己的局部信息,也需要知道项目全局进展,但把所有历史都塞进上下文既不经济也不稳定。
我在agency-agents里做了两层记忆管理。
短期记忆使用“执行轨迹”记录。协调者每派发一个子任务,就生成一条轨迹日志,包含任务描述、输入引用、输出引用、耗时和Token消耗。系统运行时,协调者只保留最近几条轨迹,更早的内容会被摘要化。
长期记忆使用“知识沉淀”机制。当某个任务的结论通过质检后,系统会把它作为可复用的“经验条目”存入知识库。下次遇到相似任务,协调者可以把相关经验摘要作为参考输入。这套机制解决的是“团队记忆”问题:单个Agent不需要每次都从零开始理解背景,因为系统本身已经记住了一部分历史沉淀。
上下文压缩是我实验下来最有效的一招。早期我把检索Agent返回的完整原文都传给下游,结果一条检索结果几千字,三五个结果就把上下文撑爆了。后来改成每个结果只传200字以内的摘要和来源标识,最终报告需要细节时再按需回查原文。同一轮任务,改造前大约消耗2.6万Token,改造后降到5000左右,且输出质量没有下降。
因为模型在被压缩后可以获得更集中的信息密度,那些与结论无关的噪声文本被过滤掉了,反而更容易抓住重点。
3.3 结果校验:必须设置“第二双眼睛”
我一开始对多Agent系统的质量校验过于乐观,以为每个Agent各司其职就不会出错。实际跑了几轮发现,每个环节的误差会累积,检索阶段的错误事实没有被拦截,分析阶段就会在错误基础上继续推理,最终生成的报告看起来“逻辑自洽”但根子已经歪了。
解决办法是引入独立的质检Agent。注意,质检Agent不是“让同一个模型重新读一遍结果”,而是拥有独立的系统提示词、独立的工具调用和独立的工作流程。它不做内容生产,只做四类检查:
- 完整性检查:输出是否符合预设Schema、是否有必填字段缺失。
- 一致性检查:同一数据在不同位置出现时,数值和单位是否一致。
- 来源检查:关键结论是否都有对应的来源标识,没有来源的断言是否被明确标记为“推测”。
- 边界检查:输出内容是否超出了该Agent被允许负责的范围。
检验一旦发现异常,质检Agent会生成一条异常单,写明问题类型和所在字段,把任务退回给负责该环节的Agent重新处理。和“自我反思”相比,这种“他人评审”的最大价值在于评审过程和完成任务是两个独立推理通道,模型不会因为沉浸在原任务里而对自己产出的问题视而不见。哪怕底层用的是同一个大模型,两条独立推理路径得出的判断也要可靠得多。
4. 实操踩坑实录:我在多Agent协作中遇到的五个典型问题
4.1 问题一:Agent互相踢皮球或重复抢活
第一次做角色拆分时,我给“协调者”和“分析起草者”都在提示词里写了“负责全局统筹”和“负责输出最终报告”,结果跑出来的流程极其难看:协调者把自己的活下派给分析起草者,分析起草者又在汇报里写了“建议由协调者统一汇总”,一轮任务下来,两个Agent除了互相客气地“确认”之外,没有任何实质产出。
排查链路:我起初怀疑是模型能力不够,后来把两个Agent的输入输出日志各自打印出来,才发现在系统提示词层面就存在职责交叉。修复方案是让Agent的职责描述形成“互斥关系”,每个角色明确“负责什么”和“不负责什么”,并且在任务卡里写清楚当前环节的唯一负责人。
4.2 问题二:上下文越滚越大,Token消耗失控
项目初期,我设计的是“把所有Agent的产出都放到共享工作区全文保存”,结果跑了几轮后,协调者每次决策都需要读取全部历史记录,单次任务的Token消耗从几千一路涨到几万,成本直接失控。
排查链路:查看Token明细时发现,大头不是模型推理,而是每次调用都把历史工作区全文拼进了系统提示词。修复方案就是上文提到的上下文压缩:工作区只保留结构化摘要和指针,完整历史归档到外部存储,Agent按需回查。压测后Token消耗下降约70%,任务完成速度也快了。
4.3 问题三:结果不稳定,同样任务两次输出不一样
多Agent链路越长,最终结果越不稳定。我在一次演示任务里连续跑了五次相同输入,居然得到了三份差异明显的结论。最开始我以为是模型温度设置问题,统一改成低温后仍然有偏差。
排查链路:后来跟踪到偏差主要出现在“资料检索Agent”的排序环节。模型对同一批资料,在一次运行里把A资料排在前面,在另一次运行里把B资料排在前面,下游分析就跟着变了。修复方案是让检索结果按固定规则排序(发布时间倒序加相关性加权),并规定分析Agent必须严格按照输入顺序处理资料,不允许自作主张重置优先级。
4.4 问题四:子Agent只能“用嘴说”,不能真正改变运行时状态
初期子Agent之间的协作完全靠“对话文本”,一个Agent说“我把结果写进工作区了”,另一个Agent却读不到任何新数据。本质原因是Agent没有真正操作共享状态的能力,“写入”只是自然语言描述,而不是实际状态变更。
排查链路:我在日志里发现,某次任务中A Agent输出的“已更新任务状态”消息之后,工作区的状态字段仍然是旧值。修复方案是给每个Agent接入“状态变更工具”,所有对任务状态、结果字段的更新都必须通过显式API调用完成。Agent可以说“我建议更新状态”,但真正改变状态的是工具调用记录,不是聊天文本。系统从“对话驱动”切换到“工具驱动”之后,协作变得可靠多了。
4.5 问题五:调试困难,不知道哪一步出了问题
多Agent系统显著增加了调试复杂度,单个链路里只要有一个Agent行为异常,下游所有输出都会跟着异常,而且表面看“格式工整、逻辑通顺”。
排查链路:我后来专门给系统加了一套执行追踪器,记录每个Agent的输入摘要、输出摘要、工具调用列表、耗时和Token消耗,并支持“回放某一次完整执行”。调试时可以直接定位到具体某一轮某个Agent传入的参数,不用再靠肉眼翻日志。这套追踪能力在后期优化作用极大,几乎每次调整系统提示词,我都要先看一眼追踪记录再动手。
下面把这五个问题的修复要点整理成一个速查表:
| 问题现象 | 根因方向 | 关键修复手段 |
|---|---|---|
| 角色互相依赖,没有实质推进 | 职责边界重叠,缺少唯一负责人 | 岗位说明互斥化,任务卡指定唯一owner |
| Token消耗随任务推进飙升 | 全量历史无差别传入下文 | 工作区摘要化,按需回查原始内容 |
| 相同输入多次运行结果漂移 | 检索排序与处理顺序不稳定 | 固定排序规则,强制按序处理 |
| 子Agent口头更新状态但未生效 | 状态变更未与工具调用绑定 | 状态变更必须走显式API,对话文本不算 |
| 出错后定位困难 | 缺少全过程执行追踪 | 引入执行追踪器,记录输入输出摘要与工具调用 |
5. 从Demo到可用:评测、成本控制与迭代节奏
5.1 评测集与任务完成率:先敢于“量”质量
如果你打算认真迭代多Agent系统,评测体系是第一步,而且必须用“完整任务集”而不是几个临时例子来评测。我建立了一个包含20个典型任务的评测集,覆盖简单检索、多源交叉验证、长文档归纳和限定条件生成四类场景。
评测指标我用三层:第一层是任务完成率,指系统是否在限定步数内交付出符合Schema的结果;第二层是要素覆盖率,由评测人员对照参考答案,检查输出中关键论点、关键数据是否齐全;第三层是人工满意度,主要看表达是否通顺、结论能否直接使用。
每次改完任何提示词、编排逻辑或工具参数,我都会把评测集完整跑一遍,防止“修好一个场景,弄坏另一个场景”。这个习惯让项目后期的每次变更都有回归保障,也让我敢大胆调整。
5.2 成本优化:让Agent团队“按需上班”
多Agent系统的成本确实比单Agent高,但不等于不可控。我在项目里做了三类优化,效果显著。
第一是路由分层。不是每个任务都需要动用全部专家Agent。我加了一个前置分类Agent,先判断任务复杂度,简单任务走轻量流程,只调用一到两个Agent;复杂任务才启动完整团队流程。第二是模型分级。不同岗位使用不同规格的模型,简单筛选和格式化工作用轻量模型,推理和综合判断才用高规格模型。第三是中间产物压缩,这个前面详细讲过。
算一笔简单账:一个包含5个Agent的复杂任务,如果所有步骤都用最高规格模型,一次完整执行大约消耗5万Token;通过路由分层和模型分级,同样的任务能降到1.5万Token左右,成本下降幅度超过六成。代价是响应时间略有增加,但完全在可接受范围。
5.3 迭代节奏:先窄后宽,先稳定再追求灵活
多Agent系统最大的风险不是“做不出来”,而是“一上来就想做大而全”。
我的建议是先跑通一个窄场景。比如只做“输入几篇文章,输出结构化摘要”,用两个Agent:一个负责提取,一个负责质检。跑通之后,再逐步增加角色,比如加入检索Agent和汇总Agent。每一步都要保持评测通过,再扩展边界。
等角色足够多、流程相对稳定,再去追求动态编排和灵活决策。我自己就是先固定流程验证了每个环节的质量,然后才把协调者的动态决策节点加进去。如果反过来,一开始就让Agent自由协作,你会发现出了错都不知道该修哪个环节。
我还想强调一个容易被低估的点:日志系统不是事后补救,而是一开始就要设计好。每个Agent的输入输出摘要、工具调用记录、耗时和Token消耗全部落盘,排错的时候这就是你的“黑匣子”。我在agency-agents上最值回票价的一次投入,就是给系统加上了完整的执行追踪能力,后来的每一次调优都离不开它。
多Agent协作本身没有多么玄乎,核心就是那几条朴素的工程原则:角色清晰、通信规范、流程可控、结果可测。很多时候任务跑偏,并不是因为模型不够聪明,而是因为我们没有用工程化的手段去约束它。把这些基础打好,Agent团队的稳定性和实用性会远超你的预期。