为什么要拆成多个 Agent
LLM 在角色明确时表现最好。
这个结论来自一个简单的对比实验。同一个任务,让一个 Agent 同时做调研、写文案、翻译、出排版,和把这四件事分给四个带有独立系统提示词的子 Agent 分别完成,后者在每个环节的输出质量都更高。
原因并不复杂。一个 Agent 做多件事时,每切换一次角色,上下文中就混入了前一个角色的输出残留。调研阶段的学术用语会渗透进文案写作,文案的煽情语气会影响翻译的精确度。LLM 的注意力是有限的,角色越单一,可分配给当前任务的注意力比例越高。
这和人类团队的分工逻辑相同。一个人能同时做产品、开发、设计、测试,但每个环节的质量都在打折扣。
Alice 的解法:把不同专业的工作交给不同的角色,每个角色有独立的系统提示词、工具集和行为约束。
还有一个容易被遗漏的成本维度。Alice 是 C 端产品,每次 LLM 调用都直接消耗用户预算。主 Agent 的系统提示词本身很长(完整人设、长期记忆、用户画像),如果把调研的大量搜索结果、翻译的中间确认过程都压进主对话上下文,缓存命中率会骤降,每次交互的实际费用会急剧上升。把专业任务卸载给独立子 Agent,主对话上下文保持稳定和精简,是一个直接影响用户钱包的工程决策。
角色设计
Alice 目前有 11 个专业角色,覆盖调研、翻译、写作、配音、视觉设计、AI 绘图、数据分析、量化分析、小说创作、全栈开发、文档工程。每个角色有完整的人设、背景故事、系统提示词和预绑定的技能文件。
他们分布在不同城市,有各自的性格特点和工作习惯。和真实团队一样,每个人有擅长的领域和明确的职责边界。
当任务不属于任何专业角色的范畴时,Alice 自己上。她是团队的万能补位:行政、流程协调、需求梳理、日常闲聊。
调度配置的三个关键维度
每个角色的定义中有三个和调度直接相关的配置。
前台还是后台。 部分角色默认在后台运行。主 Agent 派完任务后不等结果,立即继续对话。这适用于耗时较长、或者不阻塞用户当前需求的角色,比如调研、翻译、量化分析。
只读还是写入。 以搜索和分析为主的角色默认只读,以内容生产为主的角色默认需要写入权限。这个标志直接影响并发策略。
并行许可。 定义角色之间能否同时工作。有些角色可以和所有人并行(典型的是只读角色),有些只能和特定角色并行。这取决于它们的产出类型是否存在冲突。
并发策略
并发决策分两层。
第一层是静态声明。在角色定义时就确定了每个角色的只读属性和并行许可范围。比如,一个只输出文本的角色可以和输出图片、输出代码的角色并行,因为它们的产出不会冲突。
第二层是运行时动态判断。调度器综合考虑调用方显式传入的参数(优先级最高)和角色默认配置。如果连角色都没指定,保守策略:串行。
调度器的执行策略:只读任务全部并行,写任务按顺序串行,最后按原始顺序合并结果。
这个设计的取舍点在于:写任务之间是严格串行的,即使两个写任务产出的文件类型完全不同。并行许可目前只在角色级别做判断,还没有下沉到任务级别的文件锁。这是一个有意识的保守选择,后续会加文件级并发控制。
调度流程与降级机制
用户发消息后,Alice 主循环识别任务类型,决定是否派人。角色推荐基于关键词匹配,但最终决策权在 LLM 手上。
整个流程是:主循环判断需要子 Agent → 创建协调器 → 协调器创建调度器 → 调度器尝试在独立工作线程中启动子 Agent → 子 Agent 运行自己的完整循环 → 结果返回主 Agent → 汇总回复用户。
有一个关键的降级机制。生产环境下,子 Agent 运行在独立的工作线程中,实现隔离。但在开发模式下,构建工具的打包方式决定了没有独立的工作线程入口。这时调度器自动降级,在主线程中运行子 Agent。
两种模式对外接口完全一致,调用方无感知。开发时和生产时的多 Agent 行为完全相同,只是隔离程度不同。
线程通信
每个子 Agent 在独立线程中跑一个完整的 Agent 循环,拥有各自独立的 LLM 客户端、上下文管理器、权限引擎等实例。
子 Agent 和主线程之间通过消息通信。有三类:
- 流式输出:文本、工具调用等事件,实时透传给主线程,主线程再推到前端渲染。
- 权限代理:子 Agent 要执行敏感操作时,发请求给主线程,主线程弹确认框给用户。有超时机制,超时默认拒绝。
- 调用事件转发:子 Agent 的每次 LLM 调用都转发给主线程的全局日志记录器,让调试面板也能看到子 Agent 的调用记录。
工作线程内部有自己的中止控制器。主线程可以随时发送中止信号。
有一个曾经出过的 bug 值得记录:工作线程发出完成消息后,主线程只更新了输出变量但没有正确结束等待,导致父 Agent 的循环永远挂起。修复方案是在完成处理中立即终止工作线程并结束等待,用标志位确保只结束一次。这类异步协调的边界问题,多线程系统里几乎一定会遇到。
后台任务管理
后台运行的判断逻辑:调用方显式传入的参数优先级最高,其次看角色的默认配置,都没有则默认前台同步等待。
前台任务有一个超时后自动后台化的兜底机制。通过竞态实现:子任务在时限内完成则正常返回结果;超时则任务转入后台管理,主 Agent 立即解除阻塞,继续回复用户。
后台任务管理器是进程内单例,负责所有后台任务的生命周期:注册、完成/失败状态更新、中止信号下发、会话结束时的清理、定期回收已完成记录。
后台任务完成后,结果推入通知队列。主 Agent 的循环在每轮开始时消费属于自己会话的通知,以结构化格式注入上下文。通知按会话隔离。当有新通知入队时,自动触发一轮新的循环,让 Alice 能主动把后台结果告诉用户。
后台任务的流式事件(子 Agent 正在搜索、正在写文件等中间过程)通过全局通道推送到前端,用户可以实时看到进度。
调研员的二次审查
调研员完成调研后会自动执行一次自我审查。这是硬编码在流程中的,只有调研角色触发。
为什么需要二次审查?LLM 在大量信息中做总结时,存在一种典型的错误模式:前半截来自来源 A,后半截来自来源 B,中间用一个看起来合理但原文中不存在的推论连接。这种错误读起来很自然,人类不去核对原文几乎发现不了。
审查的核心设计:
- 创建一个新的子 Agent 实例,注入专用审查提示词
- 审查 Agent 被禁止使用网络搜索工具,只能用文件读取工具核对已归档的材料
- 审查 Agent 逐一比对报告中的结论与原始材料
- 输出包含确认无误的部分、发现的问题、遗漏的重要信息、整体可信度评估
- 审查结果追加到原始报告末尾,一并返回
审查本身也发独立的事件,用户在 UI 上能看到两张卡片:一张调研、一张审查。
审查如果失败(比如 LLM 超时),不影响原始调研结果的返回,只在末尾追加一条警告。
为什么审查不重新搜索
禁止网络搜索的约束看起来奇怪,但背后有一套精确的逻辑。
假设流程是:① 调研员搜索得到信息 A → ② Alice 基于 A 生成内容 B → ③ 审查 Agent 审查 B。
如果在第 ③ 步重新搜索,审查 Agent 得到的是信息 A’(搜索结果有随机性,与 A 不完全相同)。他用 A’ 来评判基于 A 生成的内容 B,逻辑上已经出问题了:审查者用的是不同的信息源,来评判基于另一个信息源的内容。
我们的做法是:审查 Agent 用与初始调研相同的信息 A,对比内容 B,找出差异。这是审计,不是迭代。两者目标不同:审计的问题是「这份内容是否准确反映了原始信息」,迭代的问题是「能否找到更好的信息」。
不重新搜索还有额外收益:成本减半(省去一轮搜索的 API 费用)、防止无限循环(重新搜索可能发现新信息,引发重新生成,再引发重新审查)、终止条件明确(审查的边界是已知信息,不是一个开放的探索空间)。
中心化协调与去中心化协作
Alice 有两种多 Agent 协作模式。
中心化协调模式是默认方式。主 Agent 作为协调者,分配任务、收集结果、管理执行拓扑。它负责权限继承:子 Agent 创建时,会把父 Agent 的权限模式传下去。设计原则是只紧不松,子 Agent 不能绕过权限检查。
使用场景举例:用户说「帮我调研短视频出海,整理成英文 PPT」。Alice 拆解为调研、翻译、设计、文档生成四个子任务,其中有依赖关系的串行执行,无依赖的可以并行。协调器负责管理这个执行拓扑。
去中心化协作模式没有中心调度器,每个节点是一个独立的 Agent 工作者,通过共享数据库协调。核心机制包括:共享任务队列保证并发安全、原子领取保证同一任务不被多个节点抢占、任务依赖声明、失败重试、优先级调度。
去中心化模式更适合大量同构任务的分布式处理(比如批量翻译几十个文件),但在异构任务的依赖编排上不如中心化模式灵活。目前还是基础版本。
工具安全隔离
子 Agent 的工具集经过严格过滤。过滤的核心原则是:任何可能影响全局状态的操作,都不允许子 Agent 触发。
被禁止的操作类型包括:递归创建子 Agent(防止无限嵌套)、直接与用户对话(只有主 Agent 有这个权力)、全局模式切换、向外部渠道发消息、日历操作、记忆写入、历史对话搜索、情感日记写入、系统通知、定时任务、自进化类操作。
外部服务类工具不受限制,始终放行。这样子 Agent 可以使用用户配置的外部服务。
记忆写入被禁的理由尤其值得展开说。Alice 的用户记忆是从主对话(用户与 Alice 的直接交流)中提炼的,它的信号来源必须是用户说了什么。如果调研员在搜索大量资料后,顺手把「用户在研究某个行业趋势」这个推断写入记忆,这是用系统内部工作流的信息污染用户画像。子 Agent 的工作语境无法可靠地推断用户的长期偏好,因此子 Agent 对记忆系统的写入权限被整体封禁。
收敛信号的设计
每个子 Agent 的系统提示词由角色专属部分和通用规范部分拼接而成。
通用规范中有明确的收敛指令,核心意思是:完整完成任务,做完就收,不要过度打磨,用简洁报告总结关键发现,附上相关文件路径。
没有角色匹配时(用户没指定角色),子 Agent 用纯任务导向的提示词,不携带 Alice 的人格特征。子 Agent 是执行者,不是 Alice 本人。
这里有一个关键的设计选择。没有角色时用纯任务导向提示词,有意不用主 Alice 的人设兜底。子 Agent 的身份和主 Agent 的身份必须严格分开。主 Alice 有情感、有人设、会和用户建立关系;子 Agent 是她委托出去的工具,完成任务就好。如果子 Agent 也开始用 Alice 的口吻说话,用户会搞不清楚「在和谁说话」,整个角色系统的可信度就会崩掉。
收敛信号的另一层意义是成本控制。子 Agent 如果没有明确的终止条件,倾向于继续调用工具、继续完善输出,这在大量的工程实践中都被反复观察到。「做完了就收」是防止子 Agent 在用户无感知的情况下持续消耗预算的保险阀。
用户端体验
从用户视角,多 Agent 协作体现为对话流中的子任务卡片。
用户只和 Alice 对话。Alice 决定派人后,对话区域会出现一张子 Agent 卡片,显示角色头像、角色名、任务描述。卡片默认折叠,用户可以展开查看子 Agent 的完整输出(流式更新)。
卡片上有三种信息:工具摘要(子 Agent 调用了哪些工具)、文本输出(子 Agent 的最终报告)、状态标记(进行中 / 已完成 / 失败 / 已中止)。
如果子 Agent 卡住或运行时间过长,用户可以点中止按钮。
后台任务完成后,Alice 会收到通知并主动发一条消息概括结果。系统提示词要求 Alice 用自己的话概括关键发现,不大段复述。因为用户可以展开卡片看全文,重复转述只是浪费预算。
角色间的协作模式
系统提示词中定义了明确的协作规则。
有些协作是强制顺序的。比如需要视觉方案的产出物,必须先让设计师出方案,再让文档工程师按方案生成文件。跳过设计步骤会严重影响质量。
有些角色有明确的职责边界。比如量化分析只做技术面,资讯调研是另一个角色的活。如果分析中需要外部信息,会在报告中标注建议,由 Alice 另行调度。
有些角色是天然并行搭档:调研和翻译互不影响,调研和数据分析互不影响,写文案和画插图可以同时进行。有些角色是固定串行链条:先拿资料再写文,先出文案再调配音,先出设计方案再写代码。
人设的工程价值
这个话题在第二篇讲过一部分,这里补充一个更具体的观察。
11 个角色在 Alice 里运行了 20 天后,我发现一个规律:角色设定越具体的子 Agent,输出质量的方差越小。
比如给一个角色写了详细的工作环境、习惯细节。这些细节和他的专业能力没有直接关系。但加了这些设定后,这个角色的输出风格明显更稳定。他不会突然变成一个啰嗦的人,也不会突然变得过于简洁。
我的解释是:背景细节给 LLM 提供了一个更具体的角色空间。角色空间越具体,LLM 在生成时的随机性越小。就像你在脑海里想象一个模糊的人和一个你能看到他工位样子的人,后者更容易让你预测他会怎么说话。
这也是 Alice 选择用人格描述代替行为指令的原因。写 50 条行为规则,LLM 可能遵守 40 条。但给一个足够具体的人设,LLM 会自己推理出那 50 条规则中的大部分,还会推理出你没想到的合理行为。
传统的提示词工程倾向于穷举规则。Alice 的做法是建立一个足够具体的角色原型,让 LLM 自己去推演行为细节。前者是硬编码,后者是让 LLM 做它最擅长的事:从上下文中推理。
每个角色必须有独立人设
设计多角色系统时,一个直觉上省事的做法是:复用主 Agent 的提示词给所有子 Agent,省去维护多份提示词的开销。但这个做法有三个结构性问题。
角色一致性破坏。 主 Agent 是情感细腻、克制的助理。如果子 Agent 也用这套人设,他的输出就会带着助理的语气,缺少专业角色应有的特征。用户无法感知「Alice 找了专业的人来帮忙」,只会感觉换了个口吻的同一个 AI。
专业能力稀释。 每个子 Agent 提示词的核心任务是精确定义工作方式和工具偏好。调研员需要「每个结论都要有出处」,配音师需要「关注文字的读感、调整断句」。这些专业约束和主 Agent 的情感性人设是两套完全不同的维度,混在一起会导致两方面都做得不好。
记忆管道污染。 如果子 Agent 共用主 Agent 的提示词,当子 Agent 的输出进入记忆提炼管道时,不同风格的表达会混在一起,破坏主 Agent 人格的纯粹性。
结论:宁可管理多套提示词,也不能让所有角色用同一套。
多智能体的成本边界
引入多 Agent 必然增加成本,因为每个子 Agent 都是独立的 LLM 调用链路。我们对这件事的态度是:承认代价,但要让代价对用户可见,并且让代价值得付出。
成本对用户必须透明。 后台子 Agent 一旦开始运行,用户可能完全无感,不知道有没有 Agent 在跑、跑了多久、花了多少钱。这是多 Agent 系统最严重的产品失误之一。Alice 的解法是统一入口:所有 AI 调用都经过同一个可观测的网关;子 Agent 在运行时,UI 必须有可见的状态标记;用户随时可以中止任意子 Agent。
代价必须值得付出。 子 Agent 提高了单次任务的成本,但如果它让主对话的缓存命中率维持高位,整体反而更省。判断标准是:这个任务如果交给主 Agent,是否会显著膨胀主上下文、降低后续所有交互的缓存效率?如果是,分出去让独立的子 Agent 处理,反而是经济的选择。
何时不该启动子 Agent。 任务简单(主 Agent 直接处理反而更快)、任务高度依赖主对话上下文(子 Agent 没有足够信息来完成)、串行依赖严重(子 Agent 之间的等待时间远超并行收益),这三种情况下,引入子 Agent 只是增加了复杂性,没有带来对应的价值。
未完成的方向
多 Agent 系统还有很多待完善的地方。
- 运行时文件锁:目前并行 Agent 的文件冲突靠角色级声明来避免。更精细的方案是任务级文件锁,按实际操作的文件路径做互斥
- 工作区隔离:每个并行 Agent 用独立的工作区,最后合并。适合多个开发子 Agent 同时改代码的场景
- 续聊机制:子 Agent 完成后可以向主 Agent 发消息继续讨论,形成多轮对话链
- 节点间消息传递:去中心化模式下节点之间的异步通信,让节点能直接协作
- 按文件集并行:分析文件依赖图后,操作不同文件集的子 Agent 自动并发
- 独立调度进程:把协调器从主进程中独立出来,支持更大规模的任务编排
- 子 Agent 专属模型:不同角色可以用不同的 LLM。调研用搜索增强的模型,写代码用代码模型,生图用多模态模型
这些都在计划中,会随着使用场景的扩展逐步实现。
下一篇聊用 AI 和用户共建产品。许愿池的故事。