用 MongoIndexStore 实现对话存档和恢复 & 实现“多用户、多对话线程”场景(像一个 ChatGPT 对话列表那样)

用LlamaIndex写两个完整实用的案例!

  1. 实现如何用 MongoIndexStore 实现对话存档和恢复
  2. 实现"多用户、多对话线程"场景(像一个 ChatGPT 对话列表那样)

✅ 案例一:使用 MongoIndexStore 实现对话存档 + 恢复

单用户 + 单对话线程,基础功能:能保存、能断点续聊。

🔧 准备工作(安装依赖)

bash 复制代码
pip install llama-index pymongo

MongoDB 本地连接默认是 mongodb://localhost:27017,你需要保证本地有 MongoDB 或连接远程的 URI。


📦 示例代码(基础对话持久化)

python 复制代码
from llama_index.core import VectorStoreIndex, Document
from llama_index.core.storage import StorageContext
from llama_index.core.vector_stores import SimpleVectorStore
from llama_index.core.storage.docstore import SimpleDocumentStore
from llama_index.storage.index_store.mongodb import MongoIndexStore

# ==== 用户相关信息 ====
USER_ID = "user_123"             # 可以用于区分不同用户的对话
INDEX_ID = f"chat_{USER_ID}"     # 可以命名多个对话索引

# ==== 构造文档 ====
documents = [
    Document(text="OpenAI 是一家 AI 公司,创建于 2015 年。"),
    Document(text="ChatGPT 是 OpenAI 推出的产品,使用了 GPT-4 模型。")
]

# ==== 创建/恢复 MongoIndexStore ====
mongo_store = MongoIndexStore.from_uri(
    uri="mongodb://localhost:27017",
    db_name="llama_chat_db",      # Mongo 数据库名
)

# ==== 创建 StorageContext(连接所有存储模块)====
storage_context = StorageContext.from_defaults(
    vector_store=SimpleVectorStore(),
    docstore=SimpleDocumentStore(),
    index_store=mongo_store,
)

# ==== 构建索引(注意 index_id 保持一致)====
index = VectorStoreIndex.from_documents(
    documents,
    storage_context=storage_context,
    index_id=INDEX_ID
)

# ==== 创建多轮问答引擎 ====
chat_engine = index.as_chat_engine(chat_mode="condense_question", verbose=True)

# ==== 进行对话 ====
response1 = chat_engine.chat("ChatGPT 是谁开发的?")
print("Q1:", response1.response)

response2 = chat_engine.chat("它是基于哪个模型?")
print("Q2:", response2.response)

response3 = chat_engine.chat("那个模型好在哪里?")
print("Q3:", response3.response)

# ==== 之后你可以重启脚本,再次用同样 index_id 就能恢复对话 ====

✅ 案例二:支持多用户 + 多对话线程的对话系统(像 ChatGPT 列表页)

我们假设每个用户可以创建多个"会话"(对话线程),每个会话绑定一个 index_id

📦 结构图:

复制代码
MongoIndexStore
├── user_1
│   ├── chat_001
│   ├── chat_002
├── user_2
│   └── chat_001

🧠 使用场景代码

python 复制代码
from llama_index.core import VectorStoreIndex, Document
from llama_index.core.storage import StorageContext
from llama_index.core.vector_stores import SimpleVectorStore
from llama_index.core.storage.docstore import SimpleDocumentStore
from llama_index.storage.index_store.mongodb import MongoIndexStore

class ChatSessionManager:
    def __init__(self, mongo_uri: str, db_name: str = "llama_multi_user"):
        self.mongo_store = MongoIndexStore.from_uri(uri=mongo_uri, db_name=db_name)

    def start_or_resume_chat(self, user_id: str, session_id: str, documents: list[Document]):
        index_id = f"{user_id}__{session_id}"
        storage_context = StorageContext.from_defaults(
            vector_store=SimpleVectorStore(),
            docstore=SimpleDocumentStore(),
            index_store=self.mongo_store,
        )

        index = VectorStoreIndex.from_documents(
            documents,
            storage_context=storage_context,
            index_id=index_id
        )

        return index.as_chat_engine(chat_mode="condense_question", verbose=True)

