基于langchain+千帆sdk的一个基于文档的QA问答Demo

 

微信公众号:淼学派对
CSDN:淼学派对
哔哩哔哩:淼学派对
各大博客社区:淼学派对

背景说明

百度智能云千帆大模型平台官方SDK正式对外发布:https://pypi.org/project/qianfan/。同步支持langchain接入千帆api。
本文重点介绍基于langchain+千帆sdk的一个基于文档的QA问答Demo。

图片

Demo物料

可以直接下载Demo,只需修改step0的ak和sk,即可顺利跑完整个demo。
https://bce-doc-on.bj.bcebos.com/qianfanshequ/qianfan-langchain-QA-demo.zip

图片

版本依赖说明

  • lanchain >= 0.0.292

  • qianfan >= 0.0.3

  • python >= 3.7

QA问答Demo

用例

此处展示了如何使用 Langchian + 千帆 SDK 完成对特定文档完成获取、切分、转为向量并存储,而后根据你的提问来从文中获取答案。
并且借助 Langsmith 将整个过程可视化展现。

概览

把一个非结构化的文档转成问答链涉及以下步骤:

  • Loading: 首先我们需要加载数据,非结构化的数据可以从多种渠道加载。LangChain integration hub 查看所有 Langchain 支持的 Loader。
    每个 Loader 都会返回 Langchian 中的 Document 对象。

  • Splitting: 文本切分器 把 Documents 切分成特定的大小。

  • Storage: Storage (例如 vectorstore)会将切分的数据储存起来,通常还附带对文本做 embedding 。

  • Retrieval: 用于从 Storage 中获取切分的数据,用于后面生成答案。

  • Generation: 使用提示词和获取到的数据,搭配 LLM 来生成回答。

  • Conversation (扩展): 添加 Memory 模块来在你的问答链上实现多轮对话。

图片

接下来我们会演示如何一步步构造我们自己的流水线,并且实现我们自己定制化的功能

Step 0. Prepare

为了能够运行我们的 Demo,首先我们需要下载依赖并且设置环境变量

!pip list | grep langchain
!pip list | grep qianfan
!pip install langchain !pip install qianfan

实例代码:

import os
os.environ['QIANFAN_AK'] = "your_api_key"
os.environ['QIANFAN_SK'] = "your_secret_key"
# 此处为 Langsmith 相关功能开关。当且仅当你知道这是做什么用时,可删除注释并设置变量以使用 Langsmith 相关功能
# os.environ['LANGCHAIN_TRACING_V2'] = "true"
# os.environ['LANGCHAIN_ENDPOINT'] = "https://api.smith.langchain.com"
# os.environ['LANGCHAIN_API_KEY'] = "your_langchian_api_key"
# os.environ['LANGCHAIN_PROJECT'] = "your_project_name"
is_chinese = True
if is_chinese:
    WEB_URL = "https://zhuanlan.zhihu.com/p/85289282"
    CUSTOM_PROMPT_TEMPLATE = """
        使用下面的语料来回答本模板最末尾的问题。如果你不知道问题的答案,直接回答 "我不知道",禁止随意编造答案。
        为了保证答案尽可能简洁,你的回答必须不超过三句话。
        请注意!在每次回答结束之后,你都必须接上 "感谢你的提问" 作为结束语
        以下是一对问题和答案的样例:
            请问:秦始皇的原名是什么
            秦始皇原名嬴政。感谢你的提问。
        以下是语料:
        {context}
        请问:{question}
    """
    QUESTION1 = "明朝的开国皇帝是谁"
    QUESTION2 = "朱元璋是什么时候建立的明朝"
else:
    WEB_URL = "https://lilianweng.github.io/posts/2023-06-23-agent/"
    CUSTOM_PROMPT_TEMPLATE = """
        Use the following pieces of context to answer the question at the end. 
        If you don't know the answer, just say that you don't know, don't try to make up an answer. 
        Use three sentences maximum and keep the answer as concise as possible. 
        Always say "thanks for asking!" at the end of the answer. 
        {context}
        Question: {question}
        Helpful Answer:
    """
    QUESTION1 = "How do agents use Task decomposition?"
    QUESTION2 = "What are the various ways to implemet memory to support it?"

Step 1. Load

指定一个 DocumentLoader 来把你指定的非结构化数据加载成 Documents。一个 Document 是文字(即 page_content)和与之相关的元数据的结合体

from langchain.document_loaders import WebBaseLoader
loader = WebBaseLoader(WEB_URL)
data = loader.load()

Step 2. Split

接下来把 Document 切分成块,为后续的 embedding 和存入向量数据库做准备。

from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size = 384, chunk_overlap = 0, separators=["\n\n", "\n", " ", "", "。", ","])
all_splits = text_splitter.split_documents(data)

Step 3. Store

为了能够查询文档的片段,我们首先需要把它们存储起来,一种比较常见的做法是对文档的内容做 embedding,然后再将 embedding 的向量连同文档一起存入向量数据库中,此处 embedding 用于索引文档。

from langchain.embeddings import QianfanEmbeddingsEndpoint
from langchain.vectorstores import Chroma
vectorstore = Chroma.from_documents(documents=all_splits, embedding=QianfanEmbeddingsEndpoint())

除了非结构化的文档以外,Langchain 还可以从多种数据源获取数据并将它们存储起来。

Step 4. Retrieve

我们可以使用 相似度搜索 来从切分的文档内获取数据,获取到的数据会作为最终提交给 LLM 的 prompt 的一部分。

# 基于prompt问题查找相似文档
print("prompt问题:"+QUESTION1)
docs = vectorstore.similarity_search_with_relevance_scores(QUESTION1)
[(document.page_content, score) for document, score in docs]

Step 5. Generate

接下来我们就可以使用我们的大模型(例如文心一言)和 Langchain 的 RetrievalQA 链,来针对这篇文档进行提问并获取我们想要的回答了。

from langchain.chains import RetrievalQA
from langchain.chat_models import QianfanChatEndpoint
from langchain.prompts import PromptTemplate

QA_CHAIN_PROMPT = PromptTemplate.from_template(CUSTOM_PROMPT_TEMPLATE)

llm = QianfanChatEndpoint(streaming=True)
retriever=vectorstore.as_retriever(search_type="similarity_score_threshold", search_kwargs={'score_threshold': 0.0})

qa_chain = RetrievalQA.from_chain_type(llm, retriever=retriever, chain_type_kwargs={"prompt": QA_CHAIN_PROMPT})
qa_chain({"query": QUESTION1})

注意,此处不光可以传入 ChatModel ,也可以传入一个 LLM 对象到 RetrievalQA 中。并且通过代码我们可以看到,用户可以通过传入额外的命名参数字典来自定义我们所需使用的 prompt 模板

Step 5.1 返回源文档

用于 QA 的知识文档也可以通过指定 return_source_documents=True 被包含在返回的字典里

from langchain.chains import RetrievalQA

qa_chain = RetrievalQA.from_chain_type(llm, retriever=retriever, chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}, return_source_documents=True)
result = qa_chain({"query": QUESTION1})
len(result['source_documents'])
result['source_documents']

Step 6. Chat

我们还可以加入 Memory 模块并替换使用 ConversationalRetrievalChain 来实现记忆化的对话式查询。

from langchain.memory import ConversationSummaryMemory
from langchain.chains import ConversationalRetrievalChain

memory = ConversationSummaryMemory(llm=llm,memory_key="chat_history",return_messages=True)
qa = ConversationalRetrievalChain.from_llm(llm, retriever=retriever, memory=memory, combine_docs_chain_kwargs={"prompt": QA_CHAIN_PROMPT})
qa(QUESTION1)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM的相关知识

目录 JVM内存划分 类加载过程 类加载中的“双亲委派模型” JVM内存划分 JVM也就是java进程。这个进程一旦跑起来之后,就会从操作系统里,申请一大块内存空间。JVM接下来就要进一步的对这个大的空间进行划分。划分成不同区域,从而每个区域都…

Linux服务器安装与配置python环境 最新linux安装python 小白教程

目录 一、下载官网的安装包 二、安装流程 三、配置软连接(类似window系统的环境变量) 四、可能会出现的问题: 1.ssl连接问题,下图所示: 一、下载官网的安装包 1.官网安装包地址:https://www.python.org/…

安装node 、vscode

先安装node,再安装vscode! 目录 一、Node 1. 进入node 官网,选择版本,点击下载(4步完成下载)。 2. winR ,输入cmd 进入控制端,如下图 3. 输入node -v ,查看是否安装完成,若安装…

使用小猪APP分发打造高效的App封装工具

你是否曾经因为App封装和分发的复杂性而头疼不已?在这个移动应用迅速发展的时代,开发人员不仅需要专注于应用的功能和用户体验,还必须面对繁琐的封装和分发过程。幸运的是,小猪APP分发www.appzhu.cn正好为我们提供了一个简便而高效…

Leetcode3165. 不包含相邻元素的子序列的最大和(Go中的线段树分治包含多类数据使用maintain进行维护)

题目截图 题目分析 不能取相邻的,就是打家劫舍 然后更改某一个值就是单点更新 更新后,需要更新区间的值 需要注意的是,使用分治时需要考虑到一头一尾的问题,所以有4种情况(选or不选在两个位置) 这四种情况…

大数据——Spark

1.Spark MLlib概述 MLlib是Spark的机器学习(Machine Learning)库,旨在简化机器学习的工程实践工作,并方便扩展到更大规模。 MLlib由一些通用的学习算法和工具组成,包括分类、回归、聚类、协同过滤、降维等&#xff0…

如果不花钱,又担心钱存着贬值,怎么办?如果把大部分钱投入到赚钱的事上,特别是自己专业上,比如说我是十年的程序员,帮我分析投资?

