oh-my-openagent Planner 注入指南:Prometheus 规划 Agent 的决策完备计划工程

原创2026-09-20 11:36:161,819 阅读
文章标签:人工智能AI Agent代码智能体多智能体MCP ClientsAgent 编排

oh-my-openagent Planner 注入指南:Prometheus 规划 Agent 的决策完备计划工程

本文围绕 oh-my-openagent 中 Prometheus 规划 Agent 的精简 Planner 注入文档(planner.md)展开,说明它如何作为"简洁规划教义"与完整的 ulw-plan 技能协作,以及如何约束规划 Agent 只产出"决策完备(decision-complete)"的计划而绝不越权实现。读完本文,你将掌握 Prometheus 的职责边界、规划教义、证据与 QA 纪律,以及它在仓库中的注入与加载链路,可直接用于理解或复用这一规划 Agent 的提示词工程方案。

一、Planner 注入文档在仓库中的定位

planner.md 位于 packages/prompts-core/prompts/ultrawork/ 目录下,是 oh-my-openagent 中 Ultrawork 模式(ultrawork) 提示词变体(variant)集合的一员。与其同级的变体还包括 default.md、gpt.md、gemini.md、glm.md 和面向 Codex 的 codex.md,每个变体针对不同的执行环境或角色裁剪同一套工作哲学。

在 ultrawork-prompts.ts 中,所有变体被统一注册为 ultraworkPromptVariants:

export const ultraworkPromptVariants = {
  planner: {
    kind: "bundled",
    content: plannerPrompt,
    filePath: "packages/prompts-core/prompts/ultrawork/planner.md",
  },
  gpt: { /* ... */ },
  gemini: { /* ... */ },
  glm: { /* ... */ },
  default: { /* ... */ },
} satisfies VariantTable

这里有一个值得注意的工程细节:每个变体都携带 kind: "bundled" 与 filePath 两个字段,意味着提示词以"打包资源"的形式随包分发,同时保留源文件路径用于追溯。测试 ultrawork-prompts.test.ts 甚至直接校验 content 与磁盘文件逐字节一致(expect(codexVariant.content).toBe(readFileSync(codexPromptPath, "utf8"))),确保打包内容与源文档永不漂移。

这些提示词在运行时由 loader.ts 的 loadPrompt / loadPromptSync 加载:解析 frontmatter 后,通过 applyRuntimeInjections / applyRuntimeInjectionsSync 将 {{placeholder}} 形式的占位符替换为运行时解析器返回的真实内容,再注入到最终提示词中——这正是"Planner Injection(规划器注入)"这一标题的由来。

二、角色设定:Prometheus——只做计划,绝不实现

planner.md 开篇即给出角色锚点:

You are Prometheus, a planner agent. You create plans. You do not implement.

Prometheus 是一个纯规划 Agent。这句话是整个注入文档的基石,也是后续所有教义与纪律的出发点:它可以读、可以搜、可以分析、可以写规划产物,但永远不写产品代码。

这一角色设定并非只存在于这一个文件。在同仓库的完整规划顾问提示词 prometheus/default.md 中,同样的原则被表述得更加具体:

You are a PLANNER. You read, search, and write only plan artifacts under .omo/; you never implement - not directly and not by proxy: a subagent you spawn that edits product code is you implementing.

注意其中"by proxy(通过代理)"的表述:Prometheus 不能通过派生子 Agent 来间接实现——任何由它派生的、会编辑产品代码的子 Agent,都被视为它本人在实现。这是防止规划 Agent 变相越权实现的关键防线。从源码结构看,omo-opencode/src/agents/prometheus/AGENTS.md 等位置也延续了同一角色设定。

三、规范工作流:以 ulw-plan 技能为准绳

planner.md 的"Canonical Workflow(规范工作流)"一节明确了职责分工:

Use the path-backed ulw-plan skill as the canonical full planning workflow. Load it when planning depth, interview discipline, adversarial review, or plan artifact structure matters. This injected prompt is only the concise planner doctrine; do not recreate the full shared skill workflow here.

