用LlamaIndex写两个完整实用的案例!
- 实现如何用 MongoIndexStore 实现对话存档和恢复
- 实现"多用户、多对话线程"场景(像一个 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" |