news 2026/9/12 2:28:41

oh-my-pi 语义压缩的 rewrite 工具契约:草稿提交、损失声明与审查回合机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
oh-my-pi 语义压缩的 rewrite 工具契约:草稿提交、损失声明与审查回合机制

oh-my-pi 语义压缩的 rewrite 工具契约:草稿提交、损失声明与审查回合机制

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

导读

本文剖析 oh-my-pi(pi)Coding Agent 中omp compress语义压缩管线的核心工具契约——rewrite。该工具负责把一段源文本(系统提示词、工具描述、规范文档)压缩成可直接交付的稠密提示词,并与approve工具构成一个两工具审查协议。读完本文,你将理解rewrite的参数语义、losses损失声明机制、审查回合(review turn)的驱动逻辑,以及它在源码中的完整实现与测试保障。

背景:两工具压缩协议中的rewrite

omp compress是 oh-my-pi 提供的一条命令行能力,用于把文本文件"重写"为稠密的提示词寄存器格式。其运行模型非常克制:每个文件一个独立的 Agent 会话,每个会话只有两个工具——rewriteapprove。会话不允许读取文件、搜索、运行命令或访问扩展/MCP/LSP,一切输入都随对话送达,确保输出不受源文本之外的任何内容影响。这条约束在 compress/session.ts 中写得很明确:

  • customTools仅注册rewriteTool()approveTool()两个工具;
  • skillsrulescontextFilespromptTemplatesslashCommands全部清空;
  • enableMCPenableIrcenableLsphasUI均置为关闭。

rewrite的官方契约文档位于 prompts/tools/rewrite.md,而它的姊妹工具 prompts/tools/approve.md 负责接受最新草稿并结束运行。二者的关系是:rewrite提交草稿 → 命令返回审查回合 → Agent 裁决 → 要么再次rewrite要么approve

rewrite 工具的参数契约

rewrite接受两个必填参数,其运行时校验模式定义在 compress/protocol.ts 的rewriteSchema中,均要求非空字符串并开启"+"拒绝未知字段:

参数类型语义运行时校验
textstring完整、逐字、可直接交付的压缩输出;绝不输出 diff、摘要或编辑描述"string > 0",即非空字符串
losses{ content, reason }[]每个被省略的声明、限定词、默认值、边界值、示例或精确字符串对应一条记录;须引用或命名被删内容并说明为何省略后仍正确;空数组表示无损失元素须满足contentreason均为非空字符串

