资讯动态

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

发布时间:2026/10/24 7:28:05 来源:尧图企业网站定制
1. 从agency-agents这个标题说起一个多智能体协作框架的完整拆解第一次看到agency-agents这个命名的时候我的直觉是这大概率是一个围绕代理和代理机构概念构建的多智能体协作系统。拆开来看agency在软件语境里通常指代代理机构或能动性而agents则是智能体的复数形式。把这两个词拼在一起指向的应该是一套让多个智能体像一家代理公司那样分工协作、各司其职的架构方案。我之所以对这个方向特别感兴趣是因为过去一年多我在实际项目里反复踩过一个坑单个智能体再强面对复杂任务时也会顾此失彼。你让它同时做需求分析、代码生成、测试验证、文档撰写它往往在某个环节掉链子。而agency-agents这个思路本质上是把一个大任务拆成多个角色让每个智能体专注自己擅长的那一块再通过一套协调机制把它们串起来。这就像一家广告公司里客户经理、文案、设计师、媒介采购各管一摊最后交付一个完整方案。这篇文章适合谁看如果你正在做多智能体系统的架构设计或者你手头有一个复杂任务想用智能体来拆解又或者你只是好奇多个AI怎么协作这件事到底怎么落地那接下来的内容应该能给你一些可以直接抄作业的思路。我会从整体设计、核心角色拆解、协作机制实现、常见坑排查这几个维度把agency-agents这类系统的骨架和血肉都讲清楚。2. 整体架构设计为什么是代理机构而不是单打独斗2.1 核心设计思路与选型考量agency-agents这类系统的核心设计哲学用一句话概括就是用组织架构的思维来组织智能体。传统单智能体方案是一个全能选手干所有活而代理机构模式是一群专才各干各的通过流程串联。我选择这种架构的理由很直接。第一上下文窗口是有限资源。单个智能体如果既要记住需求文档又要记住代码规范还要记住测试用例上下文很快就会被塞满导致它在关键决策上失忆。拆成多个智能体后每个智能体只需要关注自己那一块的上下文信息密度更高决策质量更稳。第二专业化提示词的效果远好于通用提示词。你给一个智能体写你是一个资深全栈工程师这种泛泛的角色设定它的输出往往也是泛泛的。但如果你写你是一个专门负责代码审查的智能体只关注边界条件、异常处理和命名规范它的输出会精准得多。代理机构模式天然支持这种专业化分工。第三可观测性和可调试性。单智能体出错时你很难定位是哪一步推理出了问题。多智能体系统里每个智能体的输入输出都是独立的你可以清楚地看到需求分析智能体给出的结论是A但架构设计智能体理解成了B问题定位效率提升一个量级。在方案选型上我倾向于采用**协调者执行者的两层结构**。协调者负责接收原始任务、拆解子任务、分配角色、汇总结果执行者负责各自领域的实际工作。这种结构比扁平化对等协作更容易控制也比纯流水线更灵活。2.2 角色划分的底层逻辑角色划分不是拍脑袋决定的它遵循一个原则按任务阶段划分而不是按技术栈划分。什么意思不要设前端智能体后端智能体数据库智能体而要设需求澄清智能体方案设计智能体实现智能体验证智能体。原因在于按技术栈划分会导致智能体之间的依赖关系变得极其复杂前端要等后端接口后端要等数据库设计协调成本极高。而按阶段划分每个阶段的输出是下一个阶段的输入依赖关系是线性的协调逻辑简单清晰。一个典型的代理机构角色配置如下表角色名称核心职责输入输出协调者任务拆解与调度原始需求子任务列表与分配方案分析者需求澄清与边界定义子任务描述结构化需求文档设计者方案设计与技术选型需求文档架构方案与接口定义实现者代码/内容生成设计方案可运行产物验证者质量检查与反馈产物需求问题清单与修正建议汇总者结果整合与交付各阶段产物最终交付物这张表看起来简单但实际落地时每个角色的提示词设计、上下文管理、输出格式约束都有大量细节要抠。2.3 与单智能体方案的对比实测我做过一个对比实验用同一个任务生成一个带增删改查的完整模块分别跑单智能体和代理机构模式。单智能体模式下首次生成能跑通的概率大概在四成左右主要问题集中在边界条件遗漏和异常处理缺失。代理机构模式下首次生成能跑通的概率提升到七成以上而且代码的可读性和结构合理性明显更好。代价是什么Token消耗大约是单智能体的三到四倍耗时大约是两到三倍。所以这不是一个无脑选的方案而是一个用成本换质量的权衡。如果你的任务足够复杂质量比速度重要那代理机构模式值得上如果只是简单任务单智能体反而更划算。注意不要为了用多智能体而用多智能体。我见过不少项目明明一个智能体就能搞定的事硬拆成五个角色结果协调开销比实际工作还大得不偿失。3. 核心角色拆解与提示词设计要点3.1 协调者智能体任务拆解的艺术协调者是整个系统的入口它的核心能力是把模糊需求拆成可执行的子任务。这里最大的坑是拆得太粗或太细。拆得太粗执行者拿到任务后还是不知道从哪下手拆得太细子任务数量爆炸协调开销剧增。我的经验是每个子任务的粒度控制在一个执行者能在一次交互内完成。具体来说如果一个子任务的预期输出超过两千字或者超过两百行代码就应该继续拆如果少于两百字或者二十行代码就应该合并。协调者的提示词里必须包含几个关键约束。第一明确输出格式要求它输出结构化的子任务列表每个子任务包含任务描述、预期输出、依赖关系。第二明确拆解原则比如按阶段拆解而非按技术栈拆解每个子任务必须有明确的验收标准。第三明确边界告诉它哪些事情不在本次任务范围内避免它过度发散。一个实际可用的协调者提示词骨架大概是这样你是一个任务协调者。你的职责是将用户需求拆解为可独立执行的子任务。 拆解原则 1. 按任务阶段拆解不按技术栈拆解 2. 每个子任务必须能在一次交互内完成 3. 每个子任务必须有明确的输入和输出定义 4. 子任务之间的依赖关系必须显式声明 输出格式 - 子任务编号 - 任务描述不超过100字 - 预期输出具体产物形式 - 依赖的子任务编号无依赖则写无 - 验收标准可验证的条件3.2 分析者与设计者把想要翻译成要做分析者和设计者是两个最容易混淆的角色。分析者负责搞清楚用户到底要什么设计者负责决定我们怎么做。这两个角色如果合并很容易出现还没搞清楚需求就开始设计的问题。分析者的核心任务是消除歧义。用户说做一个用户管理功能这句话里有大量歧义用户有哪些字段需不需要角色权限要不要支持批量操作分析者要做的就是把这些问题列出来并给出合理的默认假设。注意分析者不需要真的去问用户而是基于常见实践给出假设并明确标注这是假设如有不同请指出。设计者的核心任务是把需求翻译成技术方案。它需要决定用什么数据结构、什么接口形式、什么存储方案。这里的关键是设计者不能引入需求之外的东西。我见过设计者自作主张加了缓存层、加了消息队列结果实现者一脸懵。所以设计者的提示词里要明确约束只设计需求文档中明确要求的功能不添加额外特性。3.3 实现者与验证者生成与检查的分离实现者和验证者必须分离这是代理机构模式里最重要的一条原则。让同一个智能体既生成又检查它几乎永远检查不出自己的问题因为它会倾向于认为自己的输出是对的。实现者的提示词要强调严格按设计方案实现不自行发挥。验证者的提示词则要强调以需求文档为唯一标准逐条核对不放过任何偏差。验证者的输出应该是一个问题清单每个问题包含位置、问题描述、严重程度、修正建议。这里有个实操技巧验证者的提示词里要加入对抗性思维的引导。比如告诉它你的任务是找出实现者可能犯的错误假设实现者一定会遗漏边界条件。这种引导能显著提升验证者的检出率。3.4 汇总者最后的把关人汇总者负责把各阶段的产物整合成最终交付物。它的工作看似简单实则不然。它需要处理各阶段产物之间的不一致比如设计文档里说用A方案但实现产物里用了B方案汇总者要能发现并标记这种冲突。汇总者的提示词要强调一致性检查。它需要逐项核对需求文档里的每个需求点在设计方案里有没有对应设计方案里的每个设计点在实现产物里有没有落地实现产物里的每个功能在验证报告里有没有被覆盖4. 协作机制实现让智能体真正对话起来4.1 消息传递与上下文管理多智能体协作的底层是消息传递。每个智能体的输出作为下一个智能体的输入形成一条消息链。这里最大的技术挑战是上下文膨胀。如果每个智能体都把前面所有智能体的完整输出作为输入到第四个智能体时上下文就已经爆炸了。我的解决方案是分层上下文。每个智能体只接收三类信息自己的角色提示词、直接上游的输出、全局共享的任务摘要。任务摘要由协调者维护只保留关键决策和约束长度控制在五百字以内。具体实现上可以用一个共享的状态对象来管理class AgencyState: def __init__(self, original_task): self.original_task original_task self.task_summary # 协调者维护的全局摘要 self.subtasks [] # 子任务列表 self.artifacts {} # 各阶段产物key为子任务编号 self.issues [] # 验证者发现的问题 def get_context_for(self, agent_role, subtask_id): # 只返回该智能体需要的上下文 context { role: agent_role, task_summary: self.task_summary, upstream_output: self._get_upstream(subtask_id), shared_constraints: self._get_constraints() } return context这种设计的好处是每个智能体看到的上下文都是精简且相关的不会被无关信息干扰。4.2 依赖调度与执行顺序子任务之间有依赖关系不能随便乱序执行。我用的是拓扑排序并行执行的策略。先把子任务按依赖关系排成一个有向无环图然后逐层执行没有依赖的子任务并行跑有依赖的等上游完成后再跑。这里有个细节要注意并行执行时多个智能体可能同时修改共享状态。比如两个实现者同时往artifacts里写东西可能冲突。解决办法是给每个子任务分配独立的命名空间汇总时再合并。调度逻辑的核心代码大概是这样def execute_agency(state): while state.has_pending_subtasks(): ready state.get_ready_subtasks() # 依赖已满足的子任务 if not ready: raise Exception(检测到循环依赖) # 并行执行就绪的子任务 results parallel_execute(ready, state) # 更新状态 for subtask_id, result in results.items(): state.artifacts[subtask_id] result state.mark_completed(subtask_id) # 协调者更新任务摘要 state.task_summary coordinator_update_summary(state)4.3 反馈循环与迭代修正代理机构模式不是一次性的流水线而是带反馈循环的。验证者发现问题后要把问题反馈给实现者让实现者修正然后再验证。这个循环要设置最大迭代次数避免无限循环。我的经验是最大迭代次数设为三轮。第一轮通常能解决大部分明显问题第二轮解决边界问题第三轮如果还有问题大概率是需求本身有歧义应该退回给分析者而不是继续让实现者改。反馈循环的提示词设计有个关键点给实现者的反馈必须具体到可操作。不要说代码质量不高要说第23行的异常处理没有覆盖空输入的情况请补充。验证者的输出格式要强制包含位置问题建议三要素。4.4 状态持久化与断点续跑多智能体系统跑起来耗时较长中途可能因为各种原因中断。状态持久化是必须的。每完成一个子任务就把状态序列化到磁盘。下次启动时先检查有没有未完成的状态有的话从断点继续。持久化的粒度要权衡。太粗中断后要重跑很多太细频繁写磁盘影响性能。我的做法是每个子任务完成后持久化一次这个粒度刚好。import json def save_state(state, path): with open(path, w) as f: json.dump({ original_task: state.original_task, task_summary: state.task_summary, completed_subtasks: state.completed_subtasks, artifacts: state.artifacts, issues: state.issues }, f, ensure_asciiFalse, indent2) def load_state(path): with open(path, r) as f: data json.load(f) state AgencyState(data[original_task]) state.task_summary data[task_summary] state.completed_subtasks data[completed_subtasks] state.artifacts data[artifacts] state.issues data[issues] return state5. 实操过程与核心环节实现5.1 环境准备与基础依赖先把基础环境搭起来。我用的是Python 3.10以上版本核心依赖包括一个支持结构化输出的模型调用库、一个用于状态管理的轻量级框架以及一个用于并行执行的线程池工具。不需要太重的框架代理机构模式的本质是提示词编排状态管理用最朴素的工具反而更可控。目录结构建议这样组织agency-agents/ ├── config/ │ ├── roles.yaml # 各角色的提示词配置 │ └── settings.yaml # 全局参数 ├── core/ │ ├── state.py # 状态管理 │ ├── scheduler.py # 调度逻辑 │ └── executor.py # 智能体执行器 ├── agents/ │ ├── coordinator.py # 协调者 │ ├── analyzer.py # 分析者 │ ├── designer.py # 设计者 │ ├── implementer.py # 实现者 │ └── verifier.py # 验证者 ├── runs/ # 运行状态持久化目录 └── main.py # 入口把角色提示词放在配置文件里而不是硬编码在代码里好处是调整提示词不需要改代码方便快速迭代。5.2 角色提示词的参数化配置每个角色的提示词都应该是模板化的支持注入动态参数。我用YAML来管理coordinator: system_prompt: | 你是一个任务协调者。你的职责是将用户需求拆解为可独立执行的子任务。 拆解原则 1. 按任务阶段拆解不按技术栈拆解 2. 每个子任务必须能在一次交互内完成 3. 每个子任务必须有明确的输入和输出定义 4. 子任务之间的依赖关系必须显式声明 当前任务摘要{task_summary} 已完成子任务{completed_subtasks} 请输出下一步的子任务拆解方案。 output_format: json max_retries: 3 verifier: system_prompt: | 你是一个质量验证者。你的任务是找出实现产物中与需求文档不符的地方。 验证原则 1. 以需求文档为唯一标准 2. 逐条核对不放过任何偏差 3. 假设实现者一定会遗漏边界条件 4. 每个问题必须包含位置、描述、严重程度、修正建议 需求文档{requirements} 待验证产物{artifact} 请输出问题清单。 output_format: json max_retries: 3这种配置方式的好处是你可以针对不同项目快速切换提示词模板而不需要动核心代码。5.3 完整执行流程的代码实现把各个模块串起来的主流程大概是这样def run_agency(original_task, config_path): # 1. 加载配置 config load_config(config_path) # 2. 初始化状态 state AgencyState(original_task) # 3. 协调者拆解任务 subtasks coordinator.decompose(original_task, config) state.subtasks subtasks state.task_summary coordinator.summarize(subtasks) # 4. 按依赖顺序执行 max_iterations 3 iteration 0 while state.has_pending_subtasks() and iteration max_iterations: ready state.get_ready_subtasks() for subtask in ready: # 根据子任务类型选择执行者 agent select_agent(subtask.type, config) context state.get_context_for(agent.role, subtask.id) result agent.execute(context) # 如果是实现类任务走验证流程 if subtask.type implementation: issues verifier.check(result, state.artifacts[requirements]) if issues: result implementer.fix(result, issues) state.issues.extend(issues) state.artifacts[subtask.id] result state.mark_completed(subtask.id) save_state(state, fruns/{state.run_id}.json) iteration 1 # 5. 汇总交付 final_output summarizer.aggregate(state) return final_output这段代码的核心逻辑是清晰的拆解、调度、执行、验证、汇总。每个环节都有明确的输入输出方便单独调试。5.4 参数调优与性能实测跑通之后就是调优。我实测下来影响效果最大的三个参数是子任务粒度、验证轮次、上下文摘要长度。子任务粒度前面说过了控制在一次交互能完成的量级。验证轮次我试过1轮、3轮、5轮3轮是性价比最高的5轮之后边际收益几乎为零。上下文摘要长度我试过200字、500字、1000字500字左右效果最好太短会丢失关键约束太长会干扰智能体注意力。性能方面一个中等复杂度的任务比如生成一个包含五个接口的模块代理机构模式大约需要8到12次模型调用总耗时3到5分钟Token消耗在2万到4万之间。这个成本对于质量敏感的场景是可以接受的。提示如果你的模型调用有速率限制记得在并行执行时加一个信号量控制并发数否则容易触发限流导致任务失败。6. 常见问题与排查技巧实录6.1 子任务拆解不合理怎么办这是最常见的问题。表现是执行者拿到子任务后输出质量很差或者输出内容明显偏离预期。排查思路是先看子任务描述是否足够具体。如果子任务描述只有一句话比如实现用户模块那执行者只能靠猜输出质量自然不稳定。解决办法是在协调者的提示词里加入强制约束每个子任务的描述必须包含做什么、输入是什么、输出是什么、验收标准是什么四个要素。缺一个就重新拆解。另一个常见表现是子任务之间依赖关系混乱出现循环依赖。这时候要检查协调者输出的依赖声明是否合理。我的经验是依赖关系超过三层的子任务链大概率是拆解粒度太细了应该合并一些子任务。6.2 验证者漏检问题怎么破验证者漏检是另一个高频问题。表现是实现产物明明有问题但验证者说通过。原因通常是验证者的提示词太温和没有对抗性。我的解决办法是在验证者提示词里加入**红队思维引导**明确告诉它你的绩效取决于你能找出多少问题找不出问题就是失职。同时给它一个检查清单模板强制它逐项核对边界条件、异常处理、输入校验、输出格式、命名规范、注释完整性。还有一个技巧是让验证者分两轮检查。第一轮做需求符合性检查逐条核对需求文档第二轮做质量检查检查代码规范、可读性、健壮性。两轮分开检出率明显提升。6.3 上下文丢失导致前后不一致多智能体系统里后面的智能体不知道前面的决策导致前后不一致这是很典型的问题。比如设计者决定用JSON格式传输但实现者用了XML。根因是上下文传递不完整。解决办法是强化任务摘要的维护。协调者每完成一个阶段就要更新任务摘要把关键决策记录进去。任务摘要要包含已确定的技术选型、已定义的接口格式、已确认的约束条件。我还会在状态对象里维护一个**决策日志**记录每个关键决策是谁在什么时候做的。当出现不一致时可以快速定位是哪个环节出了问题。6.4 常见问题速查表问题现象可能原因排查方向解决措施执行者输出质量差子任务描述太模糊检查子任务四要素是否完整补充子任务描述重新拆解循环依赖拆解粒度过细检查依赖链层数合并子任务减少依赖层级验证者漏检提示词缺乏对抗性检查验证者提示词加入红队思维引导和检查清单前后不一致上下文传递不完整检查任务摘要内容强化决策日志更新摘要任务超时并行度过高触发限流检查并发数设置加信号量控制并发状态丢失持久化粒度太粗检查持久化时机每个子任务完成后持久化Token消耗过大上下文膨胀检查每个智能体的输入精简上下文只传必要信息6.5 几个我踩过的坑第一个坑是过早优化。一开始我就想搞一套复杂的消息总线结果发现根本用不上简单的函数调用就够了。多智能体系统的复杂度应该来自任务本身而不是来自框架。第二个坑是忽视输出格式约束。早期我没强制智能体输出JSON结果它一会儿输出Markdown一会儿输出纯文本解析起来极其痛苦。后来强制所有智能体输出JSON并在提示词里给出schema示例问题就解决了。第三个坑是没有设置超时和重试。模型调用偶尔会失败或返回空结果没有重试机制的话整个流程就卡住了。后来我给每个智能体调用都加了超时和重试稳定性大幅提升。第四个坑是验证者和实现者用了同一个模型实例。虽然角色提示词不同但同一个实例的思维惯性还是会影响判断。后来我把验证者换成独立的实例检出率明显提高。7. 扩展方向与个人实践体会这套代理机构模式跑通之后我发现它的扩展空间比想象中大。一个方向是引入更多专业角色比如专门做性能优化的角色、专门做安全审查的角色。另一个方向是让角色之间支持协商比如实现者觉得设计方案不合理时可以发起一个设计复议流程让设计者重新考虑。还有一个我觉得很有价值的方向是把代理机构模式应用到非代码领域。比如内容创作可以设选题分析者大纲设计者初稿撰写者事实核查者润色者本质上和代码生成是同一套逻辑。我试过用这套框架做长文写作效果比单智能体好不少尤其是事实核查环节能抓出不少单智能体容易忽略的细节。我个人在实际操作中的体会是代理机构模式的价值不在于智能体数量多而在于职责边界清晰。一个职责边界清晰的三角色系统效果往往好过一个职责模糊的七角色系统。所以如果你刚开始尝试建议从三个角色起步一个协调者、一个执行者、一个验证者。跑顺了再逐步增加角色。最后再分享一个小技巧给每个智能体的输出加一个置信度字段。让智能体自己评估对这次输出的把握程度低于某个阈值时自动触发人工复核或重新执行。这个机制在实际使用中帮我拦下了不少潜在问题尤其是需求分析阶段分析者如果对某个假设的置信度很低就说明这里需要人工介入澄清了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