caveman cacheengine:cache-replay 活体回放协议详解——从零网络 Preflight 到 Provider 级命中证据
本文基于 caveman 仓库中的 REPLAY_PROTOCOL.md 协议文档与 cache-replay、cachebench 源码实现,完整讲解 cacheengine 的活体(live)回放协议:trace v3 数据格式与三类 timing basis、零 provider 调用的 preflight 验证、带成本接受的真实执行流程、外部任务验证器的 wire 契约、以及保留证据目录的原子化布局。读完后你可以独立构建一条“可计费、可审计、可复算”的 provider 级缓存命中证据链,而不仅仅停留在本地模拟结果。
为什么活体回放被设计得“比模拟更难”
cache-replay 的目标是把一份 cachebench trace 转化为 retained provider 证据与任务质量证据。协议开篇即明确其设计立场:活体推理有真实成本,trace 内容可能暴露给 provider,而且“靠掩盖弱时间戳或用估算 token 预算无法让证据在科学上成立”(见 REPLAY_PROTOCOL.md)。
这与 cachebench 的模拟基准形成明确分工:README 中本地 golden path 报告 benchmark_simulated | publishable: false,零 provider 调用;而 cache-replay 的 evidence basis 是 provider_observed,两者永远不混合(types.go 中 BasisSimulated/BasisObserved 两个常量即体现这一隔离)。
证据流水线:从 trace 到 exact-population 报告
协议定义了完整的证据管线:
trace.v3
-> exact NativeRequest reconstruction
-> cacheengine metadata-only optimization
-> model-visible equivalence check
-> authenticated provider request
-> retained full response + provider usage extraction
-> external task verifier
-> observation.v3 + replay-evidence.v1
-> exact-population 97% report
管线有两个关键不变式,源码中都有直接对应:
1. 请求一旦开始绝不重试。 连接失败是模糊的:即使客户端没看到响应,provider 可能已经处理并计费该请求;自动重试会造成双重计费并破坏缓存时间线(corrupt cache chronology)。在 replay_http.go 中,Send 方法注释即声明 "sends one bounded provider request without retry",且 http.Client 通过 CheckRedirect 返回 http.ErrUseLastResponse 拒绝一切重定向。
2. 绝对时间调度,而非相对间隔。 runner 在第一次 provider 调用之前先优化 trace 中所有请求,并逐一证明 wire body 与捕获 body 在模型可见意义上等价;调度使用相对第一条 trace 时间戳的绝对偏移,因此 provider 延迟不会被累加到历史的 start-to-start 间隔上。实现见 replay.go 的 Run 方法:先 prepare(对全量 records 做 Engine.Optimize + ModelVisibleEquivalent 检查,任一失败以 model_visible_mismatch 失败码终止),再按 anchorTrace/anchorReal 锚点计算 scheduled = anchorReal.Add(offset) 分派。
-max-concurrency 约束的是完整的请求生命周期(provider 调用到任务验证完成)的并发数,取值 1~1024,默认 1(main.go 中 flag.Int("max-concurrency", 1, ...))。每个 worker 在传输前立即测量漂移(drift);grounded 回放中漂移超过 -max-schedule-drift(默认 250ms)时,该请求不发送任何内容,直接产出 schedule_drift 失败码证据。证据中保留目标时间、实测漂移和容差。协议要求:并发度按真实的全局重叠度和 verifier 延迟配置,容量不足时让证据失败,而不是悄悄拉伸时间表。
Trace v3:绑定原始 body 与全部优化器输入
生成的 trace 记录绑定原始 body 和每一个优化器输入,字段清单如下(与 types.go 中 TraceRecord 结构一一对应):
- 请求 ID、provider、模型、region、endpoint、scope、epoch、partition key;
- 预期 requests/minute 与缓存 TTL 内预期调用数;
- runtime/auth mode;
- 原始 body 及其 SHA-256;
- 用于规划的声明式可缓存前缀 token 数;
- 优化后 wire 输入 token 的声明上限(ceiling)、精确的 provider 原生最大输出 token、以及调用方提供的 token 计数依据;
- 时间戳与 timing basis。
为什么活体回放强制 v3? 读者保留 trace.v1 仅用于旧 observation join、trace.v2 用于精确优化器重建;但 v2 缺少总输入/输出 ceiling,其旧的 prefix-token 上限无法约束实际计费量。v3 会把输出 ceiling 与 provider 请求 body 交叉校验(trace.go 的 requestBudgetMatchesBody):拒绝流式请求(stream: true)、模型不匹配、OpenAI 歧义的 ceiling 字段(max_tokens/max_completion_tokens/max_output_tokens 三字段只允许出现其一且与 endpoint 匹配)、缺失 ceiling 和非正值。
三种 timing basis
| basis | 含义 |
|---|---|
grounded_global_timestamps |
真实全局请求排序;live 执行默认要求 |
per_partition_timestamps_only |
LMCache 公开语料只提供会话内间隔,无全局时间线 |
synthetic_schedule |
确定性生成的合成负载 |
(常量定义见 types.go 的 TimingGrounded/TimingPerPartition/TimingSynthetic。)
token 计数依据与计费 ceiling
声称 provider 计数的输入使用 token basis provider_counted_input_tokens;声明的总输入必须覆盖优化后 wire body,而不是原始可缓存前缀。runner 把该声明绑定进 trace 哈希,但无法独立证明调用方此前的计数操作——本地 tokenizer 或 fixture 计数需要显式降级 flag,且不能确立 provider 级输入 ceiling。
preflight 会把所有请求的声明总输入加上精确最大输出求和,得到 declared_billed_token_ceiling,并拒绝超过操作员上限的总体。provider 响应中任一 total input 或 output 超过请求声明值,该请求之后整个 run 失败(replay.go 中 provider_input_budget_exceeded / provider_output_budget_exceeded 两个失败码)。完整 usage 提取要求 provider 原生 input/output 计数器;缺失、歧义、小数、负数或溢出的计数器全部 fail closed。注意边界:声明 ceiling 不是实际 token 上限、美元上限或 provider 发票,因为 provider 处理发生在响应计数器可被检查之前。
Preflight:零 provider 调用
每次运行都要求硬性限制:请求数、声明计费 token、trace 大小、响应大小、并发度、漂移、请求间隔。不带 -execute 时,命令只做校验并打印 trace digest 与调度表:
cd public
go run ./cacheengine/cmd/cache-replay \
-trace /secure/grounded-trace.jsonl \
-max-requests 500 \
-max-declared-billed-tokens 5000000
合成/公开 trace 无法满足 grounded 默认要求。机制测试可以不发流量、选择较弱证据:
go run ./cacheengine/cmd/cache-replay \
-trace /tmp/cachebench-openai.jsonl \
-max-requests 128 \
-max-declared-billed-tokens 5000000 \
-allow-ungrounded-timing \
-allow-estimated-token-budget
preflight 输出(schema caveman.cachebench.replay-preflight.v1)包含:声明总输入、声明最大输出、declared_billed_token_ceiling、timing_grounded、input_budget_claimed_provider_counted、max_concurrency——flag 永远不会重写证据 basis。
从源码结构看,preflight 核心是 replay.go 中的 ValidateReplay:它强制所有 limits 为正数且并发 ≤1024、检查 request ID 去重、时间顺序单调、v3 schema 与 NativeRequest() 可重建性、每请求预算与 body 一致、declared_billed_token_ceiling 不超过 -max-declared-billed-tokens、每个 scaled gap 不超过 -max-gap(默认 10 分钟)。CLI 层的硬边界(main.go 顶部常量):
- trace 路径必须为绝对路径;CLI 接受最多 512 MiB trace 输入与 100,000 个付费请求(
maxReplayTraceBytes/maxReplayRequests); - 库级 trace 解码默认 96 MiB/行、100,000 条记录、64 MiB 请求 body;observation 解码默认 8 MiB/条、100,000 条;
ReadTraceJSONLWithLimits与ReadObservationJSONLWithLimits允许嵌入调用方收紧边界; - verifier 输入与聚合保留工件以有界流方式序列化,而非全量内存 buffer。
活体执行:显式成本接受 + 私有输出目录 + 凭据 + 验证器
live 执行额外要求显式成本接受、全新私有输出目录、provider 凭据和任务验证器:
go run ./cacheengine/cmd/cache-replay \
-trace /secure/grounded-trace.jsonl \
-max-requests 500 \
-max-declared-billed-tokens 5000000 \
-max-concurrency 8 \
-provider-timeout 2m \
-execute \
-accept-live-cost \
-output /secure/cache-replay-2026-08-10 \
-verifier-command /absolute/path/to/task-grader \
-verifier-arg --suite \
-verifier-arg swebench-pinned
源码中 -execute 强制要求 -accept-live-cost、绝对路径 -output 与 -verifier-command(必须是已存在的常规文件),并预先校验 trace 涉及的所有 provider 凭据存在(validateProviderCredentials)。
内置 HTTP transport 支持的 provider
| Provider | 凭据环境变量 | Endpoint |
|---|---|---|
| OpenAI | OPENAI_API_KEY |
Chat Completions 或 Responses |
| Anthropic | ANTHROPIC_API_KEY |
Messages |
| Gemini | GEMINI_API_KEY |
generateContent |
| Bedrock | AWS_BEARER_TOKEN_BEDROCK,或 access key + secret + 可选 session token |
Converse,使用 IAM 时 SigV4 |
transport 安全细节(replay_http.go 的 NewHTTPReplayTransport/authorize,均与文档逐条对应):
- 拒绝重定向;默认 client
Proxy: nil忽略环境代理; - 强制 TLS 1.2+(
tls.Config{MinVersion: tls.VersionTLS12}),逐请求硬超时(1s~1h,默认 2 分钟); - 响应大小有界(默认 16 MiB/请求,
-max-response-bytes可配);凭据绝不写入证据或错误信息; - 出站 body 默认超过 64 MiB 被拒绝(
HTTPReplayConfig.MaxRequestBytes可收紧或最高提到 256 MiB); - 自定义 base URL 需要
-allow-custom-base-url;明文 HTTP 仅对显式 loopback 且带专门测试 flag 允许; - 聚合的 response + verifier buffer 跨 worker 不得超过 1 GiB(CLI 启动时按
(max-response-bytes + max-verifier-output-bytes) × max-concurrency校验)。这约束的是保留 buffer,不约束 provider SDK、内核、JSON 解码器或 verifier 进程内存。
发送前,runner 还会用原始与引擎 eligible 的总体校验目标样本下限;已知的非可缓存引擎决策在网络之前失败,唯一例外是 provider 最低长度 miss——它们保留为报告中的诚实 inelig 样本。调用方自定义 transport 与 verifier 需自行负责连接池、进程资源与更强策略。
任务验证器:stdin/stdout 的严格 wire 契约
verifier 被直接执行,从不经过 shell。每个 provider 响应通过 stdin 送入一个 JSON 对象:
{
"schema": "caveman.cachebench.verification.v1",
"request_id": "openai/session/0002",
"provider": "openai",
"model": "gpt-5.6",
"trace_body_sha256": "<sha256>",
"wire_body_sha256": "<sha256>",
"original_request": {},
"optimized_request": {},
"provider_response": {}
}
verifier 必须恰好输出一个对象:
{
"schema": "caveman.cachebench.verification.v1",
"request_id": "openai/session/0002",
"passed": true,
"verifier": "swebench-harness@immutable-revision",
"evidence": {"instance_id":"fixture","resolved":true}
}
以下情况全部使回放失败:未知字段、重复 JSON key、request ID 不匹配、控制字符、空 verifier identity/evidence、输出超限、超时、非零退出。解析逻辑见 replay.go 的 ParseVerificationCommandOutput(DisallowUnknownFields + 尾随 JSON 检查 + schema/ID 一致性校验)。
环境隔离是源码中值得注意的一点:默认只向 verifier 暴露 PATH、locale(LANG/LC_ALL)与临时目录(TMPDIR);provider 凭据变量(OPENAI_API_KEY、ANTHROPIC_API_KEY、GEMINI_API_KEY、AWS_BEARER_TOKEN_BEDROCK、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN)在 blocked 集合中被硬编码禁止,即使试图通过 -verifier-env 请求也会被拒绝(main.go 的 verifierEnvironment)。stdout/stderr 由 boundedBuffer 限制(stdout 上限 -max-verifier-output-bytes,stderr 64 KiB)。
协议最后一句定调:任务验证器拥有任务语义。请求等价性本身无法替代结果质量。
保留输出:原子写入与部分运行语义
输出目录必须不存在;命令以 mode 0700 创建它,文件原子写入、fsync、mode 0600(实现见 main.go 的 createEvidenceDirectory/atomicWriteStream:临时文件 → Chmod 0600 → Sync → Rename → 目录 Sync):
manifest.json
report.json
replay-summary.json
evidence.jsonl
observations.jsonl
responses/<sha256(request_id)>.json
quality/<sha256(request_id)>.json
evidence/<sha256(request_id)>.json
observations/<sha256(request_id)>.json
每个请求的文件名从不暴露 request ID(main.go 的 replaySink.emit 用 digest([]byte(requestID)) 命名)。摘要哈希绑定 trace body、精确 wire body、保留的 provider 响应、usage 对象与 grader 工件。
replay-summary.json(schema caveman.cachebench.replay-summary.v1)在同一保留证据总体上报告 overall/per-provider 的 p50、p95、p99 与最大延迟(nearest-rank 算法见 SummarizeReplayEvidence),外加绑定到保留 usage 对象的 provider 报告 input/output token 总和。observation.v3 把低于 provider 最低长度的请求保留在总体中,但从 eligible 命中分母中排除。
中断/失败目录仍然是证据。 它绝不会被 resume 到同一总体中:墙钟时间与 provider 缓存状态都已改变。正确做法是开新的运行目录并重放完整总体。部分运行保留失败 manifest 定稿前写出的每请求工件与聚合 JSONL;completed_requests 计数发出的证据记录(含失败项);部分 observation 无法通过精确 trace join。退出码语义:manifest.json 记录 status: running/failed,gate 失败进程退出 1(见 main.go 末尾 os.Exit(1)),配置错误 2、运行时错误 3。
证据边界:publishable 恒为 false
协议以一句硬边界收尾:provider 观察到的通过只证明所提供的总体(population)。它仍不证明生产环境流行度、被省略的尾部、发票支出或 caveman 的已验证节省。因此 publishable 保持 false——main.go 中 manifest 的 EvidenceBasis 常量即写明 "provider_observed; retained responses and external task-verifier artifacts; never verified savings"。这与 cachebench README 的立场一致:模拟基准与活体证据始终是两份独立报告,provider-observed pass 之后的“生产普遍性/发票支出/已验证节省”属于 managed-ledger 工作范畴。
小结
| 阶段 | 命令/入口 | 证据强度 |
|---|---|---|
| 本地模拟 | go run ./cacheengine/cmd/cachebench |
benchmark_simulated,零 provider 调用 |
| Preflight(零流量) | cache-replay 不带 -execute |
仅校验 + trace digest + 调度摘要 |
| 活体回放 | cache-replay -execute -accept-live-cost ... |
provider_observed,保留全量响应与 grader 工件,但 publishable: false |
cache-replay 的整套设计可以概括为一句话:宁可让证据失败(fail closed),也不让证据变弱。绝对时间调度、无重试、发送前全量等价校验、声明计费 ceiling 与 provider 计数器双向核对、verifier 环境沙箱、哈希绑定的保留工件——每一环都在把“缓存命中率 97%”从一张嘴说出的数字,变成可复算、可审计、且明确知道自己边界在哪的 provider 级证据。相关实现可继续深入 replay.go(runner 与证据校验)、replay_http.go(transport)、trace.go(v3 读写与预算校验)以及测试 replay_test.go(如 TestReplayRunnerProducesBoundObservedPopulation 验证的绑定不变式)。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00