Aider的Repo Map功能
在使用 Aider 时,Repo Map 默认只包含当前会话中明确指定的文件(通过命令行传入的 fnames
或交互中添加的文件)。要把整个项目的所有文件添加到 Repo Map 中,需要调整 Aider 的行为,让它扫描整个代码库并将所有文件纳入 Repo Map。以下是实现这一目标的几种方法,基于 base_coder.py
和 repomap.py
的逻辑。
前提
- Repo Map 由
RepoMap
类生成,依赖于abs_fnames
(会话文件)和all_fnames
(全部可用的文件,通常来自 Git 仓库)。 - 默认情况下,
all_fnames
只包含会话中涉及的文件,除非明确扩展到整个项目。
方法 1:启动时指定所有文件
通过命令行将整个项目的文件列表传递给 Aider,使其初始化时包含所有文件。
步骤
-
列出项目文件:
- 使用
git ls-files
或find
获取所有文件。例如:git ls-files > files.txt # 如果是 Git 项目 # 或 find . -name "*.py" > files.txt # 只找 Python 文件
- 使用
-
启动 Aider 并传入文件列表:
aider $(cat files.txt) --map-tokens 4096 --map-refresh auto
$(cat files.txt)
: 将文件列表作为参数传入。--map-tokens 4096
: 增加令牌限制,确保能容纳更多文件。--map-refresh auto
: 自动更新 Repo Map。
-
验证:
- 输入
/map
查看 Repo Map,确保所有文件都包含在内。
- 输入
优点
- 无需修改代码,简单直接。
缺点
- 如果文件过多,命令行参数可能超出系统限制。
- Repo Map 可能因令牌限制截断。
方法 2:修改源码扫描整个项目
通过修改 base_coder.py
,让 Aider 在初始化时自动加载整个项目的文件到 all_fnames
,从而生成包含所有文件的 Repo Map。
步骤
-
克隆并编辑 Aider:
git clone https://github.com/Aider-AI/aider.git cd aider pip install -e .
-
修改
base_coder.py
:- 打开
aider/coders/base_coder.py
,找到__init__
方法。 - 修改
all_fnames
的初始化逻辑:def __init__(self, main_model, io, fnames, edit_format, **kwargs): # 原有代码 self.main_model = main_model self.io = io self.edit_format = edit_format # 修改:加载整个项目文件 if kwargs.get("use_git", True) and os.path.exists(".git"): from aider.repo import GitRepo self.git_repo = GitRepo(self.io, fnames) self.all_fnames = set(self.git_repo.get_tracked_files()) # 获取所有 Git 跟踪的文件 else: # 如果没有 Git,扫描当前目录 from pathlib import Path self.all_fnames = set(str(f) for f in Path(".").rglob("*") if f.is_file() and not f.name.startswith(".")) self.abs_fnames = set() for fname in fnames or []: self.abs_fnames.add(os.path.abspath(fname)) # 其余初始化代码保持不变 if self.main_model.use_repo_map: self.repo_map = RepoMap( self.main_model.max_context_tokens, self.map_tokens, self.io, self.git_repo, self.verbose, ) else: self.repo_map = None
- 改动说明:
- 如果有 Git 仓库,使用
git_repo.get_tracked_files()
获取所有文件。 - 如果无 Git,递归扫描目录(
Path.rglob
),排除隐藏文件。
- 如果有 Git 仓库,使用
- 打开
-
运行 Aider:
aider --map-tokens 4096 --model gpt-4o
- 不需要指定文件,Aider 会自动加载整个项目。
-
保存 Repo Map(可选):
- 结合前一问的方法,添加保存逻辑到
update_repo_map
:if repo_map_content: with open("repo_map.txt", "w", encoding="utf-8") as f: f.write(repo_map_content)
- 结合前一问的方法,添加保存逻辑到
优点
- 自动化加载整个项目,Repo Map 完整反映代码库。
缺点
- 需要修改源码,可能增加内存和解析开销。
方法 3:利用 Git 仓库自动包含所有文件
如果你的项目是 Git 仓库,Aider 可以通过 RepoMap
的 get_repo_map
方法访问所有 Git 跟踪的文件。
步骤
-
确保项目是 Git 仓库:
git init git add . git commit -m "Initial commit"
-
启动 Aider:
aider --map-tokens 4096 --map-refresh always
- 不指定文件,Aider 默认使用 Git 仓库。
-
调整
repomap.py
(可选):- 打开
aider/repomap.py
,确保get_repo_map
使用全部文件:def get_repo_map(self, chat_fnames, other_fnames): all_fnames = set(self.git_repo.get_tracked_files()) if self.git_repo else set() # 原有逻辑继续
- 默认情况下,
other_fnames
只包含会话外的文件,这里强制使用所有文件。
- 打开
优点
- 利用现有 Git 集成,无需额外参数。
缺点
- 仅适用于 Git 项目,非 Git 项目无效。
方法 4:交互模式动态添加所有文件
在 Aider 的交互模式中,手动添加整个项目文件。
步骤
-
启动 Aider:
aider
-
添加所有文件:
- 使用
/add
命令添加通配符:/add *.py
- 或列出所有文件(借助 shell):
aider $(find . -name "*.py")
- 使用
-
检查 Repo Map:
- 输入
/map
,确认所有文件已包含。
- 输入
优点
- 无需修改代码,交互灵活。
缺点
- 手动操作,文件多时繁琐。
推荐方案
- Git 项目: 用 方法 3,结合
--map-tokens 4096
,自动包含所有文件。 - 非 Git 项目或需持久化: 用 方法 2,修改源码确保全面加载并保存。
- 快速尝试: 用 方法 1 或 方法 4,手动指定或添加。
示例运行
假设项目有 main.py
, utils.py
, lib/helper.py
:
aider --map-tokens 4096 --map-refresh always
修改后的 Repo Map(repo_map.txt
)可能如下:
main.py:
main() - def main(): ...
utils.py:
calculate_sum(a, b) - def calculate_sum(a, b): return a + b
lib/helper.py:
log(msg) - def log(msg): print(msg)
注意事项
- 令牌限制: 如果项目文件很多,增加
--map-tokens
(如 8192),否则 Repo Map 会被截断。 - 性能: 加载整个项目可能增加解析时间,尤其是非 Git 项目。
- 过滤: 如果只想要特定文件类型(如
.py
),在扫描时添加过滤(如*.py
)。
如果需要具体代码调整或测试某个项目,我可以进一步协助!有什么具体需求吗?