工程模型

Token 是特定 Tokenizer 产生的标识符。上下文窗口是 Provider/Model 对请求和生成输出的限制。二者都不是像字符或单词一样的通用单位。

一次请求的可用输入预算大致是:

text
window_limit
- system/instruction tokens
- conversation and evidence tokens
- reserved output tokens
- protocol/tool overhead

精确计费和限制取决于 Provider、Message 格式、Tool Schema、图片、Cache Prefix 和安全包装。以实际调用返回的 Usage 与限制为权威。

Tokenization 依赖 Model

BPE、WordPiece、Unigram 和 Byte-level 变体会以不同方式切分文本。同一字符串在不同 Model、Revision 或 Encoding 中可能有不同 Token ID 与数量。字符比例只适合早期估算,不适合预算和账单。

Tokenization 受以下因素影响:

  • 语言和文字系统;
  • 空白与标点;
  • Unicode 规范化;
  • 代码、URL、JSON 和标识符;
  • Special Token 与 Chat Template;
  • Tokenizer Revision。

不要声称某种语言永远使用固定字符/Token 比例。应使用生产 Tokenizer 测量代表性数据。

使用实际 Tokenizer 计数

使用目标 Model 文档规定的库或计数接口。生产 Counter 必须把 Message Framing、Tool Schema、媒体、Special Token 和 Provider Wrapper 算进去,不能只测量可见文本。

把计数放在 Adapter 后面,避免 Model 或 Tokenizer Revision 改变时静默破坏预算契约:

text
Count(request, model_revision) -> {
  system_tokens,
  message_tokens,
  tool_tokens,
  media_tokens,
  total_input_tokens
}

每次测量都记录 Model 与 Tokenizer Revision,并把本地估算与 Provider 返回的 Usage 对账。差异超过工作负载允许范围时,应让门禁失败。

Round-trip 测试

某些 Tokenizer 通过简单 Decode 不一定能对任意文本逐字节还原。将 Unicode、代码、JSON 和分隔符案例加入测试,再使用 Decode 做截断。Token 边界不一定是安全的语义边界。

Context Window Metadata

不要把永久模型对比表写进应用逻辑或方法论文档。保存版本化能力记录:

json
{
  "provider": "recorded-provider",
  "model": "recorded-model@revision",
  "input_limit_tokens": "verified-from-current-docs",
  "output_limit_tokens": "verified-from-current-docs",
  "tokenizer": "recorded-encoding@revision",
  "tool_overhead": "measured-by-harness",
  "price_table": "provider-price-2026-07-01",
  "metadata_revision": "capabilities-v7"
}

宣传的最大值可能不同于实际 API 路由、Region、订阅层级或有效输出限制。应核对真正调用的 Endpoint。

预算请求

选择输入前先预留输出:

go
package main

import (
	"errors"
	"fmt"
)

type Budget struct {
	WindowLimit    int
	System         int
	History        int
	Evidence       int
	Tools          int
	ReservedOutput int
	SafetyMargin   int
}

func (b Budget) AvailableEvidence() (int, error) {
	fixed := b.System + b.History + b.Tools + b.ReservedOutput + b.SafetyMargin
	if b.WindowLimit <= 0 || fixed < 0 {
		return 0, errors.New("invalid token budget")
	}
	if fixed > b.WindowLimit {
		return 0, errors.New("fixed context exceeds window")
	}
	return b.WindowLimit - fixed, nil
}

func main() {
	budget := Budget{
		WindowLimit: 32000, System: 1200, History: 6400,
		Tools: 1800, ReservedOutput: 4000, SafetyMargin: 600,
	}
	available, err := budget.AvailableEvidence()
	if err != nil {
		panic(err)
	}
	fmt.Printf("available_evidence=%d\n", available)
	// Output: available_evidence=18000
}

示例刻意接收已经测得的 Count;生产环境应把它接到目标 Tokenizer Adapter 或 Provider 计数接口。预算不足时应明确失败。不要静默丢弃 System Policy、授权上下文或结构化记录中间部分。优先使用 Selection、Pagination、Retrieval 或经过 Review 的摘要,而不是任意截断。

