ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

多智能体协作框架agency-agents:架构设计与工程落地实践

多智能体协作框架agency-agents:架构设计与工程落地实践 1. 从agency-agents这个名字说起一个多智能体协作框架的定位第一次看到agency-agents这个项目名我的直觉是这大概率是一个围绕代理agent和代理机构agency概念做文章的多智能体协作框架。拆开来看agency在英文里既有代理机构的意思也有能动性、自主行动能力的含义而agents则是复数形式的代理/智能体。把这两个词拼在一起指向的应该是一套让多个智能体像一家机构里的不同角色那样协同工作的系统。这个判断不是凭空来的。近两年围绕大模型的应用开发已经从单次问答快速演进到让模型自己规划、调用工具、分步执行任务的阶段。单个智能体再强遇到复杂任务也会力不从心——上下文窗口有限、单点能力有短板、无法并行处理子任务。于是多智能体协作成了很自然的方向把一个大任务拆给多个各有分工的智能体让它们像团队一样配合。agency-agents 这个名字恰好踩在这个方向上。需要先说明的是我拿到的项目正文、关键词和摘要描述都是空的所以这篇内容不是对某个具体代码仓库的逐行解读而是基于标题本身、结合多智能体协作这个领域的通用实践做一次完整的拆解和落地推演。我会把如果我要从零搭一个叫 agency-agents 的多智能体协作框架我会怎么设计、怎么踩坑、怎么调优这件事讲透。对于正在做类似事情的人这篇可以直接当设计参考对于刚接触多智能体的读者也能借此建立一套完整的认知框架。适合读这篇的人大概有三类一是想给自己的产品加上多角色协作能力的开发者二是被单个智能体越做越乱困扰、想找结构化方案的人三是对 agent 编排orchestration感兴趣、想了解工程落地细节的技术负责人。下面我会从核心概念、架构设计、角色分工、通信机制、实操步骤、避坑经验几个层面展开尽量把每个为什么都讲清楚。2. 多智能体协作到底解决了单智能体的哪些死结2.1 单智能体的三个典型瓶颈在动手设计 agency-agents 之前得先想明白一件事为什么非要多个智能体单个大模型加几个工具调用很多时候也能跑通任务。我实际做过不少单智能体的项目总结下来它有三个绕不过去的瓶颈。第一个是上下文污染。当一个智能体既要理解用户意图、又要规划步骤、还要执行具体操作、最后还要检查结果时所有这些信息都堆在同一个上下文里。任务一复杂上下文里就混进了大量中间过程的噪音模型很容易忘记最初的目标或者在执行细节时被之前的规划思路带偏。这就像让一个人同时当项目经理、程序员和测试脑子里的角色切换会互相干扰。第二个是能力无法专精。单智能体的系统提示词system prompt往往要兼顾多种能力结果就是每种能力都写得比较泛。你很难让同一个提示词既擅长严谨的代码审查又擅长天马行空的创意发散。提示词越长越全模型对每一条的遵循度反而越低这是很常见的现象。第三个是无法并行与隔离。有些子任务之间没有依赖关系本可以同时做但单智能体只能串行。更麻烦的是一个子任务失败会污染整个上下文导致后续步骤全部受影响缺乏故障隔离。2.2 多智能体带来的四个结构性收益agency-agents 这类框架的价值正是针对上面三个瓶颈给出的结构性解法。我把它归纳成四点收益。职责分离带来的上下文纯净。每个智能体只关心自己那一段规划者只管拆解任务执行者只管干活审查者只管挑毛病。各自的上下文里只有和自己相关的信息噪音大幅减少遵循度自然提升。角色专精带来的提示词优化空间。因为每个智能体只干一件事它的系统提示词可以写得非常聚焦、非常具体甚至可以为每个角色单独调参、单独选模型。便宜的模型干简单的活贵的模型干关键的活成本也能优化。并行执行带来的效率提升。没有依赖关系的子任务可以分发给多个执行智能体同时处理最后汇总。这在批量处理类任务上收益非常明显。故障隔离带来的鲁棒性。某个执行智能体跑挂了不会直接毁掉整个流程编排层可以重试、可以换一个智能体、可以把失败信息交给审查者处理。这种隔离是单智能体很难做到的。理解了这四点后面所有的架构设计其实都是在回答一个问题怎么把职责分离、角色专精、并行执行、故障隔离这四件事在工程上落地。3. agency-agents 的架构骨架编排层、角色层与共享状态3.1 三层结构的分工如果让我来设计 agency-agents我会把它拆成三层编排层Orchestration Layer、角色层Agent Layer、共享状态层Shared State Layer。这三层各司其职边界清晰是整个框架能稳定运行的基础。编排层是大脑负责接收用户任务、决定用哪些角色、按什么顺序调度、处理失败重试、判断任务是否完成。它本身通常也是一个智能体或者是一段确定性的调度逻辑。我的经验是能用确定性代码写的调度逻辑就不要交给模型去决策。比如先规划再执行再审查这种固定流程用代码写死比让模型自由发挥稳定得多。模型只应该用在真正需要判断力的地方比如任务拆解、结果评估。角色层是干活的团队每个角色是一个独立的智能体实例有自己的系统提示词、工具集、模型配置。角色之间不直接互相调用而是通过编排层或共享状态来交换信息。这一点很关键——如果让角色之间随意互相调用很快就会变成一团乱麻调试时根本追不清调用链。共享状态层是公共白板存放任务描述、中间产物、各角色的输出、执行日志等。所有角色读写这块共享区域而不是把信息塞在消息里传来传去。这样做的好处是信息有单一可信来源任何角色都能看到全局进展也方便做持久化和断点恢复。3.2 为什么用共享状态而不是纯消息传递这里我要专门解释一下为什么倾向共享状态而不是纯消息传递因为这是很多人在设计多智能体系统时容易走偏的地方。纯消息传递的模式下智能体 A 把结果发给 BB 处理完发给 C。听起来很清晰但实际跑起来问题很多消息格式要严格约定一旦某个环节格式不对整条链就断了中间结果无法复用如果 D 也需要 A 的输出就得让 A 再发一遍或者层层转发调试时你只能看到一条条消息很难还原当前全局状态到底是什么。共享状态模式则像一块大家都能读写的白板。A 把结果写到白板的某个区域B、C、D 谁需要谁去读。信息只写一次多处复用。调试时直接看白板快照全局一目了然。当然共享状态也有代价——需要处理并发写入的冲突需要设计好状态的结构。但对于 agency-agents 这种多角色协作场景共享状态的收益远大于成本。我通常会把共享状态设计成一个结构化的对象大致包含这几个字段任务目标、任务拆解后的子任务列表、每个子任务的状态待处理/进行中/已完成/失败、每个子任务的产出、全局的执行日志、以及一个当前阶段标记。这个结构用 JSON 或类似格式序列化方便持久化和恢复。3.3 编排层的调度策略选择编排层的调度策略直接决定了整个系统的行为模式。常见的有三种顺序流水线、动态路由、混合模式。顺序流水线最简单规划者拆任务执行者逐个做审查者最后检查。适合流程固定的场景比如写一份报告这种线性任务。优点是稳定可预测缺点是灵活性差。动态路由更灵活编排层根据当前状态动态决定下一步该叫哪个角色。比如执行者报告某个子任务失败编排层可以决定是重试、是换个角色做、还是叫审查者介入。这种模式适合任务结构不确定的场景但调度逻辑复杂容易出 bug。混合模式是我最推荐的主干流程用顺序流水线保证稳定在关键决策点引入动态路由处理异常。比如正常情况按规划→执行→审查走但执行阶段如果某个子任务连续失败两次就动态插入一个诊断角色来分析原因。这样既有稳定性又有灵活性。4. 角色设计一个 agency 里到底该有哪些 agent4.1 核心角色清单与职责边界一个能跑通复杂任务的 agency我建议至少包含这几类角色。注意角色不是越多越好每多一个角色就多一份调度复杂度和 token 成本够用就行。角色核心职责典型工具建议模型档位规划者 Planner把用户任务拆成可执行的子任务无或仅任务管理工具高能力模型执行者 Executor完成具体子任务搜索、代码执行、文件读写等中高能力模型审查者 Reviewer检查产出质量、发现错误无或校验工具高能力模型汇总者 Synthesizer把多个子任务产出整合成最终结果无中高能力模型诊断者 Diagnoser分析失败原因、给出修复建议日志读取高能力模型规划者是整个流程的起点它的输出质量直接决定后续所有环节。我踩过的坑是规划者拆的任务粒度太粗或太细都不行。太粗执行者拿到一个模糊的大任务还是不知道怎么做太细子任务数量爆炸调度开销和 token 成本飙升。我的经验是每个子任务应该是一个执行者能在一次交互内完成、且有明确验收标准的单元。执行者是数量最多的角色可以按领域再细分。比如做数据分析的 agency执行者可以分成数据获取者数据清洗者统计分析者可视化者。细分的好处是每个执行者的提示词和工具集都能高度专精。审查者的价值经常被低估。很多人觉得模型自己产出的东西自己检查就行但实测下来让一个独立的、带着挑刺心态的审查者来检查发现问题的概率明显高于让执行者自查。因为执行者有自己的思维惯性容易对自己的产出过度自信。审查者的提示词要明确要求它假设产出有问题主动找证据而不是看看有没有问题。4.2 角色提示词的写法三个必须写清楚的要素每个角色的系统提示词我建议必须写清楚三件事身份与目标、能力边界、输出格式。身份与目标要具体。不要写你是一个助手而要写你是一个负责把复杂任务拆解成可执行步骤的规划专家你的目标是产出粒度适中、依赖关系清晰的子任务列表。越具体模型越能进入状态。能力边界要明确说不做什么。比如执行者的提示词里要写你只负责完成分配给你的子任务不要尝试规划整体流程不要修改其他子任务的内容。这条极其重要因为模型天然有越界的倾向不明确禁止它就会去干不属于自己的活导致职责混乱。输出格式要严格约定。多智能体系统里角色之间的输出是要被程序解析的格式不对整个流程就断了。我通常要求角色输出结构化的 JSON并在提示词里给出完整的 schema 示例。如果模型经常不遵守格式可以在提示词末尾加一句只输出 JSON不要有任何其他文字效果通常不错。4.3 角色数量与成本的权衡这里分享一个很实际的经验角色数量要跟着任务复杂度走不要一上来就搭一个十几个角色的庞大体系。我见过有人一上来就设计了规划、执行、审查、汇总、诊断、记忆管理、工具路由等七八个角色结果调试了两周还没跑通一个完整任务。原因是角色越多交互路径越多出问题的地方越多而且 token 成本是线性甚至指数级增长的。我的建议是从最小可用集开始规划者 执行者 审查者三个角色先跑通一个简单任务。跑通之后再根据实际遇到的瓶颈逐步增加角色。比如发现执行者经常失败但不知道为什么再加诊断者发现多个执行者产出需要整合再加汇总者。这种渐进式的做法比一次性设计一个大而全的体系要靠谱得多。5. 智能体之间的通信消息格式、状态同步与冲突处理5.1 结构化消息格式的设计角色之间传递的信息必须是结构化的不能是自由文本。我通常设计一个统一的消息信封envelope包含这几个字段发送者、接收者、消息类型、负载payload、时间戳、关联的子任务 ID。消息类型我一般定义几种任务分配、任务结果、任务失败、状态查询、审查意见。每种类型对应不同的 payload 结构。比如任务结果的 payload 里要有子任务 ID、产出内容、执行耗时、使用的工具列表任务失败的 payload 里要有失败原因、错误堆栈、已尝试的方案。为什么要这么细因为编排层需要根据这些结构化字段做决策。比如看到某个子任务失败且错误类型是工具调用超时编排层就知道可以重试如果错误类型是输入格式错误那重试也没用得让规划者重新拆任务。这些判断都依赖结构化的错误信息自由文本是做不到的。5.2 共享状态的并发写入问题前面说了用共享状态但共享状态有个绕不开的问题多个执行者并行写入时怎么避免冲突我的做法是按子任务分区。共享状态里每个子任务有自己独立的区域执行者只写自己负责的子任务区域不碰别人的。这样并行写入时天然不冲突。全局性的字段比如当前阶段整体进度只由编排层写入执行者只读不写。如果确实需要多个角色写同一块区域比如多个审查者都要往审查意见列表里追加那就用追加append而不是覆盖overwrite的语义并且给每条记录带上写入者标识和时间戳。这样即使并发写入也只是顺序问题不会丢数据。5.3 状态同步的时机与粒度状态同步的时机也很讲究。同步太频繁开销大同步太少各角色看到的状态不一致容易做出错误决策。我的经验是在角色切换的边界做同步。也就是说一个角色完成工作、把结果写入共享状态后编排层做一次状态快照然后再启动下一个角色。这样每个角色启动时看到的都是最新的、一致的状态。角色执行过程中不需要实时同步因为它只操作自己那块区域。对于并行执行的多个执行者它们各自完成后分别写入自己的区域编排层等所有并行任务都结束后再做一次汇总同步。这种边界同步的策略在保证一致性的同时把同步开销降到了最低。6. 从零搭一个 agency-agents 的实操步骤6.1 环境准备与依赖选型假设现在要动手实现我会这样准备环境。首先是语言和框架的选择Python 是这类项目的主流选择生态成熟各种大模型 SDK 都有官方支持。编排逻辑可以用纯 Python 写也可以用现成的编排框架但我建议核心调度逻辑自己写因为现成框架的抽象往往和你的具体需求不完全匹配改起来反而更费劲。依赖方面至少需要一个大模型的调用 SDK、一个用于结构化输出的校验库比如 Pydantic 这类做数据校验的、一个持久化方案初期用本地文件或轻量数据库就够。如果涉及工具调用还需要准备各个工具对应的客户端库。配置管理要提前做好。模型 API 的密钥、各角色的模型选择、超时时间、重试次数这些都应该放在配置文件里不要硬编码。我见过太多项目把这些写死在代码里换个环境就要改代码非常痛苦。6.2 定义共享状态的数据结构第一步是定义共享状态。用 Pydantic 或类似工具定义一个状态类包含任务目标、子任务列表、每个子任务的状态和产出、执行日志、当前阶段。每个子任务本身也是一个结构包含 ID、描述、依赖的子任务 ID、状态、产出、错误信息。定义好之后写两个基础方法一个是把状态序列化成 JSON 存盘一个是从 JSON 反序列化恢复。这两个方法是断点恢复的基础一定要在项目早期就做好。我吃过亏——项目做到一半才想起来要支持断点恢复结果发现状态结构设计得不合理序列化出来一堆问题返工成本很高。6.3 实现规划者任务拆解的关键技巧规划者的实现核心是提示词设计和输出解析。提示词里要明确要求它输出一个子任务列表每个子任务包含描述、依赖关系、验收标准。输出用 JSON 格式方便解析。这里有个关键技巧在提示词里给规划者一个拆解原则。比如每个子任务应该能在一次交互内完成子任务之间的依赖关系要显式声明每个子任务要有可验证的完成标准。不给这些原则规划者拆出来的任务质量参差不齐。解析规划者输出时一定要做校验。检查子任务数量是否合理比如超过 20 个就要警惕、依赖关系是否有环、每个子任务是否有描述和验收标准。校验不通过就带着错误信息让规划者重新拆通常重试一两次就能得到合格的结果。6.4 实现执行者工具调用与结果回写执行者的实现相对直接但有几个细节要注意。执行者拿到子任务后要根据任务描述决定调用哪些工具、按什么顺序调用。这里我建议给执行者一个明确的工具使用规范比如优先使用搜索工具获取事实信息代码执行前先检查输入格式。执行完成后执行者要把结果写回共享状态对应的子任务区域并更新子任务状态。如果执行失败要写入结构化的错误信息而不是简单抛个异常。错误信息里至少要有失败原因分类、详细描述、已尝试的方案。这些信息是后续诊断和重试的依据。6.5 实现审查者与汇总者审查者拿到执行者的产出后对照子任务的验收标准做检查。它的输出应该是一个结构化的审查结果通过/不通过、不通过的具体问题、修改建议。如果审查不通过编排层要把问题反馈给执行者重新做或者交给诊断者分析。汇总者在所有子任务完成后启动把所有子任务的产出整合成最终结果。它的提示词要强调保持各部分的一致性消除重复内容确保整体逻辑连贯。汇总不是简单拼接而是真正的整合这一步做不好前面所有工作都会打折扣。6.6 编排主循环的编写编排主循环是整个系统的中枢。它的逻辑大致是初始化状态 → 调用规划者 → 循环处理子任务按依赖顺序无依赖的并行→ 每个子任务执行后调用审查者 → 全部完成后调用汇总者 → 输出最终结果。循环里要处理各种异常执行失败的重试、审查不通过的返工、超时的处理。每个异常处理分支都要有明确的策略和上限比如同一子任务最多重试 3 次整个任务最多运行 30 分钟。没有上限的循环是灾难我见过因为一个子任务反复失败导致整个流程跑了几个小时、烧掉大量 token 的情况。7. 实测中踩过的坑与调优经验7.1 规划者拆任务粒度失控最常见的坑是规划者拆出来的任务粒度不合适。要么太粗执行者拿到分析这份数据这种模糊任务无从下手要么太细把读取文件和解析文件都拆成独立子任务导致子任务数量爆炸。我的解法是在提示词里给出正反例。比如正面例子是计算过去 12 个月的月度销售增长率并生成趋势图反面例子是分析数据太粗和打开文件太细。给了具体例子之后规划者的输出质量明显提升。另外可以在解析阶段做自动检查子任务描述少于一定字数就判定为太粗打回重拆。7.2 执行者越界修改全局状态执行者越界是个隐蔽但危害很大的问题。表现是执行者在完成自己任务的同时顺手改了共享状态里不属于它的区域或者擅自修改了子任务列表。这会导致状态混乱后续角色基于错误状态做决策。解法是在执行者的提示词里明确禁止同时在代码层面做权限控制——执行者只能写自己子任务对应的区域写其他区域直接拒绝并记录警告。提示词约束加代码约束双保险基本能杜绝这个问题。7.3 审查者过于宽松或过于苛刻审查者的尺度很难把握。太宽松问题漏过去最终结果质量差太苛刻什么都通不过执行者反复返工流程卡死。我的调法是给审查者明确的判定标准并且要求它区分必须修改和建议优化两类问题。必须修改的才触发返工建议优化的记录在案但不阻塞流程。这样既保证了质量底线又避免了无限返工。另外可以给审查者设一个通过率的软约束如果它连续判定多个子任务不通过就提示它重新审视标准是否过严。7.4 token 成本失控的排查多智能体系统的 token 成本很容易失控因为每个角色都要消耗 token而且共享状态越大每个角色读取时消耗的 token 越多。排查成本问题我一般先看共享状态的大小。如果状态里堆积了大量中间过程的详细日志每个角色读取时都要把这些日志读进去成本自然高。解法是给共享状态做分层角色默认只读和自己相关的部分全局摘要信息单独维护一份精简版。这样每个角色读取的上下文就小很多。另一个成本大头是重试。如果某个子任务反复失败重试token 消耗会成倍增长。所以要给重试设上限并且每次重试时把之前的失败信息精简后再传给执行者避免上下文越滚越大。7.5 并行执行时的资源竞争并行执行多个子任务时如果它们都要调用同一个外部工具比如同一个搜索接口可能会触发限流。这个坑我在实际项目里踩过多个执行者同时发请求结果被接口方限流全部失败。解法是给外部工具调用加一个统一的限流器控制并发数。另外并行度不要设太高一般 3 到 5 个并行就够了再高收益递减而风险上升。并行度这个参数最好做成可配置的方便根据实际情况调整。8. 这套框架适合什么场景以及后续可以怎么扩展agency-agents 这类多智能体协作框架最适合的是任务结构相对复杂、可以拆解、且对结果质量有要求的场景。比如长文档的撰写与审校、多步骤的数据分析流程、需要多轮验证的代码生成、复杂的信息调研与整合。这些场景的共同点是单次交互搞不定但拆开之后每个子任务都不算太难。反过来如果任务本身很简单比如单轮问答、简单的格式转换那用多智能体就是杀鸡用牛刀徒增成本和复杂度。判断标准很简单如果你用单智能体加几个工具调用就能稳定搞定就不要上多智能体。后续扩展方向我觉得有几个值得尝试。一是引入长期记忆让 agency 能记住之前处理过的类似任务复用经验。二是动态角色生成根据任务类型自动决定需要哪些角色而不是预先写死。三是多 agency 协作让多个 agency 各自负责一块再有一个更高层的编排者协调它们。这些方向都很有意思但每加一层复杂度调试难度都会上一个台阶建议在单 agency 跑稳之后再考虑。最后分享一个我自己的体会多智能体系统的调试比单智能体难得多因为问题可能出在任何一个角色、任何一次交互上。所以日志和可观测性一定要在项目早期就做好。每个角色的输入输出、每次状态变更、每个决策点都要有清晰的日志。我现在的习惯是在编排层加一个回放功能能把一次完整执行的所有交互按时间顺序打印出来。有了这个排查问题的时间能缩短一大半。这个投入绝对值得。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表