会话阈值自动接续:机制方案 + 成本实测

2026-09-16 · 数据源 = workbuddy.db 的 session_usage.credit_json 与 automation_runs.runs_json(宿主真实计费字段,非估算)
判定三句:
① 「token 达阈值自动开新会话」能建,但只建成「半自动」——宿主无创建会话的 API,唯一通道是自动化(已实测:每次自动化运行都产生新 sessionId);钩子只能注入指令,末段动作必须由模型调 automation_update 完成。
② 但它救不了你看到的那 7–8 积分——实测那 7–8 分来自一轮里跑了 31–54 次工具调用,与会话新旧无关。三个自动化全部是全新会话的第一轮,分别烧掉 8.93 / 10.05 / 13.82 积分。
③ 真杠杆是「一轮内的工具调用次数」,不是「会话寿命」。换会话能省的只是「水位带来的约 3 倍单价膨胀」,属次要项。
④ 接得上才是前提——新会话必须能校验上一会话的进度,不能只读文字描述(实证:上一条接续点把对象写错了)。已升级为「接续包 v2 + 开机四步」,见 §五。

一、实测成本模型(8 次自动化运行,宿主原始计费字段)

自动化运行上下文 input tokens工具调用积分积分 / 工具缓存命中
覆盖网络线·归档接续200,0135413.820.25699.8%
决策方法-2168,0403710.050.27299.9%
覆盖网络线·接续(优化版)141,401318.930.28899.8%
代码仓三方同步 ③87,177201.930.09799.8%
代码仓三方同步 ①64,876151.660.11197.9%
遗留项自动推进82,712121.200.10098.7%
代码仓三方同步 ④63,147161.180.07499.7%
代码仓三方同步 ②56,422110.820.07598.5%

图:工具调用次数 → 积分(近乎线性)

红 = 水位 >14 万(单价 ≈0.27)|绿 = 水位 <9 万(单价 ≈0.09)
归档接续 54 次 13.82
决策方法-2 37 次 10.05
接续优化版 31 次 8.93
三方同步③ 20 次 1.93
三方同步① 15 次 1.66
遗留项推进 12 次 1.20
三方同步④ 16 次 1.18
三方同步② 11 次 0.82
同一批任务的 4 次「三方同步」单价 0.074–0.111(水位 5.6–8.7 万);三份覆盖网络/决策方法文档任务单价 0.256–0.288(水位 14–20 万)。
成本公式(可复算)
一轮积分 ≈ 单价 × 该轮工具调用次数 单价 —— 随会话水位上升,实测同一会话内: 水位 <10 万 ⇒ ≈ 0.10 积分 / 次工具调用 水位 15 万 ⇒ ≈ 0.41 积分 / 次工具调用 ← 4 倍 固定注入(每请求都要重发): tools 20,734 + systemPrompt 10,395 + skills 3,919 + mcp 144 = 35,192 token 但缓存命中 99.5% ⇒ 固定注入被缓存价抹平,不是主因 (b08b1c35 实测:63,488 命中 / 1,388 未命中 = 97.9% 命中率)
上表「单价」两簇(0.09 / 0.27)的差异来源:新会话 b08b1c35 内部给出了同会话、同模型、仅水位不同的对照——第 1 轮单价 0.106(起始水位 0),第 2 轮单价 0.412(水位 14.9 万)。⇒ 水位效应成立,非模型档位差异。

二、为什么「开新会话」没省到钱

铁证:三次「新建会话跑一次」的积分 = 8.93 / 10.05 / 13.82,与你观察到的「提一轮就 7 8 个积分」完全吻合。而它们每一个都是全新会话的第一轮——证据在 automation_runs.metadata_json:

{"runKind":"scheduled","conversationId":"3b096fe1-…","sessionId":"3b096fe1-…"} {"conversationId":"32d97b9a-…","sessionId":"32d97b9a-…"} …每次自动化运行 = 一个此前不存在的 sessionId

⇒ 已核实 自动化确实是「开新会话」的通道,但新会话第一轮的 31–54 次工具调用照旧收费,而且开局水位为零也没让它变便宜。

为什么不变便宜?因为成本 = 请求次数 × 每次请求量。开新会话把「每次请求量」的增量部分清零了,但:

⇒ 「会话多大」影响的是单价,不是总价;「跑多少次工具」才决定总价。

