PolarDB 开源基础教程系列 7.4 应用实践之 AI大模型外脑

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
简介: PolarDB向量数据库插件通过实现通义大模型AI的外脑,解决了通用大模型无法触达私有知识库和产生幻觉的问题。该插件允许用户将新发现的知识和未训练的私有知识分段并转换为向量,存储在向量数据库中,并创建索引以加速相似搜索。当用户提问时,系统将问题向量化并与数据库中的向量进行匹配,找到最相似的内容发送给大模型,从而提高回答的准确性和相关性。此外,PolarDB支持多种编程语言接口,如Python,使数据库具备内置AI能力,极大提升了数据处理和分析的效率。

4、PolarDB向量数据库插件, 实现通义大模型AI的外脑, 解决通用大模型无法触达的私有知识库问题、幻觉问题

b站视频链接

Youtube视频链接


4、PolarDB向量数据库插件, 实现通义大模型AI的外脑, 解决通用大模型无法触达的私有知识库问题、幻觉问题

通用大模型是使用大量高质量素材训练而成的AI大脑, 训练过程非常耗费硬件资源, 时间也非常漫长. AI的能力取决于训练素材(文本、视频、音频等), 虽然训练素材非常庞大, 可以说可以囊括目前已知的人类知识的巅峰. 但是模型是由“某家公司/某个社区”训练的, 它能触达的素材总有边界, 总有一些知识素材是无法被训练的, 例如私有(机密)素材. 因此通用大模型存在一些问题, 以chatGPT为例:

  • 在达模型训练完成后, 新发现的知识. 大模型不具备这些知识, 它的回答可能产生幻觉(胡编乱造)
  • 大模型没有训练过的私有知识. 大模型不具备这些知识, 它的回答可能产生幻觉(胡编乱造)

由于训练过程耗费大量资源且时间漫长, 为了解决幻觉问题, 不可能实时用未知知识去训练大模型, 向量数据库应运而生.

image.png

基本原理如下

  • 1、将新知识(在达模型训练完成后, 新发现的知识 + 大模型没有训练过的私有知识)分段
  • 2、将分段内容向量化, 生成对应的向量(浮点数组)
  • 需使用同一个embedding模型
  • 3、将向量(浮点数组), 以及对应的分段内容(文本)存储在向量数据库中
  • 4、创建向量索引, 这是向量数据库的核心, 有了向量索引可以加速相似搜索. 例如: 1000万条向量中召回100条相似内容, 毫秒级别.
  • 5、当用户提问时, 将用户问题向量化, 生成对应的向量(浮点数组)
  • 这一步有很多优化, 虽然和数据库无关, 但是可以提一下. 例如对问题进行补全, 模型内推理, 重新封装问题.
  • 6、到向量数据库中根据向量距离(向量相似性)进行搜索, 找到与用户问题相似度高于某个阈值的文本分段内容.
  • 这一步除了使用向量检索(语义相似), 可能还会结合文本检索(文本相似). 类似插件有pg_bm25, pg_search
  • 7、将找到的文本分段内容/或上下文+用户问题发送给大模型.
  • 8、大模型有了与用户提问问题相关新知识(分段文本内容)的加持, 可以更好的回答用户问题.

一、大模型基本知识介绍及用法简介

为了完成这个实验, 你需要申请一个阿里云账号, 使用阿里云大模型服务.

1、模型服务灵积总览

DashScope灵积,旨在通过灵活、易用的模型API服务,让业界各个模态的模型能力,能方便触达AI开发者。

通过灵积API,丰富多样化的模型不仅能通过推理接口被集成,也能通过训练微调接口实现模型定制化,让AI应用开发更灵活,更简单!

https://dashscope.console.aliyun.com/overview

2、可以先在web界面体验各种模型

https://dashscope.aliyun.com/

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.

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技术发展非常快, 更多新的信息请关注模型服务灵积

其他参考:

