一句话定义:会话隔离(Session Isolation)是指在同一套服务实例上同时服务多个用户时,保证每个会话的上下文(历史消息、临时状态、工具调用中间结果)只对属于它的那个会话可见,绝不串到别人那里去。
上下文为什么会串
大模型本身是无状态的:它不记得你上一句说了什么。所谓“记得”,是应用层每次把历史消息重新拼进请求里。于是上下文实际存在两处:一是客户端或缓存里的会话记录,二是服务进程内的临时变量、连接池、内存缓存。
多用户共用一套服务时,风险就出在第二处。打个比方:餐厅只有一位服务员(服务进程),同时招呼十桌客人。正确的做法是每桌一张点菜单,写清桌号;上错菜的概率取决于他是否始终盯着桌号。如果他把“刚有人点了宫保鸡丁”记在脑子里而不记桌号,下一桌问“我的菜呢”,他就会把别人的菜端过去。会话隔离,就是强制每张单子都带桌号,且任何环节都不允许只看菜名。
工程上常见的“串味”来源很朴素:缓存 key 只用了 user_query 而没带 session id;把对话历史放在进程级全局变量里;复用长连接时把上一个请求的上下文带进了下一个;异步任务回调时拿错了会话句柄。
Session 和 Tenant 是两个维度
这是最容易被混为一谈的地方。它们隔离的东西不一样:
| 维度 | 隔离的对象 | 回答的问题 | 串了的后果 |
|---|---|---|---|
| 会话(Session) | 一次对话或一次登录期间的上下文 | “这是同一段对话吗?” | 张冠李戴,A 的问题得到 B 的答案 |
| 租户(Tenant) | 一个客户组织及其全部数据 | “这是同一家公司吗?” | 数据越权,属于安全事故 |
一句话记法:session 管“聊到哪儿了”,tenant 管“这是谁的数据”。同一个用户可以有多个 session(手机一个、网页一个),它们同租户但必须互相隔离;而同一个 session 里绝不允许出现另一个租户的内容。所以 tenant 隔离是硬边界,通常落在存储层——数据库行级过滤、向量库的 namespace(命名空间)、对象存储前缀;session 隔离更像软边界,落在请求链路和缓存键上。
对从业者的实际意义
做应用时,最省事的做法是把 tenant_id 和 session_id 当成两把必须随身携带的钥匙:缓存键、日志字段、消息队列的 partition key、检索过滤条件,处处都带上。别指望框架默认帮你做对,具体到某个 SDK 或网关怎么配,以官方文档为准。
对普通职场人,判断标准很简单:如果一个 AI 助手会把别人的对话内容、文件或工单显示给你,那不是“小 bug”,而是隔离没做,应当立刻反馈,而不是截图发群里。
