如何把一文件夹 Markdown 变成可语义检索的向量索引:CocoIndex 最小闭环实操
【免费下载链接】cocoindexIncremental engine for long horizon agents 🌟 Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/co/cocoindex
CocoIndex 是一个增量索引引擎(数据变了只重算变化部分,不每次全量重建),你用几行 Python 声明"数据从哪来、怎么变、存到哪",变更追踪和并发由它底层的 Rust 引擎承担。跟着本文敲完 4 条命令,你本地会得到一个可语义检索的向量索引:3 个 Markdown 文件被分块、嵌入后写入 Postgres,再用一句自然语言问出最相关的段落。
关键词搜不到的那份文档
场景很常见:文档里写的是"注意力机制(attention mechanism)",你搜的却是 "self-attention",关键词检索直接落空。CocoIndex 解决的就是这个问题——把文档转成向量入库,之后按语义相似度找,措辞对不上也能命中;而且它是增量的,改一个文件只重新处理这一个文件,不是整个目录重来。
环境搭起来
启动 Postgres
git clone https://gitcode.com/GitHub_Trending/co/cocoindex cd cocoindex docker compose -f dev/postgres.yaml up -d第一条拉仓库,第二条在 5432 端口起一个带 pgvector(Postgres 的向量类型扩展)的数据库容器,账号、密码、库名都是 cocoindex。
进入示例并安装依赖
cd examples/text_embedding cp .env.example .env pip install -e ..env里已写好POSTGRES_URL=postgres://cocoindex:cocoindex@localhost/cocoindex,和容器一一对应,不用改。pip install -e .装 cocoindex[postgres,sentence_transformers]、asyncpg、pgvector 等依赖,首次运行会顺带下载 all-MiniLM-L6-v2 这个小模型,本地推理,不需要 API key。
主流程只有四个动作
examples/text_embedding/main.py 的核心(完整文件里还有查询逻辑):
@coco.fn(memo=True) # 增量开关:文件内容和代码都没变时,整份跳过 async def process_file(file: FileLike, table: postgres.TableTarget[DocEmbedding]) -> None: text = await file.read_text() # 分块:长文切成约 2000 字符的小段,重叠 500 防止语义被拦腰截断 chunks = _splitter.split(text, chunk_size=2000, chunk_overlap=500, language="markdown") id_gen = IdGenerator() await coco.map(process_chunk, chunks, file.file_path.path, id_gen, table) @coco.fn async def app_main(sourcedir: pathlib.Path) -> None: # 托管目标表:自动建表、增量 upsert、删除已消失文件的行 target_table = await postgres.mount_table_target( PG_DB, table_name=TABLE_NAME, table_schema=await postgres.TableSchema.from_class(DocEmbedding, primary_key=["id"]), pg_schema_name=PG_SCHEMA_NAME, ) target_table.declare_vector_index(column="embedding") # 给 embedding 列建 pgvector 索引 # 数据源:递归扫描目录下所有 .md 文件 files = localfs.walk_dir(sourcedir, recursive=True, path_matcher=PatternFilePathMatcher(included_patterns=["**/*.md"]), live=True) await coco.mount_each(process_file, files.items(), target_table)三个点值得停一下:
RecursiveSplitter:分块器(把长文切成嵌入模型能处理的小段),重叠 500 字符是为了不让一个完整语义断在块边界上。memo=True:引擎按"文件内容 + 函数代码"做指纹缓存,所以没变化的文件重跑时整个跳过——增量更新靠它实现。mount_table_target:建表、更新行、删孤儿行都托管给它,你不用写一行 SQL 迁移。
运行索引并验证结果 ✅
cocoindex update main跑完会打印各函数的处理统计,形如process_file: 3 added, 0 removed, 0 updated——3 正好是 markdown_files/ 目录里的示例文件数。随便改一个 .md 再跑一次,统计会变成1 updated,其余为 0,这就是增量在工作。
直接提问验证,main.py 自带查询入口,用同一个模型把问题转成向量再检索:
python main.py "what is self-attention?"输出是按相似度排序的文本块,每块带 0~1 的分数,例如:
[0.794] 1706.03762v7.md The ... attention ... 段落原文 ---想亲眼看数据落库,用任意 Postgres 客户端连 localhost:5432 的 cocoindex 库,执行SELECT count(*) FROM coco_examples.doc_embeddings;,返回的数就是 3 个文件切出的块总数。
接下来往哪走
- 实时模式:运行
cocoindex update -L main持续监视目录,文件一改动就增量入库,适合文档持续更新的场景。 - 换输入输出:examples/ 目录下还有 PDF、图片、Kafka、知识图谱等三十来个示例,结构同样是"源 → 转换 → 目标"三段。
- 看增量细节:examples/text_embedding/README.md 逐条说明了文件新增、修改、删除时引擎各自做什么。
打开终端把上面几条命令敲完,你的文档库几分钟内就能按意思搜索了。
【免费下载链接】cocoindexIncremental engine for long horizon agents 🌟 Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/co/cocoindex
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考