llm-universe | 四. 构建RAG应用

news2025/2/24 15:02:37

构建RAG应用

  • 一.将LLM 接入 LangChain
  • 二.构建检索问答链
    • 1.加载向量数据库
    • 2.创建一个 LLM
    • 3.构建检索问答链
    • 4.检索问答链效果测试
    • 5.添加历史对话的记忆功能
      • 5.1 记忆(Memory)
      • 5.2 对话检索链(ConversationalRetrievalChain)
  • 三. 部署知识库助手
    • 1. Streamlit 简介
    • 2、构建应用程序

一.将LLM 接入 LangChain

使用 LangChain 调用智谱 GLM

使用的是智谱 GLM API,需要将封装的代码zhipuai_llm.py下载到本 Notebook 的同级目录下,才可以运行下列代码来在 LangChain 中使用 GLM。

# 需要下载源码
from zhipuai_llm import ZhipuAILLM

from dotenv import find_dotenv, load_dotenv
import os

_ = load_dotenv(find_dotenv())

# 获取环境变量 API_KEY
api_key = os.environ["ZHIPUAI_API_KEY"] #填写控制台中获取的 APIKey 信息

zhipuai_model = ZhipuAILLM(model="chatglm_std", temperature=0, api_key=api_key)
zhipuai_model("你好,请你自我介绍一下!")

返回结果

' 你好,我是 智谱清言,是清华大学KEG实验室和智谱AI公司共同训练的语言模型。我的目标是通过回答用户提出的问题来帮助他们解决问题。由于我是一个计算机程序,所以我没有自我意识,也不能像人类一样感知世界。我只能通过分析我所学到的信息来回答问题。'

二.构建检索问答链

1.加载向量数据库

首先,我们加载在前一章已经构建的向量数据库。注意,此处你需要使用和构建时相同的 Emedding。

import sys
sys.path.append("../C3 搭建知识库") # 将父目录放入系统路径中

# 使用智谱 Embedding API,注意,需要将上一章实现的封装代码下载到本地
from zhipuai_embedding import ZhipuAIEmbeddings

from langchain.vectorstores.chroma import Chroma

from dotenv import load_dotenv, find_dotenv
import os

_ = load_dotenv(find_dotenv())    # read local .env file
zhipuai_api_key = os.environ['ZHIPUAI_API_KEY']

# 定义 Embeddings
embedding = ZhipuAIEmbeddings()

# 向量数据库持久化路径
persist_directory = '../data_base/vector_db/chroma'

# 加载数据库
vectordb = Chroma(
    persist_directory=persist_directory,  # 允许我们将persist_directory目录保存到磁盘上
    embedding_function=embedding
)
print(f"向量库中存储的数量:{vectordb._collection.count()}")

返回结果

向量库中存储的数量:40
question = "什么是prompt engineering?"
docs = vectordb.similarity_search(question,k=3)
print(f"检索到的内容数:{len(docs)}")
for i, doc in enumerate(docs):
    print(f"检索到的第{i}个内容: \n {doc.page_content}", end="\n-----------------------------------------------------\n")

返回结果

检索到的内容数:3
检索到的第0个内容: 
 相反,我们应通过 Prompt 指引语言模型进行深入思考。可以要求其先列出对问题的各种看法,说明推理依据,然后再得出最终结论。在 Prompt 中添加逐步推理的要求,能让语言模型投入更多时间逻辑思维,输出结果也将更可靠准确。

综上所述,给予语言模型充足的推理时间,是 Prompt Engineering 中一个非常重要的设计原则。这将大大提高语言模型处理复杂问题的效果,也是构建高质量 Prompt 的关键之处。开发者应注意给模型留出思考空间,以发挥语言模型的最大潜力

(此处省略)

2.创建一个 LLM

# 需要下载源码
from zhipuai_llm import ZhipuAILLM


from dotenv import find_dotenv, load_dotenv
import os

_ = load_dotenv(find_dotenv())

