mcpField
H
how-to-do-offline-recommendations-with-sqlite-and-gemini

how-to-do-offline-recommendations-with-sqlite-and-gemini

github.com/rodydavis数据与数据库6048 次安装2 周前更新
代码仓库

关于 how-to-do-offline-recommendations-with-sqlite-and-gemini

本指南介绍如何用 SQLite 向量搜索和 Gemini 生成的描述与嵌入,构建离线相关内容推荐,适合为 CMS 内容添加推荐功能的开发者。

主要功能

  1. 01使用 Gemini 生成描述
  2. 02创建文本嵌入
  3. 03用 sqlite-vec 存储向量
  4. 04通过 kNN 搜索相关帖子
  5. 05内容变更时更新向量

适用场景

  1. 01展示相关博客文章
  2. 02无需每次访问发起网络请求即可提供推荐

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rodydavis/skills --skill how-to-do-offline-recommendations-with-sqlite-and-gemini

安装后在 Claude Code 中输入/how-to-do-offline-recommendations-with-sqlite-and-gemini确认已加载。

详细介绍

如何使用 SQLite 和 Gemini 实现离线推荐

使用 CMS(如 PocketBase)时,通常会为相关内容添加某种推荐功能。例如,你可以列出博客文章,并通过随机选择或最近浏览的内容来展示相关文章。

我最初是从 Aaron Francis 的 YouTube 频道上了解到这项技术的:

文本嵌入

文本嵌入是一种将一段文本转换为数字数组的方法。有了这种数学表示形式,我们就可以轻松地将其存储在数据库中,并运行常见函数来计算已存储向量之间的距离。

你需要一个 AI Studio API 密钥来生成描述和嵌入。

为了创建嵌入,我们需要先生成足够小、能够适配嵌入窗口大小的文本块。例如,我们可以使用 Gemini 等大模型生成博客文章的描述,然后将描述向量化并存储在数据库中。

只有在内容发生变化时,我们才需要生成新的嵌入和描述,因此计费成本取决于内容变化的频率。

存储向量

要将文本嵌入存储为向量,我们可以使用名为 sqlite-vec 的运行时可加载扩展,将其保存到 SQLite 数据库中。下面是 README 中关于如何直接在 SQLite 中查询向量的示例:

.load ./vec0

create virtual table vec_examples using vec0(
  sample_embedding float[8]
);

-- vectors can be provided as JSON or in a compact binary format
insert into vec_examples(rowid, sample_embedding)
  values
    (1, '[-0.200, 0.250, 0.341, -0.211, 0.645, 0.935, -0.316, -0.924]'),
    (2, '[0.443, -0.501, 0.355, -0.771, 0.707, -0.708, -0.185, 0.362]'),
    (3, '[0.716, -0.927, 0.134, 0.052, -0.669, 0.793, -0.634, -0.162]'),
    (4, '[-0.710, 0.330, 0.656, 0.041, -0.990, 0.726, 0.385, -0.958]');


-- KNN style query
select
  rowid,
  distance
from vec_examples
where sample_embedding match '[0.890, 0.544, 0.825, 0.961, 0.358, 0.0196, 0.521, 0.175]'
order by distance
limit 2;
/*
┌───────┬──────────────────┐
│ rowid │     distance     │
├───────┼──────────────────┤
│ 2     │ 2.38687372207642 │
│ 1     │ 2.38978505134583 │
└───────┴──────────────────┘
*/

现在,我们只需将之前创建的向量存储在一个表中,该表会随着内容变化而更新。

CREATE TABLE posts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  title TEXT NOT NULL,
  content TEXT NOT NULL,
  description TEXT.
  embeddings TEXT
);

CREATE VIRTUAL TABLE vec_posts USING vec0(
  id INTEGER PRIMARY KEY,
  embedding float[768]
);

-- Sync vectors
INSERT INTO vec_posts(id, embedding) SELECT id, embeddings FROM posts;

我们也可以设置触发器来保持数据最新,但在 PocketBase 中,我使用事件钩子来更新虚拟表。

生成推荐结果

要离线生成推荐结果,我们只需使用一篇博客文章作为输入查询,然后通过 k 近邻搜索(kNN)获取 N 篇相关文章。

SELECT
  vec_posts.id as id,
  vec_posts.embedding as embedding,
  posts.title as title,
  posts.description as description,
  posts.slug as slug
FROM vec_posts
INNER JOIN vec_posts.id = posts.id
WHERE embedding match ?
AND k = 6
ORDER BY distance;

我们只需将当前选中的博客文章的向量作为 ? 参数传入,然后从列表中过滤掉当前博客文章,就能得到向量数据库中与之最相关的 N 篇博客文章。

总结

这样,无论一篇博客文章被访问多少次,推荐功能都不会产生网络调用,因此能够很好地扩展。

你可以在我的网站上浏览各种博客文章,查看每篇文章末尾生成的描述和相关文章,亲自体验这一功能。

评论

支持 Markdown