
agency-agents这个名字我第一次看到的时候觉得拗口后来才意识到它想说的其实是两件事agent是执行者agency是执行者手里的自主权。很多人搭多智能体系统以为把几个大模型API接在一起就算完事结果跑起来发现要么互相踢皮球要么各说各话最后只能靠一堆硬编码的if else兜底。我这次做了一个内部模拟项目核心就是围绕agency-agents这组概念去重新设计了一套协作框架让每个智能体拥有自己的任务契约、权限边界和生命周期而不是当一个只会听命令行事的函数指针。这篇文章会把整个设计思路、关键协议、踩过的坑和最终的检查清单完整拆出来适合正在做多智能体编排、或者准备从单智能体往多智能体过渡的开发者参考。1. 先想清楚多个LLM调用堆在一起为什么还算不上多智能体系统1.1 大多数人的第一版线性工具链我第一次做类似系统的时候想法很简单既然一个智能体能调工具那让两个智能体分工干活效率不就翻倍了吗实际写出来之后发现它本质上还是一个线性工具链。智能体A做完结果传给智能体BB处理完再传给C每一环都是上一个环节的输出作为下一个环节的输入中间没有任何人拥有决定自己要不要做这件事的权力。这种架构跑几个固定场景没问题一旦任务稍微开放一点就崩。比如你让A去收集资料它在某一步觉得这个数据源不太可靠我应该换个口径但代码里没给它这个选项它只能硬着头皮把不靠谱的数据往下传。这就是缺了agency的典型症状智能体对自己的任务没有ownership它只是一个大模型驱动的文本处理管道。1.2 agency的起点让智能体拥有自己的任务目标那agency这个词到底怎么落地我的理解是一个智能体如果拥有agency它至少要满足三个条件它知道自己被派来做什么而且这个目标不是一段松散的自然语言而是一份可拆解、可检查的任务契约。它对怎么做有选择权可以在边界内自己决定工具调用顺序、信息获取来源、中间结果的取舍。它需要对结果负责也就是干完之后要给出汇报说明自己做了什么、依据是什么、结论的置信度多高。这三个条件缺一个你得到的都是伪多智能体。尤其是第二点很多人不敢给智能体选择权怕它乱来于是做了很多限制最后限制到只剩一个预设路径那跟原来的工具链又有什么区别。1.3 我的判据授权、承诺、汇报三个词后来我给自己定了一套很简单的判据用来快速判断一个设计到底是真的多智能体还是套壳工具链维度工具链式的伪智能体有agency的智能体任务来源上游代码直接调用通过任务单派发智能体可确认可拒绝决策权无路径固定在权限范围内自主选工具、选顺序目标理解只拿到一段prompt持有结构化任务契约结果交付返回值结构化汇报单含结论、依据、置信度责任边界模糊出问题找主流程清晰每个结论可追溯到具体智能体这套判据帮助我在设计过程中少走了很多弯路。现在回头看很多号称多智能体框架的项目其实连第二个维度都没做到它们只是把工具调用包装成了智能体这个名字而已。2. 任务契约把你要听话换成你要完成什么事2.1 任务契约应该包含哪些字段任务契约是我在这次模拟项目X里最重要的设计也是整套系统能不能拥有agency的基石。我给每个智能体派活的时候不再直接塞一段自然语言指令而是给一份结构化的JSON任务单。大致长这样{ task_id: task_20240515_001, contract_version: 1.0, goal: { objective: 分析本周客服工单中重复出现的高频问题, success_criteria: [ 问题类别数大于等于3, 每个类别至少包含一次出现频率统计, 最高频问题的处理建议至少给出1条 ] }, context: { attachments: [conversations/2024w20/*.json], reference_docs: [kb/refund_policy.md] }, inputs_outputs: { input_schema: {format: jsonl}, output_schema: {format: json, fields: [category, count, suggestion]} }, permissions: { can_use_tools: [search, read_file, aggregate], cannot_use_tools: [send_email, modify_kb] }, boundaries: { max_steps: 12, timeout_minutes: 15, allowed_data_sources: [kb_docs, ticket_dump] } }这份契约的核心不是格式好看而是它把这个活到底算什么完成提前定义清楚了。尤其里面的success_criteria必须能被函数检查不能是给出合理的建议这种形容词堆砌。我在后面会专门讲这个问题的血泪教训。2.2 权限最小化能做什么、不能做什么要写进契约刚开始做的时候我给每个智能体都配置了同一个工具包心想反正就内部几个工具多点权限没坏处。结果有一次一个做数据分析的智能体在生成报告的时候居然调用了发送邮件的工具差点把草稿报告直接发给客户。从那以后我学乖了权限必须写进契约而且遵循最小化原则。每个智能体只拿到它完成任务必须用的工具其他一概不给。比如分析类智能体只给读文件和聚合统计的权限写总结的智能体只给读摘要和生成报告的权限。这看起来减少了灵活性实际上反而增强了agency——因为权限边界清晰之后智能体可以放心地在自己领域内做决策不用担心误碰不该碰的东西系统也更好管控。2.3 可执行的验收标准而不是模糊形容词验收标准这一项我在第一版系统里吃过非常大的亏。最开始我写的是分析准确、建议合理结果智能体交回来的报告看着像那么回事但细看数据口径全是错的我还找不到理由反驳它。后来我把验收标准全部改写成可编程校验的条件比如每个类别的计数必须等于原始数据中该类别记录的条数、建议必须引用至少一条knowledge base中的条目。这样改动之后校验环节就不再依赖人肉判断了。任务完成后系统会跑一套自动检查脚本逐条打勾全部通过才算任务闭环。这个设计带来的好处是智能体为了通过校验会主动去确保自己的结论有据可依而不是糊弄一段漂亮的文本。3. 分工与委派不是让智能体自由沟通而是让它们按协议协作3.1 三种核心消息任务单、汇报单、仲裁单很多多智能体系统做得乱问题不在智能体本身而在于它们之间通信全靠自然语言对话。几个模型你一句我一句聊起来上下文越滚越长最后谁也不知道最初的目标是什么了。我在模拟项目X里做了两件事一是所有消息都有固定schema二是不允许智能体之间直接对话所有通信必须经过一个消息总线。消息总线上跑的核心协议就三种TaskOrder也就是任务单从协调者发给执行者内容就是前面说的那份契约。Report也就是汇报单执行者完成任务后往回交包含结论、过程摘要、置信度、使用过的工具清单。Arbitrate也就是仲裁单当多个执行者给出冲突结论时由一个专门的仲裁智能体去处理矛盾输出裁决结果。这套协议的优点在于每个智能体不需要理解对话上下文它只需要理解我收到的任务单和我要交的汇报单。这大大减少了上下文污染也让每个步骤都可审计。3.2 委派规则什么时候拆任务拆到什么粒度任务拆分是另一个容易被忽视的问题。太粗了一个智能体扛着巨大的目标不知所措太细了拆出来的子任务比主任务还复杂而且智能体之间的协调成本暴增。我常用的一个经验法则是如果一个任务的完成需要超过3个不同领域的知识或者需要调用超过两类完全不同的工具就应该拆。而且拆分的边界要选在信息交接最少的地方。比如收集用户反馈并总结趋势可以拆成收集反馈和总结趋势两步因为中间交接的就是一批清洗后的文本但如果拆成收集周一反馈、收集周二反馈再合并交接成本就高得多还容易出现口径不一致。拆完之后每个子任务都会生成独立的任务单由协调者统一派发。协调者自己不做具体工作它只负责拆任务、发任务、收汇报、做汇总。这个角色定位很关键如果协调者忍不住自己下场干活系统很快就会乱套。3.3 冲突仲裁两个智能体结论不一致时怎么办多智能体协作中冲突是必然的不是异常。两个智能体用不同的数据源、不同的分析口径得出来的结论可能完全相反。这时候不能简单地把两个结果都塞给用户必须有一个仲裁机制。我在系统里设置了一个专门的仲裁智能体它不直接碰原始数据只看各方的汇报单和它们引用的依据。仲裁的规则也写成了契约首先检查双方的数据源是否都在允许列表内其次检查结论是否满足了原任务的验收标准最后如果双方都满足就按数据新鲜度优先。这套仲裁逻辑在大部分场景下都能快速给出确定性结果不会陷入各说各有理的死循环。4. 生命周期管理用状态机管住智能体的每一步4.1 状态迁移从创建到关闭的完整闭环有agency不等于放任自流。恰恰相反自主权越大生命周期管理越要严格。我为每个智能体实例维护了一个状态机状态迁移路径是固定的状态含义允许迁移idle已创建等待任务ready, closedready已接收任务契约确认开工working, waitingworking正在执行任务reporting, waiting, failedwaiting正在等待依赖资源或上游结果working, timeoutreporting正在生成汇报单closed, failedclosed任务闭环结果已归档终态failed任务失败记录原因closed这个状态机看起来简单但它解决了几个非常实际的工程问题。比如我们可以随时看到整个系统里有多少智能体在干活有多少在空等。空等状态特别重要因为大模型调用经常会因为外部API变慢而被卡住没有状态管理的话这些卡住的任务会悄悄吃掉你的资源。4.2 防止失控最大步数、等待超时和心跳机制再聪明的智能体一旦放飞自我也可能在细节里无限循环。我见过最离谱的一次一个智能体为了确认某个数字反复读取同一个文件读了7遍每次都觉得再读一次更准确。所以状态机里必须带上硬性的熔断参数。我常用的熔断组合是老三样max_steps限制总工具调用次数timeout限制总耗时max_keepalive限制等待外部资源的最长时间。任何一个超限状态直接转failed并且强制生成一份失败报告说明卡在哪一步。有了这个机制之后系统再也不会出现某个智能体半夜还在跑的诡异情况。4.3 会话记忆的边界上下文共享要有红线多智能体系统还有一个常见灾难就是上下文无限制共享。智能体A拿到的一大堆原始文本被原封不动传给BB再传给C整个系统的上下文窗口就这样被迅速塞爆。我在设计里定了三条红线智能体之间的交接信息只能是结构化汇报单不允许直接传原始材料。任何原始材料只能通过工具读取不能塞在任务单里。每个智能体只对自己的任务契约负责不继承上游智能体的完整对话历史。这三条红线一画每个智能体的上下文占用变得很可控token消耗也指数级下降。更关键的是这样每个智能体的推理过程会更聚焦不会被无关信息干扰。5. 可观测性多智能体系统Debug的真正难点5.1 全链路追踪request_id、task_id、agent_id一个都不能少单智能体调试出问题你还能靠打印prompt和response来还原现场。多智能体系统一旦跑起来几十个智能体交错执行靠打印日志早就看不过来了这时候必须有全链路追踪。我实现了一个极简但够用的追踪方案每个外部请求进来时分配一个request_id每次派发任务生成task_id每个智能体实例有agent_id每条汇报单记录它的parent_task_id。这样所有日志都能串成一颗树从根任务一路看到叶子任务每一步谁做了什么、用了什么工具、产出什么结论全都能回溯。5.2 成本账单不能只看总额要看单步消耗多智能体系统的成本比单智能体高一个数量级而且往往高得莫名其妙。如果你只盯着账单总额很难发现是哪个环节在烧钱。我在系统里给每个工具调用都记录了token消耗每份汇报单都会自动附带一个成本摘要包含输入token、输出token、工具调用次数、耗时。有一段时间我发现资料收集这个步骤的费用从每单两毛涨到八毛查追踪日志才发现某个数据源API返回的报文结构变了智能体为了从里面提取信息反复重试了好几次。如果只看总额这种问题根本发现不了。5.3 复现问题固定快照与回放机制多智能体系统的另一个难题是不确定性。同样的输入大模型每次的输出都不一样出问题之后想复现非常困难。我做了一个笨但有效的办法每个任务完成后把整个执行轨迹快照存下来包括任务契约、工具调用列表、每轮的模型输出、最终汇报单。当某个任务结果异常时我可以拿着快照做回放把每一步重新跑一遍。虽然回放时模型的输出未必一模一样但至少能定位到问题是出在工具返回异常、任务契约模糊、还是仲裁逻辑有bug。有了这个机制排查效率提升非常明显。6. 我踩过的几个大坑和一份可以直接抄走的检查清单6.1 让一个智能体总览全局结果上下文直接爆掉第一版系统里我天真地设计了一个总统智能体让它在最高层统揽所有子任务的结果汇总成最终报告。结果这个智能体收到的上下文越来越大最后还没干到一半就报上下文长度超限。后来我把这个总览全局的职责删掉了改成让每个子任务在汇报单里自带summary再由一个专门的汇编者只读取这些summary生成最终报告压根不看原始材料。这个改动之后系统再也没出现过上下文超限的问题。这件事给我一个很深的教训多智能体系统的信息流设计优先级永远高于让单个智能体变聪明。6.2 过度委派一个任务被反复转手踢皮球踢到最后没人干第二个坑是过度委派。我当时觉得把任务拆得越细并行度越高效率就越高结果拆得过碎之后很多子任务之间出现依赖关系智能体A在等BB在等CC又在等A补数据直接死锁。而且任务转手多了之后每个智能体都觉得自己只是其中一个环节对最终质量完全不上心。我后来加了两个约束一是禁止嵌套委派超过两层二是每个任务单必须声明最终验收人。这样一来任务的归属感强了很多死锁问题也基本绝迹。6.3 验收标准写合理等于没有验收这个坑前面提过但还是值得拿出来单说。你给智能体写给出合理的建议它会觉得自己写得特别合理然后交上来一段正确的废话。你必须把验收标准写成可以机器检查的布尔条件比如每个建议必须包含可执行的操作步骤、操作步骤必须引用具体的内部文档ID。我甚至把验收标准当成任务契约里最重要的字段因为它直接决定了智能体的行为边界。验收标准写得越具体智能体的自由度反而越有意义——它知道目标是什么剩下的路径选择才是真正的自主决策。6.4 一份可以直接拿去用的检查清单最后把我这次项目里沉淀下来的设计检查清单放在这里每做一个新的智能体角色我都会拿它过一遍[ ] 这个智能体有独立的task_id吗它知道自己要完成什么目标吗[ ] 它的任务契约里success_criteria是否全部可以被函数检查[ ] 它有明确的permissions列表吗已经做到最小化了吗[ ] 它和上下游智能体之间交接的是结构化汇报单还是未经加工的原始数据[ ] 如果多个智能体结论冲突是否有既定的仲裁流程[ ] 它被max_steps和timeout约束住了吗状态异常时能自动失败吗[ ] 它的每次关键行为都会写入trace日志吗成本能按单步回溯吗[ ] 它能直接或间接地看到原始上下文吗是否符合上下文隔离红线这份清单我每次设计新角色都用已经帮我避免了好几次看起来很美跑起来就废的尴尬情况。做完整套模拟项目X之后我最大的感受是agency-agents里那个agency不是给智能体的自由而是给它的责任。你要让它拥有自主决策权就必须同时给它清晰的目标、明确的边界和可检查的产出。这四样东西缺一不可少一样系统不是变得死板就是变得失控。如果你也在做多智能体系统我建议你先别急着选框架、写流程找张纸把你每个智能体的任务契约和验收标准写出来很多问题在这一步就已经暴露了。