文章目录
- 一、项目示例
- 二、基础知识:对话模式
- 2.1 概念
- 2.2 RAG
- 三、基础知识:返回结构化数据
- 四、项目实现
- 4.1 申请大模型
- 4.2 调用大模型
- 五、其他
一、项目示例
代码地址:https://github.com/weiminye/time-geekbang-org-rag
项目使用了 Python3.9
(1) 安装依赖
进入源代码解压后的目录,然后再进入
cd 源代码解压后的目录
cd 实战案例1\改造前
输入以下命令安装所有依赖
pip install -r requirements.txt
(2)运行示例
python manage.py migrate
python manage.py runserver
打开浏览器,访问 http://127.0.0.1:8000/, 出现如下页面。
二、基础知识:对话模式
2.1 概念
在对话里,用户一般称为 user, AI 一般称为 assistant。比较特殊的是,从 ChatGPT(GPT3.5)开始,OpenAI 新增了一个角色——system(系统的英文),这个角色有助于设置 AI 的行为。你可以在 system 角色里面,描述 AI 在整个对话过程中应该如何表现。例如:
系统:你是一个ERP MIS系统
用户:客户A的款项到账了多少?
AI:已到账款项为57980。
但有两点需要我们注意。第一,系统消息是可选的。第二,目前除了 OpenAI 之外,很多大模型都不支持系统这一角色。
2.2 RAG
RAG 全称是“Retrieval-Augmented Generation”,即“检索增强的生成”。
它的核心思想是利用外部知识库或数据集来辅助模型的生成过程。具体来说,RAG 通常包含以下关键步骤。
- 检索阶段:首先,模型会根据输入的查询或问题,从预先构建的索引中检索出最相关的数据、文档或文本片段。
- 生成阶段:随后,模型会使用这个综合的表示来生成答案或输出文本。在问答任务中,这通常意味着生成一个对原始查询的直接回答。
除此之外,还有两个阶段:
- 编码阶段:检索到的文档或文本片段会与原始查询一起被编码成高维向量(多维数组的专业说法,只不过这里的多维多到几百、上千的那种)。
- 融合阶段:编码后的向量会进行融合,以生成一个综合的表示,这个表示同时包含了原始查询和检索到的相关信息。
也就是说RAG会包含四个阶段:
- 检索阶段
- 编码阶段
- 融合阶段
- 生成阶段
但编码和融合阶段并不是 RAG 应用必需的,检索和生成阶段才是 RAG 应用必需的。
三、基础知识:返回结构化数据
大模型对话模式返回的结果通常是人类语言,我们可以通过一些特定的 prompt 让模型返回 JSON 格式的结果。
无论要返回什么类型的数据,可以都让模型以 JSON 格式的方式返回。
此外还可以添加辅助信息。通过辅助信息我们可以理解大模型为什么会输出这样的结果。例如,我们可以要求大模型输出以下 json 结果。
{'result':false,'理由':'不是,老婆饼和老婆不是同一类东西'}
Few-shot
在实际应用中,大模型可能还是无法正常输出结构化数据。这时可以给大模型一个示例,让大模型参考输出。提供示例的对话模式如下。
messages=[{"role": "user", "content": f"""请根据用户的输入返回json格式结果:示例1:用户:客户北京极客邦有限公司的款项到账了多少?系统:{{'模块':1,'客户名称':'北京极客邦有限公司'}}用户:{用户输入}系统:"""},]
四、项目实现
原文 UI 部分、DB部分等与RAG无关,这里不展开,具体可参考项目代码。
4.1 申请大模型
这里使用使用百度 ERNIE-Lite-8K 大模型。
由于百度的 v1 版本推理服务创建入口关闭,原文的鉴权方式已经失效,详见:v1版本推理服务创建入口关闭通知
新的 v2 版本的 API 鉴权方式参考:https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Um2wxbaps
4.2 调用大模型
v2 版本模型服务的调用方式与原文有一些区别,具体可参考官网文档:https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Fm2vrveyu
相关调用代码改造如下:
import jsonimport requests# 原文的“对话模式”函数修改后代码如下
def 对话模式(messages, 用户输入, 原文不带入大模型对话中, 结果不带入大模型对话中):api_key = xxxx # 替换为你的 api_keyurl = "https://qianfan.baidubce.com/v2/chat/completions"json_obj = {"model": "ernie-lite-8k","messages": messages,}playload = json.dumps(json_obj)headers = {'Content-Type': 'application/json','Authorization': 'Bearer ' + api_key}response = requests.request("POST", url, headers=headers, data=playload)json_result = json.loads(response.text)if "error" in json_result:return json_result["error"]["message"] + ": " + playloadelse:处理后结果 = 对AI结果进一步处理(json_result["choices"][0]["message"]["content"])保存对话记录(messages[-1]["role"], 用户输入, messages[-1]["content"], playload, 原文不带入大模型对话中)保存对话记录("assistant", json_result["choices"][0]["message"]["content"], 处理后结果, None, 结果不带入大模型对话中)return 处理后结果
你的 api_key 可以在 这里 找到。
如果模型输出不够理想,可以通过修改提示词(更明确的需求描述、更多的示例等)、增加重试策略等方式来优化。
五、其他
python 代码归类技巧,可以将代码用 region 块分隔,示例如下:
# region 跟具体大模型相关的,如果需要修改大模型,可能需要修改这部分函数
....
# endregion#region 诊断与调试
...
#endregion
分块后可以按 region 折叠。