fix(spawner): Review M1/M2 — 删除 overflow/timeout 死代码,只保留 precheck;更新设计文档 v5
M1: overflow/timeout 标记不含 sessionKey,被前置过滤跳过是死代码。
precheck 总在 overflow 之前触发且含 sessionKey,已覆盖 overflow 场景。
删除 overflow/timeout 分支,只保留 precheck route=compact_then_truncate。
M2: §24 设计文档新增 v5 章节描述(方案概述、三种触发路径分析、为什么只依赖 precheck)。
This commit is contained in:
@@ -1,12 +1,54 @@
|
||||
# §24 — Compact 检测方案修正
|
||||
|
||||
> 状态:v4(trajectory prompt.submitted),待实施
|
||||
> 状态:**v5 已实现**(gateway log + jsonl 配对)
|
||||
> 作者:庞统
|
||||
> 日期:2026-06-11
|
||||
> 日期:2026-06-11(v4),2026-06-13(v5)
|
||||
> 框架:基于 §07 Spawner Acquire-First
|
||||
> 评审:仲达 4 轮评审(v1 trajectory → v2 gateway precheck → v3 rotation-only → v4 prompt.submitted)
|
||||
> 评审:仲达 4+2 轮评审
|
||||
> 备选方案:B(内存 flag + sessions.json status),见 §2B
|
||||
|
||||
---
|
||||
|
||||
## 0. v5 方案(已实现)
|
||||
|
||||
### 0.1 方案概述
|
||||
|
||||
**gateway log 开始标记(precheck `route=compact_then_truncate`)+ jsonl 结束标记(`type: "compaction"` entry)配对**。
|
||||
|
||||
- **开始标记**:扫描 gateway 日志,找含目标 agent sessionKey 且 `route=compact_then_truncate` 的 precheck 日志行,提取时间戳。
|
||||
- **结束标记**:扫描 session jsonl,找开始时间之后的 `type: "compaction"` entry。
|
||||
- **判定逻辑**:有开始无结束 → compact 进行中 → skip ticker;有开始有结束 → compact 已完成 → 不 skip。
|
||||
- **超时兜底**:开始标记超过 15 分钟仍未结束 → 自动忽略(防止死锁)。
|
||||
|
||||
### 0.2 三种 Compact 触发路径分析
|
||||
|
||||
Gateway 的 compact 有多种触发路径,日志表现不同:
|
||||
|
||||
| 触发路径 | 有开始标记? | 有 sessionKey? | 有 compaction 结束标记? | 检测策略 |
|
||||
|---------|------------|---------------|----------------------|--------|
|
||||
| **overflow** | 有(`attempting auto-compaction`) | ❌ 不含 | 有 | 依赖 precheck 覆盖 |
|
||||
| **timeout** | 有(`[timeout-compaction]` + `attempting`) | ❌ 推测不含 | 有 | 依赖 precheck 覆盖 |
|
||||
| **precheck** | 有(`[context-overflow-precheck]` + `route=compact_then_truncate`) | ✅ 含 | 有 | **直接检测** |
|
||||
| **threshold** | 无(静默执行) | — | 有 | counter+lock+status 保护 |
|
||||
| **manual** | 无(静默执行) | — | 有 | counter+lock+status 保护 |
|
||||
|
||||
### 0.3 为什么只依赖 precheck 标记
|
||||
|
||||
1. **overflow/timeout 标记不含 sessionKey**:实测证实 overflow 标记(`context overflow detected; attempting auto-compaction for zhipu/glm-5.1`)不包含 `agent:xxx:main` 格式的 sessionKey,被前置 `session_key not in msg` 过滤跳过,是死代码。
|
||||
2. **precheck 总在 overflow 之前触发**:同一 compact 事件中,precheck `route=compact_then_truncate` 先检测到,overflow 是 fallback。所以 precheck 已覆盖 overflow 场景。
|
||||
3. **threshold/manual 无开始标记**:这两种是静默执行,没有 gateway 日志标记。它们依赖 counter+lock+status 三重保护(见 §07),不需要 gateway 日志检测。
|
||||
|
||||
> **注意**:`route=truncate_tool_results_only` 的 precheck 不触发 compact 检测,只有 `route=compact_then_truncate` 才触发。
|
||||
|
||||
### 0.4 超时兜底
|
||||
|
||||
15 分钟超时窗口:如果 compact 开始标记超过 15 分钟仍无结束标记,自动忽略该开始标记。这覆盖了:
|
||||
- daemon 重启后残留的开始标记
|
||||
- 极端长时间的 compact(正常 compact 通常 < 7 分钟)
|
||||
- 日志轮转导致的结束标记丢失
|
||||
|
||||
---
|
||||
|
||||
## 1. 问题
|
||||
|
||||
### 1.1 现象
|
||||
@@ -257,3 +299,6 @@ trajectory jsonl 路径 = `{sessionFile}.trajectory.jsonl`,其中 sessionFile
|
||||
- **v2**:gateway 日志 precheck 开始标志 → 仲达指出开始标志覆盖率仅 30%,建议 rotation-only
|
||||
- **v3**:rotation-only + 120s 窗口 → 合并 PR #36,但实测 51 分钟 compact loop 无法覆盖
|
||||
- **v4**:trajectory prompt.submitted → 仲达背靠背验证(源码 7 条 skipPromptSubmission 路径 + 实际数据 ~8% 假阳性但方向安全)→ 修正检测目标为"session 是否正常"
|
||||
- **v5**:gateway log(precheck 开始标记)+ jsonl(compaction 结束标记)配对 → 仲达评审通过后实现,PR #48 Review 驳回 M1/M2 修正后合并
|
||||
|
||||
> ⚠️ **v4 已 deprecated**。v4 的 trajectory prompt.submitted 方案未实施,最终实施的是 v5。v4 的分析(skipPromptSubmission 路径、实测数据)仍有参考价值。
|
||||
|
||||
Reference in New Issue
Block a user