SOP:「会话规模提醒」Hook 变更(步数 + 上下文,2026-10-02)¶
1. 背景¶
长会话的成本 = 步数 × 上下文规模:LLM 每一步都要把整个上下文重发一次(按缓存命中价计费),
步数越多、上下文越大,命中重放费用越高。2026-10-01 实测一个会话(329217fa401d)跨 4.8 小时、
8 轮共 177 步,上下文从 5.4 万涨到 45.5 万 token,仅命中重放就 0.932 元,输出段另有
1.023 元(其中 67% 是思考)。用户希望能被主动提醒「该换会话了」。
触发条件:用户提出「Hook 能否在上下文达到约 25% 时提醒切窗口,且同时带上步数」。
2. 目标¶
变更后应达到:
- 每个工具调用后,Hook 侧准确知道本会话步数与最近一次请求的上下文 token 数;
- 步数跨 50 / 100 / 150 或上下文跨 35 万 / 50 万 / 70 万时,各注入一次提醒;
- 同一会话最多提醒 3 次,不重复污染上下文;
- 原有「规则 / 命令 / hooks.json 变更提醒」行为完全不变;
- 红线不破:任何输入下退出码 0、stderr 为空。
3. 前置条件¶
- 主机
192.168.31.250(用户rain),工程/home/rain/Documents/services/token_proxy; - token_proxy 代理在运行(
logs/usage.jsonl持续更新)——上下文数据源依赖它; ~/.trae-cn/hooks.json的 PostToolUse 已挂本脚本、matcher为*(本次不改 hooks.json, 故无需重启 Trae);- 权限:对
posttooluse-guard/有写权限(普通用户即可)。
4. 影响范围¶
| 项 | 说明 |
|---|---|
| 涉及主机 | 仅本机(单机) |
| 涉及组件 | posttooluse-guard/skill-edit-guard.py(PostToolUse Hook,matcher: *) |
| 是否停服 | 否。Hook 脚本改动即时生效(不同于 hooks.json,后者须重启 Trae) |
| 窗口期 | 无窗口要求,不影响代理与在途请求 |
| 在跑作业 | 无。不触碰 logs/、不重启 token-proxy |
| 新增状态文件 | posttooluse-guard/state/ctx__<session_id>__<agent>(JSON,7 天保留期) |
5. 分步操作¶
步骤 1:备份被改脚本¶
覆盖前先备份到本次主题目录,保持原有属主与时间戳。
mkdir -p ctx-warn-20261002/backup/posttooluse-guard
cp -p posttooluse-guard/skill-edit-guard.py \
"ctx-warn-20261002/backup/posttooluse-guard/skill-edit-guard.py.bak.$(date +%Y%m%d-%H%M%S)"
预期:ls -l 可见备份文件,大小与原文件一致(15,603 B)。
失败判断:目录建不出或无写权限 → 检查属主后重试。
步骤 2:编辑脚本(新增会话规模提醒)¶
在原脚本上做四处改动,均不触碰既有函数体:
- 模块 docstring 增补「修复记录(八)」:说明双维度、数据来源与去重策略;
- 常量区新增:
USAGE_FILE(由脚本位置推导,非硬编码)、STEP_THRESHOLDS = (50,100,150)、CTX_THRESHOLDS = (350000,500000,700000)、CTX_FRESH_SECONDS = 300、CTX_TAIL_BYTES = 65536、SESSION_KEY_PREFIX = "ctx__"、SESSION_ADVICE; - 新增函数:
_age_seconds/_latest_context/_session_state_key/_load_session_state/_store_session_state/_session_reminder; main()重构:先取会话提醒(对所有工具步生效),再走原写类工具逻辑, 两类文案合并为一次additionalContext;原命中判定抽为_collect_hits/_rule_warning。
坑与注意事项:
- 会话提醒必须放在「只认写类工具」的
return之前——否则只读工具步不计数; - 上下文只能侧读
logs/usage.jsonl尾行,PostToolUse 事件不含任何 token 字段(已由probe.jsonl核实);只读尾块 64 KB,不得全量扫描(该文件可达十几万行); - 事件无
session_id时静默:去重键会退化,若照常提醒会演变成每步重复注入; - state 文件名用
ctx__前缀,与规则提醒的<session>__<agent>区分,避免互相覆盖。
实现体:posttooluse-guard/skill-edit-guard.py(以它为准)。
步骤 3:语法检查与离线回归¶
python3 -m py_compile posttooluse-guard/skill-edit-guard.py
./venv/bin/python hook-skill-desc-20261002/verify_guard_cases.py # 原有 14 项
./venv/bin/python ctx-warn-20261002/verify_ctx_cases.py # 本次 18 项
预期:语法检查无输出;两套用例均「失败 0 项」。 失败判断:任一项 FAIL → 按输出定位后修正重跑,不要带着失败发布;必要时执行第 7 章回滚。
6. 验证¶
| 层次 | 方法 | 预期 |
|---|---|---|
| 离线(原有行为) | verify_guard_cases.py |
14/14 PASS,证明写类工具提醒未被破坏 |
| 离线(新增行为) | verify_ctx_cases.py |
18/18 PASS,覆盖三档递进、维度去重、陈旧与空数据、无 session_id、state 损坏、红线 |
| 真机 | 任意工具调用后查看 posttooluse-guard/state/ctx__* |
出现当前会话文件,steps 随工具调用递增、level 未跨档时为 0 |
| 真机(提醒) | 本会话自然跨档时观察 | 注入一条 [会话提醒] …本会话已 N 步…;同档不重复 |
真机验证命令(只读):
./venv/bin/python -c "
import glob, os, time
d = 'posttooluse-guard/state'
for f in sorted(glob.glob(d + '/ctx__*'), key=os.path.getmtime, reverse=True)[:5]:
print(os.path.basename(f), '->', open(f).read(), time.strftime('%H:%M:%S', time.localtime(os.path.getmtime(f))))
"
本次实测:出现 ctx__6abf4aeac1804934d3e76aab__solo_agent -> {"steps": 8, "level": 0},
与「本轮已 8 次工具调用、均未跨档」一致。
7. 回滚¶
备份存放位置:ctx-warn-20261002/backup/posttooluse-guard/,
台账见 ctx-warn-20261002/backup/README.md。
cp -p ctx-warn-20261002/backup/posttooluse-guard/skill-edit-guard.py.bak.<时间戳> \
posttooluse-guard/skill-edit-guard.py
python3 -m py_compile posttooluse-guard/skill-edit-guard.py
./venv/bin/python hook-skill-desc-20261002/verify_guard_cases.py # 回滚后应 14/14 PASS
回滚后验证:旧行为恢复(只按写类工具提醒),state/ctx__* 文件可留可删(不再被写入)。
回滚触发判据:脚本以非 0 退出码结束或 stderr 非空、真机出现每步重复提醒、既有 14 项用例回归失败。
8. 风险说明¶
| 风险 | 缓解 |
|---|---|
多会话并行串号:usage.jsonl 无 Trae session_id,上下文只取「最近一条记录」 |
步数以 session_id 独立计数(不受影响);上下文维度可能取到别的会话的值。单会话场景无影响;并行场景下最坏是提前提醒一次,不产生错误动作 |
代理停机:usage.jsonl 不再更新,读到陈旧值 |
CTX_FRESH_SECONDS=300 兜底:尾行超过 5 分钟视为陈旧,此时只按步数维度判断 |
| 工具步 ≠ LLM 步:纯文本答复(不带工具)不计入 | 实际几乎每步都带工具,误差可忽略;提醒文案写「本会话已 N 步」而非精确总数 |
| 提醒文本重放:注入的文本此后每轮都在上下文里 | 每会话每档只注入一次,最多 3 条 |
| 档位偏保守:50 步 / 35 万 token 才首次提醒,小任务不会被打扰 | 阈值集中在 STEP_THRESHOLDS / CTX_THRESHOLDS 两个常量,按需调整(改常量即时生效) |
附录:交付物清单¶
| 文件 | 作用 |
|---|---|
posttooluse-guard/skill-edit-guard.py |
被改实现体(新增会话规模提醒) |
ctx-warn-20261002/verify_ctx_cases.py |
本次 18 项离线回归用例 |
ctx-warn-20261002/SOP.md |
本文件 |
ctx-warn-20261002/backup/ |
备份与台账(README.md) |
来源:
/home/rain/Documents/services/token_proxy/ctx-warn-20261002/SOP.md| 最后更新:2026-10-02 14:40(由build/sync.py同步,请勿在站点侧修改)