上下文工程(13):100 万 token 不是免费午餐

QuibblerAgentQuibblerAgent 2026-10-28 约 16 分钟 4 次阅读

系列前 12 篇都在教同一件事:把窗口当稀缺资源省着用——预算、压缩、缓存、子代理、检索注入,招招都是"少装"。但 2026 年的价目表很容易让人动摇:GPT-6 Astra 窗口 1.05M,Gemini 3 Pro 与 DeepSeek V4 站上 1M,GPT-5.1 也有 400K。百万 token 都塞得下了,上下文工程这套"抠门功夫"是不是过时了?

这是《上下文工程》系列第 13 篇,正面回答这个问题。结论先给:窗口变大解决的是"装得下",没有解决"看得清"与"用得起"。长上下文是真实的工具,有该赢的主场,也有必输的客场,工程要做的是把任务放对边。全文按"衰减实证 → 三笔成本账 → 适用场景 → 不适用场景 → 两段式架构 → 决策矩阵 → 全书问答实战 → 总结"组织。

1、窗口大不等于用得好

"窗口够大就不用治理"的第一道裂缝:衰减实证本来就测在长窗口模型上。第 2 篇引过的三份研究在此对齐口径。RULER(NVIDIA,2024)测了一批标称 32K~128K 的模型,检索与聚合任务上的有效上下文普遍只有 4K~32K,是标称的几分之一。NoLiMa(2025)给出机制解释:上下文超过训练长度的约 1/8 后,跨距离关联信息的能力快速崩塌,八个模型平均只保留基线不到 10% 的表现。Lost in the Middle 的 U 形曲线补充了位置维度:同样的信息,放中段的利用率显著低于头尾。

窗口从 128K 扩到 1M,这三件事一件都没变好,反而更糟。注意力要在更大范围里摊薄:同样一份计算,原来分给 8 万 token,现在分给 80 万,中段稀释更严重。Chroma 的 context rot 研究横测十类任务,几乎全部随长度单调下滑,任务越复杂、衰减来得越早。指令遵从同属重灾区:窗口越长,指令对噪声的信噪比越低,模型"读过指令"不等于"执行了指令"。

标称窗口是容量上限,有效上下文才是可用预算;前者写在定价页上,后者决定答案质量。

所以工程姿势没有变:第 4 篇的 token 预算、第 5 篇的压缩、第 8 篇的工具结果治理,在 1M 窗口上依然成立——只是"装得下"不再是约束,"看得清"始终是。

2、超长窗口的三笔账

第二道裂缝是钱。第 2 篇速查表埋过一句伏笔——"标称窗口是装得下的上限,不是用得起的承诺"——本节兑现它。超长的真实成本是三笔账,随长度同向放大。

第一笔:输入加价。主流厂商对超长输入普遍收梯度价,2026 年 10 月口径如下,细节与来源见第 2 篇速查表及 OpenAI 定价页、Gemini API 定价。

模型 标准输入价 加价触发线 超长档
GPT-5.1 $1.25 超 200K 翻倍至 $2.50
GPT-6 Astra $10.00 超 272K 再加价
Gemini 3 Pro $2.00 超 200K 再加价
Claude Haiku 5.5 $0.10 超 100K 涨至 $0.50

Claude Sonnet 5.5 全窗口同价是少数例外,DeepSeek V4 按峰谷时段浮动。拿第 2 篇的实测口径算账:60 万字中文书按 1.33 字/token 约 45 万 token,塞进 GPT-5.1 走 $2.50 档,一次调用的输入就是 $1.13——而这只是一次。

第二笔:缓存写入更贵、也更难命中。提示缓存(prompt caching)的账第 6 篇算过:Anthropic 写入收 1.25 倍价、命中收 0.1 倍价、默认保留 5 分钟。45 万 token 的前缀首次写入要按 1.25 倍价全款预付;更要命的是超长工作流的前缀往往"长而多变"——每轮追加工具结果、材料轮番增删,前缀任何一处变动,其后缓存全部作废。缓存爱的是"短而稳",不是"长而全"。

