oh-my-pi 工程散文改写指南:用 implementation-scratchpad 语体重构系统提示词
2026/9/20 14:51:27 网站建设 项目流程

oh-my-pi 工程散文改写指南:用 implementation-scratchpad 语体重构系统提示词

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

导读

本指南围绕 rewrite-system-prompt.style.md 展开,它是 oh-my-pi 项目用于把自然语言风格的提示词文档改写成"极简实现草稿(implementation-scratchpad)"语体的风格规范。文章会完整解析风格规则、硬性约束与 JSON 协议,并结合 rewrite-system-prompt.ts 的实现细节,说明"哪些行会被改写、哪些行必须逐字节保留、改写结果如何被校验"。读完你既能独立套用这套语体改写自己的提示词文档,也能理解自动化管线背后的行分类、令牌保全与容错回退机制。

一、这份风格文档是什么:从"工程散文"到"实现草稿"

oh-my-pi 的 Agent 系统提示词(默认输入为 packages/coding-agent/src/prompts/system/system-prompt.md)中包含大量面向 LLM 的自然语言指导。风格文档定义了一种刻意"未完成感"的语体,模仿工程师边写代码边记笔记的思维流:

  • 删掉主语、冠词和"to""The color wheel is hidden"写成"Color wheel hidden"
  • 以固定小动词集合开头NeedCouldWe'llLet's等;
  • 用松散小词不断对冲maybeperhapscould~okay散布在从句中间,形成"思考的质感";
  • 以单词式裁决收尾Fine.Good.Nice.complicated.

这种风格的价值在于:它把"决策过程"(在多个方案间权衡、否定、锁定)压缩进极短的句子,让模型在推理时以最小 token 开销完成同样的规划,同时保留原始的技术判断逻辑。

二、风格规则的完整拆解

文档# Style一节共给出 11 条具体规则,逐条展开如下。

2.1 删除冠词、主语与不定式 to

规则原文:Drop articles, subjects, and "to." Strip "a," "the," "I," and the infinitive "to" wherever the meaning survives.

在语义不受损的前提下,一律去掉:

  • 冠词:athe
  • 主语:I
  • 不定式符号:to

示例对照:

原句(工程散文)改写后(scratchpad)
I need to render the SVG backgroundNeed render SVG background
The color wheel is hiddenColor wheel hidden

2.2 以小动词集合开启从句

规则原文:Open clauses with a small fixed set of verbs. Most sentences start with Need, Need maybe, Need perhaps, Could, We'll, or Let's.

