You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Langchain构建带对话历史与引用的RAG整合问题求助

整合Langchain对话历史与引用提取的RAG实现方案

核心思路

要同时实现对话历史记忆和引用提取,关键是让对话历史参与检索与生成环节,同时通过bind_tools让模型自动从检索文档中提取引用信息。以下是具体实现步骤:

1. 导入依赖库

from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

2. 定义引用提取工具

用@tool装饰器定义工具,让模型可以调用它从检索到的文档中提取来源和关键内容:

@tool
def extract_references(documents: list) -> list:
    """从检索文档中提取引用信息,返回包含来源、关键内容的列表"""
    references = []
    for doc in documents:
        references.append({
            "source": doc.metadata.get("source", "未知来源"),
            "key_content": doc.page_content[:120] + "..."  # 截取核心内容便于展示
        })
    return references

3. 构建带对话历史的检索生成链

  • 先给LLM绑定引用提取工具,让模型具备调用工具的能力
  • 构建包含对话历史占位符的Prompt,确保历史对话能传入生成环节
  • 组合检索链与对话历史组件:
# 初始化LLM并绑定工具
llm = ChatOpenAI(model="gpt-3.5-turbo")
llm_with_tools = llm.bind_tools([extract_references])

# 定义带对话历史的Prompt
prompt = ChatPromptTemplate.from_messages([
    ("system", "结合对话历史和检索到的文档回答问题,必须调用工具提取引用信息并附在回答末尾。"),
    MessagesPlaceholder(variable_name="chat_history"),
    ("user", "{input}"),
    ("system", "检索文档:{context}")
])

# 创建文档处理链
document_chain = create_stuff_documents_chain(llm_with_tools, prompt)

# 替换为你已实现的检索器(比如向量数据库检索器)
# retriever = your_vector_store.as_retriever()

# 创建基础检索链
retrieval_chain = create_retrieval_chain(retriever, document_chain)

# 绑定对话历史管理
session_store = {}
def get_session_history(session_id: str) -> InMemoryChatMessageHistory:
    if session_id not in session_store:
        session_store[session_id] = InMemoryChatMessageHistory()
    return session_store[session_id]

# 最终整合对话历史的RAG链
final_chain = RunnableWithMessageHistory(
    retrieval_chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="chat_history",
    output_messages_key="answer"
)

4. 调用示例

# 第一次提问(初始化对话)
first_response = final_chain.invoke(
    {"input": "RAG的核心优势是什么?"},
    config={"configurable": {"session_id": "user_001"}}
)
print("回答内容:", first_response["answer"])
print("提取的引用:", first_response["tool_calls"])

# 第二次提问(自动携带对话历史)
second_response = final_chain.invoke(
    {"input": "那它在长文本处理上比传统LLM好在哪里?"},
    config={"configurable": {"session_id": "user_001"}}
)
print("回答内容:", second_response["answer"])
print("提取的引用:", second_response["tool_calls"])

关键注意事项

  • 确保Prompt中的MessagesPlaceholder变量名与RunnableWithMessageHistory中的history_messages_key一致
  • 检索器返回的文档必须包含metadata字段(如来源、页码),否则引用提取工具无法获取有效来源信息
  • 如果需要将引用直接嵌入回答正文,可以修改Prompt指令,让模型把提取的引用自然整合到回答中

内容的提问来源于stack exchange,提问作者PiluSus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:10:20