news 2026/9/20 12:58:59

oh-my-openagent Team Mode 实战指南:基于共享邮箱与任务清单的并行多 Agent 协作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
oh-my-openagent Team Mode 实战指南:基于共享邮箱与任务清单的并行多 Agent 协作

oh-my-openagent Team Mode 实战指南:基于共享邮箱与任务清单的并行多 Agent 协作

【免费下载链接】oh-my-openagentOmO: Just type "mass ulw" keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent

Team Mode 是 oh-my-openagent(OmO)提供的并行多 Agent 协调机制,参照 Claude Code 的 Agent Teams 设计,通过共享邮箱、共享任务清单与可选的 tmux 可视化布局,让一个 Lead 会话同时调度多个专用成员会话。本文以 docs/guide/team-mode.md 为主体,结合 packages/team-core 与 packages/omo-opencode 的源码实现,完整覆盖从配置启用、团队定义、成员资格、12 个team_*工具、生命周期到磁盘存储布局的全部细节。读完本文,你将能够独立搭建并调优一个受限并行、有界协调、可优雅关停的 Agent 团队。

什么是 Team Mode:默认关闭的并行协调层

Team Mode 是 OmO 中"受限并行(bounded parallelism)+ 有界协调"的实现:多个成员会话围绕**共享邮箱(mailbox)共享任务清单(tasklist)**协作,全部由当前会话(Lead)驱动。它默认关闭(OFF),需要通过 JSONC 配置显式开启。

从源码结构看,这套能力被拆成两层:

  • 领域原语层packages/team-core:无 harness 依赖的注册表、邮箱、任务清单、状态存储、worktree 与 tmux 布局原语,共 82 个 TypeScript 文件;
  • OpenCode 适配层packages/omo-opencode/src/features/team-mode:负责会话派生、hooks、工具注册与配置集成,被team_mode.enabled门控。

适用场景

  • 并行探索 + 受限协调:多个侦察成员同时扫读代码库,通过任务清单汇总发现,避免无边界发散;
  • 跨专用 Agent 拆分的长周期多步重构:不同成员各管一个模块,Lead 统一派活与收口;
  • 需要共享任务清单的"研究 + 实现"流水线:研究成员的产出以任务形式交接给实现成员。

如果只需要一次性委托单个子任务,且不需要团队级协调,应当走task(delegate-task)工具而不是 Team Mode——两者并不等价(详见下文"Team Mode 不做什么")。

启用 Team Mode:11 个配置字段全解

[opencode]块中写入配置:用户级写入~/.omo/omo.jsonc,项目级写入<project>/.omo/omo.jsonc

{ "team_mode": { "enabled": true, "max_parallel_members": 4, "max_members": 8, "tmux_visualization": false } }

启用后必须重启 opencode,12 个team_*工具才会出现在工具注册表中——工具注册通过 packages/omo-opencode/src/plugin/tool-registry.ts 的teamModeToolsRecord完成,且仅在启用时注册。

Schema 与默认值(11 个字段)

该 schema 的权威定义在 packages/team-core/src/config.ts#L3-L15,由 Zod 校验,字段与默认值如下:

字段类型 / 取值范围默认值含义
enabledbooleanfalse总开关
tmux_visualizationbooleanfalse是否为每个成员派生 tmux pane 布局
max_parallel_membersint1..84同时在飞的成员上限
max_membersint1..88硬性成员上限(同时约束团队规格)
max_messages_per_runint>=110000单次运行消息总量上限
max_wall_clock_minutesint>=1120单次运行墙钟时间上限
max_member_turnsint>=1500单个成员轮转次数上限
base_dir可选 string~/.omo覆盖团队规格 / 运行时 / worktree 的基础目录
message_payload_max_bytesint>=102432768单条消息体字节上限
recipient_unread_max_bytesint>=1024262144单收件人未读邮箱字节上限
mailbox_poll_interval_msint>=5003000收件轮询间隔(毫秒)

