6.7 KiB
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.tsscripts/build-claude-append-probe.mjs
探针通过 SDK 原始 query() API 创建一个保持打开的异步输入流,流程如下:
- 发送带 UUID
INITIAL的PROBE_INITIAL。 - 挂起首个模型请求的 SSE 响应。
- 在首个请求仍在途时,向同一输入流追加带 UUID 的
PROBE_APPEND_A、PROBE_APPEND_B。 - 不调用
interrupt(),不关闭输入流;释放首个响应后等待全部逻辑回合结束。 - 对照捕获的模型请求体、SDK 运行时帧和
result帧。
本次生成报告:.tmp/claude-append-protocol-probe.json,顶层结果为 PASS。
请求侧结果
请求 1 只包含 PROBE_INITIAL,且正常完成,未被追加消息取消或改写。
请求 2 包含:
- 初始用户消息
PROBE_INITIAL; - 首轮 assistant 文本
answer-1:PROBE_INITIAL; - 同一个 user message 中按顺序合并的 A、B 文本块。
本次 CLI 将 A 序列化为 PROBE_APPEND_A\n,B 保持 PROBE_APPEND_B。因此追加消息不会注入
已经在途的 HTTP 请求,而是在首轮完成后成为下一逻辑回合的输入;相邻追加可合并为一个 user message。
结果与归属
本次观察到两个 result:
result[0]只归属INITIALUUID;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():
- 输入带独立 UUID 推入同一原生输入流,不取消当前请求,不声称改写已发出的上游请求。
- 按
user_message_uuid(s)路由后续输入组;首个 result 不会提前结算仍待交付的追加项。 - 前一组完成后先保存旧 assistant;匹配到新组的原生身份帧后,由宿主原子保存完整用户消息及新 assistant,再确认对应队列项交付。A/B 可合并到同一原生组,但正式历史保留两条用户消息。
- 后续组沿用根运行的冻结模型、权限和工作区;新组保存期间工具/审批等待交接,避免挂到旧 assistant。
- 取消会关闭并排空原生生产者,再允许下一运行;推入前失败可明确重试,推入后未确认的消息标记 unknown,不自动重放。
scripts/claude-kernel-integration.ts 直接调用生产内核验证双追加、不打断首请求、身份归属、交接回调、空闲追加拒绝、原生压缩和压缩后请求。2026-10-20 重新构建后运行 CLAUDE_PROTOCOL_PROBE=1,输出 PASS(16 requests / 43 events / 9 turns)。这些数字属于确定性回环夹具,不是实际模型效果或完整 UI 验收。
5. 复验命令
在仓库根目录执行:
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 完成并记录证据。
- 原生追加与压缩混发被产品入口拒绝;真实网络故障、工具密集追加、多平台进程崩溃注入仍需要进一步验证。