Postgres 能否处理你的 RAG 流程?

我们测试了 pgai 的数据库优先方法,了解它在哪些方面简化了 RAG 运维,以及复杂工作负载为何仍需更高的灵活性。

执行摘要

  • LLM 一次只能“看到”有限量的文本(即上下文窗口)。这适用于小型任务,但当知识库长达数千页时便难以奏效。即使上下文窗口足够大,性能仍可能因“大海捞针”问题而下降。

  • RAG(“检索增强生成”)已成为一种非常常见的模式:维护一个知识库(文档、Wiki、政策、文字记录等),根据用户查询进行语义搜索,通过嵌入检索最相关的片段,再将这些文本块与问题一起输入 LLM。这能限制模型使用的上下文;如果实施得当,还可提高答案质量并减少幻觉。

  • pgai 是一个开源 Postgres 扩展及配套工具,可帮助你基于值得信赖的开源数据库 PostgreSQL 构建“AI 检索”工作流。

  • 其核心思路是把标准 RAG 流程中的更多环节下沉到数据库层(摄取 → 分块 → 嵌入 → 保持嵌入同步),而不是将数据库视为“仅用于存储”嵌入的工具。

  • 我们的初步看法是,它很有前景,但只要 RAG 流程稍微复杂一些(尤其是分块方法),它就不太适用了。不过,我们会密切关注这个项目。

RAG 模式

