用一个索引同时做语义搜索与 LLM 编排(txtai)

txtai 是 Python 写的开源 AI 框架,把向量索引、图网络和关系数据库合成一个 embeddings 数据库,用于语义搜索、RAG 与多模型工作流。这篇文章拆开它的三层结构、四个关键设计,并把它真实的资源代价(1 万条文档索引约占 4.32GB 内存)摊开讲清楚,帮读者判断自己的场景该不该上这套框架。

做检索的人常撞上两道墙。关键词搜索抓不住同义表达,用户搜「退货」,文档里写的是「退款」,词对不上就搜不出来;另一道墙在拼装,向量库一套配置,图数据库一套,关系数据库再一套,光把三边的查询串起来就得写不少胶水代码。txtai 省的是后一道墙的功夫。

txtai 是 Python 写的 AI 框架,把向量索引、图网络和关系数据库合成一个 embeddings 数据库,输入文本、图像或音频,输出的语义搜索结果可以直接作为 LLM 应用的知识源。

用它的人大致两类。一类要给手里的文档、图片、音频建一套按意思检索的搜索,另一类要在这套检索上面接 LLM,做 RAG、问答或者多模型流程。仓库在 GitHub 上有 12990 个 Star、907 个 Fork、113 个 Watcher,开放 issue 13 个,主要语言是 Python(占比 99.6%),许可证为 Apache License 2.0,仓库地址是 https://github.com/neuml/txtai。

txtai 官方仓库的 logo 与框架定位示意图

项目自带 70 多个示例 notebook,从语义搜索、图像检索一路覆盖到知识图谱与 LLM 集成。它面向的是要从数据入库一路走到 API 服务与 agent 编排的场景,只想算一次相似度的人用不上。

它怎么做到的

核心是一个 embeddings 数据库。官方把它的构成描述为向量索引(稀疏与稠密)、图网络和关系数据库的并集。数据进来先过模型转成向量,写进索引;文本、文档、音频、图像、视频都走这条通道。查询进来先做相似度检索拿到候选,再用 SQL 条件、图关系或子索引把关联数据取回。再往上是 pipelines 与 workflows,把多个模型按顺序串成流程;agents 则把 embeddings、pipelines、workflows 和别的 agent 接到一起,自主完成任务。检索默认走哪条路径、图网络怎么建图、每种 ANN 后端在什么条件下被选中,README 在这一层没有展开说明。

几个关键设计

把三类索引放进一个对象

Embeddings 是入口。不加任何参数就带默认模型,几行就能跑起来,这也是官方强调的「开箱默认值」那一部分。

import txtai

embeddings = txtai.Embeddings()
embeddings.index(["Correct", "Not what we hoped"])
embeddings.search("positive", 1)
# [(0, 0.29862046241760254)]

index 接收文本列表,search 返回 (id, 分数) 的元组,上面这段和它的输出来自 README。子索引(subindexes)用来把图像这类别的数据挂进同一个库,检索时可以和主索引一起用。限制出现在写入侧:issue 里有人每 2 秒 upsert 约 100 个文档,撞上 sqlite3.OperationalError: database is locked,这条反馈已经关闭。

Pipelines 与 Workflows

pipelines 由语言模型驱动,跑 LLM prompt、问答、打标、转写、翻译、摘要这些任务;workflows 把多个 pipeline 串起来,并在中间汇总业务逻辑。官方说明一个 txtai 进程既可以是简单的微服务,也可以是多模型工作流。内置 pipeline 的完整清单 README 没有列全,只给到「and more」这个程度。

Agents

agents 负责把 embeddings、pipelines、workflows 以及其他 agents 连起来,自主处理复杂问题。README 没有说明它内部的调度策略、终止条件和失败回退方式。

Web API 与多语言绑定

框架内置 Web API 与 Model Context Protocol(MCP)API,官方绑定覆盖 JavaScript(txtai.js)、Java(txtai.java)、Rust(txtai.rs)与 Go(txtai.go)。起服务靠一份 YAML 配置:

# app.yml
embeddings:
    path: sentence-transformers/all-MiniLM-L6-v2
CONFIG=app.yml uvicorn "txtai.api:app"
curl -X GET "http://localhost:8000/search?query=positive"

有人问过 .NET 绑定,那条 issue 已经关闭,仓库里没有对应的官方绑定。运行结果在终端里看:HTTP 接口直接返回检索结果,索引与配置状态则落在本地的索引目录中。

这样设计的代价

内存是第一笔账。issue 里有人对比过两种加载方式,同样的数据内存占用差了约 3GB:把 agnews 数据集(60MB)的前 1 万条存成索引之后,进程占到约 4.32GB 内存。这是用户侧的实测反馈,不是官方基准,但量级有参考价值。

第二笔是依赖。框架建立在 Python 3.11+、Hugging Face Transformers、Sentence Transformers 和 FastAPI 之上,默认装下来的体积不小,直到 v9.9.0 才补上零依赖的最小安装。近几个版本还在持续加后端:v9.10.0 加入 LiteRT 向量支持与知识蒸馏训练,并新增 URLRetrieve pipeline;v9.11.0 带来 turbovec 这个 ANN 后端与 LiteParse 文本抽取;v9.12.0 继续扩充 ANN 后端(例如 zvec);v9.13.0 加入 LEMUR 学习式多向量检索,同时改进 MUVERA 与 pooling。

