<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>开发者工具 on Yison's Blog</title><link>https://blog.7ys.top/tags/%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7/</link><description>Recent content in 开发者工具 on Yison's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Tue, 12 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.7ys.top/tags/%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7/index.xml" rel="self" type="application/rss+xml"/><item><title>Claude Code 的记忆系统是怎么工作的？源码级拆解</title><link>https://blog.7ys.top/posts/claude-code-%E7%9A%84%E8%AE%B0%E5%BF%86%E7%B3%BB%E7%BB%9F%E6%98%AF%E6%80%8E%E4%B9%88%E5%B7%A5%E4%BD%9C%E7%9A%84%E6%BA%90%E7%A0%81%E7%BA%A7%E6%8B%86%E8%A7%A3/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://blog.7ys.top/posts/claude-code-%E7%9A%84%E8%AE%B0%E5%BF%86%E7%B3%BB%E7%BB%9F%E6%98%AF%E6%80%8E%E4%B9%88%E5%B7%A5%E4%BD%9C%E7%9A%84%E6%BA%90%E7%A0%81%E7%BA%A7%E6%8B%86%E8%A7%A3/</guid><description>&lt;img src="https://blog.7ys.top/" alt="Featured image of post Claude Code 的记忆系统是怎么工作的？源码级拆解" /&gt;&lt;h1 id="claude-code-的记忆系统是怎么工作的源码级拆解"&gt;Claude Code 的记忆系统是怎么工作的？源码级拆解
&lt;/h1&gt;
 &lt;blockquote&gt;
 &lt;p&gt;你周五用 Claude Code 调 bug 到凌晨两点，周一打开新会话，它张嘴就说：&amp;ldquo;上次那个 auth 模块的 bug 修好了吗？测试记得起 Redis。&amp;ldquo;你愣住了——你没告诉过它这些。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一一个细思极恐的瞬间"&gt;一、一个细思极恐的瞬间
&lt;/h2&gt;&lt;p&gt;用过 Claude Code 的开发者大概都经历过这个瞬间：&lt;/p&gt;
&lt;p&gt;你关掉终端，第二天重新打开，开始一个新对话。Claude 什么都没问，直接开始干活。它知道你的项目用 pnpm 而不是 npm，知道测试需要本地 Redis，知道你讨厌 verbose 的输出。&lt;/p&gt;
&lt;p&gt;你仔细回想：&lt;strong&gt;我什么时候告诉它这些的？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答案是：你没有直接告诉它。是它自己&amp;quot;记住&amp;quot;的。&lt;/p&gt;
&lt;p&gt;Claude Code 每次启动都是一个全新的上下文窗口，不携带任何历史对话。所有它&amp;quot;知道&amp;quot;的东西，都必须在第一轮对话之前从磁盘加载。&lt;/p&gt;
&lt;p&gt;我花了一周时间读 Claude Code 的 TypeScript 源码（是的，它是开源的），发现它的记忆系统比官方文档描述的复杂得多。今天来拆解一下。&lt;/p&gt;
&lt;h2 id="二两套记忆系统你写的-vs-ai-写的"&gt;二、两套记忆系统：你写的 vs AI 写的
&lt;/h2&gt;&lt;p&gt;Claude Code 有两套完全独立的记忆系统，各司其职：&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph TB
 subgraph "Claude Code 记忆全景"
 subgraph "CLAUDE.md（你写的）"
 A1[手动维护]
 A2[指令/规则/偏好]
 A3[通过 git 同步]
 A4[加载后不变化]
 end
 
 subgraph "Auto Memory（AI 写的）"
 B1[自动提取]
 B2[用户画像/行为纠正]
 B3[项目状态/外部引用]
 B4[每轮对话可能更新]
 end
 
 A1 --&gt; C[启动时加载到上下文]
 B1 --&gt; C
 end
 
 style A1 fill:#0f3460,stroke:#e94560,color:#fff
 style A2 fill:#0f3460,stroke:#e94560,color:#fff
 style A3 fill:#0f3460,stroke:#e94560,color:#fff
 style A4 fill:#0f3460,stroke:#e94560,color:#fff
 style B1 fill:#533483,stroke:#e94560,color:#fff
 style B2 fill:#533483,stroke:#e94560,color:#fff
 style B3 fill:#533483,stroke:#e94560,color:#fff
 style B4 fill:#533483,stroke:#e94560,color:#fff
 style C fill:#e94560,stroke:#fff,color:#fff&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;关键区别：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;CLAUDE.md&lt;/th&gt;
 &lt;th&gt;Auto Memory&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;谁写的&lt;/td&gt;
 &lt;td&gt;你手动写&lt;/td&gt;
 &lt;td&gt;Claude 自动写&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;存储位置&lt;/td&gt;
 &lt;td&gt;项目目录 / 用户目录&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;~/.claude/projects/&lt;/code&gt; 下&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;同步方式&lt;/td&gt;
 &lt;td&gt;Git（可提交）&lt;/td&gt;
 &lt;td&gt;本地（不同步）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;更新频率&lt;/td&gt;
 &lt;td&gt;你改才变&lt;/td&gt;
 &lt;td&gt;每轮对话可能更新&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;大小限制&lt;/td&gt;
 &lt;td&gt;40KB（建议）&lt;/td&gt;
 &lt;td&gt;索引 200 行 / 25KB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;加载方式&lt;/td&gt;
 &lt;td&gt;启动时全部加载&lt;/td&gt;
 &lt;td&gt;索引全加载，topic 按需&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="21-claudemd-的加载链"&gt;2.1 CLAUDE.md 的加载链
&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;优先级（高→低）：

