通过 sqlite-vec 扩展在 SQLite 内实现向量搜索,在 5 美元 VPS 上完成本地嵌入和亚毫秒级向量查询,无云依赖、无供应商锁定。
多年来通往语义搜索等 AI 驱动功能的道路直指一套复杂技术栈:专用的向量数据库服务(如 Pinecone 或 Weaviate)、托管的 Embedding API,以及云函数。这种方案可行,但会带来持续运营成本、厂商锁定和数据隐私问题。每一次查询、每一个存储的向量都会产生费用。
如果最强大的能力不是云,而是离开云的能力呢?现代开发者技术栈正在悄然转变。我们现在可以用一个无处不在的文件——SQLite 数据库——实现生产级、亚毫秒级的语义搜索。通过将 SQLite 与 sqlite-vec 扩展结合,我们创造了一个无依赖、可移植、成本惊人的向量数据库,能运行在任何设备上——从树莓派到每月 5 美元的 VPS。
魔力来自于 sqlite-vec,这是一个开源的 SQLite 扩展,添加了原生向量存储和搜索能力。它编译成单个动态库文件。没有服务器守护进程,没有独立进程,没有 YAML 配置。只需加载扩展,你的数据库就获得了 VECTOR 类型的列。
想想你不需要的基础设施:向量数据库集群、独立 embedding 服务(如果你本地运行模型的话)、Kubernetes 编排器,或复杂的微服务网格。你的整个应用内存栈变成磁盘上单个 .db 文件。这将部署、备份和扩展简化到几乎微不足道的程度。要开始使用,你只需要编译好的扩展和一个语言绑定(如 Python 的 sqlite-utils)。
# On your $5 VPS (Ubuntu 22.04)
sudo apt-get update
sudo apt-get install -y python3-pip
# Install the binding and the extension
pip install sqlite-utils
wget https://github.com/sgenoud/sqlite-vec/releases/download/v0.1.1-alpha/sqlite_vec.c
gcc -shared -o sqlite_vec.so sqlite_vec.c -lm
这五行安装就给了你一个完整的向量数据库引擎。无需账户、无需 API key、无需 npm install 150 个传递依赖。
下一个关键部分是消除对云端 Embedding API 的依赖。本地运行 Embedding 模型让所有数据留在你的服务器上,确保完全隐私,消除每次请求的延迟和成本。对于轻量级、高质量的本地 Embedding,像 all-MiniLM-L6-v2 这样的模型是完美选择,能从文本生成 384 维向量。
在我们的 schema 中,存储原始文本、计算得到的向量和一个简单 ID。sqlite-vec 扩展负责其余部分。美妙之处在于简洁:数据库是唯一有状态的组件。
import sqlite_utils
import sqlite_vec
import sqlite3
from sentence_transformers import SentenceTransformer
# Initialize the local embedding model (downloads once, runs offline thereafter)
model = SentenceTransformer('all-MiniLM-L6-v2')
# Connect to our database file
db = sqlite_utils.Database("knowledge_base.db", memory=False)
# Enable the vector extension
db.enable_extension("sqlite_vec")
# Create our table with a VECTOR column
db["documents"].create({
"id": int,
"text": str,
"embedding": bytes, # Vectors are stored as binary blobs
}, pk="id")
这种架构意味着文档只索引一次、Embedding 在本地计算,文本和向量共存于同一个事务性、ACID 合规的数据库中。向量数据库和主数据库之间不需要同步——这是常见且代价高昂的复杂度来源。
数据摄入后,真正的威力在搜索阶段显现。sqlite-vec 提供的 vec_distance_cosine 函数允许我们直接在 SQL 查询中计算相似度。我们可以在向量列上创建索引来大幅加速大规模数据集的搜索。
让我们用 10 万条技术支持工单的数据集来实际演示。我们来找出与新用户查询最语义相似的 5 条历史问题。在 2 vCPU、1GB 内存的 VPS 上,性能令人瞩目。
# Indexing for performance (run once after bulk insert)
db.execute("CREATE INDEX vec_index ON documents USING vec_search(embedding);")
# Define our new query
query = "The application crashes when I export the large CSV file."
# Embed the query locally
query_embedding = model.encode(query).tobytes()
# Execute the semantic search
results = db.execute("""
SELECT
id,
text,
vec_distance_cosine(embedding, :query_vec) AS distance
FROM documents
ORDER BY distance ASC
LIMIT 5;
""", {"query_vec": query_embedding}).fetchall()
for row in results:
print(f"ID: {row[0]}, Distance: {row[2]:.4f}")
print(f"Text: {row[1][:150]}...\n")
在这台简陋硬件上的基准测试显示,对 10 万条数据建立向量索引大约需要 25 秒。此后每次相似性搜索在 15 毫秒内返回。整个数据库文件(含向量)的内存占用通常低于 200MB——完全在 5 美元 VPS 的能力范围内。
这套技术栈不是玩具;对于隐私、成本和简单性不可或缺的大量高影响力应用来说,它是一个稳健的解决方案。
内部知识库搜索:公司可以将所有内部文档、Slack 频道和 Confluence 页面索引到单个 SQLite 文件。员工获得类 ChatGPT 的语义搜索,同时公司数据永远不会离开本地网络或产生云成本。
开发者工具与 AI 记忆:想象一个编码助手,能语义搜索你的整个 Git 历史、本地文档和个人笔记,提供上下文感知的回答。本地向量数据库是这类工具的理想「记忆」层,如 Aider 等项目所展示的那样。
个人笔记与研究管理:.db 文件的所有权属于你。
虽然 SQLite 以「无服务器」著称,但它确实在单写多读的并发模型下运行。对于以读为主的应用——这正是它的主要场景——这通常完全够用。对于需要多源高频写入的场景,可以用简单的预写日志或消息队列将写入汇聚到单一进程来扩展架构。
这套技术栈真正的可扩展性在于它的可移植性和运维简单性。备份整个 AI 记忆就是一次文件复制。迁移到更强大的服务器就是一次文件传输。没有配置文件要合并,没有数据库集群要重新分片。这种运维简单性对于小型团队和独立开发者来说是巨大的效率倍增器。
准备好构建你自己的私有、零成本的语义搜索引擎了吗?力量就在你手中。从单个文件开始,在 TormentNexus 发现无依赖向量技术栈的潜力。
Originally published at tormentnexus.site