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

基于LangChain+OpenAI+ChromaDB构建记忆式RAG多会话系统求助

问题解答:构建带记忆的多用户多会话RAG系统

1. 构建带向量检索的记忆式RAG核心步骤

  • 向量知识库搭建:将业务文档转换为向量存入ChromaDB,生成检索器(Retriever),用于查询时召回相关文档。
  • 会话记忆管理:为每个用户的每个会话维护独立的聊天历史,确保上下文连贯性。
  • 多模块融合:将用户当前查询、会话历史、检索到的知识库文档整合后输入大模型,生成基于上下文和知识库的精准回答。

2. 用Runnable Chain结合OpenAI与ChromaDB实现系统

核心实现与错误修正

步骤1:初始化向量数据库与检索器

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

# 加载持久化的ChromaDB
persist_directory = "./chroma_db"
embedding = OpenAIEmbeddings()
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embedding)
retriever = vectordb.as_retriever(k=4)  # 召回4条相关文档

步骤2:设计包含记忆与检索内容的Prompt

Prompt需同时承载知识库上下文、会话历史和用户输入:

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "结合以下知识库内容和会话历史回答用户问题:\n{context}"),
        MessagesPlaceholder(variable_name="history"),
        ("human", "{input}"),
    ]
)

步骤3:构建核心Runnable Chain

先检索文档并格式化,再结合输入和历史传入Prompt,最后调用LLM:

from langchain_openai.chat_models import ChatOpenAI
from langchain_core.runnables import RunnablePassthrough

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)

# 格式化检索到的文档为字符串
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

# 整合检索、输入、历史的Chain
retrieval_chain = (
    {"context": retriever | format_docs, "input": RunnablePassthrough(), "history": RunnablePassthrough()}
    | prompt
    | llm
)

步骤4:绑定多用户多会话记忆

通过RunnableWithMessageHistory为每个会话维护独立历史:

from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.runnables import ConfigurableFieldSpec
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory

# 会话存储,用(user_id, conversation_id)作为唯一标识
store = {}

def get_session_history(user_id: str, conversation_id: str) -> BaseChatMessageHistory:
    key = (user_id, conversation_id)
    if key not in store:
        store[key] = ChatMessageHistory()
    return store[key]

# 为Chain添加记忆支持
with_message_history = RunnableWithMessageHistory(
    runnable=retrieval_chain,
    get_session_history=get_session_history,
    input_messages_key="input",  # 与输入字段名对应
    history_messages_key="history",  # 与Prompt中的占位符对应
    history_factory_config=[
        ConfigurableFieldSpec(
            id="user_id",
            annotation=str,
            name="用户ID",
            description="用户唯一标识",
            default="",
            is_shared=True,
        ),
        ConfigurableFieldSpec(
            id="conversation_id",
            annotation=str,
            name="会话ID",
            description="会话唯一标识",
            default="",
            is_shared=True,
        ),
    ],
)

步骤5:测试调用

user_id = "user123"
conversation_id = "conv456"

# 首次提问
response = with_message_history.invoke(
    {"input": "法国的首都是什么?"},
    config={"configurable": {"user_id": user_id, "conversation_id": conversation_id}},
)
print(response.content)

# 跟进提问(测试记忆)
response2 = with_message_history.invoke(
    {"input": "它的人口大约是多少?"},
    config={"configurable": {"user_id": user_id, "conversation_id": conversation_id}},
)
print(response2.content)

关键错误修正说明

  • 原代码直接拼接retriever|llm无效:Retriever输出的是文档对象,需先格式化为字符串才能传入Prompt。
  • 统一字段名:确保输入字段、Prompt变量、记忆配置的key一致(如用"input"代替"query"),避免匹配错误。
  • Chain结构逻辑:必须先完成文档检索与格式化,再将上下文、输入、历史一起传入Prompt,最后调用LLM。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:14:55