会话长度守卫(Session Length Guard)
三十秒说清它能帮你做什么
会话过长会让模型变笨且变贵——但它不会报错,只会悄悄少想、重复做、每轮更贵。等你察觉时已经烧掉一大截额度。
这个技能解决一个问题:什么时候该开新会话,用数据说话,不靠感觉。
- 读真实 token 用量,不是"数轮数 × 每轮估算"——后者误差极大
- 单一界限 350,000 tokens,不做多级分档,不打扰你
- 过线前先写交接文档再建议换会话,不丢上下文
- 附带成本曲线,让你看到长会话到底贵在哪
- 阈值可复现:附两个校准脚本,换模型/换机器后自己重跑一遍
数据源
<用户目录>/.workbuddy/projects/<slug>/<sessionId>.jsonl
→ providerData.usage.inputTokens 服务端返回的真实 prompt token 数
这是硬数据,不是估算。社区同类方案(context-guard-pro 等)靠"数轮数 × 每轮
500~2000 token"估算,误差极大;tide-watch 之类依赖 OpenClaw 的 session_status
工具,在 WorkBuddy 上用不了。
判级:单一界限 350,000 tokens
不分工作模式,不做多级分档。 craft / plan / ask 一视同仁。
| 上下文占用 | 判定 | 动作 |
|---|---|---|
| < 350,000 | OK 未过界限 |
继续,不用管 |
| ≥ 350,000 | SHIFT 该换会话 |
生成交接文档后开新会话 |
为什么是 350K(作者本机 940 轮实测,脚本 references/calibrate_quality.py):
- 重复调用率:25K–150K 平稳在 0–1.4%;175K–200K 升到 2.7%;
200K–250K 6.5%–6.9%;350K–375K 飙到 34.1%(约每 3 次调用就有 1 次重复) - 思考 token:< 100K 均值 826 → ≥ 100K 428(−48%)
- 350K 是"灾难级"起点。
以 100K 为界整体对比:重复率 0.78% → 4.78%(+510%),思考量 −48%。
> ⚠️ 数据同时显示 200K 起已有明显信号(重复率 6.5%+)。350K 是偏宽松的
> 界限,换取更少打扰。若你觉得该更保守,把脚本里的 SHIFT_AT 调到 200000 即可。
恶化不是"崩溃",别用异常率衡量
实测:异常率按上下文分档后基本平坦(各档 3–5%,合计 4.7%),响应延迟也
与长度无关(300–350K 的中位延迟 10.7 秒,比 150–200K 的 18.6 秒还快)。
所以别拿"有没有报错"判断会话是否健康。 模型不会报错,只会:
悄悄少想(思考 token −48%)、重复做(重复率 +510%)、每轮更贵(成本 O(n²))。
成本是另一个独立维度(只显示,不参与判定)
每轮请求都要把完整历史当 prompt 重发,第 n 轮 prompt ≈ 起始 + n×增量,
累计成本 = O(n²) 二次增长。
| 会话(示例) | 首轮 | 末轮 | 倍数 | 累计消耗 |
|---|---|---|---|---|
| 会话 A | 16,222 | 346,444 | 21.4x | 49.3M |
| 会话 B | 16,620 | 287,664 | 17.3x | 72.5M |
拆成 4 段短会话做同样的事,可省 46%–83%。后 25% 轮次成本是前 25% 的
1.9–3.5 倍。
成本与质量无关,即使会话没到 350K,长会话依然很贵。脚本会显示累计消耗供参考。
依据可复现
阈值和成本结论都来自真实会话数据,可随时重跑验证(把 $PY 换成你的 Python):
"$PY" "<skill_dir>/references/calibrate_quality.py"
"$PY" "<skill_dir>/references/calibrate_cost.py"
换模型、换机器后建议重跑一次,阈值可能不同。
用法
PY="<你的 python 解释器路径>"
S="<skill_dir>/scripts/check_context.py"
"$PY" "$S" # 检查当前会话
"$PY" "$S" --all # 列出所有会话,按占用降序
"$PY" "$S" --session <id> # 指定会话(支持前缀匹配)
"$PY" "$S" --json # 机器可读
"$PY" "$S" --quiet # 只输出一行
"$PY" "$S" --handoff # 生成交接文档草稿
Windows 用户若想双击运行,可在本技能根目录自建一个 会话体检.cmd(内容如下)。
> 注:.cmd 属可执行文件类型,平台不允许随包上传,因此需要你本地自建一次。
@echo off
chcp 65001 >nul
title Session Length Guard
setlocal
set "PY=%USERPROFILE%\.workbuddy\binaries\python\versions\3.13.12\python.exe"
if not exist "%PY%" set "PY=python"
set "CHK=%~dp0scripts\check_context.py"
"%PY%" "%CHK%" --all
echo.
pause
endlocal
提示:路径建议一律用正斜杠写法。若你的 Windows 用户名含空格或特殊字符,
命令里的路径要加引号,或改用不带特殊字符的家目录别名。
触发时机
- 用户主动询问:出现"上下文""开新会话""重启""会话太长"等词时立即执行。
- 子任务完成时(主触发):每完成一个阶段/里程碑,跑一次
--quiet。
最贴合工作流,不打断思路,不用在脑子里计数。 - 兜底计数:距上次检查又新增约 50 次工具调用时检查一次。
- 校准依据:实测平均 2,091 tokens/次,50 次 ≈ 100K。
- ⚠️ 方差极大(单会话 1,209~7,400 tokens/次,6 倍),计数只能兜底,
不能替代第 2 条。 - 收到危险信号时立即检查:单次工具输出异常长(几千行)、或发现自己开始
重复相同调用/产出相似输出。这类信号不用跑脚本也能感知。
提醒话术
判定为 SHIFT 时直接建议行动,不要只陈述数字:
> ⚠️ 当前会话 372K tokens,已过 350K 界限。建议现在收尾:我把关键信息写成
> 交接文档,你开新会话后让 AI 先读它。
未过界限但接近时(比如 346K,距界限 3.5K):
> 💡 当前 346K,距 350K 界限只差 3.5K,下一步大操作可能会过线。
交接流程(开新会话前必做)
- 跑
--handoff,生成<用户目录>/.workbuddy/handover-YYYY-MM-DD.md
(同名文件已存在时自动加时间戳后缀,不覆盖) - 把当前任务进度、关键结论、未完成事项填进文档空位
- 开新会话,第一句让 AI 读取该交接文档
禁止在不写交接文档的情况下直接建议用户开新会话——那等于丢失上下文。
额外检测项
- 循环风险:最近 15 次工具调用中,同工具+相同参数重复 ≥3 次 → 空转征兆,
立即换策略(长会话是高发场景)。 - 膨胀源:单次工具输出 >8000 字符时提示,长输出是上下文膨胀主因。
- 压缩事件:token 骤降 >35% 记为一次压缩。实测压缩阈值很高(约 480K 才触发),
10 个会话里只有 2 个触发过,不能依赖它兜底。
已知限制
- 判定用当前 token 数。若会话曾冲高到 500K 后被压缩回 287K,会显示
OK
(压缩后上下文确实是新的),但"历史峰值"一栏仍会显示那个高危数字。 - 同一工作目录下有多个时间接近的会话时(平台有时会并行开会话),
脚本会提示ambiguous并列出候选,用--session指定。 - 默认取"当前工作目录下最近有写入的会话";在错误目录下运行会选错,用
--cwd
或--session修正。 - 平台未公开上下文窗口上限(
models.json写 360,000,但实测有会话跑到 500,939),
百分比仅按 400,000 参考窗口换算,不参与判定。 - 阈值来自作者本机、特定模型下的实测;换模型后建议重跑校准脚本。