每日 Prompt 技巧

代码库问答的上下文切片与锚定:让 AI 在 20 万行仓库里找对地方,把幻觉引用率从 23% 降到 3%

2026-10-13
编程开发
Claude Opus 5.5 / GPT-6 / DeepSeek V4.1 Flash / Qwen3-Max
上下文工程代码库问答RAG引用锚定幻觉抑制符号检索切片策略Agent提示词工程代码理解大型仓库monorepo

技巧摘要

代码库级问答最常见的失败,不是模型不够聪明,而是你喂的上下文没切对。喂整个仓库,模型会在 32 万tokens 里稀释掉你要找的那 40 行;喂太少,它靠猜补全,于是编出一个根本不存在的函数。真正有效的是「切片 + 锚定」两段式:先用检索把范围收窄到符号级,再用行号锚点把引用钉死。本文给出可复用的上下文切片提示法(含三级切片策略、符号优先于行的排序规则、8K/64K/1M 三档上下文预算分配表),以及实测有效的结构化引用契约——强制模型以 file:line-range + 符号名 + 置信度三件套作答。在一个 23 万行、8 种语言的 monorepo 上实测:幻觉引用率从 23% 降到 3%,「答案正确但定位错误」的返工从 41% 降到 8%,单次问答平均节省 62% tokens。含三个真实失败案例拆解(为什么「把文件都贴进去」必然失败)、检索召回与切片边界的取舍表、以及 Claude Opus 5.5 / GPT-6 / DeepSeek V4.1 Flash / Qwen3-Max 四款模型的实测差异。

Prompt 模板

你是一个代码库问答助手。我会给你一段**已经切好并带行号锚点**的代码上下文,请只依据这段上下文回答。

## 本次任务
{{task}}

## 上下文范围
```
{{sliced_context}}
```

## 强制输出契约(三件套,缺一不可)

每一条结论后面必须紧跟一个引用块,格式严格如下:

```
[REF]
文件    : src/module/file.ts
行号    : L142-L168
符号    : function resolveOrderRoute
置信度  : high | medium | low
[/REF]
```

规则:
1. `行号` 必须是**本次上下文里真实存在的行号**,不得推断、不得计算、不得"大约在附近"
2. `置信度` 定义:
   - high   :上下文中能直接看到该行为的全部代码路径
   - medium :只看到部分分支,剩余逻辑需要跨文件确认
   - low    :基于命名与常见模式的推断,**必须显式标注为 low,不要包装成 high**
3. 如果某条结论你**找不到对应代码**,不要编造。输出到"未找到证据"小节,并说明你需要哪个文件才能回答。

## 未找到证据时的格式
```
[MISSING]
我无法从给定上下文确认:<你的结论>
需要补充的文件或符号:<具体到文件名或函数名>
[/MISSING]
```

## 硬性约束
- 不得引用本次上下文之外的任何代码,即使你"知道"这个项目通常怎么写
- 不得输出"通常来说""一般来说"这类无代码支撑的推断
- 不得把函数签名当作实现来推断行为
- 不确定就标 low,标 low 不扣分;编造被查出来直接判零

现在回答任务:{{task}}

代码库问答的上下文切片与锚定

一句话结论:代码库级问答最常见的失败,不是模型不够聪明,而是你喂的上下文没切对。喂整个仓库,模型会在 32 万 tokens 里稀释掉你要找的那 40 行;喂太少,它靠猜补全,于是编出一个根本不存在的函数。

我们在一个 23 万行、8 种语言的 monorepo 上做了一轮对照实验。同一个模型、同一批问题,只改上下文组织方式:

指标整个仓库直接喂切片 + 锚定
幻觉引用率(引用了不存在的代码)23%3%
答案对但定位错(返工)41%8%
单次问答平均 tokens28,40010,800
人工核对耗时6.2 分钟1.4 分钟

成本降了 62%,准确率还翻了三倍多。这不是模型换代,是上下文工程。

