68 lines
2.2 KiB
Markdown
68 lines
2.2 KiB
Markdown
|
|
---
|
|||
|
|
title: Patch Tool 模糊补丁工具
|
|||
|
|
created: 2026-04-16
|
|||
|
|
updated: 2026-04-16
|
|||
|
|
type: entity
|
|||
|
|
tags: [tool, agent]
|
|||
|
|
sources: [packages/backend/src/modules/netaclaw/tools/builtin/patch.ts, packages/backend/src/modules/netaclaw/tools/fuzzy_match.ts]
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Patch Tool 模糊补丁工具
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
文件局部查找替换工具,支持 9 级模糊匹配。比 `write_file` 更安全(只改局部)、更省 token(不需要传完整文件内容)。注册在 [[tool-catalog]] 的 `base` 工具集。
|
|||
|
|
|
|||
|
|
## Schema 定义(TypeBox)
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
const PatchParams = Type.Object({
|
|||
|
|
path: Type.String({ description: '文件绝对路径' }),
|
|||
|
|
old_string: Type.String({ description: '要查找的文本片段' }),
|
|||
|
|
new_string: Type.String({ description: '替换为的文本' }),
|
|||
|
|
replace_all: Type.Optional(Type.Boolean({ description: '替换所有匹配,默认 false' })),
|
|||
|
|
});
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 执行流程
|
|||
|
|
|
|||
|
|
1. 读取目标文件内容
|
|||
|
|
2. 调用 `fuzzyFindAll()` 进行模糊匹配
|
|||
|
|
3. 验证匹配结果(0个报错 / 多个且非 replace_all 报错 / 唯一通过)
|
|||
|
|
4. 从后往前替换(避免索引偏移)
|
|||
|
|
5. 写回文件
|
|||
|
|
|
|||
|
|
## 9 级模糊匹配引擎
|
|||
|
|
|
|||
|
|
**文件**: `tools/fuzzy_match.ts`(~304行)
|
|||
|
|
|
|||
|
|
| 级别 | 策略 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 1 | `exact` | 精确字符串匹配 |
|
|||
|
|
| 2 | `line_trimmed` | 每行 trim 后匹配 |
|
|||
|
|
| 3 | `whitespace_normalized` | 所有空白压缩为单空格 |
|
|||
|
|
| 4 | `indent_flexible` | 去除行首缩进 |
|
|||
|
|
| 5 | `escape_normalized` | 转义字符还原(`\n` → 换行) |
|
|||
|
|
| 6 | `trimmed_boundary` | 首尾行 trim |
|
|||
|
|
| 7 | `unicode_normalized` | Unicode 标点归一化(智能引号等) |
|
|||
|
|
| 8 | `block_anchor` | 首尾行锚定 + 中间相似度 |
|
|||
|
|
| 9 | `context_aware` | 逐行相似度滑动窗口 |
|
|||
|
|
|
|||
|
|
**核心算法**: Levenshtein 编辑距离 → `similarity = 1 - (distance / maxLen)`
|
|||
|
|
|
|||
|
|
**返回结构**:
|
|||
|
|
```typescript
|
|||
|
|
interface FuzzyMatchResult {
|
|||
|
|
strategy: string; // 匹配策略名
|
|||
|
|
startIndex: number; // 原始文本起始位置
|
|||
|
|
endIndex: number; // 原始文本结束位置
|
|||
|
|
matchedText: string; // 匹配的原始文本
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 关联页面
|
|||
|
|
|
|||
|
|
- [[tool-catalog]] — 工具目录系统(注册在 base 工具集)
|
|||
|
|
- [[tool-system]] — 工具系统总览
|
|||
|
|
- [[agent-runtime]] — Agent 运行时执行
|