数据截至 (上游 commit f546440b04bc)
open-multi-agent — 这是什么 · 全景 · 阅读地图
30 秒导读: open-multi-agent(简称 OMA)是一个给 TypeScript 后端用的多智能体编排框架。你给它一个目标(一句自然语言),一个"协调者(coordinator)" agent 会在运行时把目标拆成一张任务 DAG(有向无环图),让互不依赖的任务并行跑,最后把各任务结果合成一份答案。一行
runTeam(team, goal)就跑起来。本篇只建立大盘认知,不深入任何单个子系统——细节路由到各章。
1. 这是什么(零基础也能懂)
一句话定义。 OMA 是一个"你说目标、它排活并干完"的多智能体编排引擎,原生长在 Node.js / TypeScript 里。
解决什么问题。 假设你要让一队 AI 协作完成一件复杂事——"给待办清单做一套 REST API":要先设计接口、再写实现、同时搭测试、最后有人 review。传统"图优先(graph-first)"框架(如 LangGraph)要你开跑前手工画好每个节点和每条边。OMA 反过来:你只描述目标,拆图这件事交给协调者在运行时做。README 把这句话印在最显眼处(README.md:44 Your engineers describe the goal, not the graph.)。
给谁用。 用 TypeScript 写后端、想加一层"多 agent 协作"、又不想为此另起一个 Python 服务的团队(README.md:78 vs. CrewAI 段)。
它能做什么(功能一览):
- 目标驱动的自动编排:一次
runTeam完成拆解 → 并行 → 合成。 - 三种执行模式:单 agent、自动编排团队、显式任务流水线(下面第 2 节)。
- 混用 13 个内置模型 provider + 任意 OpenAI 兼容端点,一支队伍里自由搭配。
- 工具系统:6 个内置工具(
bash/file_*/grep/glob)默认全部拒绝,按需授权;可自定义工具、接 MCP。 - 生产控件:token 预算、重试退避、上下文压缩、检查点恢复、观测面板、密钥自动脱敏。
用起来什么样(最小真实用例)。 下面是 README 的官方最小示例,核心就是最后那行 runTeam——建一支队伍,给一个目标,拿回结果(节选自 packages/core/README.md:81):
const orchestrator = new OpenMultiAgent({ defaultProvider: 'openai', defaultModel: model })
const team = orchestrator.createTeam('api-team', { name: 'api-team', agents, sharedMemory: true })
// 给目标,不给图。协调者自己拆任务、并行、合成。
const result = await orchestrator.runTeam(
team,
`Create a REST API for a todo list in ${process.cwd()}/.agent-workspace/todo-api/`,
)
console.log(result.success, result.totalTokenUsage.output_tokens)
一句话直觉/类比。 把 OMA 当一个项目经理:你交给它一句"目标",它自己拆成工单、分给合适的人、能并行的并行、有人卡住就绕过、最后把大家的产出汇成一份交付。你不用画甘特图,它当场排。
2. 顶层全景(它大概怎么转)
三种执行模式:先分清你在用哪一种
OMA 对外的门面类叫 OpenMultiAgent(packages/core/src/orchestrator/orchestrator.ts:396)。它有三个入口方法,复杂度递增,这是理解全库的第一个岔路口:
| 模式 | 方法 | 谁来拆任务 | 什么 时候用 |
|---|---|---|---|
| 单 agent 一发入魂 | runAgent(config, prompt) | 没有任务,一个 agent 跑一个 prompt | 简单一次性问答 |
| 自动编排团队(招牌功能) | runTeam(team, goal) | 协调者 agent 运行时拆 | 给目标、让它自己规划并执行 |
| 显式任务流水线 | runTasks(team, tasks) | 你自己写好 dependsOn | 你已经知道任务图长什么样 |
三个方法的类文档就写在源码里:runAgent(orchestrator.ts:1595,"single agent, one-shot")、runTeam(orchestrator.ts:1684,标注 KILLER FEATURE)、runTasks(orchestrator.ts:2199,"no coordinator agent is involved")。另有 runConsensus(orchestrator.ts:2240,提议者→裁判校验)是可信度增强,见第 05 章。
runTeam 和 runTasks 的关键区别:前者多了一个协调者拆解 + 最后合成的环节;后者跳过协调者,你给的任务直接进队列(orchestrator.ts:2192 注释:"Simpler than runTeam: no coordinator agent is involved")。
一张顶层图:runTeam 主线怎么流
这是全库最核心的一条链路。怎么读这张图:从上到下是一次 runTeam 的时间顺序;协调者出现两次(开头拆解、结尾合成),中间是"排活—调度—并行执行—写记忆"的循环。
你的输入: 一个 team(agent 名册) + 一个 goal(自然语言)
│
▼
┌────────────────────────────────┐
│ OpenMultiAgent (门面 / 编排器) │ orchestrator.ts
│ runTeam / runTasks / runAgent │
└────────────────┬─────────────────┘
│
①简单目标就短路,直接派给最合适的 agent(不拆)
│ isSimpleGoal() 命中?
▼ 否 → 走完整编排
┌────────────────────────────────┐
│ Coordinator(临时协调者 agent) │ ②拆解
│ 收「目标 + 名册」→ 吐一个 JSON │
│ 任务数组(标题/描述/负责人/依赖)│
└────────────────┬─────────────────┘
│ 解析 JSON,标题依赖 → 任务 ID
▼
┌────────────────────────────────┐
│ TaskQueue(依赖感知队列) │ task/queue.ts
│ pending → blocked → ready │
│ 某任务完成 → 自动解锁下游 │
│ 某任务失败 → 级联标记下游 │
└───────┬──────────────────┬───────┘
│ 谁没指定负责人? │ 哪些任务 ready?
▼ ▼
┌───────────────────┐ ┌──────────────────────┐
│ Scheduler(调度) │ │ AgentPool(并发池) │ agent/pool.ts
│ 4 种分配策略 │ │ Semaphore 限并发 │
│ 给任务挑 agent │ │ 独立任务并行跑 │
└───────────────────┘ └──────────┬───────────┘
│ 每个被选中的 agent
▼
┌──────────────────────────┐
│ Agent loop(对话循环) │ agent/runner.ts
│ 调模型 → 抽工具调用 → │
│ 执行工具 → 回填 → 再循环 │
│ 直到 end_turn │
└──────────┬────────────────┘
│ 任务产出
▼
┌──────────────────────────┐
│ SharedMemory(共享内存) │ memory/shared.ts
│ <agentName>/<key> 命名空间 │
│ 下游 agent 读上游的产出 │
└──────────┬────────────────┘
│ 所有任务跑完
▼
┌────────────────────────────────┐
│ Coordinator(再登场) │ ③合成
│ 读全部任务产出 → 合成最终答案 │ runCoordinatorSynthesis()
└────────────────┬─────────────────┘
▼
返回 TeamRunResult(含最终答案 + token 用量)