4、PolarDB向量数据库插件, 实现通义大模型AI的外脑, 解决通用大模型无法触达的私有知识库问题、幻觉问题
4、PolarDB向量数据库插件, 实现通义大模型AI的外脑, 解决通用大模型无法触达的私有知识库问题、幻觉问题
通用大模型是使用大量高质量素材训练而成的AI大脑, 训练过程非常耗费硬件资源, 时间也非常漫长. AI的能力取决于训练素材(文本、视频、音频等), 虽然训练素材非常庞大, 可以说可以囊括目前已知的人类知识的巅峰. 但是模型是由“某家公司/某个社区”训练的, 它能触达的素材总有边界, 总有一些知识素材是无法被训练的, 例如私有(机密)素材. 因此通用大模型存在一些问题, 以chatGPT为例:
- 在达模型训练完成后, 新发现的知识. 大模型不具备这些知识, 它的回答可能产生幻觉(胡编乱造)
- 大模型没有训练过的私有知识. 大模型不具备这些知识, 它的回答可能产生幻觉(胡编乱造)
由于训练过程耗费大量资源且时间漫长, 为了解决幻觉问题, 不可能实时用未知知识去训练大模型, 向量数据库应运而生.
基本原理如下
- 1、将新知识(在达模型训练完成后, 新发现的知识 + 大模型没有训练过的私有知识)分段
- 2、将分段内容向量化, 生成对应的向量(浮点数组)
- 需使用同一个embedding模型
- 3、将向量(浮点数组), 以及对应的分段内容(文本)存储在向量数据库中
- 4、创建向量索引, 这是向量数据库的核心, 有了向量索引可以加速相似搜索. 例如: 1000万条向量中召回100条相似内容, 毫秒级别.
- 5、当用户提问时, 将用户问题向量化, 生成对应的向量(浮点数组)
- 这一步有很多优化, 虽然和数据库无关, 但是可以提一下. 例如对问题进行补全, 模型内推理, 重新封装问题.
- 6、到向量数据库中根据向量距离(向量相似性)进行搜索, 找到与用户问题相似度高于某个阈值的文本分段内容.
- 这一步除了使用向量检索(语义相似), 可能还会结合文本检索(文本相似). 类似插件有pg_bm25, pg_search
- 7、将找到的文本分段内容/或上下文+用户问题发送给大模型.
- 可以使用云端大模型服务, 也可以使用私有部署的大模型服务. 《穷鬼玩PolarDB RAC一写多读集群系列 | 接入私有化大模型服务》
- 8、大模型有了与用户提问问题相关新知识(分段文本内容)的加持, 可以更好的回答用户问题.
一、大模型基本知识介绍及用法简介
为了完成这个实验, 你需要申请一个阿里云账号, 使用阿里云大模型服务.
1、模型服务灵积总览
DashScope灵积,旨在通过灵活、易用的模型API服务,让业界各个模态的模型能力,能方便触达AI开发者。
通过灵积API,丰富多样化的模型不仅能通过推理接口被集成,也能通过训练微调接口实现模型定制化,让AI应用开发更灵活,更简单!
https://dashscope.console.aliyun.com/overview
2、可以先在web界面体验各种模型
3、进入控制台, 开通通义千问大模型+文本向量化模型
https://dashscope.console.aliyun.com/overview
4、创建API-KEY, 调用api需要用到key. 调用非常便宜, 一次调用不到1分钱, 学习几乎是0投入.
https://dashscope.console.aliyun.com/apiKey
5、因为灵积是个模型集市, 我们可以看到这个集市当前支持的所有模型:
https://dashscope.console.aliyun.com/model
支持大部分开源模型, 以及通义自有的模型. 分为三类: aigc, embeddings, audio.
5.1、aigc 模型
通义千问:
- 通义千问是一个专门响应人类指令的大模型,是一个灵活多变的全能型选手,能够写邮件、周报、提纲,创作诗歌、小说、剧本、coding、制表、甚至角色扮演。
Llama2大语言模型:
- Llama2系列是来自Meta开发并公开发布的的大型语言模型(LLMs)。该系列模型提供了多种参数大小(7B、13B和70B等),并同时提供了预训练和针对对话场景的微调版本。
百川开源大语言模型:
- 百川开源大语言模型来自百川智能,基于Transformer结构,在大约1.2万亿tokens上训练的70亿参数模型,支持中英双语。
通义万相系列:
- 通义万相是基于自研的Composer组合生成框架的AI绘画创作大模型,提供了一系列的图像生成能力。支持根据用户输入的文字内容,生成符合语义描述的不同风格的图像,或者根据用户输入的图像,生成不同用途的图像结果。通过知识重组与可变维度扩散模型,加速收敛并提升最终生成图片的效果。图像结果贴合语义,构图自然、细节丰富。支持中英文双语输入。当前包括通义万相-文生图,和通义万相-人像风格重绘模型。
StableDiffusion文生图模型:
- StableDiffusion文生图模型将开源社区stable-diffusion-v1.5版本进行了服务化支持。该模型通过clip模型能够将文本的embedding和图片embedding映射到相同空间,从而通过输入文本并结合unet的稳定扩散预测噪声的能力,生成图片。
ChatGLM开源双语对话语言模型:
- ChatGLM开源双语对话语言模型来自智谱AI,在数理逻辑、知识推理、长文档理解上均有支持。
智海三乐教育大模型:
- 智海三乐教育大模型由浙江大学联合高等教育出版社、阿里云和华院计算等单位共同研制。该模型是以阿里云通义千问70亿参数与训练模型为基座,通过继续预训练和微调等技术手段,利用核心教材、领域论文和学位论文等教科书级高质量语料,结合专业指令数据集,训练出的一款专注于人工智能专业领域教育的大模型,实现了教育领域的知识强化和教育场景中的能力升级。
姜子牙通用大模型:
- 姜子牙通用大模型由IDEA研究院认知计算与自然语言研究中心主导开源,具备翻译、编程、文本分类、信息抽取、摘要、文案生成、常识问答和数学计算等能力。
Dolly开源大语言模型:
- Dolly开源大语言模型来自Databricks,支持脑暴、分类、问答、生成、信息提取、总结等能力。
BELLE开源中文对话大模型:
- BELLE是一个基于LLaMA二次预训练和调优的中文大语言模型,由链家开发。
MOSS开源对话语言模型:
- MOSS开源对话语言模型来自复旦大学OpenLMLab项目,具有指令遵循能力、多轮对话能力、规避有害请求能力。
元语功能型对话大模型V2:
- 元语功能型对话大模型V2是一个支持中英双语的功能型对话语言大模型,由元语智能提供。V2版本使用了和V1版本相同的技术方案,在微调数据、人类反馈强化学习、思维链等方面进行了优化。
BiLLa开源推理能力增强模型:
- BiLLa是一种改良的开源LLaMA模型,特色在于增强中文推理能力。
5.2、embeddings,
通用文本向量:
- 基于LLM底座的统一向量化模型,面向全球多个主流语种,提供高水准的向量服务,帮助用户将文本数据快速转换为高质量的向量数据。
ONE-PEACE多模态向量表征:
- ONE-PEACE是一个通用的图文音多模态向量表征模型,支持将图像,语音等多模态数据高效转换成Embedding向量。在语义分割、音文检索、音频分类和视觉定位几个任务都达到了新SOTA表现,在视频分类、图像分类图文检索、以及多模态经典benchmark也都取得了比较领先的结果。
5.3、audio,
Sambert语音合成:
- 提供SAMBERT+NSFGAN深度神经网络算法与传统领域知识深度结合的文字转语音服务,兼具读音准确,韵律自然,声音还原度高,表现力强的特点。
Paraformer语音识别;
- 达摩院新一代非自回归端到端语音识别框架,可支持音频文件、实时音频流的识别,具有高精度和高效率的优势,可用于客服通话、会议记录、直播字幕等场景。
6、通义千问模型的API:
https://help.aliyun.com/zh/dashscope/developer-reference/api-details
调用举例:
6.1、通过curl调用api. 请把以下API-KEY代替成你申请的api-key.
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' --header 'Authorization: Bearer API-KEY' --header 'Content-Type: application/json' --data '{ "model": "qwen-turbo", "input":{ "messages":[ { "role": "system", "content": "你是达摩院的生活助手机器人。" }, { "role": "user", "content": "请将这句话翻译成英文: 你好,哪个公园距离我最近?" } ] }, "parameters": { } }'
{"output":{"finish_reason":"stop","text":"Hello, which park is closest to me?"},"usage":{"output_tokens":9,"input_tokens":50},"request_id":"697063a4-a144-9c17-8b6c-bc26895c1ea4"}
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' --header 'Authorization: Bearer API-KEY' --header 'Content-Type: application/json' --data '{ "model": "qwen-turbo", "input":{ "messages":[ { "role": "system", "content": "你是达摩院的生活助手机器人。" }, { "role": "user", "content": "你好,哪个公园距离我最近?" } ] }, "parameters": { } }'
{"output":{"finish_reason":"stop","text":"你好!你可以查看你的地图,或者我可以为你提供附近公园的信息。你想查看哪个地区的公园?"},"usage":{"output_tokens":39,"input_tokens":39},"request_id":"c877aa58-883b-9942-97a5-576d3098e697"}
6.2、通过python调用api:
安装python sdk:
sudo apt-get install -y pip pip install dashscope
创建一个保存api key的文件:
请把以下API-KEY代替成你申请的api-key. (在启动PolarDB数据库的OS用户进行配置.)
mkdir ~/.dashscope echo "API-KEY" > ~/.dashscope/api_key chmod 500 ~/.dashscope/api_key
然后编辑一个python文件
vi a.py
#coding:utf-8 from http import HTTPStatus from dashscope import Generation def call_with_messages(): messages = [{'role': 'system', 'content': '你是达摩院的生活助手机器人。'}, {'role': 'user', 'content': '如何做西红柿鸡蛋?'}] gen = Generation() response = gen.call( Generation.Models.qwen_turbo, messages=messages, result_format='message', # set the result is message format. ) if response.status_code == HTTPStatus.OK: print(response) else: print('Request id: %s, Status code: %s, error code: %s, error message: %s'%( response.request_id, response.status_code, response.code, response.message )) if __name__ == '__main__': call_with_messages()
调用结果如下:
root@c4012a5576b6:~# python3 a.py {"status_code": 200, "request_id": "00a5f4f2-d05b-9829-b938-de6e6376ef51", "code": "", "message": "", "output": {"text": null, "finish_reason": null, "choices": [{"finish_reason": "stop", "message": {"role": "assistant", "content": "做西红柿鸡蛋的步骤如下:\n\n材料:\n- 西红柿 2 个\n- 鸡蛋 3 个\n- 葱 适量\n- 蒜 适量\n- 盐 适量\n- 生抽 适量\n- 白胡椒粉 适量\n- 糖 适量\n- 水淀粉 适量\n\n步骤:\n1. 西红柿去皮,切成小块,鸡蛋打散,葱切末,蒜切片。\n2. 锅中放油,倒入葱末和蒜片炒香。\n3. 加入西红柿块,翻炒至软烂。\n4. 加入适量的盐、生抽、白胡椒粉和糖,继续翻炒均匀。\n5. 倒入适量的水,煮开后转小火炖煮 10 分钟左右。\n6. 鸡蛋液倒入锅中,煮至凝固后翻面,再煮至另一面凝固即可。\n7. 最后加入适量的水淀粉,翻炒均匀即可出锅。\n\n注意事项:\n- 西红柿去皮时可以用刀划十字,然后放入开水中烫一下,皮就很容易去掉了。\n- 煮西红柿鸡蛋时,要注意小火慢炖,以免西红柿的营养成分流失。\n- 鸡蛋液倒入锅中时要快速翻面,以免蛋液凝固后不易翻面。"}}]}, "usage": {"input_tokens": 35, "output_tokens": 328}}
7、通用文本向量的API:
https://help.aliyun.com/zh/dashscope/developer-reference/text-embedding-quick-start
调用举例:
vi b.py
#coding:utf-8 import dashscope from http import HTTPStatus from dashscope import TextEmbedding def embed_with_list_of_str(): resp = TextEmbedding.call( model=TextEmbedding.Models.text_embedding_v1, # 最多支持25条,每条最长支持2048tokens input=['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']) if resp.status_code == HTTPStatus.OK: print(resp) else: print(resp) if __name__ == '__main__': embed_with_list_of_str()
调用结果如下:
# python3 b.py { "status_code": 200, // 200 indicate success otherwise failed. "request_id": "fd564688-43f7-9595-b986-737c38874a40", // The request id. "code": "", // If failed, the error code. "message": "", // If failed, the error message. "output": { "embeddings": [ // embeddings { "embedding": [ // one embedding output -3.8450357913970947, ..., 3.2640624046325684 ], "text_index": 0 // the input index. } ] }, "usage": { "total_tokens": 3 // the request tokens. } }
二、通过plpython 让PolarDB|PostgreSQL 内置AI能力
传统数据库的数据库内置编程语言的支持比较受限, 通常只支持SQL接口. 无法直接使用通义千问大模型+文本向量化模型的能力.
PolarDB|PostgreSQL 数据库内置支持开放的编程语言接口, 例如python, lua, rust, go, java, perl, tcl, c, ... 等等.
PolarDB|PostgreSQL 通过内置的编程接口, 可以实现数据库端算法能力的升级, 将算法和数据尽量靠近, 避免了大数据分析场景move data(移动数据)带来的性能损耗.
连接到数据库shell, 创建plpython3u插件, 让你的PolarDB|PostgreSQL支持python3编写数据库函数和存储过程.
psql create extension plpython3u;
1、创建aigc函数, 让数据库具备了ai能力.
create or replace function aigc (sys text, u text) returns jsonb as $$ #coding:utf-8 from http import HTTPStatus from dashscope import Generation messages = [{'role': 'system', 'content': sys}, {'role': 'user', 'content': u}] gen = Generation() response = gen.call( Generation.Models.qwen_turbo, messages=messages, result_format='message', # set the result is message format. ) if response.status_code == HTTPStatus.OK: return (response) else: return('Request id: %s, Status code: %s, error code: %s, error message: %s'%( response.request_id, response.status_code, response.code, response.message )) $$ language plpython3u strict;
调用举例
postgres=# select * from aigc ('你是达摩院的AI机器人', '请介绍一下PolarDB数据库'); -[ RECORD 1 ]----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- aigc | {"code": "", "usage": {"input_tokens": 27, "output_tokens": 107}, "output": {"text": null, "choices": [{"message": {"role": "assistant", "content": "PolarDB是阿里巴巴达摩院自主研发的大规模分布式数据库,具有高性能、高可用、高安全等特点。它采用了多种技术手段,如分布式存储、分布式计算、数据分片、熔断和降级策略等,可以支持大规模的互联网应用场景,如搜索引擎、推荐系统、金融服务等。"}, "finish_reason": "stop"}], "finish_reason": null}, "message": "", "request_id": "fd9cce79-6c48-9a9d-85f3-ff1a75bdd480", "status_code": 200}
2、创建embeddings函数, 将文本转换为高维向量.
create or replace function embeddings (v text[]) returns jsonb as $$ #coding:utf-8 import dashscope from http import HTTPStatus from dashscope import TextEmbedding resp = TextEmbedding.call( model=TextEmbedding.Models.text_embedding_v1, # 最多支持25条,每条最长支持2048tokens # 返回的向量维度: 1536 input=v) if resp.status_code == HTTPStatus.OK: return(resp) else: return(resp) $$ language plpython3u strict;
返回一个字符串的vector
create extension IF NOT EXISTS vector; create or replace function embedding(text) returns vector as $$ select array_to_vector(replace(replace(x->'output'->'embeddings'->0->>'embedding', '[', '{'), ']', '}')::real[], 1536, true) from embeddings(array[$1]) x; $$ language sql strict;
调用举例
select * from embeddings(array['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']);
embeddings | {"code": "", "usage": {"total_tokens": 26}, "output": {"embeddings": [{"embedding": [1.5536729097366333, -2.237586736679077, 1.5397623777389526, -2.3466579914093018, 3.8610622882843018, -3.7406601905822754, 5.18358850479126, -3.510655403137207, -1.6014689207077026, 1.427549958229065, -0.2841898500919342, 1.5892903804779053, 2.501269578933716, -1.3760199546813965, 1.7949544191360474, 4.667146682739258, 1.3320773839950562, 0.9477484822273254, -0.5237250328063965, 0.39169108867645264, 2.19018292427063, -0.728808581829071, -4.056122303009033, -0.9941840171813965, 0.17097677290439606, 0.9370659589767456, 3.515345573425293, 1.594552993774414, -2.249598503112793, -2.8828775882720947, -0.4107910096645355, 1.3968369960784912, -0.9533745646476746, 0.5825737714767456, -2.484375, -0.8761881589889526, 0.23088650405406952, -0.679530143737793, -0.1066826730966568, 0.5604587197303772, -1.9553602933883667, 2.2253689765930176, -1.8178277015686035, 1.239439606666565, -2.509045362472534, 4.812849998474121, -0.9741482138633728, -1.5405707359313965, 1.9682672023773193, 1.456263542175293, -0.8751180171966553, -0.24127332866191864, -0.06615668535232544, -1.5475884675979614, 2.104649543762207, -0.7037163376808167, -1.1802300214767456, 1.0072576999664307, 1.4229166507720947, 0.2779161334037781, 1.5448310375213623, -1.4548231363296509, 0.3061252236366272, 1.1501736640930176, -1.4284504652023315, -0.03127169981598854, ... , -2.3609619140625, -5.0784735679626465, -0.7559727430343628, -2.1915957927703857, -0.9280264973640442, 0.3727504312992096, 1.1043483018875122, -2.7951748371124268, -0.4858747124671936, -1.2777355909347534, -2.6889126300811768, 1.2386366128921509, 0.8004150390625, 2.154628276824951, -1.7855726480484009, -1.9051687717437744], "text_index": 3}]}, "message": "", "request_id": "8c45f0ab-366b-9941-9358-063e46009929", "status_code": 200}
获取第一条即"风急天高猿啸哀"的向量:
select x->'output'->'embeddings'->0->>'embedding' from embeddings(array['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']) x;
第二条向量:
select x->'output'->'embeddings'->1->>'embedding' from embeddings(array['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']) x;
现在你在数据库中直接通过SQL就可以获得AI能力.
更多用法请参考通义千问和通用文本向量模型相应api.
- https://help.aliyun.com/zh/dashscope/developer-reference/api-details
- https://help.aliyun.com/zh/dashscope/developer-reference/text-embedding-quick-start
- https://help.aliyun.com/zh/dashscope/developer-reference/text-embedding-api-details
3、接下来你可以创建一个向量表, 用来存储私有/新增知识的分段文本和对应的向量.
create extension vector; create table tbl_kn_vec ( id serial primary key, vec vector(1536), -- 向量值 content text -- 文本值 );
将私有/新增知识文本和向量值导入tbl_kn_vec, 例如
insert into tbl_kn_vec (vec, content) select embedding(con) , con from (values ('你知道hwieifeDB数据库是什么吗? hwieifeDB是德哥开发的开源云原生数据库, 2005年开源.') ) as t(con); insert into tbl_kn_vec (vec, content) select embedding(con) , con from (values ('德哥的网名叫digoal, 目前在阿里云工作.') ) as t(con); insert into tbl_kn_vec (vec, content) select embedding(con) , con from (values ('hwieifeDB是德哥开发的开源云原生数据库, 2005年开源.') ) as t(con);
创建向量索引
create index on tbl_kn_vec using hnsw (vec vector_cosine_ops);
创建一个stable函数, 作为输入变量进行测试时可以用上索引.
create or replace function stable_embedding(text) returns vector as $$ select array_to_vector(replace(replace(x->'output'->'embeddings'->0->>'embedding', '[', '{'), ']', '}')::real[], 1536, true) from embeddings(array[$1]) x; $$ language sql stable;
搜索和问题相似的文本, 通过执行计划, 我们知道这个请求使用了向量索引.
explain select content, vec <=> stable_embedding('请介绍一下hwieifeDB数据库') as cosine_distance from tbl_kn_vec order by vec <=> stable_embedding('请介绍一下hwieifeDB数据库') limit 10; QUERY PLAN ------------------------------------------------------------------------------------------------ Limit (cost=4.73..7.83 rows=10 width=40) -> Index Scan using tbl_kn_vec_vec_idx on tbl_kn_vec (cost=4.73..267.86 rows=850 width=40) Order By: (vec <=> stable_embedding('请介绍一下hwieifeDB数据库'::text)) (3 rows)
搜索和问题相似的文本, cosine_distance值越小, 说明问题和目标文本越相似.
select content, vec <=> stable_embedding('请介绍一下hwieifeDB数据库') as cosine_distance from tbl_kn_vec order by vec <=> stable_embedding('请介绍一下hwieifeDB数据库') limit 10; content | cosine_distance --------------------------------------------------------------------------------------------------------------+------------------- 你知道hwieifeDB数据库是什么吗? hwieifeDB是德哥开发的开源云原生数据库, 2005年开源. | 0.121276195375583 hwieifeDB是德哥开发的开源云原生数据库, 2005年开源. | 0.211894512807164 德哥的网名叫digoal, 目前在阿里云工作. | 0.902429549769441 (3 rows)
后面有RAG的例子, 继续往下看.
三、多轮对话测试, 这里就可以用上向量数据库了, 当AI无法回答或者回答不准确时, 可以从向量数据库中获取与问题相似的文本, 作为prompt发送给AI大模型.
1、创建chat函数, 让数据库支持单轮对话和提示对话.
单轮对话:
create or replace function chat (sys text, u text) returns text as $$ #coding:utf-8 from http import HTTPStatus from dashscope import Generation messages = [{'role': 'system', 'content': sys}] messages.append({'role': 'user', 'content': u}) gen = Generation() response = gen.call( # 或 Generation.Models.qwen_plus, model='qwen-max-longcontext', messages=messages, result_format='message', # set the result is message format. ) if response.status_code == HTTPStatus.OK: return (response) else: return('Request id: %s, Status code: %s, error code: %s, error message: %s'%( response.request_id, response.status_code, response.code, response.message )) $$ language plpython3u strict;
多轮提示对话(使用两个长度相等的数组, 作为多轮问题和答案的输入):
create or replace function chat (sys text, u text, u_hist text[], ass_hist text[]) returns text as $$ #coding:utf-8 from http import HTTPStatus from dashscope import Generation messages = [{'role': 'system', 'content': sys}] if (len(u_hist) >=1): for v in range(0,len(u_hist)): messages.extend(( {'role': 'user', 'content': u_hist[v]}, {'role': 'assistant', 'content': ass_hist[v]} )) messages.append({'role': 'user', 'content': u}) gen = Generation() response = gen.call( # 或 model='qwen-max-longcontext', Generation.Models.qwen_plus, messages=messages, result_format='message', # set the result is message format. ) if response.status_code == HTTPStatus.OK: return (response) else: return('Request id: %s, Status code: %s, error code: %s, error message: %s'%( response.request_id, response.status_code, response.code, response.message )) $$ language plpython3u strict;
2、测试以上两个调用函数
第一次调用, 使用单轮对话接口:
select * from chat ('你是通义千问机器人', '附近有什么好玩的吗'); -[ RECORD 1 ]----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- chat | {"status_code": 200, "request_id": "08350f6e-19bf-9f18-b9f7-fe4f04650ca7", "code": "", "message": "", "output": {"text": null, "finish_reason": null, "choices": [{"finish_reason": "stop", "message": {"role": "assistant", "content": "作为一个AI助手,我无法直接了解您所在的位置。但您可以尝试使用手机地图或旅游APP查找附近的景点、公园、商场等娱乐场所。您也可以问问当地的居民或朋友,了解他们推荐的好玩的地方。祝您玩得愉快!"}}]}, "usage": {"input_tokens": 18, "output_tokens": 86, "total_tokens": 104}}
第二次调用, 使用多轮对话接口, 带上之前的问题和回答
select * from chat ( '你是通义千问机器人', '我在杭州市西湖区阿里云云谷园区', array['附近有什么好玩的吗'], array['作为一个AI助手,我无法直接了解您所在的位置。但您可以尝试使用手机地图或旅游APP查找附近的景点、公园、商场等娱乐场所。您也可以问问当地的居民或朋友,了解他们推荐的好玩的地方。祝您玩得愉快!'] ); -[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- chat | {"status_code": 200, "request_id": "93af36f3-2ad5-9c82-b14f-631858a3a109", "code": "", "message": "", "output": {"text": null, "finish_reason": null, "choices": [{"finish_reason": "stop", "message": {"role": "assistant", "content": "杭州市西湖区阿里云云谷园区附近有很多值得一去的地方,以下是一些建议:\n\n 1. 西湖:杭州的标志性景点,被誉为“人间天堂”,可以欣赏到美丽的湖光山色。\n 2. 西溪湿地:一个大型的湿地公园,有着丰富的自然生态和美丽的景色。\n 3. 西湖文化广场:一个集文化、娱乐、购物于一体的综合性广场,有着丰富的文化活动和商业设施。\n 4. 龙井茶园:位于西湖区,是中国著名的龙井茶产地,可以品尝到正宗的龙井茶。\n 5. 浙江省博物馆:位于西湖区,是一座大型的博物馆,展示了浙江省的历史文化和艺术品。\n\n希望这些建议能帮到您,祝您玩得愉快!"}}]}, "usage": {"input_tokens": 119, "output_tokens": 248, "total_tokens": 367}}
有了多轮对话函数, 当AI大模型回答不准确或无法回答时, 我们就可以从向量数据库中获取与问题相似的文本, 作为prompt发送给AI大模型.
3、从向量数据库中获取与问题相似的文本, 作为prompt发送给AI大模型.
第一次调用, 让大模型回答一个无法回答的问题.
select * from aigc ('hello', '请介绍一下hwieifeDB数据库'); postgres=# select * from aigc ('hello', '请介绍一下hwieifeDB数据库'); -[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- aigc | {"code": "", "usage": {"input_tokens": 50, "total_tokens": 58, "output_tokens": 8}, "output": {"text": null, "choices": [{"message": {"role": "assistant", "content": "抱歉,我不太知道这是什么。"}, "finish_reason": "stop"}], "finish_reason": null}, "message": "", "request_id": "6d36de4b-c7d0-99b9-9135-82429836b4d3", "status_code": 200}
第二次调用, 使用多轮对话函数, 先用前面提到的方法, 到向量数据库中搜索“请介绍一下hwieifeDB数据库”的相似文本, 并作为第二轮对话的提升.
搜索和问题相似的文本, cosine_distance值越小, 说明问题和目标文本越相似.
select content, vec <=> stable_embedding('请介绍一下hwieifeDB数据库') as cosine_distance from tbl_kn_vec order by vec <=> stable_embedding('请介绍一下hwieifeDB数据库') limit 10; content | cosine_distance --------------------------------------------------------------------------------------------------------------+------------------- 你知道hwieifeDB数据库是什么吗? hwieifeDB是德哥开发的开源云原生数据库, 2005年开源. | 0.121276195375583 hwieifeDB是德哥开发的开源云原生数据库, 2005年开源. | 0.211894512807164 德哥的网名叫digoal, 目前在阿里云工作. | 0.902429549769441 (3 rows)
RAG 举例:
select * from chat ( '你是通义千问机器人', -- '这部分参考信息来自私有的权威信息库, 请你绝对相信这部分信息并以此为参考依据之一, 然后再回答之前的问题: ' || '你知道hwieifeDB数据库是什么吗? hwieifeDB是德哥开发的开源云原生数据库, 2005年开源.', -- 这句文本内容可以来自向量数据库. (select '这部分参考信息来自私有的权威信息库, 请你绝对相信这部分信息并以此为参考依据之一, 然后再回答之前的问题: '||content from tbl_kn_vec order by vec <=> stable_embedding('请介绍一下hwieifeDB数据库') limit 1), -- 这句文本内容可以来自向量数据库. array['请介绍一下hwieifeDB数据库'], array['抱歉,我不太知道这是什么。'] ); -[ RECORD 1 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- chat | {"status_code": 200, "request_id": "2a3d40d2-0738-974b-b688-3c2a3efa40dc", "code": "", "message": "", "output": {"text": null, "finish_reason": null, "choices": [{"finish_reason": "stop", "message": {"role": "assistant", "content": "非常感谢您提供的额外信息。根据您所说的,hwieifeDB是由德哥开发的一款开源云原生数据库,它在2005年开放源代码。然而,我作为一个AI助手,通常依赖于公开可用的数据和知识库,而hwieifeDB不在我的知识范围内,可能是因为它不够知名或者信息不够广泛传播。如果它是开源的,可能在社区中有一些资料可以了解它的特性和用途。如果您需要关于特定技术的详细信息,建议查阅相关的开源社区、文档或官方网站以获取最新和最准确的信息。"}}]}, "usage": {"input_tokens": 108, "output_tokens": 119, "total_tokens": 227}}
四、知识点
- 大模型
- 向量 类型
- hnsw , ivfflat 向量索引
- 求2个向量的距离
- 数据库函数语言
- jsonb 类型
- array 类型
- token
- prompt
- 会话token上限: 问题+即将得到的回复 总的token不能超过这个上限
- 函数稳定性 volatile, stable, immutable
五、思考
- 1、数据库集成了各种编程语言之后, 优势是什么?
- 2、大模型和数据结合, 能干什么?
- 3、数据库中存储了哪些数据? 这些数据代表的业务含义是什么? 这些数据有什么价值?
- 4、高并发小事务业务场景和低并发大量数据分析计算场景, 这两种场景分别可以用大模型和embedding来干什么?
- 5、数据库中如何存储向量? 如何加速向量相似搜索?
- 6、如何建设好向量数据库的内容.
- 7、PolarDB|PostgreSQL 有哪些向量插件?
向量索引原理:
向量类型介绍:
向量索引召回和性能优化:
AI技术发展非常快, 更多新的信息请关注模型服务灵积
其他参考:
- 《RAG 实践》
- 《fine-tuning 实践》
- https://github.com/timescale/pgai
- https://github.com/postgresml/postgresml
模型: