← 返回信息流
AI 资讯Hacker News·2 小时前

开发者用Rust实现ContextCodeCache

原标题:Show HN: ContextCodeCache in Rust

速览

该项目名为ContextCodeCache,使用Rust语言实现,旨在提供上下文代码的缓存功能。它可能用于加速代码生成或AI推理中的上下文管理。该展示在Hacker News上引发关注,展示了Rust在系统编程中的高效性能。

AI 深度解读

背景

随着大型语言模型(LLM)和 AI 代理越来越多地被用于代码分析与自动补全,一个关键问题浮现:如何让代理在无需完整解析项目的情况下,高效获取最新、最完整的代码上下文?传统的做法是让代理读取整个源文件或依赖外部索引服务,但这要么成本高昂(token 消耗大),要么延迟高(动态构建索引)。Hacker News 上发布的 ContextCodeCache(Rust 实现)正是为了解决这一痛点:它通过预先扫描项目,生成一个紧凑、机器可读的缓存目录(.ccc),涵盖每个源文件的常量、函数(含返回类型和文档摘要)、文件内调用图以及标记注释(TODO/FIXME 等)。设计目标是给 AI 代理提供一个廉价、始终新鲜的代码项目索引。

核心内容

ContextCodeCache 是一个用 Rust 编写的命令行工具,依赖 tree-sitter 解析器来准确提取代码结构信息。它构建后生成可执行文件 ccc,提供多个子命令:

  • install:将当前运行的二进制文件复制到用户本地 bin 目录(默认 ~/.local/bin),无需 sudo;支持通过 --dir 指定目录、--force 覆盖已有文件。如果目标目录不在 $PATH 中会打印添加提示。
  • scan [PATH]:扫描指定路径(默认为当前目录),重新生成 .ccc 目录。如果加上 --tokens 参数,还会预编码缓存为 token 流。
  • check [PATH]:检查 .ccc 缓存是否过时(通过比较内存重新生成的结果与已提交的缓存,忽略生成时间戳)。如果过时则返回非零退出码,适合 CI 集成。支持 --format json 输出 JSON 格式的差异信息。
  • tokenize [PATH]:对已有的 .ccc 目录进行 token 预编码,生成 tokens.bintokens.json

生成的 .ccc/ 目录结构如下:

.ccc/
├── CCC.md          # 索引:总览 + 每文件一行
├── src-main.rs.md  # <module>-<file>.<ext>.md,每源文件一个
└── src-math.rs.md

每个源文件的 .md 条目采用固定格式,例如 math.rs.md

# math.rs.md (yyyymmdd-hh-mm-ss) UTC
# source: src/math.rs [rust]
# const
- L4@PI:f64
# funcs
- L7:8@square:f64 // Square a number.
- L12:8@circle_area:f64 // Area of a circle with the given radius.
# refs
- circle_area@L14 calls L7:8@square:f64
# note
- @L13 NOTE: uses the truncated PI above, so results are approximate.

各部分的含义:

  • const:文件级常量/静态变量,格式为 L<行号>@<名称>:<类型>。对于不同语言使用对应规则:Rust 仅识别 const/static,Go 识别 const/var,Python 仅考虑全大写下划线命名(SHOUTING_SNEK_CASE)的模块级绑定,JS/TS 仅考虑 const 声明(不处理 let/var)。类/实现的属性被视为成员而非文件常量。
  • funcs:函数定义,格式为 L<起始行>:<起始列>@<名称>:<返回类型> // 文档摘要
  • refs:文件内调用图,通过作用域解析(不仅仅是名称匹配)确定调用关系。格式为 <调用者>@L<行号> calls L<调用点行>:<列>@<被调用函数>:<返回类型>。裸调用(如 foo())会绑定到同文件自由函数;接收者调用(self.foo()this.foo()、Go 的 recv.Foo())会绑定到所属类型上的方法。对其他接收者的调用(如 other.foo())因缺少类型信息不会生成边,避免猜测。
  • note:标记注释(TODO、FIXME、XXX、HACK、BUG、NOTE、SAFETY),格式为 @L<行号> <类型>: <注释内容>

工具内建了示例项目 example/ 及其生成的 example/.ccc/ 供参考。

Token 流功能: 生成的 token 流(通过 ccc tokenizeccc scan --tokens)使用预训练的 tiktoken 词汇表(默认 o200k_base,也可用 --encoding cl100k_base),将整个 .ccc 语料编码为小端序 u32 token ID 并写入 tokens.bin,同时 tokens.json 提供索引(编码类型、布局和每个文件的偏移量+长度)。消费者可以直接读取 tokens.bin 为 u32 切片,无需重新分词。TokenCache 加载器实现了这一逻辑,每次 tokenize 运行都会验证持久流解码后与原始语料字节一致。注意:该 token 流不兼容 Anthropic 模型(如 Claude),但可用于共享 OpenAI 词汇表的模型(如 DeepSeek V4-Pro),或仅用于粗略大小估算。使用 Claude 时,建议直接使用 .ccc 的 markdown 作为上下文。tokens.json 中包含 approximate: true 的提示。

支持语言:目前支持 Rust、Python、JavaScript、TypeScript(含 TSX)和 Go,均通过 tree-sitter 解析。不支持的文件会被跳过;隐藏目录、常见构建/供应商目录(如 targetnode_modules)以及 .gitignore 规则会被尊重。添加新语言只需扩展 src/languages.rs(映射扩展名、语法和节点种类集合),提取器 src/extract.rs 是语法无关的。

CI 集成:建议在 CI 中添加 ccc check . 步骤,缓存过期则构建失败。项目提供了内置工作流 .github/workflows/ccc-update.yaml,在推送至主分支和每周定时执行时,通过 ccc check --format json 检查每个根目录,若缓存过期则重新生成并创建由 CCC-bot 提交的 PR。check 步骤会暴露 stalechanged_files(JSON 数组)和 changed_count 作为下游作业的输出。通过环境变量 CCC_ROOTS 可指定项目的缓存目录。

关键要点

  • 设计目标:为 AI 代理提供廉价、始终新鲜的代码索引,避免动态解析的高昂成本。
  • 存储格式.ccc 目录中的纯文本 Markdown 文件,清晰展示每个源文件的常量、函数、调用关系和注释标记,机器可读且容易调试。
  • 调用图准确性:通过作用域解析而非简单名称匹配,减少误报;对无法确定的调用(如外部对象的方法)不生成边。
  • 语言支持:基于 tree-sitter 解析,当前支持 Rust、Python、JS/TS、Go,扩展性良好。
  • Token 预编码:支持 tiktoken 格式的 token 流,便于直接消费(如 DeepSeek V4-Pro),但明确说明不兼容 Anthropic 模型(Claude)。
  • CI 自动维护:通过 ccc check 和内置 GitHub Action 工作流,确保缓存始终与源文件同步,并在过期时自动创建 PR 更新。
  • 安装简便ccc install 将二进制放入用户本地目录,无需 sudo,降低使用门槛。
  • 版本要求:需要 Rust ≥ 1.77(因 tree-sitter 0.25 栈,部分传递依赖使用了 edition 2024)。

意义与影响

ContextCodeCache 填补了 AI 代理与代码仓库之间轻量级、静态索引的空白。传统上,代理要么直接读取全部源文件(消耗大量 token),要么依赖外部代码库索引服务(增加延迟和依赖)。该工具通过本地扫描生成紧凑的、可直接作为上下文注入的 Markdown 摘要,大幅降低了 token 消耗

查看原文 →github.com