三、真杠杆排序(按效力)

#杠杆效力做法
①一轮内的工具调用次数主导 · 线性批量活写成脚本「一次跑完」:1 次 Bash 顶 20 次 Read/Edit/Bash。31 次 → 5 次 ⇒ 8.93 分 → 约 0.5 分
②会话水位次要 · 约 3 倍到阈值换会话(就是你想建的那套机制)
③固定注入 35,192 token很轻缓存命中 99.5%,基本不用管

⚠️ 顺序不能反:先治 ①,再治 ②。只换会话不减工具调用 = 每次省一点单价、总量照旧,这正是「没达到节约效果」的成因。

四、机制设计:能建,但只能建成「半自动」

现状:缺口只有一个

水位探测已有 stop-dialog-guard.py 三级阈值 12 万 / 20 万 / 30 万,数据源 = 转录里的真实 usage.input_tokens,同级去重只报一次
指令注入已有 三级文案 = 强制收口(落盘 → 接续包 → 告知开新会话)
创建会话缺 钩子事件只有 SessionStart / PreToolUse / UserPromptSubmit,输出只有「注入上下文」与「拦工具」两种,没有任何创建 / 切换会话的能力
可用通道自动化 模型可调 automation_update 登记一次性自动化;宿主调度到点即开新会话
⛔ 钩子脚本不能直接写数据库来建自动化——自动化只能经 automation_update 创建,这是硬约束。

建议链路(在现有三级告警上追加一段)

[硬] 水位 ≥ 30 万 ↓ stop-dialog-guard.py 注入(已有文案 + 新增第 ④ 条) [软] 模型执行收口四步: ① 落盘:在途状态写进 .workbuddy/memory/ ② 出接续包:目标/已完成/在途/下一步/关键决定/回滚点 ③ 【新增】调 automation_update 登记一次性自动化 name = "<原会话名>-2" prompt = "读 <接续包路径>,从「下一步」起继续。 ⛔ 第一轮必须把批量活写成脚本一次跑完,工具调用 ≤ 8 次。" 时间 = 当前时刻 + 2 分钟 ④ 终结本会话 ↓ [硬] 宿主到点执行 ⇒ 新会话(实测通道可靠)

它的真实价值:把「被迫收口 → 用户手工开新会话」变成「自动续上」,省掉人工一步,并把单价膨胀(约 3 倍)压回去。它不省工具调用次数——所以第 ③ 步 prompt 里那句「工具调用 ≤ 8 次」才是真正值钱的部分。

它的局限(如实说):末段是软环节——钩子只能要求模型照做,模型若不调 automation_update 则链条断在最后一步。硬保证只有前半段(提醒 / 强制收口)。

五、让新会话「明确知道进度 + 未执行项」

这是自动接续能不能用的真正前提——接不上状态,「自动开销」只是白花钱重新探索一遍。原规范(工作区根《会话接续规范》)已有 6 项内容清单,本轮补的是可校验性:文字会失真,证据不会。

实证:上一条接续点原话写「清理被截断的 .workbuddy/memory/MEMORY.md」——照做就会改错对象(真正被截断的是用户级那份)。凡是结论,必须附一条能复现的命令。

接续包 v2 · 固定表头(新会话机械读取)

## 接续点 · <工作线名> · <YYYY-MM-DD HH:MM> - 来源会话: <sid> | 结束原因: <水位 N 万强制收口 | 用户要求> - 原目标: <用户原话,不翻译、不缩写> - 基线: HEAD=<git sha> | 远端 master=<sha> | 全局锁=<无 | 占用者> - 产物: <绝对路径1> | <绝对路径2> ← 新会话逐一确认存在 - 校验命令: <一条命令> → 期望输出: <关键片段> ← 证明"上一步真完成" - 未完成: ①<…> ②<…> ← 用户要的、还没做的 - 下一步: 第 1 个动作 = <具体命令> ← ⛔ 不写"继续处理" - 关键决定: <已定项 + 为什么> ← 防新会话推翻重来 - 回滚点: <能退回的位置> - ⛔ 不要重做: <已完成的,免得重复劳动>

硬要求:① 「校验命令」必填,只读、30 秒内跑完、输出可判真假;② 「下一步」第 1 条必须可直接执行;③ 产物 / 未完成 / 不要重做 三节一个都不能空(空写「无」);④ 全篇 ≤3 KB,只写「在哪 + 什么状态」。