第三笔是写入节奏。索引落在 SQLite 上时,高频 upsert 会撞数据库锁,前面提到每 2 秒写一次的场景就是典型例子。

第四笔是概念数量。子索引、external vectors、各种 ANN 后端、图分析各是一套要单独理解的东西,官方用 70 多个 notebook 铺开,学完一遍不算快。

对你的实际影响

把这几笔账换算一下。1 万条文档的索引占约 4.32GB 内存,意味着一台 8GB 的笔记本跑起来要留足余量,同时开别的服务容易吃紧;数据量再上一个量级,就得换更大的机器,或者按仓库说明用容器编排横向扩出去。

默认安装的体积决定 CI 里要不要配缓存,或者干脆用 v9.9.0 起的零依赖最小安装,只装用得上的部分。写入频繁的场景要么拉长保存间隔,要么换外部存储方案——issue 里有人在 AKS 上挂外部存储时碰到子索引重新加载的问题,已经解决,但配置确实需要调。

换个角度看,本地跑意味着数据不必发往外部服务,micromodel 到大型语言模型都能在同一套接口下调用,没有 GPU 也能先起小模型。判断值不值,先看数据量和查询类型:几千条文本、只按关键词找,用不上它;一旦要在同一套东西里混着搜文本与图像、再叠 SQL 过滤,它省下的拼装成本才显出来。

选型时的横向参照

项目适合谁部署方式主要限制什么情况下选它更合适项目地址
txtai要在自有机器上同时做向量检索、图分析和 LLM 编排的 Python 团队pip 安装或 Docker,要求 Python 3.11+默认依赖较重,用户侧反馈 1 万条文档索引约占 4.32GB 内存需要把文本、图像、音频放进同一个索引并配上 SQL 过滤txtai
LEANN想在笔记本上给个人数据建本地 RAG 索引的个人开发者仓库没有说明未逐一核实只需要一个体积更小的本地向量索引,不打算铺开多模型工作流LEANN:把个人数据装进笔记本的本地 RAG 索引
Graphify要把代码库变成可查询知识图谱的开发者仓库没有说明未逐一核实目标集中在代码这一种数据源,要的是更窄的图谱视角Graphify:把代码库变成可查询的知识图谱

这两项与 txtai 只在「本地建索引、再拿去做检索」这一层重合。如果目标只是给个人文档建一个本地向量索引,LEANN 这类更聚焦的工具依赖更轻;如果只想把代码库变成一张知识图谱,Graphify 的路径更直接。txtai 的长处是一套框架同时覆盖多种模态和多种索引形态,代价就写在默认依赖与起步内存上。小规模、单用途的场景,不必为了框架的覆盖面买单。

适合用 txtai 的,是已经有一批多模态数据、需要在同一套检索上接 LLM,并且有能力维护 Python 服务与容器编排的团队。不适合的,是只想做几千条文本的关键词搜索、或者只需要一次性算相似度的脚本场景。

它自带 URLRetrieve pipeline,可以把 URL 内容抓下来入库,这类抓取只应当用于自有资产或已明确授权的目标。抓取第三方站点前要确认 robots 协议与平台条款,误用可能带来法律与平台层面的风险。

焚评:这个项目的量化评分

本项目的选题来自 焚.com(一个按公开公式给 GitHub 项目打分的站)。焚评当前总分 9.9 分(满分 10)。下表是各维度的得分:

评分维度得分
热度动量(权重 25%)10.0 / 10
开发活跃(权重 25%)10.0 / 10
社区响应(权重 15%)10.0 / 10
文档质量(权重 15%)10.0 / 10
发布节奏(权重 10%)9.3 / 10
风险控制(权重 10%)10.0 / 10

评分口径、权重与计算方式见焚.com 的评分方法页;数据随 GitHub 指标刷新,具体数值以焚.com 当前页面为准。本文正文为诀.com 独立撰写,评分数据由焚.com 授权引用。

内容核验说明

txtai 值得留下,是它把选型最难问清的两件事摊开了:一套 embeddings 数据库同时覆盖向量、图与关系查询,以及为此付出的内存与写入代价。4.32GB 内存、SQLite 写锁、AKS 外部存储子索引重载都有出处,属用户反馈而非官方基准,读者可据此估算机器规格。适合已有多种模态数据、要接 LLM 的 Python 团队;

文中 1 万条文档约占 4.32GB 内存、每 2 秒 upsert 触发 SQLite 锁、AKS 外部存储子索引重载等,均出自仓库 Issue 中提交者的自述,诀.com 未独立验证,结果不保证复现;Star、Fork、issue 数取自 GitHub 抓取时点,会随时间变化;焚评评分由焚.com 按公开公式计算,正文为引用。

项目来源与说明

开源项目:neuml(neuml)

本文由诀.com 编辑基于该项目的公开信息独立撰写,属原创解读,不是对项目文档的翻译或转载;文中提到的功能与参数以官方仓库为准,代码与文档版权归原作者所有。

查看项目仓库