估算、百分比与严格阈值
区分 Token 估算、使用率计算和 exceeds_threshold 的严格比较语义
本页解决的问题
先给结论「估算、百分比与严格阈值」要解决的关键问题是什么?
区分 Token 估算、使用率计算和 exceeds_threshold 的严格比较语义
让这个结论先证明自己值得留下。 把这一页当成决策工具,而不是需要背下来的定义。把概念连到一个真实任务、一个可观察结果,以及一个能改变你判断的失败上。
写下一个问题:试完这个方法后,你能用什么证据回答它?
结论听起来很完整,却没有检查最关键的假设。
usage_percentage、exceeds_threshold、exceeds_threshold_with_headroom,并准确判断 85% 的等号边界。
used × 100 >= window × percent。usage_percentagetotal == 0 时返回 0,其他情况计算百分比,并把结果上限限制为 100。
exceeds_threshold使用整数饱和乘法,避免浮点舍入改变触发边界。默认自动压缩比例在配置中常见为 85。
used × 100 >= window × pct...with_headroom在百分比阈值前预留固定 token 空间。减法使用 saturating_sub,窗口为 0 时仍返回 false。
used × 100 >= window × pct - headroom × 100本地估算
estimate_tokens(s) 使用 UTF-8 字节长度除以 4。它可在请求前、工具输出加入后提供快速预测;单张低分辨率图片的固定估值为 765 token。
服务端 usage 观测
服务端 usage 描述已完成请求的实际计量。百分比函数不会获取或判断数据来源,它只处理调用方传入的数值。调用链可在不同阶段使用估算总量或已更新的 usage。
exceeds_threshold(850, 1000, 85) 为 true,849 为 false。若窗口 100,000、阈值 85%、headroom 4,000,则提前到 81,000 触发。pub fn usage_percentage(used: u64, total: u64) -> f64 {
if total == 0 { 0.0 }
else { ((used as f64) / (total as f64) * 100.0).min(100.0) }
}
pub fn exceeds_threshold(
used: u64, context_window: u64, threshold_percent: u8
) -> bool {
if context_window == 0 { return false; }
used.saturating_mul(100)
>= context_window.saturating_mul(threshold_percent as u64)
}
pub fn exceeds_threshold_with_headroom(
used: u64, context_window: u64, threshold_percent: u8, headroom: u64,
) -> bool {
if context_window == 0 { return false; }
used.saturating_mul(100) >=
context_window.saturating_mul(threshold_percent as u64)
.saturating_sub(headroom.saturating_mul(100))
}
grok-build-main 的 crates/codegen/xai-token-estimation/src/lib.rs,并核对 compaction 调用点,核对日期 2026-07-17。页面没有采用按中英文、代码类型分别计价的虚构公式。手算两个触发点
上下文窗口为 128,000,阈值为 85%。先算无 headroom 的最早触发 used,再算 headroom 为 4,000 时的最早触发 used。两题都要保留等号。
>=,等于阈值时立即为 true,headroom 会把触发点进一步前移。
「核心视觉 · 85% 边界」如何改变一次回答
「total == 0 时返回 0,其他情况计算百分比,并把结果上限限制为 100」说明,模型处理的不是我们眼中的“字数”,而是一段段 Token。Token 的切分方式会影响输入长度、上下文能放下多少内容,以及一次请求要花多少计算。
长度、信息量和上下文不是一回事
当「使用整数饱和乘法,避免浮点舍入改变触发边界。默认自动压缩比例在配置中常见为 85」变长时,先要分清三件事:文字被切成多少 Token、哪些内容真正参与当前判断、以及旧内容是否已经超出上下文窗口。删掉重复说明通常比单纯把窗口开得更大更有效。
先保留会改变判断的内容
可以用「上下文窗口为 128,000,阈值为 85%。先算无 headroom 的最早触发 used,再算 headroom 为 4,000 时的最早触发 used。两题都要保留等号」做一次对照:保留同样的问题,分别删掉重复背景、压缩格式和移除无关历史,比较答案质量、延迟与 Token 数量。
从「核心视觉 · 85% 边界」走到「三个核心函数」
「核心视觉 · 85% 边界」先把问题落在「context_window = 1,000 85% = 850 0 1,000 used = 849 false used = 850 true,等号触发 阈值采用整数交叉相乘: used × 100 >= window × percent」上;到了「三个核心函数」,讨论继续推进到「total == 0 时返回 0,其他情况计算百分比,并把结果上限限制为 100」。两段连起来,重点就不只是记住一个结论,而是看清它成立所依赖的条件。
把这条判断带到下一个场景
处理长文本时,先保留会改变结论的内容,再决定如何压缩格式和历史;上下文更长只有在新增信息真正有用时才值得付出代价。
- 「核心视觉 · 85% 边界」:context_window = 1,000 85% = 850 0 1,000 used = 849 false used = 850 true,等号触发 阈值采用整数交叉相乘: used × 100 >= window × percent
- 「三个核心函数」:total == 0 时返回 0,其他情况计算百分比,并把结果上限限制为 100
- 「最后的要点」:在百分比阈值前预留固定 token 空间。减法使用 saturating_sub,窗口为 0 时仍返回 false
最后的「最后的要点」把讨论落到「在百分比阈值前预留固定 token 空间。减法使用 saturating_sub,窗口为 0 时仍返回 false」。回看这条线索时,最值得保留的是:当输入、规模或风险改变,哪些判断需要重新做一遍。
我把这篇文章里的一个判断改写成了今天可以验证的小实验。比记住结论更有用的是,知道下一步要观察什么。
读完以后我先回头找它成立的条件,而不是直接把方法搬进项目。这个顺序让后面的取舍清楚很多。
如果把这个判断放到真实工作里,最先需要补的约束是什么?我想知道从阅读到第一次实践之间,哪一步最值得先做。
还没有这篇文章的讨论。