如果你不想花钱,但又担心钱存着会贬值,有几个策略可以帮助你在不花费大量金钱的情况下保护你的资金价值: 高收益储蓄账户或货币市场账户: 选择一个高收益的储蓄账户或货币市场账户,这些账户通常比传统储蓄账户提供更高…

爬虫案例-亚马逊反爬分析-验证码突破(x-amz-captcha)

总体概览:核心主要是需要突破该网站的验证码,成功后会返回我们需要的参数后再去请求一个中间页(类似在后台注册一个session),最后需要注意一下 IP 是不能随意切换的 主要难点: 1、梳理整体反爬流程 2、验证…

手把手教你如何在 Sider (ChatGPT Sidebar) 中免费使用阿里云通义千问

最近国产大模型正在疯狂降价,推出了众多的免费策略,是时候该“白嫖”一手了。用过 Sider 的小伙伴应该很少有说不“妙”啊,用户体验也做得很棒。奈何它要开通使用全部的功能价格有可能不太能承受,且有些功能不一定用得上。但是免费…

Java+Spring+ IDEA+MySQL云HIS系统源码 云HIS适合哪些地区的医院?

JavaSpring IDEAMySQL云HIS系统源码云HIS适合哪些地区的医院? 云HIS适合哪些地区的医院? 云HIS(云医院信息系统)适合多种地区的医院,特别是那些希望实现医疗服务的标准化、信息化和规范化,同时降低IT运营成…

Clion远程调试

本文详细介绍了如何使用CLion进行远程调试,旨在帮助开发者解决在远程开发环境中进行代码调试的难题。文章首先概述了远程调试的概念和重要性,强调了其在提高开发效率和代码质量方面的作用。接着,详细阐述了在CLion中配置远程调试环境的步骤&a…

【html+css(大作业)】二级菜单导航栏

目录 实现效果 代码及其解释 html部分 CSS部分 hello&#xff0c;hello好久不见&#xff01; 今天我们来写二级导航栏&#xff0c;所谓二级导航栏&#xff0c;简单来说就是鼠标放上去就有菜单拉出&#xff1a; 实现效果 代码及其解释 html部分 <!DOCTYPE html> &l…

气膜建筑的运行保障:应对停电的解决方案—轻空间

气膜建筑作为一种现代化的建筑形式&#xff0c;以其独特的结构和多样的应用赢得了广泛关注。这种建筑依靠风机不断往内部吹气来维持其结构形态&#xff0c;那么如果遇到停电的情况&#xff0c;该如何确保其正常运行呢&#xff1f; 气膜建筑的供风系统 气膜建筑内部的气压维持依…

UI自动化测试最佳设计模式POM

当使用Selenium进行UI自动化测试时&#xff0c;Page Object Model&#xff08;POM&#xff09;是一种最佳实践的设计模式。POM的核心思想是通过将页面封装成对象&#xff0c;使得测试代码更加清晰、可维护和可重用。 POM的主要组成部分包括页面对象类、元素定位方式和操作方法…

【CCF-CSP】 202309-3 梯度求解

思路&#xff1a; 将表达式整理成只有目标求导变量的无括号加法表达式&#xff0c;其他变量均代入其值&#xff0c;然后利用最简单的求导公式&#xff0c;求出最终值。 样例1 x1 x1 x1 * x2 *转换成 x1*x1*x1x1*x2 若求导x1&#xff0c;则只留下x1&#xff0c;变为 x1*x1*x1…

6公里远距离视频传输,飞睿智能无线CV5200模组方案,设备稳定连接通信

随着科技的不断进步&#xff0c;物联网&#xff08;IoT&#xff09;和智能设备正逐渐渗透到我们生活的方方面面。在这一进程中&#xff0c;远距离无线通信成为推动行业发展的关键因素。 智能控制、远程无线传输是实现设备间的协作场景的关键&#xff0c;CV5200模组通过无线WiF…

大白话70个你必须知道的AI重要概念

本文按英文起首字母顺序&#xff0c;整理了70个常用的生成式AI领域常用概念&#xff0c;试图以大白话进行诠释&#xff0c;如果你不求甚解、但也求略解的话&#xff0c;欢迎收藏。第一部分从A到I&#xff0c;第二部分从L到P&#xff0c;第三部分从Q到Z。 A 1 Agents: 代理人。…

民国漫画杂志《时代漫画》第31期.PDF

时代漫画31.PDF: https://url03.ctfile.com/f/1779803-1248635507-e54e55?p (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

笔记-python-map的用法

map()函数 map()是 Python 内置的高阶函数&#xff0c;它接收一个函数 f 和一个 list&#xff0c;并通过把函数 f 依次作用在 list 的每个元素上&#xff0c;得到一个新的 list 并返回。 1、当seq只有一个时&#xff0c;将函数func作用于这个seq的每个元素上&#xff0c;并得到…

【御控工业物联网】 Java JSON结构转换、JSON结构重构、JSON结构互换(17):数组To对象——键值互换属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、核心构件之转换映射三、案例之《JSON数组 To JSON对象》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换…