从啤酒风味到向量检索:WAWTech+Summer 2026 的 Postgres AI 实践

2026-07-31 24 预计阅读时间: 1 分钟
来源: postgr.es AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

WAWTech+Summer 2026 把传统会议中心换成了华沙 Tor Służewiec 的露天科技节。此次发布的不是整理完毕的正式记录,而是一段标记为 UNLOGGED 的原始切片:搭建 Postgres 展位、与国际团队交流、登台分享,以及活动结束后的快餐行程都被保留下来。对开发者而言,其中最值得继续拆解的线索,是演讲主题《From Hops to Vectors: Building AI-Powered Beer Recommendations in Postgres》:如何把啤酒风味转换成向量,并在 PostgreSQL 内完成相似度检索。

原始现场与 PostgreSQL 双关

UNLOGGED 和“Skip the WAL”既描述了视频未经压缩整理的风格,也借用了 PostgreSQL 的术语。

在 PostgreSQL 中,普通表的修改会写入 WAL(Write-Ahead Log),以支持崩溃恢复、备份和复制。UNLOGGED 表减少了这部分写入,适合可以重建的临时数据或批处理暂存区,但它并不是免费的性能开关:数据库异常关闭后,表可能被截断,而且数据不会通过物理流复制传到备库。

因此,推荐系统中的啤酒目录、用户反馈和模型版本通常应该放在普通持久表中。只有可重新导入的 embedding 暂存数据,才值得考虑 UNLOGGED

CREATE UNLOGGED TABLE embedding_staging (
    beer_id bigint PRIMARY KEY,
    embedding vector(384) NOT NULL
);

这段定义需要 pgvector 扩展。生产环境还应记录 embedding 模型名称、版本和生成时间,避免不同模型产生的向量被放进同一个距离空间。

从酒花描述走向向量

向量推荐的核心不是让数据库“理解啤酒”,而是把可比较的特征映射到同一向量空间。输入可以来自酒款描述、风格标签、配料说明或用户评价;embedding 模型将文本转换成固定维度的数值数组,Postgres 再用距离运算符查找邻居。

一次典型查询可以分成四步:

  1. 为每款啤酒保存文本资料和 embedding。
  2. 使用同一个模型把用户偏好转换成查询向量。
  3. 在 PostgreSQL 中按余弦距离或其他距离度量排序。
  4. 结合库存、地区、价格和过敏原等结构化条件过滤结果。

这里有一条重要边界:来源摘要没有披露演讲所用模型、向量维度或完整数据库结构。下面不是演讲源码,而是一个可以直接运行、用于验证检索机制的最小实践。

运行一个最小啤酒推荐库

下面用三维人工特征表示“苦度、柑橘感、烘烤感”。它不是生产级 AI embedding,但能完整演示 pgvector 的建表、写入和余弦距离查询。运行前需要本机安装 Docker,并确保 5432 端口未被占用。

docker run --name beer-vector-db \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  -d pgvector/pgvector:pg16

until docker exec beer-vector-db pg_isready -U postgres >/dev/null 2>&1; do
  sleep 1
done

docker exec -i beer-vector-db psql -U postgres <<'SQL'
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE beers (
    id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name text NOT NULL,
    style text NOT NULL,
    flavor vector(3) NOT NULL
);

INSERT INTO beers (name, style, flavor) VALUES
    ('Citrus Current', 'IPA',       '[0.85, 0.95, 0.10]'),
    ('Dark Signal',   'Stout',     '[0.45, 0.08, 0.98]'),
    ('Summer Packet', 'Wheat Ale', '[0.20, 0.75, 0.12]'),
    ('Clean Commit',  'Pilsner',   '[0.55, 0.25, 0.05]');

-- 查询偏好:明显苦味、强柑橘感、较弱烘烤感
SELECT
    name,
    style,
    round((1 - (flavor <=> '[0.80, 0.90, 0.10]'))::numeric, 3) AS similarity
FROM beers
ORDER BY flavor <=> '[0.80, 0.90, 0.10]'
LIMIT 3;
SQL

<=> 是 pgvector 的余弦距离运算符,距离越小越接近。示例把它转换成 1 - distance,让结果更像便于阅读的相似度分数。

接入真实 embedding 服务时,可以保留查询结构,只需把 vector(3) 改成模型实际维度,并用同一模型生成入库向量和查询向量。数据量增长后,可以这样实践:为向量列建立 HNSW 索引。

CREATE INDEX beers_flavor_hnsw
ON beers USING hnsw (flavor vector_cosine_ops);

ANALYZE beers;

HNSW 用更高的存储和建索引成本换取近似最近邻查询速度。小表不一定需要它;上线前应使用真实数据量比较召回率、延迟和内存占用。

推荐结果不能只看距离

向量最相近,不等于最适合推荐。一个可用的系统还要处理硬约束:商品是否有库存、用户所在地区能否购买、酒精度是否符合偏好,以及配料或过敏原是否需要排除。这类条件继续交给 SQL,而不是塞进 prompt。

SELECT name, style
FROM beers
WHERE style <> 'Stout'
ORDER BY flavor <=> '[0.80, 0.90, 0.10]'
LIMIT 3;

用户点击、收藏或明确评分也应该单独保存。后续可以把向量相似度与流行度、个体反馈和业务规则组合成重排分数,同时记录每次推荐使用的模型版本,方便复现结果。

采用前检查

这段 UNLOGGED 现场记录展现的是技术活动未经精修的一面,而演讲标题提供了一个清晰的工程方向:Postgres 不只保存推荐结果,也能承担向量检索和结构化过滤。真正落地时,需要守住几条边界:持久业务数据不要为了少写 WAL 而改成 UNLOGGED;文档向量和查询向量必须来自兼容模型;索引应由基准测试驱动;最终结果必须经过库存、合规和用户约束过滤。

从人工三维特征开始验证 SQL,再替换为真实 embedding,是成本较低的采用路径。它能先证明数据流和查询逻辑,再决定是否需要更复杂的模型、索引和重排服务。


相关推荐