• 欢迎访问少将全栈,学会感恩,乐于付出,珍惜缘份,成就彼此、推荐使用最新版火狐浏览器和Chrome浏览器访问本网站。
  • 吐槽,投稿,删稿,交个朋友
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏少将全栈吧

不需要向量数据库:用 SQLite-vec 搭建迷你 RAG 检索系统

AI Coding 实测 admin 21小时前 18次浏览 已收录 扫描二维码

不需要向量数据库:用 SQLite-vec 搭建迷你 RAG 检索系统

做 RAG 系统最重的一步是什么?不是写 Prompt,不是接 LLM,是搭向量数据库。Pinecone 要注册账号,Qdrant 要 Docker 部署,Chroma 要装一堆依赖。如果你的项目只是个个人工具或者原型验证,这些太重了。

有个更轻的方案:sqlite-vec。一个 SQLite 扩展,装完就能做向量检索,不需要额外的数据库服务。30 行 Python 代码能跑起来一个最小可用的语义搜索。

sqlite-vec 是什么

sqlite-vec 是 SQLite 的一个向量搜索扩展,用纯 C 写的,没有外部依赖。它是之前 sqlite-vss 项目的继任者,由 Alex Garcia 开发,Mozilla Builders 项目赞助。

核心能力很简单:在 SQLite 里创建虚拟表存储向量数据,然后用 KNN(K-Nearest Neighbors)查询找最相似的向量。支持 float、int8 和 binary 三种向量类型。

根据 GitHub 项目文档,它能在任何 SQLite 运行的地方运行——Linux、macOS、Windows、浏览器 WASM、甚至树莓派。这意味着你可以在本地跑,也可以在 Cloudflare Workers 里跑,还可以在浏览器里直接跑。

安装和初始化

Python 里装一行搞定:

pip install sqlite-vec

初始化也很直接。加载扩展,创建虚拟表,就完事了:

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)

# 创建向量表,这里用 4 维做演示,实际用 1536 维(OpenAI embedding)
db.execute("""
  CREATE VIRTUAL TABLE vec_docs USING vec0(
    embedding float[4],
    title text
  )
""")

注意 float[4] 这个维度参数。如果你用 OpenAI 的 text-embedding-3-small,维度是 1536。用 Jina 的 v3 模型,维度可能是 1024。维度一旦定下来就不能改,建表前先确认你的 embedding 模型输出维度。

插入数据和查询

插入向量数据用 JSON 字符串或者二进制 BLOB 都行。Python 里推荐用 serialize_float32() 把 list 转成二进制,性能更好:

# 插入文档向量
docs = [
  (1, "如何部署 Next.js 到 Cloudflare", [0.1, 0.2, 0.3, 0.4]),
  (2, "React 性能优化技巧", [0.5, 0.1, 0.8, 0.2]),
  (3, "Docker Compose 入门指南", [0.9, 0.7, 0.1, 0.3]),
  (4, "SQLite 向量搜索实战", [0.2, 0.9, 0.5, 0.7]),
]

for rowid, title, emb in docs:
  db.execute(
    "INSERT INTO vec_docs(rowid, embedding, title) VALUES (?, ?, ?)",
    [rowid, serialize_float32(emb), title]
  )

# KNN 查询:找跟查询向量最相似的 2 条文档
query_vec = serialize_float32([0.15, 0.85, 0.45, 0.65])
results = db.execute("""
  SELECT rowid, title, distance
  FROM vec_docs
  WHERE embedding MATCH ?
  ORDER BY distance
  LIMIT 2
""", [query_vec]).fetchall()

for rowid, title, dist in results:
  print(f"rowid={rowid}, title={title}, distance={dist:.4f}")

输出会类似这样:

rowid=4, title=SQLite 向量搜索实战, distance=0.0566
rowid=2, title=React 性能优化技巧, distance=0.2883

distance 是 L2 距离(欧几里得距离),值越小越相似。这个查询语法看着有点奇怪——MATCH 是 SQLite 全文搜索的语法,sqlite-vec 复用了这个语法来做向量匹配。

