目录
概述
相比于单轮对话,多轮对话要考虑历史对话记录,大模型需要根据对话上下文去回答用户的问题。在RAG的场景中,通常需要通过问题去召回和问题相关的知识,再将知识和问题交给大模型去润色回复用户。但是有没有想过,如果这个问题指代了历史消息的某个重要对象(通常是问题的核心)时,就不能召回有用的知识,大模型的回答效果不会太好。解决办法是,让大模型基于历史消息对用户最新的问题进行改写,补充指代对象,然后再去进行知识的召回,效果会大大改善。以下将以豆瓣电影《白蛇:浮生》作为大模型的知识补充来进行多轮对话。
整体架构
- history_aware_retriever将用户的当前输入和历史消息通过大模型来进行改写,从而去进行文档的召回
- question_answer_chain会基于召回的文档、历史消息、当前输入给到大模型进行润色输出
- embedding的部分采用BCE模型,embedding+ranking可以达到SOTA水平,本案例只有embedding,后续可以考虑将召回再过一层ranking
- 向量库采用的是qdrant,在一些数据集和指标上也可以达到SOTA水平,本地部署可以采用内存、持久化到磁盘和docker模式,氪金的话就可以上它的cloud
- 模型采用的是Qwen/Qwen2-7B-Instruct,采用vllm部署openai接口形式提供服务
代码实现
from typing import List
from langchain_openai.chat_models import ChatOpenAI
from langchain.chains.history_aware_retriever import create_history_aware_retriever
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance
from langchain_qdrant import QdrantVectorStore
from langchain.prompts.chat import ChatPromptTemplate
from langchain.prompts import MessagesPlaceholder
from langchain_core.documents import Document
from langchain_huggingface.embeddings import HuggingFaceEmbeddings
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.document_transformers import Html2TextTransformer
from langchain.text_splitter import Recursive