你搭过 RAG 吗?
如果搭过,大概率踩过这个坑:代码库昨天刚改了一版,文档上周更新了一批,但 AI 助手还在用两周前的索引回答你的问题。 它看起来在认真回答,但依据的是旧数据。
更烦的是,要刷新这个索引,你得全量重跑一次 embedding——把所有文件重新切块、重新向量化、重新写库。哪怕只改了一个函数,也得跑全部。
这不是某个工具的 bug,这是批量处理管道的结构性缺陷。
问题的根源:批量管道天生会"过期"
传统的 RAG 数据管道长这样:
- 1
定时任务触发→全量读取源数据→全量 embedding →写入向量库每隔一段时间跑一次,跑完之前数据是旧的,跑完之后马上又开始变旧。
这套方案在数据量小、变化慢的场景下勉强够用。但一旦:
你的 AI Agent 就永远活在"昨天"里。
CocoIndex 的核心思路:只处理变化的 Δ
CocoIndex[1] 是一个开源的增量式数据索引框架,Apache-2.0 协议,Rust 核心 + Python API。
它的核心思路用一句话说清楚:
声明你想要什么目标状态,引擎负责把它保持同步——只处理变化的部分。
项目文档里有一个类比我觉得很准:CocoIndex 之于数据工程,就像 React 之于 UI 开发。
React 你不用手动操作 DOM,只声明"界面应该长这样",框架自动算出最小变更集去更新。CocoIndex 同理——你声明"索引应该包含这些数据",框架自动追踪哪些源文件变了、哪些没变,只重算受影响的行。
两种变化都能处理
这是 CocoIndex 比较实用的一点:它追踪的不只是"数据变了",还包括"代码变了"。
场景一:源文件变化
handbook.md 第 42 行改了一段内容 → 只有包含这段内容的 chunk 重新 embed → 其他几千个 chunk 走缓存
场景二:转换逻辑变化
你把 RecursiveSplitter 的 chunk_size 从 512 改成了 1024 → 只有用这个切分逻辑生成的行需要重算 → 不受影响的数据不动
两种情况,系统都能精确知道哪些行需要重新处理,哪些可以直接复用缓存。
代码长什么样
安装:
- 2
pip install -U cocoindex一个把本地 Markdown 文件做成向量搜索的最小示例:
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
import cocoindex as cocofrom cocoindex.connectors import localfs, postgresfrom cocoindex.ops.text importRecursiveSplitterfrom cocoindex.ops.sentence_transformers importSentenceTransformerEmbedder@coco.fn(memo=True)# memo=True:按 hash(输入)+hash(代码) 缓存async def index_file(file, table):for chunk inRecursiveSplitter().split(await file.read_text()):table.declare_row(text=chunk.text,embedding=embed(chunk.text))@coco.fnasync def main(src):table = await postgres.mount_table_target(PG, table_name="docs")table.declare_vector_index(column="embedding")await coco.mount_each(index_file, localfs.walk_dir(src).items(), table)# 首次:全量建索引。之后再跑:只处理改动的文件coco.App(coco.AppConfig(name="docs"), main, src="./docs").update_blocking()
关键在 @coco.fn(memo=True):这个装饰器让引擎把每次执行的输入和代码的哈希值都记下来,下次运行时对比,一致就跳过,不一致才重算。
支持的数据源和目标存储
数据源:
目标存储:
官方仓库里有 20+ 个开箱即用的示例,覆盖代码库索引、PDF RAG、会议记录转知识图谱、HN 话题提取等常见场景。
旗舰应用:CocoIndex-code
官方基于自己的框架做了一个代码智能 MCP Server,叫 CocoIndex-code。
它让 Claude Code、Cursor 这类 AI 编程工具实时感知整个代码库:
根据项目文档,实测数据是 Token 消耗降低约 70%,re-index 缓存命中率 80-90%。
什么时候值得用
不是所有 RAG 场景都需要 CocoIndex。
值得用:
不一定需要:
判断标准很简单:如果你已经在为"数据过期"或"重跑太贵"烦恼,就是该用的时候了。
一个可以快速验证的实验
如果你有一个现成的 RAG 项目,可以用这个步骤验证 CocoIndex 是否值得接入:
pip install -U cocoindex,跑官方的 text_embedding 示例(约 50 行 Python)2.改动一个源文件,重新跑一次3.观察日志:哪些文件走了缓存、哪些重新计算了4.对比全量重跑的时间和 API 调用次数整个实验 30 分钟内能跑完,不需要改你现有的任何代码。
你现在用的 RAG 方案,多久全量刷新一次?遇到过数据过期的问题吗?欢迎评论区聊聊。
参考来源: 本文核心内容基于 CocoIndex 开源项目(https://github.com/cocoindex-io/cocoindex,Apache-2.0 协议)及其官方文档(https://cocoindex.io/docs)整理,文中代码示例来自项目官方 examples 目录,性能数据引自项目 README 及官方文档。
本文内链接
CocoIndex: https://github.com/cocoindex-io/cocoindex
夜雨聆风