04 · 实战:第一个仓库问答任务
用三个真实任务验证 agent 的能力,看看它在什么场景下表现好、什么场景下会出错,理解当前 agent 的能力边界。
能跑不等于能用
前几节搭出了骨架,实现了搜索和读文件工具,也在本地跑通了基本流程。但"能跑"和"能用"之间还有一段距离。这一节用三个真实的仓库问答任务来检验 agent,看看它到底能做到什么程度。
三个任务按难度递进:
- 简单的定位问题
- 需要跨文件理解的追踪问题
- 需要综合多个信息源的总结问题
准备测试环境
直接用 mini-coding-agent 自己的代码作为测试仓库。在项目根目录启动 agent:
cd mini-coding-agent
pnpm start这时 agent 的工作目录就是 mini-coding-agent/,它能搜索和读取项目里的所有源文件。
任务一:这个项目的入口文件在哪
难度:简单。 只需要搜索和读取少量文件。
> 这个项目的入口文件在哪?
输出: 入口文件是 main.ts。
[模型调用: 2次 | 工具调用: 1次]模型调用了 1 次 search,1 次 model.chat 就给出了答案。关键词明确("入口"),搜索目标清晰(main.ts),读取文件数量少。
容易失败的情况: 如果模型搜索的关键词不精确(比如搜"start"而不是"main"),可能找不到入口文件。这时模型通常会换个关键词重试,但如果重试两三次还没找到,可能会给出一个基于猜测的回答。弱模型(如 glm-4-flash)特别容易犯这个错。
任务二:工具是怎么注册到 agent 的
难度:中等。 需要跨文件追踪代码路径。
> 工具是怎么注册到 agent 的?有哪些工具?
输出: 根据代码分析,工具注册到 Agent 的流程如下:
1. 定义工具接口:在 src/types.ts 中定义了 Tool 接口
2. 实现具体工具:每个工具在 src/tools/ 下独立实现
3. 组装工具集:src/tools/index.ts 中 createAllTools() 将基础工具
和计划管理工具合并
4. 在 Agent 中注册:src/agent.ts 调用 createAllTools(todoManager, baseTools)
5. 工具执行:Agent 循环中通过 allTools.find() 查找并调用 tool.execute()
现有工具(共 4 个):search、read_file、create_todos、update_todo
[模型调用: 7次 | 工具调用: 11次]这个任务比第一个难得多——7 次模型调用、11 次工具调用。答案分散在多个文件中:工具接口在 types.ts,实现在 tools/ 下各文件,组装逻辑在 tools/index.ts,调用在 agent.ts。agent 需要反复搜索和读取才能拼出完整答案。
容易失败的情况:
- 弱模型可能不调用工具,直接编造一个泛泛的回答
- 模型可能只搜索到
tools/index.ts但没看到agent.ts中的调用,导致回答不完整 - 模型可能在第一轮搜索后就给出答案,没有继续追踪代码路径
这说明一个重要的点:agent 的回答质量取决于它搜索和读取的完整性。 漏读一个关键文件,答案就会缺一块。
任务三:解释这个项目的整体架构
难度:较难。 需要综合多个文件的信息,给出结构化的总结。
> 解释这个项目的整体架构
输出: mini-coding-agent 项目架构
模块架构:
main.ts (CLI入口)
→ 创建 Model、tools、AgentState
→ 循环接收用户输入,调用 runAgent
↓
agent.ts (Agent Loop)
→ 构建 system prompt
→ ReAct 循环:模型调用 → 工具执行 → 再调用模型
↓ ↓
model.ts tools/
OpenAI SDK封装 search / read_file / create_todos / update_todo
↓
types.ts (类型定义)
数据流:用户输入 → main.ts → runAgent → model.chat() → 工具调用 → 结果追加 → 再次 model.chat() → 返回回答
[模型调用: 7次 | 工具调用: 12次]12 次工具调用,agent 逐个读取了 main.ts、agent.ts、model.ts、tools/index.ts、types.ts、todo.ts 等文件,最终给出了完整的架构图。
当前 agent 的能力边界: 这个任务的难点在于"综合":
- 上下文碎片化。 模型读了 4-5 个文件的内容,加上搜索结果和系统提示词,对话历史已经不短了。模型可能在处理这些信息时遗漏某些细节。
- 缺少目录结构视角。 当前工具只有搜索和读文件,没有"列出目录结构"的能力。模型只能通过搜索来推测项目结构,这对理解整体架构来说不够直接。第 3 章会加入 glob 工具来弥补。
- 总结的结构化能力取决于模型。 agent 能读到的信息是对的,但最终回答的组织质量取决于模型本身的总结能力。
从三个任务看当前能力边界
跑完三个任务,可以对当前 agent 的能力画一个清晰的边界:
做得好的:
- 定位特定代码片段("入口文件在哪")——1 次工具调用就够了
- 读取单个文件并解释其内容
- 通过关键词搜索找到相关代码
需要多轮搜索才能完成的:
- 跨多个文件的综合理解(11-12 次工具调用)
- 对项目结构的全局视角
- 追踪代码调用链路
根本做不到的(这一章不要求):
- 修改代码(需要写文件工具,第 3 章)
- 执行命令验证结果(需要命令工具,第 3 章)
- 复杂的多步骤任务规划(需要 Agent Loop,第 2 章)
模型选择很重要。 弱模型(如 glm-4-flash)容易跳过工具直接编造答案。中等以上的模型(如 qwen3.6-plus)能主动搜索、跨文件追踪、给出结构化总结。agent 的能力上限取决于模型,但代码架构决定了能力下限——无论模型多弱,只要它调用了工具,返回的信息就是准确的。
项目验收:最小仓库问答 Agent
这一章的验收标准很简单:你的 agent 能在任意一个本地代码仓库上运行,回答关于代码结构、函数位置、文件内容的问题。
验收步骤:
- 在
mini-coding-agent(或其他任意 Git 仓库)目录下运行pnpm start - 问三个不同类型的问题(定位、追踪、解释)
- 检查 agent 的回答是否基于实际搜索和读取的结果,而不是凭空猜测
如果三个问题中至少两个能得到基本正确的回答,这一章就算通过了。
当前项目结构
这一章结束时,项目结构应该是:
mini-coding-agent/
├── src/
│ ├── types.ts # 消息、状态、工具、模型响应的类型定义
│ ├── model.ts # LLM 调用封装
│ ├── agent.ts # Agent 循环,调用模型和工具
│ ├── main.ts # CLI 入口
│ └── tools/
│ ├── index.ts # 工具注册和 createAllTools
│ ├── search.ts # ripgrep 搜索
│ └── read-file.ts # 带长度控制的文件读取
├── package.json
└── tsconfig.json五个文件对应五个部件。这个结构在后续章节中会持续扩展:第 2 章升级 agent.ts 中的循环逻辑,第 3 章往 tools/ 里加新工具,第 4 章新增权限模块,第 5 章升级输出层。但核心的分层架构不会变。
这一章搭出了最小可用的 agent。它能搜索、能读文件、能回答关于代码仓库的问题。但它还不能自己规划多步骤任务,还不能修改代码,还不能跑测试。下一章把"单轮问答"升级成"持续推进的执行循环",让 agent 真正具备自主行动的能力。
登录以继续阅读
解锁完整文档、代码示例及更多高级功能。