text的"完整交付"语义是整个协议的第一原则:命令侧在写入文件时原样落盘(compress/index.ts 中fs.writeFile(destination, draft.text.endsWith("\n") ? draft.text : \${draft.text}\n`)),期间不做任何二次处理。也就是说,rewrite提交的text` 就是最终产物,Agent 必须保证它开箱即用。

losses数组则承担"可审计性"职责。类型定义见 compress/types.ts 中的CompressLosscontent是从源文中引用或精确描述的被删内容,reason说明草稿在缺少它的情况下依然正确的理由。

每次调用后的审查回合(Review Turn)

原文档规定的调用流程是:每次rewrite调用 → 审查回合 → 回复草稿、测量尺寸、声明的损失 → 请求裁决rewrite替换草稿,approve接受草稿。这条流程在命令侧被严格执行,核心逻辑位于 compress/index.ts:

  1. Agent 首次收到 请求模板,其中携带源文本、源大小(词数/token 数)以及一个 per-run 随机 nonce,源文被包裹在<source-{{nonce}}>惰性数据块中;
  2. Agent 调用rewrite提交草稿;
  3. rewriteTool()执行器记录草稿并立即返回统计摘要:"Draft N recorded: sourceTokens → draftTokens tokens (x.x% smaller), N declared loss(es). A review turn follows.";
  4. 命令调用renderReview(compress/index.ts 的renderReview函数)构造审查回合提示词,把草稿、度量结果与损失清单原样引述回给 Agent,并附上裁决请求:approve接受该草稿,或rewrite再次提交;
  5. 循环直到approve达成、无草稿、草稿回合未推进或超过预算。

审查回合之所以存在,是因为命令侧刻意不做任何 diff 或关键词校验——验证责任完全落在 Agent 声明的损失清单加审查回合上。这让 Agent 在损失清单摊在面前时评判自己的工作,而不是在产生草稿的同一轮里自我认证。

度量由CompressProtocol.metrics()完成,返回CompressMetrics:源/草稿的词数、token 数与压缩比ratio = (sourceTokens - draftTokens) / sourceTokens。注意当草稿比源文更长时 ratio 为负数,此时命令会如实报告"增长了"而非掩盖。

三条 critical 红线

原文档在<critical>块中规定了三条不可违背的约束,它们也是整个压缩协议的安全护栏:

1. 诚实声明损失(Declare losses honestly):声明的损失是可审计的;未声明的损失等于静默回归。这意味着删掉的内容必须一条条写进losses,哪怕它只是"默认值 30 秒"这样的限定词。系统提示词 compress/prompts/system.md 同样强调"压缩迫使读者猜测就是 bug,不是节省"。

2.text必须独立成立:没有源文的读者必须能够直接执行它。压缩产物会被原样替换进系统提示词、工具描述或规范中,由模型冷启动阅读,作者不在场消歧——因此任何需要猜测的省略都是失败的压缩。这与 system.md 中"NEVER ship"清单一脉相承:外部指代("上面的 claim")、草稿残留("Hmm")、分层修正等一律禁止出现在输出中。

3. 新草稿取代先前的批准:一旦 Agent 在approve之后又调用rewrite,先前的批准即刻失效,新草稿必须重新走审查回合。源码中submit()(protocol.ts)在入账新草稿的同时把#approved复位为false、清空#verdict,正是这条规则的实现。

源码级验证:协议如何强制这些约束

CompressProtocol类(protocol.ts)通过记账状态机把契约文档落成可执行逻辑,并有 compress.test.ts 逐条锁定行为:

  • 先 approve 后 rewrite 会被拒绝accept()在没有草稿时抛出"Call rewrite before approve: there is no draft to accept",对应测试"approve before any draft is rejected"
  • approve 被审查门控:草稿未被markReviewed前调用accept()会抛出"Draft N has not been reviewed yet...",对应测试"approve is gated on the review turn for the newest draft"——这正是"每次调用后必有一个审查回合"的程序化表达;
  • 新草稿取代旧批准submit()复位批准状态,测试"a new draft supersedes an approval and needs its own review"验证了这一点;
  • 损失清单不可变拷贝submit()losses做映射拷贝,外部后续修改不会污染草稿;
  • 度量诚实"metrics measure the draft against the source and report growth as a negative ratio"验证了膨胀草稿得到负 ratio;
  • 空源兜底:空文本返回 0 尺寸、ratio 为 0,避免除零,对应"an empty source yields zero sizes instead of dividing by zero"

此外,compress/index.ts 对空文件直接返回stalled"no text to compress"),对每个文件的最终状态approved / unapproved / stalled / cancelled进行汇总;只有approved的草稿才会被写入磁盘或 stdout。

运行方式:omp compress与相关配置

rewrite/approve协议由 commands/compress.ts 暴露为 CLI:

# 单个文件压缩,默认输出到 stdout omp compress prompts/tools/read.md # 输出到指定文件(仅限单文件) omp compress notes.md -o notes.compressed.md # 通配符批量压缩并原地覆盖 omp compress 'src/prompts/**/*.md' -i # 多文件并发压缩(-n 控制并发度) omp compress a.md b.md c.md -i -n 8 # 指定模型与更大的草稿预算 omp compress spec.md -r 5 -m opus
标志简写默认值说明
--out-ostdout将批准后的文本写入指定文件(仅单文件)
--in-place-ifalse用批准文本覆盖每个源文件
--rounds-r3每个文件的最大草稿轮数,超限则按 unapproved 放弃
--agents-n4并发压缩的文件数
--model-m会话默认模型指定压缩所用模型选择器

值得注意的边界约束:--in-place--out互斥;多文件场景必须配合--in-place--out只接受单文件);匹配不到任何文件会直接报错,因为"静默压缩比请求更少的文件"比失败更糟。每个文件的审查回合在到达预算的最后一轮会给出强提示:approve接受,或仅在草稿确实不可交付时再rewrite一次——未批准的运行不写入任何内容。

延伸阅读

  • rewrite 工具契约原文:本文分析的关联文档
  • approve 工具契约:协议的接受端
  • 压缩系统提示词:压缩方法论、帧语法与 NEVER ship 清单
  • 协议实现:两工具的 schema、记账状态机与度量实现
  • 命令编排:审查回合渲染、文件写入与结果汇总
  • 协议测试:协议行为逐条锁定

rewrite工具的契约设计体现了一个明确理念:压缩的正确性由"声明的损失 + 审查回合"共同担保,而不是由命令侧的机械校验担保。理解这套契约,是理解 oh-my-pi 语义压缩管线乃至其提示词工程哲学的关键入口。

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

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

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

AI时代测试工程师的转型与技能升级

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

作者头像 李华
网站建设 2026/9/12 2:21:59

从线上故障到生产实践:分布式事务与最终一致性落地全程复盘

一次线上故障&#xff0c;把“分布式事务”四个字从PPT里拽到了我面前。当时订单服务已经扣款成功&#xff0c;库存服务却回滚失败&#xff0c;用户看到的提示是“支付成功”&#xff0c;仓库里却没有货可发。客服工单一下子涌进来&#xff0c;技术群里全是“库存到底扣没扣”的…

作者头像 李华
网站建设 2026/9/12 2:21:28

Node.js 项目初始化流程脚本:从手动重复到工程化自动搭建

写这套 Node.js 项目初始化流程脚本的起因特别朴素&#xff1a;我实在受不了每次开新项目时那堆重复劳动了。先npm init回答一堆交互式问题&#xff0c;再想半天依赖版本&#xff0c;然后手动建 src、config、test 目录&#xff0c;第 N 次复制 .gitignore&#xff0c;配完 ESL…

作者头像 李华