1. 管理级 /etc/claude-code/CLAUDE.md ← IT 管理员写的，无法覆盖
2. 用户级 ~/.claude/CLAUDE.md ← 你的个人偏好
3. 项目级 ./CLAUDE.md 或 ./.claude/CLAUDE.md ← 团队共享（git 提交）
4. 本地级 ./CLAUDE.local.md ← 你的个人覆盖（不提交）

加载顺序：
 工作目录 → 向上遍历目录树 → 加载沿途所有 CLAUDE.md
 离工作目录近的优先级高
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;一个细节：&lt;/strong&gt; &lt;code&gt;CLAUDE.local.md&lt;/code&gt; 不在官方文档里，但源码中存在。它在项目 CLAUDE.md 之后、Auto Memory 之前加载。适合放个人的数据库密码、调试开关之类的——不提交到 git，但本地有效。&lt;/p&gt;
&lt;h3 id="22-auto-memory-的四种类型"&gt;2.2 Auto Memory 的四种类型
&lt;/h3&gt;&lt;p&gt;Auto Memory 不是随意的笔记，而是有严格的分类：&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph TB
 subgraph "四种记忆类型"
 subgraph "user（用户画像）"
 U1[角色/偏好/知识水平]
 U2[始终私有]
 end
 
 subgraph "feedback（行为纠正）"
 F1[验证过的模式]
 F2[默认私有]
 end
 
 subgraph "project（项目状态）"
 P1[工作进展/决策]
 P2[倾向团队共享]
 end
 
 subgraph "reference（外部引用）"
 R1[系统指针]
 R2[通常团队共享]
 end
 end
 
 style U1 fill:#0f3460,stroke:#e94560,color:#fff
 style U2 fill:#0f3460,stroke:#e94560,color:#fff
 style F1 fill:#533483,stroke:#e94560,color:#fff
 style F2 fill:#533483,stroke:#e94560,color:#fff
 style P1 fill:#16213e,stroke:#e94560,color:#fff
 style P2 fill:#16213e,stroke:#e94560,color:#fff
 style R1 fill:#1a1a2e,stroke:#e94560,color:#fff
 style R2 fill:#1a1a2e,stroke:#e94560,color:#fff&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;为什么这样分？&lt;/strong&gt; 因为团队协作时，你的编码偏好（user）不应该泄露给队友，但项目进度（project）应该共享。这种分类直接影响记忆的加载和同步策略。&lt;/p&gt;
&lt;h2 id="三三个时间尺度实时--会话--梦境"&gt;三、三个时间尺度：实时 / 会话 / 梦境
&lt;/h2&gt;&lt;p&gt;这是整套系统最精妙的部分。Auto Memory 不是&amp;quot;Claude 注意到什么就随手记下来&amp;rdquo;，而是有三个独立的后台进程，在不同时间尺度上提取信息：&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph LR
 subgraph "时间轴"
 A[Per-Turn&lt;br/&gt;实时提取] --&gt;|每轮对话| B[Per-Session&lt;br/&gt;会话记忆]
 B --&gt;|每个会话| C[autoDream&lt;br/&gt;梦境整合]
 end
 
 subgraph "成本"
 D[极低&lt;br/&gt;共享cache] 
 E[低&lt;br/&gt;偶尔触发]
 F[中&lt;br/&gt;24h+5会话门槛]
 end
 
 A --- D
 B --- E
 C --- F
 
 style A fill:#e94560,stroke:#fff,color:#fff
 style B fill:#533483,stroke:#fff,color:#fff
 style C fill:#0f3460,stroke:#fff,color:#fff
 style D fill:transparent,stroke:#e94560,color:#e94560
 style E fill:transparent,stroke:#533483,color:#533483
 style F fill:transparent,stroke:#0f3460,color:#0f3460&lt;/pre&gt;&lt;h3 id="31-per-turn实时提取每轮对话后"&gt;3.1 Per-Turn：实时提取（每轮对话后）
&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;触发：每次完整查询循环结束
方式：fork 一个子 Agent 在后台运行
成本：极低（共享父 Agent 的 prompt cache）
权限：只读项目文件，只写记忆目录
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;一个细节：&lt;/strong&gt; 如果主 Agent 在本轮已经写过记忆（你明确说&amp;quot;记住这个&amp;rdquo;），提取步骤会跳过那个范围，避免重复。&lt;/p&gt;
&lt;h3 id="32-per-session会话记忆上下文增长时"&gt;3.2 Per-Session：会话记忆（上下文增长时）
&lt;/h3&gt;&lt;p&gt;这是一个独立于 Auto Memory 的系统，目的是让当前会话的上下文&lt;strong&gt;在压缩后还能保留&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;触发条件（三个同时满足）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;✅ 总上下文 ≥ 10,000 tokens
✅ 上下文增长 ≥ 5,000 tokens（自上次提取后）
✅ 工具调用 ≥ 3 次
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;提取的结构化笔记：&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│ Session Memory 模板 │
├─────────────────────────────────────────┤
│ ## Current State │
│ 当前正在做什么，进展到哪一步 │
│ （上限 ~2000 tokens） │
├─────────────────────────────────────────┤
│ ## Files and Functions │
│ 涉及的文件、函数、关键代码位置 │
│ （上限 ~2000 tokens） │
├─────────────────────────────────────────┤
│ ## Errors &amp;amp; Corrections │
│ 遇到的错误、尝试过的方案、最终解决方案 │
│ （上限 ~2000 tokens） │
├─────────────────────────────────────────┤
│ ## Worklog │
│ 工作日志：做了什么、还剩什么 │
│ （上限 ~2000 tokens） │
└─────────────────────────────────────────┘
总计上限 ~12,000 tokens
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;为什么需要这个？&lt;/strong&gt; 当对话太长需要压缩时，有这些结构化笔记，auto-compact 可以复用它们，而不是从头重新摘要整个对话。效果好很多——因为笔记是增量提取的，上下文还完整时就记录了关键信息。&lt;/p&gt;
&lt;h3 id="33-autodream梦境整合每天每几天"&gt;3.3 autoDream：梦境整合（每天/每几天）
&lt;/h3&gt;&lt;p&gt;这是最让人惊讶的部分。源码中明确把这叫做 &lt;strong&gt;&amp;ldquo;DreamTask&amp;rdquo;&lt;/strong&gt;，UI 中会显示进度条。&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph TB
 subgraph "autoDream 触发条件"
 G1[Gate 1: 时间检查&lt;br/&gt;≥ 24小时] --&gt;|✅| G2[Gate 2: 会话检查&lt;br/&gt;≥ 5个会话修改]
 G2 --&gt;|✅| G3[Gate 3: 锁检查&lt;br/&gt;.consolidate-lock 未占用]
 G3 --&gt;|✅| EXEC[执行整合]
 
 G1 --&gt;|❌| SKIP[跳过]
 G2 --&gt;|❌| SKIP
 G3 --&gt;|❌| SKIP
 end
 
 style G1 fill:#0f3460,stroke:#e94560,color:#fff
 style G2 fill:#0f3460,stroke:#e94560,color:#fff
 style G3 fill:#0f3460,stroke:#e94560,color:#fff
 style EXEC fill:#e94560,stroke:#fff,color:#fff
 style SKIP fill:#1a1a2e,stroke:#533483,color:#533483&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;整合流程（四阶段）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Phase 1: 定向
 ├── 读取 MEMORY.md 索引
 └── 浏览现有 topic 文件
 目的：了解当前记忆状态