构建 RAG 的方法有很多。如需深入了解不同的 RAG 方法,请阅读《定制 RAG 解决方案实用示例》一旦开始关注质量,设计空间会变得出乎意料地复杂,而常见的“默认”方法通常如下:

  1. 准备一批文档。

  2. 将其拆分成文本块。拆分方法有很多种,例如按段落或语义分组。

  3. 将每个文本块转换为嵌入。

  4. 将嵌入存储在向量数据库(Pinecone、Milvus 等)中,或使用 pgvector 存储在 Postgres 中。

  5. 查询时,搜索最接近的文本块`并将其输入 LLM(同样……这一步也有很多实现方法)。

在许多技术栈中,步骤 (1)–(3) 都通过应用程序代码或数据管道在数据库外完成,数据库主要用于:

  • 存储嵌入

  • 搜索嵌入

pgai 的用途

pgai 是一个 Postgres 扩展(开源,由 Timescale 开发),旨在模糊这条界线。

pgai 不再让应用手动管理嵌入,而是将嵌入变成一项数据库功能:

  • 定义要进行嵌入的表或文档。

  • 指定嵌入模型和分块策略。

  • 其余工作由 pgai 管理,包括在源数据发生变化时及时更新嵌入。

它的优势很有吸引力:

  • 需要维护的定制粘合代码更少。

  • 底层源文档发生变化时,应能更轻松地保持嵌入“最新”。

  • Postgres/pgai 会管理重试、速率限制、失败的作业等。

读者须知:pgai 内置了 pgvector(另一个非常流行的 RAG Postgres 扩展)。pgvector 为 Postgres 增加了向量存储和相似度搜索功能,而 pgai 在此基础上进一步实现了 RAG 流程自动化,包括分块、嵌入和及时更新嵌入。

对 pgai 的初步看法

我们喜欢的方面

1)启动和运行十分简单。

理想情况下,操作相当简单:

  • 拉取 Timescale Docker 镜像(数据库和工作进程)。

  • 提供嵌入服务商的 API 密钥。

  • 运行少量 SQL 来声明向量化器(基本上就是指定嵌入哪些内容、如何分块以及使用哪个模型)。

随后,pgai 会安排向量化器工作进程以独立进程的形式运行,并异步生成嵌入(例如每 5 分钟一次,也可采用你需要的其他频率)。

2)在数据库“附近”完成整个流程很方便。

pgai 可以从表中摄取内容,也能从 S3 等位置加载文档,然后进行解析、分块和嵌入。它还可以处理 PDF、Markdown 等不同的文本文档格式。

存在的局限

1)会失去很多控制力(而 RAG 有时恰恰需要这种控制力)。

高性能 RAG 系统(以答案质量衡量)通常需要定制流程,例如:

  • 自定义分块规则(按标题、页面、说话轮次等)

  • 感知元数据的分块(保留章节标题、时间戳、作者和文档类型)

  • 针对不同文档类型采用不同的嵌入策略

pgai 在上述方面的灵活性较低。

目前主要有两种分块策略:字符文本拆分器和递归字符文本拆分器,此外还可选择不分块。这对某些用例或许已经足够,但许多生产级 RAG 系统需要更高的定制程度。

如果 Timescale 能整合 Chonkie 等库中更复杂的分块策略,并支持 Anthropic 的上下文检索等高级设计,那将非常出色。

2)以文本为主,而非多模态。

许多有趣的 RAG 问题已不再局限于纯文本

  • 包含图表的 PDF

  • 屏幕截图/图像

  • 录音

  • 视频片段

即使能从这些来源“提取文本”,也不等同于真正的多模态嵌入流程。

如果 pgai 最终能提供端到端的多模态模型支持(对存储在 S3 中的大型图像、音频和视频进行加载 → 分块 → 嵌入,并可靠同步),将非常有吸引力;但目前它仍是文本嵌入工作流。

3)如果只需要嵌入,你可能并不需要 pgai。

如果摄取流程已经是定制的(或必须定制),那么“对文本块进行嵌入”并不是 RAG 最难的环节。在这种情况下,pgai 解决的只是问题中最简单的部分。

此外,如果知识库不经常更新,自动同步嵌入的价值也不会那么高。

文本转 SQL 层

pgai 一个特别理想的用法,是在数据库之上部署文本转 SQL 接口。使用 pgai 提供的 semantic_catalog 模块即可轻松实现。只需按如下方式设置:

Bash

OPENAI_API_KEY="your-OpenAPI-key-goes-here"TARGET_DB="postgres://user:password@host:port/database"CATALOG_DB="postgres://user:password@host:port/database"

然后运行 pgai semantic-catalog create,让语义目录抓取数据字典。这会根据数据存储生成上下文,大致如下:

Plain Text

---schema: postgres_airname: aircrafttype: tabledescription: Lists aircraft models with performance characteristics and unique codes.columns:- name: model  description: Commercial name of the aircraft model.- name: range  description: Maximum flight range in kilometers.- name: class  description: Airframe class category or configuration indicator.- name: velocity  description: Cruising speed of the aircraft.- name: code  description: Three-character aircraft code serving as the primary key....

pgai 现在可通过多种方式使用此上下文:

通过语义搜索:

此查询会返回可能与你的自然语言查询相关的表、函数及其他对象:

Bash

pgai semantic-catalog search -p "Your natural language question goes here!"

获取原始上下文:

这会呈现与你的自然语言查询相关的原始 YAML 上下文:

Bash

pgai semantic-catalog search -p "Your natural language question goes here!" --render

生成 SQL:

也可以直接生成回答查询所需的原始 SQL。上一步的上下文会发送给 LLM,由其生成响应:

Bash

pgai semantic-catalog generate-sql -p "Your natural language question goes here!"

现在可以如何使用 pgai

如果你正在构建较为简单的 RAG 系统,并且有以下需求,pgai 值得一试:

  • 将 Postgres 用作记录系统,

  • 尽量减少粘合代码,

  • 让嵌入自动保持同步,

  • 快速将文本转 SQL 功能应用到数据库,

  • 尝试新的 RAG 工具和 Postgres 扩展。

需要谨慎的情况

如果 RAG 流程有以下任何需求,可能值得暂缓采用 pgai:

  • 高度定制的摄取或分块逻辑

  • 大量具有不同解析要求的文档类型

  • 多模态嵌入

最后,pgvector 显然已得到广泛采用,但 pgai 能否获得同等程度的关注和相应支持仍不明确(尽管它问世仅约 18 个月)。

展示 Timescale 的 pgai 采用量随时间变化的 GitHub 星标历史图表。

总结

pgai 为 RAG 提供了一种有趣的方法,让数据库承担更多日常运维工作,从而简化应用程序代码。

目前,它:

  • 适用于简单的 RAG 配置,而且使用体验确实不错

  • 对高度定制的流程不够灵活,尤其是多模态流程

它展现出了潜力,绝对值得持续关注其后续发展。

作者

Andrew Liubinas