txtai Embeddings 方法全解析:从索引构建到语义搜索的完整 API 指南
2026/9/15 15:05:45 网站建设 项目流程

txtai Embeddings 方法全解析:从索引构建到语义搜索的完整 API 指南

【免费下载链接】txtai💡 All-in-one AI framework for semantic search, LLM orchestration and language model workflows项目地址: https://gitcode.com/GitHub_Trending/tx/txtai

txtai 的 Embeddings 是驱动语义搜索的核心引擎:数据被转换为 embeddings 向量,含义相近的概念会得到相近的向量,从而让检索结果“语义相关”而非仅仅“关键词相同”。本文以官方文档 docs/embeddings/methods.md 为主体,结合 Embeddings 源码 与 indexing.md、query.md 等配套指南,系统讲解Embeddings类的构造、索引、搜索、更新删除、持久化与资源管理等全部核心方法,读完即可在自己的项目中构建、保存并检索一个可用的语义搜索引擎。

快速上手:构建并搜索一个 Embeddings 索引

先看一个最小可运行示例,它完整演示了“创建实例 → 索引数据 → 语义搜索”三步流程,也是理解后续所有方法的起点。

from txtai import Embeddings # 创建 embeddings 模型,底层由 sentence-transformers & transformers 驱动 embeddings = Embeddings(path="sentence-transformers/nli-mpnet-base-v2") data = [ "US tops 5 million confirmed virus cases", "Canada's last fully intact ice shelf has suddenly collapsed, " + "forming a Manhattan-sized iceberg", "Beijing mobilises invasion craft along coast as Taiwan tensions escalate", "The National Park Service warns against sacrificing slower friends " + "in a bear attack", "Maine man wins $1M from $25 lottery ticket", "Make huge profits without work, earn up to $100,000 a day" ] # 索引文本列表 embeddings.index(data) print(f"{'Query':20} Best Match") print("-" * 50) # 对每个查询执行语义搜索 for query in ("feel good story", "climate change", "public health story", "war", "wildlife", "asia", "lucky", "dishonest junk"): # 取第一条结果的 uid # search 结果格式: (uid, score) uid = embeddings.search(query, 1)[0][0] # 打印命中的原文 print(f"{query:20} {data[uid]}")

这段代码演示了 txtai 语义搜索的核心价值:"feel good story"会命中彩票中奖的新闻,"climate change"会命中冰架坍塌的报道,"dishonest junk"会命中诈骗广告——检索依据是语义而非字面关键词。

Build:配置驱动的 Embeddings 实例构造

Embeddings实例是配置驱动的,构造函数接受一个配置字典(也可全部以关键字参数传入)。从源码看,构造函数会合并configkwargs为单一字典,再调用configure()加载各类模型组件:

def __init__(self, config=None, models=None, **kwargs): # 合并配置 config = {**config, **kwargs} if config and kwargs else kwargs if kwargs else config # 设置初始配置并加载配置驱动的模型 self.configure(config)

上面示例通过 path 参数指定了具体的向量模型。也可以创建一个不带任何配置的实例:

embeddings = Embeddings()

此时,当加载和检索数据时,会使用默认的 transformers 向量模型sentence-transformers/all-MiniLM-L6-v2对数据做向量化。这一点在源码 base.py 的 defaults 方法中有明确体现:当没有显式模型且允许默认值时,会写入self.config["path"] = "sentence-transformers/all-MiniLM-L6-v2"。向量模型的选型建议可参考模型指南。

从源码结构看,一个Embeddings实例会按需挂载以下组件(对应 base.py 的初始化清单):

属性作用
model稠密向量模型,将数据转换为相似度向量
ann近似最近邻(ANN)索引,存储稠密向量
database文档数据库,存储文档原文内容
scoring稀疏向量/关键词索引(BM25、TF-IDF、SPLADE 等)
graph语义图网络
indexes子索引(subindexes),也是 embeddings 数据库
ids关闭内容存储时的 indexid→id 映射
query查询翻译模型,把自然语言查询转成 SQL

Index:向索引添加数据