# ==== 示例 ====
chat_manager = ChatSessionManager("mongodb://localhost:27017")

user_id = "alice"
session_id = "session_001"

documents = [
    Document(text="Python 是一种流行的编程语言。"),
    Document(text="Flask 是一个基于 Python 的 Web 框架。")
]

# 创建或恢复会话
chat_engine = chat_manager.start_or_resume_chat(user_id, session_id, documents)

# 聊天示例
res1 = chat_engine.chat("Flask 是干什么的?")
print("A1:", res1.response)

res2 = chat_engine.chat("它是用什么语言写的?")
print("A2:", res2.response)

# 下次只要保持 user_id 和 session_id 不变,就能继续这个会话

✅ 多会话系统的设计建议

模块 功能
MongoIndexStore 存储所有对话索引
index_id 使用 user_id + session_id 组合,做到多用户+多对话隔离
StorageContext 每个 session 创建一次,绑定三个 store
chat_engine 每次使用都从正确的 index_id 创建

这里多解释

user_id 和 session_id分别是什么,为什么要两个

🧠 简单说:

  • user_id用户的唯一标识,比如你是张三,我是李四,后台就要知道"是谁在发消息"。
  • session_id这个用户的某一次对话的编号,比如你今天聊的是"贷款业务问题",明天聊的是"转账失败问题",每次对话是一个"会话"。

📌 举个生活例子:

你打开 ChatGPT,左边是不是有很多聊天记录?

  • 你是唯一的一个用户 ------ 这就是 user_id
  • 左边每一个聊天记录,就是一次 session ------ 它们各自有不同的 session_id

比如:

复制代码
user_id = "alice"
session_id = "2024_贷款问题"

user_id = "alice"
session_id = "2024_发票问题"

user_id = "bob"
session_id = "2024_融资问题"

🚀 系统设计上的作用:

✅ 为什么不能只有 user_id?

  • 因为一个用户可能开启多个聊天,不能所有历史记录都堆在一起。

✅ 为什么不能只有 session_id?

  • 因为会有多个用户,比如张三和李四可能都创建了 session_id="2024_chat",那系统无法区分是谁的聊天。

✅ 两个一起用,能确保:

python 复制代码
index_id = f"{user_id}__{session_id}"
  • 绝对唯一,支持多用户 + 多会话
  • 你下次恢复对话,只要传入这两个就能找回上下文

🧩 你开发系统的时候,这样设计会有什么优势?

场景 好处
同一用户多个对话 用户体验好,可以"分主题聊"
多用户使用系统 数据隔离安全,用户互不干扰
MongoDB 查询 可以用复合主键高效索引 {"user_id": ..., "session_id": ...}
断点续聊 一键恢复之前的上下文

✅ 总结

参数 作用 举例
user_id 谁在发消息 "alice"
session_id 哪一场对话 "invoice_202404"
index_id 唯一标识这场聊天 "alice__invoice_202404"
相关推荐
Feel_狗焕2 小时前
transformer架构详解由浅入深-大模型入坑笔记真的很详细
chatgpt·llm
赵钰老师3 小时前
【大语言模型DeepSeek+ChatGPT+python】最新AI-Python机器学习与深度学习技术在植被参数反演中的核心技术应用
人工智能·arcgis·语言模型·chatgpt·数据分析
昊昊昊昊昊明3 小时前
10天学会嵌入式技术之51单片机-day-3
数据库·mongodb
Awesome Baron4 小时前
《Learning Langchain》阅读笔记2-基于 Gemini 的 Langchain PromptTemplate 实现方式
jupyter·chatgpt·langchain·llm
QX_hao5 小时前
【mongodb】--下载
mongodb
ruokkk6 小时前
解决 MongoDB 查询中的 `InvalidMongoDbApiUsageException` 错误
mongodb
john_hjy8 小时前
人类行为的原动力是自我保存-来自ChatGPT
chatgpt
明明跟你说过10 小时前
LangChain + 文档处理:构建智能文档问答系统 RAG 的实战指南
人工智能·python·语言模型·自然语言处理·chatgpt·langchain·gpt-3
爱的叹息10 小时前
LangChain、LlamaIndex 和 ChatGPT 的详细对比分析及总结表格
人工智能·chatgpt·langchain