fast-jev-compaction:用Jev决策重构Claude Code有损压缩
先说个我上周差点崩掉的现场用 Claude Code 跑一个跨十几个文件的重构任务会话到四十多轮触发了自动 compact。等它压缩完我继续往下对话结果模型开始乱改命名规范还把我已经在代码里确认过的边界条件当成新问题重新提了一遍。回头看压缩产生的摘要文本才发现问题不是模型变笨了而是上下文在压缩那一刻就已经被“有损”掉了。也就是从那时起我开始认真研究 fast-jev-compaction 这套方案不用 LLM 做有损摘要而是用 Jev 决策的方式重构 Claude Code 的上下文压缩。先说这套东西是什么、适合谁如果你平时用 Claude Code 做长会话、批量代码重构、自动化多步骤任务被 compact 之后“失忆”坑过那这篇文章值得看完。我会从传统摘要为什么容易丢信息讲起说清楚 Jev 到底在决策什么再给出接入 Claude Code 的完整实操路线和问题排查记录。1. 问题根源为什么说传统 LLM 摘要是有损压缩1.1 一次被摘要坑掉的完整任务现场先说那个重构任务的细节方便你对照自己踩过的坑。我当时让 Claude Code 做的是把项目里一套旧的状态管理逻辑迁移到新的数据流架构上涉及文件多、耦合重而且我已经在会话中明确和模型对齐过几次关键约束旧模块里的resolveState函数要继续保留但对外只暴露新接口部分历史字段要兼容到下一版本再废弃有几个边界条件之前已经排查过结论是“不需要处理”并备注了原因。在 compact 之前这些信息确实都在上下文里模型也好好的。触发压缩之后模型给我的回复开始出现一种典型的“失忆感”它不知道resolveState是保留对象于是主动提议“把这个函数重命名并重构”它不记得那几个边界条件已经排查过又开始一本正经地提出要加防御逻辑。我一开始以为是 Claude Code 温度或者模型版本问题直到我去翻了~/.claude/projects下的会话日志找到 compact 时生成的摘要原文才发现它不是不知道这些信息而是这些信息在摘要里被直接抹掉了。摘要文本本身写得很通顺把“我们在做状态管理迁移”讲得像模像样但具体到哪个函数保留、哪个边界不被处理、哪个约束不能被破坏全都没留下来。这个场景最有意思的地方在于摘要模型不是故意坑你它只是在做它最擅长的事——把对话“讲成一个完整的故事”。可问题恰恰出在这里聊天记录需要的是故事性而 agent 上下文需要的是可执行性。这两者根本不是一回事。1.2 有损摘要的三大致命伤传统做法的问题可以归结成三点第一信息密度选择由模型临时决定不稳定。同一个会话连续触发两次 compact产出摘要的逻辑可能完全不同。第一次它觉得“函数名重命名”是重点第二次它觉得“架构迁移目标”是重点。这不是模型笨而是摘要任务本身缺少一个明确的保留优先级。模型在逐 token 生成时靠的是语义通顺度和注意力权重而不是“后续任务执行需要什么”。于是高价值但孤立的细节很容易被当作冗余信息丢进垃圾桶。第二摘要会“顺滑处理”矛盾点。真实开发会话里有很多未完成事项、冲突结论、临时方案。这些信息在原文中是直白的、带刺的。但摘要模型写出来的文本有一种天然倾向把矛盾抹平、把未完成的部分绕过去让上下文看起来“更清晰”。可是对 agent 来说那些未完成事项恰恰是它下一步行动的入口。摘要一顺滑入口就没了后续决策全部失去锚点。第三也是最要命的摘要模式下后续决策只基于摘要文本原始信号无法回溯。一旦压缩完成旧消息被清出上下文窗口模型手里只有一份“二手转述”。它没有原始代码片段、没有原始对话语气、没有你当时敲下的精确约束。后续如果你追问“我什么时候说过不处理这个边界”它答不上来因为它手里只有那份被加工过的故事没有原始档案。联系到最近社区里频繁讨论的“LLM 的 token 三个点key 我是谁、query 我在找什么、value 我能提供什么”传统摘要的问题就看得更清楚了。摘要模型把 key、query、value 混在一起重写没有区分哪条消息承担的是“身份定位”功能哪条是“当前诉求”功能哪条是“知识供给”功能。它统一当作“文本素材”处理结果就是对后续任务而言最关键的 query 来源被稀释了value 携带的结构化信息被故事化key 的连续性被切断了。2. Jev 决策从“重写摘要”到“结构化取舍”2.1 Jev 到底在决策什么Jev 这个词在不同语境下含义有差别。在 fast-jev-compaction 这个项目语境里它并不是又一个“更大更强的摘要模型”而是一套压缩时的取舍机制。用标题里的话说就是“Jev 决策”——它把压缩这件事从“让模型写一段好读的文字”变成“让系统做一次结构化的取舍决策”。它的核心逻辑正好对应上面说的 token 三元模型。压缩器在拿到一段上下文时先给每条消息或每个信息块打标签key这条消息是谁发起的是用户、是工具输出、还是模型中间推理它承担什么身份角色query这条消息在找什么它提出了什么诉求、期待什么回应value这条消息能提供什么它包含哪些事实、约束、代码片段、决定、待办打标完成之后压缩器再做决策高价值 query 对应的上下文片段必须完整保留因为后续行动要靠它导航被多次引用过的 value不能只留一句概括要保留原始描述哪怕节省 token 也要忍住纯寒暄、重复确认、与当前任务相关性低的片段优先丢弃key 的身份链要保留也就是“谁在什么角色下说过什么”否则后续 agent 分不清约束来源和权限边界。这套逻辑最厉害的地方在于它把压缩目标从“让摘要读起来顺”变成了“让下一次决策还能做出来”。生活化类比一下传统摘要像是你把一份施工图纸交给别人让他口头转述给施工队“我们在建一个房子”Jev 决策则像工地交接班谁负责什么、当前做到哪、哪些问题不能碰、哪个地方有隐患一条条对照着交接。后者不好看但好使。2.2 和传统摘要的关键差异拿一张表把区别列出来方便你对号入座对比维度传统 LLM 摘要fast-jev-compaction / Jev 决策保留对象语义通顺的“故事梗概”带 key/query/value 标签的结构化决策链信息失真点孤立细节、矛盾点、待办项被抹掉低价值片段被主动丢弃但高价值片段保留原始文本Token 成本取决于摘要模型生成长度通常固定输出按信息块评分动态取舍可配置阈值控制回溯能力压缩后几乎无法恢复原始细节通过保留关键原文和引用关系支持局部回溯对后续决策影响后续模型只能基于二手转述推断后续模型直接基于可执行的约束和待办继续推进主要风险信息悄悄丢失丢失点难以发现如果评分规则配置不当可能误删“看似无用但隐含重要”的文本我用下来最深的体会是它的核心差异不在模型更强而在压缩目标的定义方式变了。从“生成式压缩”变成“抽取排序 决策式压缩”模型承担的任务从写作者变成了裁判员。写作者当然可以把文字写流畅但裁判员知道哪些东西上场哪些东西下场。顺带说一句现在社区里也有“spatial LLM”“记忆池”这类方向的探索思路本质类似给上下文增加空间感或分级记忆不再把它当成一条平面文本流。fast-jev-compaction 更聚焦它只解决 compaction 这个具体时机点上的问题——压缩发生前怎么筛选压缩后留下什么。想折腾记忆系统的朋友也可以从它入手找到感觉。3. fast-jev-compaction 实操从安装到接入 Claude Code3.1 先搞清楚 Claude Code 的压缩机制实操之前得先弄清楚 Claude Code 默认的 compact 是怎么触发的。长会话上下文接近窗口上限时Claude Code 会自动执行一次 compact也可以在会话里手动输入/compact强制执行。默认流程就是把当前会话记录交给模型生成一段摘要文本然后清掉旧消息用摘要作为后续对话的基底。我自己建议你在动手接 fast-jev-compaction 之前先做一次基线检查。具体方法打开一个长会话的日志目录通常在~/.claude/projects/下找到对应项目的.jsonl会话文件搜compact相关的记录把压缩前后文本都看一遍。这一步非常重要它能让你直观感受到“压缩丢了什么”。我当初就是看完日志才发现很多丢失不是“被 rewrite 了”而是“根本没进摘要” —— 这些信息连被讨论的资格都没有直接就蒸发了。3.2 本地部署 fast-jev-compaction 的最小步骤标题里叫 fast-jev-compaction社区里通常以本地工具/服务方式运行。我这里给一套通用、可落地的最小部署流程具体命令以你 clone 到的仓库 README 为准把项目拉到本地git clone 仓库地址 fast-jev-compaction cd fast-jev-compaction安装依赖通常用 Python 或 Node 生态直接看仓库里的requirements.txt或package.json配置模型接入在.env或环境变量里指定压缩器的模型端点启动服务或命令行入口让它监听本地端口这里补充一个极其重要的经验fast-jev-compaction 这种压缩器并不是非要接和 Claude Code 同一个模型。你完全可以用更便宜、更快的模型来跑“筛选-评分-保留”这些决策操作让高价模型专注于真正的生成和推理任务。这样既省钱又能把决策逻辑稳定在一个可复现的配置里。我测试下来把决策和生成拆开比所有事都堆在一个模型里可控得多。3.3 接入三种主流模型的路线图接入 Claude Code 的时候你面前大致有三条路线我从省事到折腾排个序。路线 A继续用 Claude 官方模型只替换压缩器实现方式。也就是说Claude Code 本身还是走官方 API但压缩动作从“默认摘要”换成“调用本地 fast-jev-compaction 服务获取筛选结果再交给会话”。这种方式最稳不改变原有网络路径只是改变压缩时生成文本的逻辑。路线 B通过 LM Studio 跑本地模型把 Claude Code 的基础地址指到本地端点。社区里很多人喜欢这么玩因为本地部署确实省心还能避开云端费用。需要在 Claude Code 的环境变量里设置类似ANTHROPIC_BASE_URL指向http://localhost:1234/v1并配上对应的认证 token。但这里有几个大坑本地模型上下文窗口普遍比云端小如果模型本身不支持足够长的上下文压缩器接上去之后反而会提前触发窗口截断另外部分本地模型对 Anthropic 风格的工具调用 schema 支持不完整后面我会专门讲这个报错。路线 C用 cc-switch 这类第三方切换工具接 DeepSeek、Qwen、GLM 等模型。cc-switch 本身是可视化管理供应商配置的工具可以做到不同模型之间快速切换。实际场景里很多人是把 fast-jev-compaction 的决策模型和 Claude Code 的主模型分开配主模型走一种供应商压缩器走另一种。这样能充分利用各家模型的价格差异和上下文能力差异。不管走哪条路线我都建议你把“主模型”和“压缩器模型”分开对待。它们俩的任务形态完全不同——主模型要写代码、推理方案压缩器要做取舍和评分哪一部分用哪个模型、给多大的上下文窗口这是一个值得精细调配的优化点。4. 压缩效果实测与参数调优4.1 一个 300 条消息会话的实测案例我拿一个大约 300 条消息、涉及 6 个文件重构的真实会话做了对比。压缩前我先手动从日志里整理出 23 个“关键决策点”包括明确的代码约束、待验证项、用户强调过的边界、未完成的 TODO、已经被否决的方案。传统摘要压缩之后我从摘要文本里反查这 23 个关键点能找回来的只有 6 个而且其中 2 个是模糊提及不是精确表述。令人意外的是摘要却新增了 3 个原文里从来没出现过的“建议”也就是模型自己脑补出来的内容。这就是典型的对齐失败。fast-jev-compaction 处理同一份日志之后23 个关键点找回来 19 个丢失的 4 个集中在一段非常长的错误排查记录里——那段记录本身重复信息太多评分器把它整体降权了属于可以接受的误伤。但原来那 3 个脑补内容没有出现因为它不是生成式重写而是基于原文标签筛选。指标传统摘要fast-jev-compaction关键点保留数共 23619脑补内容出现数30压缩后 Token 消耗略高可控动态取舍回溯原始信息能力无保留引用关系可局部回溯当然这是一个偏正面的案例样本就一次不能代表所有场景。但至少验证了核心问题同样的上下文不同的压缩策略对后续决策质量的影响是数量级的差别。4.2 调参心得与 Token 成本估算fast-jev-compaction 这类工具实际用下来主要调几个参数保留优先级阈值决定一段文本得分多高才被完整保留。阈值设得太高会丢细节太低压缩就没意义。最小保留片段长度有些信息块很短但很重要比如“用户说了不要动 resolveState”。这类短片段必须设一个较低的最小长度保护否则会被当作噪声丢掉。低置信度消息丢弃策略模型对自己评分没把握的消息可以走“二次确认”而不是直接丢弃也可以选择降级为一行摘要。白名单关键词像“待办”“BUG”“blocker”“不要”“不能”这些词一旦出现对应片段强制保留。我强烈建议你在自己的领域里维护一份这样的白名单效果立竿见影。Token 成本方面可以按这个公式粗算压缩成本 ≈ 被压缩的原始 Token 数 × 单 Token 决策计算量 保留片段的重组开销举个例子一个会话有 12 万 Token压缩器需要扫描全部文本来做决策。如果决策模型的处理效率是每 Token 成本极低的那种压缩一次的成本会明显低于让主模型重新生成一次 8000 Token 摘要的成本。而且这笔开销是一劳永逸的——它买来的是后续 50 条消息不再因为失忆而返工。5. 常见问题与排查实录5.1 请求报错provider rejected the request schema or tool payload这个报错我见到太多了社区里也在疯狂讨论。核心原因通常是Claude Code 默认发给模型的消息里带了 Anthropic 风格的工具调用 schema而你在压缩器上接的是第三方模型或本地模型对方不支持这套 schema直接拒了。排查思路先看日志里是不是在 compact 前一刻发出的请求。如果是基本确认是压缩器与主模型之间的 schema 不兼容。解决办法之一在压缩器配置里关闭工具回传只让模型处理纯文本压缩任务。办法之二换一个兼容性更好的供应商配置把工具调用格式改成目标模型支持的 JSON 风格。办法之三给压缩器单独配一个更“克制”的模型不启用工具能力。这类问题最烦人的点在于报错可能不是稳定复现而是隔几次才出现一次。我的经验是一旦出现第一时间确认是不是工具 schema 问题而不是怀疑网络或授权能省下大量排查时间。5.2 订阅限制与区域可用性提示有人会碰到两类提示一个类似 “your organization has disabled claude subscription access for claude code”另一个类似 “claude code might not be available in your country. check supported countries”。这两者性质不同但处理路径都是要先确认账号的订阅状态和组织的访问策略。前者多是企业版/团队版的后台开关问题需要找管理员开权限后者属于服务可用性问题以官方支持范围为准不建议想任何偏门办法正常做法就是确认自己的账号区域与订阅类型是否符合目标服务的要求。我个人的建议是这种账号层面的问题不要在技术配置上反复折腾最有效的永远是去官方文档确认支持的账号类型和订阅策略或者直接找管理员开通访问。5.3 接本地模型之后压缩上下文反而更短了有一种很误导人的情况明明给压缩器配了一个很大的本地模型结果 compaction 之后上下文长度反而暴跌甚至主线任务开始频繁断片。原因基本跑不出这几个本地模型的 context window 配置不对上下文压缩时模型被强制要求输出固定长度或者模型的 KV Cache 占用导致实际可用上下文远小于标称值。检查方法很直接去看压缩前后会话文件里记录的 token 数变化如果压缩后 token 数比压缩前还少一个数量级大概率是压缩器在死板地按配置输出固定长度而不是按内容决策取舍。我遇到过最典型的一次是本地模型标称 128K 上下文但实际因为聊天模板格式从 128K 直接缩水了四分之一压缩器还能用但主模型的毫秒级决策链受到了挤压。解决办法是给压缩器模型单独开一个端口和一套配置不要和主模型抢同一个上下文空间。5.4 VSCode 插件与终端环境变量不一致Claude Code 可以跑在终端里也可以集成到 VSCode 使用。很多人折腾完终端配置之后发现 VSCode 里的行为没变特别困惑。原因十有八九是VSCode 插件进程没有继承终端里的环境变量。你在.zshrc或.bashrc里设置了ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN终端生效了但 VSCode 是从桌面启动的根本不会读取 shell 的配置文件。解决路径有两个要么把环境变量写到系统层面或 VSCode 的 settings 里要么在 VSCode 里重新启动集成终端确认变量存在后再拉起 Claude Code。我这边的习惯是所有模型接入配置尽量用工具自身的管理界面比如 cc-switch来维护少依赖 shell 环境变量这样跨终端、跨编辑器都能保持一致少一次排查就多一次愉快编码。最后再分享一个小技巧我之前一直以为“压缩后效果差”只能靠调压缩器参数来缓解直到有一次在 compact 之前我习惯性让 Claude Code 先输出了一份结构化的“交接清单”把当前任务的上下文浓缩成“目标 / 已完成 / 未完成 / 不可触碰约束 / 待验证项”五段。然后 fast-jev-compaction 基于这份清单做决策压缩保留率一下高了很多。后来我复盘才想明白Jev 决策再强也需要上下文里有“像样的 key、query、value”供它识别。如果你平时对话记录本身就松散、重复多那再好的压缩器也是在垃圾堆里淘金。反过来如果你在平时就维护好结构化的任务表达压缩器只是在帮你把金子留下来。还有一个经验压缩之后不要立刻闷头继续干花几秒钟读一遍压缩结果确认那些关键约束还在。这一步只需要十秒但能帮你避免模型在错误基座上跑出半小时无效工作。踩了几次坑之后我已经把它当成和/compact配套的固定动作了。