题目结构说明:每题四部分。考点定位讲面试官在考察什么;深拆是机制加数字加失败模式,数字是可信度的来源;工程方案给 Python 风格伪代码或可复制模板给占位符模板,逐行中文注释就是面试时口述的话术;追问链是答完后大概率跟上的问题,附答法。标记:⭐ 高频(出现率过半)、🔥 近两年新增。Q1 Coding Agent 架构:探索-编辑-验证三段回路 ⭐🔥考点定位:考对 coding agent 的本质理解。最常见的丢分姿势:把 Claude Code 说成「模型帮你写代码的插件」,答不出它和代码补全差在哪一层。分水岭就在验证回路:补全是单轮预测,agent 是带客观反馈的闭环。这题答好了,后面九题的框架就立住了。深拆:三段回路是机制骨架。探索阶段只做只读操作:看目录树、grep 符号、读相关文件,目的是把「改哪里、依赖谁」变成模型上下文里的事实;编辑阶段基于事实产出最小 diff,原则是不重写没弄懂的代码;验证阶段跑测试、编译、lint,让编译器和测试当裁判,失败信号回喂给下一轮编辑。与补全的本质区别在正确性来源:补全输出的正确性靠人眼审查,模型自己不知道对不对;agent 闭环把正确性从「看起来对」变成「跑起来对」,错误信号来自确定性的外部程序,模型可以据此自我纠错,这是它能独立领任务的前提。数字上,一个中等复杂度的修复任务通常要跑几十轮工具调用,其中验证类调用占相当比例;公开榜单上头部模型在 SWE-bench Verified 的通过率从 2024 年中的三成上下提升到 2025 年底的七成上下,截至 2026-08 头部已到八成上下,涨幅的主要来源不是模型变聪明,而是验证信号和上下文工程变好。失败模式两种:验证环节缺失时,模型写完就宣称完成,即幻觉式完成,diff 看着漂亮根本跑不起来;验证信号本身有噪声(flaky 测试、环境依赖缺失),模型跟着噪声修三轮,把好代码改坏。工程上还有个细节常被忽略:验证输出不能全量回喂,一份全量测试日志几万 token,回喂给模型的应是解析后的失败摘要加相关代码片段,结构化错误信号的利用率远高于原始日志。工程方案:def coding_agent_loop(task, max_steps=40): # 探索阶段:只读操作,把仓库结构和相关符号变成上下文里的事实 facts = explore(task) # 读目录树、grep 符号定义、读命中文件的关键片段 diff = plan_and_edit(facts, task) # 编辑阶段:最小 diff,不重写没读懂的代码 verdict = verify(diff) # 验证阶段:跑目标测试,编译器当裁判 for step in range(max_steps): if verdict.passed: return diff # 客观信号通过才算完成,模型自述不算数 # 验证失败:带着报错回到编辑段,而不是推倒重来重新探索 diff = edit_with_errors(diff, verdict.errors) verdict = verify(diff) return escalate(diff, verdict) # 步数耗尽:止损升级,附上最后一份报错追问链:「为什么失败后回到编辑而不是回到探索?」- 报错已经是精确定位的事实,重新探索是浪费;只有当编辑连续多轮修不动同一报错时,才说明探索阶段的事实收集有问题,该回去补探索。「三段的边界是硬的还是软的?」- 是软约束:现代 agent 产品并不强制分段,模型在单循环里自由选择工具,三段是分析行为的视角,也是写系统提示词时的引导框架,面试时能讲清这个软硬之辨反而加分。「验证只有测试一种吗?」- 测试是金标准但不是唯一信号,编译通过、类型检查、lint 是更便宜的分层信号,聪明的做法是按成本从低到高逐层验,测试放最后。Q2 仓库级上下文工程:repo map 与按需懒加载 ⭐🔥考点定位:coding agent 区别于「把代码粘给模型」的核心工程题。看的是候选人知不知道大仓库根本塞不进上下文,以及塞进去的部分怎么选。答「用 200k 窗口装下整个仓库」的基本没算过账;能主动讲出 repo map、懒加载、预算分配三个词的,才算摸过这类系统。深拆:机制三件套。第一是目录树概览:给模型一张两到三层的地图,让它知道这个仓库有哪些模块、往哪找;第二是符号索引:用 ctags 或 tree-sitter 这类工具给全仓的函数、类、方法建索引,只保留名字、签名和位置,不含实现体,几万行代码的索引压缩后只有几千 token,模型据此决定读哪些文件的哪些片段;第三是按需懒加载:探索请求只命中片段就只读片段,绝不整文件硬灌。上下文预算要显式分配:常见做法是 repo map 与已加载代码占大头,给对话历史和模型输出各留固定比例,探索类内容超预算就触发压缩,把早期读过的文件摘要化。目录树只给两到三层也是预算考量:给全量树会让 map 体积随仓库线性膨胀,两层概览足以支撑「去哪个模块找」的决策,更细的结构交给符号索引表达。数字上一家中型仓库几十万行、几百万 token,超出任何窗口一个数量级,全量加载从一开始就是死路;懒加载下一个任务实际进上下文的代码常常只有仓库的百分之几,这百分之几选得准不准,直接决定任务成败,上下文工程在 coding agent 里的权重不亚于模型本身。repo map 还有一个常被漏讲的要求:常驻。多轮任务里它是每轮决策「去哪找」的底图,必须始终在场且随编辑增量更新,而不是每次重新构建。失败模式两种:一种是探索失控,模型连环读了几十个文件,上下文在写第一行代码之前就被灌爆,只能中途压缩,关键事实在压缩中丢失;另一种是只看符号签名不读实现就动手改,调用约定全靠猜,diff 看着对、一跑就崩。工程方案:def build_repo_context(repo, task, budget=100_000): ctx = [] ctx.append(tree_overview(repo, max_depth=2)) # 目录树地图:先让模型知道去哪找 ctx.append(symbol_index(repo)) # ctags 类索引:名字加位置,不含实现体 used = sum_tokens(ctx) reserve = int(budget * 0.3) # 三成预算留给对话历史和输出 for hit in rank_by_relevance(symbol_index, task): if budget - used reserve: break # 触顶即停:宁缺勿滥,绝不挤占保留区 chunk = read_lines(hit.path, hit.line_span) # 懒加载:只读命中的行区间 ctx.append(chunk) used += tokens(chunk) return ctx # 后续按需追加,用一次读一次 def compact_if_needed(ctx, threshold=0.9): # 压缩策略:diff、验证报错、关键决策保留原文,探索过程摘要化或直接丢弃 if tokens(ctx) threshold * WINDOW: return [system, summarize_explored(ctx), keep_artifacts(ctx)] return ctx追问链:「为什么符号索引优于向量检索?」- 代码的引用关系是精确的,改一个函数要找的是它的定义和调用点,符号索引零误差;向量检索解决语义相似,适合找「大概在哪」,两者常配合用而不是二选一。「读过的文件被编辑后索引怎么办?」- 编辑后对该文件做增量重索引,符号索引是缓存就有失效问题,失效的索引比没有索引更害人。「预算怎么在多轮任务里持续生效?」- 每轮检查水位,超阈值先摘要早期内容再继续,diff 和报错这类硬事实标记为不可压缩项。Q3 验证回路:测试反馈驱动的修错循环 ⭐🔥考点定位:这是 coding agent 面试最可能让你现场手撕的一段。考三件事:修错循环怎么写、最大迭代次数设多少、修不好怎么止损。只会「跑测试、报错给模型」一句话的,属于没做过;追问一定会落在数字和止损上,那是区分背过和写过的位置。深拆