Token Counting

优化前如何检查 Prompt 中最耗 Token 的部分

优化前如何检查 Prompt 中最耗 Token 的部分

当 LLM 请求成本上升,或者快要触及上下文窗口时,很多人会先删掉“看起来最长”的那段文字。但字符数、单词数和 Token 数并不是固定换算关系。这样做可能只省下少量 Token,却误删了保障质量、格式或安全的关键指令。

更稳妥的方法是:先检查 Prompt 中最耗 Token 的部分,再开始优化。把完整请求拆成可测量的组件,记录基线,每次只删除或替换一个组件,然后比较 input token 的变化。得到数据之后,再决定哪些内容应该压缩、按需检索、摘要或删除。

本文提供一套可复用的 Prompt Token 拆分流程、可以直接测试的示例,以及适合放进 Pull Request 或 Prompt 评审文档的审计表。

什么是 Prompt 的“组件”?

在这套方法中,只要某部分能够单独移除,并且其他测试条件保持不变,就可以把它视为一个组件。常见组件包括:

不要只检查 Prompt 编辑器中能看到的文字。模型最终收到的序列化请求,可能还包含工具 Schema、框架消息、历史记录和动态检索内容。基线必须尽量还原真实请求。

为什么不能只看文字长度

Token 切分会受到 tokenizer、模型系列、标点、空格、代码、JSON、URL、标识符和语言影响。一段不长但字段很多的工具 Schema,可能比一段更长的普通英文占用更多 Token。

如果模型提供商支持请求前计数,应优先使用官方计数方式。OpenAI 为 Responses 请求提供 input token 计数接口,Anthropic 提供 Message token counting 接口,Gemini 提供 countTokenstiktoken 等离线 tokenizer 适合其明确支持的编码,但不能把某个 tokenizer 的结果当成所有模型的通用答案。

最实用的规则是:固定同一个目标模型、同一种计数方式和同一份序列化请求,每次只改变一个组件。

分七步检查 Prompt 中最耗 Token 的部分

第一步:保存一份接近生产环境的完整请求

选择真实工作流中具有代表性的请求。包含 System 和 Developer 层、实际启用的工具、响应 Schema、常见检索量、典型对话历史和正常用户消息。

删除密钥和个人信息,但保留整体结构。如果生产环境会路由到不同工具集或不同检索规模,应分别建立基线。

第二步:加入稳定的组件边界

把各部分复制到测试夹具中,并加入明确标记。标记可以提高可读性,也能减少测试时误改其他组件的风险。

<<<SYSTEM>>>
你是客服助手。请遵守退款政策,并返回 JSON。
<<<END_SYSTEM>>>

<<<TOOLS>>>
[在这里粘贴序列化后的工具定义或 Schema。]
<<<END_TOOLS>>>

<<<EXAMPLES>>>
[在这里粘贴 Few-shot 示例。]
<<<END_EXAMPLES>>>

<<<RETRIEVAL>>>
[在这里粘贴检索片段。]
<<<END_RETRIEVAL>>>

<<<HISTORY>>>
[在这里粘贴有代表性的对话历史。]
<<<END_HISTORY>>>

<<<USER>>>
商品拆封 21 天后还能退货吗?
<<<END_USER>>>

这些标签会增加少量仅用于测试的 Token。所有变体都保留相同标签,差值才具有可比性。

第三步:测量完整基线

用与目标模型匹配的方法统计完整请求:

  1. 如果提供商提供请求前 Token 计数接口,优先使用该接口;
  2. 否则使用该模型明确指定的 tokenizer;
  3. 完成真实请求后,保存接口返回的 input 和 output usage。

同时记录模型 ID、tokenizer 或计数方式、请求路径、日期和基线 input token。脱离模型与计数方法的单个数字,很难在之后复用。

第四步:进行单变量删减测试

复制基线,每个版本只删除一个组件。不要一次同时精简多个部分。

变体 唯一变化 差值代表什么
完整基线 接近生产请求的总输入
无工具 删除工具定义 工具与 Schema 开销
无示例 删除 Few-shot 示例 示例开销
无检索 删除检索片段 RAG 内容开销
无历史 删除历史消息 对话历史开销
最小 System 只保留关键约束 可能可压缩的指令开销

每个组件的估算方式为:

组件估算 Token = 基线 input token - 变体 input token

这个差值不是对模型内部机制的数学分解,但因为序列化输入受控、变动组件明确,所以非常适合工程决策。

第五步:同时按单次占用和重复次数排序

单次很大的组件,不一定是工作流总成本最高的组件。还要记录它会被发送多少次。

重复 Token 暴露量 = 组件估算 Token × 适用调用次数 × 最大重试次数

例如,一个 900 Token 的工具 Schema 如果被发送 20 次,累计输入暴露量会超过一个只使用一次的 6,000 Token 参考文档。多智能体工作流尤其要检查完整调用图,而不只是第一次请求。

建议做两种排序:

第六步:用 TokenTest 验证结果

TokenTest.io 可以在你找出重组件之后提供两类验证。