这句话传达了分层设计思想:

  1. 注入文档是"精简教义":只承载不可妥协的原则与边界,适合随 Ultrawork 模式常驻上下文;
  2. ulw-plan 技能是"完整工作流":当需要规划深度、访谈纪律、对抗性评审或计划产物结构时,必须加载该技能,而不是在注入文档里重复实现完整流程。

ulw-plan 技能本体位于 packages/shared-skills/skills/ulw-plan/SKILL.md,其核心承诺是"把模糊或庞大的请求转化为一份下游 worker 无需再次访谈即可执行的决策完备工作计划"。值得注意的是,该技能在仓库中被多处同步分发,例如 packages/omo-senpi/skills/ulw-plan/SKILL.md 与 packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md,说明同一套规划工作流被 senpi 与 codex 两大执行 harness 共同采用。

技能激活本身还有强制仪式:首次激活时第一行用户可见输出必须是 ULW-PLAN MODE ENABLED!,随后立即用一句话声明"从此刻起我以 Prometheus(规划顾问)身份工作,在您明确同意前绝不开始实现"的工作契约——这与 planner.md 的职责边界一脉相承。

四、规划教义:六条不可妥协的纪律

planner.md 的 "Planner Doctrine" 一节是全文的核心,六条纪律共同定义了一个合格规划 Agent 的行为边界:

4.1 保持规划者作用域

Stay in planner scope. Read, search, analyze, and write planning artifacts only.

规划 Agent 的全部活动被限制在四件事:读(Read)、搜(Search)、分析(Analyze)、写规划产物(Write planning artifacts)。除此之外的一切动作都在作用域之外。

4.2 产出单一、决策完备的计划

Produce one decision-complete plan that a downstream worker can execute without another interview.

"决策完备"是规划的北极星:下游执行 worker 没有访谈上下文,它拿到的计划必须已消除所有歧义。结合 full-workflow.md 的展开说明,决策完备意味着:每一个决策都已做出、每一个歧义都已解决、每一个模式都带有具体路径引用,执行者需要做的判断调用数为 零。也正因为如此,规划者对计划中的 todo 要写明"精确路径、'每个 X 中的每一个'、明确的 Must-NOT-Have",绝不给实现者留下自由裁量空间。

4.3 先探索,后提问

Explore before asking. Ask only for decisions or ambiguities that repo evidence cannot resolve.

提问是最后手段。凡是仓库证据能够回答的(可发现事实),一律通过探索解决并给出带引用的确认;只有仓库无法回答的偏好/取舍(owner-decision)才值得占用用户时间。在 ulw-plan 技能中,这一原则被进一步形式化为"两道过滤器":

  1. 收集到的证据能否回答?→ 能,就去探索;
  2. 用户已表达的意图加上可辩护的默认值能否回答?→ 能,就采纳默认并记录。

但有一类问题永远越过过滤器、必须以问题形式存活:不可逆/破坏性/安全关键的操作,以及用户长期承受的跨切面产品选择(公开配置面、分发/打包方式、外部依赖或固定 SHA、数据/模式形状、真实预算/付费开销、预期规模或容量目标、目标受众/合规限制)。

4.4 仓库探索工具的分工

For repo how/where/what/flow questions: LSP for symbols, the ast-grep skill for structure, Read/Grep/Glob for text.

针对不同的仓库问题类型,规划 Agent 使用不同的工具组合:

问题类型 推荐工具 用途
符号级(how/where) LSP 解析符号定义与引用
结构级(what/flow) ast-grep 技能 按 AST 模式理解代码结构
文本级 Read / Grep / Glob 直接检索与阅读文本

这一分工在 planner.md 中仅一句带过,但仓库中对应能力均有实体实现,例如 packages/lsp-core 提供 LSP 能力、packages/ast-grep-mcp 提供基于 ast-grep 的 MCP 工具。规划 Agent 在动手提问前,应当先按这套分工把仓库"榨干"。

4.5 显式化依赖顺序

Make dependency order explicit: waves, task ownership, acceptance criteria, and verification channels.

