开发者生态
morning
更好的长文档矢量搜索:Manticore 搜索中的分块
摘要
Say you are building search over your team's internal documentation — guides, runbooks, postmortems. You have a table with auto embeddings : you insert text, Manticore runs the model and fills the vec...
the
and
document
you
search
Manticore
vector
column
with
model
2026-09-17
1 阅读
约7分钟阅读
GloriaVinogrado
字号:
假设您正在对团队的内部文档(指南、操作手册、事后分析)进行搜索。您有一个带有自动嵌入的表:您插入文本,Manticore 运行模型并为您填充向量列。 (如果您不熟悉,请从 Manticore 中的矢量搜索开始。)您加载了一个 4,000 字的文档。插入成功。搜索有效。一切看起来都很好。除了您选择的模型有一个包含 512 个令牌的输入窗口外,该文档的长度约为 5,000 个令牌。该模型读取了前 380 个单词,并丢弃了其余 3,600 个单词。超过该点的文档中的任何内容都无法检索,也没有任何地方告诉您。嵌入也可能不代表整个文档。到目前为止,您通常会自己将文档分成几个部分,为每个部分创建嵌入,然后如果您想要文档搜索而不是块搜索,则计算出如何组合结果。 Manticore 现在在表定义中处理此问题:将 chunk_strategy 添加到 CREATE TABLE 中的向量列,并且 Manticore 将每个文档拆分为块,嵌入每个块,并搜索所有块: DROP TABLE IF EXISTS docs;创建表文档(标题文本、内容文本、块 float_vector_array knn_type = 'hnsw' hnsw_similarity = 'cosine' model_name = 'Xenova/all-MiniLM-L6-v2' from = 'title,content' chunk_strategy = 'sentence' max_tokens = '256' Overlap_tokens = '32' );这就是全部功能。没有摄取管道,没有拆分器库,没有用于块的第二个表,没有用于将块命中折叠回文档的 GROUP BY。 TL;DR 五种策略:截断(旧的默认)、均值、固定、递归、句子。在模型支持的向量列上使用 chunk_strategy 设置。 truncate 和mean 为每个文档生成一个向量并在float_vector 列上工作。固定、递归和句子产生很多,因此它们需要一个 float_vector_array 列。文档仍然是一个搜索结果。块单独竞争,Manticore 返回文档一次,并用 knn_dist() 报告到其最近块的距离。 k 计算文档数,而不是块数。调整旋钮:max_tokens(块大小)、overlap_tokens(邻居之间共享令牌)、max_chunks(每个文档的上限)。根据 Manticore 手册(189 页,约 298k 字)进行测量:对于隐藏在模型窗口之外的内容,recall@5 从 55.1% → 83.3% 变化,MRR 从 0.44 → 0.70 变化,内存约为 2.5 倍,摄取时间约为 4 倍。查询永远不会被分块。查询足够短,可以作为一个整体嵌入;仅存储的文档被分割。通过一个小示例显示的问题 假设您有四个文档: 备份和恢复 Runbook — 大约 700 个单词,大约 900 个标记。备份计划、保留、恢复练习、凭证、容量规划。最后一部分介绍如何轮换复制端口使用的 TLS 证书。监控和警报指南 - 不相关。 CLI 入门 — 无关。 HTTP API 的 TLS 和证书——一个简短的页面,完全是关于证书的,从不提及轮换或复制。您可以使用以下命令创建表并添加文档。因此,我们所拥有的是:一张表,三个具有相同源文本的向量列——每个策略一列。单个 INSERT 填充所有三个,因此比较条件是相同的: DROP TABLE IF EXISTS docs;创建表文档(标题文本,正文文本,v_truncate float_vector knn_type = 'hnsw' hnsw_similarity = 'cosine' model_name = 'Xenova/all-MiniLM-L6-v2' from = 'title,body' , v_mean float_vector knn_type = 'hnsw' hnsw_similarity = 'cosine' model_name = 'Xenova/all-MiniLM-L6-v2' from = 'title,body' chunk_strategy = 'mean' , v_sentence float_vector_array knn_type = 'hnsw' hnsw_similarity = '余弦' model_name = 'Xenova/all-MiniLM-L6-v2' from = 'title,body' chunk_strategy = '句子' max_tokens = '128'重叠令牌='32');插入四个文档 INSERT INTO docs (id, title, body) VALUES ( 1 , 'Backup and Restore Runbook' , '每夜备份在 02:00 UTC 从备用节点运行。该作业对每个表目录进行快照,写入清单,并将结果上传到对象存储。保留为 30 个每日副本、12 个每月副本和一个每年副本。恢复演练在每个月的第一个星期一针对临时集群运行。演练仅当对已恢复数据的全文搜索返回与生产相同的文档计数时,才算通过。在恢复之前,冻结目标集群,以便在替换文件时不会写入数据。如果校验和不匹配,则停止:部分恢复比不恢复更糟糕,因为集群将启动并静默地服务一半的文件到位,然后解冻并让复制赶上。观察队列深度,如果十分钟内没有耗尽,则节点可能仍在从冷存储中读取数据,并且需要预热通道才能为流量提供服务。
这篇文章对您有帮助吗?
订阅66必读
每日精选科技资讯,直达你的邮箱