接上 LLM 就是迷你 RAG

向量检索跑通了,接上 LLM 就是一个完整的 RAG。流程是:用户提问 → embedding → sqlite-vec 检索相关文档 → 把检索结果塞进 Prompt → 调 LLM 生成回答。

import openai

client = openai.OpenAI()

def mini_rag(question, db):
  # 1. 问题转 embedding
  resp = client.embeddings.create(
    model="text-embedding-3-small",
    input=question
  )
  query_emb = resp.data[0].embedding

  # 2. 向量检索 top 3
  results = db.execute("""
    SELECT title, distance
    FROM vec_docs
    WHERE embedding MATCH ?
    ORDER BY distance
    LIMIT 3
  """, [serialize_float32(query_emb)]).fetchall()

  context = "\n".join([r[0] for r in results])

  # 3. 构造 prompt 调 LLM
  completion = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
      {"role": "system", "content": f"根据以下参考资料回答问题。\n\n参考资料:\n{context}"},
      {"role": "user", "content": question}
    ]
  )
  return completion.choices[0].message.content

这段代码加上前面的初始化和插入逻辑,总共不到 50 行。一个能跑的 RAG 系统就这么简单。

什么时候该用 sqlite-vec,什么时候不该用

适合用的场景:

  • 个人项目和原型验证,数据量在几千到几万条
  • Edge 部署,比如 Cloudflare Workers 上跑轻量 RAG
  • 本地优先应用,数据不想发到外部服务
  • 嵌入式场景,资源受限的设备

不该用的场景:

  • 数据量百万级以上。sqlite-vec 用的是暴力扫描做 KNN,没有 HNSW 这样的近似最近邻索引。数据量大了查询会线性变慢
  • 需要高并发写入。SQLite 是文件级锁,不适合多进程同时写
  • 需要复杂的元数据过滤。虽然支持 partition key,但功能远不如 Qdrant 或 Milvus 完善

根据 sqlite-vec GitHub 文档的说明,它定位是”extremely small, fast enough”——牺牲了大规模性能换取极简部署。如果你的向量数据在 5 万条以内,查询延迟通常在 10ms 级别,完全够用。

一个容易被忽略的细节:SQLite 版本

sqlite-vec 的部分功能需要 SQLite 3.41 或更高版本。但 Python 自带的 sqlite3 模块绑定的 SQLite 版本可能比较旧。检查方法:

python -c 'import sqlite3; print(sqlite3.sqlite_version)'

如果版本低于 3.41,推荐装 pysqlite3 包来用更新的 SQLite:

pip install pysqlite3-binary

然后在代码里替换:

# from sqlite3 import connect
from pysqlite3 import connect

这个坑踩过一次就记住了。症状是某些 SQL 语法报错,但代码看着没问题。

成本对比

跟主流向量数据库比,sqlite-vec 的成本基本是零。没有云服务费,没有额外的服务器开销,就是你的应用进程里多加载一个扩展。对比 Pinecone 的最低档每月 $70,或者自托管 Qdrant 至少一台 2GB 内存的机器,sqlite-vec 的开销可以忽略不计。

代价是规模上限。但说实话,大部分独立开发者的项目,文档量能到一万条就算很多了。在这个规模下,sqlite-vec 是性价比最高的选择。

小结

不是所有 RAG 系统都需要一个独立的向量数据库。如果你在做个人工具、原型验证、或者 Edge 部署的轻量应用,sqlite-vec 给了一个极简的方案:一个 pip install,一个文件,30 行代码。

等你的数据量真到了需要专业向量数据库的时候,迁移也不难。把数据导出来灌进 Qdrant 或者 Milvus,改一下查询接口就行。早期不要过度设计架构,能跑起来比跑得完美重要得多。

sqlite-vec GitHub 仓库地址:github.com/asg017/sqlite-vec

喜欢 (0)赏
[🍬谢谢你请我吃糖果🍬🍬~]
分享 (0)
关于作者:
少将,关注Web全栈开发、项目管理,持续不断的学习、努力成为一个更棒的开发,做最好的自己,让世界因你不同。