计划不能是一张扁平的待办列表,而必须是显式依赖图:每个任务属于哪个 wave(波次)、由谁负责(task ownership)、验收标准是什么(acceptance criteria)、通过哪个通道验证(verification channels)。在 scaffold-plan.mjs 生成的计划骨架中,## Execution strategy 小节内嵌了"并行执行波次(5–8 个 todo 为一波)"与"依赖矩阵"(Todo / Depends on / Blocks / Can parallelize with)两个结构化区域,正是这条纪律的落地形态。

4.6 绝不实现,需要时交接

Do not implement. Do not edit product code, tests, loaders, runtime wiring, config, or docs as part of planning. If the user asks you to implement, state that you are the planner and hand off to the execution workflow.

第六条把"不实现"的边界清单化:产品代码、测试、加载器、运行时接线、配置、文档——全部在禁止之列。当用户要求实现时,规划 Agent 的正确反应是声明自己的规划者身份并把任务交接给执行工作流(例如 $ulw-execute),而不是就地变身实现者。ulw-plan 技能中还有一句"模式粘性(Plan mode is sticky)"的警告:"do X / fix X / build X / just do it" 统统意味着"规划 X"——即使任务很小、很明显、很紧急,也绝不开始实现,包括通过子 Agent 间接实现。

五、证据与 QA 纪律:没有证据就没有完成

planner.md 的 "Evidence And QA" 一节定义了规划产物的质量底线:

5.1 计划必须命名证据,而非仅仅命名命令

Every plan must name the evidence needed to prove the work, not just the commands to run.

每个计划都要写清楚"用什么证据证明工作完成",而不是只罗列要执行的命令。这要求计划中每个验收标准都是 Agent 可执行的(如确切的命令或断言),并且每个 QA 场景都指名"确切的工具 + 确切的调用方式"。在计划骨架中,每个 todo 都要求携带 Acceptance criteria (agent-executable) 与 QA scenarios (happy + failure, evidence <path>) 字段,正是这条纪律的模板化强制。

5.2 QA 期望与风险匹配

Include QA expectations sized to risk: tests, real-surface/manual QA, cleanup receipt, and residual risks.

QA 的强度要与风险匹配,通常包含四类要素:

  • 测试(tests):有代码接缝处写测试;
  • 真实表面/手工 QA(real-surface/manual QA):通过 tmux 转录、curl 状态与响应体、浏览器/Playwright 断言等真实用户可见表面验证;
  • 清理凭证(cleanup receipt):QA 过程中产生的临时资源(脚本、tmux 资产、浏览器上下文、PID、端口、容器、临时目录)都要有拆除 todo,并捕获拆除凭证——残留进程/会话/端口/临时目录 = 未完成;
  • 残余风险(residual risks):明确列出计划完成后仍存在的风险。

仓库中的 ulw-plan 技能甚至给出了"双重证据工件"要求:每个场景需要 RED→GREEN 证明(测试运行器在变更前后的输出)加真实表面工件(用户实际看到的东西)两份证据,单纯"测试通过"不足以证明完成。

5.3 成功日志只是"声称",不是事实

Treat success logs as claims until the exact command, artifact, and assertion are verified.

成功日志、子 Agent 摘要、grep 命中,都只是"声称(claims)"——直到验证者确认确切的命令、产物与断言真实执行过。这是对"看起来成功"的防御:一个日志说成功,不等于工作真的完成。在完整工作流中,这对应"拒绝误导性成功输出(misleading success output)"的对抗性验证原则。

5.4 记录对抗性探针

Record adversarial probes when relevant: stale state, dirty worktree, misleading success output, and prompt injection.

规划过程中,当场景相关时应主动记录四类对抗性探针:

探针 含义 典型场景
stale state 陈旧状态 源与打包产物的分裂、旧线程上下文
dirty worktree 脏工作树 存在未关联的已修改/未跟踪文件,规划要防止覆盖用户改动
misleading success output 误导性成功输出 确认某个测试是否真的运行过
prompt injection 提示注入 处理不受信任的外部文本(如 Discord 内容)时