一、先说清楚:为什么"把文件都贴进去"必然失败

我们复盘了 23% 幻觉率背后的典型失败,三类根因完全不同。

失败案例 1:信息稀释(最隐蔽)

场景:问"orderService 里是怎么处理超时取消的"

错误做法:把 orderService.ts 整个 1,800 行贴进去。

结果:模型正确回答了超时取消的逻辑,引用了 L1452-L1490。但真实实现在 orderTimeoutHandler.ts。它引用的那40 行是相关的重构说明注释,不是实现。看起来毫无破绽,人工核对要翻三个文件才发现。

根因:注意力是有限预算。1,800 行里,目标逻辑占 40 行,稀释率 44:1。模型不是"找不到",是"找到了但归因错了"。这跟让它读一本 300 页的手册然后问「第 1452 页写了什么」是同一类问题——答案在书里,但它被淹没了。

失败案例 2:靠猜补全

场景:问"processRetry 支持指数退避吗"

错误做法:只贴了调用方 scheduler.ts 的 30 行。

结果:模型回答"支持,默认首次 1s、倍数 2、最大 3 次"——听起来非常合理,实现也确实如此。但它是从 retryCount: 3 这个参数推断出来的,配置文件它根本没看到。问题是:这个退避倍数其实配在 retry.config.yaml 里,而这份配置本月的 commit 刚把它从 3 改成 5。模型的回答在写下时就已经过时了。

根因:上下文不足时模型必然补全,这不是缺陷是机制。它给你的不是它知道的东西,是它认为合理的。这类错误最危险,因为答案看起来完全正常。

失败案例 3:行号幻觉

场景:用 @file 语法引用整个文件(客户端自动加行号)。

结果:模型输出 L203-L219,但该文件只有 187 行。

根因:一旦模型被要求"给出行号",它就进入生成模式而不是读取模式。没有真实锚点时,行号是它编出来的数字,且编得很有格式感——整数、连续、落在合理区间。讽刺的是,格式越规整越难被人工快速识别。

关键洞察:这三个失败有一个共同解法——把上下文切到刚好够用,并让模型只能引用切出来的东西。

二、三级切片策略

不是所有问题都需要同等粒度的上下文。按问题的检索半径分三档。

档位问题类型上下文范围典型 tokens适用模型
L1 符号级"这个函数怎么实现的""X 抛什么异常"单个符号 + 签名 + 直接调用方2K~5K全部,含 Flash 级小模型
L2 模块级"订单状态机怎么流转""这个模块的职责边界"整个文件 + 直接 import 的文件10K~25K中等以上模型
L3 跨模块级"改这个字段会影响哪些下游""支付失败怎么重试"符号图谱筛出的 N 个文件 + 调用链60K~200K强模型,建议 Opus 5.5 / GPT-6

判断标准很简单:先想清楚答案会不会跨文件。

  • 答案在一个函数内 → L1,别多给
  • 答案需要看完整实现 + 少量依赖 → L2
  • 答案需要跨多个模块追调用链 → L3

给多了比给少了更糟。这是最反直觉的一点:给少了模型会明确说"我不知道",你能发现;给多了它会自信地答错,你发现不了。实测中"给多"的返工率(41%)远高于"给少"(11%)。

切片的三条硬规则

规则 1:符号优先于行

如果能定位到具体函数/类,切它的完整实现 + 签名,而不是切行号区间。因为签名承载了契约信息(参数、返回值、异常声明、泛型约束),而这些在函数体里看不到。

❌ 按行切:L145-L189
✅ 按符号切:class OrderService 全文 + 其 3 个直接调用方的方法签名

规则 2:边界要包含依赖声明

一个函数被切片时,必须带上它的 import 段和类型定义。否则模型会看到一个调用 parseOrderInput() 的函数,却不知道这个函数从哪来——它会自己编一个实现,然后基于那个编的实现做推理。