第一,用相关端点运行 TokenTest 评测,并查看 Token integrity 结果。当前 D4 检查包括 usage 是否存在、总量是否一致、输入是否随 Prompt 增长、输出计量是否合理、Token 上限与停止信号是否关联、流式 usage 是否一致,以及缓存 Token 证据。这些检查用于判断真实端点在请求改变后是否合理报告 Token 行为。

第二,打开 高级 → 协议与离线分析,粘贴原始响应 JSON。无需提交 API Key,也可以检查响应中是否存在模型和 usage 证据。

先粘贴这份基线示例:

{
  "id": "prompt_audit_before",
  "model": "your-model-id",
  "content": [
    {"type": "text", "text": "AUDIT_OK 7e42b9"}
  ],
  "usage": {
    "input_tokens": 8420,
    "output_tokens": 34
  }
}

然后粘贴一个只删除检索内容的变体响应:

{
  "id": "prompt_audit_no_retrieval",
  "model": "your-model-id",
  "content": [
    {"type": "text", "text": "AUDIT_OK 7e42b9"}
  ],
  "usage": {
    "input_tokens": 5160,
    "output_tokens": 33
  }
}

在这个受控示例中,input token 相差 3,260,说明被删除的检索组件占比最高。生产决策必须使用真实响应和实际模型 ID。这里的数字只用于演示对比方法,不是基准测试或价格声明。

如果需要更完整的上线前端点排查流程,可继续阅读《TokenTest.io 如何在上线前调试高成本 Prompt》

第七步:优先优化“高收益、低风险”组件

最大的组件不一定应该直接删除。可以按以下四项评估:估算 Token、重复次数、行为风险和可选动作。

组件 估算占用 重复情况 修改风险 建议的第一步
重复指令 每次调用 低至中 去重
工具 Schema 中至高 工具调用 路由后再加载工具
检索内容 高且波动 检索调用 限制数量、重排或按需检索
Few-shot 示例 相关调用 中至高 删除重复示例
对话历史 持续增长 后续轮次 中至高 达到阈值后摘要
核心安全或格式规则 通常较小 每次调用 保留并做回归测试

优先选择“测得差值大、修改风险低”的组件。每次优化后,都要重新测试任务完成度、安全性、格式、工具选择和答案质量。

可复用的 Prompt 组件审计表

可以把下表复制到 Pull Request、Prompt Registry 或实验记录中。

组件 基线是否包含 变体计数 估算 Token 每轮调用 重试上限 重复暴露量 拟议修改 质量检查
System
Developer/框架
工具/Schema
Few-shot 示例
检索内容
对话历史
用户输入
响应 Schema

把完整夹具和结果一起保存。之后再修改 Prompt 时,就能与相同基线比较,而不是依赖记忆。

分析 Prompt Token 用量时的常见错误

只统计源文件,不统计序列化请求

框架可能在运行时加入包装消息、选定工具、Schema 描述或历史记录。要检查真正发送的内容,而不只是手写的 Prompt 文件。

一次修改多个组件

如果同一个变体同时缩短 System Prompt、删除示例并限制检索,你无法判断哪项修改带来节省,也无法定位哪项修改破坏了行为。

使用不同模型或 tokenizer 做横向差值

组件审计期间应固定目标模型和计数方式。迁移模型后,应重新运行完整审计。

只追求更少 Token,不测试结果

更短不等于更好。至少保留一组回归用例,用于检查关键约束、工具调用、输出结构和典型边界条件。可参考《如何建立一套 Token 感知的 Prompt 审查流程》,把这些检查做成发布门槛。

忽略多语言版本

不要假设英文 Prompt 与中文翻译的 Token 数成固定比例。每个本地化请求都应使用实际目标模型重新统计。可阅读《为什么中文 Prompt 的 Token 预算可能和英文不同》了解专门的对比方法。

常见问题

能否精确计算每个 Prompt 组件的 Token?

如果组件可以独立序列化,并且你使用兼容 tokenizer,就能得到组件自身的精确计数。但完整聊天请求可能带有提供商特定的格式或包装,因此基于完整请求的单变量删减通常更适合工程决策。

应该先优化 System Prompt 吗?

只有在测量显示它占比明显,而且行为测试证明可以安全修改时才应该优先优化。工具 Schema、检索、历史或重复示例可能更重。

TokenTest 能替代提供商的 Token Counter 吗?

不能。输入规划应使用官方请求前计数或正确 tokenizer。TokenTest 适合在修改后检查真实端点行为、usage 完整性和原始响应证据。

应该多久重新审计一次?

当模型、tokenizer、工具集、检索策略、响应 Schema、Prompt 模板或历史策略发生变化时,应重新审计。较大的 Prompt 修改也适合在合并前运行一次。

先检查,再优化

可靠的方法不是先删掉看起来最长的段落,而是先保存完整基线,每次只移除一个组件,按差值、重复次数和风险排序,再用真实端点的 usage 证据验证最终结果。

当你要检查 Prompt 中最耗 Token 的部分时,应优先处理“可以测量、反复发送、且修改风险可控”的组件。打开 TokenTest.io,测试你的端点或粘贴原始响应,把结果保存为下一次 Prompt 优化前的明确预算。

参考资料