多 Agent 路由与隔离
多 Agent 路由与隔离
学习目标
读完本章后,你将能够:
- 设计多 Agent 系统的隔离边界(数据、认证、会话、工具)
- 实现基于渠道/发送者/账户的消息路由
- 评估委托(Delegate)架构的适用场景和安全要求
前置知识
- 会话(Session)和轮次(Turn)概念
- 基础的认证和授权模型
核心概念
1. Agent 隔离模型
多 Agent 系统的核心挑战是隔离:每个 Agent 应有独立的数据、配置和运行时环境。
隔离维度:
| 维度 | 隔离内容 | 实现方式 |
|---|---|---|
| Workspace | 文件、bootstrap 配置、技能 | 独立目录 |
| Auth | API Key、OAuth Token | 独立配置文件 |
| Sessions | 对话历史、上下文状态 | 独立存储路径 |
| Tool Policy | 允许/禁止的工具列表 | 每 Agent 配置 |
| Model | 默认模型、fallback 链 | 每 Agent 配置 |
为什么需要隔离?
- 数据安全:防止 Agent A 读取 Agent B 的敏感会话
- 认证安全:避免认证配置冲突(如 OAuth token 混用)
- 行为一致性:每个 Agent 的上下文历史独立,不受其他 Agent 干扰
2. 消息路由策略
消息路由决定哪条消息由哪个 Agent 处理:
路由维度:
| 维度 | 粒度 | 适用场景 |
|---|---|---|
| 渠道(Channel) | 所有该渠道的消息 | 单 Agent 部署 |
| 发送者(Sender) | 按用户身份 | 多用户共享同一渠道 |
| 渠道+发送者 | 按渠道和用户组合 | 同一用户多渠道隔离 |
| 账户+渠道+发送者 | 最细粒度 | 多账户多渠道多用户 |
绑定(Bindings)机制:
- 将渠道账户绑定到特定 Agent
- 支持正则/通配符匹配发送者 ID
- 允许一个账户绑定多个 Agent(按发送者分流)
会话密钥(Session Key):
- 路由的结果是一个 session key,决定消息进入哪个会话
- DM 默认共享
mainsession key,可通过配置隔离
3. 会话隔离级别
对于直接消息(DM),系统通常提供多种隔离策略:
| 级别 | 行为 | 风险 |
|---|---|---|
| main(默认) | 所有 DM 共享一个会话 | 多用户时上下文泄露 |
| per-peer | 按发送者隔离(跨渠道) | 同一用户多渠道共享上下文 |
| per-channel-peer | 按渠道+发送者隔离 | 推荐的多用户配置 |
| per-account-channel-peer | 按账户+渠道+发送者隔离 | 最严格,配置最复杂 |
身份链接(Identity Links):
- 允许将同一人的多个渠道身份关联到同一个会话
- 解决 “用户从 Telegram 和 WhatsApp 联系你” 的场景
4. 委托架构(Delegate Architecture)
委托是 Agent 的一种特殊运行模式:Agent 拥有独立身份,代表人类或组织行动。
委托 vs 个人助手:
| 维度 | 个人助手 | 委托 |
|---|---|---|
| 身份 | 使用用户凭证 | 拥有独立凭证 |
| 发件人 | 显示为用户本人 | 显示为 Agent,标注 “on behalf of” |
| 信任边界 | 用户个人 | 组织策略 |
| 权限来源 | 用户授权 | 身份提供商委派 |
能力层级:
- Tier 1(只读+草稿):阅读组织数据、起草消息供人工审核
- Tier 2(代发):以 Agent 身份发送消息、创建日历事件
- Tier 3(自主执行):按计划自主执行 standing orders,无需逐动作审批
安全前提:
- 在授予任何身份提供商权限前,先建立 hard blocks(
SOUL.md+AGENTS.md) - 使用工具策略限制 Agent 能力边界
- 启用沙箱隔离高安全部署
- 配置完整审计日志
5. 跨 Agent 资源共享
完全隔离并非总是最优解。某些资源可以安全共享:
| 资源 | 共享方式 | 风险 |
|---|---|---|
| 技能(Skills) | 全局技能目录 + 每 Agent allowlist | 低 |
| 记忆搜索(Memory Search) | 跨 Agent QMD 集合配置 | 中(隐私泄露) |
| Provider 配置 | 全局 provider 列表 | 低 |
| 会话历史 | 不推荐共享 | 高(上下文污染) |
模型级 Agent 路由
除了基于渠道/身份的 Agent 路由外,每个 Agent 可以路由到不同的底层模型以实现成本与能力的最佳平衡:
| Agent 类型 | 推荐模型 | 原因 | 成本影响 |
|---|---|---|---|
| 规划/架构(planner/architect) | Opus | 复杂推理、多步骤规划 | 最高,但调用频率低 |
| 代码审查(code-reviewer) | Sonnet | 模式识别、静态分析 | 中等,调用频率高 |
| 构建修复(build-error-resolver) | Sonnet | 错误日志分析、增量修复 | 中等 |
| 探索/文件读取 | Haiku | 简单查找、阅读 | 最低,适合大量调用 |
| 后台观察(observer) | Haiku | 模式检测、置信度更新 | 最低,持续运行 |
这种模型级路由在实践中可带来 ~60% 的整体成本降低:高频低复杂度操作使用低成本模型,低频高复杂度操作保留高成本模型。
陷阱:
- 模型切换时状态不共享 —— 每个 Agent 的上下文是独立的,需要在委托时传递足够的上下文
- 低能力模型可能遗漏高能力模型能发现的问题 —— 需要在关键路径上设置”审查升级”机制
- 模型路由配置本身需要维护 —— 新增 Agent 类型时需要决定其模型分配
问题与规避
会话漂移
- 同一用户的多渠道消息进入不同会话,导致上下文断裂
- 对策:使用 identity links 关联同一人的多渠道身份
认证冲突
- 多个 Agent 共用
agentDir导致 auth profile 和会话冲突 - 对策:严格禁止跨 Agent 复用
agentDir
委托的权限膨胀
- Tier 3 委托的自主执行能力可能被滥用
- 对策:实施 hard blocks、工具策略、沙箱隔离三层防御;保留完整审计日志
设计取舍
进程内多 Agent vs 多进程
- 进程内:简化部署、资源共享、低延迟;单点故障风险
- 多进程:故障隔离、资源隔离;部署复杂、IPC 开销
- 折中:进程内运行 + 每 Agent 独立工作目录和配置
共享渠道账户 vs 独立渠道账户
- 共享账户(如一个 WhatsApp 号码):降低成本,但无法区分发件人身份
- 独立账户:完全隔离,但配置和维护成本高
参考来源
- Busoniu, L., Babuska, R., & De Schutter, B. (2008). A Comprehensive Survey of Multi-Agent Reinforcement Learning. IEEE Transactions on Systems, Man, and Cybernetics, Part C.
补充:Hermes Agent 的 Kanban 持久协作板与角色委派
来源:Hermes Agent(NousResearch/hermes-agent)tools/delegate_tool.py、tools/kanban_tools.py,commit 2517917
同步子代理委派(delegate_task)
Hermes 的 delegate_task 工具产生子 AIAgent 实例,采用同步等待模型:父 Agent 等待子 Agent 完成后才继续。
角色分级:
| 角色 | 能力 | 限制 |
|---|---|---|
leaf(默认) | 执行专注任务 | 不能调用 delegate_task、clarify、memory、send_message、execute_code |
orchestrator | 可继续生成子代理 | 受 max_spawn_depth(默认 2)限制 |
关键安全设计:
- 被禁止的工具列表是硬编码的(
DELEGATE_BLOCKED_TOOLS),防止子 Agent 与用户交互、写入共享记忆或产生跨平台副作用 - 审批回调:子 Agent 运行在 ThreadPoolExecutor worker 线程中,CLI 的交互式审批回调不继承。默认安装
_subagent_auto_deny自动拒绝危险命令 - 模块级
_active_subagents字典跟踪所有运行中的子 Agent,支持 TUI 可观测层和中断
Kanban 持久协作板
不同于临时的子代理委派,Hermes 的 Kanban 板提供SQLite 驱动的持久协作:
- Board 是硬边界:工人通过
HERMES_KANBAN_BOARD环境变量隔离,无法看到其他 Board - Tenant 是软命名空间:同一 Board 内不同业务通过 workspace-path + memory-key 隔离
- Dispatcher 循环(默认每 60 秒): reclaim stale claims → promote ready → atomic claim → spawn assigned profiles
- 失败自动阻塞:同一任务连续失败(默认 2 次)后自动阻塞,防止自旋循环
- 零 Schema 开销:工人不在 Kanban 任务内时,kanban_* 工具集从工具列表中移除
与通用委派的区别:delegate_task 是临时的、同步的、面向单次任务的;Kanban 是持久的、异步的、面向多 Agent 协作流水线的。
补充:CrewAI 的顺序与层级 Agent 路由
来源:CrewAI(crewAIInc/crewAI)lib/crewai/src/crewai/crew.py,commit 77a6127
顺序路由(Sequential Process)
CrewAI 最基础的多 Agent 路由是顺序链式传递:
Task 1 (Agent A) → Task 2 (Agent B) → Task 3 (Agent C) output output output ↓ ↓ ↓ context 传递给 context 传递给 最终输出 Task 2 Task 3关键设计:
- 每个
Task的context参数可以显式引用前序任务的输出 - 任务间无共享状态——数据通过
TaskOutput对象链式传递 ConditionalTask支持基于前一个任务输出决定是否跳过(检查conditional函数返回值)
陷阱:任务顺序固定,无法在运行时动态调整。如果 Task 2 需要 Task 3 的结果,必须重新排列 tasks 列表或使用 Hierarchical 模式。
层级路由(Hierarchical Process)
当 process=Process.hierarchical 时,CrewAI 创建一个 Manager Agent:
Manager Agent 的运作:
- 拥有自己的 LLM,通过提示词教导它如何分解任务、选择合适的 Agent
- Manager 不直接执行任务,而是将任务委派给最合适的 Agent
- 委派通过
DelegateWorkTool实现——Manager 调用该工具,目标 Agent 执行并返回结果
关键设计决策:
manager_llm或manager_agent必须显式指定——CrewAI 不自动创建 Manager 的 LLM- Manager 的提示词是硬编码的(i18n 模板),包含”如何分析任务”、“如何选择 Agent”的指令
- 委派工具支持
result_as_answer=True——Agent 的响应可以直接作为 Manager 的决策依据
与顺序模式的对比:
| 维度 | Sequential | Hierarchical |
|---|---|---|
| 控制流 | 固定顺序 | Manager 动态决定 |
| 适用场景 | 流水线式任务 | 需要智能分配的多变任务 |
| LLM 调用次数 | 少(每任务一次) | 多(Manager + 各 Agent) |
| 灵活性 | 低 | 高 |
陷阱:Hierarchical 模式下 Manager 的 LLM 调用次数可能远超 Sequential,因为 Manager 本身需要推理如何分配任务。对于简单的流水线任务,Sequential 更高效。
补充:LlamaIndex 的 Handoff 工具模式
来源:LlamaIndex llama-index-core v0.14.22,commit f027669
return_direct 工具作为 Handoff 机制
LlamaIndex 的多 Agent 编排(AgentWorkflow)不使用独立的路由器或 Manager Agent,而是通过 handoff 工具实现 Agent 间的控制权转移:
核心机制:
AgentWorkflow自动为每个 Agent 创建 handoff 工具,标记为return_direct=True- Agent 在推理过程中可以决定调用 handoff 工具,将控制权转移给目标 Agent
aggregate_tool_results步骤检测到next_agent状态后,切换到目标 Agent 继续执行can_handoff_to列表限制每个 Agent 可以交接的目标,防止无限循环
与 Router 模式的对比:
| 维度 | Handoff 工具 | Router Agent |
|---|---|---|
| 决策者 | 当前 Agent | 独立的 Router |
| 灵活性 | 高(每个 Agent 自主决定) | 中(Router 集中决策) |
| 可控性 | 低(Agent 可能意外交接) | 高(Router 统一约束) |
| LLM 调用 | 不额外消耗(嵌入在正常推理中) | 额外一次 Router 调用 |
from_tools_or_functions 工厂方法
AgentWorkflow.from_tools_or_functions() 根据 LLM 是否支持 function calling 自动选择 Agent 类型:
- 支持 function calling →
FunctionAgent(使用原生工具调用协议) - 不支持 →
ReActAgent(使用文本格式化的 Thought-Action-Observation 循环)
补充:Flowise 的双多 Agent 引擎
来源:Flowise(FlowiseAI/Flowise)packages/server/src/utils/buildAgentGraph.ts、packages/components/nodes/multiagents/Supervisor/Supervisor.ts、Worker/Worker.ts,commit bc22bf8
Flowise 在同一平台中同时支持两种多 Agent 协作模式:Supervisor/Worker(基于 LangGraph)与 Sequential Agents(顺序状态机)。
Supervisor/Worker 模式
核心机制:
- Supervisor 使用 LLM 进行路由决策:通过
RouteTool(结构化输出工具)选择下一个 Worker 或返回FINISH - LangGraph StateGraph 编译:Worker 节点注册为图节点,Supervisor 的 route 函数决定边的走向
- 递归限制:默认最大 100 步,防止无限路由循环
- 可选的 Summarization:最终输出可以是对话摘要而非原始结果
Supervisor Prompt 关键约束:
You are a supervisor tasked with managing a conversation between the following workers: {team_members}.Given the following user request, respond with the worker to act next.Each worker will perform a task and respond with their results and status.When finished, respond with FINISH.Select strategically to minimize the number of steps taken.设计决策:Supervisor 通过结构化输出(z.object({ reasoning, next, instructions }))确保路由决策可解释。reasoning 字段记录了选择特定 Worker 的原因。
与 CrewAI Hierarchical 的对比:
| 维度 | Flowise Supervisor | CrewAI Manager |
|---|---|---|
| 执行引擎 | LangGraph StateGraph | 自定义 DelegateWorkTool |
| 路由方式 | 结构化输出(tool calling) | 提示词教导 |
| 状态管理 | LangGraph CheckpointSaver | TaskOutput 链式传递 |
| 可视化 | React Flow 画布 | Python 代码定义 |
Sequential Agents 模式
Sequential Agents 是一种线性状态机模式,适合需要明确步骤顺序的多 Agent 流程:
| 节点类型 | 功能 |
|---|---|
| Start | 流程入口,接收用户输入或 Webhook |
| Agent | LLM Agent,可调用工具 |
| Condition | 条件分支(文本匹配) |
| ConditionAgent | LLM 驱动的条件分支(语义判断) |
| ToolNode | 工具执行节点 |
| Loop | 循环控制,支持最大迭代次数 |
| Iteration | 迭代执行 |
| LLMNode | 纯 LLM 调用(无工具) |
| CustomFunction | 用户自定义 JavaScript 函数 |
| ExecuteFlow | 嵌套执行另一个 Flow |
| End | 流程终止 |
| State | 状态读写 |
关键设计:
- 状态传递:
$state变量在节点间传递数据 - Webhook 引用解析:Start 节点支持
{{ $webhook.body.* }}、{{ $webhook.headers.* }}引用 - 原型链防护:Webhook 引用解析使用 lodash.get,但阻断了
__proto__/constructor/prototype路径 - HumanInput 节点:支持人机协作中断点,收集表单输入后继续执行
与 Supervisor/Worker 的对比:
| 维度 | Supervisor/Worker | Sequential Agents |
|---|---|---|
| 控制流 | LLM 动态路由 | 预定义的线性/分支流程 |
| 适用场景 | 任务类型不确定,需要智能分配 | 步骤明确的流水线 |
| LLM 调用 | 每个路由决策一次额外调用 | 无额外路由开销 |
| 调试性 | 路由路径不可预测 | 路径可预测,易于调试 |
补充:Oh-My-ClaudeCode 的四 Lane 架构与跨 Provider 编排
来源:Oh-My-ClaudeCode(Yeachan-Heo/oh-my-claudecode)docs/ARCHITECTURE.md、src/agents/definitions.ts、skills/team/SKILL.md,commit ed7800dd,版本 v4.14.4
四 Lane 架构
OMC 将 19 个专业 Agent 组织为四个独立的 Lane(车道),每个 Lane 覆盖软件开发生命周期的不同阶段:
Lane 职责:
| Lane | 职责 | 典型流水线 |
|---|---|---|
| Build/Analysis | 完整的开发生命周期:探索→分析→规划→设计→执行→验证 | explore → analyst → planner → architect → executor → verifier |
| Review | 质量门控,在交付前捕获正确性和安全问题 | executor → code-reviewer → security-reviewer |
| Domain | 领域专家,按需调用 | executor → test-engineer → qa-tester |
| Coordination | 挑战计划和设计,多角审查 | planner → critic → (revision) → critic |
Lane 间的协作模式:
- 顺序流转:Build 产出后送 Review 审查
- 按需调用:Domain 专家在需要时被主流水线调用
- 挑战循环:Coordination 对计划提出质疑,迫使重新规划
跨 Provider 异构编排
OMC 不仅编排 Claude Agent,还支持与外部 AI Provider 的异构协同:
CCG(Claude-Codex-Gemini)三模型协同:
用户请求 → Claude 协调器 ├──→ Codex CLI(架构验证、代码审查交叉检查) └──→ Gemini CLI(设计审查、UI 一致性,1M token 上下文) ←── 合成结果tmux CLI Worker(v4.4.0+):
omc team 2:codex "review auth module for security issues"omc team 2:gemini "redesign UI components for accessibility"omc team 1:claude "implement the payment flow"每个 Worker 是独立的 CLI 进程,在 tmux 分屏中运行:
- 按需启动:Worker 有任务时才启动
- 完成任务即消亡:无空闲资源消耗
- 进程隔离:每个 Worker 在独立的 tmux pane 中运行,互不干扰
混合编排的挑战与解决:
| 挑战 | 解决方式 |
|---|---|
| Provider 能力差异 | 通过角色分配(Codex 负责架构,Gemini 负责 UI)规避 |
| 上下文同步 | 每个 Worker 独立访问共享文件系统 |
| 延迟不均衡 | 使用 run_in_background 并行执行,等待最慢的完成 |
| 认证管理 | 各 Provider 使用各自的认证机制(API Key、OAuth),OMC 不介入 |
陷阱
- Agent 过多导致上下文爆炸:19 个 Agent 的描述如果全部加载会消耗大量上下文窗口
- Lane 间通信瓶颈:Build Lane 的产出必须传递给 Review Lane,信息传递可能丢失细节
- 跨 Provider 调试困难:当 Codex 和 Claude 给出矛盾的结论时,难以判断哪个正确
- tmux Worker 清理:如果 Worker 异常退出,tmux pane 可能残留,需要手动清理
补充:Agent Skills 的编排模式目录与反模式防御
来源:Addy Osmani / agent-skills v0.6.1,references/orchestration-patterns.md + agents/README.md + AGENTS.md,commit 6ce0298
agent-skills 项目定义了一套编排模式目录,明确区分了已批准的模式和应避免的反模式。这套目录的核心治理规则是:用户(或斜杠命令)是编排者。Persona 不调用其他 Persona。
五种已批准的编排模式
| # | 模式 | 结构 | 成本 | 适用场景 |
|---|---|---|---|---|
| 1 | 直接调用 | user → persona → report → user | 1 次往返 | 单视角单工件 |
| 2 | 单人斜杠命令 | /cmd → persona(with skill) → report | 同直接调用 | 重复工作流,省去每次重新解释 |
| 3 | 平行扇出 + 合并 | /cmd → fan-out → N personas → merge → verdict | N 个并行上下文 + 1 次合并 | 独立调查,墙时钟延迟重要 |
| 4 | 用户驱动的顺序流水线 | user runs /spec → /plan → /build → … | 每步 1 个上下文 | 有依赖关系,步骤间需要人工判断 |
| 5 | 研究隔离 | main → research sub-agent → digest → main continues | 1 个隔离上下文 | 大量阅读不应污染主上下文 |
四种反模式
| 反模式 | 结构 | 为什么失败 | 替代方案 |
|---|---|---|---|
| A: 路由角色 | work → router-persona → code-reviewer → router(paraphrase) → user | 纯路由层无领域价值,两次转述导致信息丢失 + 2× token 成本 | 完善斜杠命令和意图映射 |
| B: 角色调用角色 | code-reviewer 内部调用 security-auditor | 破坏单一视角设计,调用者转述丢失被调用者需要的上下文 | 在报告中推荐后续审计,由用户或斜杠命令执行 |
| C: 顺序编排器复述 | 自动按顺序调用 /spec → /plan → /build | 丢失人工检查点,每步转述上下文导致漂移,token 成本翻倍 | 保持用户为编排者,文档化推荐序列 |
| D: 深层角色树 | /ship → pre-ship-coord → quality-coord → code-reviewer | 每层增加延迟和 token 而无决策价值,调试变成多层调查 | 编排深度最多 1 层(斜杠命令 → 角色),合并在主 Agent |
决策流程
工作是否是一个视角对一个工件?├── 是 → 直接调用。停止。└── 否 → 同样的组合会重复吗? ├── 否 → 临时直接调用。停止。 └── 是 → 子任务是否独立? ├── 否 → 用户运行的顺序斜杠命令(模式 4)。 └── 是 → 平行扇出 + 合并(模式 3)。 用验证清单检查。 如果任何检查失败 → 回退到单人命令(模式 2)。平台强制约束
Claude Code 平台通过架构设计自动阻止了部分反模式:
- “Subagent 不能生成 Subagent” → 反模式 B(角色调用角色)和 D(深层角色树)无法存在
- “Team 不能嵌套” → 在 Agent Teams 层面同样阻止
与现有编排模式的对比
| 维度 | Agent Skills 编排目录 | CrewAI Hierarchical | Flowise Supervisor |
|---|---|---|---|
| 编排者 | 用户(或斜杠命令) | Manager Agent(LLM 驱动) | Supervisor Node(LLM 路由) |
| 自动化程度 | 低(人工决策每步) | 高(Manager 自动分配) | 中(LLM 动态路由) |
| 人工检查点 | 每步之间 | 无 | 无 |
| Token 成本 | 最低(无额外编排层) | 高(Manager 额外调用) | 中(路由额外调用) |
| 防漂移 | 天然(人工确认每步) | 需要设计 | 需要设计 |
Agent Skills 编排目录的独特价值在于:将用户定位为编排者,而非试图用 LLM 自动编排。这避免了上下文漂移和额外 token 成本,同时保留了人类在关键节点的判断力。