caveman-compress 技能实战:把 CLAUDE.md 等记忆文件压缩成穴居人语法,降低每轮会话输入 Token
【免费下载链接】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
导读
caveman-compress是 caveman 项目中的一个 Claude Code 技能(skill),核心思路一句话概括:把每次会话都要加载的项目记忆文件(CLAUDE.md、todo 清单、偏好说明)从啰嗦的自然语言压缩成「穴居人式」短句,从而降低每轮会话固定的输入 token 开销,同时把可读的原始版本备份到项目目录之外、不会被技能自动加载器二次摄入的地方。阅读本文你将掌握:如何触发/caveman-compress命令、它背后的「检测 → 压缩 → 校验 → 定点修复 → 重试」执行链、哪类内容会被原样保留、哪类文件被坚决跳过,以及仓库源码层面对代码块保真、备份安全与敏感文件防护的实现细节。
本技能的定义文档位于 plugins/caveman/skills/caveman-compress/SKILL.md,同一份技能在仓库根目录另有本地副本 skills/caveman-compress/SKILL.md(skills/caveman-compress/README.md 声明本地副本位于skills/caveman-compress/)。下文分析与阅读路径均以仓库相对路径给出。
一、为什么记忆文件值得压缩:每会话重复读入的 token 成本
CLAUDE.md这类项目记忆文件会在每次会话启动时被 Claude 加载。文件越大,每次开启项目就要为同样的内容重复支付一次输入 token。按仓库 README 的估算口径:「一份 1,000 token 的项目记忆文件,每打开一次项目就多消耗 1,000 输入 token,100 次会话即 100,000」——这正是 skills/caveman-compress/README.md 中「Why This Matter」一节说明的动机模型。
caveman-compress的解法不是删除信息,而是改写自然语言部分:去掉填充词、把长句改成短语、合并重复条目,同时对代码、路径、URL 等「不能碰的内容」做字节级保真。它只处理自然语言文本,天然适合CLAUDE.md、todo、偏好文件这类「散文 + 少量结构化内容」的混合文档。
需要强调的是:仓库实测的是结构化保真 + token 计数下降。README 给出 5 组真实夹具的平均 token 节省约 46%(详见下文第七节),并明确说明这些数据「不证明语义等价或任务质量等价」——这是基于当前仓库内容的准确表述,不应夸大为普适的压缩率承诺。
二、触发方式与基本使用
技能的 YAML frontmatter 声明了两个触发途径:
- Slash Command:
/caveman-compress <filepath> - 自然语言意图:当用户要求「压缩某个记忆文件」时由 Agent 触发
用法与CLAUDE.md中说明一致,形式为:
/caveman-compress <filepath>实际示例(来自 README):
/caveman-compress CLAUDE.md /caveman-compress docs/preferences.md /caveman-compress todos.md整个流程会经历:压缩后的文件就地覆盖原文件(CLAUDE.md),而人类可读的原版被保存为CLAUDE.original.md——注意它不会放在源文件旁边,而是放进项目目录树之外的数据目录,以免技能自动加载器把备份当成「活文件」再次摄入。备份目录规则:
- macOS / Linux:
$XDG_DATA_HOME/caveman-compress/backups/<parent-dir-name>/ - Windows:
%LOCALAPPDATA%\caveman-compress\backups\<parent-dir-name>\
(若未设置XDG_DATA_HOME,POSIX 环境实际回退到~/.local/share,见 skills/caveman-compress/scripts/compress.py。)
想恢复可读版本时,去该数据目录编辑*.original.md,然后再次运行技能即可基于新内容重新压缩。
三、一次压缩的完整执行链:CLI 入口到写入回读
SKILL.md 中「Process」一节描述了 CLI 的工作步骤。技能的 Python 实现位于scripts/(与 SKILL.md 同级),入口为python3 -m scripts <absolute_filepath>,由 skills/caveman-compress/scripts/main.py 转发到cli.py的main()。
调用链与关键源码对应如下:
前置检查(不消耗 token)——cli.py:校验命令行参数个数、文件存在、是普通文件并做
resolve();随后调用detect_file_type()与should_compress()做文件类型判定;非自然语言文件直接跳过并退出(退出码 0),出错返回非零。CLI 在启动阶段还对stdout/stderr强制reconfigure(encoding="utf-8", errors="replace"),避免 Windows 默认 cp1252 控制台碰到 emoji 状态符时崩溃。安全与容量闸门——
compress_file()在 compress.py 中先做三项互不依赖的快速拒绝:文件不存在、超过 500KB 上限(MAX_FILE_SIZE = 500_000)、命中敏感路径名单。这三项检查刻意放在加锁之前执行,避免一次被拒的调用在共享状态目录留下永久锁文件。跨会话文件锁——file_lock() 使用操作系统原生文件锁(POSIX 用
fcntl.flock,Windows 用msvcrt.locking),锁路径是(parent-dir-name, stem)身份经 SHA-256 摘要后生成的.lock文件。崩溃或被杀掉的进程会自动释放锁,无需手工清理陈旧标记。等待上限LOCK_WAIT_SECONDS = 900(15 分钟),超过则抛出LockTimeoutError让用户重试。类型检测(无 token)——由 detect.py 完成,返回
natural_language / code / config / unknown四种分类,详见下文第四节。Claude 压缩(消耗一次调用)——见 call_claude():优先使用 Anthropic Python SDK(设置了
ANTHROPIC_API_KEY时),模型取环境变量CAVEMAN_MODEL,默认claude-sonnet-4-5,max_tokens=8192;未设置密钥时回退到claude --printCLI(复用桌面端已有登录态),并且固定参数列表、文件内容经 stdin 传入而非 shell 参数。校验输出(无 token)——由 validate.py 对「备份 vs 压缩结果」做结构化比对,详见下文第五节。
出错则定点修复、最多重试 2 次——校验失败后,构造
build_fix_prompt()(compress.py),只针对错误清单做补丁式修复(如把 ORIGINAL 中缺失的 URL / 代码块 / 标题原文精确补回 COMPRESSED),明确禁止重新压缩或改写未报错段落。MAX_RETRIES = 2。最后一次失败时,脚本把原始字节原样写回、删除备份并报告错误,源文件保持未动。写入——所有写入均走原子替换路径 write_bytes_atomic():先
mkstemp建同目录临时文件、写字节、fsync、再os.replace覆盖目标,并保留原文件权限位。这样即使中途编码失败,目标文件也只会「从一个完整有效文件跳到另一个」,绝不出现半截写入。
这里有个值得注意的细节:SKILL.md说「若校验失败后仍失败就报告用户并保持源文件不动」,而实现里实际上分为两步——第一步把备份写盘后先做一次备份回读字节比对,不一致就直接中止且不触碰源文件(compress.py),然后才覆盖源文件进入校验循环;校验彻底失败时再恢复原始字节并删除备份(compress.py)。也就是说「先保全,再改写,最后回滚」,数据安全优先。
四、可压缩与不可压缩的边界:检测器的判定规则
SKILL.md 的「Boundaries」一节划出了文件边界,detect.py是它的代码化实现:
允许压缩(自然语言)
| 类型 | 判定 |
|---|---|
.md、.txt、.markdown、.rst、.typ、.typst、.tex | 可压缩 |
无扩展名但内容判定为自然语言(如TODO) | 可压缩(需内容启发式通过) |
*.original.md(备份文件) | 永远跳过 |
禁止压缩(代码 / 配置):.py、.js、.ts、.tsx、.jsx、.json、.yaml、.yml、.toml、.env、.lock、.css、.scss、.html、.xml、.sql、.sh、.go、.rs、.java等,均定义于 COMPRESSIBLE_EXTENSIONS / SKIP_EXTENSIONS。
边界判断还有几层额外兜底(来自 detect.py):
- 无扩展名的已知代码文件名单(
KNOWN_CODE_FILENAMES):Dockerfile、Makefile、Jenkinsfile、Gemfile、Justfile、Procfile、CMakeLists.txt等。原因很实际——Dockerfile没有后缀(.dockerfile规则匹配不到它),而CMakeLists.txt会误搭.txt顺风车。 - 扩展名缺失时的内容启发式:shebang(
#!)判定为代码;前 10KB 能解析为 JSON 判为 config;前 30 行 YAML 特征占比超过 60% 判为 config;前 50 行中超过 40% 命中CODE_PATTERNS(import/def/class/function/JSON 键值对/赋值字面量等)判为 code。 .original.md后缀直接排除,保证永远不会对备份再压缩。
对混合内容文件(散文 + 代码),规则明确:只压缩散文段,把代码段当作只读区域,且不得围绕代码合并相邻章节。检测阶段无法确定某行属于代码还是散文时,保持原样。
五、校验器:让「该保留的」一个都不能少
SKILL.md 反复强调「Preserve EXACTLY」,而真正守住这条底线的是压缩后自动运行的校验器validate(original_path, compressed_path)。它不消耗任何 token,把备份(原始内容)与当前压缩文件逐项比对:
| 校验项 | 规则 | 处置 |
|---|---|---|
标题validate_headings | 标题数量、标题文本与顺序必须完全一致 | 文本/顺序改动 = error(会破坏文档内锚点链接);仅级别变化 = warning(slug 不变,链接仍有效) |
代码块validate_code_blocks | 围栏代码块与 4 空格缩进代码块逐字节相等 | 不等 = error |
URLvalidate_urls | http(s)://...集合一致 | 丢失或新增 = error |
文件路径validate_paths | 以./..//盘符开头或带点号尾名的「确定路径」不能丢 | 硬性丢失 = error;模糊差异 = warning |
项目符号validate_bullets | 符号数量变化超过 15% | warning |
行内代码validate_inline_codes | 反引号内联代码按 Counter 计数一致 | 丢失 = error;新增 = warning |
validate_paths值得一提:路径正则是有意「粗略」的,普通散文里的pros/cons、Node/browser这类带斜杠的组合也可能被匹配到,因此只有无歧义路径(前导./、../、/、盘符,或末段是name.ext带点号文件名)丢失才报 error,其余只降级为 warning——见 validate.py 的注释。
为什么校验要做到 error 级别?源码注释里给出了惨痛教训式的理由:4 空格缩进代码块如果不单独抽取校验,kubectl delete pod --all -n prod这类命令会被散文判定逻辑漏掉,出现「干净通过校验但命令已被悄悄改写」的假阳性——那将直接覆盖用户文件,是这类工具最恶劣的失败模式(validate.py)。
校验只产生 error/warning,不直接改文件;真正触发「定点修复 + 重试」循环的是 error 列表,这在第三节的执行链中已说明。
六、压缩规则:删什么、保什么、怎么改
SKILL.md 的「Compression Rules」是本技能的语言学核心,按「删 / 保 / 改」三层组织,逐条如下。
6.1 Remove(这些词删掉)
- 冠词:
a、an、the - 填充词:
just、really、basically、actually、simply、essentially、generally - 客套语:
sure、certainly、of course、happy to、I'd recommend - 模糊兜底:
it might be worth、you could consider、it would be good to - 冗余措辞改写:
in order to→to;make sure to→ensure;the reason is because→because - 连接性水分:
however、furthermore、additionally、in addition
6.2 Preserve EXACTLY(绝不改动)
- 围栏代码块(
```与缩进代码块) - 行内代码(反引号
`...`内容) - URL 与 Markdown 链接
- 文件路径(
/src/components/...、./config.yaml) - 命令(
npm install、git commit、docker build) - 技术术语(库名、API 名、协议名、算法名)
- 专有名词(项目名、人名、公司名)
- 日期、版本号、数值
- 环境变量(
$HOME、NODE_ENV)
CRITICAL RULE(原文级强约束):任何位于...之间的内容必须逐字节照抄——不删注释、不动空格、不重排行、不缩短命令、不做任何简化;行内代码同理,反引号内的任何字符都不得修改。若文件含代码块,代码块一律视作只读区域,仅压缩其外的文本,且不得围绕代码合并段落。
代码块保真在实现上还有更硬的一层保障:压缩前,脚本先用mask_code_blocks()把围栏块与 4 空格缩进块整体替换为@@CAVEMAN_PRESERVED_CODE_<序号>_<哈希>@@这样的不透明行标记,让模型根本「看不到」代码原文;压缩后restore_code_blocks()再把标记还原成原块,并要求每个标记恰好出现一次——模型若移动、复制或改写任何代码块,直接抛错并拒绝写入(compress.py)。相比单纯在提示词里叮嘱「别动代码」,这种做法把保护从「模型自觉」升级成了「结构强制」。
6.3 Preserve Structure(结构骨架原样)
- 所有 Markdown 标题:标题文本逐字保留,只压缩标题下方的正文
- 项目符号层级:保留嵌套深度
- 有序列表:保留编号
- 表格:压缩单元格文字、保留表格结构
- Markdown 文件开头的 Frontmatter / YAML 头:整体原样保留
Frontmatter 的保真同样是工程化处理的:split_frontmatter()(compress.py)在压缩前把---包裹的 YAML 头从输入中外科手术式剥离,压缩完成后原样前缀回输出。原因见源码注释:压缩模型在提示词强调保留结构的情况下,仍习惯性改写或删除 frontmatter——干脆让它根本接触不到。(顺带一提,本技能自己的 SKILL.md 文件开头就带 YAML frontmatter,它自身就是一个很好的观察样本。)
6.4 Compress(正文怎么改)
- 用短同义词:写
big而非extensive,fix而非implement a solution for,use而非utilize - 允许短语碎片:
Run tests before commit,而非You should always run tests before committing - 去掉
you should、make sure to、remember to,直接陈述动作 - 合并「换种说法表达同一意思」的冗余条目
- 多个示例演示同一模式时只保留一个
七、压缩前后的模式对照
SKILL.md「Pattern」给出了两组原文与压缩结果的对照,这里完整保留,便于直观把握「信息量与 token 数」的取舍尺度。
示例一
原句:
You should always make sure to run the test suite before pushing any changes to the main branch. This is important because it helps catch bugs early and prevents broken builds from being deployed to production.
压缩后:
Run tests before push to main. Catch bugs early, prevent broken prod deploys.
示例二
原句:
The application uses a microservices architecture with the following components. The API gateway handles all incoming requests and routes them to the appropriate service. The authentication service is responsible for managing user sessions and JWT tokens.
压缩后:
Microservices architecture. API gateway route all requests to services. Auth service manage user sessions + JWT tokens.
注意第二例中技术名词(microservices architecture、API gateway、JWT tokens)均被原样保留,改变的只是连接语和句子结构——与第六节「Preserve technical terms」规则吻合。
实测收益(来自仓库自身夹具)
skills/caveman-compress/README.md 记录了对 tests/caveman-compress 目录下 5 组真实夹具(每组一份.md压缩稿 + 一份.original.md原文)的实测结果:
| 文件 | 原文 token | 压缩后 token | 节省 |
|---|---|---|---|
claude-md-preferences.md | 706 | 285 | 59.6% |
project-notes.md | 1145 | 535 | 53.3% |
claude-md-project.md | 1122 | 636 | 43.3% |
todo-list.md | 627 | 388 | 38.1% |
mixed-with-code.md | 888 | 560 | 36.9% |
| 平均 | 898 | 481 | 46% |
README 同时声明:所有夹具的标题、代码块、URL、文件路径校验全部通过;但该结果「不证明语义等价或任务质量等价」——即校验保证的是结构不损坏,而非压缩稿能在任意任务上完全替代原文。mixed-with-code.md这类含代码的混合文件节省相对较低(36.9%),与「代码区域不可压缩」的边界规则相互印证。
该数据可复算:仓库提供了 benchmark.py,用tiktoken的o200k_base编码计数(无 tiktoken 时回退为词数),对每对夹具跑同一套validate。以python3 -m scripts.benchmark或直接运行脚本即可复现上表。
八、备份策略与「树外数据目录」的设计动机
备份不放在源文件旁边是刻意的设计决定。如果CLAUDE.original.md与CLAUDE.md同目录,Claude Code 等工具在扫描项目记忆文件时会把备份当活文件摄入,白白为「已经压缩掉的原文」再次付 token——与压缩的目的背道而驰。所以备份落到平台相关的用户数据目录(见第二节路径),并由父目录名 + 文件 stem 构成键,降低不同项目间碰撞概率。
实现上有三点值得一提:
- 备份与压缩写入同样走原子写 + 回读校验:备份先写盘并做字节级回读比对,确认磁盘上确实落下了完整原文,才允许碰源文件;若备份已存在,脚本直接中止以防覆盖旧的原始内容(compress.py)。
- 严格 UTF-8 解码:
read_source()(compress.py)拒绝任何非 UTF-8 文件并给出可操作的错误信息——压缩是就地重写,无法解码的字节会在这场往返中永久消失,所以「读不准就不许写」。它还从原始字节中检测行尾(CRLF/LF),写入时原样还原,避免把用户文件的换行风格全局改掉。 - 锁目录/文件的反符号链接防护:锁目录要求 0700 权限、锁文件以
O_NOFOLLOW打开,防止预先放置的符号链接把锁操作重定向到别处(见 compress.py 注释)。
九、安全边界:什么文件被「先拒后问」
压缩的本质是「把文件内容发给第三方大模型 API」,这决定了数据边界必须是显式的。除了第五、八节提到的边界与原子写,还有一道敏感路径闸门:is_sensitive_path()(compress.py)通过正则与路径组件命中,对.env*、.netrc、credentials*、secret*、password*、id_rsa/authorized_keys/known_hosts、*.pem/*.key/*.p12/*.asc/*.gpg等文件,以及.ssh、.aws、.gnupg、.kube、.docker及名字含secret/credential/token/apikey等令牌的目录一概硬性拒绝——即使这些文件扩展名恰好是.txt(能通过自然语言筛选)。误判时用户需改名后重试,错误信息里会明确说明原因。
skills/caveman-compress/SECURITY.md 对该技能被静态扫描工具(Snyk)标为 High Risk 的成因做了逐条澄清:
subprocess:仅在未配置ANTHROPIC_API_KEY时以claude --print兜底,参数列表固定、无 shell 插值、内容经 stdin 传入;- 文件读写:只碰用户指定的目标文件与树外备份目录;
- 明确不做的事:不执行文件内容、除 Anthropic API 外不发网络请求、不访问用户指定路径以外的文件、不使用
shell=True或字符串拼接、除被压缩文件本身外不采集传输任何数据; - 认证行为:有
ANTHROPIC_API_KEY走 SDK,否则走claudeCLI 复用桌面登录态; - 500KB 上限在发起任何 API 调用前生效。
这些约束与仓库里 skills/caveman-compress/scripts/compress.py 的实际代码相互印证,也与 SKILL.md 的 Process/压缩规则形成一致的「先拒绝、后压缩、再验证」安全策略。
十、把技能接入项目:安装与运行前提
README 明确说明:该技能随caveman插件内置,安装一次 caveman 即可使用/caveman-compress,无需单独安装。若需本地文件,技能代码位于:
- 插件发布副本:
plugins/caveman/skills/caveman-compress/(含本技能 SKILL.md 与scripts/) - 仓库级本地副本:
skills/caveman-compress/(SKILL.md、README.md、SECURITY.md、scripts/) - 基准夹具:
tests/caveman-compress/下 5 组.md/.original.md对照对
运行前提:Python 3.10 及以上;需要可用的 Claude 访问渠道(Anthropic SDK 密钥,或已登录的claudeCLI)。可选环境变量:CAVEMAN_MODEL(默认claude-sonnet-4-5)、ANTHROPIC_API_KEY。压缩由 Agent 依据 SKILL.md 的指引,在包含scripts/的目录下以python3 -m scripts <absolute_filepath>方式执行;若路径不可直接获得,应先在本技能目录旁定位 scripts/main.py。
结语:一条「省 token」的工程化路径
caveman-compress把「记忆文件太大导致每会话重复付 token」这个朴素痛点,做成了一个有明确边界与自愈机制的工程方案:自然语言散文交给模型压缩并接受结构校验,代码与元数据靠屏蔽标记 + 校验器双重保护,原始内容由树外原子备份兜底,敏感文件在最前端被拒绝。它的价值不在于把压缩率吹得多高,而在于压缩过程可验证、可回滚、绝不越界——对任何依赖CLAUDE.md这类常驻记忆文件、又在意长会话 token 成本的 Claude Code 工作流而言,都是值得纳入日常工具箱的一环。
【免费下载链接】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),仅供参考