当企业拥有大量非结构化的文档(如 PDF、Word、Markdown)时,传统的数据库查询无法有效利用这些信息。用户难以通过简单的提问,从海量文档中快速获得精准答案。PolarDB PostgreSQL版通过polar_ai扩展,在数据库内部集成了一站式的检索增强生成(RAG)能力。您无需复杂的外部服务集成,仅通过SQL接口,即可将私有文档数据转化为智能问答知识库,实现对非结构化数据的高效、精准查询,快速构建企业级智能问答应用。
适用范围
开始前,请确保已完成以下准备:
引擎:PostgreSQL 16(内核小版本2.0.16.10.11.0及以上)。
节点:增加GPU规格的AI节点,并设置AI节点的连接数据库账号:添加与管理AI节点
说明若您在购买集群时已添加AI节点,则可以直接为AI节点设置连接数据库的账号。
AI节点的连接数据库账号需具有读写权限,以确保能够顺利读取和写入目标数据库。
访问地址:使用集群地址连接PolarDB集群。
工作原理
在PolarDB中实现RAG的核心流程是将外部文档处理后存入数据库,并通过结合向量检索与大语言模型(LLM)的能力,最终生成问题的答案。
数据准备与加载:将您的原始文档加载到数据库的数据表中。
文档分片(Chunking):调用
polar_ai.ai_rag_chunking函数,将长文档切分为更小的、语义完整的文本片段(Chunk)。这有助于后续的精准检索。向量化(Embedding):调用
polar_ai.ai_rag_text_embedding函数,将每个文本片段转换为高维向量(Vector),并与文本内容一同存储。向量是文本在数学空间中的表示,能够捕捉其语义信息。创建向量索引:在存储向量的列上创建HNSW索引,以极大地加速后续的相似性搜索。
检索:当用户提出问题时,首先将问题本身也向量化,然后在数据库中执行向量相似性搜索,快速召回与问题最相关的若干个文本片段。
重排序(Rerank):为进一步提升相关性,可以调用
polar_ai.ai_rag_rerank函数对初步召回的文本片段进行二次排序,筛选出最关键的信息。生成回答:将经过重排序的、最相关的文本片段作为背景知识(Context),连同用户的原始问题一起,提交给大语言模型,由模型基于提供的背景知识生成最终的、精准的自然语言答案。
准备环境
本节将指导您完成RAG功能的全部前置准备工作。
使用高权限账号登录集群。
获取节点Token。
请前往PolarDB控制台,目标集群详情页中数据库节点区域,找到AI节点,并单击查看记录节点Token。

创建
polar_ai扩展并配置节点Token。在数据库中执行以下命令,创建功能扩展并设置访问大模型服务所需的密钥。
重要请确认您已为AI节点设置了连接数据库账号。
-- 创建扩展 CREATE EXTENSION polar_ai; -- 设置您的密钥 SELECT polar_ai._ai_nl2sql_alter_token('sk-xxx');创建vector扩展。
-- 提供向量数据类型、向量索引及相似度计算能力 CREATE EXTENSION vector;部署RAG服务:
在AI节点上加载并启动RAG所需的模型和服务。执行以下命令来部署RAG服务。
SELECT polar_ai.ai_nl2sql_deployModel('RAG');
准备数据(导入、分片与向量化)
本节将以一个PDF文档为例,演示如何将其导入数据库,并高效地完成分片和向量化处理。
登录集群:您可以继续使用高权限账号或使用AI节点的数据库账号。
创建用于存储原始文档和处理后数据的数据表,执行以下SQL创建两张表。
file_content:用于存储上传的原始文档二进制内容。file_chunk:用于存储文档分片后的文本内容及其对应的向量。
-- 存储原始文档 CREATE TABLE file_content ( id SERIAL PRIMARY KEY, -- 文档的唯一标识 name TEXT, -- 文档名称 content BYTEA -- 文档二进制内容 ); -- 存储分片和向量 CREATE TABLE file_chunk ( file_id INTEGER, -- 关联的文档ID chunk_id INTEGER, -- 在文档内的切片ID chunk_content TEXT, -- 切片文本内容 embedding VECTOR(1024) -- 切片向量,维度需与模型输出保持一致 );将本地PDF文档加载到
file_content表中。推荐使用以下两种方式之一导入文档。方案一(推荐):使用
polar_ai_util插件,从OSS中加载文件的二进制内容。CREATE EXTENSION polar_ai_util; -- 用于从oss上加载文档 INSERT INTO file_content(name, content) SELECT 'PolarAI.pdf', polar_ai.AI_LOADFILE('oss://<access-key-id>:<access-key-secret>@oss-cn-beijing-internal.aliyuncs.com/your-bucket/path/to/PolarAI.pdf');方案二:使用客户端程序写入,您可以使用任何支持PostgreSQL的编程语言(如Python的
psycopg2库)编写脚本,读取本地文件内容,并将其以bytea格式INSERT到file_content表中。
对导入的文档进行分片,并将结果存入
file_chunk表。INSERT INTO file_chunk(file_id, chunk_id, chunk_content) SELECT 1, -- 文档id (polar_ai.ai_rag_chunking(content, 'pdf')).* -- 分片函数 FROM file_content;将内容向量化,以方便进行检索。
UPDATE file_chunk SET embedding = polar_ai.ai_rag_text_embedding(chunk_content);为向量检索创建高性能索引,在
embedding列上创建HNSW索引。HNSW是一种高效的近似最近邻搜索算法,适用于高维向量数据。-- 使用 HNSW 索引和 L2 欧氏距离 CREATE INDEX ON file_chunk USING HNSW (embedding vector_l2_ops);
构建RAG查询
整合向量检索、重排序和LLM调用,实现完整的RAG问答流程。
RAG执行步骤:
将问题转换为向量。
进行向量检索或混合检索找到需要的文档分片(Chunk)。
将召回的文档分片(Chunk)进行重排序(Rerank),找出相关性最大的一些文档分片(Chunk)。
将相关性最大的文档分片(Chunk)提交给大模型,生成回答。
操作步骤
创建自定义函数
ai_summarize:创建一个自定义 SQL 函数ai_summarize,用于封装调用大语言模型生成最终答案的逻辑。这个函数负责将问题和检索到的背景知识拼接成一个结构化的提示(Prompt),并调用底层的文本生成函数。CREATE OR REPLACE FUNCTION public.ai_summarize(question text, contents text[]) RETURNS text LANGUAGE plpgsql AS $function$ DECLARE body text; BEGIN body = format('根据已有的材料回答问题: %I 已有的材料包括: %I', question, contents::text); RETURN polar_ai.ai_text_generation(body, '_polar4ai/_polar4ai_nl2sql_tongyi'); END; $function$;执行端到端的RAG查询:您可以执行以下SQL来提问。这个查询清晰地展示了RAG的每一步:
-- RAG SELECT public.ai_summarize('PolarAI有哪些优势?', array_agg(chunks)) FROM ( -- rerank SELECT unnest(polar_ai.ai_rag_rerank('PolarAI有哪些优势?', array_agg(chunk_content))) as chunks FROM ( -- vector search SELECT chunk_content FROM file_chunk ORDER BY -- vectorize question polar_ai.ai_rag_text_embedding('PolarAI有哪些优势?')::vector(1024) <-> embedding ASC LIMIT 10 ) t LIMIT 5 );
相关SQL
SQL | 说明 |
对二进制文档内容进行解析和分片。 | |
将文本内容转换为向量。 | |
对检索到的文本片段列表根据与问题的相关性进行重排序。 |