# Agent Note: 高缓存命中率的小数显示

Status: implemented
Archived: 2026-08-22

[English](2026-08-19-high-cache-hit-decimal-display.md) | 中文

## 问题

Web 会话统计行会把所有非空缓存命中率舍入为整数。真实比率超过 99% 后，显示会隐藏后续提升；比率达到 99.5% 时，即使仍有未缓存输入或缓存写入，也会显示为 100%。

用户因此无法区分接近完整的缓存命中与真实满命中。

## 决策

`StatsLine` 继续从 `@deepseek-ai/dsh-token-meter` 所拥有的完整会话 `tokenUsage` 投影派生比率；该投影仍是未缓存输入、缓存读取、缓存写入与输出计数的唯一所有方（[投影决策](../architecture/2026-07-29-projected-token-usage-and-request-context.zh.md)）。展示层只改变插入现有 `stats.cacheHit` locale 模板的文本。

| 真实比率 | 显示结果 |
|---|---|
| 没有计费输入 | 省略缓存命中分组 |
| 整数舍入结果低于 100% | 舍入后的整数 |
| 当前舍入结果为 100% 的非满命中 | 舍入结果低于 100% 所需的最少小数位 |
| 100% | `100%` |

所有非空比率都从零位小数开始。非满命中只有在舍入结果会成为 100% 时才逐位增加精度，因此 `99.1%` 与 `99.49%` 仍显示为 `99%`，而 `99.5%`、`99.95%` 与 `99.995%` 分别保留一位、两位与三位小数。`StatsLine` 对安全整数 token 计数执行精确的小因子比较，并且只在中间值仍处于该范围内时缩放接近满命中的差值。该算法既避开浮点临界值误差，也不设置精度上限或替代文案。真实满命中不会携带多余的小数。同一份派生字符串同时用于行内统计与溢出 tooltip。

## 归属与生命周期

token-meter 继续从完整持久会话日志折叠用量。标准投影值变化时，`StatsLine` 同步派生显示文本。本决策不引入设置、持久百分比、事件、协议字段、客户端状态或恢复路径。

实时更新、刷新回放与重连恢复都会还原同一组 `tokenUsage` 计数，并运行同一个显示函数。投影缺失时仍会省略全部 token 分组；输入分母为零时仍只省略缓存命中分组。

## 验证

组件测试固定了零分母、普通整数舍入、多个小数精度上的半步舍入、直至三位小数的各个精度边界、需要十四位小数的近满累计样本、真实 `100%`、两种 locale，以及行内值与 tooltip 值的一致性。组装后的 `lifecycle-chrome` replay sidecar 将 `9,950 / 10,000 = 99.5%` 选作确定性测试输入；该比率按整数舍入会误报为 100%，同时基础会话 fixture 仍可重录。活跃页面断言与刷新后的浏览器快照都会显示 `99.5%`，且不会产生额外模型调用。

## 备选方案

**对所有比率继续使用整数舍入。** 不予采纳，因为它会隐藏 99% 以上的全部变化，并继续把部分非满命中显示为 100%。

**把高位区间向下截取到一位小数。** 不予采纳，因为 `99.95%`、`99.995%` 以及更接近满命中的比率都会坍缩为 `99.9%`，无法保留区分真实满命中所需的最少精度。

**限制精度并使用 `<100%` 等替代文案。** 不予采纳，因为精确累计计数能够产生所需的数值结果，而精度上限会让显示行为依赖任意的展示限制。

**所有比率都显示一位小数。** 不予采纳，因为低位区间的额外变化会增加无效抖动，并改变整数精度已经足够的既有显示。

**在 token-meter 中持久化显示百分比。** 不予采纳，因为投影已经携带精确计数，而展示精度属于 Web 统计行。第二个持久值会复制可派生状态，并扩大回放与协议职责。

## 后果

高缓存命中率会保持稳定的整数显示，直到整数舍入会错误地报告满命中；此时界面只展示维持区分所需的小数位。极接近满命中的非满比率可能因此产生较长的小数字符串，这是不设置任意精度上限或非数值回退所接受的代价。所有交付与恢复路径继续沿用既有持久投影生命周期。