动词选择承载语义状态:

  • Need:未解决的待办事项(unresolved to-dos);
  • We'll / Let's:刚刚拍板的决策(decisions you've just committed to)。

文档给出一个关键范例,说明"选择如何被锁定":

The shift from "Need maybe set palette width…" to "We'll set .wb-pen-rack…" is how a choice gets locked in.

即:先用Need maybe试探,一旦决定就用We'll收口,动词本身即体现决策状态机。

2.3 用裸语气词持续对冲

规则原文:Hedge constantly with bare particles. maybe, perhaps, could, might, ~, okay.

语气词不放在句首做铺垫,而是散布在从句中间

  • "width 420 maybe ok"
  • "height 220 maybe"

文档强调:The hedging is the texture; don't smooth it out.对冲本身就是语体的纹理,不允许被"平滑"掉。

2.4 以单词式裁决收尾

规则原文:End deliberations with one-word verdicts as full sentences. Fine. Good. Nice. complicated. Fine.

一个讨论线程以完整句子的单个裁决词关闭。典型模式是"抛出想法 → 指出问题 → 一笔带过":

transform scale? complicated. Fine.

2.5 自问自答,同一口气内解决

规则原文:Self-interrogate, then resolve in the same breath.

提出片段式问题后立刻回答或挥开:

For smaller viewport, width 420 maybe ok. In screenshot browser 1200.

We have width 420; max-width calc. But control positions fixed…

2.6 用裸 "But" 转折

规则原文:Pivot on a bare "But." Mid-thought reversals get a lone "But" with no setup.

思维中途的反转用孤立的But开头,不做任何铺垫:

Could use scale? Not needed? … But to get proper arc positions, flex plus transform works okay.

2.7 用分号串联微从句,内联原始数字与单位

规则原文:Chain micro-clauses with semicolons; inline raw numbers and units.

不要叙述测量过程,直接把数字丢进句子:

  • "width constant 280; visible width 420"
  • "absolute left 82 top 24, height 112"

2.8 压缩因果关系

规则原文:Collapse cause and effect. Conditionals get telegraphed.

条件句被电报化压缩:

  • "If color hidden, width row stays."
  • "For eraser state, no swatches means width row maybe still at y 157."

2.9 不设框架地穿插代码片段

规则原文:Interleave code fragments without framing.

在推理中途直接丢入代码,不需要"这里是代码"之类的引言,代码之后继续散文:

width 420; max-width calc:max-width: calc(100% - 40px);But control positions fixed…

2.10 保持现在时与中性情绪

规则原文:Stay in present tense, neutral affect. No feelings, no "let me think," no recap of what you just did.

不允许出现情绪、let me think、或对已完成动作的回顾,始终保持问题上的"纯前向推进"。

三、硬性约束(Hard constraints):令牌保全是第一优先级

风格规则之上,文档列出 5 条不可违背的硬性约束,其中最重要的是第一条——技术令牌逐字节保全

3.1 所有技术令牌必须原样保留

Preserve every technical token EXACTLY as written, with the same characters, casing, and number of occurrences.

受保护的令牌类型包括:

  • 反引号代码段:`like this`
  • XML/HTML 标签:<like-this>
  • 模板表达式:{{like.this}}
  • URL、文件路径、flag、命令名、API 名、数字、单位

约束明确说明:如果压缩从句会导致这些令牌丢失,就保留该令牌——任何令牌缺失都会导致改写被拒绝(the rewrite is rejected when any token goes missing)。绝不重写、重排、拆分或删除代码段/标签/{{…}}表达式的内部内容。

这一约束直接呼应了目标文件的形态——system-prompt.md 中大量使用 XML 标签(<system-conventions>)、Handlebars 模板表达式({{#if …}}{{#each skills}}{{toolRefs.think}})和内联代码段,这些结构性令牌一旦被改写就可能破坏提示词模板的渲染逻辑。

3.2 RFC-2119 关键词保持大写

MUSTMUST NOTREQUIREDSHOULDSHOULD NOTRECOMMENDEDMAYOPTIONALNEVERAVOID即使被去掉主语也必须保持大写:

  • "You MUST load context""MUST load context",而不是"must load context"
  • "You NEVER yield""NEVER yield"

这与 system-prompt.md 开头<system-conventions>RFC 2119的约定完全一致——大写本身就是被解析的语义。

3.3 子句起始动词大写

NeedCouldWe'llLet'sCheckRiskFixRunFineGoodDecision等草稿起始动词需要大写。

3.4 只改写,不翻译、不注释、不总结

Rewrite only. Do not translate, annotate, summarize, or explain. No commentary.

输出中禁止任何元评论。

3.5 一对一映射

One fragment in maps to exactly one fragment out. Never merge two fragments, never split one, never reorder.

输入片段与输出片段严格一对一,禁止合并、拆分或重排。

四、协议(Protocol):JSON 批处理格式

文档定义了模型与调用方之间的通信协议:

输入:单个 JSON 对象,每个片段带整数id和原始文本:

{"items":[{"id":1,"text":"<fragment>"},{"id":2,"text":"<fragment>"}]}

输出:同构 JSON 对象,id一一对应(顺序可任意):

{"items":[{"id":1,"text":"<rewritten fragment>"},{"id":2,"text":"<rewritten fragment>"}]}

硬性要求

  • 响应中只能有这个 JSON 对象,前后不允许任何 markdown 围栏或散文;
  • 返回的条目数量 MUST 等于输入条目数量,且id必须一致;
  • 每个text值 MUST 是合法 JSON——内部的每个双引号和换行都必须转义。

五、源码实现:rewrite-system-prompt.ts 如何执行这套规范

风格文档不是孤立的规范文本,它被 rewrite-system-prompt.ts 直接作为 LLM 的 system prompt 使用(脚本通过import STYLE_GUIDE from "./rewrite-system-prompt.style.md" with { type: "text" }加载),整个管线完整实现了协议与约束。以下是实现与规范的对应关系。

5.1 管线总览

脚本以行为单位处理提示词文件:

  1. 块级跳过:YAML frontmatter 与围栏代码块逐字节保留,绝不发送给模型(blockSkipMask,见 rewrite-system-prompt.ts);
  2. 行分类:判断一行是"结构行"(保留)还是"散文行"(改写)(isVerbatimLine);
  3. 剥离:把行拆成prefix + core + suffix{{…}}块令牌与列表标记归入 prefix/suffix 原样保留(peel);
  4. 批量请求:散文行按 chunk 分组、并发发送给 OpenRouter;
  5. 令牌校验:每个改写结果必须通过preservesTokens校验,失败则回退为原文;
  6. 重组写回:默认原地覆盖(in place)。

5.2 结构行 vs 散文行的判定(isVerbatimLine)

在 rewrite-system-prompt.ts 中,isVerbatimLine按以下规则把行判为"逐字保留":

  • 空行;
  • Markdown 标题(/^#{1,6}\s/)与水平线(/^[-*=_]{3,}\s*$/);
  • 剥离掉 Handlebars 表达式、XML 标签、代码段和 URL 后,剩余字母词少于 3 个且不含句子标点——这正好保护了 XML 标签、Handlebars 指令、模板数据列表项和token: label定义行。

这解释了风格文档中"结构令牌逐字节保留"如何在工程上落地:<system-conventions>{{#if renderMermaid}}这类行在送到模型之前就被识别为 verbatim,根本不参与改写。

5.3 脆弱令牌的正则与多重性校验

FRAGILE_RE(rewrite-system-prompt.ts)定义了必须存活的令牌:

/\{\{[^}]*\}\}|<[^>]*>|`[^`]*`|[A-Za-z][\w+.-]*:\/\/\S+/g

覆盖四类:模板表达式{{…}}、尖括号标签、反引号代码段、URL。

preservesTokens(rewrite-system-prompt.ts)用计数 Map 校验出现次数(multiplicity)——每个令牌在原句中出现的次数必须全部出现在改写结果中,数量不足即判失败。这与风格文档"same number of occurrences"的措辞精确对应。

5.4 重试与容错回退

makeOpenRouterRewriter(rewrite-system-prompt.ts)实现了"改写出错 → 降级为原文"的韧性设计:

  • 模型回复先经parseItemsResponse宽容解析(剥掉围栏、在无法直接解析时截取首个{到末个}之间的 JSON 片段);
  • 只接受通过preservesTokens的改写,未通过者进入重试队列,重试耗尽后该行保留原文;
  • 调用方rewriteAll侧同理:返回 Map 中缺失的 id 或令牌丢失的改写一律回退原始行。

即"flaky batch degrades to unchanged, never to corruption"——批次故障退化为"未改动",绝不产生损坏。

5.5 并发控制与 OpenRouter 调用细节

  • 默认模型:anthropic/claude-sonnet-4.5
  • 默认端点:https://openrouter.ai/api/v1,并带HTTP-RefererX-Title头;
  • 请求使用 OpenAI 风格的 JSON-Schema 强制响应格式(REWRITE_RESPONSE_FORMAT,strict: true),从协议层保证模型返回{"items":[{id,text}]}结构;
  • 批内重试间隔为400ms × (attempt+1)线性退避。

六、CLI 实战:如何运行改写任务

脚本通过 Bun 运行,支持完整参数集。全部用法与默认值如下(默认值取自 rewrite-system-prompt.ts 与parseCli):

# 原地改写默认系统提示词 OPENROUTER_API_KEY=… bun scripts/rewrite-system-prompt.ts # 改写所有内置 prompt + rule(始终原地) OPENROUTER_API_KEY=… bun scripts/rewrite-system-prompt.ts --all # 改写指定文件并输出到别处 OPENROUTER_API_KEY=… bun scripts/rewrite-system-prompt.ts -i a.md -o b.md # 仅做规划,不发网络请求 bun scripts/rewrite-system-prompt.ts --dry-run

完整参数表

参数说明默认值
-i, --input <path>源文件packages/coding-agent/src/prompts/system/system-prompt.md
-o, --output <path>单文件运行输出(默认原地覆盖)等于输入
--all改写全部内置 prompt 与 rule(始终原地)
--model <id>OpenRouter 模型 IDanthropic/claude-sonnet-4.5
--base-url <url>OpenRouter 兼容端点https://openrouter.ai/api/v1
--chunk <n>每个请求的散文行数3
--concurrency <n>并行请求数6
--retries <n>每个 chunk 的网络/解析重试次数2
--temperature <n>采样温度0.4
--limit <n>每个文件仅改写前 N 行散文(0 = 全部)0
--dry-run只分类 + 分块、打印计划,不联网

--all模式的扫描范围由PROMPT_GLOBS定义(rewrite-system-prompt.ts),覆盖:

  • packages/coding-agent/src/prompts/**/*.md
  • packages/coding-agent/src/commit/prompts/*.mdagentic/prompts/*.md
  • packages/coding-agent/src/autoresearch/*.md
  • packages/coding-agent/src/discovery/builtin-rules/*.md
  • packages/agent/src/compaction/prompts/*.md
  • packages/ai/src/prompts/*.md
  • packages/typescript-edit-benchmark/src/prompts/*.md

同时会跳过*.rewritten.md旧产物。运行前须设置环境变量OPENROUTER_API_KEY(未设置会直接报错退出)。

七、前置条件与适用边界

  • 运行环境:脚本以#!/usr/bin/env bun声明,使用Bun.fileBun.GlobBun.sleep等 Bun 专属 API,需在 Bun 运行时下执行;
  • 目标文件形态:默认目标 system-prompt.md 是包含 XML 系统约定(<system-conventions>)、RFC 2119 大写关键词与大量 Handlebars 条件块的模板文件——正是风格文档"结构令牌逐字节保全"约束所要保护的场景;
  • 失败语义:令牌丢失、网络错误、解析失败均不会损坏文件,而是回退到原文,输出统计中分别计为changedfallback(见rewriteAllRewriteStats)。

结语

rewrite-system-prompt.style.md是一份"语体即协议"的规范:风格规则负责把工程散文压缩为信息密度极高的实现草稿,硬性约束负责保证模板的结构令牌与语义关键词在改写中零丢失,JSON 协议则让这条规则可以被任何支持 JSON 输出的模型直接消费。而 rewrite-system-prompt.ts 证明了这套规范的可执行性——从行分类、令牌多重性校验到失败回退,每一个约束都在代码里有对应的落地实现。如果你正在维护自己的 Agent 提示词模板,这份风格文档和它配套的管线,是一套可以直接借鉴的"提示词减肥"方案。

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询