当前位置:   article > 正文

chainlit系列03-- chainlit+langchain 实现基于文档的智能知识问答

chainlit

chainlit+langchain 实现智能知识问答

1. 业务场景

我们将结构化和非结构化数据,经过一定处理后放到向量数据库中,作为我们的语意检索源,检索与用户问题相似度较高的向量片段作为数据源,输入给llm,让LLM(大模型)理解给出的数据源内容,并从中组织答案。
在这里插入图片描述

2. 简要处理步骤

  1. 加载文档
  2. 将文档分片
  3. embedding 分片内容并存储
  4. 检索问题,将问题转成向量,找到相似度较高的几个片段
  5. 将片段组装成prompt的的内容,提交给LLM
  6. LLM理解内容并组织语言输出问题答案
    在这里插入图片描述

结下来,我们就去实现这个功能。

3 . 环境依赖

  • chainlit 快速生成对话UI
  • langchain 模型开发框架,目前最流行的大模型应用开发框架
  • openai openAI模型库
  • chromdb 向量数据库
  • python 3.9
pip install openai chromedb chainlit
pip install 'langchain[all]'
  • 1
  • 2

4. 加载文档

4.1 准备检索内容

因为内容较多embedding会比较费账号,所以我就百度搜了个特斯拉的简介
在这里插入图片描述
将百科内容放到tesla文件中,内容如下:
在这里插入图片描述

# 将你准备好的文本放到当前文件目录下的doc目录下,我的文档名字叫tesla
from langchain.document_loaders import TextLoader
loader = TextLoader("doc/tesla")
data = loader.load()
  • 1
  • 2
  • 3
  • 4

文件文档化之后的结构为:
在这里插入图片描述

4.2 将文档进行分块

from langchain.text_splitter import RecursiveCharacterTextSplitter
# chunk_size 分块大小 chunk_overlap 分块重叠量
text_splitter = RecursiveCharacterTextSplitter(chunk_size = 30, chunk_overlap = 0)
all_splits = text_splitter.split_documents(data)

  • 1
  • 2
  • 3
  • 4
  • 5

文档分块后的数据为:
在这里插入图片描述

4.3 分块embedding存储,也就是让openai帮我转成向量

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
import os

# 如果没有的话,可以联系我帮你搞一个
os.environ["OPENAI_API_KEY"] = "你的openapikey"

vectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.4 初始化LLM并运行

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

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:"""
QA_CHAIN_PROMPT = PromptTemplate.from_template(template)

llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
    llm,
    retriever=vectorstore.as_retriever(),
    chain_type_kwargs={"prompt": QA_CHAIN_PROMPT},
    chain_type="stuff"
)
result = qa_chain({"query": question})
result["result"]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

运行结果:
在这里插入图片描述
至此 langchain 实现文本检索和调用大模型的过程全部完成了,现在我们将上述代码和chainlit集成起来,实现一个有界面的对话。

from langchain import PromptTemplate, OpenAI, LLMChain
import chainlit as cl
from langchain.document_loaders import WebBaseLoader

from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import RecursiveCharacterTextSplitter
import os

os.environ["OPENAI_API_KEY"] = "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"


from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI

#加载文档
loader = TextLoader("doc/tesla")
data = loader.load()
#文档分块
text_splitter = RecursiveCharacterTextSplitter(chunk_size = 30, chunk_overlap = 0)
all_splits = text_splitter.split_documents(data)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

文本块embedding之后存储到向量数据库

vectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())
  • 1

创建对话提案

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 "谢谢提问!" at the end of the answer. 
{context}
Question: {question}
Helpful Answer:"""

@cl.on_chat_start
def main():
  # 构建模型链实例
  QA_CHAIN_PROMPT = PromptTemplate.from_template(template)
  llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
  # 初始化调用链
  qa_chain = RetrievalQA.from_chain_type(
    llm,
    retriever=vectorstore.as_retriever(),
    chain_type_kwargs={"prompt": QA_CHAIN_PROMPT},
    chain_type="stuff"
  )
  # 保存模型链实例到用户session
  cl.user_session.set("llm_chain", qa_chain)

@cl.on_message
async def main(message: str):
   # 最新的版本这个地message的类型变成了cl.Message
   # 用户输入内容需要从message.content 内获取
  message_str = ''
  # 处理用户业务逻辑
  if isinstance(message,str):
    message_str = message
    print('ok')
  if isinstance(message,cl.Message):
    message_str = message.content
    print(f'receive: {message.content}')
    
  # 如果是最新的版本,
  # 从用户会话中获取模型链实例
  qa_chain = cl.user_session.get("llm_chain")
  # 异步调用模型链
  result = qa_chain({"query": message_str})
  
  # 在这里可以做任何处理
  print(f'ask:{message_str}, answer:{result["result"]}')


  # "res" is a Dict. For this chain, we get the response by reading the "text" key.
  # This varies from chain to chain, you should check which key to read.
  await cl.Message(content=result["result"]).send()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

文件目录结构如下:
在这里插入图片描述
运行起来:

chainlit run langchain_chat.py -w

  • 1
  • 2

启动完成:
在这里插入图片描述
访问: http://localhost:8000
在这里插入图片描述

在这里插入图片描述

好啦,本篇到此就全部完成了,要是大家在做的过程中遇到什么问题可以加我微信(leeahuamsg), 备注AIGC,一起探讨哈,接下来我会继续用langchain实现一个智能聊天机器人。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/771269
推荐阅读
相关标签
  

闽ICP备14008679号