LLM ChatServer 实战 - 会话管理、SSE 流式与错误语义的接口设计(附清单)

客服机器人从命令行 demo 变成给三个人用的内部工具,中间隔着一层 HTTP 服务。模型本身早就调通了,这两天把服务层重构了一遍,精力主要消耗在把会话管理、流式输出和错误语义这些杂事做对。这篇文章把接口设计里的关键决策和踩过的坑整理出来。

先给结论

接口 方法 功能 关键点
/api/session POST 创建会话 绑定模型,返回 session_id
/api/sessions GET 会话列表 附带首条消息,方便 UI 展示
/api/session/{id}/history GET 历史消息 时间戳统一 int64
/api/session/{id} DELETE 删除会话 不存在返回 404
/api/message POST 发消息(全量) 简单场景用
/api/message/async POST 发消息(SSE 流式) 前端体验的刚需

多轮对话场景直接用流式接口,全量接口留着给后台批处理和测试用。

统一响应格式

所有接口返回同一个骨架,前端只需要写一次解析逻辑。

json 复制代码
{
  "success": true,
  "message": "create session success",
  "data": {}
}

错误语义也固定下来,不要每个接口自己发明。

状态码 含义
200 业务成功
400 请求体解析失败、字段缺失
404 session_id 不存在
500 模型调用失败等内部错误

我专门写了 build_response(message, success) 这么一个函数,所有错误响应都从它出去。一开始每个接口里手写 JSON 序列化,改一次错误格式要动七个地方,后来收拢到一处,字段增减只改一行。

流式接口是体验的生死线

全量接口下用户盯着转圈等十几秒,感觉系统死了。改用 SSE(Server-Sent Events)分块传输后,首字响应压到一秒内,体感完全不同。

几个协议层面的细节值得单独拎出来。

  1. 响应头设 text/event-stream,关缓存、保持长连接
  2. 每帧以 data: 开头,两行换行符收尾,收尾时发一个 [DONE] 标记
  3. 模型吐出的增量文本必须做 JSON 转义再放进帧里。模型输出里出现引号和换行是常态,不转义直接把前端的事件解析打碎,而且这种 bug 表现为随机丢字,很难定位
  4. 连接建立后立刻发一个空帧。模型首 token 之前有一段静默期,不发空帧某些代理和网关会判定连接超时掐掉
python 复制代码
async def stream_chat(session_id: str, message: str):
    yield sse_frame("")          # 先发空帧防网关超时
    async for chunk in llm.call_stream(session_id, message):
        yield sse_frame(json.dumps({"delta": chunk}))
    yield sse_frame("[DONE]")

另外踩过一个隐蔽的坑。流式回调函数返回 false 时,底层直接断流,后半段内容全部丢失且没有任何报错。回调里的异常处理一定要包住,转成日志而不是让它炸穿传输层。

分层

协议归协议,业务归业务。服务层只做三件事,解析请求、校验参数、组织响应。会话管理和模型调用全部下沉到 SDK 层。

刚开始我把模型重试逻辑写在接口处理器里,三个接口各复制了一份,后来一次超时参数调整只改了两处,漏了第三处,线上行为不一致折腾了半天。分层是给未来的自己留活路。协议层保持轻薄,业务变更就不会碰坏传输层。

踩坑清单速查

  1. 时间戳序列化时统一转 int64,否则 JSON 输出类型飘忽不定
  2. 路径参数用正则捕获组取值,下标写错会静默取到空值
  3. SSE 帧少了尾部换行符,前端 EventSource 解析不到事件
  4. 删除不存在的会话返回 404,别图省事返回 200
  5. 流式回调里的异常必须捕获,否则静默断流

结合系列

  • 模型调用失败的重试与降级,在《多模型路由实战》里有完整方案
  • 流式首字延迟的测量口径见《LLM 延迟实战》里的 TTFT、TPOT 与首字慢的排查顺序
  • 会话历史越积越长之后怎么办,见《Agent 记忆实战》的截断与摘要方案
  • 接口鉴权和防注入边界,参考《Agent 安全护栏实战》

写在最后。服务层没有算法难点,全是约定和细节,但这些约定直接决定前端工程师骂不骂你。把响应格式、错误语义、流式协议三件事定死,后面的接口就是在流水线上复制粘贴。

下一篇写会话服务加上多用户隔离的实践,觉得有用的话点个关注,有问题评论区聊。

参考《【AI大模型接入SDK】ChatServer接口实现》,作者 艾莉丝努力练剑。结构借鉴,实现与结论按本项目场景独立重写。

相关推荐
狂师5 小时前
AI Agent 评测:到底要测什么、新手怎么测?(附完整流程)
人工智能·llm·测试
lucas_AI5 小时前
不训扩散模型也能生成文本?BERT 本来就是半个去噪生成器,加个外置解码器就够
llm
lucas_AI5 小时前
单集群一天吐 155 万亿 token 的引擎开源了:DeepSeek 放出生产级推理框架 DeepInfer
llm
lucas_AI5 小时前
证不动的引理别再死拆了:Maestro 给 Lean 证明装上「总指挥」,研究级定理多证 63%
人工智能·llm
虎鲸不是鱼16 小时前
【虎鲸进化论 30】安全护栏:人类闸门、审计与爆炸半径
人工智能·自动化·大模型·llm·自进化agent
方方洛18 小时前
ai-agent教程-18-附录E-推荐阅读与资源
人工智能·llm·agent
blackappleD18 小时前
DeepSeek 开源推理框架 DeepInfer:KVCache 存三天、投机解码少验 30% 是怎么做到的
llm·deepseek