会话与流式响应
理解聊天历史、流式枚举、会话隔离和中断后的状态。
聊天模型通常根据本次提交的上下文生成回答。应用所说的“记住上次对话”,可能是每次重发历史,也可能是模型服务提供会话标识并保存上下文。两者的资源消耗和状态归属不同。
历史如何参与请求
当前 ChatSession 会先把用户消息加入本地历史,再请求聊天服务。没有服务端 ConversationId 时,请求包含预置提示词和已有历史;有该标识时,请求使用预置提示词及当前消息,连续上下文交由相应提供者处理。
因此,本地历史不等于服务端状态,也不等于完整审计记录。清空本地历史是否同时清除服务器保存的上下文,不能只根据本地集合的变化作出判断。
普通响应与流式响应
普通响应在得到结果后把返回消息加入历史。流式响应则逐项返回更新,并在流完整枚举结束后把累积的助手文本加入历史。
完整读取响应
展示增量内容,最后记录完成状态
用户停止生成
取消上游调用,明确显示回答未完成
连接中断
保留已展示文本与错误状态,不能冒充完整回答
需要审计工具调用
另行保存结构化事件;不要只依赖流式累计文本
流式响应是异步数据序列;得到序列不代表请求已经成功完成。异常可能发生在后续枚举中。应把读取循环包含在错误处理和取消范围内,而不是只包住获取序列的那一行。
会话隔离与生命周期
会话管理器的 Current 表示该管理器的当前会话,不是自动绑定 HTTP 用户的上下文。Web 应用应显式传递会话标识,并维护“用户或租户 → 允许访问的会话”关系。随机标识只能减少猜测机会,不能替代归属校验。
同一个会话的并发请求会共享历史及选项;当前调用还可能修改 ChatOptions.ConversationId。建议对单会话请求串行化,或者为独立任务建立独立会话和选项对象。不要把同一可变选项实例随意复用于多个并发请求。
Abandon 会释放会话。当前会话释放还涉及聊天服务的释放,因此自定义实现若在多个会话之间共享同一个服务实例,必须核对资源所有权,避免关闭一个会话影响其他会话。会话存活时间和进程内历史也不能作为持久化承诺。
Web 调用路径
以下路径以名为 ollama 的助手为例。部署和连接设置见智能化。
POST /AI/Assistants/ollama/Chats
创建会话,返回会话标识
GET /AI/Assistants/ollama/Chats/{id}
读取会话摘要
POST /AI/Assistants/ollama/Chats/{id}/Chat
在指定会话中聊天,请求体为文本
POST /AI/Assistants/ollama/Chats/Chat
无本地会话历史的聊天
GET /AI/Assistants/ollama/Chats/{id}/History
获取角色及文本历史
DELETE /AI/Assistants/ollama/Chats/{id}/History
清空本地历史
DELETE /AI/Assistants/ollama/Chats/{id}
移除并释放会话
当前聊天控制器在指定标识未找到时会退回无会话调用,而不是统一返回会话不存在。需要严格连续性的业务应先验证会话存在并校验归属,不要把“收到回答”当作“旧历史已经参与请求”的证据。
HTTP 响应由 Web 的异步枚举响应机制输出,不应未经核对就当作某个厂商的 SSE 协议。客户端应按实际内容类型和响应格式解析,并验证中途取消、代理缓冲、超时及断线重连的行为。
接入时的验收场景
先验证同一会话的两轮问答,再测试两个用户的会话不能互访;随后测试生成中取消、服务端报错、过期标识和并发提交。若需要跨进程恢复,应把必要的历史与业务元数据持久化,并明确恢复后的上下文如何重建。
源码入口:ChatSession、会话 Web 接口。
最后更新于