1.背景
欢迎数据库应用开发者参与贡献场景, 在此issue回复即可, 共同建设《沉浸式数据库学习教学素材库》, 帮助开发者用好数据库, 提升开发者职业竞争力, 同时为企业降本提效.
- 系列课程的核心目标是教大家怎么用好数据库, 而不是怎么运维管理数据库、怎么开发数据库内核. 所以面向的对象是数据库的用户、应用开发者、应用架构师、数据库厂商的产品经理、售前售后专家等角色.
本文的实验可以使用永久免费的阿里云云起实验室来完成.
如果你本地有docker环境也可以把镜像拉到本地来做实验:
x86_64机器使用以下docker image:
ARM机器使用以下docker image:
2.业务场景1 介绍: 向量数据库, 作为通义AI的外脑设计
chatbot是大模型应用之一, 在与chatbot沟通时会遇到token上限问题, 例如通义目前是8K, chatgpt是4K. 也就是问题上下文(包含多轮对话的内容)最多8k或4k, 超出就无法处理了.
解释一下token: 对于通义模型来说, 中文字符串的token就是字数(含符号). 英文则可能是词、片段等.
我们的核心目的是通过有限的上下文来拿到结果.
这就需要你的prompt(上下文)足够精确, 防止无效垃圾对话浪费token限额.
上下文的组成:
1、每一轮对话的提问内容和大模型的回答内容
2、外脑中的FAQ
这个实验要体验的就是怎么建设AI的外脑?
向量数据库的核心价值:
- AI的外脑.
参考知识:
- https://help.aliyun.com/zh/dashscope/developer-reference/api-details
- https://neon.tech/docs/extensions/pg_tiktoken
- https://neon.tech/docs/ai/ai-concepts
- https://github.com/kelvich/pg_tiktoken
2.1实现和对照
2.1.1传统方法 设计和实验
传统数据库不支持向量, 略.
2.1.2PolarDB|PG新方法1 设计和实验
上一个实验比较简单, 大家应该体验到了通义大模型可以干什么? 在阿里云可以使用plpython3u来调用灵积里面的诸多大模型能力, 玩法参考:
同时大家也可以思考一下向量数据库到底能干什么?
进入实验环境容器.
安装python sdk:
pip install dashscope
创建一个保存api key的文件:
请把以下API-KEY代替成你申请的api-key.
su - postgres mkdir ~/.dashscope echo "API-KEY" > ~/.dashscope/api_key chmod 500 ~/.dashscope/api_key
连接到数据库shell, 创建plpython3u插件, 让你的PG|PolarDB支持python3编写数据库函数和存储过程.
psql create extension plpython3u;
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, 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( 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;
第一次调用, 使用单轮对话接口:
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}}
第三次调用, 使用多轮对话接口, 继续补上之前交流的内容
select * from chat ( '你是通义千问机器人', '我想去找个足浴店, 需要正规绿色并且口碑好的', array['附近有什么好玩的吗', '我在杭州市西湖区阿里云云谷园区'], array['作为一个AI助手,我无法直接了解您所在的位置。但您可以尝试使用手机地图或旅游APP查找附近的景点、公园、商场等娱乐场所。您也可以问问当地的居民或朋友,了解他们推荐的好玩的地方。祝您玩得愉快!', '杭州市西湖区阿里云云谷园区附近有很多值得一去的地方,以下是一些建议:\n\n 1. 西湖:杭州的标志性景点,被誉为“人间天堂”,可以欣赏到美丽的湖光山色。\n 2. 西溪湿地:一个大型的湿地公园,有着丰富的自然生态和美丽的景色。\n 3. 西湖文化广场:一个集文化、娱乐、购物于一体的综合性广场,有着丰富的文化活动和商业设施。\n 4. 龙井茶园:位于西湖区,是中国著名的龙井茶产地,可以品尝到正宗的龙井茶。\n 5. 浙江省博物馆:位于西湖区,是一座大型的博物馆,展示了浙江省的历史文化和艺术品。\n\n希望这些建议能帮到您,祝您玩得愉快!'] ); -[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- chat | {"status_code": 200, "request_id": "520e9c40-852b-9256-b1a1-10e7cea36531", "code": "", "message": "", "output": {"text": null, "finish_reason": null, "choices": [{"finish_reason": "stop", "message": {"role": "assistant", "content": "作为一个AI助手,我无法直接推荐具体的足浴店。但您可以通过以下几种方式寻找正规、绿色并且口碑好的足浴店:\n\n 1. 在网上搜索评价:您可以在搜索引擎或者相关的点评网站上搜索附近的足浴店,查看其他消费者的评价和口碑,选择评价较高的店铺。\n 2. 向当地居民或朋友咨询:您可以向当地的居民或朋友咨询他们推荐的足浴店,了解他们的服务质量和口碑。\n 3. 查看相关资质:在选择足浴店时,可以查看店铺的相关资质,如营业执照、卫生许可证等,确保店铺是正规合法的。\n\n希望这些建议能帮到您,祝您找到满意的足浴店并享受愉快的时光!"}}]}, "usage": {"input_tokens": 397, "output_tokens": 232, "total_tokens": 629}}
准备第四次调用.
第三轮的答案不理想, 需要给机器人一点提示, 假设我的数据库中有足浴店及其地址, 并且已经将其转换成了embedding向量, 那么我可以先通过足浴店这个关键字进行向量近似搜索, 假设搜索到了
尚沐汇影院式足道在哪里: 浙江省杭州市余杭区五常街道荆长路768号顺帆科技园
那么我们就可以把这一对信息放入多轮对话中, 生成下面的调用: `
select * from chat ( '你是通义千问机器人', '我想去找个足浴店, 需要正规绿色并且口碑好的', array['附近有什么好玩的吗', '我在杭州市西湖区阿里云云谷园区','尚沐汇影院式足道在哪里'], array['作为一个AI助手,我无法直接了解您所在的位置。但您可以尝试使用手机地图或旅游APP查找附近的景点、公园、商场等娱乐场所。您也可以问问当地的居民或朋友,了解他们推荐的好玩的地方。祝您玩得愉快!', '杭州市西湖区阿里云云谷园区附近有很多值得一去的地方,以下是一些建议:\n\n 1. 西湖:杭州的标志性景点,被誉为“人间天堂”,可以欣赏到美丽的湖光山色。\n 2. 西溪湿地:一个大型的湿地公园,有着丰富的自然生态和美丽的景色。\n 3. 西湖文化广场:一个集文化、娱乐、购物于一体的综合性广场,有着丰富的文化活动和商业设施。\n 4. 龙井茶园:位于西湖区,是中国著名的龙井茶产地,可以品尝到正宗的龙井茶。\n 5. 浙江省博物馆:位于西湖区,是一座大型的博物馆,展示了浙江省的历史文化和艺术品。\n\n希望这些建议能帮到您,祝您玩得愉快!','浙江省杭州市余杭区五常街道荆长路768号顺帆科技园'] ); -[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ chat | {"status_code": 200, "request_id": "03e53792-1895-9ff9-9986-046493674b6b", "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\n请注意选择正规、绿色的足浴店,确保自身安全和健康。祝您享受愉快的足浴体验!"}}]}, "usage": {"input_tokens": 433, "output_tokens": 191, "total_tokens": 624}}
以此类推, 当我们发现机器人的回答不是特别准确时, 尽快给出提示.
这个提示就是我们之前一直在说的, 通过将垂直内容输入本地向量数据库, 将近似问题作为prompt来提升AI精准度的方法.
create table tbl_faq( id int primary key, f text, -- 问题 q text, -- 回答 faq_tokens int, -- f+q 的token数. embedding vector -- faq 的向量值, 调用大模型可以将text文本转换为向量, 参考第16个实验 ); create index on tbl_faq using hnsw (embedding);
将有价值的内容输入到tbl_faq表. 例如企业知识库, 数据库应用实践文档.
获取与‘关键字’ 相关的近似问题, 作为prompt来提升AI精准度的方法.
select f,q from tbl_faq order by '关键字' <-> embedding limit 2;
除了之前的问答内容, 再将以上请求得到的 f,q 分别塞入array1, array2.
select * from chat ( '你是通义千问机器人', '我想去找个足浴店, 需要正规绿色并且口碑好的', array1, array2);
2.1.3对照
通过好的prompt, 向量数据库可以让 AI更好的发挥能力. 所以把向量数据库称之为AI外脑不为过.
前提是, 你已经将已有的知识提炼成FAQ, 并存储在向量数据库中.
3.知识点
token
向量
prompt
会话token上限: 问题+即将得到的回复 总的token不能超过这个上限
hnsw
PolarDB|PostgreSQL有哪些向量插件?
4.思考
如何建设好向量数据库的内容.
5.参考
参考知识:
- https://help.aliyun.com/zh/dashscope/developer-reference/api-details
- https://neon.tech/docs/extensions/pg_tiktoken
- https://neon.tech/docs/ai/ai-concepts
- https://github.com/kelvich/pg_tiktoken
- 《沉浸式学习PostgreSQL|PolarDB 16: 植入通义千问大模型+文本向量化模型, 让数据库具备AI能力》
- 《德说-第257期, 新生产力工具AI推动下一级人类文明跃迁? AI如何倒逼数据库的进化? AI加持后的数据库应用场景有哪些变化?》