这里主要讲解一些重要概念,这是理解 AI 业务,和后续设计的基础。
1、sessionId、agentId、eventId
一个完整的逻辑流示例:
- 场景:你在一个名为“旅行助手”的对话框(Session ID:
S-123)里问:“帮我查下上海明天的天气”。 - 动作:
- 点击发送,后端启动一个 Agent 进程,生成 Agent ID:
A-999。 - 前端立刻建立 SSE 连接:
GET /sub/A-999。 - 微服务开始推送事件:
- 推送 Event ID:
E-1→ 内容:{"type": "thought", "text": "我需要调用天气插件"} - 推送 Event ID:
E-2→ 内容:{"type": "tool_call", "name": "weather_api"} - (此时网络闪断 1 秒)
- 前端重连,带上
Last-Event-ID: E-2。 - 推送 Event ID:
E-3→ 内容:{"type": "answer", "text": "上海明天多云转晴"}
- 推送 Event ID:
- 回答结束,Agent ID:
A-999销毁,但该回答被存入 Session ID:S-123的历史记录中。
- 点击发送,后端启动一个 Agent 进程,生成 Agent ID:
2、SSE
场景:
- 你打开对话框,给 AI 发了一条消息
- AI 回复你,对话框的字是一个一个打印机一样的出来,耗时很长
这种效果怎么实现呢?
- 前端轮询:性能不现实。
- WebSocket:太重了。
- SSE:
SSE 是一种在基于 HTTP 协议之上的服务器推送技术。它的工作原理非常“返璞归真”:
- 握手:前端发起一个普通的 HTTP 请求。
- 不关门:后端在 Header 中设置
Connection: keep-alive和Content-Type: text/event-stream,告诉浏览器:“这个请求还没完,别关掉,我要开始不停发数据了”。 - 流式传输:后端持续不断地向这个连接里写入数据块。
为什么 Agent 场景首选 SSE 而不是 WebSocket?
- 轻量级:它就是 HTTP,不需要处理复杂的 WebSocket 握手和心跳。
- 原生重连:浏览器会自动处理断线重连。
- 单向性:Agent 场景主要是后端向前端单向输出状态,SSE 的设计初衷就是如此。
3、当我给 AI 发了一个问题,这期间发生了什么?
用户感知:
1、打开对话框,给 AI 发了一个问题:1+1 等于几?
2、AI 开始回答,回答像打印机效果一样,一个字一个字出现。
按时间顺序发生了什么?
阶段一:建立通信管道 (Handshake)
当用户点击“发送”按钮的那一刻,系统首先要搭建一条实时传输的“高速公路”。
-
客户端 (Client):向业务后端发送一个普通的 HTTP POST 请求(带着你的问题:“1+1等于几?”)。
-
业务后端 (App Server):
- 接收请求,验证用户身份。
- 在数据库创建一条新的对话记录(关联 Session ID)。
- 生成一个新的任务实例(关联 Agent ID)。
- 关键动作:立即返回这个
agentId给客户端。
-
客户端 (Client):拿到
agentId后,立刻发起 SSE 订阅:const source = new EventSource('/sse/subscribe/agent_001'); -
SSE 微服务:接收订阅请求,保持连接挂起,并将该连接存入内存 Map 中。
阶段二:驱动 AI 思考 (Reasoning)
此时,前端页面可能正在显示“AI 正在思考…”的占位符。
- 业务后端 (App Server):调用 AI 模型接口(如 OpenAI/Claude)。
- AI 模型:开始处理,并通过 Stream 模式 返回数据块(Chunks)。
- 业务后端 (App Server):
- 接收到 AI 的第一个 Chunk(例如:“1”)。
- 将这个碎片封装成一个 Event,发给 SSE 微服务。
阶段三:事件分发与渲染 (Streaming)
这是最核心的“打印机效果”来源。
- SSE 微服务:
- 收到业务后端发来的事件。
- 根据
agentId找到对应的所有前端连接。 - 按照 SSE 格式(
data: {...})将字符串写入连接。
- 客户端 (Client):
- 触发
onmessage回调。 - 解析出 JSON 数据,提取出文本碎片。
- 触发
- 前端 UI (React/Vue):
- 将新收到的字符追加到当前的 state 中:
content += newChar。 - 触发页面重新渲染,用户看到字符“跳”了出来。
- 将新收到的字符追加到当前的 state 中:
阶段四:收尾与持久化 (Completion)
- AI 模型:发送一个结束标志(如
[DONE])。 - 业务后端 (App Server):
- 通知 SSE 微服务 发送一个
type: "done"的事件。 - 将完整的回答(1+1=2)一次性写入数据库,供以后翻阅历史记录。
- 通知 SSE 微服务 发送一个
- 客户端 (Client):
- 收到
done事件,关闭 SSE 连接。 - 停止“打印”状态,将该次对话标记为完成。
- 收到