66caeef35c
LLM 自主在 agent 间路由/委派:orchestrator=ReAct(Eino 出机器),编排认知按 Anthropic orchestrator-worker 配方(出脑子)。专家=包成工具的子 agent(agent-as-tool),lead 给 每个专家写定制简报(brief)后并行派发、综合。方案见 MULTI_AGENT.md。 为什么 agent-as-tool 而非 Eino host:host 的 specialist 拿原始输入(preHandler return state.msgs),传不了 lead 写的定制简报,而定制简报正是 Anthropic 多智能体的 精髓。agent-as-tool 让 orchestrator 自己 emit 工具调用、参数 brief 即简报。 = OpenAI agent.as_tool() / Anthropic 研究系统的 orchestrator-worker。 - coordinator.go: specialistTool(react.Agent/ChatModel 包成 InvokableTool,入参 brief, 精炼返回) + parseSpecialists/buildSpecialists(带工具→react,不带→ChatModel,MCP 工具 按 spec.tools 过滤) + runCoordinator(lead 提示词=Anthropic 配方) + leadOrchestratorPrompt。 - 双路接入 execDSLNode(compose)+ runGraph(graph.go)的 case coordinator。 - 护栏:禁套娃(专家是内联叶子)/ MaxStep / 专家 I/O 计入共享 Budget / 降级(无 ToolCallingModel 或 0 专家 → runAgent)。 - streamAgentReply:抽出 runReactAgent 与 runCoordinator 共用的流式回流尾段。 - 复用即得:evaluator-optimizer=harness 低分纠偏;成本天花板=预算护栏;上下文隔离= 专家独立 react.Agent;观测=每次派发落 agent 轨迹。 测试:parseSpecialists / agent-as-tool 包装(brief 透传+精炼返回+失败作观察) / 降级。 live 验证(真 deepseek):两专家**并行派发**、lead 给各自写**不同定制简报**、最终 **综合**(非拼接)成稿,评测 1.00。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.8 KiB
4.8 KiB
多智能体方案(Eino × Anthropic 融合)
现状:单 agent 自主调工具(ReAct)已落地;多 agent 静态接力(DSL 图)已落地。 缺的是 LLM 自主在 agent 之间路由/委派 —— 即"多智能体协同"。本方案是它的落地设计。
设计原则:Eino 出机器,Anthropic 出脑子
| 层 | 谁的强项 | 怎么用 |
|---|---|---|
| 运行时机器 | Eino | react.Agent + ToolsNode(并行工具调用)+ 流式 + 预算/熔断 + callbacks 观测 + checkpoint |
| 编排认知 | Anthropic | lead 的"分解→定额→写定制简报→综合"全在提示词;worker 返回精炼结论而非原始堆料 |
| 闭环纪律 | 两者皆有现成 | evaluator-optimizer = 复用 harness 低分自动纠偏;成本天花板 = 复用预算护栏 |
关键判断:用 agent-as-tool,不用 host.NewMultiAgent。
Eino 的 host 模式里,specialist 拿到的是原始输入(preHandler return state.msgs),host 的工具参数只是路由理由、不传给专家当任务。而 Anthropic 多智能体的精髓正是 lead 给每个 worker 写定制简报。host 表达不了,故用 agent-as-tool:orchestrator 自己 emit 工具调用,参数 brief 就是它写的简报。host 留作"无简报简化版"备选。
业界对照:本方案 = OpenAI Agents SDK 的
agent.as_tool()+ handoff 思路,= Anthropic 研究系统的 orchestrator-worker。心智模型与头部项目通用、可迁移。
v1 架构
coordinator 节点
└─ orchestrator = react.Agent(lead 提示词 = Anthropic 配方)
├─ tool: specialist_A (= 包成工具的子 react.Agent / ChatModel)
├─ tool: specialist_B
└─ (可选) MCP 工具
流程:lead 分解任务 → 给每个专家写 brief → 并行派发(并行 tool-call)
→ 收齐精炼结论 → lead 在最后一轮综合成稿
- 并行:orchestrator 一轮 emit 多个 tool-call → Eino ToolsNode 并发跑专家(Anthropic 的并行 breadth)。
- 综合:ReAct 天然在最后一轮综合,不需要单独 summarizer。
- 上下文隔离:每个专家是独立 react.Agent、独立消息上下文(原生)。
- 定制简报:专家工具入参
brief= lead 写给它的子任务/期望输出/边界。 - 精炼返回:专家系统提示词追加"只回结论要点,不堆原文",省 orchestrator 综合时的上下文。
与现有 harness 的融合点(零/少新代码)
- evaluator-optimizer:协调者综合稿照常进 harness 评测 + 低分自动纠偏 —— 已有。
- 成本天花板:协调者 + 专家 I/O 共享
harness.Budget,触顶中止 —— 已有,专家 I/O 在 agent-as-tool 边界计入。 - 观测:每次派发落一条
kind=agentexec 事件(brief + 精炼结论)+ OTel 嵌套 span。
落地增量
增量 1 —— 后端核心(dispatcher/internal/eino/coordinator.go)✅ 本次
specialistTool:react.Agent / ChatModel 包成 InvokableTool,入参brief,精炼返回。parseSpecialists/buildSpecialists:从节点 config 的agents[]建专家工具集(带工具→react;不带→ChatModel;MCP 工具按spec.tools过滤)。runCoordinator:orchestrator = react.Agent(lead 提示词),双路接入execDSLNode(compose)+runGraph(graph.go)的case "coordinator"。- 护栏:禁套娃(专家是内联叶子,不能再是 coordinator)/ MaxStep / 共享 Budget / 降级(无 ToolCallingModel 或 0 专家 → 退
runAgent)。 streamAgentReply:抽出 runReactAgent 与 runCoordinator 共用的流式回流尾段。
增量 2 —— 前端(desktop Studio)
- nodeCatalog 加
coordinator节点 +agentList字段(子智能体卡片:名称/用途/系统提示词/工具多选)。 - 运行轨迹:专家调用渲染成可展开子节点(显示 brief + 精炼结论)。
增量 3(可选,按场景)—— handoff / 可中断多智能体
- 真需要"专家间多轮协商/控制权移交"才上:迁
adk(SetSubAgents+Transfer),复用 HITL 的 checkpoint 做可中断恢复。不推翻 v1。
开放决策
| 决策 | v1 取舍 |
|---|---|
| 专家定义 | 内联(写在协调者节点);注册表(跨节点复用)留 v1.5 |
| Summarizer | 不单设,ReAct orchestrator 末轮自综合 |
| 专家带工具 | 支持但可选(无 tools = 纯对话专家,有 tools = react 子 agent) |
DSL 形态
{ "id":"coord", "kind":"coordinator", "config":{
"system":"任务背景(可选)",
"agents":[
{"name":"legal", "use":"法律条款/合规问题", "system":"你是法律专家…", "tools":["wiki_search"]},
{"name":"finance", "use":"财务/数字测算", "system":"你是财务专家…"}
]
}}