关于 sqlite-vec
sqlite-vec 是用于在 SQLite 数据库中存储向量嵌入并执行相似度搜索的扩展,面向无需单独向量数据库的开发者。它支持多种向量类型、元数据筛选和分区键。
主要功能
- 01在 SQLite 中存储向量
- 02KNN 相似度查询
- 03支持 float、int8 和 bit 向量
- 04元数据筛选与分区键
- 05向量运算与量化
适用场景
- 01为 SQLite 应用添加相似度搜索
- 02按元数据筛选近邻结果
- 03按租户划分向量查询
- 04执行向量变换和量化
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ existential-birds/ beagle --skill sqlite-vec安装后在 Claude Code 中输入/sqlite-vec确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/tables.mdoperations.mdqueries.mdsetup.md详细介绍
sqlite-vec
sqlite-vec 是一个轻量级 SQLite 扩展,用于向量相似度搜索。它支持直接在 SQLite 数据库中存储和查询向量嵌入,无需外部向量数据库。
检查关卡
配置存储和 KNN 查询时,请按顺序执行以下步骤;在生产环境中依赖结果或在评审评论中引用结果之前,每一步都必须通过客观检查。
- 维度锁定 —
float[N]、int8[N]或bit[N]中的N必须与嵌入模型的输出长度(以及你应用的任何 Matryoshka 切片)一致。通过标准:CREATE VIRTUAL TABLEDDL 和序列化向量长度(len(vector)或模型文档中注明的维度)中出现相同的N。 - 序列化匹配 — 列类型必须与 Python(或其他语言)的辅助函数相匹配:
float[N]使用serialize_float32,int8[N]使用serialize_int8,bit[N]使用二进制规则。通过标准: 至少对一个已知测试向量执行往返插入,并使用相同的序列化器进行MATCH查询,且返回预期行(例如,k = 1返回该行)。 - 有文档依据的边界声明 — 只有当距离度量选择、元数据筛选运算符、分区键规则或特定版本行为出现在本技能或 资源 下链接的官方文档中时,才能对其作出断言。通过标准: 在将相关声明视为已确认之前,必须在产物(issue、PR 或备注)中引用相关 URL 或文档章节。
快速参考
加载扩展
import sqlite3
import sqlite_vec
from sqlite_vec import serialize_float32
db = sqlite3.connect(":memory:")
db.enable_load_extension(True)
sqlite_vec.load(db)
db.enable_load_extension(False)
基本 KNN 查询
-- Create table
CREATE VIRTUAL TABLE vec_items USING vec0(
embedding float[4]
);
-- Insert vectors (use serialize_float32() in Python)
INSERT INTO vec_items(rowid, embedding)
VALUES (1, X'CDCCCC3DCDCC4C3E9A99993E00008040');
-- KNN query
SELECT rowid, distance
FROM vec_items
WHERE embedding MATCH '[0.3, 0.3, 0.3, 0.3]'
AND k = 10
ORDER BY distance;
核心概念
向量类型
sqlite-vec 支持三种向量元素类型:
-
float[N] - 32 位浮点数(每个元素 4 字节)
- 最常用于嵌入(OpenAI、Cohere 等)
- 示例:文本嵌入 3 小型模型使用
float[1536]
-
int8[N] - 8 位有符号整数(每个元素 1 字节)
- 范围:-128 到 127
- 用于量化嵌入
-
bit[N] - 二进制向量(每个元素 1 位,打包为字节)
- 存储最紧凑
- 用于二进制量化
二进制序列化格式
向量必须以二进制 BLOB 或 JSON 字符串的形式提供。Python 辅助函数:
from sqlite_vec import serialize_float32, serialize_int8
import struct
# Float32 vectors
vector = [0.1, 0.2, 0.3, 0.4]
blob = serialize_float32(vector)
# Equivalent to: struct.pack("%sf" % len(vector), *vector)
# Int8 vectors
int_vector = [1, 2, 3, 4]
blob = serialize_int8(int_vector)
# Equivalent to: struct.pack("%sb" % len(int_vector), *int_vector)
NumPy 数组可以直接传入(必须转换为 float32):
import numpy as np
embedding = np.array([0.1, 0.2, 0.3, 0.4]).astype(np.float32)
db.execute("SELECT vec_length(?)", [embedding])
vec0 虚拟表
vec0 虚拟表是向量搜索的主要数据结构。
创建基本表
CREATE VIRTUAL TABLE vec_documents USING vec0(
document_id integer primary key,
contents_embedding float[768]
);
距离度量
CREATE VIRTUAL TABLE vec_items USING vec0(
embedding float[768] distance_metric=cosine
);
支持的度量:l2(默认)、cosine、hamming(仅限二进制向量)
列类型
vec0 表支持四种列类型:
- 向量列 - 存储嵌入(float[N]、int8[N]、bit[N])
- 元数据列 - 建立索引,可在 KNN 查询中筛选
- 分区键列 - 通过内部分片加快筛选查询
- 辅助列 - 未建立索引的存储(以 + 为前缀)
包含所有列类型的示例:
CREATE VIRTUAL TABLE vec_knowledge_base USING vec0(
document_id integer primary key,
-- Partition keys (sharding)
organization_id integer partition key,
created_month text partition key,
-- Vector column
content_embedding float[768] distance_metric=cosine,
-- Metadata columns (filterable in KNN)
document_type text,
language text,
word_count integer,
is_public boolean,
-- Auxiliary columns (not filterable)
+title text,
+full_content text,
+url text
);
KNN 查询
标准查询语法
SELECT rowid, distance
FROM vec_items
WHERE embedding MATCH ?
AND k = 10
ORDER BY distance;
关键组成部分:
WHERE embedding MATCH ?- 触发 KNN 查询AND k = 10- 限制为 10 个最近邻ORDER BY distance- 按距离由近到远排序结果
元数据筛选
SELECT document_id, distance
FROM vec_movies
WHERE synopsis_embedding MATCH ?
AND k = 5
AND genre = 'scifi'
AND num_reviews BETWEEN 100 AND 500
AND mean_rating > 3.5
AND contains_violence = false
ORDER BY distance;
元数据支持的运算符:=、!=、>、>=、<、<=、BETWEEN
不支持:IS NULL、LIKE、GLOB、REGEXP、标量函数
分区键筛选
SELECT document_id, distance
FROM vec_documents
WHERE contents_embedding MATCH ?
AND k = 20
AND user_id = 123 -- Partition key pre-filters
ORDER BY distance;
分区键支持多租户或按时间分片。最佳实践:
- 每个唯一分区值应至少对应 100 个向量
- 最多使用 1-2 个分区键
- 避免过度分片(唯一值过多)
与源表联接
WITH knn_matches AS (
SELECT document_id, distance
FROM vec_documents
WHERE contents_embedding MATCH ?
AND k = 10
)
SELECT
documents.id,
documents.title,
knn_matches.distance
FROM knn_matches
LEFT JOIN documents ON documents.id = knn_matches.document_id
ORDER BY knn_matches.distance;
距离函数
对于手动计算距离(非 vec0 表):
-- L2 distance
SELECT vec_distance_l2('[1, 2]', '[3, 4]');
-- 2.8284...
-- Cosine distance
SELECT vec_distance_cosine('[1, 1]', '[2, 2]');
-- ~0.0
-- Hamming distance (bit vectors)
SELECT vec_distance_hamming(vec_bit(X'F0'), vec_bit(X'0F'));
-- 8
向量操作
构造函数
-- Float32
SELECT vec_f32('[.1, .2, .3, 4]'); -- Subtype 223
-- Int8
SELECT vec_int8('[1, 2, 3, 4]'); -- Subtype 225
-- Bit
SELECT vec_bit(X'F0'); -- Subtype 224
元数据函数
-- Get length
SELECT vec_length('[1, 2, 3]'); -- 3
-- Get type
SELECT vec_type(vec_int8('[1, 2]')); -- 'int8'
-- Convert to JSON
SELECT vec_to_json(vec_f32('[1, 2]')); -- '[1.000000,2.000000]'
算术运算
-- Add vectors
SELECT vec_to_json(
vec_add('[.1, .2, .3]', '[.4, .5, .6]')
);
-- '[0.500000,0.700000,0.900000]'
-- Subtract vectors
SELECT vec_to_json(
vec_sub('[.1, .2, .3]', '[.4, .5, .6]')
);
-- '[-0.300000,-0.300000,-0.300000]'
转换
-- Normalize (L2 norm)
SELECT vec_to_json(
vec_normalize('[2, 3, 1, -4]')
);
-- '[0.365148,0.547723,0.182574,-0.730297]'
-- Slice (for Matryoshka embeddings)
SELECT vec_to_json(
vec_slice('[1, 2, 3, 4]', 0, 2)
);
-- '[1.000000,2.000000]'
-- Matryoshka pattern: slice then normalize
SELECT vec_normalize(vec_slice(embedding, 0, 256))
FROM vec_items;
量化
-- Binary quantization (positive→1, negative→0)
SELECT vec_quantize_binary('[1, 2, 3, 4, -5, -6, -7, -8]');
-- X'0F'
-- Visualize
SELECT vec_to_json(
vec_quantize_binary('[1, 2, -3, 4, -5, 6, -7, 8]')
);
-- '[0,1,0,0,1,0,1,0]'
迭代
-- Iterate through elements
SELECT rowid, value
FROM vec_each('[1, 2, 3, 4]');
/*
┌───────┬───────┐
│ rowid │ value │
├───────┼───────┤
│ 0 │ 1 │
│ 1 │ 2 │
│ 2 │ 3 │
│ 3 │ 4 │
└───────┴───────┘
*/
Python 集成
完整示例
import sqlite3
import sqlite_vec
from sqlite_vec import serialize_float32
# Setup
db = sqlite3.connect(":memory:")
db.enable_load_extension(True)
sqlite_vec.load(db)
db.enable_load_extension(False)
# Create table
db.execute("""
CREATE VIRTUAL TABLE vec_items USING vec0(
embedding float[4]
)
""")
# Insert vectors
items = [
(1, [0.1, 0.1, 0.1, 0.1]),
(2, [0.2, 0.2, 0.2, 0.2]),
(3, [0.3, 0.3, 0.3, 0.3])
]
with db:
for rowid, vector in items:
db.execute(
"INSERT INTO vec_items(rowid, embedding) VALUES (?, ?)",
[rowid, serialize_float32(vector)]
)
# Query
query = [0.25, 0.25, 0.25, 0.25]
results = db.execute(
"""
SELECT rowid, distance
FROM vec_items
WHERE embedding MATCH ?
AND k = 2
ORDER BY distance
""",
[serialize_float32(query)]
).fetchall()
for rowid, distance in results:
print(f"rowid={rowid}, distance={distance}")
嵌入 API 集成
from openai import OpenAI
from sqlite_vec import serialize_float32
client = OpenAI()
# Generate embedding
response = client.embeddings.create(
input="your text here",
model="text-embedding-3-small"
)
embedding = response.data[0].embedding
# Store in sqlite-vec
db.execute(
"INSERT INTO vec_documents(id, embedding) VALUES(?, ?)",
[doc_id, serialize_float32(embedding)]
)
# Query
query_embedding = client.embeddings.create(
input="search query",
model="text-embedding-3-small"
).data[0].embedding
results = db.execute(
"""
SELECT id, distance
FROM vec_documents
WHERE embedding MATCH ?
AND k = 10
""",
[serialize_float32(query_embedding)]
).fetchall()
性能提示
- 对多租户或按时间筛选的查询,使用分区键
- 将 k 控制在合理范围内(大多数用例为 10-100)
- 尽可能使用元数据列进行筛选
- 为嵌入选择合适的距离度量
- 在事务中批量执行操作
- 对不需要用于筛选的大型数据,使用辅助列
- 确保每个唯一值对应的分区键至少有 100 个向量
常见模式
多租户搜索
CREATE VIRTUAL TABLE vec_docs USING vec0(
doc_id integer primary key,
user_id integer partition key,
embedding float[768]
);
SELECT doc_id, distance
FROM vec_docs
WHERE embedding MATCH ? AND k = 10 AND user_id = 123;
混合搜索
SELECT product_id, distance
FROM vec_products
WHERE embedding MATCH ?
AND k = 20
AND category = 'electronics'
AND price < 1000.0
ORDER BY distance;
Matryoshka 嵌入
-- Adaptive dimensions: slice then normalize
SELECT vec_normalize(vec_slice(embedding, 0, 256))
FROM vec_items;
参考文件
- setup.md - 安装、扩展加载、Python 绑定、NumPy 集成
- tables.md - vec0 表创建、列类型、元数据/分区/辅助列
- queries.md - KNN 查询模式、元数据筛选、分区筛选、优化
- operations.md - 向量操作、构造函数、转换、量化、批量操作
资源
评论
支持 Markdown