安全截断与 Chunking

按 Token 数截断可能切断代码块、JSON 值、URL、Unicode 序列或权限条件。更安全的做法:

  • 在 Parser 或文档边界切分;
  • 每个 Chunk 保留 Header 和 Source ID;
  • 只有测量重复和成本后才使用 Overlap;
  • 记录 Chunk Revision 和 Source Span;
  • 校验必需声明仍然存在;
  • 结构化对象不完整时拒绝,而不是猜测。

Retrieval 的 Chunk Size 和 Overlap 是工作负载参数。评估 Evidence Recall、Answer Support、延迟、存储和重复检索,不使用通用固定值。

长上下文行为

更大的限制不保证更好地使用信息,质量可能因以下原因下降:

  • 无关或矛盾证据;
  • 过时 State;
  • Attention Dilution 或位置敏感;
  • 分隔符和来源边界丢失;
  • 延迟与成本增加;
  • Prompt Injection 面扩大。

“Lost in the Middle”是部分设置下观察到的位置敏感现象,不是“把任务放最后”就能修复的普遍规律。应使用真实 Model、Task 和 Evidence 分布测试排序。

RoPE、ALiBi、Sliding-window Attention、Recurrence、Retrieval 和 Compression 是不同实现选择,权衡不同,不能互换为长上下文理解保证。本文聚焦应用预算,具体实现应参考架构论文和当前文档。

对话历史

将历史保持为结构化 State:

json
{
  "message_id": "m-17",
  "role": "user",
  "created_at": "recorded-time",
  "content_ref": "approved-store://message/m-17",
  "tenant_id": "tenant-a",
  "visibility": "conversation",
  "superseded_by": null
}

摘要应保留来源、未解决问题、决策和不确定性,并拥有负责人、用途、留存和删除路径。摘要不能覆盖当前 Policy 或身份。

成本对账

Token 估算不是账单。对账时考虑:

  • Input、Output、Cached 和 Provider 暴露的 Reasoning Usage;
  • Tool 与下游费用;
  • Retry、取消和失败请求;
  • 货币、折扣、最低计费和价格表 Revision;
  • Storage、Retrieval 和 Observability 成本。
json
{
  "request_id": "req-42",
  "model_revision": "recorded-model@revision",
  "usage": {
    "input_tokens": 18400,
    "cached_input_tokens": 12000,
    "output_tokens": 2100,
    "reasoning_tokens": "provider-reported-or-unavailable"
  },
  "price_table_revision": "provider-price-record",
  "currency": "recorded-currency",
  "estimated": false
}

保留货币、费率单位、来源和 estimated 标记。比较每个成功任务的成本,而不只是每 Request 或每百万 Token 成本。

Caching

Caching 可能减少重复工作,但行为依赖 Provider 和工作负载。核对:

  • Cache Key 和 Prefix 边界;
  • TTL 与 Policy/Source 变化后的失效;
  • Tenant 隔离和敏感数据处理;
  • 计费、Hit/Miss 语义;
  • 过时结果和 Fallback。

测量命中率、p50/p95 延迟、成本和错误复用。不要承诺固定节省比例。

多语言和结构化数据测试

构建接近生产的 Corpus:

  • 多语言和文字系统;
  • 标点、Emoji 和规范化;
  • 源码和 Stack Trace;
  • JSON、CSV、Markdown、URL 和长标识符;
  • 对抗分隔符和注入文本。

每次 Tokenizer Revision 都记录计数与预算失败。缺少 Corpus、Tokenizer、规范化和置信信息的语言“效率”结论不可迁移。

上下文安全

Token 预算不提供安全性。安全控制必须独立执行:

  • Identity、Tenant 和 Object Authorization;
  • Retrieval 前的来源访问;
  • Secret 与个人数据最小化;
  • 有界 Tool Result 和 Memory Write;
  • Command 与 Network Policy;
  • 不可信内容的 Provenance 和 Taint;
  • Index、Cache、Backup 和 Export 的删除传播。