几点值得注意的实现细节:

  • base_dir未设置时,resolveBaseDir会展开为~/.omo(packages/team-core/src/team-registry/paths.ts#L68-L70),并支持~/~/形式的主目录展开;基础目录及其子目录(teamsruntimeworktrees)会在首次使用时以0o700权限创建并校验(ensureBaseDirs,同上文件#L209-L228)。
  • message_payload_max_bytes与消息 schema 中bodymax(32 * 1024)校验(packages/team-core/src/types.ts#L91-L103)一致,超限消息会在写入阶段被拒绝。
  • 所有运行期上限(bounds)会被固化到运行时状态中:maxMembersmaxParallelMembersmaxMessagesPerRunmaxWallClockMinutesmaxMemberTurns(packages/team-core/src/types.ts#L151-L157)。

启用后的验证与排障

启动日志会输出解析后的team_mode状态以及团队工具数量([tool-registry] Built tool registry条目)。若重启后工具仍未出现,检查oh-my-opencode.log中的已加载配置路径[tool-registry] Built tool registry条目。仓库还配有覆盖"最小配置 + 全新安装"场景的回归测试,专门防住这类配置未生效的回归。

定义团队:TeamSpec 与两种作用域

团队规格文件(TeamSpec)存放在:

  • 用户级:~/.omo/teams/{name}/config.json
  • 项目级:<project>/.omo/teams/{name}/config.json

同一团队名在两处同时定义时,项目级优先。这一优先级逻辑在discoverTeamSpecs中实现:先收集项目级规格,再跳过与项目级同名的用户级规格(packages/team-core/src/team-registry/paths.ts#L146-L181),并在冲突时输出team-spec-collision日志。

一个完整的团队规格示例:

{ "name": "ccapi-explorers", "description": "Explore the ccapi project structure.", "members": [ { "kind": "category", "name": "scout-1", "category": "deep", "prompt": "Scout the source directory for auth patterns." }, { "kind": "category", "name": "scout-2", "category": "quick", "prompt": "Scout tests for auth coverage." }, { "kind": "subagent_type", "name": "auditor", "subagent_type": "my-security-auditor", "prompt": "Audit the auth findings the scouts report." } ] }

字段约定与校验(来自 packages/team-core/src/types.ts#L58-L89 的TeamSpecSchema):

  • versioncreatedAt为可选项,loader 会自动填充(version固定为 1,createdAt默认当前时间戳);
  • name与成员name必须匹配正则^[a-z0-9-]+$
  • members至少 1 个、至多 8 个(与max_members上限一致);
  • Lead 无需声明:当前会话始终是 Lead,团队中没有 lead member 条目;
  • team_create也接受同样的内联形状:{ name, members: [{ name, category|subagent_type, prompt? }] }

loader 还会对常见错误给出专门的可读报错(packages/team-core/src/team-registry/loader.ts):成员数超过 8 报TEAM_MEMBER_LIMIT_EXCEEDED;同时指定categorysubagent_typeAMBIGUOUS_MEMBER_KIND;缺失kind判别字段报MISSING_MEMBER_KINDcategory成员缺少必填的promptMISSING_CATEGORY_PROMPT

成员种类与资格边界

两种成员种类

  • kind: "category":路由到分类 worker——一个由该分类的模型与技能配置的全新 worker 会话。prompt必填。若分类无法解析,直接以UNRESOLVABLE_CATEGORY失败,错误信息会列出可用分类。
  • kind: "subagent_type"(别名"agent"):直接调用omo.json中用户自定义的agentsprompt可选。kind 可根据你设置的字段自动推断,因此可省略kind本身。

两种成员的 schema 差异也在 packages/team-core/src/types.ts#L37-L49 中体现:category成员强制要求category+promptsubagent_type成员要求subagent_typeprompt可选。

谁能成为成员

  • 合格:任何可解析的 category,以及任何用户自定义 agent。
  • 解析期拒绝:curated 只读 agent(explorelibrarianplan-consultantplan-reviewer)与 ulw-loop 审查三件套(omo-senpi-code-revieweromo-senpi-qa-executoromo-senpi-gate-reviewer)。

拒绝原因在 packages/senpi-task/src/team/member-validator.ts#L25-L69 中给出:curated agent 是只读且进程内的,无法写入邮箱状态;reviewer 三件套被拒绝是因为进程模式成员会丢失审查指令与工具白名单。这两类都应通过task工具路由。

需要说明的是,成员词汇表是宿主相关的:senpi-task 宿主使用上述的CURATED_READONLY_AGENT_NAMES/ULW_REVIEWER_AGENT_NAMES校验;而在 team-core 的 OpenCode 适配层,AGENT_ELIGIBILITY_REGISTRY(packages/team-core/src/types.ts#L190-L237)给出了三级裁决:

裁决Agent说明
eligiblesisyphusatlassisyphus-junior直接可用
conditionalhephaestus默认缺少teammate: "allow"权限;要么打 D-36 补丁(在tool-config-handler.ts中加teammate: "allow"),要么改用subagent_type: "sisyphus"
hard-rejectoraclelibrarianexploremultimodal-lookermetismomusprometheus只读或仅 plan 模式,无法写邮箱;请改用 delegate-task

hard-reject 会在 TeamSpec 解析期直接抛错("Agent 'X' is read-only…"),错误信息会指引使用者改用 delegate-task——即解析期拒绝、运行时永不接触的原则。

生命周期:从 team_create 到 team_delete

  1. team_create—— 派生团队与各成员会话;
  2. Lead 通过team_send_messageteam_task_create派活;
  3. 成员通过team_task_updatestatus: "claimed")认领任务,完成后用team_send_message回报;
  4. team_shutdown_request→ 成员或 Lead 通过team_approve_shutdown/team_reject_shutdown应答;
  5. team_delete—— 清理运行时状态、worktrees 与(可选的)tmux 布局。

底层有几条关键不变量(packages/omo-opencode/src/features/team-mode/AGENTS.md):

  • 派生竞态安全:每次派生都在 sessionID 已知时同步调用registerTeamSession;所有 hooks 在loadRuntimeState之前先lookupTeamSession,避免 spawn-race 窗口;
  • 延迟确认:消息 fire-and-forget,收件方通过独立调用确认(ack);
  • 任务加锁:任务认领使用原子文件锁,并发认领可安全解决;
  • 原子写入:状态变更走"临时文件 + rename",见 packages/team-core/src/team-state-store/locks.ts;
  • 仅合格成员:解析期拒绝,运行时不再复查;
  • 禁止嵌套团队:成员不可调用team_create

运行时状态 schema(RuntimeStateSchema,packages/team-core/src/types.ts#L176-L188)记录version: 1、UUIDteamRunIdteamNamespecSourceproject/user)、createdAtstatusleadSessionId、可选tmuxLayoutmembersshutdownRequestsbounds。运行状态机为creating → active → shutdown_requested / deleting → deleted / failed / orphaned;成员状态机为pending → running → idle / errored / completed / shutdown_approved

12 个 team_* 工具

工具在启用后注册(teamModeToolsRecord),完整清单与职责如下:

工具用途
team_create派生团队(按命名或内联 TeamSpec)
team_delete拆除(仅 Lead 可用;存在活跃成员时拒绝,除非force: true
team_shutdown_requestLead 请求某成员收尾
team_approve_shutdown/team_reject_shutdown成员或 Lead 应答关停请求
team_send_message点对点邮箱;Lead 可*广播
team_task_create/_list/_update/_get共享任务清单的增、查、改、取
team_status聚合运行时视图(成员、任务、邮箱)
team_list已声明 + 活跃团队

实现分布在 packages/omo-opencode/src/features/team-mode/tools 下:生命周期类(lifecycle.tslifecycle-create-tool.tslifecycle-participant.tslifecycle-shutdown-tools.ts)、消息类(messaging.ts及其 live-delivery 子模块)、任务类(tasks.ts)、查询类(query.ts)。

消息kind有五种:messageshutdown_requestshutdown_approvedshutdown_rejectedannouncement(packages/team-core/src/types.ts#L4-L10);任务状态五种:pendingclaimedin_progresscompleteddeleted(同上#L14)。任务 schema 还支持blocks/blockedBy依赖关系与metadata,可构建任务间的先后依赖(同上#L105-L119)。

运行边界(Bounds 默认值)

  • 最多 8 个成员、4 个同时在飞;
  • 每条消息体最大 32 KB,每个收件人未读上限 256 KB;
  • 单次运行最多 10000 条消息、120 分钟墙钟、每成员 500 轮。

这些默认值都可被上文 11 字段配置覆盖,并固化进运行时状态供审计。

Worktrees:可选的成员级 git 工作树

在成员条目中加"worktreePath": "../wt-scout"即可为该成员分配独立工作树。路径支持相对文件系统路径或绝对路径;裸分支名被拒绝(避免把成员会话丢进无法工作的状态)。需要环境存在git。工作树创建、校验与孤儿清理由 packages/team-core/src/team-worktree 负责,目录约定为~/.omo/worktrees/{teamRunId}/{member}/

tmux 可视化:可选的面板布局

设置tmux_visualization: true后,每个成员会获得一个专属 tmux pane,通过opencode attach挂到该成员的会话上——pane 内运行成员完整的交互式 opencode TUI,可以实时观察流式输出。要求:

  • 运行在 tmux 会话内,且 PATH 上有 tmux;
  • 失败被隔离:缺少 tmux 永远不会阻塞团队创建——依赖探测在 packages/omo-opencode/src/features/team-mode/deps.ts#L16-L30 完成,tmux_visualization=true但 tmux 不可用时只打警告,运行时跳过布局;
  • pane 默认从process.cwd()启动;配置了 worktree 的成员从各自 worktree 启动;
  • team_delete关闭全部 pane 并拆除团队布局;单成员关停只关闭其 pane 并重新平衡剩余布局。

布局原语(网格 pane 排布、调用方 tmux 会话解析、布局重平衡、陈旧会话清扫)位于 packages/team-core/src/team-layout-tmux。

Team Mode 不做什么

  • 无嵌套团队:成员不能调用team_create(由team-tool-gatinghook 强制);
  • 无同步回复等待team_send_message是 fire-and-forget;
  • 成员被引导不要再生子:成员指导 prompt(member-guidance)会要求成员不再派生子会话;task工具未被预算门控到 0,但嵌套team_create被拒绝;
  • team_delete拒绝活跃成员,除非force: true

诊断:doctor 的 team-mode 检查

bunx oh-my-openagent doctor包含team-mode检查项,输出 tmux / git 可用性、已声明团队数量与活跃运行时目录数。其实现(packages/omo-opencode/src/cli/doctor/checks/team-mode.ts#L10-L33):

  • enabled为 false 时直接skipteam_mode: disabled);
  • 启用时探测tmux/git(缺失则warn),报告基础目录状态、teams/下声明数与runtime/下运行时目录数。

存储布局:邮箱、任务清单与投递预留

默认(base_dir未覆盖)磁盘结构如下:

~/.omo/ ├── teams/{name}/config.json # declared specs └── runtime/{teamRunId}/ ├── state.json # durable runtime state ├── inboxes/{member}/{uuid}.json # mailbox (atomic per-message files) ├── inboxes/{member}/.delivering-{uuid}.json # transient live-delivery reservation ├── inboxes/{member}/processed/ # acked messages ├── tasks/{id}.json # shared task list ├── tasks/claims/ # task claim records └── tasks/.highwatermark # tasklist id allocator

几点底层机制值得展开:

  • 投递预留(delivery reservation).delivering-{uuid}.json仅在消息正通过promptAsync实时投递时存在。投递成功则提交到processed/;失败则释放回{uuid}.json;若因崩溃遗留,团队恢复时会按10 分钟 TTL回收。listUnreadMessages会忽略点文件条目,因此兜底轮询绝不会重复注入已被预留的消息——这是"实时投递 + 轮询兜底"双通道不丢不重的前提(相关实现见 packages/team-core/src/team-mailbox)。
  • 任务 ID 分配:任务 ID 为十进制自增(.highwatermark分配器),与 senpi 的st_*任务 ID 体系区分;任务认领使用tasks/claims/{id}.lock文件锁实现原子认领(packages/team-core/src/team-registry/paths.ts#L116-L123)。
  • 路径安全:所有运行时路径都经过resolveContainedPath校验,拒绝..、空段、含/\的段与 NUL 字符,越界直接抛TeamPathTraversalError(packages/team-core/src/team-registry/paths.ts#L43-L66),任务 ID 还额外要求纯数字。
  • senpi-task 项目的存储差异:对 senpi-task 项目,状态目录默认解析到<project>/.omo/senpi-task,团队运行时路径随之变为<stateDir>/teams/runtime/<teamRunId>/...(详见 packages/team-core/AGENTS.md 与 packages/senpi-task/src/team/storage.ts)。

源码地图:继续深入的方向

  • 用户文档:docs/guide/team-mode.md(本文主体);
  • 配置 schema:packages/team-core/src/config.ts、packages/omo-opencode/src/config/schema/team-mode.ts;
  • 领域类型与资格注册表:packages/team-core/src/types.ts;
  • 规格加载与校验:packages/team-core/src/team-registry(loader.tsvalidator.tspaths.tsteam-spec-input-normalizer.ts);
  • OpenCode 适配层:packages/omo-opencode/src/features/team-mode/AGENTS.md(12 工具、模块布局、集成点与反模式)及其tools/目录;
  • 领域原语总览:packages/team-core/AGENTS.md(注册表、邮箱、任务清单、状态存储、worktree、tmux 布局六大原语);
  • 依赖探测与诊断:packages/omo-opencode/src/features/team-mode/deps.ts、packages/omo-opencode/src/cli/doctor/checks/team-mode.ts;
  • senpi 成员校验:packages/senpi-task/src/team/member-validator.ts。

自检提示:启用后若team_*工具未出现,按顺序检查配置是否落在正确作用域(用户或项目)、是否已重启 opencode、oh-my-opencode.log中是否出现[tool-registry] Built tool registry;若团队成员创建失败,优先查看错误码(UNRESOLVABLE_CATEGORYTEAM_MEMBER_LIMIT_EXCEEDEDAMBIGUOUS_MEMBER_KINDMISSING_MEMBER_KINDMISSING_CATEGORY_PROMPT、hard-reject 的只读 agent 提示),它们已覆盖绝大多数配置失误。

【免费下载链接】oh-my-openagentOmO: Just type "mass ulw" keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 12:54:11

3 步 + 2 个开关:PowerToys FancyZones 窗口管理实战指南

3 步 2 个开关&#xff1a;PowerToys FancyZones 窗口管理实战指南 【免费下载链接】PowerToys Microsoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows 项目地址: https://gitcode.com/GitHub_Trending/po/PowerTo…

作者头像 李华
网站建设 2026/9/20 12:53:53

Docker 国内镜像加速配置指南:多源组合与 daemon.json 实战

1. 为什么国内用 Docker 总卡在拉镜像这一步如果你在国内做开发&#xff0c;大概率经历过这种场景&#xff1a;docker pull一条命令敲下去&#xff0c;进度条像蜗牛爬&#xff0c;几分钟后直接报net/http: TLS handshake timeout或者context deadline exceeded。这不是你的网络…

作者头像 李华
网站建设 2026/9/20 12:53:46

腾讯Agent Suite办公智能体套件:从单点聊天到工作流智能

先说结论&#xff1a;如果2025年你还在把“智能体”理解成一个会聊天的窗口&#xff0c;那大概率已经落后半步了。真正让智能体产生业务价值的&#xff0c;是一整套能编排、能调工具、能对接行业流程的“套件”&#xff0c;而不是单点模型能力。腾讯这轮Agent Suite办公智能体套…

作者头像 李华
网站建设 2026/9/20 12:53:06

Elasticsearch 8.16.1中文分词插件HanLP实战指南

简介&#xff1a;这是面向 Elasticsearch 8.16.1 的中文分词插件&#xff0c;将 HanLP 的能力封装为 ES 原生分词器&#xff0c;让 Elasticsearch 无需依赖外部接口即可直接完成中文分词、词性标注等自然语言处理&#xff0c;适合在搜索、日志分析、内容管理等场景中处理大量中…

作者头像 李华
网站建设 2026/9/20 12:51:16

GLM 5.3 Flash 上了 LiveCodeBench:用 TaoToken 同一把 Key 跑同一题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华