前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于langchain+千帆sdk的一个基于文档的QA问答Demo

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

作者头像
淼学派对
发布2024-05-30 12:55:01
1580
发布2024-05-30 12:55:01
举报
文章被收录于专栏:云开发小程序1云开发小程序1

背景说明

百度智能云千帆大模型平台官方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,首先我们需要下载依赖并且设置环境变量

代码语言:javascript
复制
!pip list | grep langchain
!pip list | grep qianfan
!pip install langchain !pip install qianfan

实例代码:

代码语言:javascript
复制
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)和与之相关的元数据的结合体

代码语言:javascript
复制
from langchain.document_loaders import WebBaseLoader
loader = WebBaseLoader(WEB_URL)
data = loader.load()

Step 2. Split

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

代码语言:javascript
复制
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 用于索引文档。

代码语言:javascript
复制
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 的一部分。

代码语言:javascript
复制
# 基于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 链,来针对这篇文档进行提问并获取我们想要的回答了。

代码语言:javascript
复制
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 被包含在返回的字典里

代码语言:javascript
复制
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 来实现记忆化的对话式查询。

代码语言:javascript
复制
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)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Demo物料
  • 版本依赖说明
  • QA问答Demo
    • 用例
      • 概览
        • Step 0. Prepare
          • Step 1. Load
            • Step 2. Split
              • Step 3. Store
                • Step 5. Generate
                  • Step 5.1 返回源文档
                    • Step 6. Chat
                    相关产品与服务
                    对象存储
                    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档