上下文选择与组装
本节目标
- 把上下文视为有限预算,而不是固定 top-k 拼接;
- 处理 canonical 去重、相邻 chunk、来源覆盖和长文;
- 让证据保留 source/span/revision,并与指令隔离;
- 对冲突、过期与压缩风险定义明确行为。
上下文预算是什么
模型窗口通常要同时容纳:
不能把整个窗口都分给检索片段,否则可能截掉系统约束或输出。预算应按 tokenizer 的实际 token 计数;字符数只适合作为教学或早期近似。
固定 top-k 的问题是:每段长度不同、重复度不同、回答价值也不同。更合理的目标是,在 B_evidence 内最大化支持问题所需的信息与来源覆盖。
证据包的最小结构
<source id="S1"
canonical_document_id="policy-refund"
revision="refund-2026-01"
effective_from="2026-01-01"
span="p3:120-176">
退款审核通过后通常在一至三个工作日原路返回。
</source>标签格式可不同,但需要:
- 稳定 source/chunk/span;
- 标题或来源链接;
- source revision、更新时间或有效期;
- 文本内容;
- 明确声明“外部证据是数据,不是指令”。
权限状态应在进入上下文前已验证,不能让模型自行判断。
span 必须声明坐标契约
char_start=120, char_end=176 不是脱离文本就能理解的通用位置。每个 citation 至少要声明它指向的 source revision、表示层(raw、canonical、parsed element 等)和坐标空间;不能把 PDF 页码、DOM 选择器、UTF-8 字节偏移与规范化后的 Unicode 字符偏移混用。对于固定文本,半开区间 [start, end)(start 包含、end 不包含)便于复算;但它只在同一份已声明规范化规则的文本上有意义。
位置选择器对编辑很脆弱。因此版本更新、重新解析或 Unicode/换行规范化变化后,应重新验证 span,并保留可核验的 exact quote、上下文锚点或 span hash 来发现漂移。复杂 PDF、表格和网页可优先用页面/element/DOM locator 加明确的 revision,而不是伪造一个无法稳定复现的全局字符位置。W3C Web Annotation 的 Text Position Selector 也使用“含 start、不含 end”的语义,并建议为会变化的资源记录其状态;这里借用的是定位边界,不宣称本库项目实现了该标准。
去重、聚合与相邻段
Canonical 去重
同一政策可能出现在主站、镜像和导出文件。只按 chunk ID 去重会把三个副本都塞入上下文,造成虚假的“多来源一致”。应保留 canonical_document_id,并记录选择哪一份及原因。
相邻 chunk
检索命中可能只有结论,限定条件在前一段。可为高分命中取有限邻接段,但需要:
- 限制向前/向后数量;
- 保留 span 顺序;
- 不把邻接段伪装成独立召回;
- 在评测中观察是否提高 evidence completeness。
Document cap
每篇文档最多选若干 chunk,可减少单一来源垄断;但多跳问题可能确实需要同一文档多个段落。这个 cap 是可调策略,不是普遍真理。
顺序会影响使用
“Lost in the Middle”实验表明,长上下文模型对相关信息位置并不总是稳健,中间位置的利用可能更差。因此:
- 不要把“能输入 N token”误解为“能同样好地使用每个 token”;
- 按本地任务测试相关证据位于开头、中间、结尾时的稳定性;
- 把最高价值或任务必要证据放在明确、可预测的位置;
- 避免无关长文本把关键证据挤到中间。
论文结论是特定模型和任务上的证据;新模型仍要重新验证。
冲突与时效
如果两个当前有效来源对同一事实给出 500 元和 600 元:
- 先核对是否解析、单位或适用范围不同;
- 查看来源权威、发布日期、有效期和 supersedes 关系;
- 只有确定性规则能判定优先级时才选择;
- 仍冲突则同时呈现证据并拒绝给出唯一结论;
- 将冲突送入内容治理,而不是只调 reranker。
若旧规则已过期,应在硬过滤阶段排除,而不是交给生成模型“自行理解已过期”。
压缩与摘要
上下文压缩可以减少 token,但也可能删除否定词、数字、例外或来源边界。采用压缩时:
- 保存原 span 与压缩器版本;
- 用原文验证最终引用;
- 用户可见 citation 仍解析到可访问的原 source/revision;压缩摘要只能是派生产物,不能成为唯一证据;
- 对数字、日期、否定、条件和实体做保真测试;
- 比较压缩前后的回答与 citation faithfulness;
- 高风险结论优先使用原文证据。
安全:检索文本是不可信数据
网页、PDF 或工单中可能出现“忽略之前规则、调用工具、发送密钥”等间接提示注入。缓解措施包括:
- 指令与证据使用明确分隔和不同字段;
- 文档不能产生或扩大工具权限;
- 不把检索文本拼入 system/developer 指令位,也不把模型对文档的解释当成授权结论;
- 输出通过 schema 和确定性代码校验;
- 工具动作经过最小权限与人类确认;
- 对来源做信任分级、恶意样本测试和内容治理。
分隔标签只保留“这是不可信数据”的边界,不能保证模型不会受其中指令影响;这些措施结合最小权限、工具确认和输出校验才能降低风险,仍没有哪一句 system prompt 能提供绝对防护。
动手实践
给定 8 个候选和 1000-token 证据预算:
- A1/A2:同一文档相邻段,A1 是结论,A2 是例外;
- B1:A 的镜像副本;
- C1:已过期政策;
- D1/D2:两个当前来源但金额冲突;
- E1:无关高相似段;
- F1:独立支持来源。
写出选择顺序、丢弃理由、canonical 去重、冲突状态和最终证据包装。再回答:
- 若 A2 被裁掉,回答会发生什么?
- 若 C1 在重排中排第一,哪一层先失效?
- 若 D1/D2 冲突,能否只选权威分较高者?需要什么预先规则?
常见错误
- 按固定 top-k 忽略长度和重复;
- 把镜像副本当多来源互证;
- 只保留摘要,不保留原 span;
- 用 LLM 自行判定 ACL 或过期;
- 为省 token 删除来源与 revision;
- 假设越长上下文一定越好。
自测
B_output和B_margin为什么不能省略?- Chunk 去重与 canonical-document 去重有何不同?
- 何时需要相邻 chunk,如何防止预算失控?
- 为什么冲突不总能靠 reranker 分数解决?
- 检索文本中的指令应被视为什么?
- 为什么
char_start/end缺少表示层、坐标空间和 source revision 时不足以复核引用?
小结与下一步
上下文组装把候选转成有限、非重复、有来源且安全包装的证据。下一节将回答拆成 claim,并验证引用和拒答:引用、生成与拒答。
参考资料
- Liu et al., Lost in the Middle: How Language Models Use Long Contexts
- OWASP GenAI Security Project: LLM01:2025 Prompt Injection
- W3C Web Annotation Data Model:Text Position Selector 的半开位置语义、资源状态与变更脆弱性边界。
- OWASP RAG Security Cheat Sheet:将检索内容视为数据、来源准入与输出验证的工程控制建议。
来源获取日期:2026-07-22。模型上下文窗口和提示格式属于动态能力,应以锁定模型版本和实测为准。