84 lines
3.9 KiB
Markdown
84 lines
3.9 KiB
Markdown
# 用户对话 API 工作流
|
||
|
||
## 1. 首轮对话
|
||
|
||
客户端向 `POST /api/chat` 发送 `message`,不传 `conversation_id`。服务端创建 SuperAgent Session,随后通过 SSE 返回:
|
||
|
||
1. `conversation`:包含新生成的 `conversation_id` 和 `reused=false`。
|
||
2. 零个或多个 `progress`:只用于展示运行/工具进度。
|
||
3. `message`:严格完成后的最终回答。
|
||
4. `done`:包含同一 `conversation_id`、安全 Run ID 和 token usage。
|
||
|
||
客户端只有在收到 `done` 后才把本轮标记为成功,并保存 `conversation_id`。
|
||
|
||
## 2. 后续对话
|
||
|
||
后续请求同时发送 `message` 和前一轮保存的 `conversation_id`。成功流中的 `conversation` 事件返回 `reused=true`,说明复用了原 SuperAgent Session 上下文。
|
||
|
||
同一对话在收到 `done` 或终止 `error` 前不得再次提交。若服务端返回 `CHAT_CONVERSATION_BUSY`,客户端应保留当前流并稍后重试,不能自动改用同一个问题创建多轮并发 Run。
|
||
|
||
## 3. 失败处理
|
||
|
||
- HTTP JSON 错误:SSE 尚未开始;按 HTTP 状态和 `error.code` 处理。
|
||
- SSE `error`:流已经开始,但本轮没有可信最终回答;不得把此前进度当作答案。
|
||
- `CHAT_CONVERSATION_NOT_FOUND`:会话已过期、服务重启或请求落到其他实例;提示用户上下文已失效,并在用户确认后省略 `conversation_id` 创建新对话。
|
||
- 上游超时、协议错误、Run 失败或客户端中途断开:当前实现会使会话映射失效,以免继续复用可能仍有活动 Run 的 Provider Session。
|
||
- 网络断开且没有看到 `done`:结果未知;首版不自动重放原消息,避免重复 Run。
|
||
|
||
## 4. curl 联调
|
||
|
||
先把 `.env` 显式加载到当前 shell,再启动服务;Go 程序不会自动读取 `.env`:
|
||
|
||
```bash
|
||
set -a
|
||
source .env
|
||
set +a
|
||
go run ./cmd/server
|
||
```
|
||
|
||
另开终端发起首轮请求:
|
||
|
||
```bash
|
||
curl -N \
|
||
-H "Authorization: Bearer ${FIRE_SAFETY_CHAT_AUTH_TOKEN}" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Accept: text/event-stream" \
|
||
--data '{"message":"观水镇附近有哪些水源候选?"}' \
|
||
http://127.0.0.1:8080/api/chat
|
||
```
|
||
|
||
从 `conversation` 或 `done` 事件复制 ID 后测试下一轮:
|
||
|
||
```bash
|
||
curl -N \
|
||
-H "Authorization: Bearer ${FIRE_SAFETY_CHAT_AUTH_TOKEN}" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Accept: text/event-stream" \
|
||
--data '{"message":"再说明这些候选的限制","conversation_id":"conv_替换为上一轮返回值"}' \
|
||
http://127.0.0.1:8080/api/chat
|
||
```
|
||
|
||
浏览器前端还必须把其精确 Origin 加入 `FIRE_SAFETY_CHAT_ALLOWED_ORIGINS`,例如 `http://localhost:5173`。静态 Chat Bearer 会被浏览器用户看到,因此只适用于受控联调,不能直接作为公网最终用户鉴权。
|
||
|
||
## 5. 既有 DashScope 风格客户端
|
||
|
||
设置 `FIRE_SAFETY_CHAT_COMPAT_APP_ID` 后,同一个 Chat Service 还会注册:
|
||
|
||
```text
|
||
POST /api/v1/apps/{FIRE_SAFETY_CHAT_COMPAT_APP_ID}/completion
|
||
```
|
||
|
||
首轮请求使用 `xtoken: ${FIRE_SAFETY_CHAT_AUTH_TOKEN}`:
|
||
|
||
```bash
|
||
curl -N \
|
||
-H "xtoken: ${FIRE_SAFETY_CHAT_AUTH_TOKEN}" \
|
||
-H "Content-Type: application/json" \
|
||
--data '{"input":{"prompt":"杨家盘瞭望哨 3 公里内的水源?"},"parameters":{}}' \
|
||
http://127.0.0.1:8080/api/v1/apps/fire-safety-public-app/completion
|
||
```
|
||
|
||
兼容流先返回 `finish_reason: "null"` 和本地 `session_id`,严格成功后返回 `finish_reason: "stop"` 与最终 `text`。后续轮次把该 `session_id` 放入 `input.session_id`。客户端不得使用 URL 中的 App ID、静态 token 或 session ID推断身份与权限,也不得把未出现 `stop` 的断流结果当作成功答案。
|
||
|
||
公网 Nginx 示例和完整 curl 见 [`../project/operations/nginx-public-entry.md`](../project/operations/nginx-public-entry.md)。兼容字段的唯一项目契约见 [`../specs/fire-safety-ymd-dashscope-compatible-chat-v1.md`](../specs/fire-safety-ymd-dashscope-compatible-chat-v1.md)。
|