新会话开机四步(接手方强制动作)

#动作为什么
1只读接续包(⛔ 不许一上来就全库探索 / 扫全盘)探索是最贵的动作;接续包就是用来免掉它的
2跑「校验命令」并比对期望输出——不符就停下报告,⛔ 不许照文字硬做文字会失真;跑不通的校验会伪装成"通过"
3复述「未完成」与「下一步」,确认与用户当时要的一致防目标漂移(本线最大历史坑)
4从「下一步」第 1 条开工;⛔ 不重做「不要重做」列的东西省掉重复劳动

⚠️ 接续包会过期:写完后又改了东西,必须回头改接续包并同步「基线」里的 sha 与时间戳。

自动接续任务 · 标准 prompt 模板(照抄填空)

读「<接续包绝对路径>」的「接续点」。 ① 先跑其中的「校验命令」,输出与期望不符 ⇒ 停下、只报告,⛔ 不许照文字硬做。 ② 从「下一步」第 1 条开工;⛔ 不重做「不要重做」列的东西。 ③ 批量活必须先写成脚本一次跑完,⛔ 不许逐份探索;本脚本工具调用 ≤ 8 次。

第 ③ 条才是钱的开关:31 次工具调用 = 8.93 积分;压到 8 次 ≈ 1 分。前两条保证「不跑偏」,第 ③ 条保证「不贵」。

六、顺带发现(只报告,未动手)

1. 两个「定时」自动化仍在按钟点烧钱——它们与水位无关,是「定时触发」而非「阈值触发」,恰好是你这次想改掉的那种:

自动化周期频率已跑已花
代码仓三方同步(DSH)FREQ=HOURLY;INTERVAL=3约 8 次/天4 次5.59
遗留项自动推进(DSH 平台)FREQ=HOURLY;INTERVAL=8约 3 次/天1 次1.20

合计约 11 次/天 × 每次新建会话;按实测均值 ≈1.4 积分/次估算 ⇒ 约 15 积分/天纯自动化消耗,且每次都会在仓库里产生一个新会话与新的未提交改动。

2. 五个一次性自动化已过期但仍为 ACTIVE(08-27 ×2、08-30、08-31,以及今天的三个覆盖网络/决策方法一次性任务)⇒ 属清理项。

3. 前一轮对本问题的结论需要更正:stop-dialog-guard.py 里写着「③ 因此本级不做自动开,做强制收口」并注明「自动开这一半无法实现」。前半句仍成立(钩子确实做不到),但后半句不准确——经自动化这一通道,自动接续可以做到半自动。此处属发现,未改脚本。

七、落地清单(按效力排序,待你点头后执行)

  1. (最高)给两个周期自动化的 prompt 加硬约束:写明「批量活必须先写脚本一次跑完,工具调用上限 8 次」。预期把单次 8–14 分压到 1–2 分。收益最大
  2. 接续包换成 §五 的 v2 表头 + 新会话按「开机四步」启动 —— 这正是你要的「新会话明确知道上个会话的进度与未执行内容」。规范已就地升级(工作区根《会话接续规范》,§3.1.1–3.1.4 / §3.2.1),下次收口即生效。已就绪 · 靠纪律
  3. 在 stop-dialog-guard.py 三级文案后追加第 ④ 条(提示模型登记 +2 分钟一次性自动化)。改动在 hook 脚本内、即刻生效,无需重启。收益次要 · 消除人工一步
  4. 清理 5 个过期的一次性自动化;与 ③ 一起或单独做。
  5. 重估两个周期自动化的存在必要——「代码仓三方同步」每 3 小时一次是否真需要;若只是兜底,改日频即可。

⚠️ 落地 ③ 需改文档库脚本 ⇒ 要抢全局执行锁 + 推镜像 + 复跑对账。本轮为无人值守运行,未动任何脚本 / 自动化 / 文档库,未抢锁、未提交、未推送;只升级了工作区根《会话接续规范》(本工作区自有文档,非文档库)。

八、附:为什么自动化会话要跑那么多工具调用

你的感觉对,但原因不是「自动化」这个身份。
实测今日 6 个会话:自动化平均每轮 5.6–8.9 积分,手动平均每轮 3.3 积分(约 2–3 倍)。差距来自三件事,全都可以改。