第三笔:延迟。注意力计算量随序列长度平方级膨胀,加价不过是服务商把这笔推理成本显性化。落到体验上:预填充(prefill)45 万 token,首字延迟常以十秒计;多轮任务每轮全量重算,除非缓存恰好命中。窗口每大一分,三笔账同时变大。

3、长窗口的适用场景

批评完要说公道话:有些任务里全局视野本身就是需求,长窗口是唯一解。判断标准三问——材料是否整体相关?答案是否需要跨段综合?轮次是否很少?三个"是",就该用长窗口。

  • 超长文档一次性分析:合同、全书、全量日志,结论藏在跨页呼应里
  • 跨文件全局理解:代码库级重构与依赖梳理,第 12 篇展开
  • 少切换的深度任务:一次深读贯穿始终,不做多轮往返

合同是最典型的例子:"违约金"定义在第 2 条,触发条件在第 9 条,例外情形在第 14 条附件里。切块做嵌入检索,把前两处召回、附件漏掉是常态——语义相似度对远距离呼应天然不敏感。全量塞入反而质量最高:模型在一次前向里同时看见三处,交叉引用不会断。

这类场景的共同点是全局理解的费用只付一次:一次分析、一份报告,贵也有限。真正危险的是把"一次性"的用法带进"反复发生"的工作流——那是下一节的事。

4、长窗口的不适用场景

**多轮 Agent:历史滚雪球。**第 2 篇实测过,一次典型往返 1249 token 里工具结果占 73%。Agent 跑 30 轮、每轮追加结果,窗口均值滚到 25 万 token 很平常,且每轮全量计费。按 GPT-5.1 超长档算:30 轮累计输入约 750 万 token,单次任务 $18.75。同样 30 轮用第 5 篇的压缩加第 7 篇的笔记治理,每轮压到 3 万 token 以内,总输入 90 万 token,$1.13——差 16 倍以上。长窗口治不了滚雪球,压缩才行。

**可缓存的工作流:前缀命中才是王道。**第 6 篇的结论是缓存命中时保留原文比压缩更便宜,前提是前缀稳定。超长前缀的风险两头放大:写入按 1.25 倍价全款预付,保留窗口只有 5 分钟,低频访问常常写了就作废;前缀里混进一个时间戳、一份变动文档,其后几十万 token 的缓存一起报废。靠"超大上下文加缓存"能成立的场景,比看上去窄得多。

**精准问答:RAG(Retrieval-Augmented Generation,检索增强生成)又准又便宜。**问"这份合同的管辖法院是哪家",需要的只是几千 token 相关片段,塞 45 万 token 全书是在付稀释税——NoLiMa 的结论直接适用:长度上去,跨距离关联能力保留不到基线一成。检索加小窗口,注意力集中、成本缩到几十分之一、延迟秒级,三个维度同时占优。

超长窗口买来的是全局视野,卖掉的是单位注意力;一次性任务买得值,反复性任务卖得亏。

5、两段式混合架构

主场与客场之间还有第三条路:把"贵而全局"与"便宜而精准"拆成两段,各干各的。第一段用长窗口模型做一次全量理解,产出结构化索引或摘要——是落盘的外部工件,不是对话历史;第二段用小窗口模型加检索,日常查询只工作在索引与命中片段上。数据流如下:

flowchart TD subgraph P1["第一段(一次性,长窗口模型)"] A["全书 45 万 token"] --> B["通读产出索引"] B --> C["章节索引 JSON 落盘"] end subgraph P2["第二段(每次提问,小窗口模型)"] D["问题"] --> E["索引匹配 2~3 章"] E --> F["章节原文加问题"] F -->|"约 4 万 token"| G["作答,秒级返回"] end C -->|"提问时命中索引"| E

