自己写的终端 code agent ,edit 工具基于 hashline 锚定 + 内容校验 编辑模型,大致流程:
1. read 文件 → 返回 [文件路径#4 位 hex TAG] + N:内容 (N 是 1-based 行号)
2. LLM 输出 patch → edit 工具解析、校验、应用
3. post-edit 返回新的 TAG + 编辑后内容 (链式编辑无需重新 read)
已经做的防错机制
A. TAG 校验 read 时对文件内容 hash 生成 4 位 hex TAG ,存 SnapshotStore 。edit 时校验 TAG ,不匹配意味着文件被外部改过。不依赖 LLM 的操作正确性——只防并发冲突。
B. 内容校验 (%OLD 哨兵) SWAP 操作要求 LLM 提供被替换的原内容。执行时与实际文件内容做 progressive match: exact → NFC 归一化 → 去行尾空格 → 全 trim → NFKC 归一化。
匹配失败时返回精确错误信息:第一个差异行的内容对比 + hex dump (处理 visually identical 但编码不同的情况,如 NFC vs NFD)。
C. 纯内容匹配模式 不依赖行号,LLM 只给出要替换的文本内容,引擎在文件中搜索定位。唯一匹配直接执行,多处匹配报错提示加行号消歧。
D. TAG 过期自动恢复 TAG 不匹配时,用 LCS 算法 (大文件降级为行哈希贪心) 计算快照→当前文件的行号映射,校验范围连续性 + 偏移均匀性 + 交换位置内容一致性。全部通过则自动重映射行号执行。失败则让 LLM 重新 read 。
E. 操作冲突检测 同文件多个 section 之间检测操作区间重叠,拒绝执行并报告冲突位置。
仍然存在的问题
上述机制能防"文件被别人改了"和"LLM 的 old content 写错",但挡不住:
- 行号偏移 — LLM 看到的行号是 41-47 ,输出的 SWAP 行号却是 42-48 (差 1-2 行)。边界条件 (函数首尾) 尤其容易错
- 结构闭包遗漏 — SWAP 需要 body 包含
}等闭合括号,LLM 偶尔漏掉,生成的文件语法错误 - %OLD 缺失 — LLM 有时忘记提供 old content 做验证,引擎只能靠 TAG 兜底 (弱校验)
这三类错误约占 20%,目前靠 "编译失败 → 读错误日志 → 重试" 循环处理,体验不够好。
想请教
- 有没有办法在 LLM 生成 patch 的阶段 就提高行号准确率? constrained decoding 或 structured output 在这类场景有用吗
- 除了 post-edit 编译检查,还有哪些 低延迟的语义验证手段?(AST diff? 增量类型检查?)
- Aider / Claude Code / Cline 在这块有什么值得借鉴的做法吗
交流下经验,感谢 🙏