创建实例后,下一步就是写入数据:

embeddings.index(rows)

index方法接受一个可迭代对象,其中每个元素支持三种格式:

  • (id, data, tags)—— 默认处理格式

    元素说明
    id唯一记录 id
    data待索引的输入数据,可以是文本、字典或对象
    tags可选的标签字符串,用于在索引时标记/标注数据
  • (id, data)—— 同上,但没有 tags。

  • data—— 单一元素。此时会自动生成唯一 id。注意:对于自动生成的 id,后续的 upsert 和 delete 调用需要先执行一次搜索来拿到目标 id。

data是字典时,文本通过text键传入,二进制对象通过object键传入。需要特别注意的是:必须开启 content 才能存储元数据,开启 objects 才能存储二进制对象;如果提供了idtags键,也会被自动提取。

输入可迭代对象可以是列表或生成器(generator)。对于非常大的数据集,生成器能显著降低内存占用,因为任意时刻只有一部分数据驻留内存。索引的更多细节(向量化、后端设置、稀疏向量、子索引等)参见索引指南。

从源码看,index内部流程(base.py#L103-L153)大致为:初始化索引 → 用Stream流式读取文档 → 用Transform将文档写入数据库并转为向量(结果暂存到临时.npy文件)→ 可选执行 PCA 降维 → 创建 ANN 并把向量灌入 → 再依次索引稀疏评分、子索引与图网络。因此一次index调用是“全量重建”语义:它会覆盖已有索引。

Search:执行语义查询

数据索引完成后即可检索:

embeddings.search(query, limit)

search方法接收两个参数:查询语句与结果条数限制。返回结果的格式取决于是否开启 content 存储:

  • 未存储内容时:返回(id, score)元组列表
  • 存储内容时:返回{**query columns}字典列表(包含查询中涉及的全部列)

自然语言查询与 SQL 查询都被支持。简单自然语言查询示例:

embeddings.search("feel good story") embeddings.search("wildlife")

开启内容存储后,还能使用带过滤条件的 SQL:

SELECT text, flag, actiondate FROM txtai WHERE similar('query') AND flag = 1 AND actiondate >= '2022-01-01'

关于similar()子句、绑定参数、聚合查询、自定义 SQL 函数、混合检索权重、图检索与子索引查询的完整说明,见查询指南。

从搜索执行源码(search/base.py)可以看清查询分派逻辑:当存在图网络且查询是图语句时走图搜索;否则若未强制索引搜索且有数据库,则走“索引 + 数据库”联合搜索(先做相似度检索拿到候选 id,再注入数据库查询完成过滤);其余情况走纯向量索引搜索(稀疏、稠密或两者加权融合的 hybrid 搜索)。limit默认值为 3,hybrid 权重默认值为 0.5。

批量查询

index对应,search也提供了批量版本batchsearch(queries, limit, weights, index, parameters, graph),一次调用可处理多条查询,返回按查询分组的嵌套列表。源码中search就是batchsearch对单条查询的封装(base.py#L356-L376)。

增删改:upsert、delete 与 reindex

Upsert:插入或更新记录

embeddings.upsert(documents)

upsert在索引已存在时,把新数据追加进索引、已存在的数据更新;若索引尚不存在或为空,则退化为标准index操作(源码见 base.py#L166-L169)。与index的全量重建不同,upsert不需要重建整个索引

Delete:删除记录

embeddings.delete(ids)

delete接收 id 列表并返回实际删除的 id 列表(base.py#L203-L258)。从源码看:有数据库时,先从数据库查询 indexid→id 映射,再删除数据库记录;没有数据库时,则在ids映射中按 id 反查内部索引位置;随后依次对 ANN、稀疏评分、子索引和图网络执行删除。

Reindex:换模型/换后端重索引

开启内容存储后,可以调用reindex用新配置重建索引——例如把后端从 faiss 切换为 hnsw,或更换向量模型,而无需回到原始数据

embeddings.reindex(path="sentence-transformers/all-MiniLM-L6-v2", backend="hnsw")

源码(base.py#L260-L290)会保留原有的contentobjects配置以确保数据库得以复用,从已存文档重新向量化并建索引。

其他常用方法

除上述主流程外,Embeddings还提供以下实用方法(均可从 base.py 中查看实现):

  • transform(document, category, index)/batchtransform(documents, ...):把单个/多个文档转换为 embeddings 向量,支持指令式嵌入的category参数与子索引的index参数。
  • similarity(query, data)/batchsimilarity(queries, data):计算查询与一组数据的相似度,返回按得分降序的(id, score)列表(id 即数据在列表中的下标)。实现上利用归一化向量的点积等价于余弦相似度(base.py#L441-L445)。
  • explain(query, texts, limit):解释查询中每个输入 token 的重要程度(分数越高越相关),需要开启内容存储或显式传入texts
  • terms(query)/batchterms(queries):把查询缩减为关键词项,常用于稀疏检索场景。
  • count():返回索引中的元素总数(按 ANN、scoring、database、ids 的顺序择一计算)。
  • info():以 JSON 打印当前索引的完整配置,便于调试。

资源管理:上下文管理器与 close

Embeddings数据库实现了上下文管理器协议(__enter__/__exit__,见 base.py#L85-L89),以下代码块结束后会自动调用 close 释放资源:

# 创建新的 Embeddings 数据库,索引数据并保存 with Embeddings() as embeddings: embeddings.index(rows) embeddings.save(path) # 加载已保存的 Embeddings 数据库并搜索 with Embeddings().load(path) as embeddings: embeddings.search(query)

虽然不显式调用close也通常没问题(资源会被垃圾回收),但最佳实践是:一旦不再需要,就尽早释放数据库连接等共享资源。从源码看,close会依次关闭 ANN、数据库、scoring、图网络、子索引与向量模型,并把所有引用置空。

持久化:save、load 与 exists

索引可以保存到目录或压缩文件中:

# 保存到目录 embeddings.save("/path/to/save") # 保存为压缩包 embeddings.save("/path/to/save/index.tar.gz") # 加载 embeddings.load("/path/to/load")

从 save 实现可以看到,保存会按组件分文件落盘:config(配置)、embeddings(ANN 向量)、lsa(PCA 降维模型)、idsdocuments(数据库)、scoringindexesgraph,路径以.tar.gz.tar.bz2.tar.xz.zip结尾时自动打包为压缩文件。load则按同名规则逐一恢复(base.py#L533-L604),并支持传入config覆盖已有配置。

此外,索引还可以持久化到云存储(仅支持压缩包形式,适合 serverless 或临时计算环境),以及通过exists(path)检查某路径下是否已存在有效索引。更多索引读写场景见索引指南的 Save 章节。

方法背后的架构:多组件协同

Embeddings之所以能同时支持语义搜索、关键词搜索与结构化过滤,是因为它把多种存储与索引组件组合在了一起:内容存储在底层关系数据库中,同时维护 ANN 索引、关键词索引(scoring)与可选的图网络。

以一次带数据库的查询为例,检索链路是:自然语言查询 → 向量化 → ANN 相似度检索得到候选 id → 将这些 id 注入底层 SQL 查询 → 结合动态列过滤返回结构化结果。动态列在 SQLite 中会转换为json_extract子句,客户端-服务器数据库则通过 SQLAlchemy 方言支持(前提是底层引擎具备 JSON 类型支持)。这一“相似度检索 + 结构化过滤”的组合架构,正是 txtai 查询层的核心设计。

延伸阅读

  • Embeddings 总览:语义搜索引擎的定位与入门示例
  • 索引指南:向量化、后端设置、稀疏向量、图与子索引的深入讲解
  • 查询指南:SQL、similar 子句、绑定参数、混合检索、图检索
  • 配置参考:pathcontentobjectsscoringindexes等全部配置项
  • 示例集合:语义搜索相关的完整 notebook 示例列表

【免费下载链接】txtai💡 All-in-one AI framework for semantic search, LLM orchestration and language model workflows项目地址: https://gitcode.com/GitHub_Trending/tx/txtai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询