聊一个最近热度很高的名词:agency-agents。我的理解是,它不单指某一个开源项目,也不完全是某一个API的名字,而是描述一种正在快速落地的AI应用模式——把多个智能体组织起来,像一家数字代理机构那样分工协作,去完成一个人做不了、或者做起来很吃力的复杂任务。你可以把它理解为给大模型套上了一层“组织管理”的外壳,让不同的Agent各司其职,由协调者负责任务拆解,由执行者负责具体干活,由审查者负责把关质量。
这篇文章我想从实际使用的角度,把agency-agents的来龙去脉说清楚:它解决了什么问题、内部角色如何划分、消息通道怎么设计、关键参数怎么配,以及踩过哪些坑之后总结出来的避坑清单。适合两类人看:一类是想用大模型做点正经事的开发者,另一类是负责技术选型和架构设计的同学。看不懂底层推理没关系,我会尽量用日常协作的例子把这套东西的骨架讲明白。
1. 项目概述与核心需求拆解
1.1 从单个助手到agency:到底在解决什么问题
单Agent方案最直观的问题,是那一小块上下文窗口。假设你给一个大模型投喂一份五万字的项目文档,让它基于文档输出一份落地方案,输出到一半它就“忘了”前文的关键约束。即便模型本身支持长上下文,单次推理的注意力和稳定性也会随文本长度快速衰减,表现就是前后矛盾、细节失真。
另一个问题是角色冲突。让同一个Agent既当文案又当代码审查员,它的决策路径是混在一起的,很容易出现“自己写的代码自己觉得没问题”的情况,这在AI领域同样成立。某个模型生成的SQL语句,站在生成者的视角看很自然,但换一个严格审查的视角,就能挑出字段缺失、索引漏建、边界未考虑等多类问题。人类团队的做法是分工和复审,Agency架构相当于是把这个成熟的组织经验搬到了AI智能体上。
所以agency-agents解决的不只是“任务变复杂”,而是“单一智能体的能力边界已经跟不上复杂任务的需求”。当一个任务同时需要信息检索、材料整理、方案设计、代码实现、结果校验时,把这几个环节交给不同的Agent,并且用一套明确的通信机制把它们串联起来,质量和可控性都会好得多。
1.2 什么样的场景适合引入agency-agents
不是所有任务都需要上多Agent,这一步一定要先想清楚。适合引入的场景有几个共性:
第一,任务天然可分。比如市场调研,可以拆成“数据收集”、“竞品分析”、“内容撰写”、“格式校验”四步,每一步相对独立,可以并行或流水线化。第二,任务对准确性要求高。财务报告、技术文案、代码提交这类内容,不能只生成一次就交付,必须有复核环节。第三,任务需要多视角审视。同一个产品决策,从用户视角、技术视角、商业视角得到的结论完全不同,多Agent天然具备这个多维审视能力。
反过来,一些简单任务就不适合引入agency-agents。比如“帮我把这段文本润色”,单个Agent一次调用就够了,强行上多Agent只会增加延迟和成本。我的判断标准是:如果任务需要反复多轮修订、需要跨领域知识拼接、或者结果会直接对外交付,才值得用agency模式。
2. 整体架构与角色设计思路
2.1 角色的划分:协调者、执行者、审查者
最常见的Agency架构,是参考项目管理三角色的模式来划分的:
协调者是入口,负责接收用户需求,将大任务分解成多个子任务,决定子任务的执行顺序,并在所有子Agent完成后汇总结果。协调者不能参与具体业务内容的生成,它的核心能力是任务拆解和进程管理。
执行者是干活的,比如信息搜集Agent、文案生成Agent、代码开发Agent。每个执行者只负责单一类型的工作,它的Prompt围绕本职展开,不掺入其他角色要求,上下文也更聚焦,输出稳定。
审查者站在执行者的对立面,职责是校验。它接收执行者的产出,根据预设规则做质量评估,不通过就退回给执行者修改,通过则交给协调者汇总。这样能显著压住模型幻觉。
在实际项目落地时,角色还可以继续细分,甚至每个角色内部再组一层子Agency。我见过一个跨平台系统的设计,整体是五级结构:入口协调者之下挂了技术调研团队和业务分析团队,每个团队又分配了各自的策略Agent和专业执行Agent。看起来复杂,但逐层分解下来,每个节点只需要处理一个清晰的小任务,反而更容易排查问题和定位质量瓶颈。
2.2 消息传递与共享状态:让agents开口交流
多Agent架构能不能跑起来,关键看消息系统设计。最粗糙的做法是各Agent独立调用大模型API,各干各的,最后拼起来。这种方式交互链路断裂、逻辑不连贯,而且中间的调整无法传导。
更可靠的做法是引入消息总线,所有Agent的解读、请求、反馈都通过消息总线传递,而不是Agent之间直接通信。每个Agent只感知自己的输入消息和处理结果,无需关心上下游是谁,这样替换、扩展单个Agent非常方便。业务数据上有共享状态区,各个Agent把阶段结果写入状态区,供下游角色读取。
消息格式建议统一使用结构化JSON,包含任务ID、发送者、接收者、消息类型、内容块、状态标志。这样一方面便于跟踪任务链路,排查问题时有完整的审计线索,另一方面不同Agent不需要感知彼此的内部实现细节,只需按协议解析消息。
2.3 任务编排模式:链式、并联、混合
Agency的任务流转通常有三种编排模式。
链式:任务像流水线一样按顺序流转,一个Agent的输出是下一个Agent的输入。适合有明确先后依赖的任务,比如“信息收集→内容撰写→质量审核”。优点是链路直观、可控性高;缺点是整体耗时等于各环节耗时之和。
并联:多个执行者同时处理不同子任务,协调者统一分发、统一回收。适合相互独立的子需求,效率高。比如市场调研中的数据抓取、问卷整理、竞品分析可以同时跑。注意点在于并联涉及并发调用,预算控制和后端限流要提前做。
混合:主干走链式,局部走并联。实际项目中我九成以上都用混合模式,先由协调者拆解,再把无依赖的子任务交给多个执行Agent并发处理,等结果汇总后再进入评审和修订环节。这样能兼顾效率和可控性。
3. 核心机制与关键参数配置
3.1 上下文窗口与记忆管理
多Agent架构虽然缓解了单Agent的信息负载压力,但每个Agent自己的上下文管理依然不能忽视。一个常见的错误是每个Agent都把历史消息全量塞进上下文。随着任务推进,上下文中无关内容越来越多,响应质量必然下降,成本也在悄悄上升。
我的习惯是为每个Agent设定明确的上下文策略:每个Agent只保留与本角色相关的指令和最近一轮的任务输入,上级的历史会话不跨Agent传递。如果确实需要全局信息,就通过共享状态区的摘要来获取,而不是直接把完整历史拼接进下一次调用。另外要控制上下文的压缩频率,每两到三轮对话做一次摘要归档,把旧消息折叠成结构化要点,保持上下文窗口始终留给当前最重要的信息。
参数方面,max_tokens建议分类设置。执行类Agent负责产出长文档或大量代码,max_tokens设到4096甚至8192;审查类Agent只做判断和修订意见,max_tokens只需要1024到2048就够了,太大反而会诱导模型输出冗长的无意义内容。频次惩罚和存在惩罚(frequency penalty和presence penalty)也要根据Agent类型调配,执行者适当降低重复惩罚以保持长文逻辑连贯,审查者可以稍微调高重复惩罚,避免冗词赘句。
3.2 温度与模型选择:不同角色用不同参数
temperature的选择是影响Agency整体效果的高敏感性参数。不同角色应当使用不同的temperature策略。
创作类Agent需要多样性和发散性,temperature设置在0.7到0.9之间效果较好,能生成更自然的文案。分析类Agent介于发散和稳定之间,0.3到0.5比较合适。审查类和代码生成类Agent对精确度要求极高,temperature应尽量贴近0。实际经验是代码生成超过0.5时,很容易出现语法看起来正常但运行报错的代码,这类问题是审查环节的噩梦。
模型选择上,协调者需要强指令跟随和归纳能力,选推理能力强的旗舰模型。执行者根据任务领域选择。审查者不一定要用最大参数量的模型,有时小模型反而更严格,因为它不会被“生成者”的思路带跑。我这里不推荐具体品牌,但有一点建议:如果审查者和生成者用完全相同的模型和技术栈,两者容易放大同样的盲点,产出都会存在相似缺陷。能错开尽量错开。
3.3 工具注册与权限隔离
Agency中的工具调用能力很容易失控。设想一个信息搜集Agent被赋予了文件写入和网络访问权限,而审查Agent也可以访问文件系统,风险敞口就会非常大。工具注册应遵循最小权限原则:每个Agent对外暴露的工具接口按角色精确裁剪,并且每个工具接口要有调用审计日志,记录调用者、时间、输入参数。
具体到架构层,可以在工具总线上做一层独立鉴权,只有协调者拥有跨域工具调用权,执行者只能调用自己角色内部的工具集。审批流程里,需要外部权限或网络访问的工具调用必须先经过审查Agent确认,再交由协调者执行。这样即使某个Agent发生幻觉,它也无法自主对外发起破坏性操作。
4. 实操过程:搭建一个最小可用的agency-agents
4.1 定义角色与任务协议
搭建一套最小可用的Agency系统不需要花哨框架,用Python的标准库就能完成核心骨架。我先定义角色基类和消息协议。
from enum import Enum from dataclasses import dataclass, field from typing import Any, Optional class AgentRole(Enum): COORDINATOR = "coordinator" RESEARCHER = "researcher" WRITER = "writer" REVIEWER = "reviewer" @dataclass class Message: task_id: str sender: str receiver: str msg_type: str # request / response / revise / final content: dict status: str = "pending" @dataclass class AgentContext: role: AgentRole rules: list[str] memory: dict = field(default_factory=dict)每个Agent基于这个上下文来工作。role决定它能执行什么类型的任务,rules是它必须遵守的约束条件,比如“必须给出三个备选方案”“必须只使用中文”。协调者会把这些规则写入任务描述,确保Agent在推理时方向正确。
4.2 简单消息总线实现
消息总线是整个架构的大脑。它的作用是统一收发消息、维护会话队列、记录日志。
import uuid from collections import defaultdict from queue import Queue class MessageBus: def __init__(self): self.queue = Queue() self.registry = {} self.logs = defaultdict(list) def register(self, agent_name: str, agent_instance): self.registry[agent_name] = agent_instance def send(self, msg: Message): self.queue.put(msg) self.logs[msg.task_id].append(msg) def deliver(self): while not self.queue.empty(): msg = self.queue.get() receiver = self.registry.get(msg.receiver) if receiver: response = receiver.handle(msg) if response: self.send(response)这里我做了简化,实际项目里还要加入并行分发、重试、死信队列。核心思路是一致的:所有交互通过总线中转,而不是Agent之间直接调用。总线层方便做全链路的日志记录和问题监控,一旦接了外部API,也能清晰统计每次调用的消耗。
4.3 任务调度与结果回收
协调者负责任务拆解。它的代码逻辑是:接收用户输入,根据规则生成子任务清单,然后通过MessageBus把子任务派发给对应的执行Agent。
class CoordinatorAgent: def __init__(self, bus: MessageBus): self.bus = bus def handle(self, user_input: str): # 实际场景中,这里应调用LLM进行意图分析和任务拆解 subtasks = self._plan(user_input) for sub in subtasks: msg = Message( task_id=str(uuid.uuid4()), sender="coordinator", receiver=sub["agent"], msg_type="request", content=sub["content"] ) self.bus.send(msg) # 此处应等待所有子任务完成并做汇总子任务的结果回收依赖全局任务状态表,协调者在派发时记录任务ID,收到response类型的消息后标记对应任务完成。全部完成后,再调用汇总逻辑生成最终答复。审查者收到执行者的初步产出后,返回revise或final两种消息状态,协调者根据状态决定是否进入下一轮修订。
这一段实操展示的是最简版本,开发环境里可以直接复制跑通。如果跑通了,你会对Agency模式有一个非常直观的感受:协调者像项目经理,把活拆给不同的人,等结果汇总;审查者像验收员,不合格的打回返工;执行者只需要专注自己那一摊事。
5. 常见问题排查与避坑实录
5.1 上下文爆炸和任务漂移
实跑Agency系统最常遇到的就是上下文爆炸。多轮修订过程中,审查者的反馈、执行者的重新生成内容会越积越多,Agent每轮都要带着越来越长的历史记录,响应速度显著下降。
我的处理办法是每轮修订只保留本轮的任务描述和审查反馈,不把前几轮的生成草稿全量带入。协调者保存所有历史版本用于审计,但执行者和审查者的当前上下文保持在最小尺寸。利用这个策略,一个长期运行的内容生产Agent,响应时间稳定下来了,费用大约降了三成。
任务漂移指的是执行者的产出渐渐偏离最初要求,这在多轮修订中尤其明显。修订过多轮之后,生成内容逐渐向审查者的口味偏移,而忘记用户最初的目标。为解决这个,协调者每次派发修订请求时,都会在消息里附带原始任务摘要,用高优先级字段锁定核心要求,审查反馈只针对当前版本的局部问题。这个做法类似于在会议中始终把需求文档投在屏幕上,不要让讨论过程扭曲原意。
5.2 角色循环与会话死锁
角色循环是个隐蔽的坑。当审查者要求修改,执行者改完,审查者觉得还有问题,再次要求修改,如果协调者没有设置最大修订轮数,系统就会陷入无限循环,白白烧掉大量API费用。
我在实际项目中强制给每轮任务设置修订上限,默认3次,超过后无论审查者是否满意,任务直接进入协调者人工审核队列。另一方面,要保证每个消息都带超时机制,特别是下游Agent调外部API时,一旦外部接口无响应,总线要在规定时间内做降级处理。
还有一个常见的死锁场景:Agent A等待Agent B的结果,而Agent B的任务被挂在Agent A的后续步骤中。这类问题最好的解法是编排时禁止双向依赖。任务拆解阶段就做依赖分析,保证所有任务构成的图是一个有向无环图,从根源上避免循环等待。
5.3 预算失控与性能优化
多Agent系统的费用不是简单的加法,而是乘法。每多一个Agent,任务拆解、执行、审查、汇总,每一步都在消耗token,整体开销往往超出单个Agent方案的三到五倍。上线前一定要做完整的预算估算,我和团队的习惯是:先拿10个真实业务任务做一轮全量试跑,统计平均单任务token消耗,乘以预计业务量,得到预估月度费用,再决定哪些环节可以改用轻量模型。
性能优化和预算控制高度相关。优先替换的是审查Agent和部分执行Agent,改用轻量模型,在很多业务场景下质量下降可以控制在可接受范围,费用却能大幅下降。并发上要做限流保护,尤其是总线向多个Agent同时分发任务时,上游API的并发限制可能导致大量调用失败,需要设置信号量控制最大并发数。
5.4 安全合规与审计留痕
多Agent系统最容易被忽视的是安全合规。多个Agent协作,等于在多个维度同时调动大模型能力、外部API和内部数据。必须在架构初期就把审计能力内置到总线中,记录每一次消息的发送者、接收者、时间戳、内容摘要和token消耗。
一个重要的原则是:任何Agent都不应该直接接触原始敏感数据。比如涉及用户信息的任务,数据脱敏必须在总线之前的入口统一完成,执行类和审查类Agent拿到的都是脱敏后的数据;需要用原始字段的环节,由协调者单独走加密通道处理,不加到共享状态区。工具调用同样要遵循最小权限,我在前面提过,这里再强调一次:即使单个Agent出现异常,权限隔离能保证它只能影响自己的子任务,而不能伤害整体系统。
最后分享一个我实测下来很有用的习惯:在系统里给每个Agent加上独立的温度系数配置和上下文策略,不要让所有角色共用一套参数。你可能会花一周时间去调整每个角色的职责边界和通信协议,但一旦跑通,你会发现多Agent协作完成复杂任务的稳定性和可维护性,确实比单Agent硬拟合要高出几个台阶。这也是我认为agency-agents会成为未来一段时间AI应用主流形态的根本原因。