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

如何在LangChain中结合对话记忆与文档上下文加载?

解决方案:结合LangChain对话记忆与文档上下文加载

你遇到的问题核心是ConversationChain仅支持单一输入参数,无法同时处理文档检索结果和对话历史。正确的做法是使用ConversationalRetrievalChain——LangChain专门为「带对话记忆的文档检索问答」场景设计的链结构,它能自动整合文档检索、对话记忆和LLM推理逻辑。

修改后的完整代码

import pickle
from langchain.chat_models import OpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferWindowMemory
from langchain.callbacks import get_openai_callback

# 加载预存的文档检索对象
with open('/content/gdrive/My Drive/ai-data/docsearch.pkl', 'rb') as f:
    docsearch = pickle.load(f)

# 配置LLM参数
model_kwargs = {
    "model": "text-davinci-003", 
    "temperature": 0.7, 
    "max_tokens": -1, 
    "top_p": 1, 
    "frequency_penalty": 0, 
    "presence_penalty": 0.5, 
    "n": 1, 
    "best_of": 1
}
llm = OpenAI(model_kwargs=model_kwargs)

# 定义统计token的函数
def count_tokens(chain, query):
    with get_openai_callback() as cb:
        # ConversationalRetrievalChain会自动处理文档检索和对话记忆,直接传入query即可
        result = chain.run(query)
        print(f'总共消耗 {cb.total_tokens} 个token')
        return result

# 创建带对话记忆的检索问答链
conversation_chain = ConversationalRetrievalChain.from_llm(
    llm=llm,
    # 将docsearch转换为检索器供链使用
    retriever=docsearch.as_retriever(),
    # 保留你原来的对话记忆配置
    memory=ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True)
)

# 测试调用
count_tokens(
    conversation_chain, 
    "Good morning AI!"
)

关键修改说明

  1. 替换链类型:用ConversationalRetrievalChain替代ConversationChain,这个链原生支持文档检索与对话记忆的结合。
  2. 传入检索器:通过docsearch.as_retriever()将你的向量搜索对象转换为LangChain标准检索器,链会自动根据用户query检索相关文档。
  3. 简化调用逻辑:无需手动调用similarity_search和传入input_documents,链内部会完成「检索文档→结合对话历史→生成回答」的全流程,直接调用chain.run(query)即可。
  4. 记忆参数适配:添加memory_key="chat_history", return_messages=True是为了匹配ConversationalRetrievalChain默认的记忆键名,确保对话历史能被正确读取和使用。

额外提示

如果需要自定义回答的提示模板,可以在创建链时传入combine_docs_chain_kwargs参数,比如:

from langchain.prompts import PromptTemplate

custom_prompt = PromptTemplate(
    template="根据以下文档内容和对话历史回答问题:\n文档:{context}\n对话历史:{chat_history}\n问题:{question}\n回答:",
    input_variables=["context", "chat_history", "question"]
)

conversation_chain = ConversationalRetrievalChain.from_llm(
    llm=llm,
    retriever=docsearch.as_retriever(),
    memory=ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True),
    combine_docs_chain_kwargs={"prompt": custom_prompt}
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:23:20