跳到主要内容

txtai — 这是什么 / 全景图 / 阅读地图

30 秒导读: txtai 是一个 all-in-one 的 AI 框架,但本套文档只聚焦它的检索心脏——「嵌入数据库」(embeddings database):一个把「稠密向量索引 + 稀疏关键词索引 + 关系数据库 + 图网络」四种后端焊在一起的对象,专门服务语义搜索RAG(检索增强生成,先查资料再让大模型作答)

本页是索引页(顶层路由)。 它只覆盖三件事:这是什么、全景怎么转、该往哪读。任何单一机制的原理与代码走读都留给 01–06 章,本页不深入、不与后续重复。


1. 这是什么(零基础也能懂)

一句话定义。 txtai 是一个开源 AI 框架;它对外自称「all-in-one AI framework for semantic search, LLM orchestration and language model workflows」(setup.py:181)。

但本文只讲它的一个部件。 按官方 README 的原话,txtai 最关键的组件是嵌入数据库,它是「向量索引(稀疏 + 稠密)、图网络、关系数据库的联合体」(README.md 顶部特性段)。搜索、RAG、agent 都建在这块地基上,所以理解 txtai 的检索能力 = 理解嵌入数据库。

它给谁、解决什么问题。 传统搜索按关键词匹配;语义搜索理解意思——查「positive」,能命中「Correct」这种词面不同但含义相近的结果。假设你有一堆文档、图片、音频,想让程序「按意思找」,或想给大模型接一个外部知识源,txtai 就是那层「把数据变成可被意思检索的库」。

它能做什么(本文范围内):

  • 把文本 / 文档 / 图像 / 音频 / 视频转成向量并建索引
  • 稠密向量搜索、稀疏关键词搜索、两者混合(hybrid)搜索
  • 用 SQL 在向量库上做带过滤条件的检索
  • 把结果组织成图网络,跑关系检索与主题建模

用起来什么样。 最小示例来自 README——三行建库、一行搜索:

# 示意(取自 README.md),非源码走读
import txtai

embeddings = txtai.Embeddings() # 用默认句向量模型,零配置
embeddings.index(["Correct", "Not what we hoped"])
embeddings.search("positive", 1)
# [(0, 0.29862046241760254)] # 命中 "Correct",按语义而非词面

一句话直觉 / 类比。 把嵌入数据库想成一台多引擎的搜索发动机:同一批数据,既能「按意思」查(稠密向量),又能「按词」查(稀疏关键词),还能「带条件」查(SQL),还能「顺着关系」查(图)——而它们共享同一份 id 和内容,所以可以随意组合。这套「可插拔」正是 txtai 的设计取向:setup.pyann / database / graph / scoring / vectors 全部拆成可选依赖分组setup.py:57-161),你只装用得到的引擎。

本节到此不碰任何底层代码。往下才进入「大盘怎么转」。


2. 全景图(一个 Embeddings 里的『五联合』)

一个 Embeddings 实例(embeddings/base.py:22)就是一个装配现场:它按你的 config,把最多五个协作部件挂到自己身上(__init__ 里的 self.ann / self.scoring / self.database / self.graph / self.model,见 embeddings/base.py:46-65)。README 说的「联合体」,落到代码就是这五个字段。

怎么读下面这张图: 上半是四个数据存储 / 索引后端(查询时被路由到的目标),下半的向量模型是给它们供料的公共上游;中间的 Embeddings 是编排者,谁都不直接对话,全经它转发。

┌──────────────────────────────┐
文档流 documents → │ Embeddings (编排 / 路由) │ ← 查询 query
│ embeddings/base.py:22 │
└───┬────────┬────────┬─────────┘
┌───────────────────┘ │ └───────────────────┐
▼ ▼ ▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌──────────┐ ┌───────────┐ (content 存哪)
│ ① 稠密索引 │ │ ② 稀疏索引 │ │ ④ 图网络 │ │ ③ 关系数据库│
│ ANN 近邻 │ │ scoring │ │ graph │ │ database │
│ self.ann │ │self.scoring│ │self.graph │ │self.database│
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│「按意思」 │「按词」 │「顺关系」 │「按条件/存原文」
└──────────┬──────┴─────────────┴───────────────┘

