Hashline 内容哈希编辑协议
Hashline 内容哈希编辑协议
学习目标
- 理解 Hashline 协议在 Oh-My-OpenAgent 中的 Hook 增强实现
- 掌握 Read Enhancer 和 Edit Diff Enhancer 的协作流程
- 识别并发编辑和空白差异陷阱
前置知识
本章涉及 Hashline 协议的通用原理,建议先阅读:
下文假设你已理解 Harness Problem 和 Hashline 协议概念,直接聚焦 Oh-My-OpenAgent 的具体实现。
项目实践
Hook 增强架构
Oh-My-OpenAgent 的 Hashline 不是修改核心编辑工具,而是通过 Hook 增强模式实现:
read 工具执行 → Hashline Read Enhancer (tool.execute.after) ↓ Agent 看到带哈希的行: 11#VK| function hello() ↓ Agent 发送 edit: { op: "replace", pos: "11#VK", lines: [...] } ↓ 哈希验证 → 匹配则应用 / 不匹配则拒绝 ↓edit 工具执行 → Hashline Edit Diff Enhancer (tool.execute.before/after) ↓ 生成 metadata.diff 和 metadata.filediffRead Enhancer Hook
位于 src/hooks/hashline-read-enhancer/hook.ts,在 read 工具执行后拦截输出:
处理流程:
- 检测是否为 read 工具输出
- 识别文本文件(检查是否匹配
行号: 内容或行号| 内容格式) - 跳过已被截断的行(带有
... (line truncated to 2000 chars)标记) - 对每行计算内容哈希:
computeLineHash(lineNumber, content) - 转换格式:
11: function hello()→11#VK| function hello()
内容块检测:支持 <content>/<file> 标签包裹的输出格式,仅增强标签内的行。
Write 后的行号报告
写入完成后,Read Enhancer 自动读取文件并报告实际行数:
File written successfully. 42 lines written.这使得 Agent 能立即了解文件的新行数,为后续编辑提供准确的行号参考。
Edit Diff Enhancer
位于 src/hooks/hashline-edit-diff-enhancer/hook.ts,在 write 工具执行前后工作:
Before Hook:
- 捕获文件旧内容
- 存储到
pendingCapturesMap(带 5 分钟超时清理)
After Hook:
- 读取文件新内容
- 计算行级 diff:
countLineDiffs(oldContent, newContent) - 生成统一 diff:
generateUnifiedDiff(oldContent, newContent, filePath) - 注入 metadata:
metadata.diff:统一 diff 字符串(供 TUI 展示)metadata.filediff:结构化对象(含 additions、deletions 计数)
Hashline 编辑操作
位于 packages/hashline-core/src/types.ts,支持三种操作:
| 操作 | 描述 | 必需参数 |
|---|---|---|
replace | 替换指定行或行范围 | pos(哈希锚定的行号),可选 end |
append | 在指定行后插入或文件末尾 | 可选 pos |
prepend | 在指定行前插入或文件开头 | 可选 pos |
编辑应用时的处理逻辑(packages/hashline-core/src/edit-operations.ts):
- 去重编辑(
dedupeEdits) - 按行号排序编辑
- 验证行引用(
validateLineRefs) - 检测重叠范围(
detectOverlappingRanges) - 依次应用编辑
启用条件
Hashline 是实验性功能,通过配置开关控制:
{ "hashline_edit": true}默认关闭,因为并非所有模型都能正确理解哈希锚定格式。
问题与规避
并发编辑冲突
问题:Agent 读取文件后、编辑前,用户或其他进程修改了文件,导致哈希不匹配。
规避:哈希不匹配时拒绝编辑并要求 Agent 重新读取。在 Team Mode 中通过 git worktree 隔离多 Agent 的编辑。
模型兼容性
问题:不是所有模型都能理解 Hashline 格式。GPT-5.5 对哈希锚定的理解较好,但部分小模型可能忽略哈希标签。
规避:Hashline 默认关闭。启用后,通过编辑成功率监控决定是否保持开启。
哈希计算开销
问题:每次读取和编辑都计算行级哈希,增加处理延迟。
规避:使用截断哈希(短标签),在 token 效率和碰撞概率之间平衡。行号 + 短哈希组合已足够区分。
设计取舍
Hook 增强 vs 核心工具集成
| 方案 | 优势 | 代价 |
|---|---|---|
| Hook 增强 | 不修改核心工具、可随时启用/关闭、独立测试 | 增加一次 Hook 调用开销 |
| 核心工具集成 | 零额外开销、原生支持 | 修改核心逻辑、影响所有用户 |
Oh-My-OpenAgent 的选择:Hook 增强模式,因为 Hashline 是实验性功能且需要逐步验证效果。
参考来源
- Can Bölük, The Harness Problem
- oh-my-pi — Hashline 灵感来源