# SQLite-Vec 向量库使用指南 > 基于 HR 智能助手项目实战经验总结 > 最后更新:2026-03-12 --- ## 📌 什么是 sqlite-vec? sqlite-vec 是 SQLite 的扩展插件,让 SQLite 支持**向量存储**和**相似度搜索**。适合轻量级 RAG 应用,无需额外部署向量数据库服务。 **核心优势:** - ✅ 轻量级 - 只需 SQLite + 一个扩展 - ✅ 零部署 - 单文件数据库,随处运行 - ✅ 高性能 - C 语言实现,本地计算 - ✅ 易集成 - Python API 简洁 --- ## 🚀 完整代码示例 ```python ### 向量数据库存储 import sqlite3 import sqlite_vec import numpy as np class sqlightvec: def __init__(self, db_path='vector_db.db'): """初始化SQLite-Vec连接""" # -------------------------- 1. 初始化数据库连接(解决权限问题) -------------------------- # 创建连接并启用扩展加载权限 self.conn = sqlite3.connect(db_path) # 关键:启用扩展加载权限(解决 not authorized 错误) self.conn.enable_load_extension(True) # 启用sqlite-vec扩展 sqlite_vec.load(self.conn) # 关闭扩展加载权限(安全最佳实践) self.conn.enable_load_extension(False) # 创建游标(作为实例变量,供其他方法使用) self.cursor = self.conn.cursor() # -------------------------- 2. 创建带向量字段的表 -------------------------- def create_vector_table(self, VECTOR_DIM=768): """创建包含向量字段的虚拟表""" # 向量维度根据你的embedding结果调整(示例用768维,可改为你的实际维度) # 执行建表语句 - 使用 VIRTUAL TABLE 和 float[维度] 语法 self.cursor.execute(f""" CREATE VIRTUAL TABLE IF NOT EXISTS document_vectors USING vec0( embedding float[{VECTOR_DIM}], -- 向量字段(float类型,指定维度) content TEXT, -- 原始文本内容 id INTEGER PRIMARY KEY -- 主键ID ) """) self.conn.commit() print("向量表创建成功(或已存在)") # -------------------------- 3. 插入向量数据 -------------------------- def insert_vector(self, content: str, embedding: np.ndarray): """ 插入向量数据到表中 :param content: 文本内容 :param embedding: 向量数组(numpy数组或列表) """ # 确保向量是float32类型并展平 embedding = np.array(embedding, dtype=np.float32).flatten() # 插入数据 - 使用 serialize_float32 序列化向量 self.cursor.execute(""" INSERT INTO document_vectors (content, embedding) VALUES (?, ?) """, (content, sqlite_vec.serialize_float32(embedding))) # 使用 sqlite_vec 序列化 self.conn.commit() print(f"成功插入向量:{content[:20]}...") # -------------------------- 4. 向量相似度检索 -------------------------- def search_similar_vectors(self, query_embedding: np.ndarray, top_k: int = 5): """ 检索与查询向量最相似的结果 :param query_embedding: 查询向量 :param top_k: 返回前k个相似结果 :return: 相似结果列表(包含内容、相似度) """ # 预处理查询向量 query_embedding = np.array(query_embedding, dtype=np.float32).flatten() # 执行相似度检索 - 使用正确的函数名 vec_distance_cosine self.cursor.execute(f""" SELECT id, content, vec_distance_cosine(embedding, ?) as distance FROM document_vectors ORDER BY distance ASC -- 余弦距离越小越相似 LIMIT {top_k} """, (sqlite_vec.serialize_float32(query_embedding),)) # 同样需要序列化 # 获取结果 results = self.cursor.fetchall() # 格式化输出 - 距离转相似度 formatted_results = [ { "id": res[0], "content": res[1], "cosine_similarity": 1 - res[2] # 余弦距离转相似度 } for res in results ] return formatted_results # -------------------------- 5. 关闭连接 -------------------------- def close(self): """关闭数据库连接""" self.conn.close() print("数据库连接已关闭") ``` --- ## 📚 核心知识点 ### 1. 安装 ```bash pip install sqlite-vec ``` 或者下载预编译扩展: - GitHub Releases: https://github.com/asg017/sqlite-vec/releases ### 2. 初始化(关键步骤) ```python import sqlite3 import sqlite_vec # 1. 创建连接 conn = sqlite3.connect('vector_db.db') # 2. 启用扩展加载权限(必须!) conn.enable_load_extension(True) # 3. 加载 sqlite-vec 扩展 sqlite_vec.load(conn) # 4. 关闭扩展加载权限(安全) conn.enable_load_extension(False) ``` ⚠️ **注意**:`enable_load_extension(True)` 必须在 `load()` 之前调用! ### 3. 创建虚拟表 ```sql CREATE VIRTUAL TABLE table_name USING vec0( embedding float[768], -- 向量字段,指定维度 content TEXT, -- 元数据字段 id INTEGER PRIMARY KEY ); ``` | 要点 | 说明 | |------|------| | `VIRTUAL TABLE` | 必须使用,不能用普通 `CREATE TABLE` | | `USING vec0` | 指定使用 sqlite-vec 扩展 | | `float[维度]` | 向量类型,维度要和 Embedding 模型输出一致 | ### 4. 插入数据 ```python import sqlite_vec import numpy as np # 确保向量是 float32 embedding = np.array(embedding, dtype=np.float32).flatten() # 使用 serialize_float32 序列化 cursor.execute( "INSERT INTO table_name (content, embedding) VALUES (?, ?)", (content, sqlite_vec.serialize_float32(embedding)) ) ``` ⚠️ **必须使用 `serialize_float32()`**,不能直接 `tobytes()`! ### 5. 向量检索 ```python # 查询向量同样需要序列化 query_vec = np.array(query_embedding, dtype=np.float32).flatten() cursor.execute(""" SELECT content, vec_distance_cosine(embedding, ?) as distance FROM table_name ORDER BY distance ASC LIMIT 5 """, (sqlite_vec.serialize_float32(query_vec),)) ``` | 函数 | 说明 | |------|------| | `vec_distance_cosine(a, b)` | 余弦距离(越小越相似) | | `vec_distance_l2(a, b)` | 欧几里得距离 | | `vec_distance_l1(a, b)` | 曼哈顿距离 | ### 6. 距离 vs 相似度 ```python # 余弦距离范围:[0, 2] # 0 = 完全相同,2 = 完全相反 # 转换为相似度(0-1范围,越大越相似) cosine_similarity = 1 - distance ``` --- ## ❌ 常见错误 | 错误信息 | 原因 | 解决方案 | |---------|------|---------| | `no such function: vecf32` | 使用了错误的函数名 | 不要用 `vecf32()`,直接用 `?` 占位符 | | `no such function: vec_cosine_distance` | 函数名错误 | 正确名是 `vec_distance_cosine` | | `not authorized` | 未启用扩展加载 | 调用 `conn.enable_load_extension(True)` | | `no such module: vec0` | 扩展未加载 | 检查 `sqlite_vec.load(conn)` | | 维度不匹配 | 表定义维度和实际向量维度不一致 | 确保 `float[768]` 和 Embedding 输出一致 | --- ## 🔗 参考链接 - **官方文档**: https://alexgarcia.xyz/sqlite-vec/ - **GitHub**: https://github.com/asg017/sqlite-vec - **Python API**: https://alexgarcia.xyz/sqlite-vec/python.html --- ## 💡 最佳实践 1. **维度选择**:根据 Embedding 模型输出确定(如 BGE-Large 是 1024 维) 2. **批量插入**:使用 `executemany()` 提高性能 3. **索引**:sqlite-vec 自动创建向量索引,无需手动 `CREATE INDEX` 4. **元数据**:可以同时存储文本内容、来源文件等元数据 --- *文档由小小叶整理,基于 OpenClaw HR 智能助手项目实战经验*