6.3 KiB
上下文用量获取、计算与保存复核
后续用户授权的实现已完成,见用量与分类修复记录。下文保留当时的只读发现;“尚未实现”是诊断阶段状态。
用户要求查看当前用量无法获取及保存逻辑,确认是否可以计算。本轮为只读诊断;未修改产品代码、用户数据或发送模型消息。
实查结果
- 用户数据目录最近五个会话的 YCode
sessions.json均没有contextUsage,但其用户消息记录的原生 OMP transcript 存在。最近hi会话的原始助手消息有 input 4009、cacheRead 1152、output 125,最近请求输入占用为 5161,contextSnapshot.promptTokens同为 5161。 - 将该 transcript 复制到隔离目录,以独立 HOME、仅指向 localhost:1 的无鉴权 profile 启动 OMP,只调用
get_state,未调用 prompt,未接触原文件。实测返回contextUsage:{tokens:5161,contextWindow:262144,percent:1.9687652587890625}。报告.tmp/context-state-readonly-Fv6wfQ/report.json。窗口 262144 来自此次隔离 profile(与用户当前配置相同),这不是对历史模型窗口从未修改的证明。 - 当前实际应用主进程于 2026-10-17 19:51 启动,早于
chat-turn-service.ts20:39 的保存修复;该进程尚未完整重启。不能用它生成的旧数据证明最新持久化字段仍然丢失,也不能认为更新 renderer 已加载主进程修复。
已确认的产品缺口
session:messages只读取 YCode 保存的消息;lastContextUsage只扫描这些消息。没有查询内核状态或从原生记录恢复统计的入口。无旧快照时 UI 提示“请稍后重试”,实际上没有重试动作。- 新发送未清除/标识上次请求统计;最新助手无 usage 时,恢复函数还会跳过它,继续拾取更早的样本。这会把更早请求的数据呈现为当前用量。
- 现有保存记录只有 usage 与冻结窗口,没有采样请求、原生分支、采样时间及来源标识。它适合作为历史样本,不能单独承担实时上下文查询。
- 新版 usage 事件已能进入助手消息、checkpoint 及磁盘,相关受控回归已通过;主要问题是获取/恢复路径及样本时效语义,不应笼统认定 JSON 保存损坏。
改法
建立独立的上下文用量查询,优先读取已绑定当前会话的 OMP get_state.contextUsage,无需为了数字再发模型消息,也不累计多次请求。读取必须校验会话/模型/分支身份,不为查询随意切换、重建或重启正在工作的内核。
未运行的旧会话可从当前保留分支的原生记录恢复最近请求真实输入量;恢复需绑定相应助手消息和原生分支,不用当前模型配置冒充未知的历史窗口。若需重新计算,则由内核针对实际输入计算,并将估计来源与上游 usage 区分。单看界面正文不足以精确还原隐藏提示、工具定义、图像与协议封装。
保存保留为缓存/历史依据,增加来源、采样时间、请求及分支身份;新回合、换分支、压缩和换模型时重新核对有效性。无法取到新统计时明确显示“上次统计”或“暂无统计”,不能无提示地复用更旧样本。没有分母时仍可展示已知 token 数,不应将整个数值隐藏为“无法获取”。
分类数值目前没有来源,不由总量分摊伪造。此次验证只证明 OMP 已保存的最近输入用量可恢复,不代表已实现每次编辑草稿后的全输入实时精确分词。
此前七项记录中的 N04 代表新样本保存与指定恢复测试通过;以上旧会话恢复、查询和时效缺口尚未修复,不能将它表述为上下文用量功能完整完成。
分类明细追查:系统提示词、工具、对话、连接器与技能
用户进一步询问能否获得这类明细。实测报告 .tmp/context-breakdown-readonly-6qX2rb/report.json:在另一隔离副本上仅执行 get_state、set_host_tools(声明一个测试工具,未调用工具)和 get_messages,没有 prompt 或模型请求。
get_state.systemPrompt可读取当前内核系统提示词,本例为两个字符串的数组;报告只记录类型/数量,不输出正文。get_state.dumpTools提供当前工具定义。本例以--no-tools启动时为空,注册测试工具后返回一个包含name/description/parameters的对象。get_messages返回 user/assistant 等内容块,可识别正文、thinking、toolCall 等;原始助手记录保留 usage 与contextSnapshot。- 原始
contextSnapshot有promptTokens/nonMessageTokens/compactionEpoch,本例非消息部分为 3306;它不是“系统提示词独占 3306”,不能据此拆出各类。 - 关键时效限制:注册新工具前后
contextUsage.tokens仍是 5161。已证该值在此路径中复用最近请求统计,不是配置变化后即时重算的全输入总量。此前“get_state 负责当前用量”的建议须加来源/采样身份约束,不能把它包装成任意时刻的实时精确分词。
当前 YCode 自有来源也足以做归类:OMP 回合注册实际 tools;createCapabilitySnapshot 保有技能 references/注入正文、专家身份及 MCP tool 的 server/tool 元数据;工具调用和返回能按 toolCallId 对应。分类应按来源,不应仅按 role:技能/专家指令可能被注入 user 文本,仍归入其指令来源,避免重复计数。
结论:可以实现这些明细,但当前产品尚未接入分类采集/分词/IPC,内核状态接口也没有直接给出五类 token 账单。可靠实现要捕获同一次实际准备发送的输入(系统提示词、最终工具定义、当前消息分支和实际注入能力),按模型可用分词器独立计数并保留来源/精度标识。工具未被调用时,其定义仍可能占输入;历史工具返回在停用连接器后仍可能留在输入中。提供商隐藏封装及子代理私有上下文不能凭空计入。
总量保留上游实测/原生快照;分类独立标注本地分词计数或估算,合计差异列为未归类/协议开销,不把分类按比例缩放到总量,也不把“总数减已知数”伪装成已证实系统提示词。旧历史缺少当时完整输入时只能显示可恢复部分,不能以当前提示词和工具反推过去。