
1. 从agency-agents这个标题说起一个多智能体协作框架的完整拆解第一次看到agency-agents这个标题的时候我脑子里蹦出来的第一个念头是这大概率是一个围绕代理和智能体做文章的项目而且从命名习惯来看它多半不是单指某一个agent而是一整套agency级别的体系——也就是说它关注的不是单个智能体怎么跑而是一群智能体怎么组织、怎么分工、怎么协作。这个判断不是拍脑袋来的。做过智能体相关项目的人都知道单个agent能做的事情其实很有限给它一个prompt它调用几个工具返回一个结果流程就结束了。但真实业务场景里几乎没有哪个需求是一问一答就能解决的。比如你要做一个自动化的市场调研需要有人负责搜集信息、有人负责清洗数据、有人负责分析、有人负责写报告、还有人负责审核。这一整套流程靠一个agent硬扛要么prompt长到爆炸要么中途就开始胡言乱语。所以agency这个词才是关键——它暗示的是一种组织化的智能体架构。我打算把这篇文章写成一份完整的项目拆解笔记从设计思路、核心机制、实操落地到踩坑排查全部摊开来讲。适合谁看如果你正在做多智能体编排、任务自动化、或者想把自己手头的一堆脚本升级成能自己干活的小团队那这篇内容应该能帮你省下不少试错时间。如果你只是刚听说智能体这个词也没关系我会尽量用生活化的类比把每个概念讲清楚。2. 项目整体设计与思路拆解2.1 为什么是agency而不是agent先把这个最核心的命名逻辑讲透。单个agent的架构本质上是一个感知-决策-执行的循环接收输入思考下一步调用工具拿到结果再思考直到任务完成。这个模式在简单任务上很好用但一旦任务复杂度上来就会遇到三个绕不过去的坎。第一个坎是上下文窗口的物理限制。一个agent要处理完整流程就得把所有中间结果都塞进上下文里。搜集的资料、清洗后的数据、分析结论、草稿、修改意见……这些东西叠加起来很容易就超出模型能承受的长度。一旦超了要么截断丢信息要么压缩丢细节两种结果都很难受。第二个坎是角色冲突。让同一个agent既当创作者又当审核者它在审核自己的产出时往往会倾向于认为我写得挺好这就是所谓的自我评估偏差。人也是这样自己写的方案自己审很难挑出毛病。第三个坎是错误传播。单agent流程里如果中间某一步推理错了后面所有步骤都会基于这个错误继续往下走而且很难定位到底哪一步出的问题。agency的思路就是针对这三点来的把一个大任务拆成若干子任务每个子任务交给专门的agentagent之间通过明确的接口传递信息。这样一来每个agent的上下文只需要装自己那部分内容窗口压力小了创作者和审核者分开评估更客观某一步出错也能快速定位到具体是哪个agent的问题。打个比方单agent像是一个什么都干的自由职业者多agent agency就像是一家小公司有销售、有设计、有开发、有质检。公司不一定比自由职业者聪明但处理复杂项目时组织化的分工明显更稳。2.2 核心架构选型编排层与执行层分离在具体实现上这类项目通常会采用编排层执行层的两层结构。这个选择背后有很实际的考量。编排层负责的是谁在什么时候做什么。它维护整个任务的状态决定下一步该唤醒哪个agent处理agent之间的依赖关系。执行层则是每个具体的agent它们只关心我拿到输入该怎么产出输出不需要知道整个流程长什么样。为什么要这么分因为如果让每个agent都感知全局那每个agent的prompt里都得塞进整个流程说明维护起来是灾难——改一个环节所有agent的prompt都要跟着改。分离之后编排逻辑集中在一处agent只需要定义好自己的输入输出契约两边可以独立演进。我见过不少项目一开始图省事把所有逻辑写在一个大prompt里前期跑得挺欢等到要加一个新角色或者调整流程顺序时就发现牵一发动全身最后只能推倒重来。所以这个分层不是过度设计而是被现实教育出来的经验。2.3 通信机制消息传递还是共享状态agent之间怎么交换信息是另一个关键决策点。主流有两种做法一种是消息传递agent A把结果打包成消息发给agent B另一种是共享状态所有agent读写同一个全局状态对象。消息传递的好处是解耦彻底每个agent只需要知道自己上游是谁、下游是谁不关心别人怎么存数据。缺点是当流程变复杂、出现分支和循环时消息的路由逻辑会变得很绕。共享状态的好处是简单直接任何agent都能拿到自己需要的那部分数据适合流程复杂、数据被多方引用的场景。缺点是容易产生隐式依赖——某个agent偷偷改了状态里的某个字段另一个agent莫名其妙就出错了排查起来很痛苦。我的建议是如果流程是线性的、角色数量在五个以内用消息传递更清爽如果流程有大量分支、循环、或者需要多个agent反复读写同一批数据共享状态更实用。很多成熟项目其实是混着用的——主干流程走消息传递共享的上下文比如原始需求、全局约束放在一个只读的状态区里。3. 核心细节解析与实操要点3.1 Agent的角色定义别让prompt变成流水账定义每个agent的时候最容易犯的错误是把prompt写成一份冗长的说明书。我见过一个agent的prompt写了三千多字从项目背景讲到注意事项结果模型执行时反而抓不住重点经常漏掉关键约束。正确的做法是让每个agent的prompt聚焦在三件事上我是谁、我拿到什么、我要产出什么。角色描述要短而准输入输出格式要明确到字段级别。至于项目背景这类信息应该放在编排层统一注入而不是每个agent都重复一遍。举个例子一个信息搜集agent的prompt可以这样写你是信息搜集专员。你会收到一个调研主题和一组关键词。 你的任务是针对每个关键词产出3-5条关键信息点。 输出格式为JSON数组每条包含关键词、信息点、来源类型、可信度评分1-5。 不要做分析不要下结论只负责搜集和整理。注意最后那句不要做分析不要下结论——这是角色边界的硬约束。如果不写模型很容易越界把分析和搜集混在一起导致下游的分析agent拿到的是已经被加工过的信息失去了独立判断的基础。3.2 任务拆解的粒度控制任务拆多细是个需要反复调的手感活。拆得太粗单个agent还是扛不住拆得太细agent之间通信开销剧增而且每个agent拿到的上下文太少反而做不出好判断。我的经验法则是一个agent的职责应该能用一句话说清楚且这句话里不出现并且。如果发现某个agent的职责是搜集信息并且做初步分析那就说明该拆了。反过来如果两个agent的职责高度重叠只是输入格式略有不同那就可以合并。还有一个实操技巧先按最粗的粒度跑通全流程观察哪个环节的输出质量最差或者耗时最长再针对性地拆那个环节。不要一上来就设计一个十几个agent的完美架构那样调试成本高到你会想放弃。3.3 上下文传递的裁剪策略agent之间传递上下文时最忌讳的是全量转发。上游agent产出的所有内容不加筛选地塞给下游会让下游的上下文迅速膨胀而且引入大量无关信息干扰判断。合理的做法是给每个agent定义明确的输入契约只接收它真正需要的字段。比如分析agent只需要搜集agent产出的信息点和可信度评分不需要知道每条信息是从哪个来源类型来的。这种裁剪在编排层完成agent本身不需要关心。提示裁剪策略要写进编排层的配置里而不是散落在各个agent的代码中。否则当你需要调整传递内容时又得满项目找。3.4 失败重试与降级机制多agent系统里某个agent失败是常态不是异常。模型可能返回格式错误、可能超时、可能产出明显不合理的内容。如果每次失败都让整个流程崩掉那这套系统根本没法用。必须设计重试和降级。重试的策略通常是格式错误就重新调用一次并在prompt里强调格式要求超时就缩短输入或者换更快的模型内容不合理就触发一次自我修正调用把问题反馈给同一个agent让它重做。降级则是当重试多次仍失败时的兜底方案。比如分析agent连续失败可以让编排层跳过分析环节直接把原始信息交给报告agent并在报告里标注分析环节缺失。这样至少能产出一个不完整但可用的结果而不是彻底失败。4. 实操过程与核心环节实现4.1 环境准备与依赖梳理动手之前先把依赖理清楚。这类项目通常需要三样东西一个大模型调用接口、一个流程编排的运行时、以及一个存放中间状态的地方。大模型接口这块建议抽象成一个统一的client把重试、超时、日志这些通用逻辑封装进去。不要在每个agent里各写一套调用代码否则后面换模型或者调参数时会非常痛苦。编排运行时如果项目规模不大用简单的状态机就够了不需要上重型的工作流引擎。状态机的好处是逻辑直观每个状态对应一个agent状态之间的转移条件写清楚就行。规模大了再考虑引入更复杂的编排框架。中间状态的存放小项目用内存字典就够但要注意加锁因为agent可能是并发执行的。如果流程需要持久化比如中途要人工介入那就得用数据库或者文件系统。4.2 编排层的核心逻辑实现编排层是整个系统的大脑它的核心逻辑可以概括成一个循环检查当前状态决定下一个要执行的agent调用它处理它的输出更新状态然后进入下一轮。用伪代码表示大概是这样def run_agency(task): state init_state(task) while not state.is_finished: agent select_next_agent(state) if agent is None: break try: result agent.execute(state.get_input_for(agent)) state.update(agent.name, result) except AgentError as e: handle_failure(state, agent, e) return state.final_output这里有几个细节值得展开。select_next_agent不是简单地按顺序取而是要根据当前状态判断哪些agent的前置条件已经满足。比如报告agent必须等分析agent完成后才能启动如果分析还没做就不能选它。state.get_input_for(agent)体现了前面说的裁剪策略每个agent拿到的输入是经过筛选的不是全量状态。handle_failure里包含了重试计数、降级判断等逻辑。这里要注意重试次数要有限制否则一个持续失败的agent会让整个流程卡死。4.3 单个Agent的执行封装每个agent的执行逻辑本质上是构造prompt、调用模型、解析输出三步。但每一步都有讲究。构造prompt时要把角色定义、输入数据、输出格式要求三部分拼装好。输入数据要做序列化通常是JSON格式方便模型理解结构。输出格式要求要写得非常明确最好给出一个示例模型照着示例产出的准确率会高很多。调用模型时要设置合理的超时和重试参数。超时太短会导致正常的长任务被误杀太长会让失败任务拖慢整个流程。我的经验是根据任务复杂度设置简单任务30秒复杂任务可以到2分钟。解析输出时不要假设模型一定返回合法JSON。要先做格式校验失败了就走重试流程。解析成功后还要做一次内容合理性检查比如必填字段是否为空、数值是否在合理范围内。4.4 一个完整的任务流转示例假设我们要做一个竞品调研报告的任务整个流转过程是这样的第一步编排层接收任务初始化状态把调研主题和关键词列表写入状态。第二步唤醒搜集agent。它拿到关键词列表逐个关键词去检索信息产出结构化的信息点列表。编排层把结果存入状态。第三步唤醒分析agent。它从状态里取出信息点列表做归类、对比、提炼产出分析结论。这里要注意分析agent拿到的输入是裁剪过的只有信息点和可信度没有原始来源信息。第四步唤醒报告agent。它拿到分析结论按照预设的报告模板组织内容产出最终报告。第五步唤醒审核agent。它检查报告的完整性、逻辑一致性、是否有明显错误产出审核意见。如果审核不通过编排层会把意见反馈给报告agent让它修改然后再次审核最多循环三次。第六步编排层把最终报告写入输出标记任务完成。这个流程里每个agent的职责都很清晰输入输出都有明确契约任何一步出问题都能快速定位。5. 常见问题与排查技巧实录5.1 常见问题速查表问题现象可能原因排查方向解决思路流程卡住不动某个agent的前置条件永远不满足检查状态转移条件修正条件判断逻辑输出格式频繁错误prompt里的格式说明不够明确查看失败时的原始输出补充示例强化格式约束结果质量差上下文裁剪过度关键信息丢失对比裁剪前后的输入调整裁剪策略保留必要字段流程耗时过长串行执行或某个agent反复重试查看各agent耗时统计并行化无依赖的agent优化重试策略审核环节形同虚设审核agent的prompt太宽松检查审核标准是否具体给出明确的审核清单和判定标准状态数据被意外覆盖多个agent并发写同一字段检查状态更新逻辑加锁或改为消息传递5.2 几个我踩过的坑坑一把编排逻辑写进了agent的prompt里。早期我图省事在搜集agent的prompt里写了搜集完成后请把结果交给分析agent。结果模型真的在输出里加了一句接下来请分析导致解析失败。编排是编排层的事agent只管自己的输入输出这个边界一定要守住。坑二忽略了模型输出的不确定性。同样的输入模型两次调用可能产出格式略有不同的结果。一开始我按固定格式解析遇到一点偏差就报错。后来改成宽松解析——先尝试严格解析失败则用正则提取关键字段再失败才走重试。这样鲁棒性好了很多。坑三审核agent和报告agent用了同一个模型同一个温度。结果审核agent总是倾向于通过报告因为它的审美和报告agent一致。后来我把审核agent的温度调低并且在prompt里明确要求以挑刺的心态审核通过率才回归正常。坑四没有做超时控制。有一次某个agent因为输入过长模型调用一直不返回整个流程挂了半小时。后来给每个agent都加了硬超时超时就走降级流程再也没卡死过。5.3 性能优化的几个实用技巧第一个技巧是并行化无依赖的agent。比如搜集agent和分析agent之间如果有多个独立的搜集任务可以并发执行最后汇总。这能显著缩短整体耗时。第二个技巧是缓存中间结果。如果某个agent的输入没变就没必要重新执行。这在调试阶段特别有用改了下游逻辑时上游结果可以直接复用。第三个技巧是分级模型。不是所有agent都需要用最强的模型。搜集、格式化这类任务用轻量模型就够了分析和审核再用强模型。这样能在保证质量的同时控制成本。第四个技巧是日志要记全。每个agent的输入、输出、耗时、重试次数都要记录。出问题时这些日志就是你的排查依据。我习惯把日志按任务ID分组这样查一个任务的完整流转非常方便。6. 关于这套架构的扩展思考这套agency-agents的架构跑通之后其实可以往几个方向继续演进。一个方向是引入人工介入节点。有些关键决策比如最终报告是否发布可以让流程暂停等人工确认后再继续。这需要在编排层支持挂起和恢复状态。另一个方向是动态调整agent数量。根据任务复杂度自动决定是启动三个agent还是八个agent。这需要一套任务复杂度的评估机制目前还比较依赖人工配置。还有一个方向是agent之间的协商机制。现在agent之间是单向传递上游产出什么下游就接收什么。如果引入双向协商下游可以向上游提出我需要更多细节整个系统的智能程度会更高但复杂度也会大幅上升。我个人在实际操作中的体会是不要一开始就追求这些高级特性。先把最基础的三四个agent跑通把编排、通信、重试这些基础设施做扎实再考虑扩展。很多项目失败不是因为架构不够先进而是因为基础没打牢跑起来到处漏风。最后分享一个小技巧给每个agent起一个简短好记的名字并且在日志和状态里统一使用这个名字。这看起来是小事但当你有十几个agent、排查一个跨多个agent的问题时好记的名字能帮你省下大量脑力。