Phase 2: 发现
 └── 搜索日志和会话记录中的新知识
 目的：找到需要整合的信息

Phase 3: 写入
 ├── 写入/更新 topic 文件
 ├── 合并新信号到现有文件
 └── 相对日期 → 绝对日期（&amp;#34;昨天&amp;#34; → &amp;#34;2026-05-11&amp;#34;）
 目的：持久化新知识

Phase 4: 清理
 ├── 修剪 MEMORY.md 至 200 行以下
 ├── 移除过期指针
 └── 解决新旧事实矛盾
 目的：保证记忆质量
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;一个有趣的细节：&lt;/strong&gt; 如果你杀掉整合进程，锁的修改时间会回滚，让下一个会话可以重试。这个错误处理很体贴。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;它什么时候运行？&lt;/strong&gt; 不是等你关掉电脑或睡觉，而是在一次对话结束时——只要满足那三个 Gate。只是因为 24 小时和 5 个会话的门槛，大多数时候不会触发。&lt;/p&gt;
&lt;h2 id="四记忆召回sonnet-替你选"&gt;四、记忆召回：Sonnet 替你选
&lt;/h2&gt;&lt;p&gt;记忆存下来了，但怎么在需要的时候找到正确的记忆？&lt;/p&gt;
&lt;p&gt;Claude Code 的方案是：&lt;strong&gt;让 Sonnet 替你选，不是关键词匹配。&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph TB
 subgraph "记忆召回流程"
 START[启动时] --&gt; A[读取 MEMORY.md 索引&lt;br/&gt;前 200 行]
 A --&gt; B[扫描 topic 文件 frontmatter]
 B --&gt; C[构建 manifest&lt;br/&gt;filename + description]
 
 C --&gt; D[每轮对话]
 D --&gt; E[用户输入 + 工具结果]
 E --&gt; F[调用 Sonnet 选择相关文件&lt;br/&gt;最多 5 个]
 F --&gt; G[读取选中文件&lt;br/&gt;每文件 4KB 限制]
 G --&gt; H[注入到 prompt]
 end
 
 subgraph "限制"
 L1[每轮最多 5 个文件]
 L2[每文件 4KB]
 L3[每轮预算 20KB]
 L4[会话累计 60KB]
 end
 
 style START fill:#e94560,stroke:#fff,color:#fff
 style A fill:#0f3460,stroke:#e94560,color:#fff
 style B fill:#0f3460,stroke:#e94560,color:#fff
 style C fill:#0f3460,stroke:#e94560,color:#fff
 style D fill:#533483,stroke:#fff,color:#fff
 style E fill:#533483,stroke:#fff,color:#fff
 style F fill:#533483,stroke:#fff,color:#fff
 style G fill:#533483,stroke:#fff,color:#fff
 style H fill:#e94560,stroke:#fff,color:#fff
 style L1 fill:transparent,stroke:#e94560,color:#e94560
 style L2 fill:transparent,stroke:#e94560,color:#e94560
 style L3 fill:transparent,stroke:#e94560,color:#e94560
 style L4 fill:transparent,stroke:#e94560,color:#e94560&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;为什么用 Sonnet 而不是关键词？&lt;/strong&gt; 因为语义理解更好。比如用户问&amp;quot;怎么跑测试&amp;quot;，关键词匹配可能找不到 &lt;code&gt;feedback_testing.md&lt;/code&gt;，但 Sonnet 能理解这个意图。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;但这里有一个结构性缺陷：&lt;/strong&gt; 没有向量搜索，没有语义索引。如果 MEMORY.md 中的描述写得不好，或者 topic 文件太多（最多扫描 200 个，按修改时间排序），记忆就可能被&amp;quot;遗忘&amp;quot;。&lt;/p&gt;
