08 · 综合项目与面试复盘
项目目标:代码库研究 Agent
Section titled “项目目标:代码库研究 Agent”本单元给出一个可自行实现的 capstone 方案,不表示仓库已经包含该系统。目标是在本机运行一个代码库研究 Agent:用户询问仓库行为时,系统通过只读工具检索源文件,给出带路径和行范围的答案;用户要求修改时,系统先生成具体 diff,等待明确批准,再进行受限写入并运行测试。每个阶段都要能解释做了什么、依据是什么、哪些部分未验证。
浏览器教程站是 Astro + Starlight 静态站,不会访问用户本机仓库,也不启动本机 Python 或 stdio Server。GitHub 源码仓库为 Private;公开 Pages 上只有静态构建内容。项目运行、测试和 trace 应在自己的本机开发环境中完成,网页中的架构图或演示不能当作本机项目的执行证据。
不要一次搭完:按 vertical slice 交付
Section titled “不要一次搭完:按 vertical slice 交付”每个 slice 都要从一条用户可见路径贯通到可检查结果。先做窄而完整的只读流程,再扩展检索和模型能力;不要一开始就并行做长期记忆、广泛工具接入与自动修改。
Slice 0:明确边界和最小测试仓库
Section titled “Slice 0:明确边界和最小测试仓库”选一个你有权访问的小型代码库,定义根目录、允许文件类型和大小上限、绝不读取的路径,以及本机运行条件。先写出成功问题、无答案问题、越界路径和超大文件等验收样例。不要把 API Key 放进仓库或测试数据。
**验收:**项目说明列出允许行为、明确拒绝项及威胁模型;所有后续工具默认只能访问设定的仓库根目录。
Slice 1:只读工具与安全路径
Section titled “Slice 1:只读工具与安全路径”实现最少的 list_files、read_text 和 search_text。解析路径后确认其仍在仓库根目录下;检查符号链接、绝对路径、..、二进制文件及文件大小限制。为读取输出保留相对路径和行号。尽可能将工具拆分为只读实现,不让“搜索”间接执行 shell 命令。
**验收:**合法文件可读;路径穿越和仓库外符号链接被拒绝;二进制、超大和不存在文件返回可区分的错误;拒绝用例确认文件内容没有变化。
Slice 2:证据化回答
Section titled “Slice 2:证据化回答”先用关键词或简单词法基线完成检索,不要求先接向量数据库。每个候选片段保存路径、行起止位置和匹配内容。模型只收到有限片段,并要对重要事实引用这些片段;检索不到足够证据时应说明不确定或拒答。
**验收:**建立一小组带标准证据位置的问题和无答案问题。逐题标记检索是否命中、结论是否正确、引用是否确实支持结论。只在页面答案里出现一个路径,不算证据支持。
Slice 3:有界 Agent Loop
Section titled “Slice 3:有界 Agent Loop”加入模型决策,但将模型输出视为提议:验证工具名和参数,只允许已注册的只读工具;限制轮数、工具调用次数、上下文大小、超时和费用。将检索、证据判断、回答和结束条件拆成可单独测试的步骤。出现格式错误或工具失败时,要么返回明确错误并停止,要么按已定义策略恢复,不允许无限循环。
**验收:**成功问题得到带引用答案;无答案问题不编造;非法工具名和错误参数在执行前被拒绝;达到轮数或预算上限时能停止并报告原因。
Slice 4:接入 MCP,而不是做界面假象
Section titled “Slice 4:接入 MCP,而不是做界面假象”参照第 06 单元本机运行的 Python stdio 例子,单独实现或接入一个受限的只读 MCP Server。通过 Client 实际执行初始化、list_tools 和 call_tool,保留版本、启动方式、transport、schema 和调用结果的记录。先只暴露已审阅的只读能力;不要把无关 MCP 工具一次性开放给模型。
**验收:**本机 trace 能证明 Client 启动或连接了实际 Server,发现预期工具并得到预期结果;网页中的固定工具卡片或模拟消息不作为证据。Server 不可用时 Agent 不应继续假装调用成功。
Slice 5:审批与受限修改(可选扩展)
Section titled “Slice 5:审批与受限修改(可选扩展)”仅在前面只读路径稳定后,才增加修改能力。将模型建议转换为可审阅 diff;审批界面显示目标路径、变更内容和影响。用户批准后,执行器再次验证根目录、文件版本和批准内容一致,再以受限方式写入。获批不意味着任意路径写入;内容变化或审批过期时要重新确认。写后运行相关测试并保留实际结果。
**验收:**拒绝审批时文件不变;修改目标或内容后旧批准失效;获批后 diff 与实际写入一致;写入失败或测试失败被如实报告。若课程项目没有实现这些能力,应将其列为未完成,不要在简历或面试中声称支持。
Slice 6:失败恢复与评测
Section titled “Slice 6:失败恢复与评测”为模型超时、工具超时、明确失败、取消、重启恢复和结果未知增加固定 stub 或隔离测试。涉及外部写入时,设计幂等键、状态查询或人工恢复;禁止对未知结果无条件重试。将提示注入样例放入仓库文件或检索文本,检查它不会扩大工具权限。记录脱敏 trace 和评测结果。
**验收:**测试能确定性复现成功、拒绝、失败和未知结果;没有 API Key 也能运行核心边界测试;每个失败能定位到检索、模型决策、参数校验、工具执行、审批或报告环节。
建议目录草图
Section titled “建议目录草图”这是可调整的设计建议,不是当前仓库已有的目录:
repo-agent/ README.md # 范围、启动、限制与安全说明 pyproject.toml src/repo_agent/ app.py # 命令行/本机入口 graph.py # 有界状态与节点路由 state.py # 显式状态、预算和停止原因 policy.py # 工具白名单、参数和路径策略 retrieval.py # 片段检索与来源位置 citations.py # 引用生成及支持关系检查 tools/ filesystem.py # 受限只读工具 mcp_client.py # 本机 MCP Client 封装 writer.py # 可选;审批后受限写入 approval.py # diff 展示、批准绑定与再验证 tracing.py # 脱敏事件与关联 ID tests/ test_paths.py test_retrieval_citations.py test_agent_limits.py test_mcp_stdio.py test_approval_write.py test_faults.py evals/ questions.jsonl # 带标准答案/证据位置的问题集 attacks.jsonl # 注入和越权测试输入目录结构不是边界本身。例如 policy.py 存在并不证明所有文件操作都经过它;要通过代码调用链和拒绝测试证明执行器实际应用了策略。测试中使用无密钥 stub;真实模型调用可作为单独集成测试,并明确标示其服务商、费用和数据处理边界。
端到端 trace 应回答什么
Section titled “端到端 trace 应回答什么”一次研究任务的 trace 至少要能回答:用户问题是什么(可脱敏);用了哪个模型/配置;检索到哪些路径与行段;模型建议过哪些工具;工具执行器接受或拒绝了什么参数;预算消耗多少;为什么停止;最终答案引用了什么证据。写操作还需包含审批对象、审批结果、绑定的 diff/版本以及写入和测试的实际结果。
不要只保存模型的最终文本。若模型说“我已运行测试”,但 trace 没有测试进程的退出码和输出摘要,系统就没有证据证明测试执行过。错误可以向用户简化表达,但内部状态要区分模型未回答、工具失败、审批拒绝、预算耗尽和结果未知。
评测集怎样支持判断
Section titled “评测集怎样支持判断”对一组小而明确的问题,先人工标注标准答案和必要证据位置,再按阶段报告结果。可以统计检索 Top-k 中包含必要证据的问题比例、引用定位正确率、答案事实是否得到片段支持、证据缺失时的拒答行为,以及工具参数是否符合任务。数字要连同题集规模和样例范围一起报告;十道自选问题上的满分只表示这十道题通过,不能推广为对任意仓库都可靠。
错误最好按原因拆分。例如某题答案不对,若正确片段不在候选集合中,优先调查切分与召回;片段已包含证据但答案推导错误,才调查生成或证据判断;答案内容正确但行号指错,应修引用定位。若只汇总最终答案准确率,会把不同问题混成一个数字,难以选择下一项改进。
对副作用和权限测试不要只统计成功率。单条未授权写入就是需要处理的安全失败。为越界路径、被拒审批、审批后参数变化、提示注入和结果未知定义明确的预期行为;持续集成或本地测试应验证它们没有触发写入、外发或权限扩大。核心权限边界的通过条件应是拒绝行为正确,而不是“总体正确率够高”。
验收 Rubric(每项 0–2 分)
Section titled “验收 Rubric(每项 0–2 分)”| 维度 | 0 分 | 1 分 | 2 分 |
|---|---|---|---|
| 权限与路径 | 可读写任意路径 | 有部分校验或拒绝用例 | 默认只读、根目录强制约束,关键路径/参数拒绝测试通过 |
| 证据与引用 | 无来源或伪引用 | 有路径但定位不完整 | 路径与行段可复查,结论逐项有证据,无证据时拒答 |
| 工作流边界 | 无限循环或无失败分支 | 只有轮数限制 | 工具、时间、费用预算明确,失败与终止条件可测 |
| 副作用恢复 | 超时盲目重试 | 有人工确认但状态不清 | 结果未知独立建模,有幂等/查询/人工恢复策略 |
| 测试与可复现性 | 只演示一次成功 | 有若干单测 | 成功、边界、拒绝、超时、注入等有固定可复现实例 |
总分 10 分,建议至少 8 分;权限与路径、副作用恢复任一项为 0 时,不应进入自动写入扩展。分数只是课程验收工具,不是生产安全认证,也不能替代真实部署审查。
项目演示的顺序
Section titled “项目演示的顺序”一次 5–8 分钟演示可以按以下顺序组织:
- 说明目标用户、数据边界和当前实现范围。
- 演示一个只读问题,打开引用对应的源文件行段。
- 演示一个无答案问题,展示系统如何承认证据不足。
- 展示一次越界路径或提示注入被拒绝的 trace。
- 若实现了写入,演示审批前后状态,并确认拒绝时文件不变;再展示获批后的 diff 和测试实际结果。
- 展示超时/结果未知测试,解释系统为什么没有盲目重试。
- 说明哪些能力尚未实现、未覆盖的风险和本机运行条件。
演示只证明展示出的路径。单次成功不能证明所有工具安全、所有引用正确或生产系统可靠。标注固定 stub、模拟服务和真实 MCP Server 的区别。
面试故事:讲实现与证据,不夸大功能
Section titled “面试故事:讲实现与证据,不夸大功能”用“问题—设计—验证—限制”组织回答:
- **问题:**具体用户任务是什么,原流程哪里容易出错?只陈述自己实际观察到的情况。
- **设计:**你实际实现了哪些节点、工具和边界?区分已完成、计划和外部依赖。
- **验证:**用哪条 trace、测试或评测集确认行为?给出可复现命令和失败样例,不用“效果很好”代替数据。
- **限制:**哪些攻击、错误或部署条件还没覆盖?下一步会怎样验证?
例如可以说:“我实现了本机只读检索和带路径行号的回答;用固定问题集分别检查召回和引用支持。写入审批还是设计项,没有实现,因此这个版本不会修改文件。”如果 capstone 仍是计划阶段,就把它称为方案或练习目标,不要包装成已交付系统。
面试问题与参考回答
Section titled “面试问题与参考回答”1. 如何证明引用支持答案,而不只是存在路径?
保存检索片段的原文、路径和行范围;对答案里的每个事实判断对应片段是否蕴含该结论。使用带标准证据位置的问题集,分别报告检索命中、引用正确和结论支持率;无证据样例应允许拒答。
2. 写工具超时后系统处于什么状态?
若服务端执行状态不明,应标为结果未知。先按操作 ID 查询或用服务端支持的幂等键安全重试;都没有时停止自动写入并交由用户核验。
3. 怎样定位端到端失败?
用关联 ID 检查逐阶段 trace:检索是否召回证据、模型是否选择正确节点、参数校验是否通过、工具是否执行、审批是否匹配、最终报告是否对应真实结果。每阶段设置结构化错误类型和独立测试。
4. 哪些指标不能取代运行时权限控制?
回答准确率、拒答率、工具选择准确率和提示注入评测只能说明已测样例上的表现,不能阻止新的越权参数。文件根目录、工具白名单和审批必须由执行器在调用时强制执行。
5. 你的方案有哪些未验证之处?
回答自己的真实情况,例如当前只测试固定 stub、尚未验证长时间运行或真实多用户授权。解释影响和补测计划;不要用假设能力填补实现空白。
最终验收清单
Section titled “最终验收清单”- 本机只读研究 trace 可复现,引用含相对路径和行范围。
- 越界路径、无答案及恶意输入均有拒绝或安全降级测试。
- 工具白名单、最大轮次、超时和预算在运行时生效。
- MCP 如被列为已实现功能,有本机真实 Client/Server 调用证据。
- 若包含写入,拒绝审批时内容不变;批准绑定具体 diff;写后测试结果可查。
- 超时、取消与结果未知测试不把状态误报为成功或失败。
- 说明本机依赖、模型费用、数据边界、公开站点与私有仓库的区别。
- 面试陈述清楚区分已实现、已验证、模拟和计划中的功能。