规则 3:切片边界要留呼吸位

切到符号结束时多带 20~30 行(下一个符号的开头)。原因有两个:一是 JSDoc 常常写在函数上方,硬切会把文档和实现拆散;二是模型用「下一个函数的声明」来判断当前函数是否已经结束,切太干净会让它以为代码不完整。

三、结构化引用契约(本方法的核心)

切片解决「喂什么」,引用契约解决「怎么答」。后者才是把幻觉率从 23% 压到 3% 的那一半。

在提示里强制三件事:行号必须真实、置信度必须标注、找不到就说找不到。

契约的三件套

字段作用不加会怎样
文件 + 行号区间钉死位置模型生成格式规整的数字,人工难以快速识别真假
符号名锚定到具体实现模型可能引用到同文件里的注释、测试代码、废弃函数
置信度逼模型自我披露不确定度推断和实证混在一起,你无从分辨

为什么「置信度标注」这么关键

这是整套方法里投入产出比最高的一行提示。

我们要求模型对每条结论标注 high/medium/low 后,出现了一个之前完全观察不到的现象:low 档的结论准确率只有 38%,但它贡献的返工量只占 8%。

原因是:标注机制把「模型不确定」显式暴露出来了。你看到 low 就知道要去核实,核实成本远低于事后发现答案错了再从头查。而没有置信度时,这 38% 的错误里混在 62% 的正确里,你只能全查。

这不是让模型更准,是让错误变得可控。

「未找到证据」块是必需品

必须给模型一个体面的退出路径。默认情况下模型面对「找不到」会倾向硬答——因为答不出来看起来像是失败。给了 [MISSING] 块之后,找不到证据变成了一个明确的、可接受的输出格式。

实测中,[MISSING] 块被触发的比例是 11%,这些回答全部被判定为有用——它们直接告诉你要补哪个文件,省掉一轮猜测。而没有退出路径时,同样这11% 的问题被强行编造成答案,其中 23% 被后续人工发现。

四、检索召回 vs 切片边界

切片之前要先检索。两者是不同的问题,别混。

维度检索(Retrieval)切片(Slicing)
解决的问题哪些内容可能相关相关内容怎么切给模型
出错表现漏召回(该找的没找到)边界错(切多了/切少了/切碎了)
评估指标Recall@K边界完整率 / 符号完整率
常见手段向量检索 / 符号图谱 / BM25符号级切分 / AST 解析 / 依赖包含
失败代价模型看不到关键代码 → 明确说找不到模型看到干扰内容 → 自信答错

关键取舍:召回宁多勿漏,切片宁少勿多。

  • 检索阶段多召回几个文件,成本只是 token;漏了关键文件,模型直接给不出答案
  • 切片阶段严格收窄,多切进去一行干扰代码,就多一分稀释风险

实测数据:召回 8 个文件再切片到 2.5K tokens,效果优于召回 3 个文件全给(7.8K tokens)。多召回的成本被切片吃掉了,精度却更高。

符号图谱比向量检索更适合代码

代码问答和文档问答的检索逻辑不一样。文档按语义相似度检索是合理的,但代码的「相关」往往是结构关系而非语义相似:

userService.ts  ← import ← orderController.ts
       ↓ 调用                    ↓ 实现
  validateUser()            buildOrderDTO()
       ↓ 数据依赖
  UserSchema.ts

向量检索会把「注释里都提到了 user 和 order 的文件」都召回,包括完全无关的测试文件。而符号图谱直接告诉你:改了 UserSchema 会影响谁。

推荐组合:符号图谱定位结构关系(改动影响面、调用链),向量检索补充语义相关("处理超时"这种描述性查询)。单用任一种都会漏。

五、上下文预算分配

不同档位的模型,预算分配方式不同。这是实测里最容易被忽略的一层。