&lt;h2 id="五什么能活过压缩"&gt;五、什么能活过压缩？
&lt;/h2&gt;&lt;p&gt;长对话会被压缩。压缩后，什么能保留？&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph TB
 subgraph "压缩后存活分析"
 subgraph "✅ 能活过的（从磁盘重新加载）"
 A1[CLAUDE.md 文件]
 A2[Auto Memory 文件]
 A3[Session Memory 文件]
 end
 
 subgraph "❌ 活不过的"
 B1[只在对话中说过&lt;br/&gt;没有保存到记忆系统的内容]
 end
 end
 
 style A1 fill:#0f3460,stroke:#e94560,color:#fff
 style A2 fill:#0f3460,stroke:#e94560,color:#fff
 style A3 fill:#0f3460,stroke:#e94560,color:#fff
 style B1 fill:#1a1a2e,stroke:#e94560,color:#e94560&lt;/pre&gt;&lt;p&gt;源码中的清理代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 压缩时，强制清除所有缓存，从磁盘重新加载
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;getUserContext&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;cache&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;resetGetMemoryFilesCache&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;compact&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;clearSystemPromptSections&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;教训：&lt;/strong&gt; 如果你在对话中告诉 Claude 什么重要的东西，确保它写入了记忆。否则压缩后就没了。&lt;/p&gt;
&lt;h2 id="六与其他工具的对比"&gt;六、与其他工具的对比
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;Claude Code&lt;/th&gt;
 &lt;th&gt;Aider&lt;/th&gt;
 &lt;th&gt;Cursor&lt;/th&gt;
 &lt;th&gt;DeepSeek-TUI&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;记忆系统&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅ 三层架构&lt;/td&gt;
 &lt;td&gt;❌ 无&lt;/td&gt;
 &lt;td&gt;⚠️ 简单 rules&lt;/td&gt;
 &lt;td&gt;✅ 基础记忆&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;自动提取&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅ per-turn&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;⚠️ 手动&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;梦境整合&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅ autoDream&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;记忆分类&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅ 4 种类型&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;模型辅助召回&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅ Sonnet 选择&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;团队同步&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;⚠️ feature flag&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;记忆持久化&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅ 文件系统&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;⚠️ 配置文件&lt;/td&gt;
 &lt;td&gt;✅ 文件系统&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;结论：&lt;/strong&gt; Claude Code 的记忆系统是目前 AI 编程工具中最完善的。Aider 完全没有记忆，Cursor 只有简单的 rules 文件，DeepSeek-TUI 有基础记忆但没有自动提取和整合。&lt;/p&gt;
&lt;h2 id="七这套系统的局限"&gt;七、这套系统的局限
&lt;/h2&gt;&lt;p&gt;读完源码，我认为有几个结构性局限：&lt;/p&gt;
&lt;h3 id="71-记忆是-per-repo-的"&gt;7.1 记忆是 per-repo 的
&lt;/h3&gt;&lt;p&gt;你在项目 A 教 Claude 的偏好，不会自动带到项目 B。用户级的 &lt;code&gt;~/.claude/CLAUDE.md&lt;/code&gt; 可以处理一部分，但它是静态的——Claude 不能在会话中自动更新它。&lt;/p&gt;
&lt;h3 id="72-记忆是-machine-local-的"&gt;7.2 记忆是 machine-local 的
&lt;/h3&gt;&lt;p&gt;项目目录名经过 sanitize（非字母数字替换为连字符），但不同机器、不同用户名、不同挂载点会产生不同的目录名。同一项目，不同机器，不同记忆。&lt;/p&gt;
&lt;h3 id="73-没有记忆衰减"&gt;7.3 没有记忆衰减
&lt;/h3&gt;&lt;p&gt;所有记忆都是平等的。一个月前的偏好和今天的偏好权重一样。没有&amp;quot;热度&amp;quot;概念，没有自动遗忘机制。&lt;/p&gt;
&lt;h3 id="74-依赖-sonnet-的选择能力"&gt;7.4 依赖 Sonnet 的选择能力
&lt;/h3&gt;&lt;p&gt;如果 Sonnet 选错了记忆文件，或者描述写得不好，记忆就&amp;quot;丢了&amp;quot;。没有 fallback 机制。&lt;/p&gt;
&lt;h2 id="八对我们的启示"&gt;八、对我们的启示
&lt;/h2&gt;&lt;p&gt;这套系统给我们什么启发？&lt;/p&gt;
&lt;h3 id="81-记忆是-ai-工具的核心差异化"&gt;8.1 记忆是 AI 工具的核心差异化
&lt;/h3&gt;&lt;p&gt;目前市面上的开源 AI 编程工具（Aider、OpenCode、Continue），没有一个有真正意义上的记忆系统。这是差异化机会。&lt;/p&gt;
&lt;h3 id="82-梦境整合是一个优雅的设计"&gt;8.2 梦境整合是一个优雅的设计
&lt;/h3&gt;&lt;p&gt;不是每次对话都提取记忆（太频繁，噪音多），也不是完全不提取（会丢失）。三个时间尺度的设计——实时、会话、梦境——是一个很好的平衡。&lt;/p&gt;
&lt;h3 id="83-模型辅助召回比关键词匹配更好"&gt;8.3 模型辅助召回比关键词匹配更好
&lt;/h3&gt;&lt;p&gt;让 Sonnet 选择相关的记忆文件，而不是 grep 关键词。这在语义理解上好很多，但成本也更高。&lt;/p&gt;
&lt;p&gt;对于开源工具，可以考虑一个折中方案：先用关键词过滤缩小范围，再用小模型选择。&lt;/p&gt;
&lt;h3 id="84-记忆质量--记忆数量"&gt;8.4 记忆质量 &amp;gt; 记忆数量
&lt;/h3&gt;&lt;p&gt;Claude Code 严格限制记忆的大小（200 行索引、4KB 单文件、60KB 会话累计）。这不是偷懒，而是有意为之——太多记忆反而会干扰。&lt;/p&gt;
&lt;h2 id="九写在最后"&gt;九、写在最后
&lt;/h2&gt;&lt;p&gt;读完 Claude Code 的记忆系统源码，我最大的感受是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;好的 AI 工具不是模型能力的比拼，而是工程设计的比拼。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;同样的 Claude 模型，有记忆系统和没有记忆系统，用户体验天差地别。记忆系统本身不需要更强大的模型，它需要的是精心的工程设计——什么时候提取、怎么存储、如何召回、何时整合。&lt;/p&gt;
&lt;p&gt;这些工程细节，才是真正的壁垒。&lt;/p&gt;
&lt;hr&gt;

 &lt;blockquote&gt;
 &lt;p&gt;本文基于 Claude Code TypeScript 源码分析。
