会话与消息模型
公开教程 · 无需登录

会话与消息模型

多轮问答需要两样东西:一个容器,一串文本。conversations 记这次连续追问属于谁、属于哪个班、由哪个智能体作答;messages 按写入顺序记下说过的每一句,以及助手这侧的出处。两者以会话编号关联。

1两张表的职责划分

会话是容器,消息是内容。会话行只记归属、角色与标题;对话正文与出处全部落在消息行。

表字段含义与约束
conversationsid主键,自增
class_id所属班级,取自登录用户,请求无法指定
user_id归属用户;会话列表与单条读取都按它过滤
agent_id会话选定的智能体;新建时写入,此后不再变更
title新建时为占位串「新的提问」,首轮提问后改为其前 24 字
created_at · updated_atupdated_at 随每次提问刷新,会话列表按它倒序
messagesid主键,自增;同一会话内按它排序
conversation_id所属会话;会话行删除时一并清掉
role只有 user 与 assistant,由数据库约束
content消息正文
citations_json · skill_name出处信息,仅助手消息有:引用列表与本次命中的技能名
created_at写入时间
conversations · 会话 id 主键 class_id · user_id 归属 agent_id 选定的智能体 title 首轮提问前 24 字 created_at · updated_at messages · 消息 id · conversation_id role user 或 assistant content 正文 citations_json · skill_name created_at 一条会话对应多条消息:messages.conversation_id = conversations.id 会话行既不存提示词,也不存对话正文
会话编号把一批消息归到一次追问下;agent_id 让每轮回答都能回到当时那套角色设定与绑定。助手消息上的技能名与引用列表,则记下这轮用了什么、引了哪些材料。

标题由服务端生成

新建会话时,标题写入占位串「新的提问」。首轮提问到达后,服务端取该提问的前 24 字覆盖它;若截取结果为空,保留占位串。此后每轮提问只刷新 updated_at——会话列表按它倒序,最近问过的排在最前。

会话选定一个智能体

新建会话时必须指定一个智能体:服务端校验它属于本班且处于启用状态,通过后把编号写进会话行。此后这个会话一直用它,请求里再带别的编号也不会更换;要换只能新开会话。

该智能体后来被停用,已有会话仍可继续提问——停用只拦住新建时的选用。若本班当时一个已启用的智能体都没有,新建会话会返回 400。

2上下文窗口:末尾 6 条消息

消息全部留在库里,但送进上下文的只有最靠后的一小段。窗口固定,不随会话变长。

全量历史会让上下文无界增长(unbounded context growth),每轮的开销也随会话长度上涨。本课取一个固定窗口:每次回答都重新查询消息表,按写入顺序取末尾 6 条(一问一答算一轮,6 条约合 3 轮),每条正文再截断到 500 字。角色不是 user 或 assistant 的记录、以及正文为空的记录,一律跳过。本轮提问在生成之前已写入库,因此必定落在窗口内。

窗口内:末尾 6 条消息,每条截断 500 字 第 1 条 第 2 条 第 3 条 第 4 条 第 5 条 第 6 条 第 7 条 第 8 条 第 9 条 第 10 条 第 11 条 本轮提问 窗口之外的消息仍留在库里,只是不进上下文
窗口是滑动的(sliding window):每次回答都重新查询消息表、取列表末尾的若干条,而不是记录上次读到哪里。更早的消息仍可翻看,只是不再进入上下文。

3会话的归属与跨班判定

会话是私有资源。读取与新建都要过两道判定:先看是不是本人,再看是不是本班;任一不符,与「不存在」返回完全一致的响应。

情形结果
读取自己的会话返回会话与消息列表
读取他人会话查询带上用户编号,查不到这条会话,返回 404
读取他班会话先按用户取出该行,再比对班级;不一致时同样返回 404
新建会话时选定智能体只接受本班已启用的;不存在、他班或未启用一律按「不存在」返回 404
新建会话但本班没有已启用的智能体返回 400,提示本班暂无可用的智能体
会话所属智能体后来被停用已有会话照常提问;停用只挡住新会话的选用
在未登录时访问返回 401,不清空任何数据
两重过滤缺一不可,防的是对象级越权(BOLA/IDOR):只按用户过滤,防不住班级维度的越权读取;只按班级过滤,防不住跨用户维度的越权读取。跨班与不存在必须返回完全一致的响应,避免通过状态码差异泄露资源存在性(information disclosure)。