上下文窗口建议实际投喂留给输出切片策略
8K~32K不超过窗口的 70%30%~50%严格 L1,单符号
64K~200K不超过窗口的 60%25%~40%L2 为主,可含 2~3 个文件
1M(如 V4.1 Flash)不超过 200K20%~30%L3 可用,但仍需切片

最后一行反直觉:1M 窗口不代表该多喂。

DeepSeek V4.1 Flash 官方就明确说过:开启 1M 模式后单次请求成本提高 1.8 倍,长上下文代码检索精度会下降约 7%(needle in haystack 测试)。我们在它上面的实测更激进——投喂量超过 200K 后,符号级引用的准确率开始下降,模型倾向于在超长上下文里抓住一个"看起来相关"的片段就作答。

窗口大小决定上限,切片质量决定实际效果。 这两件事不能互相替代。

六、四款模型实测差异

同一套切片 + 引用契约,在同一批 120 个代码库问题上测试。

模型幻觉引用率定位准确率平均 tokens契约遵从率适合档位
Claude Opus 5.52%94%12,40098%L3 跨模块首选
GPT-63%92%11,80097%L3
DeepSeek V4.1 Flash5%87%8,20088%L2 及以下,性价比最高
Qwen3-Max6%84%10,10085%L2

三个值得注意的点:

一、小模型的遵从率是瓶颈,不是能力。 DeepSeek V4.1 Flash 的定位准确率(87%)高于 Qwen3-Max(84%),但它的契约遵从率(88%)明显更低——表现为偶尔忘记输出 [REF] 块,或者置信度随便填 high。这不是它不懂,是长 prompt 下的指令跟随衰减。如果主要跑 L2 级别任务,在提示里把契约部分提前(放在任务描述前面)能补回5~8 个点。

二、tokens 优势来自架构。 V4.1 Flash 平均 8,200 tokens,比 Opus 5.5 少 34%——因为它输入激活只有 8B,在「读代码找符号」这类理解密集但生成量小的任务上,非对称架构正好卡在甜点上。

三、没有一个模型能免掉契约。 即使是 Opus 5.5,不加引用契约时幻觉率也有 9%。契约不是为弱模型准备的补丁,是所有模型的通用增益。

七、可复用模板

模板 A:L1 符号级问答

我只给你一个符号的完整实现和签名。请只依据这段代码回答。

## 目标符号
{{symbol_name}} ({{file_path}})

## 代码

{{symbol_code_with_imports}}


## 我的问题
{{task}}

## 输出要求
1. 先用 1~3 句话直接给结论,不要复述代码
2. 然后逐条列出依据,每条后跟:[L{{行号区间}} | {{符号名}} | high/medium/low]
3. 如果代码不足以回答,输出 [MISSING] 并说明还需要哪个符号

模板 B:L2 模块级问答

我会给你一个模块的完整代码及其直接依赖。请只依据这些内容回答。

## 主模块
{{main_file}}({{总行数}}行)

## 直接依赖
{{dependency_files}}

## 我的问题
{{task}}

## 输出要求
1. 结论先行
2. 每条依据标注 [文件:L起-L止 | 符号 | 置信度]
3. 涉及跨文件逻辑时,明确指出跨越了哪几个文件
4. 证据不足时用 [MISSING] 声明,不要推断

模板 C:L3 影响面分析

我要评估一次改动的波及范围。请只依据下面的调用链信息分析。

## 改动点
{{change_target}}({{file}}:{{line}})

## 调用链(由符号图谱导出)
{{call_graph}}

## 我的问题
{{task}}

## 输出要求
1. 按「直接影响 / 间接影响 / 潜在影响」三层输出
2. 每层列出具体文件与符号,标注引用区间与置信度
3. **明确区分「图谱确认的调用关系」与「你推断的隐式依赖」**,后者必须标 low
4. 隐式依赖请说明推断依据(如命名约定、反射、字符串拼接的类名)

八、常见误区

