Files
ycode/docs/Claude追加与压缩协议验证-2026-10-20.md
T

123 lines
6.7 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.
# Claude 追加与压缩协议本地验证
日期:2026-10-20
验证状态:SDK/CLI 协议探针和生产 ClaudeKernel 追加、压缩集成回归通过;Electron 主进程端到端结果另见本轮交接记录,不代表 WorkBuddy 1:1 验收。
## 1. 验证对象
- `@anthropic-ai/claude-agent-sdk`:`0.3.304`
- SDK 内置 Claude Code:`2.1.304`
- `node_modules/@anthropic-ai/claude-agent-sdk-win32-x64/claude.exe`
- Claude Code SHA-256:`019E5174D5D954585EDB1A946FE280E44A973050B4897034ADF0E16306F85FDD`
- 运行平台:Windows x64
本验证使用本机回环模拟的 Anthropic Messages SSE,不连接真实模型服务。HOME、USERPROFILE、
`CLAUDE_CONFIG_DIR` 和 `CLAUDE_SECURESTORAGE_CONFIG_DIR` 均重定向到临时目录,仅使用 dummy key。
因此本文件证明的是当前 SDK/CLI 的消息协议和帧归属行为,不是模型质量、真实供应商行为或
WorkBuddy 原版行为。WorkBuddy 原版结论仍必须通过 REA 采集并记录其 Evidence ID。
## 2. 追加协议探针
探针文件:
- `scripts/claude-append-protocol-probe.ts`
- `scripts/build-claude-append-probe.mjs`
探针通过 SDK 原始 `query()` API 创建一个保持打开的异步输入流,流程如下:
1. 发送带 UUID `INITIAL` 的 `PROBE_INITIAL`。
2. 挂起首个模型请求的 SSE 响应。
3. 在首个请求仍在途时,向同一输入流追加带 UUID 的 `PROBE_APPEND_A`、`PROBE_APPEND_B`。
4. 不调用 `interrupt()`,不关闭输入流;释放首个响应后等待全部逻辑回合结束。
5. 对照捕获的模型请求体、SDK 运行时帧和 `result` 帧。
本次生成报告:`.tmp/claude-append-protocol-probe.json`,顶层结果为 `PASS`。
### 请求侧结果
请求 1 只包含 `PROBE_INITIAL`,且正常完成,未被追加消息取消或改写。
请求 2 包含:
1. 初始用户消息 `PROBE_INITIAL`;
2. 首轮 assistant 文本 `answer-1:PROBE_INITIAL`;
3. 同一个 user message 中按顺序合并的 A、B 文本块。
本次 CLI 将 A 序列化为 `PROBE_APPEND_A\n`,B 保持 `PROBE_APPEND_B`。因此追加消息不会注入
已经在途的 HTTP 请求,而是在首轮完成后成为下一逻辑回合的输入;相邻追加可合并为一个 user message。
### 结果与归属
本次观察到两个 `result`:
- `result[0]` 只归属 `INITIAL` UUID;
- `result[1]` 同时归属 A、B 两个 UUID,其中 `user_message_uuid` 是最后一条 B 的 UUID。
两个 `assistant` 帧也按相同边界归属:首轮 assistant 不包含 A/B UUID,合并后的第二轮 assistant
同时包含 A/B UUID。输入文本没有产生 SDK `user` echo 帧。
当前版本的 assistant/result 帧未观察到 `prompt_id`。可用的稳定归属键是
`user_message_uuid` / `user_message_uuids`;在合并回合中,`user_message_uuid` 只是
`user_message_uuids` 的最后一项,不能代表该 result 只覆盖 B。
关键结论:
- 一个 `result` 可能覆盖多个追加 UUID;不能用“收到一次 result”直接结算所有排队发送。
- 在途请求和后续追加属于不同逻辑回合,当前观察到一个逻辑回合对应一个 `assistant` 和一个 `result`。
- 该协议结论来自 SDK 原始异步输入流;生产 `ClaudeKernel` 的实现和验证单独记录在第 4 节。
## 3. 原生压缩边界复验
使用 `scripts/claude-kernel-integration.ts` 的 `compact` 分支,设置
`CLAUDE_PROTOCOL_PROBE=1` 后运行真实 SDK + 内置 CLI + 回环假模型。观察到
`system/compact_boundary`,后续收到成功 `result`,探针断言通过。
集成回归同时继续发送压缩后的请求,断言旧 ASK 内容不再出现在上游请求中。生产命令专用路径不附加普通聊天提醒,成功必须同时收到原生边界和成功结果;应用可见历史不随压缩删除。没有证明:
- 真实模型压缩后的内容质量或语义完整性;
- 自动压缩的 token 阈值和触发条件;
- 并发追加用户消息与压缩同时发生时的行为;
- 压缩失败、重试和真实供应商错误分类。
## 4. 对 YCode 内核的影响
生产 `src/main/agent/claude/claude-kernel.ts` 保留单个活动根运行,新增 `appendInput()`,不放开并发 `runTurn()`:
1. 输入带独立 UUID 推入同一原生输入流,不取消当前请求,不声称改写已发出的上游请求。
2. 按 `user_message_uuid(s)` 路由后续输入组;首个 result 不会提前结算仍待交付的追加项。
3. 前一组完成后先保存旧 assistant;匹配到新组的原生身份帧后,由宿主原子保存完整用户消息及新 assistant,再确认对应队列项交付。A/B 可合并到同一原生组,但正式历史保留两条用户消息。
4. 后续组沿用根运行的冻结模型、权限和工作区;新组保存期间工具/审批等待交接,避免挂到旧 assistant。
5. 取消会关闭并排空原生生产者,再允许下一运行;推入前失败可明确重试,推入后未确认的消息标记 unknown,不自动重放。
`scripts/claude-kernel-integration.ts` 直接调用生产内核验证双追加、不打断首请求、身份归属、交接回调、空闲追加拒绝、原生压缩和压缩后请求。2026-10-20 重新构建后运行 `CLAUDE_PROTOCOL_PROBE=1`,输出 PASS(16 requests / 43 events / 9 turns)。这些数字属于确定性回环夹具,不是实际模型效果或完整 UI 验收。
## 5. 复验命令
在仓库根目录执行:
```powershell
npx tsc --ignoreConfig --noEmit --target ES2023 --module ESNext --moduleResolution Bundler --strict --skipLibCheck --types node --lib ES2023 scripts/claude-append-protocol-probe.ts
node scripts/build-claude-append-probe.mjs
node .tmp/claude-append-protocol-probe.mjs
node scripts/build-claude-kernel-regression.mjs
$env:CLAUDE_PROTOCOL_PROBE='1'
node .tmp/claude-kernel-integration.mjs
npm run typecheck
```
预期:
- 追加探针输出 `result: PASS`,报告写入 `.tmp/claude-append-protocol-probe.json`;
- 压缩探针输出 `probe: compact`、`boundary: true`,随后 integration 输出 `result: PASS`;
- `npm run typecheck` 通过。
`node .tmp/claude-append-protocol-probe.mjs` 使用随机回环端口和临时配置目录;报告中的端口、
UUID 和消息 UUID 每次运行都会变化。稳定复验依据是版本、二进制哈希、帧结构和上述断言。
## 6. 限制与后续
- 探针只覆盖 Windows x64 和当前 SDK/CLI 版本,不能外推到其他平台或版本。
- 假模型只返回固定文本,不覆盖真实长上下文、网络重试、限流和供应商差异。
- 没有验证 WorkBuddy 原版是否采用相同的追加/压缩交互;该比较需另行通过 REA 完成并记录证据。
- 原生追加与压缩混发被产品入口拒绝;真实网络故障、工具密集追加、多平台进程崩溃注入仍需要进一步验证。