Files
deerflow-code/NEW_CHAT_STREAM_FORMAT.md
xuhdandClaude Sonnet 4.6 adeace0f7b feat: 新增 multi-llm 路由智能体及 API 端点
添加 multi-llm 路由智能体(LangGraph),支持多 LLM 分发能力;在 Gateway 中注册 /api/multi-llm 路由,并豁免其 CSRF 和认证校验;同时新增 asyncmy 依赖和聊天流格式文档。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:48:16 +08:00

475 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# New Chat 接口流式返回格式说明
## 接口概览
- **路径**:`POST /new_chat`
- **传输协议**:Server-Sent Events (SSE)
- **Content-Type**:`text/event-stream`
- **协议基础**:Vercel AI SDK Data Stream Protocol
---
## 请求格式
```json
{
"chat_id": 123,
"search_space_id": 456,
"user_query": "用户问题",
"pic_query": [{"image_url": "/tmp/xxx.png"}],
"model_name": "gpt-4o",
"enable_citations": true,
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `chat_id` | int | ✅ | 会话 ID,同时作为 LangGraph 的 thread_id |
| `search_space_id` | int | ✅ | 搜索空间 ID |
| `user_query` | string | ✅ | 用户问题 |
| `pic_query` | list\|null | ❌ | 图片路径列表,格式 `[{"image_url": "..."}]` |
| `model_name` | string\|null | ❌ | 指定模型名称(插件场景使用) |
| `enable_citations` | bool | ❌ | 是否启用引用(默认 true) |
| `messages` | list\|null | ❌ | 历史消息列表 |
| `attachments` | list\|null | ❌ | 上传附件(已解析为 Markdown) |
| `mentioned_document_ids` | list\|null | ❌ | 前端 @ 引用的文档 ID 列表 |
---
## 响应 Headers
```
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
```
---
## SSE 数据帧格式
每条消息均为标准 SSE 格式:
```
data: {JSON 对象}\n\n
```
流结束时发送:
```
data: [DONE]\n\n
```
---
## 事件类型详解
### 1. 消息生命周期
#### `start` — 消息开始
```json
{"type": "start", "messageId": "msg_abc123"}
```
| 字段 | 说明 |
|------|------|
| `messageId` | 本次消息的唯一 ID |
---
#### `finish` — 消息结束
```json
{"type": "finish"}
```
---
#### `[DONE]` — 流终止标记
```
data: [DONE]
```
> 这是流中最后一帧,为纯字符串,不是 JSON。
---
### 2. 步骤控制(多轮工具调用)
#### `start-step` — 步骤开始
```json
{"type": "start-step"}
```
#### `finish-step` — 步骤结束
```json
{"type": "finish-step"}
```
> 每次 LLM 调用算一个 step。工具调用期间会有多个 step 交替出现。
---
### 3. 文本块(start / delta / end 模式)
#### `text-start` — 文本块开始
```json
{"type": "text-start", "id": "text_abc123"}
```
#### `text-delta` — 文本增量内容
```json
{"type": "text-delta", "id": "text_abc123", "delta": "Hello, "}
```
#### `text-end` — 文本块结束
```json
{"type": "text-end", "id": "text_abc123"}
```
---
### 4. 推理块(Reasoning,适用于 DeepSeek R1 等思维链模型)
#### `reasoning-start` — 推理块开始
```json
{"type": "reasoning-start", "id": "reasoning_abc123"}
```
#### `reasoning-delta` — 推理增量内容
```json
{"type": "reasoning-delta", "id": "reasoning_abc123", "delta": "让我先思考..."}
```
#### `reasoning-end` — 推理块结束
```json
{"type": "reasoning-end", "id": "reasoning_abc123"}
```
> 触发时机:
> - 模型返回 `additional_kwargs.reasoning_content`(DeepSeek R1 原生)
> - 模型输出中包含 `<think>...</think>` 标签(自动剥离)
---
### 5. 工具调用
#### `tool-input-start` — 工具调用开始
```json
{"type": "tool-input-start", "toolCallId": "call_abc123", "toolName": "search_knowledge_base"}
```
#### `tool-input-delta` — 工具输入流式内容(增量)
```json
{"type": "tool-input-delta", "toolCallId": "call_abc123", "inputTextDelta": "San Fra"}
```
#### `tool-input-available` — 工具输入完整参数
```json
{
"type": "tool-input-available",
"toolCallId": "call_abc123",
"toolName": "search_knowledge_base",
"input": {"query": "机器学习入门"}
}
```
#### `tool-output-available` — 工具执行结果
```json
{
"type": "tool-output-available",
"toolCallId": "call_abc123",
"output": {"status": "completed", "result_length": 1234}
}
```
> 注意:`search_knowledge_base` 只返回摘要(不含全文),`write_todos`、`link_preview`、`display_image`、`scrape_webpage`、`generate_podcast` 会返回完整 output 供前端渲染组件。
---
### 6. 来源引用
#### `source-url` — URL 来源
```json
{
"type": "source-url",
"sourceId": "https://example.com",
"url": "https://example.com",
"title": "示例页面"
}
```
#### `source-document` — 文档来源
```json
{
"type": "source-document",
"sourceId": "doc_123",
"mediaType": "file",
"title": "报告.pdf",
"description": "第三季度报告"
}
```
---
### 7. 文件
```json
{"type": "file", "url": "https://example.com/image.png", "mediaType": "image/png"}
```
---
### 8. 自定义数据(`data-*` 类型)
#### `data-terminal-info` — 终端信息提示
```json
{
"type": "data-terminal-info",
"data": {
"text": "知识库搜索已完成",
"type": "success"
}
}
```
`type` 枚举值:`info` | `error` | `success` | `warning`
---
#### `data-further-questions` — 推荐追问问题
```json
{
"type": "data-further-questions",
"data": {
"questions": ["问题1", "问题2", "问题3"]
}
}
```
---
#### `data-thinking-step` — 思考步骤(思维链 UI 展示)
```json
{
"type": "data-thinking-step",
"data": {
"id": "thinking-1",
"title": "正在搜索知识库",
"status": "in_progress",
"items": ["Query: 机器学习入门"]
}
}
```
| 字段 | 说明 |
|------|------|
| `id` | 步骤唯一 ID(格式 `thinking-N`) |
| `title` | 步骤标题 |
| `status` | `pending` \| `in_progress` \| `completed` |
| `items` | 步骤详情列表(可选) |
> 同一个 `id` 的步骤事件会被重复发送以更新状态(先 `in_progress` 后 `completed`)。
**常见步骤标题对照:**
| 工具 / 场景 | 标题 |
|------------|------|
| 初始分析 | 正在理解您的请求 / 正在分析您的内容 |
| `search_knowledge_base` | 查询个人知识库中 |
| `search_web` | 网查搜索中 |
| `link_preview` | 正在获取链接预览 |
| `display_image` | 正在分析图片 |
| `scrape_webpage` | 正在抓取网页 |
| `write_todos`(首次) | 正在创建计划 |
| `write_todos`(更新) | 正在更新进度 |
| `generate_podcast` | 正在生成播客 |
---
### 9. 错误
```json
{
"type": "error",
"errorText": "API rate limit exceeded",
"errorType": "llm",
"errorCode": "rate_limit"
}
```
| 字段 | 说明 |
|------|------|
| `errorText` | 错误描述文本 |
| `errorType` | 错误类型(见下表) |
| `errorCode` | 具体错误代码(可选) |
**errorType 枚举:**
| 值 | 含义 |
|----|------|
| `llm` | LLM / API 错误(模型不存在、限流、密钥错误等) |
| `network` | 网络连通性错误 |
| `timeout` | 请求超时 |
| `authentication` | 鉴权 / 权限错误 |
| `rate_limit` | 速率限制 |
| `validation` | 输入验证错误 |
| `internal` | 内部服务器错误 |
| `unknown` | 未知错误 |
---
### 10. 中断(Human-in-the-loop)
```json
{
"type": "interrupt",
"messageId": "msg_abc123",
"interrupt": {
"action_requests": [...],
"review_configs": [...]
},
"payload": {"expertAgentId": 42}
}
```
---
## 完整流示例(普通问答)
```
data: {"type":"start","messageId":"msg_abc123"}
data: {"type":"start-step"}
data: {"type":"data-thinking-step","data":{"id":"thinking-1","title":"正在理解您的请求","status":"in_progress","items":["Processing: 什么是向量数据库?"]}}
data: {"type":"data-thinking-step","data":{"id":"thinking-1","title":"正在理解您的请求","status":"completed","items":["Processing: 什么是向量数据库?"]}}
data: {"type":"text-start","id":"text_xyz789"}
data: {"type":"text-delta","id":"text_xyz789","delta":"向量数据库是"}
data: {"type":"text-delta","id":"text_xyz789","delta":"一种专为存储和检索"}
data: {"type":"text-delta","id":"text_xyz789","delta":"高维向量而设计的数据库..."}
data: {"type":"text-end","id":"text_xyz789"}
data: {"type":"finish-step"}
data: {"type":"finish"}
data: [DONE]
```
---
## 完整流示例(含工具调用)
```
data: {"type":"start","messageId":"msg_abc123"}
data: {"type":"start-step"}
data: {"type":"data-thinking-step","data":{"id":"thinking-1","title":"正在理解您的请求","status":"in_progress","items":["Processing: 搜索最新 AI 论文"]}}
data: {"type":"data-thinking-step","data":{"id":"thinking-1","title":"正在理解您的请求","status":"completed","items":["Processing: 搜索最新 AI 论文"]}}
data: {"type":"data-thinking-step","data":{"id":"thinking-2","title":"查询个人知识库中","status":"in_progress","items":["Query: 最新 AI 论文"]}}
data: {"type":"tool-input-start","toolCallId":"call_xxx","toolName":"search_knowledge_base"}
data: {"type":"tool-input-available","toolCallId":"call_xxx","toolName":"search_knowledge_base","input":{"query":"最新 AI 论文"}}
data: {"type":"data-thinking-step","data":{"id":"thinking-2","title":"Searching knowledge base","status":"completed","items":["Query: 最新 AI 论文","Found relevant information (2048 chars)"]}}
data: {"type":"tool-output-available","toolCallId":"call_xxx","output":{"status":"completed","result_length":2048}}
data: {"type":"data-terminal-info","data":{"text":"知识库搜索已完成","type":"success"}}
data: {"type":"text-start","id":"text_xyz789"}
data: {"type":"text-delta","id":"text_xyz789","delta":"根据知识库中的内容..."}
data: {"type":"text-end","id":"text_xyz789"}
data: {"type":"finish-step"}
data: {"type":"finish"}
data: [DONE]
```
---
## 完整流示例(含推理过程)
```
data: {"type":"start","messageId":"msg_abc123"}
data: {"type":"start-step"}
data: {"type":"reasoning-start","id":"reasoning_r01"}
data: {"type":"reasoning-delta","id":"reasoning_r01","delta":"让我先分析这个问题..."}
data: {"type":"reasoning-delta","id":"reasoning_r01","delta":"需要考虑以下几个方面..."}
data: {"type":"reasoning-end","id":"reasoning_r01"}
data: {"type":"text-start","id":"text_xyz789"}
data: {"type":"text-delta","id":"text_xyz789","delta":"综合分析后,结论是..."}
data: {"type":"text-end","id":"text_xyz789"}
data: {"type":"finish-step"}
data: {"type":"finish"}
data: [DONE]
```
---
## 标准消息流顺序
```
start
└─ start-step
├─ [data-thinking-step × N] 思考步骤(可多次)
├─ [reasoning-start/delta/end] 推理过程(可选)
├─ [tool-input-start] 工具调用开始(可多次)
├─ [tool-input-available] 工具参数确认
├─ [tool-output-available] 工具结果
├─ [data-terminal-info] 终端提示(可多次)
├─ [source-url / source-document] 来源引用(可选)
├─ text-start
│ └─ text-delta × N 流式文本
└─ text-end
finish-step
finish
[DONE]
```