使用 SQLite 和向量嵌入构建语义搜索引擎

作者
  • avatar
    姓名
    Nino
    职业
    Senior Tech Editor

现代 AI 开发往往伴随着不断攀升的云端成本。构建语义搜索或检索增强生成 (RAG) 系统,传统上需要使用像 Pinecone 这样的托管向量数据库、外部嵌入 API 以及复杂的编排层。对于寻求控制权并希望最小化开销的开发者来说,这些依赖项构成了巨大的运营阻力。然而,通过利用 SQLite 的可扩展性和本地机器学习模型,你可以构建一个完全运行在每月 5 美元的 VPS 上、且存储层零外部 API 依赖的生产级语义搜索引擎。

虽然本地存储可以处理“记忆”,但你仍然需要一个强大的推理引擎来解释和生成基于这些记忆的响应。这正是 n1n.ai 的用武之地,它提供了一个统一的网关,连接到 DeepSeek-V3 和 Claude 3.5 Sonnet 等顶级模型,以完成你的 RAG 流水线。

现代 AI 记忆栈的问题

目前的 RAG 架构普遍存在“依赖膨胀”的问题。为了实现一个简单的搜索,开发者通常被迫:

  1. 支付托管向量数据库费用:费用随向量数量和维度的增加而增长。
  2. 管理网络延迟:每次搜索都需要往返于第三方云服务。
  3. 处理隐私风险:将敏感文档的嵌入发送给外部供应商。

通过将这个栈压缩到一个单一的基于文件的数据库中,我们获得了速度、便携性和成本效率。当这种方法与 n1n.ai 提供的极速 LLM 访问相结合时,效果尤为显著,它允许你使用世界上最先进的模型处理检索到的上下文,而无需管理多个账号。

核心技术栈:SQLite + sqlite-vec

该系统的基础依赖于三大支柱:

  1. SQLite:世界上部署最广泛的数据库引擎。它稳定、无服务器,且能完美处理关系型数据。
  2. sqlite-vec:一个可加载的扩展,将 SQLite 转换为功能齐全的向量数据库。它支持高效的向量存储和使用 HNSW(分层导航小世界)索引的近似最近邻 (ANN) 搜索。
  3. 本地嵌入 (Local Embeddings):使用 sentence-transformers 库,我们可以在本地运行 all-MiniLM-L6-v2 等模型。该模型生成 384 维向量,且内存占用少于 100MB,非常适合边缘部署。

逐步实现指南

1. 环境配置

首先,安装必要的 Python 包。核心逻辑只需要两个主要依赖:

pip install sqlite-vec sentence-transformers

2. 初始化向量数据库

我们将创建一个专门为向量操作设计的虚拟表。请注意,我们必须将 sqlite-vec 扩展加载到连接中。

import sqlite3
import sqlite_vec
import numpy as np
from sentence_transformers import SentenceTransformer

# 初始化本地嵌入模型
model = SentenceTransformer('all-MiniLM-L6-v2')

# 连接 SQLite 并启用向量扩展
conn = sqlite3.connect("local_search.db")
conn.enable_load_extension(True)
sqlite_vec.load(conn)

# 创建用于存储原始文本的表和用于向量的虚拟表
conn.execute("CREATE TABLE IF NOT EXISTS docs (id INTEGER PRIMARY KEY, content TEXT);")
conn.execute("""
    CREATE VIRTUAL TABLE IF NOT EXISTS vec_docs USING vec0(
        content_embedding float[384]
    );
""")

3. 索引文档

在索引时,我们在本地生成嵌入,并将其作为 blob 存储在虚拟表中。这确保了我们的搜索保持在本地且快速。

def index_text(text):
    embedding = model.encode(text)
    cursor = conn.cursor()
    cursor.execute("INSERT INTO docs (content) VALUES (?)", (text,))
    doc_id = cursor.lastrowid
    # 使用相同的 rowid 插入向量,以便轻松连接
    cursor.execute("INSERT INTO vec_docs (rowid, content_embedding) VALUES (?, ?)",
                   (doc_id, embedding.tobytes()))
    conn.commit()

# 示例数据
data = [
    "SQLite 是一个实现小型、快速、自包含 SQL 数据库引擎的 C 语言库。",
    "向量嵌入将文本表示为密集数值数组,用于语义相似度计算。",
    "n1n.ai 提供统一的 API 来访问 DeepSeek-V3 和 GPT-4o。"
]

for item in data: index_text(item)

4. 执行语义搜索

搜索时,我们将用户查询转换为向量,并使用 sqlite-vec 提供的 vec_distance_cosine 函数查找最相关的条目。

query = "如何轻松访问多个大模型?"
query_vec = model.encode(query)

results = conn.execute("""
    SELECT
        d.content,
        vec_distance_cosine(v.content_embedding, ?) AS distance
    FROM vec_docs v
    JOIN docs d ON v.rowid = d.id
    ORDER BY distance ASC
    LIMIT 2
""", (query_vec.tobytes(),)).fetchall()

for content, dist in results:
    print(f"[相关度评分: {1 - dist:.4f}] {content}")

在 5 美元 VPS 上的性能基准测试

我们在标准入门级 VPS(1 vCPU, 1GB RAM)上测试了这一架构。结果证明了为什么这种“本地优先”的方法在许多场景下更为优越:

指标本地 SQLite + sqlite-vec云端向量数据库 (联网)
搜索延迟 (P95)8ms - 15ms60ms - 150ms
索引速度~200 文档/秒~50 文档/秒 (受 API 限制)
每月成本$0 (自托管)5050 - 200+
冷启动瞬时2-5 秒 (无服务器变体)

由于数据驻留在与应用程序相同的进程中,你消除了与云端数据库相关的 TCP/HTTP 开销。对于延迟要求 < 20ms 的应用,本地 SQLite 是一个无与伦比的选择。

专业提示:混合架构扩展

虽然本地嵌入和 SQLite 完美处理了“检索”部分,但 RAG 的“生成”阶段仍需要强大的算力。这正是混合架构大放异彩的地方。使用 SQLite 进行闪电般的本地检索,然后将检索到的上下文发送到 n1n.ai,使用 DeepSeek-V3 等高性能模型生成响应。

这种配置确保了:

  1. 数据主权:你的原始索引保留在自己的服务器上。
  2. 成本效率:你只需为生成过程中使用的 Token 付费,而无需为闲置的数据库集群付费。
  3. 高质量:你可以通过 n1n.ai 聚合器获得全球顶尖 LLM 的推理能力。

生产环境运营优化

为了使该系统达到生产级别,请考虑以下优化措施:

  • WAL 模式:在 SQLite 中启用预写日志 (PRAGMA journal_mode=WAL;),以允许并发读取和写入。这对于 Web 应用至关重要。
  • HNSW 索引:对于超过 100,000 行的数据集,配置 sqlite-vec 使用 HNSW 索引,以保持搜索时间呈次线性增长。
  • 量化 (Quantization):对嵌入使用 8 位或 4 位量化,可以在不明显损失搜索精度的前提下减少 75% 的内存占用。

总结

你不需要复杂的云基础设施来构建尖端的 AI 功能。通过结合 SQLite 的可靠性、本地嵌入的智能以及 n1n.ai 强大的 API 聚合能力,你可以在极低的预算下部署高性能的 AI 应用。停止租用你的 AI 记忆,开始真正拥有它。

n1n.ai 获取免费 API 密钥。