Files
dsh_shenxian/dsh-server-docs/04-调整方案/126-会话接续规范.md
T
admin 04776af4b1 docs: 工作区根项目文档批量入仓(04-调整方案 113–128 / 交接单 T09–T21 / ops / archive)
起因:用户 2026-09-17 明确「所有文档都要同步,都放在开发仓库 docs 对应文件夹下」。
判据:工作区根 *.md 中在仓库(git ls-files --quotepath=false)搜不到的那些。

入仓 33 份(一律复制,工作区根原件保留不动,避免引用断链):
- 04-调整方案/113–128(16 份 · 原子占号后落盘):覆盖网络 传输方案取舍 / 应用场景与待完善清单 /
  插件化vs改内核 / 问题逐条推演 / 参数表与观测口径;会合中继拆分取证与改造方案;
  集群化改造方案 Manager-Worker;跨节点迁移与节点自举;项目代码分层范式与迭代风险评估;
  搬运与共享重建方案 guest w47→w106;方案规划方法提炼;文档无效信息审计报告;
  会话接续机制复盘与修复;会话接续规范;dsh 客户端化部署方案;dsh 桌面客户端开发方案
- 交接单/archive/交接单-已完成/T09–T21(13 份 · 覆盖网络线已完成单归档)
- ops/(2 份运行态指针:接续入口 / 接续包 · 覆盖网络线)
- archive/(2 份临时与内部简报)

已排除(无需重复入仓):覆盖网络线 10 份方案正文已入档案 103–112(文件名不同)。

登记:INDEX.md §二 新增 04-113–128 共 16 行 + §四 追加 T09–T21 说明 + 机器摘要行刷新
(⛔ 未跑 docs-index-stats.py --write:该脚本会按 \r\n 归一化全文件行尾,故改为字节级单行替换);
README.md 追加 1 条入仓指针;docs-manifest.json 复跑 scripts/docs-manifest.py 刷新。

验收:工作区根 47 份 .md —— 同名已入仓 8 / 本次内容一致 29 / 已知改名映射 10 / 未入仓 0;
git status 待提交清单只含本次新增与登记 3 件(未涉 src/ 与 relay 代码面)。
2026-09-17 18:24:19 +08:00