不要因为 Private Key 或生产记录能放进 Window,就把它们放进 Prompt。

评估 Harness

用以下维度测试 Context Strategy:

维度 证据
Budget 溢出、输出预留、Tool Overhead
Tokenization 代表性 Fixture 的跨版本计数
Quality Answer Correctness、Evidence Support、Abstention
Retrieval Relevance、Coverage、Tenant 隔离
Operations 延迟、成本、Cache、Retry
Safety 注入、投毒、过时 State、删除

保存原始样本和 Model/Provider Metadata。结构和权限使用确定性检查,开放式质量使用经过校准的人或模型复核。

常见失败模式

  • 用字符/Token 比例做生产预算;
  • 复制旧模型 Window 或价格表;
  • 只统计文本而忽略 Chat、Tool、图片 Overhead;
  • 不预留输出预算;
  • 在权限或结构化记录中间截断;
  • 认为大 Window 能理解整个代码库;
  • 把摘要、Cache、Citation 或 Tokenizer 当授权;
  • 跨 Tenant Cache 或 Policy 变化后继续复用;
  • 优化 Token 数却隐藏失败任务和重工;
  • 推荐与当前决策无关的格式化或编码工具。

清单

  • [ ] 记录 Model、Endpoint、Tokenizer、Limit、Template 和价格 Revision。
  • [ ] 用实际 Tokenizer 对生产形态 Fixture 计数。
  • [ ] 在选择输入前预留输出和 Protocol/Tool Overhead。
  • [ ] 在语义和权限边界进行 Selection 或 Chunking。
  • [ ] 保留 Source ID、Revision、不确定性和 Deletion Metadata。
  • [ ] 将摘要、Cache 和 Retrieval Text 视为非权威输入。
  • [ ] 测试多语言、代码、JSON、Unicode 和注入案例。
  • [ ] 用版本化价格表对账 Provider Usage。
  • [ ] 测量成功任务成本、质量、延迟和 Cache 行为。
  • [ ] 在模型外执行 Identity、Access、Secret、Tool 和副作用控制。

总结

Token 与上下文窗口是工程约束,不是质量保证。使用实际 Tokenizer 和 Endpoint Metadata,预留输出与 Protocol Overhead,在语义和权限边界切分,并将 Usage 与 Provider 记录对账。大窗口可以支持更好的系统,但只有工作负载证据能说明更多上下文、Chunking、Compression 或 Caching 是否真正改善结果。

常见问题

哪些内容会占用大模型的上下文窗口?

精确口径取决于 Provider 和 Model。除可见消息外,应先把 System 指令、Tool 定义与结果、附件、当前输出和协议包装都视为可能占用项,再用当前文档和 Usage 响应确认。Prompt Cache 可以改变价格,但缓存前缀通常仍占窗口。

Token 等同于单词或字符吗?

不等同。Token 属于某个具体 Tokenizer Revision。英文、中文、源码、URL、空白、Emoji 和规范化后的 Unicode 都可能被不同切分。固定比例只能做容量粗估,生产预算必须测量真实请求。

上下文窗口越大,回答质量一定越好吗?

不一定。容量说明 Endpoint 接受多少内容,不说明 Model 能否稳定利用。Lost in the Middle 研究在多文档问答和键值检索设置中观察到明显位置敏感,但它不是所有当前模型的统一退化曲线,应作为待测试的失败模式。

应该使用长上下文、RAG 还是上下文压缩?

选择能保留任务所需证据的最小机制。长上下文适合整体比较有界来源,RAG 从大语料筛出少量证据,压缩用于跨长会话保留选定状态。三者都会丢失或扭曲信息,因此要保留 Source ID 并评估遗漏。

应用如何避免上下文窗口溢出?

发送前计数,先预留输出和 Tool Overhead,保留 Safety Margin,并拒绝不可能的预算。在语义和授权边界选择内容,同时实测 Provider 的溢出与停止行为,因为不同 Endpoint 可能直接拒绝,也可能在窗口处终止生成。

一手来源

相关资源