第二阶段 · 可靠的本地编码 Agent第 5 / 30 章
本章目录

第 05 章 · 仓库发现与代码搜索

本章目标:让 Agent 在动手修改前建立足够准确的代码地图,同时避免把整个仓库塞进上下文。

1. 为什么“先把全部代码读完”行不通

真实仓库可能有几万文件,包含依赖、构建产物、图片和生成代码。即使上下文窗口足够大,全量阅读也会把关键需求淹没。编码 Agent 更像侦探:先看目录和项目说明,再用错误、符号和调用关系逐层缩小范围。

发现阶段的目标不是理解全部系统,而是回答三个问题:入口在哪里,相关行为由哪些文件共同决定,修改后用什么命令验证。

2. 从便宜信息到昂贵信息

推荐的探索顺序是:

  1. 查看 Git 状态,知道用户已有修改;
  2. 读取 AGENTS.md、README、构建配置;
  3. 列出浅层目录,识别语言和模块边界;
  4. 根据任务词、错误栈和符号做文本搜索;
  5. 读取命中位置附近的有限行;
  6. 追踪定义、引用、测试和配置;
  7. 只有必要时才读取大文件或运行索引器。

这是一种信息经济学:每一步都用少量成本换取更准确的下一步查询。搜索不是为了收集更多文字,而是为了减少不确定性。

3. 搜索工具怎样设计

search_text 至少需要 query、path、glob 和 max_results。结果应包含文件、行号和短上下文,而不是返回整个文件。默认忽略 .git、node_modules、虚拟环境、构建目录和二进制文件。

src/auth.py:42:def validate_token(token):
tests/test_auth.py:18:def test_expired_token():
docs/security.md:71:Expired tokens must be rejected.

这个结果同时暴露实现、测试和规则。模型下一步可以读取三个局部,而不是漫无目的浏览。

4. 仓库地图不是一次性目录树

成熟 Agent 会逐步形成工作地图:模块职责、入口、测试命令、依赖方向和当前修改范围。地图可以保存在本次任务状态里,也可以把稳定事实写入项目记忆。需要区分“观察到的事实”和“模型推断”:文件名暗示 auth 不等于它一定拥有认证逻辑。

对于大型仓库,可以使用语言服务器、语法树、符号索引和 Git 历史。文本搜索仍然重要,因为配置、字符串和文档未必进入代码索引。好的发现系统会组合多种证据,而不是迷信一种检索技术。

5. 什么时候应该停止探索

探索也会成瘾。停止条件可以是:

如果模型不断打开文件却没有形成假设,Runtime 可以要求它输出“已知、未知、下一次查询为什么有价值”。这比简单限制读取次数更能恢复方向。

6. 与用户修改共存

开始前必须读取 git status 和 diff。未提交变化可能是用户正在做的工作,Agent 不能用整文件重写把它覆盖。搜索和读取时要基于当前工作树,而不是假设仓库等于 HEAD。遇到同一文件已有修改,应先理解差异,再做局部补丁。

本章实践

给当前 Agent 增加 list_files 与 search_text 时,先设计返回格式和结果上限,再写执行代码。工具的价值不在于“能搜索”,而在于把搜索结果变成下一轮模型容易使用的观察。