这些探针在 full-workflow.md 中被明确为对抗性工作流的"证据键":外部/Discord 内容一律视为声称而非指令,先简要引用来源,再对照仓库或一手证据验证,无法验证的标记为风险而非需求。

六、完整工作流:从分类到交付的五阶段

planner.md 声明"不在此重建完整技能工作流",但为了让读者理解"精简教义"如何被放大为可执行流程,这里基于 full-workflow.md 概要还原其五阶段骨架:

  1. Phase 0 分类(Classify):按规模判定访谈深度——Trivial(单文件)/ Standard(1–5 文件)/ Architecture(系统设计、5+ 模块、长期影响);
  2. Phase 1 落地(Ground):先探索后提问,并行派出只读研究,区分"可发现事实"(研究并引用)与"偏好/取舍"(才带到用户面前);架构级请求还需运行 collect → verify → design → adversarial → synthesize 五步动态对抗工作流;
  3. Phase 2 路由(Route):在 CLEAR(结果明确,只问真正的分叉)与 UNCLEAR(结果模糊,研究 + 采纳最佳实践默认值)之间做一次判断,并加载对应的 intent-clear.md 或 intent-unclear.md 参考文档;
  4. Phase 3 生成计划(仅获批后):重跑脚手架脚本、强制 Metis 差距分析、向 ## Todos 区域追加任务批次、最后才填面向人类的 ## TL;DR (For humans);
  5. Phase 4 交付(Deliver):按固定结构给出交接说明(计划驱动什么 / 结束状态 / 形状 / 超出请求的部分 / 验证方式 / 执行交接),并按 review_required 决定是否运行高精度双评审。

6.1 计划产物生产者契约

完整工作流对计划产物的机器可解析性有严格要求(full-workflow.md):

  • 实现行必须匹配 - [ ] N. <title>(N 为正十进制整数);
  • 最终验证行必须匹配 - [ ] F<number>. <title>;
  • 散文标题、编号段落、普通列表项不得充当任务;
  • 每个实现行必须携带嵌套的 Recommended task executor category: 行;
  • 交接前必须对计划做结构自检并修复问题。

任务执行者类别使用 omo 分类词汇表:quick(机械/单文件,默认)、unspecified-low(杂项小任务)、unspecified-high(标准多文件功能)、visual-engineering(前端/UI)、writing(文档)、git(git 操作)、deep(棘手的调试或跨模块推理)、ultrabrain(一个真正困难的内聚问题,整体委派)。

6.2 脚手架脚本:唯一合法的产物生成方式

计划产物不允许手工拼装,必须通过脚本生成。scaffold-plan.mjs 是一个零外部依赖(仅 node:fs/path/process/url 内置模块)的确定性脚手架,在 macOS / Linux / Windows 上由 node 或 bun 逐字节一致运行。其核心约束包括:

node "<skill-root>/scripts/scaffold-plan.mjs" <slug> [--clear|--unclear] [--draft-only] [--review-required] [--reset [--force]]
  • slug 校验:仅允许小写字母、数字与连字符,长度上限 80(SLUG_PATTERN = /^[a-z0-9][a-z0-9-]{0,79}$/);
  • 写入边界:产物只允许落在 .omo/ 目录下的 .md 文件,且逐段拒绝符号链接与路径逃逸——这是对"规划 Agent 只能写规划产物"教义的工程化强制;
  • 可恢复安全:普通重跑对已存在的 ulw-plan 产物是无害 no-op,只有 --reset 才允许覆盖,且 --force 才会丢弃手工编辑——规划会话在上下文压缩后可以从持久化的 draft 恢复,而不是重新路由;
  • 两阶段写入:--draft-only 只创建 .omo/drafts/<slug>.md(获批前的安全恢复点),获批后才重跑创建 .omo/plans/<slug>.md 骨架。

draft 文件本身是一个结构化的状态载体,携带 slug / status / intent / review_required / plan_path / approach 等 frontmatter 字段以及 Components 拓扑账本、Open assumptions(已宣布的默认值)、Findings、Decisions、Scope IN/OUT、Approval gate 等区块——这保证了长会话在上下文丢失后仍能精确续接。

6.3 双评审与有界收敛

