背景
使用 LangChain 实现多轮对话记忆时,可通过 session_id 完成多用户、多聊天窗口的记忆隔离。
session_id 为对话唯一标识:相同 ID 共享对话记忆,不同 ID 则记忆相互独立。调用链时需主动传入该参数。
python
chain.invoke(
{"user_input": "问题"},
config={"configurable": {"session_id": 这里按需传入}}
)
session_id 支持多种取值:用户 ID、前端生成的临时 ID、手机号、用户名、UUID 等。
架构设计:前端管理 session_id
在前后端交互场景中,session_id 由前端生成、维护并随请求传递,后端不做固定处理,仅使用前端传入的值区分会话。
设计原因
同一用户可同时打开多个聊天窗口,每个窗口对应独立对话,由前端感知窗口状态,因此交由前端统一管理会话 ID。
前端生成时机
- 用户打开新聊天窗口
- 用户点击新建对话
- 聊天界面首次加载
ID 仅生成一次,在前端本地留存,直至窗口关闭或清空对话。
前端生成方案
简易方案
基于时间戳 + 随机数拼接,实现简单。
python
// 前端 JS 代码(最简单)
const session_id = "session_" + Date.now() + Math.random()
标准方案:原生 UUID
借助浏览器原生 crypto.randomUUID() 生成标准 UUID,无需额外安装依赖,现代浏览器、Vue、React 及主流小程序均兼容。
注意:crypto.randomUUID() 仅在浏览器安全上下文中生效:http://localhost/127.0.0.1 以及所有 HTTPS 访问场景均可正常使用;除 localhost 外,其余 HTTP 协议访问(无论域名、公网 / 内网 IP)都会被浏览器禁用该 API,进而抛出报错。
本项目为个人项目,仅在本地开发与线上 HTTPS 环境运行,因此直接使用原生 window.crypto.randomUUID() 即可,无需额外做降级兼容。
python
const session_id = crypto.randomUUID()
限制:IE 及 2018 年前的老旧浏览器不支持该 API。
常见问题:TS 提示 randomUUID 不存在
报错信息
python
TS2339: Property 'randomUUID' does not exist on type
问题原因
TypeScript 依靠内置 lib.dom.d.ts 识别浏览器 API,该文件是 TS 版本发布时的浏览器 API 快照。
randomUUID 属于较新 API,4.6 版本之前的 TS 内置类型声明未收录该方法,因此编译报错,但浏览器实际可正常运行代码。
解决方案
-
临时补丁:补充缺失的类型声明(不改动 TS 版本,快速修复)
-
升级 TypeScript(治本)
bash
# 升级至最新版
npm install typescript@latest --save-dev
# 老项目推荐指定兼容版本
npm install typescript@5.1.6 --save-dev
升级成功后重启服务。
注意:Vue2 + Webpack 等老旧技术栈项目,不建议直接升级到 TS 6.0,相关构建工具、校验插件(代码语法 / 类型检查工具)暂未兼容,最高建议使用 TS 5.x 系列,避免编译报错。
- 使用 uuid 库(兼容性最优)
跨环境、全版本 TS 通用,稳定性最强。
python
# 安装核心库
npm install uuid
# 安装 TS 类型声明文件
npm install -D @types/uuid
说明:uuid 为纯 JavaScript 库,@types/uuid 提供配套类型定义,缺失会导致 TS 无法识别模块。
使用方式
python
import { v4 as uuidv4 } from 'uuid';
const session_id = uuidv4();
前后端请求对接
前端请求
每次发送对话请求时,携带已维护的 session_id.
python
axios.post("/api/chat", {
user_input: "你好",
session_id: session_id // 每次都带!
})
后端接收与使用
后端直接提取参数,传入 LangChain 配置即可实现会话隔离。
python
@app.post("/api/chat")
def chat(user_input: str, session_id: str):
config = {"configurable": {"session_id": session_id}}
return chain.invoke(
{"user_input": user_input},
config=config
)
总结
session_id 由前端统一生成、管理,每次请求随参数传给后端。后端依据该标识隔离对话记忆,最终实现多用户、多聊天窗口的独立多轮对话能力。