┌──────────────────┐
│ ⑤ 向量模型 model │ 文本/文档 → 向量,供 ①②④ 使用
│ self.model │ (VectorsFactory 造)
└──────────────────┘

五个部件一句话职责(谁造它、在哪,详见对应章):

#部件干什么(白话)装配入口(base.py 符号)详见章
稠密索引 ANN「按意思找」——近似最近邻搜向量createann (:958)03
稀疏索引 scoring「按词找」——bm25/tfidf 等关键词打分createscoring (:1054)03
关系数据库 database存原文 + 用 SQL 带条件检索(content store)createdatabase (:972)05
图网络 graph顺着节点关系检索、跑主题建模creategraph (:994)06
向量模型 model把数据变成向量,喂给 ①②④loadvectors (:888)02

五个部件都可缺席:只挂 ① 就是纯向量库,① + ② 就是 hybrid,③ 决定「结果是 (id, score) 元组还是带原文的 dict」。它们如何按 config 被选择性创建,是 01 章的主题。


3. 主线走一遍(高层,不进代码)

嵌入数据库有两条主干路径:建索引(index)搜索(search)。这里只画流向,代码级走读见 01/04 章。

3.1 index 路径:文档流 → 分发 + 向量化 → 建 ANN

入口是 Embeddings.indexembeddings/base.py:103)。它不亲自干活,而是把文档流交给两个助手对象 StreamTransformembeddings/base.py:117-122),后者一边把原始文档分发进各数据存储,一边向量化

documents

▼ Stream + Transform (index/stream.py:9 · index/transform.py:13)
├─▶ 灌入 database / scoring / graph 的原文与词项 (分发 side)
└─▶ model 向量化 → (ids, dimensions, embeddings) (向量 side)

▼ base.py:133-136
createann → ann.index(embeddings) 建稠密索引

之后按需依次收尾: ▼ base.py:144-153
scoring.index() → indexes.index() → graph.index()

一个关键时序细节:稀疏 scoring 必须在图之前建好,因为图会用到它——代码里明确注释「This must occur before graph index in order to be available to the graph」(embeddings/base.py:143)。

3.2 search 路径:query → 路由(图 / DB / 向量)→ 融合

入口是 Embeddings.searchbatchsearchembeddings/base.py:356 / :378),真正的调度在 Search.__call__embeddings/search/base.py:44)。它按「有没有对应部件 + query 长什么样」三选一路由

query ─▶ Search.__call__ (search/base.py:44)

├─ 是图查询?(graph.isquery) ─▶ graphsearch 顺关系找 [06]
│ search/base.py:75-76
├─ 有 database 且非 indexonly? ─▶ dbsearch SQL+索引 [05]
│ search/base.py:79-80
└─ 否则 ─▶ search() 向量检索 [03/04]
search/base.py:83

├─ 只有 ann → 稠密搜索
├─ 只有 scoring → 稀疏搜索
└─ 两者都有 hybrid → Hybrid 融合两路分数
search/base.py:107-119

融合(fusion) 是 hybrid 的精华:稠密与稀疏各取更大候选集(limit*10),再由 Hybridembeddings/search/hybrid.py:8)按权重把两套分数合成一套。默认权重 0.5、默认 limit 3(embeddings/search/base.py:63-64)。融合策略细节留给 04 章

3.3 装配关系概览:configure 与五个 create*

上面所有部件不是在 __init__ 里一次造齐的,而是由 config 驱动、分两个时机装配:

  • configureembeddings/base.py:761 ——加载配置时就绪的:词权重 scoring、向量模型 model、query 模型。
  • initindexembeddings/base.py:785 ——建索引前才创建的:database、(稀疏)scoring、subindexes、graph;ANN 则要等向量算完才 createannbase.py:133)。

也就是说 config 里写了 path / content / scoring / graph / indexes 这些键,分别触发 createann / createdatabase / createscoring / creategraph / createindexesbase.py:9581052)去挂对应部件;什么都不写时 defaults() 会兜底塞一个默认句向量模型 sentence-transformers/all-MiniLM-L6-v2embeddings/base.py:843)。这条「config → 装配」链是 01 章的核心。


4. 阅读地图(01–06 每章一句话)

按「由浅入深」建议顺序读;每章都独立带 frontmatter 和代码地图。