源码地址：&lt;a class="link" href="https://github.com/anthropics/claude-code" target="_blank" rel="noopener"
 &gt;github.com/anthropics/claude-code&lt;/a&gt;
参考文章：&lt;a class="link" href="https://db0.ai/blog/how-claude-code-memory-works" target="_blank" rel="noopener"
 &gt;How Claude Code memory actually works&lt;/a&gt;&lt;/p&gt;

 &lt;/blockquote&gt;</description></item><item><title>RTK：让 AI 编码工具的 Token 账单打一折</title><link>https://blog.7ys.top/posts/rtk%E8%AE%A9-ai-%E7%BC%96%E7%A0%81%E5%B7%A5%E5%85%B7%E7%9A%84-token-%E8%B4%A6%E5%8D%95%E6%89%93%E4%B8%80%E6%8A%98/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://blog.7ys.top/posts/rtk%E8%AE%A9-ai-%E7%BC%96%E7%A0%81%E5%B7%A5%E5%85%B7%E7%9A%84-token-%E8%B4%A6%E5%8D%95%E6%89%93%E4%B8%80%E6%8A%98/</guid><description>&lt;img src="https://blog.7ys.top/" alt="Featured image of post RTK：让 AI 编码工具的 Token 账单打一折" /&gt;&lt;h1 id="rtk让-ai-编码工具的-token-账单打一折"&gt;RTK：让 AI 编码工具的 Token 账单打一折
&lt;/h1&gt;
 &lt;blockquote&gt;
 &lt;p&gt;用 Cursor 写代码，一次深度交互能烧掉四五百万 tokens，平时也动辄几十万。直到我发现 token 消耗的大头不在 prompt，而在那些被 AI 吞进去的命令输出。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一你的-token-到底花在了哪"&gt;一、你的 token 到底花在了哪？
&lt;/h2&gt;&lt;p&gt;用 AI 编码工具（Claude Code / Cursor / Copilot）写代码，AI 会频繁执行 shell 命令：读文件、搜代码、跑测试、看 diff、查 git 状态。&lt;strong&gt;每条命令的完整输出都会作为 token 塞进上下文窗口。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个典型的中等复杂度编码会话，token 消耗分布大概是这样：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;操作&lt;/th&gt;
 &lt;th&gt;频率&lt;/th&gt;
 &lt;th&gt;典型 token 消耗&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;cat&lt;/code&gt; / &lt;code&gt;read&lt;/code&gt; 读文件&lt;/td&gt;
 &lt;td&gt;20+ 次&lt;/td&gt;
 &lt;td&gt;40,000+&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;grep&lt;/code&gt; / &lt;code&gt;rg&lt;/code&gt; 搜索代码&lt;/td&gt;
 &lt;td&gt;8+ 次&lt;/td&gt;
 &lt;td&gt;16,000+&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;git status&lt;/code&gt; / &lt;code&gt;git diff&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;15+ 次&lt;/td&gt;
 &lt;td&gt;13,000+&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;go test&lt;/code&gt; / &lt;code&gt;pytest&lt;/code&gt; 跑测试&lt;/td&gt;
 &lt;td&gt;8+ 次&lt;/td&gt;
 &lt;td&gt;31,000+&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;ls&lt;/code&gt; / &lt;code&gt;tree&lt;/code&gt; 看目录&lt;/td&gt;
 &lt;td&gt;10+ 次&lt;/td&gt;
 &lt;td&gt;2,000+&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;单次会话粗估&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;~100,000+&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果是深度调试或大项目，一次会话轻松突破&lt;strong&gt;百万级&lt;/strong&gt;，最高可达&lt;strong&gt;四五百万 tokens&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;问题在于：这些输出里，&lt;strong&gt;80% 是对 AI 毫无价值的噪音&lt;/strong&gt;——通过的测试输出、git 的提示信息、空行、ANSI 颜色码、样板注释。你在为噪音买单。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="二rtk-是什么"&gt;二、RTK 是什么？
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;RTK（Rust Token Killer）&lt;/strong&gt; 是一个高性能 CLI 代理，在命令输出到达 AI 上下文&lt;strong&gt;之前&lt;/strong&gt;进行智能过滤压缩。&lt;/p&gt;
&lt;p&gt;&lt;img alt="RTK 架构总览" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.7ys.top/images/article/2026-05-04/rtk-architecture.svg"&gt;&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;项目&lt;/th&gt;
 &lt;th&gt;信息&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;GitHub&lt;/td&gt;
 &lt;td&gt;&lt;a class="link" href="https://github.com/rtk-ai/rtk" target="_blank" rel="noopener"
 &gt;rtk-ai/rtk&lt;/a&gt;（40k+ ⭐）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;语言&lt;/td&gt;
 &lt;td&gt;Rust，单二进制文件，零依赖&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;代理开销&lt;/td&gt;
 &lt;td&gt;&amp;lt; 10ms&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;支持工具&lt;/td&gt;
 &lt;td&gt;Claude Code、Copilot、Cursor、Gemini CLI、OpenClaw 等 12 种&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;官网&lt;/td&gt;
 &lt;td&gt;&lt;a class="link" href="https://www.rtk-ai.app" target="_blank" rel="noopener"
 &gt;https://www.rtk-ai.app&lt;/a&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;官方宣称的效果：&lt;strong&gt;60-90% 的 token 节省&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="三核心原理三层架构"&gt;三、核心原理：三层架构