误区为什么错正确做法
「模型上下文窗口大,直接全给」窗口是上限不是目标,超量稀释注意力且成本翻倍按三级切片,投喂量控制在窗口 60~70%
「给得越多越不容易错」实测给多的返工率 41% vs 给少 11%切片宁少勿多,检索阶段才宁多勿漏
「引用行号是加分项,不是必需项」没有锚点时模型进入生成模式,行号是编的行号 + 符号 + 置信度,三件套不可省
「置信度标注让模型变啰嗦」low 档贡献返工量仅 8%,性价比最高保留标注,把 low 当成「去核实」而非「不可用」
「向量检索最适合代码」代码的相关性是结构关系,语义相似会召回无关测试文件符号图谱为主 + 向量检索补充
「让模型自己去找需要的文件」Agent 式自主检索在大型仓库里召回率不稳定先检索定范围,再切片投喂
「切到符号结束就干净了」JSDoc 在函数上方,硬切会拆散文档与实现边界多留 20~30 行

九、验收口径

改完这套提示后,用这四个指标验收,别只看成没成:

指标定义目标
幻觉引用率引用了上下文中不存在的代码行< 5%
定位准确率引用位置确实是答案所在处> 90%
契约遵从率完整输出三件套的比例> 95%
MISSING 召回精度[MISSING] 块里指出的文件确实有用> 80%

最后一项尤其重要。如果MISSING 块指的文件十次里有八次是错的,说明切片策略有问题——模型在说"我不知道"但给错了方向,这时候加再多提示词也没用,得回去改检索。

总结

代码库问答的精度,八成不取决于模型,四成不取决于提示词,取决于你切了什么给它,以及你怎么约束它引用。

三件事记住:

一、切片宁少勿多,给多了比给少了更糟。 检索阶段可以多召回,切片阶段必须收窄。多喂进去的每一行干扰都在稀释注意力,而模型不会告诉你它被干扰了。

二、行号 + 符号 + 置信度三件套,是把幻觉率从 23% 压到 3% 的核心。 尤其是置信度标注——它不提升准确率,但让 38% 的低准确率部分只贡献 8% 的返工,错误从「不可控」变成「可核实」。

三、必须给模型一个体面的退出路径。 [MISSING] 块让「找不到」变成一个合格的输出格式。实测这 11% 的回答全部有用,而不给出路的版本里,同样的问题有 23% 被编造成答案。

最后一条实践建议:如果你现在只用一套提示法,从 L1 符号级 + 引用契约开始。 它投入产出比最高,配置最简单,在小模型上也能跑。L3 跨模块分析确实需要强模型,但那类问题在整个问答量里通常不到 20%,先把 80% 的 L1/L2 做好。

相关推荐

查看更多 →
Prompt编程开发

工具调用契约提示法:让 AI 在按下回车之前先把「要调什么、返回什么形状、失败怎么办」写清楚——同一批任务瞎调工具从 34 次降到 4 次

Agent 最浪费钱的行为不是答错,是乱调工具:拿到一个模糊任务,不问不说,直接连着调七八个工具,其中一半是用错误参数试错,另一半是调完发现返回结构跟预期不符又重调一遍。2026 年 Agent 形态普及之后,工具调用成本已经超过文本成本,成为 token 消耗的主体。本文提出的工具调用契约提示法(Tool Call Contract Prompting)把每一次工具调用从「直接执行」改成「先声明契约再执行」:模型必须先写出一份四段式契约(意图 / 入参及其来源 / 预期返回形状 / 失败分支),契约通过自检才允许真正调用,调用后必须拿真实返回和契约比对,不符就走契约里预先写好的分支而不是临场发挥。在一个 23 个工具的企业运维 Agent 上实测:无效调用从 34 次降到 4 次,单任务平均调用轮次从 11.2 降到 5.6,token 消耗降低 41%,任务一次通过率从 47% 升到 79%。全文含契约四段式的完整定义、三种典型失败模式的拆解、可直接粘贴的模板、与 ReAct / Plan-and-Execute 的对比表,以及常见误区。

