squash合并: - 意图识别层论证(8维度+10业界佐证) - 多主题上下文管理愿景+并存论证+补充论证(多轮agentic) - 架构设计文档物理分类(四子目录+INDEX+命名规范+引用同步+边界清晰化) - 前端架构技术债清单归档
3.9 KiB
3.9 KiB
patch_file 使用指南
创建: 2026-06-15 关联设计: docs/02-架构设计/专项设计/patch_file工具设计-2026-06-15.md
使用场景
局部更新文件(替代 read-merge-write 多步流程),精确定位 old_text 并替换为 new_text。
适用于只改文件中某几行的场景:大文件改 3 行无需重发全部内容,避免 write_file 全量覆盖的事故风险(参见 FR-S7 记录:762 行文件被覆盖为 248 字节)。
API 参数
| 参数 | 必填 | 说明 |
|---|---|---|
path |
是 | 目标文件路径(workspace 内,走 validate_path 校验 + 黑名单) |
old_text |
是 | 要替换的精确文本(必须与文件内容完全匹配,含空格/缩进;充当乐观锁) |
new_text |
是 | 替换后的新文本 |
line |
否 | 行号辅助定位(快速跳转 + 去歧增强;有值时优先跳到该行检查 old_text,不匹配则降级全文扫描) |
expected_hash |
否 | 文件指纹防脏写,格式 "{unix_timestamp}_{size}"(如 "1718400000_12345"),由 read_file 返回的 file_hash 字段携带 |
补充去歧参数(可选):before_text / after_text —— 当 old_text 多处匹配时,作为上下文锚精确锁定目标位置。
返回值
{
"success": true,
"patches_applied": 1,
"total_matches": 1,
"lines_changed": 2,
"warnings": [],
"file_hash": "1718400000_12400"
}
| 字段 | 含义 |
|---|---|
success |
是否成功 |
patches_applied |
成功替换的 patch 数 |
total_matches |
每个 patch 的总命中数(含未替换的) |
lines_changed |
总行数变化(正=增加,负=减少) |
warnings |
警告信息,如 ["匹配到 3 处,仅替换第 1 处"] |
file_hash |
操作后的新指纹(下次操作传入 expected_hash 用) |
安全边界
- RiskLevel Medium:修改已有文件,需人工审批
- 自动
.bak备份:复用 FR-S7 已有逻辑,误操作可恢复 - old_text 不匹配 → 报错(不修改文件,避免盲替换)
- expected_hash 不匹配 → 报错(防并发脏写,提示「文件已被外部修改,请重新读取」)
- 三层防御:L1 文件级 Mutex(防时机冲突)+ L2 old_text 精确匹配(防内容错配)+ L3 expected_hash 指纹校验(防版本漂移),底层兜底
.bak备份
最佳实践
- old_text 取足够上下文确保唯一:避免短串多处匹配,收到「匹配到 N 处」warning 时用
before_text/after_text锚定或加长old_text重试 - 大段修改用多个小 patch 而非一个巨大 patch:每个 patch 独立校验,失败可定位
- 危险操作前先
file_info确认:核对路径、大小、是否二进制(含\0的文件会被拒绝) - read → patch 链路带上 hash:
read_file返回file_hash,传入patch_file的expected_hash形成乐观锁闭环 - 多 patch 从文件末尾往前排:避免行号偏移(工具内部已按此执行)
- old_text 必须完全匹配:含空格、缩进、换行,复制粘贴原文最稳妥
示例
基础替换
{
"path": "src/main.rs",
"old_text": "fn old()",
"new_text": "fn new()"
}
带 hash 乐观锁
{
"path": "src/main.rs",
"expected_hash": "1718400000_12345",
"patches": [
{ "old_text": "fn old()", "new_text": "fn new()" }
]
}
多处匹配用 line 锚定
{
"path": "src/main.rs",
"old_text": "return Ok(())",
"new_text": "return Ok(value)",
"line": 42
}
边界情况
| 情况 | 行为 |
|---|---|
| 文件不存在 | 报错「文件不存在」 |
二进制文件(含 \0) |
报错「不支持二进制文件」 |
old_text 为空串 |
报错「old_text 不能为空」 |
new_text == old_text |
成功 + warning「无实际更改」 |
路径含 .. |
validate_path 黑名单拦截 |
目标是 .bak/.tmp |
拒绝(CR-03 噪声文件过滤) |