60 秒回答模板

如果文件过长超过 LLM 上下文窗口,我不会把整文件硬塞给模型,而是把问题变成相关代码定位和最小上下文构造。第一步建立代码结构索引,包括文件路径、符号、函数、类、调用关系、import、注释和行号;第二步结合 grep、AST 分析、LSP、调用图和语义检索找到候选片段;第三步按任务打包上下文,包含相关函数、接口定义、调用方、被调用方、配置和测试,而不是连续截取一大段文本;第四步让模型基于带行号和来源的片段分析或生成补丁,必要时分轮补充上下文;第五步用编译、单测、静态检查、搜索引用和人工 review 验证。核心原则是用工具负责召回和裁剪,用模型负责理解和改动建议,并保留可追溯的代码范围。

考点 不要把长文件硬塞给模型
难度 真实面经题
回答目标 处理长文件上下文窗口限制

深入解析

01

先识别任务需要的代码范围

文件超过上下文窗口时,问题不是模型不够长,而是上下文选择不够精确。代码定位和代码生成通常只需要与 bug、接口、符号或调用链相关的片段。先明确任务目标,例如定位某个异常、修改某个函数、补测试或理解某个调用路径,再决定需要哪些代码范围。

02

建立符号和结构索引

长文件应先被结构化处理。可以用 AST、LSP、ctags、tree-sitter 或语言编译器拿到函数、类、方法、字段、import、注释、行号和作用域。结构索引能帮助模型拿到完整函数或类定义,而不是被固定 token 切块切断语义。

03

结合关键词和语义检索

只做向量检索可能漏掉精确标识符,只做 grep 又可能漏掉语义相关代码。更稳的做法是先用错误信息、函数名、变量名、日志、接口路径做精确搜索,再用 embedding 或语义检索扩展相关片段,并根据调用关系、最近修改和测试引用重排候选。

04

打包最小但完整的上下文

传给 LLM 的上下文应该包含任务说明、相关代码片段、行号、文件路径、接口定义、调用方、被调用方、类型定义和必要测试。不要只截取某个片段的前后 N 行,也不要塞入大量无关代码。对超长依赖可以提供摘要,但关键函数必须保留原文。

05

分轮补充而不是一次塞满

如果第一轮无法确定原因,可以让模型提出需要补充的符号、调用方或测试,再由工具取回对应片段。对于代码生成,可以先生成修改计划,再取相关范围生成最小补丁。这样上下文是按问题逐步扩展,而不是一开始耗尽窗口。

06

用工程验证闭环

模型输出必须经过编译、单测、静态检查、格式化、引用搜索和差异 review。长文件场景尤其容易漏掉隐藏依赖和边界分支,所以要验证修改范围是否覆盖所有调用点,并保留来源行号和检索依据,方便人工复核。

易错点

  • 把答案写成 long context 模型质量会下降,没回答长文件如何处理。
  • 直接按 token 固定切块,导致函数、类和作用域被切断。
  • 只用向量检索,漏掉错误信息、函数名和标识符的精确匹配。
  • 只给局部片段,不给调用方、类型定义、配置或测试上下文。
  • 让模型一次性生成大补丁,没有先定位和规划最小修改。
  • 缺少编译、单测、静态检查和引用搜索验证,无法证明修改正确。

面试官追问

为什么固定 token 分块不适合直接处理代码长文件?

固定 token 分块容易把函数、类、注释、类型定义和调用关系切断,导致模型看到的片段语义不完整。代码更适合按符号、AST、函数边界、类边界和调用链切分。

grep 和 RAG 在代码定位里各自适合什么场景?

grep 适合错误栈、函数名、配置项、日志关键字等精确线索;RAG 适合自然语言需求、相似实现和跨文件语义召回。生产里通常先用精确检索缩小范围,再用语义检索补充候选。

如何避免模型修改长文件时漏掉调用方或测试?

修改前要让 Agent 明确影响范围,补齐调用方、类型定义、配置和测试上下文。修改后跑引用搜索、编译、单测、静态检查和相关用例,必要时让模型解释每个变更对应的证据行。

什么情况下应该给模型代码摘要,什么情况下必须给原文?

摘要适合提供项目结构、模块职责和历史上下文;涉及具体修改、边界条件、类型签名和逻辑判断时必须给原文片段。摘要不能替代需要逐行编辑或精确定位的代码证据。

代码 Agent 如何记录它使用过的代码证据?

应记录检索 query、命中的文件和行号、选择片段的原因、引用关系、模型生成的假设和验证命令结果。这样能审计为什么改这个地方,也方便失败后回放和修复检索策略。

如果检索召回了多个相似函数,如何让模型选对目标?

先用错误栈、调用关系、类型签名、最近变更和测试失败信息给候选排序,再让模型比较候选函数的输入输出和调用路径。不要只按向量相似度选择,要结合精确证据和验证结果。