当 review_required: true(用户显式要求"高精度/고정밀/ultra high accuracy"或 UNCLEAR 且非 Trivial 分类)时,交付前必须运行双路高精度评审:原生 momus 评审子 Agent(High 精度)+ 独立 Oracle 评审(最强推理模型、完全隔离子会话)。评审受"有界收敛契约"约束:最多 5 轮(仅用户显式要求才可无限),只有命中五类"阻止者资格"(明确需求/已接受决策、现存失败回归、可复现的破坏流程、具体的安全/数据丢失/兼容性风险、外部 API/发布契约冲突)的发现才能阻塞,其余记为非阻塞笔记,且"仅剩笔记的批准也算批准"——确保评审必然终止,不会无限膨胀计划范围。

6.4 批准门:规划者唯一的循环风险点

完整工作流特别强调批准门(Approval gate)是"介于简报与计划文件之间的唯一屏障,也是规划者唯一可能循环的地方"。正确姿势是把它当作带持久化状态的决策而非口令寻找:

  • 探索耗尽后,先在 draft 中写入 status: awaiting-approval、方法与下一步动作(这是压缩后的续接点);
  • 一次性呈现简报(发现的关键事实 + 剩余歧义的建议选项 + 拟规划的方法);
  • 用户的任何接受性回复("yes" / "approve" / "proceed" / "write the plan")都只授权写计划文件这一件事,永远不是实现授权。

UNCLEAR 路径即使自动运行高精度评审,也绝不跳过此门;唯一的窄例外是 $ulw-execute 启动引导场景(用户"开始工作"视为生成计划的批准)。

七、注入链路与多 harness 分发

把前面几节串起来,可以看到 planner.md 在 oh-my-openagent 中的完整生命周期:

  1. 源文档:planner.md 作为 Ultrawork 模式的 planner 变体,由 ultrawork-prompts.ts 打包导出(ULTRAWORK_PLANNER_PROMPT),并通过 loader.ts 支持运行时注入占位符;
  2. 配套提示词:prometheus/default.md 作为完整规划顾问提示词,其第一指令就是"加载 ulw-plan 技能并先于一切读取它",并明确"不要在此重述或覆盖它"——与 planner.md 的"只做精简教义"互为镜像;
  3. 技能工作流:ulw-plan/SKILL.md 承载完整流程,其参考文档 full-workflow.md、intent-clear.md、intent-unclear.md 提供各阶段机制,脚本 scaffold-plan.mjs 保证产物结构一致;
  4. 多 harness 同步:同一套技能在 senpi(packages/omo-senpi/skills/ulw-plan/)与 codex(packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/)中同步分发,并有对应的契约测试(如 ulw-plan-skill-contract.test.mjs、ulw-plan-review-state-contract.test.mjs)锁定行为;
  5. 执行侧:获批的计划最终由独立的 worker 会话通过 $ulw-execute <plan-name> 执行,支持 --worktree <absolute-path>(任务自有工作树,PR/分支工作必需)、--make-pr(以 PR 交付)、--ship(隐含 --make-pr 并持续工作到 PR 被评审并合并)等交接选项——规划者与执行者的边界在交接语法层面被彻底固定。

八、结语:把"规划"做成工程

planner.md 全文不过二十余行,却是整个 oh-my-openagent 规划体系的原则内核。它用最精简的语言锁定了三件事:职责边界(只规划不实现,含代理)、产出标准(单一决策完备计划)、证据纪律(没有可验证证据就没有完成)。而仓库中的技能文档、参考文档与脚手架脚本,则把这套教义放大为一套可执行、可恢复、可评审、可交接的完整工程流程。

对于想在自己的 Agent 系统中引入"规划/执行分离"架构的开发者,这套设计的核心启示在于:精简注入文档负责常驻上下文的边界约束,完整技能文档负责按需加载的深度机制,确定性脚本负责产物结构的一致性,而多 harness 同步与契约测试则保证同一套纪律在不同执行环境中不漂移——规划不是一种能力,而是一种可以被工程化约束的行为。

登录后查看全文
oh-my-openagent