CocoIndex 快速入门:10分钟从零构建第一个向量索引
【免费下载链接】cocoindexIncremental engine for long horizon agents 🌟 Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/co/cocoindex
用 CocoIndex——一个支持自定义转换逻辑与增量更新的开源数据索引引擎——把本地 Markdown 文件读进来、切成文本块、算出嵌入向量,再带着向量索引写进 PostgreSQL。这就是本文要带你做完的事:数据提取、转换、索引一条线走完,文本检索、图像识别这类场景都建立在这个模式上。
10分钟后的成果:一条可查询的向量索引
跑完本文,你会拥有:
- PostgreSQL 里一张
doc_embeddings表:每个文档块一行,含文本、块位置、嵌入向量,且向量列建了相似度索引; - 一条可重复执行的索引流:源文件新增、修改或删除时,增量重算只动变化的部分;
- 一个模板:之后换数据源、换目标存储,结构不变,只换两端。
环境三步准备 🔧
- 安装引擎与本地嵌入依赖:
pip install -U 'cocoindex[embeddings]'[embeddings]额外装好本地嵌入模型需要的依赖,同时提供cocoindex命令行。
- 起一个带 pgvector 扩展的 PostgreSQL,用来存放向量:
docker compose -f dev/postgres.yaml up -d这份配置就在仓库dev/目录里:镜像pgvector/pgvector:pg17,账号cocoindex,库名cocoindex,端口5432。不想用 Docker 的话,可按 Postgres 连接器文档 自行安装。
- 建好项目目录和放数据的文件夹:
mkdir cocoindex-quickstart && cd cocoindex-quickstart && mkdir markdown_files然后下载 markdown_files.zip,把里面 3 个示例 Markdown 文件解压到markdown_files目录中。
编写 TextEmbedding 索引流:四个任务逐段拆解
先看下数据走向:源数据经过分块、嵌入这些自定义转换,最终落进向量目标存储。
新建main.py,下面按四个任务逐段写入。
接入数据源:声明 LocalFile 与收集器
import cocoindex @cocoindex.flow_def(name="TextEmbedding") def text_embedding_flow( flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope, ): data_scope["documents"] = flow_builder.add_source( cocoindex.sources.LocalFile(path="markdown_files") ) doc_embeddings = data_scope.add_collector()flow_def注册一个名为TextEmbedding的索引流。LocalFile(path="markdown_files")把目录里每个文件变成一行数据;add_collector()建一个收集器,后面逐行攒最终结果。
递归分块:用 SplitRecursively 控制块大小
分块——把长文本切成嵌入模型能处理的小段:
with data_scope["documents"].row() as doc: doc["chunks"] = doc["content"].transform( cocoindex.functions.SplitRecursively(), language="markdown", chunk_size=2000, chunk_overlap=500, )language="markdown"让切分时遵循 Markdown 结构,优先从自然边界下手;chunk_size=2000是每块的目标长度,chunk_overlap=500让相邻两块重叠 500 个字符,避免语义在边界处被截断。每块会自动带一个location字段,记录它在文档中的位置。
生成嵌入:SentenceTransformerEmbed 产出向量
嵌入——把文本转成能计算语义相似度的数值向量:
with doc["chunks"].row() as chunk: chunk["embedding"] = chunk["text"].transform( cocoindex.functions.SentenceTransformerEmbed( model="sentence-transformers/all-MiniLM-L6-v2" ) ) doc_embeddings.collect( filename=doc["filename"], location=chunk["location"], text=chunk["text"], embedding=chunk["embedding"], )all-MiniLM-L6-v2是个轻量模型,CPU 即可运行,首次使用会自动下载。每算出一块向量,collect就把文件名、块位置、原文、向量四列攒进收集器。
声明导出:把向量写入 Postgres 并建索引
doc_embeddings.export( "doc_embeddings", cocoindex.storages.Postgres(), primary_key_fields=["filename", "location"], vector_indexes=[ cocoindex.VectorIndexDef( field_name="embedding", metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY, ) ], )"doc_embeddings"是目标表名;primary_key_fields指定“文件名+块位置”为主键,重复运行时同一块会被更新而不是重复插入;VectorIndexDef在 embedding 列上建余弦相似度索引,之后的相似度搜索就查它。
执行 cocoindex update 并即时验证向量入库 ✅
先告诉索引流数据库在哪:
export COCOINDEX_DATABASE_URL="postgresql://cocoindex:cocoindex@localhost:5432/cocoindex"地址里的账号、库名、端口与前面 Docker 起的 Postgres 完全对应。然后执行更新命令:
cocoindex update main首次运行会看到统计输出:
documents: 3 added, 0 removed, 0 updated3 added表示 3 个示例文档全部完成分块和嵌入;0 removed / 0 updated表示没有需要清理或重算的旧数据。此时进 PostgreSQL 的doc_embeddings表里查:行数等于 3 个文档的总块数,每行的embedding列就是向量,可以直接按余弦相似度检索。
延伸:核心概念、示例目录与可替换的连接器 🧭
- 核心概念:理解状态驱动编程与增量处理的原理,读一遍不亏;
- 示例目录:文本检索、图像搜索、知识图谱等现成玩法,按兴趣挑一个跟做;
- 想换数据源或目标存储,看 连接器一览:本地文件、S3、Kafka、多种向量库都能替换,本文的流结构不用动。
【免费下载链接】cocoindexIncremental engine for long horizon agents 🌟 Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/co/cocoindex
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考