代码阅读神器Aider上

   Aider初步使用

   Aider是一款帮助可以帮助阅读整个repo代码,以及进行pair编程的AI工具。aider的使用非常简单,“pip install aider”安装该工具,cd到需要review的repo code 目录,即可对真个source code进行high level的review。

  下面是clone的Solopi,(Solopi是一款ali开源的用于录制回放mobile 应用操作,以及收集性能测试数据的工具)的repo,让aider进行阅读。我提出的第一个“Solopi是如何工作的?”。此时,aider从整个repo中筛选出来了一些java的类,需要将这些java文件加入chat,以进行后续的对话。

  输入Y,将这些文件添加到Chat,aider对每个class的作用进行了很简单的概括,并抽取了PerformanceActivity进行了详细说明。并提示用户,如果需要详细reveiw解释某个java文件,可以输入文件名称和问题和chat交互。

  接着,对aider进行提问“solopi是如何收集性能数据的,例如cpu使用率”,aider紧接着给出了原理说明,以及对应java文件。在这个过程中,如果发现需要新的java文件需要添加在chat中,aider会列举出来,输入Y,同意加入新的java文件到chat中后,aider会分析新加入的java文件。针对solopi如何收集cpu性能数据的问题,并给出更加详细的答案。执行结果如下图所示:

  紧接着继续问“solopi如何实现录制回放的?”,aider会分析需要新加入chat的java文件,并将这些文件添加到chat,有了这些文件,review这些文件内容,并对这个问题进行回答。具体如下图所示:

  以上就是aider分析整个repo下的code的能力,总结下来,有两个子能力,一个是分析列举需要的source code文件,二个是针对source code文件进行概要总结。如果用户给出问题的具体的某个code文件,能得到更加详细的source code分析结果。接下来看看aider是如何实现列举需要的source code文件。

aider如何得到source code文件列表

  使用 os.walk 遍历目录树,获取所有文件及其路径。过滤出符合特定条件的文件,比如 Python 文件(.py)、Java 文件(.java)、以及其他配置文件(如 setup.py、requirements.txt 等)。打开aider的source code,在main.py文件中有一个identify_key_files的方法。代码内容如下所示,这里定义了如何事python文件,key files的规则,如果是java文件,在src/main/java目录下的,或者Main.java的是关键文件。如果不是.py或者.java开头,那么文件中包含了public static void main内容的也是关键文件,并把这些关键文件路径添加到key_files对象中。

def identify_key_files(directory="."):
    """
    Identify key code files in the given directory based on naming conventions,
    directory structure, and file contents.
    """
    key_files = []
    for root, _, files in os.walk(directory):
        for file in files:
            if file.endswith(".py") or file in ["setup.py", "requirements.txt", ".flake8"]:
                key_files.append(os.path.join(root, file))
            elif file.endswith(".java"):
                file_path = os.path.join(root, file)
                if "src/main/java" in file_path or file == "Main.java":
                    key_files.append(file_path)
                else:
                    with open(file_path, 'r') as f:
                        content = f.read()
                        if "public static void main" in content:
                            key_files.append(file_path)
    return key_files

aider如何针对source code文件,分析得到结论

  可以看到,当前面提问“how does solopi works?”,aider并没有列举所有src目录下的java文件,而是筛选了很小一部分文件,这是如何实现的呢?

  首先,使用os.walk遍历目录树,获取所有文件和路径,然后通过上面indenty_key_files方法进行了粗略的筛选,然后会将筛选出来的文件构建出一个GitRepoMap对象。GitRepoMap 是Aider用于管理和存储代码仓库信息的数据结构。它主要包含文件和标识符的定义和引用:存储每个文件中定义的函数、类等标识符,以及它们的引用关系。
文件之间的关系图:使用图结构(如 NetworkX)表示文件之间的依赖关系,基于这些关系计算文件的重要性。
文件排名信息:使用 PageRank 等算法对文件进行排序,识别出关键文件。

  下面是main文件中main方法的简略版本,可以看到首先是调用identify_key_files()方法,接着是加载一些环境变量,配置文件信息,然后实例化Coder对象,然后根据用户在chat过程中的信息进行动态调整。

def main(argv=None, input=None, output=None, force_git_root=None, return_coder=False):
    key_files = identify_key_files()
    print("Key code files identified by Aider:")
    for file in key_files:
        print(f" - {file}")
    # 其他代码省略...
    
    io = InputOutput(
        # 参数省略...
    )

    # 加载环境变量和解析命令行参数
    loaded_dotenvs = load_dotenv_files(git_root, args.env_file)
    args = parser.parse_args(argv)

    # 创建Coder实例并进行后续处理
    coder = Coder.create(
        # 参数省略...
        io=io,
        fnames=fnames,
        # 其他参数省略...
    )

    if return_coder:
        return coder

    # 动态调整和用户交互部分
    if args.message:
        io.add_to_input_history(args.message)
        io.tool_output()
        coder.run(with_message=args.message)
        return

    while True:
        try:
            coder.run()
            return
        except SwitchModel as switch:
            coder = Coder.create(main_model=switch.model, io=io, from_coder=coder)
            coder.show_announcements()

  构建source code的图文信息主要在repomap.py文件中实现,该文件中实现的主要内容,如下所示:

1 加载Tree-Sitter语言和解析器: • aider/repomap.py 从 tree_sitter_languages 导入 get_language 和 get_parser。 • 这些函数被用来为代码库中的文件加载适当的语言和解析器。

2 定义查询: • .scm 文件(例如 aider/queries/tree-sitter-go-tags.scm、aider/queries/tree-sitter-javascript-tags.scm、aider/queries/tree-sitter-typescript-tags.scm)包含Tree-Sitter查询。 • 这些查询被用来从源代码中提取特定信息(例如,函数定义、方法调用)。

3 提取标签: • aider/repomap.py 中的 get_tags_raw 方法使用已加载的解析器和查询从源文件中提取标签。 • 标签是信息片段,如函数定义和引用,用于理解代码中的结构和依赖关系。

4 构建代码库映射: • aider/repomap.py 中的 get_repo_map 方法协调构建代码库映射的过程。 • 它调用 get_ranked_tags_map 来获取基于它们的重要性和相关性的标签排名列表。

5 标签排名: • aider/repomap.py 中的 get_ranked_tags 方法使用基于图的方法对标签进行排名。 • 它构建一个图中节点代表文件,边代表它们之间的引用。 • 使用PageRank算法根据它们的重要性对节点进行排名。

6 渲染映射: • aider/repomap.py 中的 to_tree 方法将排名标签转换为树形结构。 • 然后这个树形结构被用来生成代码库映射的文本表示。

  以上就是对aider实现原理的总结介绍。

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

taoli-qiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值