Aider 使用的 *SEARCH/REPLACE* blocks prompt 主要是基于“搜索/替换”机制来高效地修改代码。它的核心原理是结合 LLM 的文本补全能力和类似 diff 的修改方式,以最小的编辑范围精准更新代码,而不是重新生成整个文件。
工作原理
-
代码上下文分析
- Aider 先获取需要修改的代码文件,并识别出与用户输入相关的部分。
- 它不会盲目地让 LLM 重新生成整个文件,而是尝试最小化修改。
-
搜索 (
SEARCH)- Aider 生成一个搜索块,定义要修改的代码范围。例如,它可能匹配某个函数、类或者特定代码片段。
- 这个块通常基于正则匹配或者直接搜索关键代码结构。
-
替换 (
REPLACE)- Aider 让 LLM 仅生成修改后的代码部分,而不是整个文件。
- 通过
REPLACE语法,它指示 LLM 在特定位置插入或修改代码,而不会影响无关部分。
-
上下文控制
- 由于 LLM 的上下文窗口有限,Aider 只提供最必要的代码片段,减少不相关的代码干扰,提高生成质量。
- 例如,它会提供函数签名、相关依赖等,但不会让 LLM 重新阅读整个项目。
-
代码合并
- 生成的修改内容会合并回原始代码,保持版本管理友好。
- 结合
git diff或patch机制,确保代码变更可追踪。
优点
- 精准修改:避免 LLM 误改其他部分,提高代码稳定性。
- 节省 Token:比全量代码生成更高效,降低 API 调用成本。
- 可读性高:搜索/替换模式让代码变更更清晰,方便用户理解和审查。
对应的代码在 github.com/Aider-AI/ai…
要自己实现类似 Aider 的 SEARCH/REPLACE 代码修改功能,你可以按照以下步骤设计:
1. 解析代码文件
- 读取目标代码文件,并将其解析成结构化的 AST(如果是 Python,可以用
ast,如果是 Java,可以用javaparser)。 - 也可以使用简单的文本匹配或正则表达式,提取需要修改的代码段。
2. 生成 SEARCH 块
- 通过关键字、函数/类名称,或者正则匹配找到待修改代码的范围。
- 你可以用
diff或 AST 分析来精确确定变更点,确保SEARCH区块尽可能小。
3. 生成 REPLACE 块
- 让 LLM 仅生成修改的部分,而不是整个文件。
- 可以通过提供
SEARCH块的上下文,让 LLM 输出替换部分,并严格控制格式。
4. 代码合并
- 解析 LLM 生成的
REPLACE代码,并替换到原文件。 - 确保缩进、格式等符合代码风格,避免意外的语法错误。
5. 版本控制
- 使用
git diff或unified diff格式,生成变更日志,方便回滚和审查。 - 让每次修改都可跟踪,提高可维护性。
示例:Python 代码替换
import re
def search_replace(filename, search_pattern, replacement_code):
with open(filename, "r") as f:
content = f.read()
# 搜索代码块
match = re.search(search_pattern, content, re.MULTILINE)
if not match:
print("Pattern not found!")
return
# 进行替换
new_content = content.replace(match.group(0), replacement_code)
# 写回文件
with open(filename, "w") as f:
f.write(new_content)
# 示例用法
search_pattern = r"def add\(a, b\):\n\s+return a \+ b"
replacement_code = "def add(a, b):\n return a * b" # 让加法改成乘法
search_replace("example.py", search_pattern, replacement_code)