Aider SEARCH/REPLACE 解密

205 阅读3分钟

Aider 使用的 *SEARCH/REPLACE* blocks prompt 主要是基于“搜索/替换”机制来高效地修改代码。它的核心原理是结合 LLM 的文本补全能力和类似 diff 的修改方式,以最小的编辑范围精准更新代码,而不是重新生成整个文件。

工作原理

  1. 代码上下文分析

    • Aider 先获取需要修改的代码文件,并识别出与用户输入相关的部分。
    • 它不会盲目地让 LLM 重新生成整个文件,而是尝试最小化修改。
  2. 搜索 (SEARCH)

    • Aider 生成一个搜索块,定义要修改的代码范围。例如,它可能匹配某个函数、类或者特定代码片段。
    • 这个块通常基于正则匹配或者直接搜索关键代码结构。
  3. 替换 (REPLACE)

    • Aider 让 LLM 仅生成修改后的代码部分,而不是整个文件。
    • 通过 REPLACE 语法,它指示 LLM 在特定位置插入或修改代码,而不会影响无关部分。
  4. 上下文控制

    • 由于 LLM 的上下文窗口有限,Aider 只提供最必要的代码片段,减少不相关的代码干扰,提高生成质量。
    • 例如,它会提供函数签名、相关依赖等,但不会让 LLM 重新阅读整个项目。
  5. 代码合并

    • 生成的修改内容会合并回原始代码,保持版本管理友好。
    • 结合 git diffpatch 机制,确保代码变更可追踪。

优点

  • 精准修改:避免 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 diffunified 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)