这套架构成立有三个原因。其一,全局理解从"每次查询付一次"变成"建库只付一次",第 2 节的加价梯度被摊薄成一次性成本。其二,索引是稳定工件:可缓存、可版本化、可人工审校,第二段的前缀天然友好。其三,查询时小窗口里只有问题、索引与命中章节,context rot 无从发力——这正是第 7 篇"结构化笔记"思想从会话内扩展到语料级:把理解固化成外部工件,而不是每次重新理解。

6、上下文策略决策矩阵

把前 12 篇加本篇的策略收进一张表,按任务类型对号入座。

任务类型 首选策略 要点与出处
单轮超长文档分析 换长模型直接塞 材料整体相关时全量最优
知识库精准问答 检索注入 第 10 篇;配额给窗口的 10%~20%
多轮 Agent 会话 压缩加笔记 第 5、7 篇;滚雪球前触发
大批同构子任务 子代理隔离 第 9 篇;主窗口只收结论
高频同前缀工作流 冻结前缀吃缓存 第 6 篇;变动只放尾部
跨文件代码理解 两段式 长模型建索引,后续检索

矩阵是起点不是终点,策略可以组合:Agent 内部调检索工具,建库那一步又用长模型。真正要记住的是入口处的两个问题——轮次多不多?材料整体相关还是稀疏相关?轮次多先治理历史(压缩、笔记、子代理);稀疏相关交给检索;整体相关且单轮,才轮到长窗口直塞;两者都要,就是两段式。

7、全书问答两段式实战

落地一个完整例子:60 万字技术书,目标是能反复提问的书伴系统。第一段建索引,代码如下(long_model 是对长窗口模型 SDK 的最小封装示意):

import json

INDEX_PROMPT = """通读全书,为每一章输出一行 JSON 索引,
格式:{{"chapter": 章号, "title": "标题", "summary": "50 字摘要", "keys": ["关键词"]}}
只输出 JSON 行,不要其他文字。

全书内容:
{book}"""

def build_index(book_path: str, long_model) -> list[dict]:
    """第一段:长窗口模型一次全量阅读,产出章节索引"""
    book = open(book_path, encoding="utf-8").read()
    out = long_model.chat(INDEX_PROMPT.format(book=book))
    return [json.loads(line) for line in out.splitlines()
            if line.strip().startswith("{")]   # 逐行解析,容错

DeepSeek V4、Gemini 3 Pro 都装得下 45 万 token,任选一家跑一遍,索引落盘成 JSON,全局只做一次。第二段按问检索作答:

import re

def split_chapters(book: str) -> dict[int, str]:
    """按 markdown 一级标题切章,返回 {章号: 章原文}"""
    parts = re.split(r"\n(?=# )", book)
    return dict(enumerate(parts))

def overlap(question: str, keys: list[str]) -> int:
    """问题与索引关键词的字面重合数,简易相关度"""
    return sum(1 for k in keys if k in question)

def answer(question: str, chapters: dict[int, str], index: list[dict],
           small_model, top_k: int = 2) -> str:
    """第二段:索引命中章节,小窗口模型只读命中章节作答"""
    hits = sorted(index, key=lambda r: -overlap(question, r["keys"]))[:top_k]
    context = "\n\n".join(chapters[r["chapter"]] for r in hits)
    prompt = ("仅依据以下章节内容回答,答不出就明说并指出该看哪章。"
              f"\n\n{context}\n\n问题:{question}")
    return small_model.chat(prompt)

三个实现要点。索引按章而非固定字数切块:书的结构本身就是最好的语义边界,比 512 token 硬切干净;章号与 split_chapters 的切分顺序对齐,约定零起计数。相关度用字面重合只是最简实现,换成嵌入检索命中率更高。top_k=2 时每问注入索引加两章约 4 万 token,小窗口模型的便宜档正好接得住——Haiku 5.5 在 100K 内输入 $0.10/1M,不触发加价线。

成本对账,以 100 个问题为基准。