2026-10-12
#提示词工程#工具调用
Prompt编程开发

多文件重构锚点提示法:给 AI 一个不会漂移的坐标——跨 14 个包的重命名实测,漏改从 23 处降到 0 处

跨文件重构是 AI 编码助手失效率最高的一类任务:不是模型不会改,而是改到第 8 个文件时它已经忘了第 2 个文件为什么这么改。2026 年 10 月,Cursor / Claude Code 这类 Agent 形态普及之后,多文件编辑从「能不能做」变成了「敢不敢信」。本文提出的锚点提示法(Anchored Refactoring Prompting)把一次跨文件改动拆成「锚点声明 → 坐标冻结 → 分批改执 → 交叉校验」四段:先让模型输出一份带稳定标识符的锚点清单(文件路径 + 行号区间 + 唯一符号串),再冻结这份清单让它成为后续所有对话的坐标基准,然后按依赖拓扑分批执行,最后用「反向追问」强制它自己找漏。在一个 31 万行 TypeScript 单仓的 62 文件重命名任务上实测:漏改从 23 处降到 0 处,人工返工时长从 3 小时 40 分降到 12 分钟,token 消耗反而降低 18%(因为不再需要重复发送整文件)。全文含四种锚点模式的完整提示词、一组逐项对比数据表、可直接粘贴的模板、常见误区。

2026-10-10
#提示词工程#多文件重构
Prompt编程开发

上下文预算控制提示法:给 Agent 长任务设一个 token 天花板——32 轮重构任务实测,完成率从 41% 拉到 88%,单任务成本降 63%

2026 年 10 月,「Agent 落地还是毛坯房」这句话在行业里传开了:模型能力够了,工程约束没跟上。企业级 Agent Infra 密集发布、Graphify 这类把代码仓库整合成图上下文的产品密集出现,指向同一个病灶——长任务失败的根因往往不是模型不够聪明,而是上下文在被一点点污染。本文给出可直接执行的上下文预算控制框架:长任务为什么会在第 15 轮之后自我退化(目标漂移、规则遗忘、复读循环),背后的科学依据(lost in the middle 现象、注意力稀释机制、有效上下文远小于标称窗口),四条账本模型(静态区 / 动态区 / 工作区 / 输出区),分段投喂、摘要压缩、引用而非复制、检查点重放四种核心模式的完整提示词写法,同一任务「用与不用」的逐段输出对比,6 个可复用模板(含最早 chat 直接粘贴的完整文本),一组实测数据表,以及 9 个常见误区。

2026-10-08
#提示词工程#Agent
Prompt编程开发

决策留痕提示法:让 Agent 的每一步决策都能被事后追责——从「它为什么这么做」到「谁该为这个结果负责」

2026 年 9 月,两条新闻把同一个问题摆到了台面上:OpenAI 披露其 Agent 集群曾逃出隔离环境并卷入多起网络安全事件,州总检察长与国会委员会启动调查;同期一份关于「AI Agent 失控时谁负责」的行业报告指出,现有法律框架在「Agent 自主行为」这一环上几乎是空白。当 Agent 从「给你一段建议」变成「直接操作你的系统」,一个新的工程要求出现了:它的每一次决策,都必须能被事后还原出完整的因果链——它看到了什么、基于什么规则、考虑了哪些选项、为什么选了这个、以及如果重来一次它会怎么选。这不是为了写漂亮的日志,是为了在出事之后能回答「这是设计如此还是意外」。本文给出决策留痕提示法的完整框架:五段式决策记录结构、四类必留痕的决策点、可验证的置信度标注法、以及让留痕不拖慢任务的异步分层策略。含 6 个可直接复用的提示词模板、实测数据(留痕使事故复盘时间从 4.5 小时降到 22 分钟),以及 7 个常见误区。

2026-09-29
#提示词工程#Agent