&lt;/h2&gt;&lt;p&gt;作为工程师，我最关心的不是&amp;quot;能省多少&amp;quot;，而是&amp;quot;怎么做到的&amp;quot;。&lt;/p&gt;
&lt;p&gt;RTK 的架构分三层，每一层解决一个独立问题：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────┐
│ Layer 1: Hook 拦截层 — &amp;#34;让 AI 不知不觉用上 RTK&amp;#34; │
│ ──────────────────────────────────────────── │
│ AI 执行 &amp;#34;git status&amp;#34; │
│ ↓ PreToolUse Hook 自动重写 │
│ 实际执行 &amp;#34;rtk git status&amp;#34; │
│ AI 完全无感知，只是收到更精简的输出 │
├──────────────────────────────────────────────────────────────┤
│ Layer 2: 命令路由层 — &amp;#34;不同命令用不同策略&amp;#34; │
│ ──────────────────────────────────────────── │
│ main.rs → Clap 解析器 → 路由到对应处理器 │
│ ├─ git/* → Git 模块（结构化解析 porcelain 格式） │
│ ├─ go/* → Go 模块（解析 NDJSON 格式） │
│ ├─ rust/* → Cargo 模块 │
│ └─ 其他 → TOML 声明式过滤引擎（回退） │
├──────────────────────────────────────────────────────────────┤
│ Layer 3: 过滤引擎层 — &amp;#34;两套系统，各司其职&amp;#34; │
│ ──────────────────────────────────────────── │
│ System A: Rust 原生过滤器（复杂命令） │
│ → git diff, go test, cargo test 等需要结构化解析的命令 │
│ System B: TOML 声明式过滤器（简单命令） │
│ → du, ping, systemctl 等只需正则+截断的命令 │
└──────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="四过滤引擎深度拆解"&gt;四、过滤引擎深度拆解
&lt;/h2&gt;&lt;h3 id="41-system-arust-原生过滤器复杂命令"&gt;4.1 System A：Rust 原生过滤器（复杂命令）
&lt;/h3&gt;&lt;p&gt;用于 git、go test、cargo test 等&lt;strong&gt;需要语义理解&lt;/strong&gt;的命令。核心思路：&lt;strong&gt;用结构化解析代替文本处理&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 id="go-test-的压缩-90"&gt;&lt;code&gt;go test&lt;/code&gt; 的压缩（-90%）
&lt;/h4&gt;&lt;p&gt;RTK 强制给 &lt;code&gt;go test&lt;/code&gt; 加上 &lt;code&gt;-json&lt;/code&gt; 参数，输出 NDJSON 格式。然后逐行解析 JSON：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 解析每一行 JSON 事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;match&lt;/span&gt; event.action.as_str() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;pass&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; pkg_result.pass &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 通过 → 只计数，丢弃输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fail&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pkg_result.fail &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pkg_result.failed_tests.push((test, outputs)); &lt;span style="color:#75715e"&gt;// 失败 → 保留
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;skip&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; pkg_result.skip &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 跳过 → 只计数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _ &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;压缩前&lt;/strong&gt;（6000 tokens）：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;=== RUN TestAdd
--- PASS: TestAdd (0.00s)
=== RUN TestSubtract
--- PASS: TestSubtract (0.00s)
=== RUN TestMultiply
--- FAIL: TestMultiply (0.00s)
 multiply_test.go:15: expected 6, got 5
=== RUN TestDivide
--- PASS: TestDivide (0.00s)
... (重复 100+ 个测试)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;压缩后&lt;/strong&gt;（600 tokens）：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;FAIL github.com/user/project
 ✗ TestMultiply (0.00s)
 multiply_test.go:15: expected 6, got 5

3 passed, 1 failed, 0 skipped
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;关键洞察：&lt;strong&gt;AI 不需要看通过的测试输出，它只需要知道&amp;quot;谁失败了&amp;quot;和&amp;quot;为什么失败&amp;quot;。&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id="git-diff-的压缩-75"&gt;&lt;code&gt;git diff&lt;/code&gt; 的压缩（-75%）
&lt;/h4&gt;&lt;p&gt;核心函数 &lt;code&gt;compact_diff()&lt;/code&gt; 做了四件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;按文件分组&lt;/strong&gt; — 只保留文件名，不保留 diff 头部的 &lt;code&gt;index&lt;/code&gt;、&lt;code&gt;---&lt;/code&gt;/&lt;code&gt;+++&lt;/code&gt; 行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统计 +/- 数量&lt;/strong&gt; — 每个文件末尾显示 &lt;code&gt;+5 -2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hunk 截断&lt;/strong&gt; — 每个 hunk 最多显示 100 行变更&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文行裁剪&lt;/strong&gt; — 只在变更附近保留上下文，中间的跳过&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 核心循环
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; line &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; diff.lines() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; line.starts_with(&lt;span style="color:#e6db74"&gt;&amp;#34;diff --git&amp;#34;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 新文件：输出文件名，重置计数器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; line.starts_with(&lt;span style="color:#e6db74"&gt;&amp;#34;@@&amp;#34;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Hunk 头：保留（含函数名信息）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; in_hunk {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; line.starts_with(&lt;span style="color:#e6db74"&gt;&amp;#39;+&amp;#39;&lt;/span&gt;) { added &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#75715e"&gt;/* 保留 */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; line.starts_with(&lt;span style="color:#e6db74"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;) { removed &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#75715e"&gt;/* 保留 */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; hunk_shown &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; { &lt;span style="color:#75715e"&gt;/* 上下文行：只在有变更时保留 */&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="git-status-的压缩-80"&gt;&lt;code&gt;git status&lt;/code&gt; 的压缩（-80%）
&lt;/h4&gt;&lt;p&gt;解析 &lt;code&gt;git status --porcelain&lt;/code&gt; 输出，按状态码分类汇总：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;* main...origin/main
+ Staged: 2 files
 src/main.rs
 src/utils.rs
~ Modified: 1 files
 src/lib.rs
? Untracked: 2 files
 docs/README.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;所有 git 提示信息（&lt;code&gt;use &amp;quot;git restore&amp;quot;...&lt;/code&gt; 等）全部丢弃。&lt;/p&gt;
&lt;h4 id="git-add--commit--push-的暴力压缩-92"&gt;&lt;code&gt;git add&lt;/code&gt; / &lt;code&gt;commit&lt;/code&gt; / &lt;code&gt;push&lt;/code&gt; 的暴力压缩（-92%）
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// git add → 直接输出 &amp;#34;ok&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// git commit → 输出 &amp;#34;ok abc1234&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// git push → 输出 &amp;#34;ok main&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;AI 不需要看 git 的 verbose 输出，只需要知道&amp;quot;成功了没&amp;quot;和关键标识。&lt;/p&gt;
&lt;h3 id="42-system-btoml-声明式过滤器简单命令"&gt;4.2 System B：TOML 声明式过滤器（简单命令）
&lt;/h3&gt;&lt;p&gt;用于 du、ping、systemctl 等&lt;strong&gt;只需正则+截断&lt;/strong&gt;的命令。零代码，纯配置。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ping.toml — 只保留统计摘要，删除逐行响应&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[&lt;span style="color:#a6e22e"&gt;filters&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ping&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;match_command&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;^ping\\b&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;strip_ansi&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;strip_lines_matching&lt;/span&gt; = [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;^PING &amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;^\\d+ bytes from &amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;# 删除每行 ping 响应&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;^\\s*$&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;# 删除空行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tail_lines&lt;/span&gt; = &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 只保留最后 4 行（统计摘要）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TOML 过滤器有 &lt;strong&gt;8 阶段管道&lt;/strong&gt;，按顺序执行：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;① strip_ansi 去除 ANSI 转义码（颜色等）
② replace 正则替换（逐行，可链式）
③ match_output 短路匹配：整个输出匹配某模式 → 直接返回固定消息
④ strip/keep_lines 按正则过滤行（二选一）
⑤ truncate_lines_at 每行截断到 N 字符
⑥ head/tail_lines 只保留前 N / 后 N 行
⑦ max_lines 绝对行数上限
⑧ on_empty 结果为空时的默认消息
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;添加新命令？只需要写一个 TOML 文件，不需要写一行 Rust。仓库里已经有 60+ 个内置过滤器。&lt;/p&gt;
&lt;h3 id="43-故障安全宁可多输出不能丢信息"&gt;4.3 故障安全：宁可多输出，不能丢信息
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 核心原则：如果过滤失败，回退到原始输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; exit_code &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 保存完整原始输出到 ~/.local/share/rtk/tee/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 输出提示：&amp;#34;[full output: /path/to/tee.log]&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个设计很工程师——&lt;strong&gt;fail-safe，不是 fail-open&lt;/strong&gt;。AI 永远不会因为 RTK 自身的 bug 而丢失关键信息。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="五安装与使用"&gt;五、安装与使用
&lt;/h2&gt;&lt;h3 id="51-安装"&gt;5.1 安装
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# macOS / Linux（推荐 Homebrew）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install rtk
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 或快速安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 验证&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk --version
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk gain &lt;span style="color:#75715e"&gt;# 查看 token 节省统计&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Windows 用户从 &lt;a class="link" href="https://github.com/rtk-ai/rtk/releases" target="_blank" rel="noopener"
 &gt;GitHub Releases&lt;/a&gt; 下载 &lt;code&gt;rtk-x86_64-pc-windows-msvc.zip&lt;/code&gt;，解压后加入 PATH。&lt;/p&gt;
&lt;h3 id="52-集成到-ai-工具"&gt;5.2 集成到 AI 工具
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Claude Code / Copilot&lt;/strong&gt;（最无缝）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk init -g &lt;span style="color:#75715e"&gt;# 安装 Hook，重启 Claude Code 即可&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Cursor&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk init -g --agent cursor
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 修改 ~/.cursor/hooks.json，添加 preToolUse 钩子&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Cursor 自动加载&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;OpenClaw&lt;/strong&gt;（插件方式）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://github.com/rtk-ai/rtk.git &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cd rtk
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;openclaw plugins install ./openclaw
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;openclaw gateway restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Gemini CLI&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk init -g --gemini
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;其他工具&lt;/strong&gt;（手动使用）：直接在命令前加 &lt;code&gt;rtk&lt;/code&gt; 前缀即可。&lt;/p&gt;
&lt;h3 id="53-常用命令速查"&gt;5.3 常用命令速查
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk ls . &lt;span style="color:#75715e"&gt;# Token 优化的目录树&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk read file.go &lt;span style="color:#75715e"&gt;# 智能文件读取（-70%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk grep &lt;span style="color:#e6db74"&gt;&amp;#34;pattern&amp;#34;&lt;/span&gt; . &lt;span style="color:#75715e"&gt;# 按文件分组的搜索结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk find &lt;span style="color:#e6db74"&gt;&amp;#34;*.go&amp;#34;&lt;/span&gt; . &lt;span style="color:#75715e"&gt;# 紧凑的查找结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Git&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk git status &lt;span style="color:#75715e"&gt;# 紧凑状态（-80%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk git log -n &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 单行提交（-80%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk git diff &lt;span style="color:#75715e"&gt;# 精简 diff（-75%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk git push &lt;span style="color:#75715e"&gt;# → &amp;#34;ok main&amp;#34;（-92%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 测试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk go test &lt;span style="color:#75715e"&gt;# Go 测试（-90%，只显示失败）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk pytest &lt;span style="color:#75715e"&gt;# Python 测试（-90%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk cargo test &lt;span style="color:#75715e"&gt;# Rust 测试（-90%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk test &amp;lt;任意命令&amp;gt; &lt;span style="color:#75715e"&gt;# 通用测试包装器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 构建 &amp;amp; Lint&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk cargo build &lt;span style="color:#75715e"&gt;# Cargo 构建（-80%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk golangci-lint run &lt;span style="color:#75715e"&gt;# Go lint（-85%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk ruff check &lt;span style="color:#75715e"&gt;# Python lint（-80%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 容器 &amp;amp; 云&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk docker ps &lt;span style="color:#75715e"&gt;# 紧凑容器列表（-80%）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rtk kubectl pods &lt;span style="color:#75715e"&gt;# 紧凑 Pod 列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="54-配置"&gt;5.4 配置
&lt;/h3&gt;&lt;p&gt;配置文件：&lt;code&gt;~/.config/rtk/config.toml&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[&lt;span style="color:#a6e22e"&gt;hooks&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;exclude_commands&lt;/span&gt; = [&lt;span style="color:#e6db74"&gt;&amp;#34;curl&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;playwright&amp;#34;&lt;/span&gt;] &lt;span style="color:#75715e"&gt;# 排除某些命令不重写&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[&lt;span style="color:#a6e22e"&gt;tee&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;enabled&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 失败时保存完整原始输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;mode&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;failures&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# &amp;#34;failures&amp;#34; / &amp;#34;always&amp;#34; / &amp;#34;never&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;还支持&lt;strong&gt;项目级自定义过滤器&lt;/strong&gt;：在项目根目录创建 &lt;code&gt;.rtk/filters.toml&lt;/code&gt;，可以覆盖或扩展内置规则。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="六为什么能省这么多总结"&gt;六、为什么能省这么多？总结
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;策略&lt;/th&gt;
 &lt;th&gt;节省比例&lt;/th&gt;
 &lt;th&gt;原理&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;删除噪音&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;30-40%&lt;/td&gt;
 &lt;td&gt;git 提示、空行、ANSI 颜色、样板文本&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;结构化解析&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;20-30%&lt;/td&gt;
 &lt;td&gt;JSON/NDJSON 解析，只提取关键字段&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;汇总代替明细&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;15-20%&lt;/td&gt;
 &lt;td&gt;&amp;ldquo;3 passed, 1 failed&amp;rdquo; 代替每个测试的完整输出&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;截断策略&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;10-20%&lt;/td&gt;
 &lt;td&gt;hunk 100 行上限、文件列表 20 个上限&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;短路匹配&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;5-10%&lt;/td&gt;
 &lt;td&gt;match_output：整个输出匹配&amp;quot;成功&amp;quot;→ 返回 &amp;ldquo;ok&amp;rdquo;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;上下文裁剪&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;10-15%&lt;/td&gt;
 &lt;td&gt;diff 中的上下文行只在变更附近保留&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;核心理念就一句话：&lt;strong&gt;语义理解 + 选择性丢弃&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;它知道 AI 编码场景下哪些信息是噪音（通过的测试、git 提示、上下文行），哪些是关键（失败信息、文件名、行号），然后只保留关键部分。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="七go-工程师的视角"&gt;七、Go 工程师的视角
&lt;/h2&gt;&lt;p&gt;RTK 是 Rust 写的。作为 Go 工程师，我第一反应是&amp;quot;为什么不用 Go？&amp;quot;&lt;/p&gt;
&lt;p&gt;答案很直接：&lt;strong&gt;性能&lt;/strong&gt;。每次命令执行都要过一遍代理，&amp;lt; 10ms 的开销要求极致的零成本抽象。Rust 的 &lt;code&gt;lazy_static!&lt;/code&gt; 正则预编译、&lt;code&gt;include_str!&lt;/code&gt; 编译时嵌入、无 GC 停顿，在这种场景下确实更合适。&lt;/p&gt;
&lt;p&gt;但 RTK 的&lt;strong&gt;架构设计&lt;/strong&gt;——Hook 拦截 → 命令路由 → 策略过滤 → 输出压缩——完全是语言无关的。它的 TOML 声明式过滤器设计特别优雅，添加新命令只需要写配置，不需要写代码。这套思路用 Go 完全可以复刻。&lt;/p&gt;
&lt;p&gt;另外，RTK 的源码值得一读。作为一个 40k+ star 的 Rust 项目，它的代码组织、错误处理、测试策略都是很好的学习材料。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;参考链接：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RTK GitHub: &lt;a class="link" href="https://github.com/rtk-ai/rtk" target="_blank" rel="noopener"
 &gt;https://github.com/rtk-ai/rtk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;RTK 官网: &lt;a class="link" href="https://www.rtk-ai.app" target="_blank" rel="noopener"
 &gt;https://www.rtk-ai.app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;RTK 架构文档: &lt;a class="link" href="https://github.com/rtk-ai/rtk/blob/master/ARCHITECTURE.md" target="_blank" rel="noopener"
 &gt;https://github.com/rtk-ai/rtk/blob/master/ARCHITECTURE.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>