ARTICLE · 人工智能

为编程模型提供正确的上下文

作者:Multigrid 来源:DEV Community: machinelearning 2026-08-08 06:55 5 分钟 6 阅读 1160 字
AI 编程LLM上下文工程开发者工具Prompt 工程
一语总结

本文提出了一个为编程 LLM 构建上下文的实用框架,将其视为 Token 预算问题,并详细介绍了签名索引、基于图的排序、高价值上下文元素、浪费规避以及缓存感知排序。

AI 总结

作者将编程智能体的上下文构建定义为一个严格的 Token 预算问题,而非简单的检索问题。由于代码的 Token 化率约为 3 字符/Token(约 10 Token/行),即使是 1M Token 的窗口也只能覆盖 100 万行代码库的 10% 左右。解决方案是发送签名(路径 + 导出符号)而非完整正文,从而将 Token 成本降低 10-100 倍。由于扁平的签名索引仍可能超出预算,因此必须通过基于图的传播(在导入图上运行 PageRank)进行排序,并以任务提及的文件作为种子,从而捕捉词法搜索会遗漏的依赖关系。剩余预算按优先级自顶向下分配:核心文件提供完整正文,次级文件提供签名,其余则不提供。高价值上下文包括:带有精确输出的失败测试、需要修改的 2-3 个文件、它们之间的接口、一个现有的模式示例以及版本锁定。主要的 Token 浪费源于:生成的文件/锁文件/压缩文件(需要明确的忽略列表)、重复的文件包含(按路径去重并保留最新版)以及过时的聊天历史。排序同样至关重要:Liu 等人 (2023) 的研究表明检索准确率呈 U 型分布,因此指令和失败测试应放在最后,大宗参考资料放在中间。这种排序还符合 Prompt 缓存机制——稳定的前缀(仓库指令、签名索引)在前,半稳定内容(任务文件)在中,易变内容(对话记录、指令)在后。缓存行为因供应商而异,需通过单次请求的缓存报告进行验证。

核心要点
  1. 上下文构建是 Token 预算问题,而非检索问题。

    代码的 Token 化率约为 3 字符/Token(约 10 Token/行),因此即使是巨大的上下文窗口也只能覆盖代码库的一小部分。深思熟虑的选择优于随机包含。

  2. 发送签名(路径 + 导出符号)而非完整正文,然后通过图传播进行排序。

    签名的成本仅为 15-30 Token,而正文则需数百个。扁平索引仍会超出预算,因此应构建导入图,以任务提及的文件为种子,运行 PageRank 风格的传播以挖掘相关依赖。

  3. 剩余预算自顶向下分配:核心文件提供完整正文,次级文件提供签名,其余不提供。

    这种分配方式最大化了信息密度。aider 项目的 repo map 有效地证明了这一方法的成功。

  4. 最高价值的上下文块:带有精确输出的失败测试、待修改文件、接口、一个模式示例、版本锁定。

    失败的测试是明确的基准真相。接口可以避免模型进行昂贵的猜测。一个真实的示例比文字描述更能教会模型遵循约定。

  5. 避免隐形的 Token 浪费:生成/锁/压缩文件、重复包含以及过时的聊天历史。

    维护一个明确的忽略列表(不仅是 .gitignore)。在构建前按路径去重,仅保留最新版本。冗长的对话记录包含过时的前提,会降低会话质量。

  6. 为了模型注意力与 Prompt 缓存而优化上下文顺序:稳定内容在前,易变内容在后。

    “Lost-in-the-middle”研究表明检索准确率呈 U 型分布。将指令和失败测试放在末尾。这种排序还为 Prompt 缓存创建了稳定的前缀,这在智能体循环中至关重要。

为编程模型提供正确的上下文

作者将编程智能体的上下文构建定义为一个严格的 Token 预算问题,而非简单的检索问题。由于代码的 Token 化率约为 3 字符/Token(约 10 Token/行),即使是 1M Token 的窗口也只能覆盖 100 万行代码库的 10% 左右。解决方案是发送签名(路径 + 导出符号)而非完整正文,从而将 Token 成本降低 10-100 倍。由于扁平的签名索引仍可能超出预算,因此必须通过基于图的传播(在导入图上运行 PageRank)进行排序,并以任务提及的文件作为种子,从而捕捉词法搜索会遗漏的依赖关系。剩余预算按优先级自顶向下分配:核心文件提供完整正文,次级文件提供签名,其余则不提供。高价值上下文包括:带有精确输出的失败测试、需要修改的 2-3 个文件、它们之间的接口、一个现有的模式示例以及版本锁定。主要的 Token 浪费源于:生成的文件/锁文件/压缩文件(需要明确的忽略列表)、重复的文件包含(按路径去重并保留最新版)以及过时的聊天历史。排序同样至关重要:Liu 等人 (2023) 的研究表明检索准确率呈 U 型分布,因此指令和失败测试应放在最后,大宗参考资料放在中间。这种排序还符合 Prompt 缓存机制——稳定的前缀(仓库指令、签名索引)在前,半稳定内容(任务文件)在中,易变内容(对话记录、指令)在后。缓存行为因供应商而异,需通过单次请求的缓存报告进行验证。

文章金句

"

上下文构建在成为检索问题之前,首先是一个预算问题,而且这个预算比宣传的窗口大小要紧得多。

"

一行签名大约消耗 15 到 30 个 Token,而它所代表的函数则需要数百个,因此同样的预算可以覆盖多出一到两个数量级的代码库。

"

失败的测试及其精确输出……是整个 Prompt 中价值最高的部分,因为它是唯一部分是毫无歧义的基准真相。

"

在构建之前按路径去重,任何文件仅保留一份且必须是最新版本。这是自研上下文构建器中最常见的 Bug。