Caveman rewriter:确定性门控与 CCR 恢复标记支撑的 Agent 轨迹压缩模块

Caveman rewriter:确定性门控与 CCR 恢复标记支撑的 Agent 轨迹压缩模块 Caveman rewriter确定性门控与 CCR 恢复标记支撑的 Agent 轨迹压缩模块【免费下载链接】caveman why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/cavemanCaveman 的rewriter包是一个引擎联动的反思式改写器reflection rewriter它让一个 Agent 看不到的外部 LLM 去压缩历史轨迹中已经老化的步骤再用一套确定性的生存survival门控、token 节省门控和 CCR 恢复门控决定是否放行。读完本文你能理解该模块的 AgentDiet 式双阈值θ500门控设计、ccr:…恢复标记契约、拒绝原因全集以及它在 Caveman 上下文压缩体系中的定位与边界。模块定位压缩老区而非缓存响应rewriter/README.md 将本模块定义为Engine-linked reflection rewriter for compressing aged trajectory zones behind deterministic survival, token, and CCR recovery gates——即针对 Agent 转录中较旧、价值较低的区域做压缩且每次放行都必须同时通过三类确定性门控生存门控survival原文中存在的失败信号、计数、退出码、源码位置在改写后必须全部存活token 门控改写必须比原文节省超过 θ 的 token否则宁可不用CCR 恢复门控被接受的改写末尾必须携带一个可解析的恢复指针指向 CCR 存储中的原始字节。rewriter/rewriter.go 的包注释说明该机制源自 AgentDietarXiv 2509.23586但被参数对参数地搬进了一个 wire proxy 而非 agent loop外部改写模型是 Agent 永远看不到的滞后 a2 步、额外上下文 b1 步双 θ500 门控且遵循rewrite-never-delete删除的文本必须被一句简短摘要取代而不是留空。与 Caveman 另一套系统——prompt-cache planner——的分工见 docs/technical/cache-and-rewriter.md缓存规划器处理精确复用稳定 provider 前缀轨迹改写器处理缩短旧对话历史两者可以共存但任何一方的证据token 估算、改写模型花费、下游模型质量都必须分开计量。构建 ClientConfig 与参数校验Client面向单一 provider 模型组合构造入口是New(Config)支持并发使用。配置结构定义在 rewriter/rewriter.go字段说明取值/默认Provider只接受anthropic或openai大小写不敏感未知 provider 直接报错不做静默默认Model改写模型名如claude-haiku-4-5、gpt-5-mini必填非空APIKey改写模型的凭据必填非空Theta双门控阈值token默认DefaultTheta 500禁止负数HTTPDoer可注入的 HTTP 执行函数nil时用http.DefaultClient.Do测试用它注入 fakeNew的校验逻辑rewriter/rewriter.go刻意拒绝优于默认未知 provider 是错误而不是降级因为一个被静默错误路由的改写器会产出没有任何门控为其设计过的字节。TestNewValidationrewriter/rewriter_test.go覆盖了未知 provider、空模型、空 API key、负 θ、大小写 provider 五类输入。调用方典型用法依据测试中的真实调用形态整理client, err : rewriter.New(rewriter.Config{ Provider: anthropic, Model: claude-haiku-4-5, APIKey: os.Getenv(ANTHROPIC_API_KEY), // Theta: 0 → 使用默认 500 }) res, err : client.Rewrite(ctx, rewriter.Request{ StepBytes: agedStep, // 滞后 2 步的目标步骤 ToolName: Bash, WindowBytes: [][]byte{prev, agedStep, next, newest}, // a2/b1 窗口 })单次改写流程Rewrite 的完整决策链Rewriterewriter/rewriter.go是唯一的业务入口其内部链条为门控 1invocation gate用本地 token 计数器估算StepBytes的 token 数 θ直接返回below_theta完全不调用 provider APIrewriter/rewriter.go。测试TestRewriteThetaBoundary专门验证边界语义恰好等于 θ 时跳过多 1 个 token 才发起调用对应 AgentDiet Algorithm 1 的第 17 行。模型调用输出上限由outputCeiling决定——原文 token 数夹在minOutputTokens256与maxOutputTokens16384之间。上限的依据是改写合法情况下不可能比原文更大所以原文自身 token 数就是诚实的天花板撞上天花板truncation是拒绝而非静默截断。截断检查如果 provider 的停止原因是max_tokensAnthropic或lengthOpenAI即使已到达的字节看起来完整也拒绝gate_failure_truncated。包注释解释得很直白被截断的尾部正是本应保留的失败所在而门控无法看见缺失的东西rewriter/provider.go。形态检查空内容gate_failure_empty、回显了step包裹gate_failure_step_wrapper、不配对的外层 markdown 围栏gate_failure_fence。配对的围栏会被剥除——改写块允许在正文内部合法包含围栏rewriter/rewriter.go。门控 2application gate 保真检查把模型正文加上恢复指针后交给纯函数Accept判定gate_failure_tokens及下述保真原因。放行只有Acceptedtrue的Result才携带字节其余所有路径Rewritten恒为空。Result的结构rewriter/rewriter.go值得逐字段看type Result struct { Rewritten []byte // 含末尾恢复指针行未接受时为空 Accepted bool RejectReason string // 未接受时的原因见下表 InputTokens int // 改写模型自身的 provider 计量用于成本轧差 OutputTokens int CandidateTokens int // 模型产物的推断尺寸被拒调用也上报 }拒绝原因全集gate.go的 reason 常量 Result文档RejectReason含义below_theta步骤 ≤ θ token未发生 API 调用api_error传输错误、非 2xx、响应不可解析gate_failure_truncated完成体撞上输出上限gate_failure_step_wrapper模型回显了step信封gate_failure_fence不配对或带尾随散文的围栏gate_failure_empty空或仅空白gate_failure_tokens节省量未超过 θgate_failure_failure_signal丢失失败信号词gate_failure_failure_detail某条独立的失败行消失gate_failure_count失败/警告计数被改写gate_failure_exit_code非零退出码丢失gate_failure_reference源码位置/引用丢失诚实计量是模块的硬约束InputTokens/OutputTokens是改写模型自身 provider 报告的 usage被拒的调用也照常上报钱已经花了而任何用本地计数器估算的数字都被视为inferred估计值绝不冒充 provider 计量。反思提示词PromptVersion 与四类结构rewriter/prompt.go 复现了 AgentDiet 的四段式反思提示任务描述## Your job分析并改写一个轨迹步骤使其以更少 token 携带同样的决策相关信息明确你不解题、不建议 AgentAgent 不知道你存在会把你的改写当作原始工具输出读。输入输出格式## Input and output format输入是一串用step id…包裹的连续步骤只有一步被标名为 target前后步骤只是上下文用于判断哪些内容仍然承重。输出只允许目标步骤的正文——无前导说明、无围栏、无step包裹。三类浪费## The three kinds of wasteUSELESS构建闲话、进度条、listing 里的__pycache__/.git条目、依赖解析噪音、重复横幅REDUNDANT窗口其他位置已存在的内容——编辑器工具回显刚写入的文本、两步前已检索过的文件体、逐文件重复的警告EXPIRED产生时重要、现在不再重要——Agent 已把候选缩到一个文件的 grep 全量 listing、已经下结论的环境探测。准则## Guidelines: condense, never delete删掉的区域必须用一句 takeaway 顶替如individual test lines omitted; 214 PASSED失败必须逐字保留FAIL/ERROR/exception/traceback/panic/fatal 行、非零退出码、其上的路径行号列号标识符测试名、符号、哈希、版本、flag、URL不得规范化或缩写Agent 尚未处理的内容未应用的 diff、未读的输出必须保留无安全可压内容时原样返回是正确答案有损改写不是。buildUserMessage把窗口渲染为step ids-2这样的编号id 从最新步骤倒数对应论文的 s / s-1 / s-2 记号目标步在 a2 窗口里是 s-2。一个防御细节若StepBytes不在WindowBytes中窗口会被丢弃、目标步骤单独呈现——调用方侧的不一致绝不能演变成改写了不是交给它的那一步rewriter/prompt.go。PromptVersion目前是1且有一条硬性存储契约任何内容寻址的改写缓存必须以SHA-256(stepBytes) || PromptVersion为键绝不能只用 step 哈希——否则提示词一改旧版提示词生成的改写会被继续回放仓库就会悄悄混入两种被 replay 网格分别定价过的机制的输出rewriter/prompt.go。任何对系统提示词或 user-message 渲染的修改都必须 bump 版本号。确定性接受门控Accept 的六层检查Accept(original, rewritten, theta)是纯函数——无时钟、无网络、无状态——离线 replay 网格用同一个函数重评分捕获语料因此离线判定与线上判定不可能分叉rewriter/gate.go。检查顺序是形状 → 节省 → 保真节省检查放在保真之前因为节省不达 θ 的改写无论保留了多少东西都会被拒AgentDiet Algorithm 1 第 22 行报告gate_failure_tokens比报告恰好先触发的某条保真规则更有用。1. 失败信号词failureNeedles17 个大小写不敏感的探针fail、error、exception、traceback、panic、fatal、warn、err!、not found、no such file、timed out、timeout、segmentation、core dumped、killed、aborted、conflict、denied、refused、unable to、cannotrewriter/gate.go。原文含而改写不含即拒。故意偏召回over-inclusivefail同时覆盖 FAILED/Failure/failingpanic覆盖 Rust 的 panicked at。误杀只让门更严而漏放才是真正的事故类别。2. 计数保活countscountPattern抓取5 failed/1 error/3 problems这类数字名词 tally且必须带数字整体存活词边界匹配1 failed不能被21 failed顶替。两个形状被刻意排除数字前不能是冒号或点eslint 的8:1 warning列号和版本号不算 tally空白只认水平空白行尾数字换行接 error: 不算 tally——排除依据是探针语料中确实产生过这两类假 tallyrewriter/gate.go。3. 非零退出码exitStatusPattern匹配exit code N/exit status N两种拼法只有非零码承重exit code 0不携带任何 Agent 需要处理的失败。存活检查按词边界所以把exit code 1改写成exit code 12会被gate_failure_exit_code打回测试TestExitCodeSurvivalIsWordBounded。4. 源码位置无条件保护sourceLocationPatterns有四条正则覆盖主流工具链的位置形态rewriter/gate.gopath.ext:line[:col]:line后缀必须存在无位置的裸路径只按失败行保护否则每个被提到的文件名都会被冻进块里无扩展名Makefile:12冒号前必须有字母避免把时钟14:03:22误认成位置tsc/MSVC 的path.ext(line,col)CPython traceback 的File …, line N。这些位置在整个块内任何位置都受保护不仅限失败行——大多数工具链go build、tsc、gcc、rustc、eslint把位置放在没有信号词的独立行上按失败行圈定保护范围会让恶意改写从这条缝里溜过去。5. 失败行引用bare references无位置的裸路径和 eslint 式12:5坐标只在承载失败信号的行上受保护——省略ok pkg/foo 0.01s正是这个组件要赚的节省。6. 失败明细行保活一个泛词如 error不能顶替多个不同失败。每条原始失败行去首尾空白后必须在改写的失败行集合中逐字节存活只允许前缀追加改写器可以给它加上被保留的源码位置不允许后缀冒充rewriter/gate.go。对抗性回归语料rewriter/gate_test.go 内置了 15 行已知敌意改写——由针对早期门控的对抗性探针生成早期门控曾全部接受这 15 个改写。覆盖 go build 编译诊断、rustc 箭头位置-- src/parser.rs:88:21、Rust panic、Python traceback、语法错误帧、eslint 裸坐标、npm ERR!块、command not found、集成超时、段错误、git merge 冲突、Java 栈帧、tsc 括号位置、失败计数被毁5 failed写成1 failed、警告计数被毁3 warnings写成1 warning。反向对照TestAcceptStillFlipsRealWaste则验证门控没有严到失用pytest 通过量批量省略、__pycache__listing 缩减、go vet ok 行省略这三类真实浪费都能被接受。一个值得记住的推论rewriter/gate.go 与rewriter.go包注释警告密集型块如 200 条警告的编译器日志在无条件位置保护规则下会永久不可翻转——保留全部 200 个位置必然压不过 θ。这是刻意发布的取舍开例外只有在 replay 网格把这类块定价为有分量之后才站得住脚。CCR 恢复标记调用方拥有的契约被接受的改写末尾固定追加一行恢复指针rewriter/rewriter.go[condensed by caveman; original recoverable via ccr:ccr_9f2c…]语法与 Caveman 代理压缩路径发出的标记一致proxy/internal/gateway的appendCCRMarker也由 retrieve 工具消费。句柄由ccr.Handle生成——对原始字节取 SHA-256取前 16 字节的十六进制编码加ccr_前缀engine/ccr/store.go测试TestRecoveryPointerUsesTheEstablishedMarker验证了 handle 前缀与ccr:…可解析性。包注释用大写字母强调了调用方必须履行的契约调用方必须在改写上 wire 之前先用ccr.Handle(StepBytes)作为键把原始字节持久化进 retrieve 路径可达的 CCR 存储。一个句柄解析不到任何东西的标记比没有改写更糟——它告诉 Agent恢复存在而实际上不存在。恢复指针最坏的情况应当是多一轮可见的恢复往返而不是静默丢失。Provider 接入两个适配器与诚实计量rewriter/provider.go 只实现两个 providerAnthropicOpenAI端点/v1/messages/v1/chat/completions认证x-api-keyanthropic-version: 2023-06-01Authorization: Bearer …输出上限字段max_tokensmax_completion_tokens停止原因stop_reasonfinish_reason一个容易被忽视的实现细节是 temperature 的分歧处理Anthropic 侧固定temperature: 0OpenAI 侧对推理档模型gpt-5*、o1/o3/o4*前缀族主动省略 temperature 字段——这些模型拒绝任何非默认 temperature而gpt-5-mini正是论文自选的改写模型、也是本模块文档化的 OpenAI 模型盲目发temperature: 0会让每次改写都 400。确定性要求改由提示词承担rewriter/provider.go、rewriter/provider.go测试见 rewriter/rewriter_test.go。传输层防御响应体上限 4 MiB超限报错response exceeds …错误体回读上限 4 KiB只用于诊断不落盘注入的 doer 返回 nil 响应/nil body 会表现为错误而非在代理热路径上 panic测试TestProviderResponseIsBounded。Token 计量基准估计值不是 provider 数rewriter/tokens.go 一行实现countTokens使用engine/tokens.Default()——离线 o200k_base BPE 编解码器嵌入词表加载失败时回退 chars/4。两级 θ 门控与接受门控都在这把尺子上测量使得replay bench 定价为正净节省的改写与本门控接受的改写是同一个改写。模块的计量诚实原则由此闭环Result里唯一经过测量的数字是InputTokens/OutputTokens来自改写模型自己的 usage 块其余一切本地计数都是 inferred 估计。命名非保证门控不防什么包注释专门列出两条命名非保证named non-guarantees对集成方决策很重要rewriter/rewriter.go附加性虚构无法被捕获。所有门控检查都是生存检查——证明原文里存在的东西在改写里仍存在没有任何约束限制模型添加了什么。一句虚构的安慰the remaining failures are unrelated能通过全部检查。对它的防线是线上 Δturns 的伤害触发器不是这个门控。警告密集块永久不可翻转如前所述是刻意发布的取舍。许可BSL-1.1Change Date 2030-06-21rewriter/README.md 的许可声明与 rewriter/LICENSE 一致源码以Business Source License 1.1发布是 source-available在 Change Date 之前不是OSI 意义的开源。关键条款rewriter/LICENSE许可方Julius BrusseeLicensed Work 为 Caveman Engine (c) 2026Additional Use Grant允许对自有第一方流量做内部评估、本地开发、CI 测试、集成与自托管生产使用不允许将其或其功能作为托管、管理或嵌入式服务提供给第三方——该用途需要单独的商业许可Change Date2030-06-21Change LicenseApache License 2.0。更完整的许可策略见仓库根目录 LICENSING.md。相关文档与延伸阅读rewriter/README.md模块定位与许可声明本文骨架rewriter/rewriter.go包契约、Rewrite主流程、Result语义rewriter/gate.goAccept全部检查与正则rewriter/prompt.go系统提示词四段结构与PromptVersion契约rewriter/provider.go / rewriter/tokens.goprovider 接入与 token 基准rewriter/rewriter_test.go / rewriter/gate_test.go接受/拒绝/对抗回归的完整测试矩阵engine/ccr/store.goccr.Handle内容寻址句柄docs/technical/cache-and-rewriter.mdrewriter 与 cache planner 的选型对照适用前提小结该模块是库级组件改写需要显式配置模型与凭据、不可离线运行对照表见 docs 中Work offline → Cache planner or Engine; not trajectory rewriter被拒改写永不进入 Agent 上下文但拒用尝试的 provider 花费仍会被上报改写产物是模型生成的文本而非无损编码调用方在宣称质量等价之前仍需任务级评测。【免费下载链接】caveman why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/caveman创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考