多智能体协作框架agency-agents:架构设计与工程实践指南 1. 项目缘起与核心定位第一次看到 agency-agents 这个命名我的直觉是这大概率是一个围绕“代理agency”与“智能体agents”做文章的项目而且命名方式带着明显的工程化气息——用连字符把两个核心概念拼在一起既像是一个代码仓库名又像是一套架构方案的代号。实际接触下来它确实是一个聚焦于“多智能体协作框架”方向的项目核心目标是让多个具备独立职责的智能体agent在一个统一的调度体系下协同完成复杂任务而不是像早期那样把所有逻辑塞进一个巨大的单体提示词里。这个项目解决的核心痛点非常明确当任务复杂度上升时单个智能体的上下文窗口、职责边界和决策质量都会迅速劣化。你让它既做需求分析、又做代码生成、还要做质量校验最后它会在某个环节掉链子而且你很难定位到底是哪一步出了问题。agency-agents 的思路是把这些职责拆开每个 agent 只负责一个明确的职能域通过一个协调层orchestrator来管理它们之间的消息传递、任务分发和结果汇总。这样做的好处是每个 agent 的提示词可以写得非常聚焦行为可预测性大幅提升调试时也能快速定位问题出在哪个环节。适合谁来参考这套东西我认为有三类人收益最大。第一类是正在做 AI 应用开发但被单体智能体搞得焦头烂额的工程师你们会发现拆分成多 agent 之后系统的可维护性会有质的提升。第二类是对多智能体协作机制感兴趣、想找一个可落地参考实现的研究者或学生agency-agents 的架构设计比很多论文里的方案更贴近工程实际。第三类是做自动化工作流编排的产品或运营同学你们可以把它理解成“用 AI 员工替代人工流转”的一套组织方案只不过这里的员工是 agent。在展开细节之前我想先把这个项目的整体设计思路讲清楚因为如果不理解它为什么这样分层后面的实操部分就会变成照猫画虎遇到问题也不知道怎么调。2. 整体架构设计与选型考量2.1 为什么是“多智能体”而不是“单体加工具”很多人一开始会问我用一个能力很强的模型配上各种工具调用function calling不也能完成复杂任务吗为什么非要拆成多个 agent这个问题我在早期也纠结过实测下来的结论是单体加工具在任务步骤少于五步、且步骤之间没有强依赖关系时确实够用但一旦任务变成“先分析、再规划、再执行、再校验、最后根据校验结果回退重做”这种带循环和分支的流程单体的提示词会膨胀到难以维护的程度。agency-agents 选择多智能体架构本质上是把“关注点分离”这个软件工程原则搬到了 AI 应用层。每个 agent 有自己的系统提示词、自己的工具集、自己的输出格式约定它们之间通过结构化的消息通常是 JSON通信。这样做带来的直接好处是你可以单独测试每一个 agent 的行为可以单独替换某一个 agent 的实现而不影响其他部分也可以针对某个 agent 单独做提示词优化和回归测试。注意多智能体不是银弹。如果你的任务本身很简单强行拆成多个 agent 只会增加通信开销和调试复杂度。我的一般判断标准是当单个 agent 的系统提示词超过 800 字或者需要处理的工具超过 5 个或者任务流程中存在条件分支和循环时才考虑拆分。2.2 协调层的设计取舍agency-agents 在协调层上有两种可选模式我在不同项目里都试过这里把对比说清楚。第一种是中心化调度有一个 orchestrator agent 负责接收用户输入、拆解任务、按顺序或按条件调用其他 agent、收集结果并决定下一步。这种模式的好处是控制流清晰所有决策逻辑集中在一处调试时只需要看 orchestrator 的日志就能还原整个执行链路。缺点是 orchestrator 本身容易变成瓶颈如果它的提示词写得不够好整个系统的表现会急剧下降。第二种是去中心化协商agent 之间可以直接通信通过某种协议比如合同网协议或者简单的消息队列来协商任务分配。这种模式理论上更灵活但实际落地时你会发现调试难度陡增因为执行路径不再是线性的而是网状扩散的出了问题很难复现。agency-agents 默认采用的是中心化调度为主、局部允许 agent 之间直接通信的混合模式。我认为这个取舍是务实的主干流程用中心化保证可控性局部需要灵活协商的场景比如多个执行 agent 竞争同一个子任务再放开直接通信。你在实际使用时建议先把所有通信都走 orchestrator等系统稳定后再考虑局部放开。2.3 消息格式与状态管理agent 之间的消息格式agency-agents 采用的是带类型标记的 JSON 结构。每条消息包含几个关键字段发送方标识、接收方标识、消息类型任务分配、结果返回、错误上报、状态查询等、负载数据、以及一个可选的上下文引用。这个设计看起来简单但实际用起来非常关键因为如果没有统一的消息格式不同 agent 之间的输出会互相不兼容你会花大量时间在格式转换上。状态管理方面项目采用了一个共享的上下文存储context store所有 agent 都可以读取和写入。这里有个坑我踩过如果所有 agent 都往共享存储里写很快就会出现数据覆盖和版本冲突。agency-agents 的做法是给每个 agent 分配独立的命名空间只有 orchestrator 有权限跨命名空间读取和汇总。这个约束在初期会觉得麻烦但后期维护时会感谢这个设计。3. 核心模块拆解与实操要点3.1 Agent 定义与注册机制在 agency-agents 里定义一个 agent你需要提供四样东西名称与唯一标识、系统提示词、可用工具列表、输入输出格式约定。这四样缺一不可我见过有人只写了提示词就注册上去结果 agent 返回的内容格式五花八门orchestrator 根本没法解析。系统提示词的写法有讲究。我的经验是采用“角色 职责边界 输出格式 禁止事项”的四段式结构。角色部分用一句话说清楚这个 agent 是谁职责边界部分明确列出它该做什么、不该做什么输出格式部分给出具体的 JSON schema 或者模板禁止事项部分列出常见的错误行为比如“不要编造不存在的数据”“不要在未收到明确指令时自行调用工具”。工具列表的配置要注意权限最小化原则。一个负责文本分析的 agent 不应该有文件写入权限一个负责代码生成的 agent 不应该有数据库删除权限。agency-agents 支持在注册时声明工具权限我强烈建议你严格配置不要图省事给所有 agent 开全部权限。# agent 注册的典型配置示例 agent_config { name: requirement_analyst, agent_id: agent_001, system_prompt: 你是一名需求分析专家..., tools: [read_document, extract_keywords], input_schema: {type: object, properties: {raw_input: {type: string}}}, output_schema: {type: object, properties: {requirements: {type: array}}}, namespace: analysis }3.2 任务分发与路由逻辑orchestrator 的任务分发逻辑是整个系统的心脏。agency-agents 默认提供了一套基于规则的路由机制你可以配置“当任务类型为 X 时分发给 agent Y”。但实际项目中任务类型往往不是预先定义好的而是需要 orchestrator 自己判断。这时候就需要在 orchestrator 的提示词里写清楚分类逻辑。我通常会把路由逻辑写成决策树的形式让 orchestrator 按顺序判断。比如先判断任务是否涉及代码如果是则走代码相关 agent 链路如果不是则判断是否涉及数据分析以此类推。决策树的深度建议控制在三层以内太深了 orchestrator 容易判断失误。这里有个实操技巧给每个 agent 写一段简短的“能力描述”在 orchestrator 的提示词里把这些描述列出来让 orchestrator 根据任务内容匹配最合适的 agent。这比让 orchestrator 记住每个 agent 的详细配置要可靠得多因为能力描述可以写得更语义化模型更容易理解。3.3 结果汇总与冲突消解多个 agent 返回结果后orchestrator 需要做汇总。如果不同 agent 的结果之间存在冲突怎么办agency-agents 提供了几种策略投票机制、优先级机制、以及回退重试机制。投票机制适合多个 agent 做同类判断的场景比如三个 agent 分别判断一段代码是否有安全漏洞取多数意见。优先级机制适合有明确权威关系的场景比如校验 agent 的结论优先于生成 agent 的自我评估。回退重试机制适合结果质量不达标的情况orchestrator 可以把结果打回给原 agent 并要求重新生成同时附上具体的改进要求。我在实际使用中发现冲突消解策略最好在项目初期就定好并且写进 orchestrator 的提示词里。如果等到运行中才发现冲突临时决定怎么处理往往会导致执行路径混乱。4. 完整实操流程与配置细节4.1 环境准备与依赖安装先把基础环境搭起来。agency-agents 本身是一个 Python 项目建议使用 Python 3.10 及以上版本因为用到了不少类型注解的新特性。依赖管理推荐用 poetry 或者 pipenv比裸 pip 要省心很多。# 创建虚拟环境 python -m venv venv source venv/bin/activate # Windows 下用 venv\Scripts\activate # 安装核心依赖 pip install agency-agents pip install pydantic # 用于消息格式校验 pip install structlog # 用于结构化日志安装完成后你需要配置模型接入信息。agency-agents 支持多种模型后端配置方式是在项目根目录创建一个config.yaml填入模型名称、接口地址和认证信息。这里注意不要把认证信息硬编码在代码里用环境变量注入。# config.yaml 示例 model: provider: openai_compatible model_name: your-model-name api_base: ${MODEL_API_BASE} api_key: ${MODEL_API_KEY} max_tokens: 4096 temperature: 0.3temperature 的设置很关键。对于需要精确输出的 agent比如代码生成、格式转换建议设在 0.1 到 0.3 之间对于需要创造性的 agent比如方案构思可以设到 0.7 左右。agency-agents 允许为每个 agent 单独配置 temperature这个灵活性要用起来。4.2 定义你的第一个 Agent 链路假设我们要做一个“技术文档自动生成”的链路涉及三个 agent需求解析 agent、内容生成 agent、质量校验 agent。下面我把每个 agent 的配置要点说清楚。需求解析 agent 的职责是把用户输入的零散需求整理成结构化的文档大纲。它的系统提示词要强调“提取关键信息、识别缺失信息、输出标准 JSON”。输出格式我通常定义为包含 sections 数组的结构每个 section 有 title 和 key_points 两个字段。内容生成 agent 的职责是根据大纲逐节生成内容。它的提示词要强调“严格按大纲结构输出、每节内容不少于指定字数、不编造技术细节”。这里有个技巧把大纲作为输入的一部分传给内容生成 agent而不是让它自己去读共享存储这样可以避免它读到其他 agent 写入的中间状态。质量校验 agent 的职责是检查生成内容是否符合要求。它的提示词要列出具体的检查项结构是否完整、字数是否达标、是否存在明显的事实错误、术语使用是否一致。校验结果输出为 pass 或 fail 加上具体的修改建议。# 链路定义示例 pipeline { name: tech_doc_generation, steps: [ {agent: requirement_analyst, input_from: user, output_to: context}, {agent: content_generator, input_from: context, output_to: context}, {agent: quality_checker, input_from: context, output_to: orchestrator} ], on_failure: retry_with_feedback, max_retries: 2 }4.3 运行与监控启动链路后agency-agents 会输出结构化的执行日志。我强烈建议你把日志级别调到 DEBUG尤其是在调试阶段。日志里会记录每个 agent 的输入、输出、耗时、以及 orchestrator 的路由决策。这些信息在排查问题时非常宝贵。监控方面项目内置了一个简单的执行追踪面板可以查看每个 agent 的调用次数、平均耗时、失败率。如果你需要更详细的监控可以把日志导出到外部系统。我一般会关注三个指标单个 agent 的失败率是否超过 10%、orchestrator 的路由决策是否有异常分布、整体链路的端到端耗时是否在可接受范围内。提示在正式跑大批量任务之前先用 5 到 10 条代表性输入做一轮冒烟测试。重点观察 orchestrator 的路由是否符合预期以及 agent 之间的消息格式是否兼容。这一步能帮你提前发现 80% 的配置问题。5. 常见问题与排查技巧实录5.1 Agent 输出格式不稳定的排查思路这是最常见的问题表现为 orchestrator 解析 agent 输出时报 JSON 解析错误。排查步骤我总结成了一张表现象可能原因排查方法解决措施偶尔解析失败模型输出带了额外说明文字查看原始输出日志在提示词中强调“只输出 JSON不要任何解释”频繁解析失败输出 schema 定义不清晰检查 output_schema 是否完整补充字段类型和必填项说明特定输入必失败输入触发了模型的特殊行为用该输入单独测试 agent在提示词中增加针对该场景的约束所有输出都失败消息格式配置错误检查 agent 注册时的 schema修正 schema 并重新注册我的经验是在提示词里用“输出格式示例”比用“输出格式说明”效果更好。给模型一个具体的 JSON 样例它模仿的准确率会明显高于根据文字描述生成。5.2 任务路由错误的定位方法orchestrator 把任务分给了错误的 agent这种问题往往比较隐蔽因为系统不会报错只是结果不对。定位方法是打开 DEBUG 日志找到 orchestrator 的决策记录看它判断任务类型时依据了哪些关键词或特征。如果发现判断依据不合理就需要调整 orchestrator 的提示词。我遇到过一个典型案例orchestrator 把“优化数据库查询”这个任务分给了代码生成 agent但实际上应该分给性能分析 agent。原因是 orchestrator 的提示词里把“优化”这个词默认关联到了代码生成。解决办法是在提示词里明确列出容易混淆的任务类型及其对应的 agent并且给出区分标准。5.3 性能瓶颈的优化方向当链路变长、agent 数量变多后端到端耗时可能会变得不可接受。优化方向主要有三个减少不必要的 agent 调用、并行化独立步骤、以及缓存重复结果。减少调用方面检查是否有 agent 的输出实际上没有被下游使用如果有就把它从链路里去掉。并行化方面如果两个 agent 之间没有数据依赖就让它们并行执行agency-agents 支持在链路定义中声明并行组。缓存方面对于相同输入会得到相同输出的 agent比如格式转换可以在 orchestrator 层加一层缓存避免重复调用。5.4 独家避坑经验第一个坑不要在 agent 的提示词里写太长的背景介绍。我见过有人把整个项目背景写了 2000 字塞进每个 agent 的提示词结果模型被背景信息干扰反而忽略了当前任务的具体要求。背景信息应该放在 orchestrator 层agent 只需要知道自己的职责和当前任务。第二个坑agent 之间的消息不要传大段原始文本。如果上游 agent 的输出是一篇长文档下游 agent 需要的是其中的关键信息那就让上游 agent 输出结构化摘要而不是把全文传下去。这能显著降低 token 消耗和解析失败率。第三个坑不要忽视 agent 的“拒绝回答”能力。有些 agent 在遇到超出职责范围的任务时应该明确返回“无法处理”而不是强行编造结果。在提示词里加上这个约束能避免很多下游的连锁错误。6. 扩展方向与个人实践体会agency-agents 的架构本身是可扩展的你可以根据业务需要增加新的 agent 类型也可以替换协调层的实现。我目前尝试过的扩展方向有两个一是引入“记忆 agent”专门负责维护跨会话的上下文让整个系统具备一定的长期记忆能力二是引入“评估 agent”在链路执行完成后对整体结果做一次端到端的质量评分用于持续优化提示词。记忆 agent 的实现要点是把历史交互压缩成结构化摘要存储而不是原样保存所有对话。评估 agent 的实现要点是定义清晰的评分维度和评分标准避免评分结果过于主观。这两个扩展我在不同项目里都跑过一段时间效果是正向的但前提是基础链路已经稳定运行否则会增加调试复杂度。最后分享一个我在使用 agency-agents 过程中形成的小习惯每次调整任何一个 agent 的提示词后我都会用一组固定的回归测试用例跑一遍确认没有引入新的问题。这组用例不需要很多五到十条覆盖主要场景即可但坚持下来能帮你避免很多“改了一个地方、坏了另一个地方”的情况。多智能体系统的调试确实比单体复杂但一旦跑通它的可维护性和可扩展性是单体方案很难比拟的。