# 获取环境变量 API_KEY
api_key = os.environ["ZHIPUAI_API_KEY"] #填写控制台中获取的 APIKey 信息
llm = ZhipuAILLM(model="chatglm_std", temperature=0, api_key=api_key)
llm.invoke("请你自我介绍一下自己!")

3.构建检索问答链

from langchain.prompts import PromptTemplate

template = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答
案。最多使用三句话。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问!”。
{context}
问题: {question}
"""

QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],
                                 template=template)

基于模板

from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(llm,
                                       retriever=vectordb.as_retriever(),
                                       return_source_documents=True,
                                       chain_type_kwargs={"prompt":QA_CHAIN_PROMPT})

创建检索 QA 链的方法 RetrievalQA.from_chain_type() 有如下参数:

  • llm:指定使用的 LLM
  • 指定 chain type : RetrievalQA.from_chain_type(chain_type=“map_reduce”),也可以利用load_qa_chain()方法指定chain type。
  • 自定义 prompt :通过在RetrievalQA.from_chain_type()方法中,指定chain_type_kwargs参数,而该参数:chain_type_kwargs = {“prompt”: PROMPT}
  • 返回源文档:通过RetrievalQA.from_chain_type()方法中指定:return_source_documents=True参数;也可以使用RetrievalQAWithSourceChain()方法,返回源文档的引用(坐标或者叫主键、索引)

4.检索问答链效果测试

question_1 = "什么是南瓜书?"
question_2 = "王阳明是谁?"

基于召回结果和 query 结合起来构建的 prompt 效果

result = qa_chain({"query": question_1})
print("大模型+知识库后回答 question_1 的结果:")
print(result["result"])

返回结果

大模型+知识库后回答 question_1 的结果:
 南瓜书是一个在线的书籍共享平台,用户可以在上面分享自己喜欢的书籍,也可以下载其他用户分享的书籍。该平台旨在让用户能够更方便地分享和获取书籍资源。谢谢你的提问!
result = qa_chain({"query": question_2})
print("大模型+知识库后回答 question_2 的结果:")
print(result["result"])

返回结果

大模型+知识库后回答 question_2 的结果:
 王阳明是中国明代著名的哲学家、政治家和军事家。他是心学派别的创立者,提出了“知行合一”的哲学观点,对中国文化产生了深远的影响。

大模型自己回答的效果

prompt_template = """请回答下列问题:
                            {}""".format(question_1)

### 基于大模型的问答
llm.predict(prompt_template)

返回结果

' 南瓜书是一本针对人工智能领域中的数学难题的书籍,由开源组织Datawhale发起,团队成员谢文睿、秦州牵头。南瓜书针对一些难以理解的公式进行解析,对跳跃性较大的公式进行推导,帮助读者解决数学难题。该书的发布受到了广大学习者的好评,并且有幸得到西瓜书作者周志华教授的好评。南瓜书的项目地址在GitHub上,star数已经突破1.1万。'
prompt_template = """请回答下列问题:
                            {}""".format(question_2)

### 基于大模型的问答
llm.predict(prompt_template)

返回结果

' 王阳明,原名王守仁,是明代著名的思想家、哲学家、文学家和军事家。他出生于浙江余姚,曾在朝廷担任兵部尚书等要职,也是心学流派的创立者。王阳明提出了“心即理”的哲学观点,认为人的本性本善,只要克服私欲,就能达到道德的境界。他的思想影响深远,被誉为中国古代哲学的瑰宝之一。'

5.添加历史对话的记忆功能

5.1 记忆(Memory)

使用 ConversationBufferMemory ,它保存聊天消息历史记录的列表,这些历史记录将在回答问题时与问题一起传递给聊天机器人,从而将它们添加到上下文中。

from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(
    memory_key="chat_history",  # 与 prompt 的输入变量保持一致。
    return_messages=True  # 将以消息列表的形式返回聊天记录,而不是单个字符串
)

5.2 对话检索链(ConversationalRetrievalChain)

对话检索链(ConversationalRetrievalChain)在检索 QA 链的基础上,增加了处理对话历史的能力。

它的工作流程是:

  1. 将之前的对话与新问题合并生成一个完整的查询语句。
  2. 在向量数据库中搜索该查询的相关文档。
  3. 获取结果后,存储所有答案到对话记忆区。
  4. 用户可在 UI 中查看完整的对话流程。
from langchain.chains import ConversationalRetrievalChain

retriever=vectordb.as_retriever()

qa = ConversationalRetrievalChain.from_llm(
    llm,
    retriever=retriever,
    memory=memory
)
question = "我可以学习到关于提示工程的知识吗?"
result = qa({"question": question})
print(result['answer'])
 是的,你可以通过吴恩达老师的《Prompt Engineering for Developer》课程学习到关于提示工程的知识。该课程由吴恩达老师与 OpenAI 技术团队成员 Isa Fulford 老师合作授课,内容涵盖了软件开发提示词设计、文本总结、推理、转换、扩展以及构建聊天机器人等语言模型典型应用场景。通过学习该课程,你可以了解到如何提升大语言模型应用效果的各种技巧和最佳实践,从而激发你的想象力,开发出更出色的语言模型应用。
question = "为什么这门课需要教这方面的知识?"
result = qa({"question": question})
print(result['answer'])
 吴恩达老师的《Prompt Engineering for Developer》课程需要教授关于提示工程的知识,因为提示工程是开发人员使用大语言模型(LLM)的关键技能。通过学习提示工程的最佳实践和技巧,开发人员可以更好地利用 LLM 的强大功能,并通过 API 接口快速构建软件应用程序。此外,提示工程对于提高语言模型应用的效果和构建出色的语言模型应用也至关重要。

三. 部署知识库助手

1. Streamlit 简介

Streamlit 是一种快速便捷的方法,可以直接在 *Python 中通过友好的 Web 界面演示机器学习模型*

Streamlit 提供了一组简单而强大的基础模块,用于构建数据应用程序:

  • st.write():这是最基本的模块之一,用于在应用程序中呈现文本、图像、表格等内容。

  • st.title()、st.header()、st.subheader():这些模块用于添加标题、子标题和分组标题,以组织应用程序的布局。

  • st.text()、st.markdown():用于添加文本内容,支持 Markdown 语法。

  • st.image():用于添加图像到应用程序中。

  • st.dataframe():用于呈现 Pandas 数据框。

  • st.table():用于呈现简单的数据表格。

  • st.pyplot()、st.altair_chart()、st.plotly_chart():用于呈现 Matplotlib、Altair 或 Plotly 绘制的图表。

  • st.selectbox()、st.multiselect()、st.slider()、st.text_input():用于添加交互式小部件,允许用户在应用程序中进行选择、输入或滑动操作。

  • st.button()、st.checkbox()、st.radio():用于添加按钮、复选框和单选按钮,以触发特定的操作。

2、构建应用程序

导入必要的 Python 库。

import streamlit as st
# from langchain_openai import ChatOpenAI
from zhipuai_llm import ZhipuAILLM


from dotenv import find_dotenv, load_dotenv
import os

# 读取本地/项目的环境变量。

# find_dotenv()寻找并定位.env文件的路径
# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中
# 如果你设置的是全局的环境变量,这行代码则没有任何作用。
_ = load_dotenv(find_dotenv())

# 获取环境变量 API_KEY
api_key = os.environ["ZHIPUAI_API_KEY"] #填写控制台中获取的 APIKey 信息
# llm = ZhipuAILLM(model="chatglm_std", temperature=0, api_key=api_key)

创建应用程序的标题st.title

st.title('🦜🔗 动手学大模型应用开发')

添加一个文本输入框,供用户输入其 zhipu API 密钥

zhipu_api_key = st.sidebar.text_input('ZhiPu API Key', type='password')

**定义一个函数,使用用户密钥对 zhipu API 进行身份验证、发送提示并获取 AI 生成的响应。**该函数接受用户的提示作为参数,并使用st.info来在蓝色框中显示 AI 生成的响应

def generate_response(input_text):
    llm = ZhipuAILLM(temperature=0.7, zhipu_api_key=zhipu_api_key)
    st.info(llm(input_text))

**使用st.form()创建一个文本框(st.text_area())供用户输入。**当用户单击Submit时,generate-response()将使用用户的输入作为参数来调用该函数

with st.form('my_form'):
    text = st.text_area('Enter text:', 'What are the three key pieces of advice for learning how to code?')
    submitted = st.form_submit_button('Submit')
    if not openai_api_key.startswith('sk-'):
        st.warning('Please enter your Zhipu API key!', icon='⚠')
    if submitted and openai_api_key.startswith('sk-'):
        generate_response(text)

保存当前的文件streamlit_app.py

返回计算机的终端以运行该应用程序

streamlit run streamlit_app.py

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1866273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文阅读】-- Temporal Summary Images:通过交互式注释生成和放置实现叙事可视化的方法

Temporal Summary Images: An Approach to Narrative Visualization via Interactive Annotation Generation and Placement 摘要1 引言2 背景及相关工作2.1 叙事可视化和讲故事2.2 显示面向时间的数据2.3 小倍数和漫画2.4 注释可视化 3 设计要求和工作流程3.1 工作流程3.2 TSI…

input()函数——输入

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 input()函数可以提示并接收用户的输入,将所有的输入按照字符串进行处理,并返回一个字符串,input()函数的…

C3P0数据库连接池

目录 一:连接池介绍 1.1连接池解决的问题 2.常用的数据库连接池 二:c3p0介绍 2.1C3P0介绍: 2.2C3P0快速入门 1.常用参数说明 2.API介绍 3.使用步骤 1.导入jar包c3p0-0.9.1.2.jar 2.编写c3p0-config.xml配置文件,配置对…

统信UOS上鼠标右键菜单中添加自定义内容

原文链接:统信UOS上鼠标右键菜单中添加自定义内容 Hello,大家好啊!今天给大家带来一篇关于在统信UOS桌面操作系统上鼠标右键菜单中添加自定义内容的文章。通过自定义鼠标右键菜单,可以大大提升日常操作的效率和便捷性。本文将详细…

KVM网络模式设置

一、KVM网络模式介绍 1、NAT ( 默认上网 ) 虚拟机利用host机器的ip进行上网,对外显示一个ip;virbr0是KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供NAT访问外网的功能,默认ip为192.168.122.1 2、自带的Bridge 将虚拟机桥接到host机器的网卡上,vm和ho…

SOA和ESB介绍

SOA(面向服务的架构) 面向服务的架构(Service-Oriented Architecture,SOA)是一种设计理念,用于构建松耦合的、可互操作的、模块化的服务。在SOA架构中,应用程序被划分为一系列的服务&#xff0c…

202485读书笔记|《我还有一片风景要完成》——溪水急着要流向海洋 浪潮却渴望重回土地 弱水长流,我只能尽一瓢饮,世界大千,我只能作一瞬观

202485读书笔记|《我还有一片风景要完成》——溪水急着要流向海洋 浪潮却渴望重回土地 弱水长流,我只能尽一瓢饮,世界大千,我只能作一瞬观 《华语散文温柔的一支笔:张晓风作品集(共5册)》张晓风&#xff0c…

分享一个微信管理工具

聚合管理多个微信号 1、聚合聊天 支持多微信账号消息,在统一端口接收回复 2、话题素材库 可提前把话题准备好用到的时候一键发送 3、朋友圈互动 支持在聊天窗口直接看到当前客户朋友圈实时点赞评论互动 批量多号添加好友 1、批量添加联系人,导入联系…

C#基于SkiaSharp实现印章管理(2)

上一篇文章最后提到基于System.Text.Json能够序列化SKColor对象,但是反序列化时却无法解析本地json数据。换成Newtonsoft.Json进行序列化和反序列化也是类似的问题。   通过百度及查看微软的帮助文档,上述情况下需自定义转换类以处理SKColor类型数据的…

java的字节符输出流基类、File Writer类和Buffered Writer类

一、字节符输出流基类:Writer 1.属于抽象类 2.常用方法 二、字节符输出流Flie Writer类 1.是writer类的子类 2.以字符为数据处理单元向文本文件中写数据 3.示例 4.实现步骤 三、BufferedWriter类 1.是Writer类的子类。 2.带有缓冲区 默认情况下&#xff0c…

游戏AI的创造思路-技术基础-深度学习(6)

让人工智障具备信念吧,依莫拉萨~~~串频道暴露年龄。。。不过深度信念和信念真的没啥关系,不知道为啥这样起名 目录 3.6. 深度信念网络(DBN) 3.6.1. 定义 3.6.2. 发展历史 3.6.3. 算法公式 3.6.4. 运行原理 3.6.4.1. 基本原理 3.6.4.2. Python实现…

Spring统一功能

文章目录 一、什么是统一功能二、拦截器2.1 什么是拦截器2.2 拦截器的使用2.3 案例:不拦截前端的请求2.4 拦截器是如何实现的 ---- >分析DispatcherServlet源码分析 三、适配器模式四、统一数据返回格式五、统一异常六、案例:在图书管理系统使用统一功…

重大进展!微信支付收款码全场景接入银联网络

据中国银联6月19日消息,近日,银联网络迎来微信支付收款码场景的全面接入,推动条码支付互联互通取得新进展,为境内外广大消费者提供更多支付选择、更好支付体验。 2024年6月,伴随微信支付经营收款码的开放,微…

【low-ui-vue】实现原生可扩展动态表格组件

本文字数:3520字 预计阅读时间:20分钟 所谓动态列的表格,就是列数不固定。像广为使用的elementUI的table组件就是表头写死的,这种也叫列数固定的表格。 01 效果 当然,动态性增加了,当然要做出一定“牺牲”。…

sys.stdin对象——实现标准输入

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 sys.stdin是一个标准化输入对象,可以连续输入或读入文件所有内容,不结束,不能直接使用。输入完成后&am…

Epic商店登录时一直转圈圈怎么回事?Epic登录转圈圈解决办法

很多游戏玩家都喜欢在Epic商店上面免费领取游戏,但是经常在登陆领取的过程中,遇到Epic账号登陆不上的问题,登陆界面一直转圈圈,下面分享一下具体解决办法,帮助大家顺利流畅登陆,轻松喜加一。 如果遇到Epic商…

常用组件详解(一):nn.Conv2d、nn.functional.conv2d()

文章目录 一、torch.nn.Conv2d基本介绍1.1构造方法1.2参数、偏置、属性1.2.1参数与偏置1.2.2可查看属性 1.3torch.nn.functional.conv2d1.4dilation 二、卷积操作2.1in_channels1, out_channels1, kernel_size3, stride1, padding02.2in_channels1, out_channels1, kernel_size…

Nuxt3 实战 (十二):SEO 搜索引擎优化指南

添加 favicon 图标和 TDK(标题、描述、关键词) nuxt.config.ts 添加配置: export default defineNuxtConfig({app: {title:Dream Site,meta: [{ name: keywords, content: Nuxt.js,导航,网站 },{ name: description, content: 致力于打造程…

详细解析MATLAB和Simulink中的文件格式:mat, mdl, mexw32, 和 m 文件

matlab 探索MATLAB和Simulink中的文件格式:MAT, MDL, MEXW32, 和 M 文件**MAT 文件 (.mat)****MDL 文件 (.mdl)****MEX 文件 (.mexw32/.mexw64)****M 文件 (.m)****总结** 探索MATLAB和Simulink中的文件格式:MAT, MDL, MEXW32, 和 M 文件 当你开始使用M…

JS(JavaScript)入门指南(DOM、事件处理、BOM、数据校验)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 玉阶生白露,夜久侵罗袜。 却下水晶帘,玲珑望秋月。 ——《玉阶怨》 文章目录 一、DOM操作1. D…