文件一句话导航
index.md(本页)这是什么 / 五联合全景 / 两条主线 / 阅读地图
0101-embeddings-database.mdEmbeddings 编排类:config 如何驱动装配,index/upsert/delete/save/load 的完整生命周期
0202-vectorization.md向量化管线:Stream/TransformVectorsFactory,文本/文档/多模态如何变成向量
0303-indexes-dense-sparse.md两类索引后端:稠密 ANN(faiss/hnsw/…)与稀疏 scoring(bm25/tfidf/…)各自怎么建、怎么搜
0404-search-and-fusion.md搜索路由 Search 与混合分数融合 Hybrid:稠密+稀疏如何合成一套排名
0505-sql-and-database.mdSQL 驱动检索与关系数据库层:content store、dbsearch、带过滤条件的语义查询
0606-graph.md图网络子系统:关系检索、子图、基于社区发现的主题建模

怎么用这张地图(给 agent): 想改「查得准不准」看 03/04;想改「存什么、按什么条件筛」看 05;想「顺着关系/做主题」看 06;想搞清「整台机器怎么被 config 装出来」看 01;想接入新模型/多模态看 02。


5. 巧妙之处速览(精华,细节见各章)

只点「妙在哪」,不展开——展开在对应章。

  • 一个对象、五种检索,靠 config 拼装。 没有五个各自为政的类库,只有一个 Embeddings 按配置挂载部件(createann/createdatabase/creategraph/createscoringbase.py:958-1073)。用户装什么依赖、写什么 config,就得到什么形态的库——可插拔在架构层就落实了。→ 01
  • shortcut 配置自动展开。keyword/sparse/hybrid/graph: true 这类简写,defaults() 会把它展开成完整 scoring/graph 配置(base.py:833-875),并在 hybrid 时顺手打开 dense。低门槛、少样板。→ 01
  • hybrid 先各扩 10 倍候选再融合。 稠密与稀疏各取 limit*10 再交给 Hybrid 合并(search/base.py:108-119),避免任一路早早截断丢掉好结果。→ 04
  • content 开关决定返回形态。 有 database 返回带原文的 dict,没有则返回 (id, score);无 database 时还得自己维护 ids 映射(base.py:139-140createids:1016)。一个开关切换两种数据契约。→ 05
  • 建索引有严格时序。 scoring 先于 graph、graph 用 Search(indexonly=True) 复用向量检索来连边(base.py:143-153)——部件间的依赖被显式排序,不是随手调用。→ 01 / 06

6. 顶层代码地图(导航索引)

顶层跳转表。列真实符号名便于 grep 定位(行号可能随上游漂移,符号名较稳)。逐部件的细粒度代码地图在各章末尾。

主题文件路径(相对克隆根 src/python/txtai/符号
编排类本体embeddings/base.pyEmbeddings
建索引入口embeddings/base.pyEmbeddings.index
增量写入 / 删除embeddings/base.pyEmbeddings.upsert · Embeddings.delete
搜索入口embeddings/base.pyEmbeddings.search · Embeddings.batchsearch
config → 装配embeddings/base.pyEmbeddings.configure · Embeddings.initindex · Embeddings.defaults
五个部件工厂调用embeddings/base.pycreateann · createdatabase · creategraph · createscoring · loadvectors
落库 + 向量化助手embeddings/index/stream.py · embeddings/index/transform.pyStream · Transform
搜索路由embeddings/search/base.pySearch · Search.__call__ · Search.search
混合融合embeddings/search/hybrid.pyHybrid
稠密后端工厂ann/dense/factory.pyANNFactory(faiss/hnsw/annoy/numpy/torch/pgvector/sqlite/…)
稀疏打分工厂scoring/factory.pyScoringFactory(bm25/tfidf/sif/pgtext/sparse)
关系库工厂database/factory.pyDatabaseFactory(sqlite/duckdb/client)
图后端工厂graph/factory.pyGraphFactory(networkx/rdbms)
向量模型工厂vectors/base.pyVectorsFactory
可选依赖分组(可插拔证据)克隆根 setup.pyextrasann/database/graph/scoring/vectors

本页是索引页,止于「是什么 / 怎么转 / 去哪读」。任何机制的原理演示、短源码走读、坑与边界,请进入上表指向的对应章节——本页刻意不与它们重叠。