288 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 会话接续规范:token 超限后如何无损继续
> 2026-09-16 立。来源 = 复盘会话 `78ac724f`(「查看 dsh 项目待办事项」)**最后 6 轮**的真实操作与失败。
> 适用:任何会话接近/超过上下文预算,需要"换会话继续"的场景。
---
## 0. 结论(先看这三行)
**能形成方法 —— 但重点不在"自动开新会话"。** 宿主不允许程序化创建会话(钩子没有这个能力),唯一通道是"**一次性定时任务**"。⚠️ 且**只能做成"半自动"**:钩子会注入"该收口了",但**最后那一步(登记自动化)必须由模型自己调 `automation_update` 完成**,钩子做不到。
**自动接续解决的是"手不用点"和"单价膨胀",不解决"钱少花"。** 09-16 实测(`workbuddy.db` 原始计费字段):
- **成本 ≈ 单价 × 一轮内的工具调用次数**;单价随水位 <10 万 ≈0.10、15 万 ≈0.41 积分/次(同会话受控实测 **4 倍**)。
- **固定注入 = 35,192 token/请求**(tools 20,734 + systemPrompt 10,395 + skills 3,919 + mcp 144),但**缓存命中 99.5%** ⇒ 它**很轻**,不是主因。
- ⛔ 三个自动化**全新会话的首轮**分别烧 **8.93 / 10.05 / 13.82** 积分(首轮跑了 31–54 次工具调用)⇒ **开新会话挡不住"一轮几十次工具调用"的钱。**
**那个会话真正的失败不是技术,是目标漂移。** AI 自造了「接续入口」「归档」这类只有它懂的内部词,把自己加的收尾动作**当成了正事** —— 用户的原话是「**感觉和我要的东西不相关**」。
---
## 1. 案例复盘:最后 6 轮实际发生了什么
| 轮 | 用户说 | AI 做了什么 | 判定 |
|---|---|---|---|
| 1 | 「确认」 | 把"接续入口"收成一个文件 | ⚠️ 用户没要求过这个词 |
| 2 | 「**能否自动创建新会话继续处理**」 | 如实答"不能创建会话",改走**一次性定时任务**(定 11:00) | ✅ 诚实 + 找到等价路径 |
| 3 | 「不用等这么久 尽快触发」 | 提前到 10:20,并核对 `nextRunAt` | ✅ 执行到位 |
| 4 | 「**第一轮就消耗 7 个积分,并没有起到降低 token 消耗的作用**」 | 认错:承诺口径不准确;真实口径见 §2-P1 | ✅ 认错 + 给真数据 |
| 5 | 「**没看懂…什么是接续入口 / 归档用脚本做,感觉和我要的东西不相关**」 | 承认那三个词是自己造的,**跑偏了** | 🔴 **本轮暴露根因** |
| 6 | 「重新创建个你优化后的自动任务不就行了」 | 重建:prompt 从 ~1.5k 降到 **~200 token**,强制脚本化 | ✅ 修正方向 |
---
## 2. 三个真问题(按严重度排序)
### P3 🔴 目标漂移 —— 最严重,且与技术无关
「接续入口」「归档」「用脚本做」**全是 AI 自己造的内部流程词**,用户从未要求。AI 把自己加的收尾动作当成正事,**反而没在做用户要的"继续未完成的任务"**。
**判据**:如果一个词是你自己发明的、用户没说过 —— 它就不该出现在给用户的说明里。**接续包的读者是"下一个会话 **和** 用户",允许出现只有 AI 懂的词,就是失败。**
### P2 任务形态错 —— 比会话形态更根本
把「10 份文档逐份 agent 化改写」交给自动任务 ⇒ **20+ 轮 × 7 积分 ≈ 140+ 积分**。
这**违反项目自己的省积分第一招「批量活写脚本」** —— 这类批量转换本就该一次性脚本跑完。
⇒ **换会话只是换场地,活还是那么贵。** 自动接续**不能**救"任务形态本身贵"的问题。
### P1 承诺不准确 —— 体感与承诺不符,损伤信任
AI 曾把"开新会话"说成"降低 token 消耗" ⇒ 用户实测第一轮 7 积分,**直接质疑**。
**准确口径**(必须这样讲,09-16 实测修正):
- **开新会话不是零成本** —— 每轮 35,192 token 固定注入躲不掉(但缓存命中 99.5%,很轻);
- **真正的收益 = 单价**:水位从 20 万降到 5 万,**每次工具调用的单价约降 3–4 倍**(0.41 → 0.10 积分/次,同会话受控实测);
- ⇒ 它是"**降低单轮单价**",**不是**"降低总消耗"。⛔ 不许再说成后者。
- ⚠️ **旧版本此处写"水位从 39 万降到 5 万(约 1/8)"—— 该比值被高估约 2 倍**(把固定注入按全价算,忽略了 99.5% 的缓存命中)。已按实测更正。
- ⛔ **而且它只对"下一轮"有效**:如果新会话第一轮又跑 30+ 次工具调用,等于没省 —— 实测三个自动化全新会话首轮 8.93 / 10.05 / 13.82 积分就是证明。
---
## 3. 方法:三条硬要求 + 一条红线
### 3.1 接续包(会话 → 会话)
**触发**:用户要求接续,或水位到 30 万(另有 `stop-dialog-guard.py` 三级机制会自动提醒)。
**内容**(**用用户的词写,不用 AI 的内部词**):
1. **原目标** —— 用用户当初的说法,别翻译
2. **已完成** —— 一句话 + 关键产物路径
3. **在途** —— 跑到一半的,写清断在哪
4. **未完成** —— 用户要的、但还没做的(**这一节最重要,优先于"AI 自己加的收尾"**)
5. **下一步** —— 新会话第一个动作
6. **关键决定 + 回滚点**
**落位**:`.workbuddy/memory/<日期>.md` 追加,或单独一份 `接续入口_<线>_<日期>.md`(**约 3 KB 以内**)。
### 3.1.1 接续包 v2:必须**机器可校验**(2026-09-16 补,用户要求「让新会话明确知道上个会话的进度和未执行的内容」)
> **为什么必须可校验**:09-16 实证 —— 上一条接续点原话写「清理被截断的 `.workbuddy/memory/MEMORY.md`」,接手会话照做**就会改错对象**(真正被截断的是**用户级**那份)。⇒ **文字会失真,证据不会。** 凡是"结论"必须带一条**能复现的命令**。
**表头(放在接续包最前面,固定字段名,便于新会话机械读取)**
```md
## 接续点 · <工作线名> · <YYYY-MM-DD HH:MM>
- 来源会话: <sid> | 结束原因: <水位 N 万强制收口 | 用户要求>
- 原目标: <用户原话,不翻译、不缩写>
- 基线: HEAD=<git sha> | 远端 master=<sha> | 全局锁=<无 | 占用者>
- 产物: <绝对路径1> | <绝对路径2> ← 新会话必须逐一确认存在
- 校验命令: <一条命令> → 期望输出: <关键片段> ← 证明"上一步真的完成了"
- 未完成: ①<…> ②<…> ← 用户要的、还没做的(优先于 AI 自己加的收尾)
- 下一步: 第 1 个动作 = <具体命令,不是"继续处理">(之后 ② ③ …)
- 关键决定: <已定项 + 为什么> ← 防新会话推翻重来
- 回滚点: <能退回的位置>
- ⛔ 不要重做: <已完成的,免得重复劳动>
```
**硬要求**
1. **「校验命令」必填**,且必须是**只读、可在 30 秒内跑完、输出可判真假**的那种(例:`docs-sync-check.sh` → 期望 `192/192, 0 差异`;`git ls-remote origin refs/heads/master` → 期望 sha 等于基线)。
2. **「下一步」第 1 条必须是可直接执行的命令或文件路径**,⛔ 不许写「继续推进」「按情况处理」这类无法执行的话。
3. **产物 / 未完成 / 不要重做 三节一个都不能空**(空就写「无」),否则新会话只能重新探索 = 白花钱。
4. **≤3 KB**:只写「在哪 + 是什么状态」,⛔ 不把内容搬进来。
### 3.1.2 新会话开机四步(接手方强制动作)
**第 0 步(2026-09-16 晚加,实测补)**:先跑 `state.py`(工作区根,只读、免抢锁、约 30 行)—— 1 次调用就拿到 `[锁] / [git] / [入口] / [收口]`,其中 `[入口]` 段**同时给出"待执行清单"和"接续包在哪"**。
⛔ 跑它之前**不许**任何 Glob / Grep / `git status` 全盘探索。
> 为什么必须补:它回答「**我该接谁的班**」——只读接续包时若不知道去哪找、或没有接续包,新会话只能自己探索。**实测反例**:14:32 那轮(`d48a9be8`)把 `state.py` 排到**第 37 次调用**,全程 40 次调用 / 9.37 积分,用户当场质问「是不是应该先确认待执行的任务有哪些再去执行」。
| # | 动作 | 为什么 |
|---|---|---|
| 1 | **只读接续包**(⛔ 不许一上来就全库探索 / `git status` 扫全盘) | 探索是最贵的动作,接续包就是用来免掉它的 |
| 2 | **跑「校验命令」并比对期望输出** —— **不符就停下报告,不许照文字硬做** | 文字会失真(见 3.1.1 实证);跑不通的校验会伪装成"通过" |
| 3 | **把「未完成」与「下一步」复述一遍**,确认与用户当时要的一致 | 防目标漂移(§2-P3 是这条线最大的历史坑) |
| 4 | **从「下一步」第 1 条开工**;⛔ 不重新探索、不重做「不要重做」列的东西 | 省掉重复劳动 |
### 3.1.3 接续包会过期 —— 写完要回头维护
> 🔴 **2026-09-16 补:入口与接续包必须"同一次更新里一起改",且都带口径时间戳。**
> **实测事故**:`接续入口`(mtime 16:48)比 `接续包`(17:29)**滞后 41 分钟**,而 `state.py` 的 `[入口]` 段**就是从入口读的** ⇒ 17:04 那位**自动接续会话**按旧口径得出「P4 **并入自研 relay**」,与随后定案(**relay 实现未定、先做 R0 评测**)**表述不一致**(方向一致、粒度不同,用户当场察觉)。
> ⇒ 三条硬要求:
> ① **改接续包时,同一个动作里把入口 §2 一起改**(入口 = "下一棒的第一信息源",且 `state.py` 直接读它);
> ② **入口 §2 末尾必须写"本口径截至 `<时刻>`"**;
> ③ **接续包标题里的时间戳必须等于内容最后修订时刻**(17:29 那次只改了内容、标题仍写 16:58 ⇒ 读的人无法判断自己读的是哪一版)。
**凡是写完接续包之后又改了东西,必须回头改接续包。**(09-16 实证:接续点写好后对象被更正,接续包没跟着改 ⇒ 下一个会话会照错的做。)
**每次改动接续包,都要同步更新「基线」里的 sha 与时间戳。**
### 3.1.4 ⛔ 收益不靠"接续包更详细"
接续包写得再全,**也压不掉"一轮 30+ 次工具调用"的钱**(实测 8.93–13.82 积分/轮)。接续包解决的是**不丢状态、不重复劳动、不跑偏**;省钱靠的是 `3.2` 里那条**工具调用上限**。
### 3.2 自动接续任务(一次性 automation)
**只在"用户明确要求自动"时建**,且必须满足五条:
**prompt 自包含** —— 不依赖任何旧会话上下文(新环境读不到)
**prompt 要短** —— 实测正解:**~200 token**(只说"读 `<接续包路径>`"),⛔ 不要罗列 10 个文件名(那是 1.5k)
**prompt 必须写死"开机四步 + 工具调用上限"** —— 见下面模板;**那一行才是真正省钱的地方**
**⛔ prompt 里不许复制任务细节**(2026-09-16 晚加,实测)—— 细节的唯一来源是**交接单 / 接续包**;把技术细节抄进 prompt 会 ① 造第二个漂移源 ② **挤掉"开机四步"那一行**。
> **实测反例**:14:32 那轮的 prompt 重述了整段 S1 技术细节(≈1.2 KB),却**没带开机四步**(无接续包、无校验命令、无"先跑 state.py")⇒ 40 次调用 / 9.37 积分;而该轮的立项验收口径是 **≤10 次 / ≈1 分**。
**prompt 必须锚定线名** —— 「线名」或「接续包绝对路径」二者至少给一个(§3.4 规则 2)。⛔ 只用"按 §2 第 1 条开工"这类**不带线名**的写法,多线并行时会**串线**。
**先抢全局执行锁** —— 抢不到就停手,不和人工会话撞车(多线并行时的完整处置见 §3.4 规则 4)
**★ 必须在给用户的回复里告知**(2026-09-16 加,用户实测反馈触发)—— 新建会话 / 新建自动化是**用户可感知的状态变更**(提问闸门 A 类原话:「AI 会不会悄悄改他的设置」)。⛔ **只登记不告知 = 缺陷**:用户会在会话列表里凭空看见多出一个会话而不知何来。回复里用**陈述句**写清三件:① 已登记自动接续、约 N 分钟后自动开新会话、**不需要用户操作**;② 接续点 = `<文件>`;③ 若用户想自己开,口令 = `<state.py 口令>`。
> **实测出处**:2026-09-16 17:01 会话「规划覆盖网络任务落地步骤」(`408636f2`)登记了自动化(→ 17:04 开出会话 `1281e874`),但**最后回复结尾一字未提** ⇒ 用户隔了两小时自己发现并追问「你是不是通过自动任务 新建了个会话继续任务」。
**★ 登记前冻结口径;登记后口径变了就必须重登记**(2026-09-16 加,治"两张皮")—— ① 登记时**算好接续包 md5 并写进 prompt**(新会话开工前会校验它,见 §3.2.1 ①b);② 登记之后**若你仍在本会话继续工作、且改动了接续包(或改了关键判断)** ⇒ **必须回来撤销 / 重登记**那条 automation。⛔ 不重登记的后果 = 下一棒按**旧口径**开工并且**无从知道**。
> 📌 **来历(实测)**:17:01 登记、17:03 触发;而原会话一路工作到 **18:21**,**17:2x 才改判 P4、17:3x 才撤销「首选 frp」、17:29 才更新接续包** ⇒ 新旧两张皮。**「收口」只登记了一个未来动作,不等于会话结束** —— 没有同步点,漂移就是必然。
⛔ **做完即失效**(一次性),**不要留成周期任务**。
#### 3.2.1 标准 prompt 模板(照抄,填空即可)
```text
⓪ 先跑 `state.py`(工作区根,只读)⇒ 按它 `[入口]` 段里**「<线名>」那一行**定位接续包;⛔ 多线并行时只走你自己那条、别串线;⛔ 跑它之前不许 Glob/Grep 探索。
读「<接续包绝对路径>」的「接续点」。
① 先跑其中的「校验命令」,输出与期望不符 ⇒ 停下、只报告,⛔ 不许照文字硬做。
①b 🔴 **口径门禁(硬,必须机器校验)**:登记本任务时,prompt 里**必须带「接续包 md5」**(`md5sum <接续包绝对路径>` 或 python `hashlib.md5`)。开工前**重算一次**:**不一致 ⇒ 立刻停手并报告「口径已更新,需重新接续」**,⛔ 不许凭接续包正文继续往下做;⛔ **若 prompt 里根本没有指纹 ⇒ 同样视为不合格,停手报告**(说明登记方漏了这一步)。⇒ 判据是**数值比对**,不是"记得去看 mtime"。
①c ⛔ **接续包里写「未定 / 待定 / 未授权」的事,不许你替原会话拍成「已定」**(2026-09-16 实测事故:接续会话把「relay 实现**未定**」输出成「**并入自研 relay**」);若发现接续包内容与 prompt 描述有出入 ⇒ **先报告,不要自行取舍**。
② 从「下一步」第 1 条开工;⛔ 不重做「不要重做」列的东西。
③ 批量活必须先写成脚本一次跑完,⛔ 不许逐份探索;本轮工具调用 ≤ 8 次。
⛔ 本轮只做上面这一件事,做完即停。不许顺手做归档 / 整理 / 写入口 / 开工别的任务。
⛔ 取证只做一次、最多 3 个命令;发现要动代码或改配置 ⇒ 停下来报告,不要动手。
```
**为什么是这五条(2026-09-16 实测,见 §6)**
| 条 | 治什么 | 实测依据 |
|---|---|---|
| ① | 照错文字硬做 | 上一条接续点把对象写错了(§3.1.1) |
| ② | 目标漂移 / 重复劳动 | §2-P3 |
| ③ | **钱的主力** | 31 次调用 = 8.93 分;压到 8 次 ≈ 1 分 |
| ④ | **无人值守时的自我扩权** | `b08b1c35` 用户只说「先确认待办」,第 28 次调用**已在写 S0 代码** |
| ⑤ | 防御性过度取证 | 同一会话第 7–24 次连续 17 次取证,reasoning 三连自我加码 |
**④⑤ 是 2026-09-16 新加的**:实测自动化**平均每轮 5.6–8.9 积分**,手动会话**平均每轮 3.3 积分**(约 2–3 倍)。根因不是"自动化"这个身份,而是**一条指令塞太多事 + 没人能打断**。⛔ 别再用「一条 prompt 跑完整条工作线」的写法。
#### 3.2.2 完整链路(哪一段是硬的、哪一段是软的)
```text
[硬] 水位 ≥ 30 万 → stop-dialog-guard.py 注入「强制收口」 ← 已上线
[软] 模型写接续包(§3.1.1 模板) ← 靠纪律
[软] 模型调 automation_update 登记一次性任务(+2 分钟) ← 靠纪律,钩子做不到
[软] ★模型在给用户的回复里告知「已登记自动接续」 ← 靠纪律(2026-09-16 补;缺这一环 = 用户不知情)
[硬] 宿主到点执行 ⇒ 新会话自动开 ← 已证实(每次运行必带新 sessionId)
[硬] 新会话按 §3.2.1 模板开机 ← 靠 prompt 写死
```
⚠️ **两处软环节必须知道**:钩子**不能**创建会话、**不能**创建自动化(自动化只能经 `automation_update`)。所以「自动接续」是**半自动**——末段若模型没调工具,链条就断在最后一步。⛔ 钩子脚本**不得**绕过 `automation_update` 直接写库建自动化(硬约束)。
### 3.3 ⛔ 红线
**不许自造流程词给用户看。** 用户说"继续未完成的任务",你就去做**他说的那件事**,不要顺手加"归档""整理""写入口"。
**不许把"AI 自己加的收尾动作"排进自动任务的正事里。** 顺序必须是:**用户要的活在前,AI 自己加的收尾在最后(或不加)**。
**不许承诺"降低 token 消耗"** —— 只能说"降低每轮水位"(见 P1)。
---
### 3.4 多线并行:怎么不打架(2026-09-16 晚加,用户提问触发)
> 用户原话:「**假如多个会话都要新建会话,新会话全都执行这个口令吗,会不会冲突**」
**会冲突,三种;真正会咬人的是第 ① 种。**
| # | 冲突形态 | 现状 | 对策 |
|---|---|---|---|
| ① | **串线** —— 口令只说"按 §2 第 1 条",而 `state.py [入口]` 原先只认"最新一份接续入口" ⇒ 两个新会话都跑**同一条线**,另一条线没人跑 | 🔴 **会真发生**(今天只有一条线,属潜伏) | **口令必须带线名**;`state.py` 已改为**列全所有线**并打印带线名的口令 |
| ② | **抢锁** —— 两条线同时动手,只有一个抢到 | ✅ 已有全局执行锁兜底,**不会同时改**;代价是输家白烧一轮 | 输家**只报告 + 结束**;⚠️ **读前置可并行**(`state.py` / 读接续包 / 校验命令都是只读) |
| ③ | **共享文件互相覆盖** —— 今日日志 / `MEMORY.md` / 文档库 / 代码仓都是**全平台共用** | ⚠️ 靠纪律(实测今日日志里已有 **15** 个接续点/收口章节) | **只追加自己的小节**(小节名带线名);⛔ 不重写别人的段落、⛔ 不全文件覆盖 |
**四条硬规则**
1. **一线一份接续入口** —— `接续入口_<线名>_<日期>.md`。⛔ 不复用别人的、⛔ 不把旧线那份当自己的;`state.py` 会列全,**按你手上那份接续包 / 自动化 prompt 里的线名认领**。
2. **口令必须锚定线名** —— 正解:「跑 `state.py`,按 **<线名>** 那段 §2 第 1 条开工」(`state.py` 末尾已直接打印这句)。⛔ 不要只说"按 §2 第 1 条"。
3. **同一时刻只许一个自动会话动手** —— 登记新的一次性自动化前,先看有没有在跑的:`automation_runtime_state.running = 1`(或 `running_conversation_id` 非空)⇒ **不再登记**,等它自己往下接。⛔ 不要同时挂两条待触发的一次性自动化。
4. **抢不到锁 = 正常信号,不是故障** —— 它说明"**另一个会话正在动手**"。处置:只读部分照做(跑 `state.py` → 读接续包 → 跑校验命令)→ 报告「X 持有锁,我未动手」→ 结束。⚠️ 此时**连日志都不该写**(写文件也要锁)⇒ **只能回复报告**,不要硬写、不要删锁。
## 4. 与既有机制的配合
| 机制 | 管什么 | 位置 |
|---|---|---|
| 三级预算告警(12/20/30 万) | **什么时候该收口** | `dsh-server-docs/scripts/stop-dialog-guard.py` |
| 本规范 §3.1.1 接续包 v2 | **收口时产出什么**(机器可校验) | 本文件 |
| 本规范 §3.1.2 开机四步 | **接手方怎么确认没跑偏** | 本文件 |
| 交接单 8 段模板 | 规划会话 → 执行会话 | `dsh-server-docs/交接单/README.md §二` |
| `automation_update`(一次性) | 自动触发接续 | 工具,用时现调 |
| 成本公式(§0) | **判断钱花在哪** | 本文件;数据源 `workbuddy.db` |
> 一句话:**告警决定"该走了",接续包决定"走得不丢东西",开机四步决定"接手方不会跑偏",工具调用上限决定"这一趟值不值钱"。**
## 5. 实测数据存档(2026-09-16)
| 自动化运行 | 上下文 tokens | 工具调用 | 积分 | 积分/工具 |
|---|---|---|---|---|
| 覆盖网络线·归档接续 | 200,013 | 54 | 13.82 | 0.256 |
| 决策方法-2 | 168,040 | 37 | 10.05 | 0.272 |
| 覆盖网络线·接续(优化版) | 141,401 | 31 | 8.93 | 0.288 |
| 代码仓三方同步 ③ | 87,177 | 20 | 1.93 | 0.097 |
| 代码仓三方同步 ① | 64,876 | 15 | 1.66 | 0.111 |
| 遗留项自动推进 | 82,712 | 12 | 1.20 | 0.100 |
| 代码仓三方同步 ④ | 63,147 | 16 | 1.18 | 0.074 |
| 代码仓三方同步 ② | 56,422 | 11 | 0.82 | 0.075 |
**取数方法**(下次直接复用,别再摸索):
- `E:/ProgramData/.workbuddy/workbuddy.db` → `session_usage.credit_json`(逐轮积分)|`automation_runs.runs_json`(逐请求 usage / 缓存命中 / byCategory)|`automation_runs.metadata_json`(sessionId)|`automations`(周期与状态)
- ⚠️ **转录 `projects/<目录>/<sid>.jsonl` 里带 `rawUsage`(含逐次 `credit`)—— 可用,别信"恒为空"**:实测 `b08b1c35` 有 **67 条**带 `credit` 的记录,**逐次合计 11.17** 与数据库 `credit_json` 总和**完全一致**(两个独立源交叉验证)。⇒ 要"逐次成本曲线"就取这里。
- 取数脚本:`_中间产物_待清理/auto-continue-20260916/`(`cost_model.py` 聚合全自动化 / `curve.py` 逐次曲线)。
**详细报告**:`会话阈值自动接续_机制方案与成本实测_20260916.html`。
## 6. 为什么自动化会话要跑那么多工具调用(2026-09-16)
**实测对比(同一工作区、同一类任务)**
| 会话 | 类型 | 轮数 | 积分总计 | 平均每轮 | 工具调用 |
|---|---|---|---|---|---|
| 自动化·接续优化版 | 自动化 | 1 | 8.93 | **8.93** | 31 |
| 自动化·决策方法-2 | 自动化 | 5 | 44.77 | **8.95** | 141 |
| 自动化·确认覆盖网络待办 | 自动化 | 2 | 11.17 | **5.59** | 77 |
| 手动·检查覆盖网络方案 | 手动 | 5 | 16.52 | **3.30** | 50 |
**两条先破除的错觉**
1. ⛔ **「自动化一定比手动贵」不成立**:手动 `df1b7c6a` 累计 **16.52 > 11.17**(单次中位 0.21 > 0.11)。差的是**单轮塞了多少事**,不是身份。
2. ⛔ **「单次很贵」不成立**:逐次 `credit` 中位数只有 **0.11(自动化)/ 0.21(手动)**,最低 0.05。⇒ **成本完全由"次数"累出来**,而模型单步决策时**看不到累计**。
**三条真根因**
1. **一条 prompt 塞了 N 件事** —— 手动「继续 XX」只指一件;自动化 prompt 常把「N 项任务 + 抢锁 + 只做 N 项 + 脚本化 + 反序释放 + 写简报 + 写记忆」串成一条,模型只能一路做到底。
2. **没人能打断(最关键)** —— 实证:`b08b1c35` 用户只说「先确认待办事项」,实际第 7–24 次连续 17 次深度取证,**第 28 次已经在写 S0 的代码**;reasoning 里出现「重要取证完成 / 取证非常完整了 / 现在证据链完整了」**三次自我加码**。你在场时那句「够了」就是唯一的刹车。
3. **规则本身在制造调用** —— 取证 / 交付门禁 / 抢锁与反序释放 / 写简报 / 写记忆,每条都是调用。规则没错,但塞进无人值守的一条指令就变成"必须做完"。
**修法**:见 §3.2.1 的第 ④⑤ 条(只做一件事、取证设上限)。预期 77 次 → 约 8 次,11.17 分 → 约 1 分。