本文将为您介绍检索增强生成(Retrieval-Augmented Generation,RAG)的概念,以及如何搭建和使用检索增强生成RAG系统。
概念
大语言模型(LLM)在生成回复的准确性和实时性方面存在一定的局限性,因此不太适合直接应用于需要精确信息的客户服务或问答场景。为了解决这一问题,业界广泛采用了检索增强生成(Retrieval-Augmented Generation, RAG)技术,提升LLM的性能。这一技术显著提高了问答、摘要生成以及其他需要引用外部知识的自然语言处理(NLP)任务的质量。
RAG通过将大语言模型(如通义千问)与信息检索组件相结合,增强了模型生成答案的准确性和信息量。在处理用户查询时,RAG通过信息检索组件从知识库中寻找与查询相关的文档或信息片段,将这些检索到的内容与原始查询一起输入大语言模型后,模型能够利用现有的归纳生成能力,产生基于最新信息的、符合事实的回复,而无需对模型进行重新创建。
PolarDB部署的对话系统服务,通过集成大语言模型(LLM)和检索增强生成(RAG)技术,有效克服了LLM在准确性和实时性方面的局限,为多种问答场景提供了准确且信息丰富的响应。这种整合显著提升了自然语言处理任务的整体效能和用户体验。
RAG系统搭建流程架构图
搭建并使用检索增强生成RAG系统的整体流程示意图如下:
构建文档向量化和分词索引表
被检索的文档已存在数据库中
当需要被检索的文档已经存在数据库时,我们需要将文档向量化。
数据准备
创建文档数据表
CREATE TABLE enterprise_context( file_id varchar(256) COMMENT '文本溯源索引', file_name varchar(256) COMMENT '标题中心内容', content text COMMENT '文本内容', category_id varchar(128) COMMENT '类目信息', PRIMARY KEY (file_id) );
插入文档数据
INSERT INTO enterprise_context(file_id,file_name,content,category_id) VALUES ('doc1','PolarDB for AI简介','PolarDB for AI是基于PolarDB MySQL版的一个数据库内的分布式机器学习组件。其基于云原生的体系架构,通过SQL语句的方式提供了支持机器学习的一系列MLOps,包括:创建模型、查看模型状态、查看模型列表、模型评估和模型推理等能力;同时提供了一系列内置的机器学习和人工智能算法,包括:分类算法、回归算法和聚类算法等。基于MLOps和内置的模型,PolarDB for AI为数据驱动的智能应用提供了高效、可靠、方便的数据智能能力,打破了数据库和业务应用之间的系统墙,提供了基于数据库数据智能的一站式服务。','c1'), ('doc2','PolarDB for AI在搜索推荐中的应用','PolarDB for AI将传统的DB+AI的数据智能应用转变为一站式数据智能应用,从数据库服务于传统的数据工程师和算法工程师转变为DB+AI服务于业务工程师,直接与业务系统对接。基于PolarDB for AI的智能推荐算法和知识图谱技术,再结合阿里巴巴电商策略,为企业提供贯穿推荐能力的一站式服务,助力企业快速过渡冷启动过程。面向不同的业务场景定制个性化解决方案,持续提升核心业务能力,以实现业务营收增长。','c2');
文档向量化及构建向量和分词索引
说明文本转向量化模型
_polar4ai_text2vec
支持将长篇文档分割成多个文本块,以便增加RAG文本检索的精确度。关于文本数据向量化的更多信息,请参见:案例二:搭建文档检索系统。
文本数据需要切片处理
创建索引表
RAG索引表固定了参数名称和类型,具体表结构SQL语句如下:
/*polar4ai*/CREATE TABLE file_index_table( chunk_id varchar(265), chunk_content text_ik_smart, file_id varchar(256), file_name varchar(256), category_id varchar(128), vecs vector_768, PRIMARY KEY(chunk_id) );
RAG索引表中的参数说明如下:
参数
说明
示例值
chunk_id
{file_id}-{chunk_order},对每一个切片文本设置的主键id,在同一文件内按序递增。
file1-1
chunk_content
切片文本,使用分词器进行分词,此处可使用text_ik_smart(粗粒度拆分的词) / text_ik_max_word(细粒度拆分的词) 等分词器进行分词。
文本内容
file_id
文件标识,用于溯源文本内容。
xxx.docx
file_name
文件名、文件标题与内容相关的语句(可选)。
中心内容
category_id
用于限定文档搜索范围,精确匹配的类目ID。
c1
vecs
切片向量,使用_polar4ai_text2vec模型将切片文本转为向量值。
说明_polar4ai_text2vec为文本转向量化模型,目前仅支持输出768维向量。
[0.1, 0.2, ...]
构建向量和分词索引
_polar4ai_text2vec
为文本转向量化模型,目前仅支持输出768维向量。将enterprise_context中的文档数据向量化并保存到RAG索引表中,当设置to_chunk=1
时,列chunk_id
和chunk_content
将通过切片方法生成。/*polar4ai*/SELECT chunk_id, chunk_content, file_id, file_name, category_id FROM predict(model _polar4ai_text2vec, SELECT content, file_id, file_name, category_id FROM enterprise_context) WITH ( x_cols='content', primary_key='file_id', mode='async', vec_col='vecs', to_chunk=1, chunk_size=128, chunk_overlap=16 ) INTO file_index_table; /*polar4ai*/SHOW TASK `your-task-id`; /*polar4ai*/SELECT * FROM file_index_table;
文本数据无需切片处理
创建索引表
RAG索引表固定了参数名称和类型,具体表结构说明如下:
/*polar4ai*/CREATE TABLE file_index_table( file_id varchar(256), file_name varchar(256), chunk_content text_ik_smart, category_id varchar(128), vecs vector_768, PRIMARY KEY(file_id) );
RAG索引表中的参数说明如下:
参数
说明
示例值
file_id
文件标识,用于溯源文本内容。
xxx.docx。
file_name
文件名、文件标题与内容相关的语句(可选)。
中心内容。
chunk_content
文本内容,使用分词器进行分词,此处可使用text_ik_smart(粗粒度拆分的词) / text_ik_max_word (细粒度拆分的词)等分词器进行分词。
文本内容。
category_id
用于限定文档搜索范围,精确匹配的类目ID。
c1。
vecs
切片向量,使用_polar4ai_text2vec模型将切片文本转为向量值。
说明_polar4ai_text2vec
为文本转向量化模型,目前仅支持输出768维向量。[0.1, 0.2, ...]。
构建向量和分词索引
_polar4ai_text2vec
为文本转向量化模型,目前仅支持输出768维向量。将enterprise_context中的文档数据向量化并保存到RAG索引表中。/*polar4ai*/SELECT chunk_content, file_id, file_name, category_id FROM predict(model _polar4ai_text2vec, SELECT content as chunk_content, file_id, file_name, category_id FROM enterprise_context) WITH ( x_cols='chunk_content', primary_key='file_id', mode='async', vec_col='vecs' ) INTO file_index_table; /*polar4ai*/SHOW TASK `your-task-id`; /*polar4ai*/SELECT * FROM file_index_table;
被检索的文档不存在数据库中
被检索的文档不在数据库中,我们会先将文档上传到数据库,并解析文档内容,再做文本向量化的工作。
创建文档知识库
上传文档数据
/*polar4ai*/UPLOAD FILE docfile WITH ( file_id='unique_file_id', file_type='.docx', src_file_location='your_file_url', dest_file_name='your_file_name.docx', metadata='{}' );
WITH()
中的参数说明如下:说明src_file_location示例文档请参见Polar4AI-Introduction.docx。
参数
说明
示例值
file_id
文件主键(不可重复)。
'Polar4AI'
file_type
文件类型。
'.docx'
src_file_location
文件URL地址。
'https://xxx.aliyuncs.com/Polar4AI-Introduction.docx'
dest_file_name
目标文件名(可重复,不支持存储路径/)。
'Polar4AI-Introduction'
metadata
元数据,暂时保留。
'{}'
查看已上传的文档
查看已上传的文档的SQL语法如下,其中
unique_file_id
需替换为已通过UPLOAD FILE
上传的文件ID。/*polar4ai*/SHOW FILES;
/*polar4ai*/SHOW FILE `unique_file_id`;
(可选)删除已上传的文档
/*polar4ai*/DROP FILE `unique_file_id`;
创建文档元数据表
在数据库中创建和更新元数据表,SQL语句如下:
CREATE TABLE file_id_list( file_id varchar(256) PRIMARY KEY, action_type varchar(10), category_id varchar(128) # any data format ... ); INSERT INTO file_id_list(file_id, action_type, category_id, ...) VALUES ('unique_file_id', 'add', 'c1', ...);
文档元数据表中参数说明如下:
参数
说明
示例值
file_id
UPLOAD FILE中指定的文件主键。
'Polar4AI'
action_type
需要对文件做的操作,可选值包括['add', 'delete'],当action_type为'add'时,在索引表中增加该文件相关内容,并重新计算索引值。当action_type为'delete'时,在索引表中删除该文件的相关内容。
'add'
'delete'
''
category_id
该文件的类目标识。
'c1'
解析文件并构建向量和分词索引
创建索引表
向量和分词索引表固定了参数名称和类型,SQL语句如下:
/*polar4ai*/CREATE TABLE file_index_table( chunk_id varchar(265), chunk_content text_ik_smart, file_id varchar(256), file_name varchar(256), vecs vector_768, PRIMARY KEY(chunk_id) );
参数说明如下:
参数
说明
示例值
file_id
文件唯一标识,用于溯源文本内容。
'Polar4AI'
file_name
文件名、文件标题与内容相关的语句。
'Polar4AI-Introduction'
chunk_content
切片文本,使用分词器进行分词,此处可使用text_ik_smart(粗粒度拆分的词) / text_ik_max_word(细粒度拆分的词)等分词器进行分词。
文档文本内容
vecs
切片向量,使用_polar4ai_text2vec模型将切片文本转为向量。
[0.1, 0.2, ...]
chunk_id
{file_id}-{chunk_order},对每一个chunk设置的主键id,在同一文件内按序递增。
'Polar4AI-1'
根据文档ID构建向量和分词索引
从文档元数据表中选取需要进行解析和构建索引的
file_id
,解析文档内容并使用_polar4ai_text2vec
模型的predict方法插入索引表中:/*polar4ai*/SELECT chunk_id, file_id, file_name, chunk_content FROM predict(model _polar4ai_text2vec, SELECT file_id FROM file_id_list) WITH ( x_cols='chunk_content', primary_key='file_id', mode='async', resource='file', to_chunk=1, headers_to_split_on=-1, chunk_size=512, chunk_overlap=64, separator='' ) INTO file_index_table;
_polar4ai_text2vec
为文本转向量化模型,目前仅支持输出768维向量。WITH()
中的参数说明如下:参数
说明
示例值或范围
x_cols
用于存储文本的字段。
chunk_content
primary_key
文件列表的主键,文档ID。
id
mode
文档数据的写入模式。目前仅支持async(异步)模式。
async
resource
在文件解析流程中为file模型。
file
to_chunk
文件中的文本是否进行切片。
0或1
headers_to_split_on
to_chunk=1时按照指定标题层级进行切分
当
headers_to_split_on
值为-1时,对文件中所有层级标题进行分块。当
headers_to_split_on
值为x
时,对文件中小于等于x
层级的标题进行分块。
-1 ≤ x ≤ 6为整数值
chunk_size
文本切分的最大长度。
chunk_size ≥ 50
chunk_overlap
相邻两个切片之间的重叠字符数量。
chunk_overlap ≤ chunk_size。
separator
分块内切片之间的分隔符。
空
''
、英文逗号,
、中文逗号,
等(可选)调整索引表内容
根据文档元数据表file_id_list中的action_type,您可以指定增加或删除文档内容。将文档的类目标识category_id作为参数输入时,类目标识信息将存入向量与分词索引表,您可以通过设置RAG查询参数中的category_ids,限定文本检索的范围。示例如下:
file_id_list
中指明操作类型,添加或删除文档。/*polar4ai*/SELECT chunk_id, file_name, chunk_content, category_id FROM predict(model _polar4ai_text2vec, SELECT file_id, action_type, category_id FROM file_id_list) WITH ( x_cols='chunk_content', primary_key='file_id', mode='async', resource='file', to_chunk=1, headers_to_split_on=-1, chunk_size=512, chunk_overlap=64, separator='' ) INTO file_index_table;
查询task状态和结果
taskStatus
为finish
时表示成功完成文件解析任务,在索引表中可以查询到切片信息。/*polar4ai*/SHOW TASK `task-id`;
/*polar4ai*/SELECT * FROM file_index_table LIMIT 10;
(可选)删除索引表中的记录
/*polar4ai*/DELETE FROM file_index_table WHERE file_id = 'unique_file_id';
检索增强生成RAG
在线使用RAG功能
您可以执行以下SQL语句在线使用RAG功能,查询返回模型生成结果、召回文本、对应文件名、向量得分、分词得分、混合得分的值:
文本数据分片
/*polar4ai*/SELECT * FROM PREDICT(MODEL _polar4ai_rag, SELECT '问题内容') WITH ( index_name='file_index_table', primary_key='chunk_id', vec_top_k=5, vec_score_threshold=0.0, pos_top_k=3, pos_score_threshold=0.0, use_vec=1, use_pos=1, hybrid_type=0, hybrid_score=0.8, ranker_model='', category_ids='', file_id='', generate=1 );
文本数据未分片
/*polar4ai*/SELECT * FROM PREDICT(MODEL _polar4ai_rag, SELECT '问题内容') WITH ( index_name='file_index_table', primary_key='file_id', vec_top_k=5, vec_score_threshold=0.0, pos_top_k=3, pos_score_threshold=0.0, use_vec=1, use_pos=1, hybrid_type=0, hybrid_score=0.8, ranker_model='', category_ids='', file_id='', generate=1 );
WITH()
中的参数说明如下:参数
说明
示例值或范围
index_name
索引表名称。
index_table
primary_key
索引表主键名称。
chunk_id、file_id
说明根据您的文本数据是否切片,当前参数有所差异。
分片:chunk_id
未分片:file_id
vec_top_k
保留前K个向量检索相关度得分最高的结果。
vec_top_k ≥ 0
vec_score_threshold
向量检索得分的阈值,去掉得分低于阈值的结果。
vec_score_threshold ≥ 0
pos_top_k
保留前K个分词检索相关得分最高的结果。
pos_top_k ≥ 0
pos_score_threshold
分词检索得分的阈值,去掉得分低于阈值的结果。
pos_score_threshold ≥ 0
use_vec
是否使用向量检索。
1(默认):是
0:否
0、1
use_pos
是否使用分词检索。
1(默认):是
0:否
0、1
hybrid_type
混合得分类型:
0:表示将两个结果取并集,排序得分通过hybrid_score计算。
1:表示取并集,但只看位置,向量检索优先。
2:表示取两个结果的交集,排序得分按hybrid_score计算。
0、1、2
hybrid_score
混合得分的比例为:
hybrid_score*vec_score + (1-hybrid_score)*pos_score
。0 ≤ hybrid_score ≤ 1
ranker_model
表示创建模型后ranker模型名称,默认为空。
''
category_ids
用英文逗号分隔category_id。
'c1, c2'
file_id
根据ID指定文件生成回答。
'Polar4AI'
generate
是否使用大模型生成。
1(默认):是,使用大模型归纳生成结果。
0:否,不使用大模型归纳生成结果,直接返回检索结果。
0、1
(可选)调用通义千问
您可以根据RAG的检索结果,调用通义千问生成结果。具体操作,请参见通义千问大模型数据推理和交互。