用 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"
相关推荐
列御寇17 小时前
MongoDB分片集群——集群组件概述
数据库·mongodb
列御寇17 小时前
MongoDB分片集群——mongos组件(mongos进程)
数据库·mongodb
Blossom.11818 小时前
大模型自动化压缩:基于权重共享的超网神经架构搜索实战
运维·人工智能·python·算法·chatgpt·架构·自动化
列御寇18 小时前
MongoDB分片集群分片模式——哈希分片(Hashed Sharding)
数据库·mongodb·哈希算法
开发者导航18 小时前
【开发者导航】ChatGPT Atlas 开源平替,一款免费的AI浏览器,让网页自动驾驶!
人工智能·chatgpt
列御寇20 小时前
MongoDB分片集群——分片键(Shard Keys)概述
数据库·mongodb
薛定谔的猫19821 天前
LlamaIndex(二)加载本地数据
llamaindex
薛定谔的猫19822 天前
LlamaIndex(一)初见
llama·llamaindex
赫尔·普莱蒂科萨·帕塔2 天前
医疗新纪元的开启
人工智能·chatgpt
TOPGUS2 天前
黑帽GEO手法揭秘:AI搜索阴影下的新型搜索劫持与风险
人工智能·搜索引擎·chatgpt·aigc·谷歌·数字营销