# 多智能体方案（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=agent` exec 事件（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 形态

```json
{ "id":"coord", "kind":"coordinator", "config":{
  "system":"任务背景（可选）",
  "agents":[
    {"name":"legal",   "use":"法律条款/合规问题", "system":"你是法律专家…", "tools":["wiki_search"]},
    {"name":"finance", "use":"财务/数字测算",     "system":"你是财务专家…"}
  ]
}}
```
