- 人工智能
- AI Agent
- AI 插件
- Agent 记忆
【免费下载链接】fast-jev-compaction
Claude Code plugin that replaces the compaction summary with Jev decisions: every tool call and result is scored in one fast request, stale ones are dropped or truncated, everything kept stays verbatim.
本文介绍 fast-jev-compaction 仓库中的 Claude Code 函数钩子(function hooks)模块:它通过session.compact与turn.complete两个钩子,把 Claude Code 默认的"总结式压缩"替换为 Jev 模型对每条工具调用与工具结果的逐项取舍决策,保留内容原样(verbatim),仅删除或截断被判定为不再需要的工具调用与结果。读完本文,你将掌握该插件的安装启用方式、全部配置项及其含义、运行时兜底与诊断机制,以及薄适配层hooks/fast-jev.ts与核心库src/之间的协作原理。
插件定位:只删不改的压缩
绝大多数上下文压缩方案会请 LLM 总结旧轮对话,而总结是有损的:一个文件路径、一条精确报错、一个约束或一条命令,即使之后仍然关键,也可能在总结中消失。fast-jev-compaction 从不改写任何内容——它只删除 Jev 判定为不再需要的工具调用和工具结果,并且在询问 Jev 时把完整对话作为state展示给它(工具输出被替换为一行说明)。用户与助手(user/assistant)的文本永远保持原样且顺序不变。
hooks/fast-jev.ts是一个薄适配器(thin adapter):它读取插件选项、找到 TypeSafe 密钥、把session.compact的会话转录(transcript)交给仓库根目录src/下的fast-jev-compaction库(插件目录就是仓库根目录,所以钩子可以直接 import),再把库的返回结果映射回会话消息。对应钩子入口在 hooks/hooks.json 中声明为./fast-jev.ts。
安装与启用(依赖函数钩子早期功能)
函数钩子是 Claude Code 的早期访问(early-access)能力。仓库内检入的类型参考(type reference)由 Claude Code2.1.274生成,位于 types/claude-code.d.ts。在安装或加载该插件之前,必须先启用函数钩子表面:
export CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 export TYPESAFE_API_KEY="<your TypeSafe key>" claude plugin marketplace add tamaratran/fast-jev-compaction claude plugin install fast-jev-compaction@fast-jev-compaction本地开发(从仓库检出目录直接运行,无需发布):
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude --plugin-dir .CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1需要在 Claude Code 运行的每一处都设置,例如写入~/.claude/settings.json的env块(参见仓库根 README.md)。插件清单由仓库根的.claude-plugin/marketplace.json提供;.claude-plugin/plugin.json 声明了插件元数据(当前版本 0.3.0)与userConfig各项。安装后重启 Claude Code 或执行/reload-plugins,此后/compact与自动压缩都会经由 Jev 执行。
配置项一览
插件在.claude-plugin/plugin.json中声明的userConfig值及其默认值如下:
| Option | Default |
|---|---|
keepThreshold | 0.5 |
preserveRecentMessages | 6 |
compactAtPercent | 60 |
minReductionRatio | 0.25 |
maxStateTokens | 25000 |
maxRequestTokens | 30000 |
truncateHeadChars | 300 |
model | jev-latest |
keepThreshold:保留某个工具调用或工具结果所需的最低 Jev 概率;低于阈值即被移除。preserveRecentMessages:最新的多少条消息被钉住(pinned)不参与压缩,第一条消息永远保留。compactAtPercent:当上下文使用百分比达到该值时,turn.complete钩子触发压缩请求。minReductionRatio:替换历史所需的最低估计字符缩减比例,低于它则回退到内置摘要。maxStateTokens:随每次 Jev 请求发送的对话状态的估计 token 预算。maxRequestTokens:单次 Jev 请求中"状态 + 问题"的估计 token 预算。truncateHeadChars:Jev 判定完整输出不再需要时,工具结果保留的前若干字符(0表示只保留说明性注记)。model:TypeSafe Jev 模型名,默认jev-latest(对应 src/request.ts 中的DEFAULT_MODEL)。
TypeSafe 密钥可以通过敏感的插件选项apiKey提供,也可以通过环境变量TYPESAFE_API_KEY提供;环境变量是推荐的开发配置。除apiKey、compactAtPercent、minReductionRatio和model外,其余选项原样传给库,其具体含义与行为见仓库根 README.md 的 Options 表。
配置解析实现在 hooks/fast-jev.ts 的resolveHookConfig:数值选项经optionNumber校验(必须是有限数值,否则回退默认值),字符串选项经optionString校验;apiKey与goal存在才写入配置。钩子自身的默认值(compactAtPercent: 60、minReductionRatio: 0.25、model: DEFAULT_MODEL)定义在HOOK_DEFAULTS。
运行时行为:两个钩子的分工
session.compact:并发请求 + 兜底
session.compact钩子把会话消息交给compactSession(hooks/fast-jev.ts),后者要求必须存在apiKey(否则抛出TYPESAFE_API_KEY is not configured),然后调用库的compact()。Jev 请求并发执行。
密钥的查找优先级在getApiKey(hooks/fast-jev.ts)中实现:插件选项apiKey→ 环境变量TYPESAFE_API_KEY→ Claude Code 设置中的env.TYPESAFE_API_KEY。
在以下任一情况下,钩子记录一条回退日志并把控制权交还 Claude Code 的内置压缩(next(event)):
- Jev 请求失败;
- 响应格式异常(如返回非 JSON、缺少
answers字段——校验见 src/request.ts 的parseJevResponse); - 密钥不可用;
- 历史无法被拟合进状态预算(
fitState抛出 "history too large for Jev"); - 估计缩减比例低于
minReductionRatio。
正常路径下,结果通过toSessionMessages(hooks/fast-jev.ts)映射回会话消息:未经改动的内容复用引擎自身的对象(含 handle),被重建的消息则是没有 handle 的新对象,引擎据此采用编辑后的内容。最终返回{ messages }替换原历史。
结果呈现与诊断
结果以 toast 形式展示并记录日志,包含缩减比例、各原因计数、状态大小与请求次数(summarize,hooks/fast-jev.ts),格式如:
45% reduction; 12 kept, 5 results truncated, 2 call_dropped, 3 pinned; state ~18k tokens (texts abridged) in 3 request(s)其中stateStage表示命中的拟合阶段(见下文)。每条调用还会输出一行decisions:诊断日志(decisionLogLines,hooks/fast-jev.ts),格式为id:tool:action/call=<keepCall>/result=<keepResult>,两个概率都保留两位小数;pinned原因的行不参与该日志。超长日志会按最多 4096 字符分块输出。
turn.complete:达到阈值自动压缩
turn.complete钩子(hooks/fast-jev.ts)通过$.session.usage()读取上下文使用百分比,当context.percent达到compactAtPercent时调用$.session.compact(),并用compacting布尔值作为在途守卫,避免压缩进行中重复触发;失败时仅记录 "auto-compact skipped (…)"。
库侧原理:状态拟合与请求分批
钩子只是薄适配层,核心决策在src/。压缩入口是 src/compact.ts 的compact(),完整流程如下:
配对与钉住:
collectToolCalls(src/state.ts)按tool_use_id将每个tool_use与它的tool_result配对;第一条消息以及最新preserveRecentMessages条消息中的调用被钉住,永不改动。构建状态:发送给 Jev 的
state是"到目前为止的完整对话",最旧在前,每个工具结果被替换成一行说明(如ok, 4213 chars (omitted)),工具输入、文本都包含其中,不做任何总结;goal默认取最近 3 条用户提示(goalFromMessages)。分阶段拟合:状态需要塞进
maxStateTokens(默认 25k)预算,fitState(src/state.ts)按序尝试多个阶段,只有上一阶段不够时才应用下一阶段:- 工具输入截断:1000 → 200 → 60 字符;
- 长文本摘要化(head 400 + tail 150,中间
[… N chars omitted …]),最旧的非钉住消息优先,钉住消息最后; - 旧的非钉住消息折叠为
[… N chars omitted …]单行注记; - 旧工具调用压缩为每行一条(如
t12 Read file_path=src/a.ts → ok 480ch); - 旧的不含调用的消息被剔除;
- 连续的旧纯调用消息合并为一条条目。
全部尝试后仍超预算则抛出异常。命中的阶段名(
full、inputs<=200、texts abridged、old messages collapsed、old calls compacted、old messages left out、old calls merged等)会写入stats.stateStage。无 tokenizer 的估算:
estimateTokens(src/state.ts)按字符数估算——每 6 个字母 1 token、每个数字 0.5 token、其他符号约 0.9 token,并向上取整;校准目标略高于 Jev 实际报告的计数。请求分批:问题被拆分为尽可能少的请求,使每个请求(状态 + 问题)保持在
maxRequestTokens(默认 30k,低于 Jev 的 32k 请求上限)以内,batchCalls(src/compact.ts)还会预留 20 token 的请求信封开销;完整状态随每个请求重新发送,请求并发执行后合并答案。逐条决策:对每个非钉住调用,Jev 收到两个
noul问题(questionsFor,src/compact.ts):该调用是否应留在历史中("知道这次调用发生过、带什么输入,对助手接下来的行动仍然重要"),以及该结果是否应原样保留("助手仍需要其内容,且重跑工具无法替代")。decideCall(src/compact.ts)按keepThreshold判定:keepResult ≥ threshold→ 调用与结果都保留(keep);- 否则若
keepCall ≥ threshold→ 保留调用,结果截断为前truncateHeadChars字符加一行注记(drop_result); - 否则 → 调用连同其结果一并删除(
drop_call)。
重建消息列表:
applyDecisions(src/compact.ts)重建会话——内容全部丢失的消息被移除,未触动的消息原样返回(保持同一对象),任何结果都不会脱离其调用单独存在。截断注记形如[fast-jev-compaction truncated N chars of this tool result; re-run the tool if needed](错误结果会标注(error))。
回退与解读
当 Jev 无法移除足够内容(如会话过短)或调用失败时,toast 显示fallback to built-in summary (…);成功用裁剪后的历史替换内置摘要时,toast 显示kept N/M messages, no summary (…)(M为原始消息数,N为保留消息数)。判定是否值得替换的依据是reductionRatio(字符缩减比例,src/compact.ts)与minReductionRatio的比较。
适用范围与注意事项
- 函数钩子属早期功能,可能在 Claude Code 版本间发生变化。本插件使用 2.1.274 生成的声明(types/claude-code.d.ts),升级 Claude Code 后应重新生成并审查该文件。
- 只有工具调用与工具结果是候选对象;输出中的文本消息永远不会被删除或缩短(它们只会在 Jev 所见的状态中被摘要化)。
- token 大小是从字符数估算的,不是 tokenizer;概率本身不能证明删除某个结果是安全的,助手随时可以重跑工具。
- 完整状态随每个请求重复发送,因此接近状态上限的历史,每少量问题就会消耗一次请求。
- 单元测试(tests/fast-jev-compaction.test.ts、tests/hook.test.ts)使用假 Jev,从不接触 TypeSafe 网络接口;
npm run demo(examples/demo.ts)是实网验证。
相关官方资料可参考 Claude Code 的 plugins、plugins reference 与 hooks 文档(早期访问功能,具体行为以当前版本为准)。
- 人工智能
- AI Agent
- AI 插件
- Agent 记忆
【免费下载链接】fast-jev-compaction
Claude Code plugin that replaces the compaction summary with Jev decisions: every tool call and result is scored in one fast request, stale ones are dropped or truncated, everything kept stays verbatim.
相关推荐
fast-jev-compaction:用 Jev 决策替代摘要式压缩的 Claude Code 上下文压缩插件
fast jev compaction:用 Jev 决策替代摘要式压缩的 Claude Code 上下文压缩插件 导读 fast jev compaction
人工智能AI AgentAI 插件Agent 记忆fast-jev-compaction完整配置指南:在Claude Code中用Jev决策替代压缩摘要
fast jev compaction完整配置指南:在Claude Code中用Jev决策替代压缩摘要 fast jev compaction 是一个 Clau
人工智能AI AgentAI 插件Agent 记忆3分钟快速上手fast-jev-compaction:Claude Code上下文压缩插件安装教程
3分钟快速上手fast jev compaction:Claude Code上下文压缩插件安装教程 还在为 Claude Code 上下文压缩丢失关键信息而烦恼
人工智能AI AgentAI 插件Agent 记忆
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考