模型:

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
1天前
|
SQL 关系型数据库 分布式数据库
PolarDB 开源基础教程系列 7.5 应用实践之 TPCH性能优化
PolarDB在复杂查询、大数据量计算与分析场景的测试和优化实践.
21 6
|
1天前
|
关系型数据库 分布式数据库 数据库
PolarDB 开源基础教程系列 9 开源社区合作和共建
本文介绍了玩转 PolarDB 开源社区指南:如何搭建 PolarDB 开发环境及参与开源社区。 主要内容: 1. **搭建开发环境**:提供多种 Docker 镜像供开发者选择,支持 x86_64 和 ARM64 架构,适配 CentOS、Debian、Ubuntu 等多个 Linux 发行版。 2. **编译与部署**:通过 Docker 容器克隆 PolarDB 源码并编译安装,支持构建一写多读集群测试 ePQ MPP 优化器功能。 3. **参与开源社区**:介绍个人、生态伙伴和用户如何从社区中获取技能、建立连接、积累战绩并提升影响力。社区活动涵盖公开课、训练营、编程大赛、企业行等。
26 5
|
1天前
|
存储 关系型数据库 分布式数据库
PolarDB 开源基础教程系列 8 数据库生态
PolarDB是一款开源的云原生分布式数据库,源自阿里云商业产品。为降低使用门槛,PolarDB携手伙伴打造了完整的开源生态,涵盖操作系统、芯片、存储、集成管控、监控、审计、开发者工具、数据同步、超融合计算、ISV软件、开源插件、人才培养、社区合作及大型用户合作等领域。通过这些合作伙伴,PolarDB提供了丰富的功能和服务,支持多种硬件和软件环境,满足不同用户的需求。更多信息请访问[PolarDB开源官方网站](https://openpolardb.com/home)。
21 4
|
1天前
|
搜索推荐 关系型数据库 分布式数据库
PolarDB 开源基础教程系列 7.3 应用实践之 精准营销场景
本文介绍了基于用户画像的精准营销技术,重点探讨了如何通过标签组合快速圈选目标人群。实验分为三部分: 1. **传统方法**:使用字符串存储标签并进行模糊查询,但性能较差,每次请求都需要扫描全表。 2. **实验1**:引入`pg_trgm`插件和GIN索引,显著提升了单个模糊查询条件的性能。 3. **实验2**:改用数组类型存储标签,并结合GIN索引加速包含查询,性能进一步提升。 4. **实验3**:利用`smlar`插件实现近似度过滤,支持按标签重合数量或比例筛选。
19 3
|
27天前
|
人工智能 运维 物联网
云大使 X 函数计算 FC 专属活动上线!享返佣,一键打造 AI 应用
如今,AI 技术已经成为推动业务创新和增长的重要力量。但对于许多企业和开发者来说,如何高效、便捷地部署和管理 AI 应用仍然是一个挑战。阿里云函数计算 FC 以其免运维的特点,大大降低了 AI 应用部署的复杂性。用户无需担心底层资源的管理和运维问题,可以专注于应用的创新和开发,并且用户可以通过一键部署功能,迅速将 AI 大模型部署到云端,实现快速上线和迭代。函数计算目前推出了多种规格的云资源优惠套餐,用户可以根据实际需求灵活选择。
|
23天前
|
人工智能 算法 前端开发
OmAgent:轻松构建在终端设备上运行的 AI 应用,赋能手机、穿戴设备、摄像头等多种设备
OmAgent 是 Om AI 与浙江大学联合开源的多模态语言代理框架,支持多设备连接、高效模型集成,助力开发者快速构建复杂的多模态代理应用。
179 72
OmAgent:轻松构建在终端设备上运行的 AI 应用,赋能手机、穿戴设备、摄像头等多种设备
|
9天前
|
人工智能 自然语言处理 搜索推荐
【上篇】-分两篇步骤介绍-如何用topview生成和自定义数字人-关于AI的使用和应用-如何生成数字人-优雅草卓伊凡-如何生成AI数字人
【上篇】-分两篇步骤介绍-如何用topview生成和自定义数字人-关于AI的使用和应用-如何生成数字人-优雅草卓伊凡-如何生成AI数字人
77 23
【上篇】-分两篇步骤介绍-如何用topview生成和自定义数字人-关于AI的使用和应用-如何生成数字人-优雅草卓伊凡-如何生成AI数字人
|
4天前
|
机器学习/深度学习 存储 人工智能
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
MNN-LLM App 是阿里巴巴基于 MNN-LLM 框架开发的 Android 应用,支持多模态交互、多种主流模型选择、离线运行及性能优化。
398 13
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
|
3天前
|
人工智能 自然语言处理 数据可视化
Cursor 为低代码加速,AI 生成应用新体验!
通过连接 Cursor,打破了传统低代码开发的局限,我们无需编写一行代码,甚至连拖拉拽这种操作都可以抛诸脑后。只需通过与 Cursor 进行自然语言对话,用清晰的文字描述自己的应用需求,就能轻松创建出一个完整的低代码应用。
376 8
|
1天前
|
人工智能 自然语言处理 搜索推荐
现在最火的AI是怎么应用到体育行业的
AI在体育行业的应用日益广泛,涵盖数据分析、伤病预防、观众体验、裁判辅助等多个领域。通过传感器和可穿戴设备,AI分析运动员表现,提供个性化训练建议;预测伤病风险,制定康复方案;优化比赛预测和博彩指数;提升观众的个性化内容推荐和沉浸式观赛体验;辅助裁判判罚,提高准确性;发掘青训人才,优化训练计划;智能管理场馆运营和票务;自动生成媒体内容,提供实时翻译;支持电竞分析和虚拟体育赛事;并为运动员提供个性化营养和健康管理方案。未来,随着技术进步,AI的应用将更加深入和多样化。

相关产品

  • 云原生数据库 PolarDB