对比(今日同一工作区、同一类任务)

会话类型轮数积分总计平均每轮
自动化·接续优化版自动化18.938.93
自动化·决策方法-2自动化544.778.95
自动化·确认覆盖网络待办自动化211.175.59
手动·检查覆盖网络方案手动516.523.30

⚠️ 手动会话的总量并不小(原会话 e2e090be 累计 221 次工具调用,比任何自动化都多)——差别在单轮。

根因一:一条指令里塞了几件事

你手动说「继续 XX 任务」,通常只指一件事;而自动化的 prompt 会把一整段工作串起来。以「决策方法-2」那条为例,它同时要求:三项任务 + 抢全局锁 + 只做三项 + 脚本化 + 反序释放锁 + 写简报 + 写记忆 + 不许承诺降低消耗 —— 八件事塞进一条指令,模型只能一路做到底。

根因二:没人能打断(最关键)

实证:新会话 b08b1c35 那一轮,用户只说了「先确认待办事项」。实际发生的:

第 1–3 次 读接续入口 / 简报 / 会合中继方案 第 4–6 次 抢锁(PATH 被 shim 重置,重试 2 次) 第 7–24 次 连续 17 次深度取证:ssh config、106 的 env、47 的 psql、 47 的 systemd drop-in、remote-spawner.ts、proxy.ts 勘误… 第 25 次 加载技能 dsh-change-workflow 第 28 次 ⚠️ 已经在写 S0 的代码了 —— src/net/reachability.ts (用户要的是「确认待办」,不是开工)

模型自己的思考留了痕:「重要取证完成」「取证非常完整了」「现在证据链完整了」—— 三次自我加码。你在场时,看到第三次就会说「够了,先停」;无人值守时没人喊停,它就自己给自己加码。

根因三:我的规则本身在制造调用

「接手前人结论先做最小取证」「交付门禁四层验证」「抢锁 / 反序释放锁」「写简报 + 写记忆」都是项目硬规则,每一条都是一个或多个工具调用。规则是对的,但把它们全塞进一条无人值守的指令里,就成了「必须一路做完」。

另有一笔环境税:Bash 每次都要重写 export PATH=…(shim 重置 PATH),虽不增加调用次数,但让每次调用都变长。

最根本的一条:单次调用极便宜,模型没有代价感

从转录里逐次请求的 credit 字段(与数据库 credit_json 合计完全对上,两个独立源交叉验证):

会话请求次数单次中位单次最低 / 最高合计
自动化·确认覆盖网络待办670.110.05 / 2.0611.17
手动·检查覆盖网络方案440.210.07 / 2.8416.52
第 1 次调用(冷启动): prompt=52,856 hit=12,288 miss=40,568 credit=0.60 ← 最贵 第 67 次调用(末次) : prompt=197,376 hit=197,120 miss=256 credit=0.11 ← 命中 99.9%

每一次调用只要 0.1 分左右——所以模型在单步决策时几乎感觉不到代价,它看不到「累计已经 67 次了」。没有人喊停,它就没有刹车。你在场时,你那句「够了,先停」就是唯一的刹车;无人值守时,刹车片不存在。

⛔ 注意:这里也顺带推翻了"自动化一定比手动贵"——按累计算,手动那个会话 16.52 反而更贵(水位 21.7 万、单次中位 0.21)。差别只在单轮塞了多少事。

修法:改 prompt,不改流程

在现有模板(§五)后面再加两条,直接掐掉前两个根因:

⛔ 本轮只做一件事:<具体那件>。做完即停。 不许顺手做归档 / 整理 / 写入口 / 开工别的任务。 ⛔ 取证只做一次、最多 3 个命令;发现要动代码或改配置 ⇒ 停下来报告,不要动手。

预期效果:b08b1c35 那一轮 77 次 → 约 8 次,11.17 分 → 约 1 分。这就是「把第一优先杠杆(一轮工具次数)压下去」的具体做法。

⚠️ 附带一条真实修正:早前记录写「转录 rawUsage 恒为空」——不准确。实测 b08b1c35 的 jsonl 里有 67 条带 credit 的 rawUsage,且逐次合计 11.17 与数据库 credit_json 完全一致。该字段可用,是逐次成本的最佳来源。