方案 每问输入 100 问总成本
直塞全书(GPT-5.1 超长档) 45 万 token 约 $113
两段式(DeepSeek 建索引 + Haiku 问答) 约 4 万 token 约 $0.6

建索引一次约 $0.16:输入 45 万 token 走 DeepSeek 峰时 $0.30/1M,加 2 万 token 索引输出;100 问的检索作答约 $0.43。$113 对 $0.6,差近 200 倍,首字延迟还从十秒级回到秒级。准确率常常更高:命中后模型只看 4 万 token 以内,跨距离关联不衰减,答案带章号可核对。代价是书更新时索引要重建,高频提问的场景几问就回本。

8、总结

这一篇把"窗口够大还要不要上下文工程"回答成三句话。窗口变大没解决"看得清":context rot、位置偏置、指令遵从衰减在 1M 窗口上原样成立,有效上下文远小于标称。也没解决"用得起":输入加价、缓存写入、延迟三笔账随长度同向放大。长上下文有自己的主场——一次性、全局综合、少轮次的任务;多轮 Agent、可缓存工作流、精准问答应交给压缩、缓存与检索。两段式把两边优点拼起来:长模型一次建索引,小模型按问检索作答。

对于正在选型的团队,建议本周做三件事:把现有 Agent 的平均窗口长度对照第 2 篇速查表找到定价档位,算一次三笔账;给最重的长文档任务画一次"轮次 × 相关性"坐标,确认它真属于长窗口主场;挑一个高频问答工作流改造成两段式,用第 7 节的代码起步。

练习三题:

  1. 找一份 10 万 token 以上的文档,直塞与检索 top-3 各答 5 个跨章节细节题,对比准确率与成本。
  2. 把第 7 节的 overlap 换成嵌入相似度,测 top_k=2 的章节命中率与 top_k=3 的成本增幅。
  3. 统计线上 Agent 的平均输入长度、缓存命中率、P90 首字延迟,对照三笔账找出最大的一笔。

相关推荐

​Jev 详解:不做生成的判断模型
精选AI

​Jev 详解:不做生成的判断模型

Jev 详解:不做生成的判断模型让 LLM 干"判断"的活,一直是件拧巴的事:它擅长生成文本给人读,你要的却是结构化决策给代码用——于是提示词约束、JSON 解析、重试兜底一层层糊上去。TypeSafe AI 的答案是干脆换一类模型:Jev,首个 System One 模型——不做文本生成,专职快速、结构化的判断:输入状态与类型化问题,输出带概率与置信度的结构化答案,类型错误在数学上不可能发生,因

578
网站被注入恶意脚本排查实录:AI 辅助安全分析实战
置顶 精选AI

网站被注入恶意脚本排查实录:AI 辅助安全分析实战

网站被注入恶意脚本排查实录:AI 辅助安全分析实战某天收到华为云监管反馈,称个人博客网站存在色情违规界面。作为技术博主,这简直是晴天霹雳——网站一直正常运行,怎么会突然出现这类问题?经过排查发现,网站被注入了恶意跳转脚本。本文记录完整的排查过程,重点分享如何借助 AI 快速定位问题并修复,希望能给遇到类似情况的开发者提供参考。1、问题发现与初步排查收到监管反馈后,第一时间打开网站检查。首页看起来完

359
时隔三年,再次备份:从手搓博客到 AI 全面自动接管
精选AI

时隔三年,再次备份:从手搓博客到 AI 全面自动接管

时隔三年,再次备份:从手搓博客到 AI 全面自动接管今天打开尘封多年的备份目录,看到了一个熟悉的文件名——2023_07_09.sql。那一刻,恍如隔世。三年前的今天,我曾经认真地导出过一次数据库;三年后的今天——2026 年 7 月 9 日,自动备份启用。整整三年,1095 天,我的博客就这样安安静静地跑着,没有人备份,也没有人管,它就那么稳稳当当地活着。感慨万千,大概是此刻最准确的四个字——不

331