Files
LaodingBot/doc/WebUI开发技术与需求说明.md

306 lines
7.6 KiB
Markdown
Raw 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.

# LaodingBot WebUI 开发技术与需求说明
> 版本: v1.0
> 目标读者: 下一个执行 WebUI 开发任务的 LLM / 前端工程师
> 依据: 当前后端已落地代码(`internal/transport/webui/bot.go`、`cmd/bot/main.go`、`internal/agent/orchestrator.go`
---
## 1. 文档目标与范围
本说明用于指导“仅 WebUI 页面层/前端层”的开发,确保严格对接当前 LaodingBot 已开放的 WebUI 后端能力。
本期范围:
- 支持纯文本对话
- 支持独立文档上传(上传后立即返回 `file_id`
- 支持“先上传文档,再发送文本提问”的两阶段交互
非本期范围:
- 不改动后端接口语义
- 不引入新的后端路由
- 不实现复杂权限系统(当前后端无鉴权)
- 不实现流式输出(当前为一次性响应)
---
## 2. 当前后端能力总览
### 2.1 消息通道
后端已支持 `MESSAGE_CHANNEL=webui`,入口在 `cmd/bot/main.go`
当通道为 `webui` 时:
- 启动 HTTP 服务
- 暴露两个接口:
- `POST /api/upload`
- `POST /api/chat`
### 2.2 运行配置
关键环境变量(`configs/env.sample`:
- `MESSAGE_CHANNEL=webui`
- `WEBUI_LISTEN_ADDR=:8090`
- `WEBUI_MAX_UPLOAD_MB=20`
- `LLM_*` 相关配置(含文件模型切换)
### 2.3 文件上下文机制(非常关键)
当前后端使用 `chat_id + user_id` 作为会话键缓存 `file_id`:
- 上传接口会把文件上传到 LLM并把 `file_id` 缓存到该键
- 后续 `chat` 接口只要带同一组 `session_id`/`user_id`,就会自动消费缓存文件上下文
结论:
- 前端必须稳定维护并复用 `session_id``user_id`
- 两者变化会导致上传文件上下文丢失(从后端视角是新会话)
---
## 3. 后端 API 契约(以代码为准)
## 3.1 `POST /api/upload`
用途:
- 独立上传文档
- 后端立即调用 LLM 文件上传并返回 `file_id`
- 同时缓存到当前会话,供下一次聊天使用
请求:
- Method: `POST`
- Content-Type: `multipart/form-data`
- Form 字段:
- `file` (required)
- `session_id` (optional建议前端始终传)
- `user_id` (optional建议前端始终传)
响应 `200`:
```json
{
"file_id": "file-xxx",
"file_ids": ["file-xxx"],
"file_name": "report.pdf",
"mime_type": "application/pdf",
"size_bytes": 12345,
"session_id": "sess_xxx",
"user_id": "user_xxx"
}
```
错误响应:
- `400`:
- `{"error":"file is required"}`
- `{"error":"invalid multipart form"}`
- `{"error":"invalid file name"}`
- `{"error":"empty file"}`
- `{"error":"read file failed"}`
- `413`:
- `{"error":"file too large"}`
- `500`:
- `{"error":"upload failed"}`
- `{"error":"upload succeeded but file_id is empty"}`
---
## 3.2 `POST /api/chat`
用途:
- 发送纯文本消息
- 若该 `session_id + user_id` 下已有上传文件,会自动携带文件上下文进行问答
请求:
- Method: `POST`
- Content-Type: `application/json`
- Body:
```json
{
"text": "请总结我上传的文档",
"session_id": "sess_xxx",
"user_id": "user_xxx"
}
```
响应 `200`:
```json
{
"reply": "...",
"session_id": "sess_xxx",
"user_id": "user_xxx"
}
```
错误响应:
- `400`:
- `{"error":"content-type must be application/json"}`
- `{"error":"invalid json body"}`
- `{"error":"text is required"}`
- `405`:
- `{"error":"method not allowed"}`
- `500`:
- `{"error":"chat failed"}`
---
## 4. WebUI 功能需求(给前端实现)
### 4.1 页面最小能力
必须实现:
1. 聊天消息列表
2. 文本输入框 + 发送按钮
3. 文件选择器 + 上传按钮
4. 当前会话标识展示(`session_id``user_id`
5. 上传结果区(展示 `file_id`、文件名、大小、时间)
6. 错误提示区(接口失败、文件超限、网络错误)
### 4.2 会话策略
必须:
- 首次进入页面时生成并持久化 `session_id``user_id`(例如 LocalStorage
- 每次请求都携带这两个字段
- 提供“重置会话”操作(清空本地 session/user 并重新生成)
建议 ID 规则:
- `session_id`: `sess_<uuid>`
- `user_id`: `user_<uuid>`
### 4.3 文件上传交互
必须:
- 文件选择后显示基本信息(名称、大小、类型)
- 点击上传后调用 `/api/upload`
- 上传成功后将返回的 `file_id` 加入“已上传文件列表”
- 上传失败时给出明确错误提示
建议:
- 前端先做大小校验(默认 20MB可配置
- 上传中禁用重复点击
### 4.4 聊天交互
必须:
- 发送前校验 `text` 非空
- 调用 `/api/chat`
- 成功后追加机器人消息
- 失败后展示错误并保留用户输入
建议:
- 支持回车发送Shift+Enter 换行)
- 增加“请求中”状态,避免并发多发
---
## 5. 前端状态模型(建议)
```ts
type UploadedFile = {
fileId: string;
fileName: string;
mimeType: string;
sizeBytes: number;
uploadedAt: number;
};
type ChatMessage = {
id: string;
role: "user" | "assistant" | "system";
content: string;
createdAt: number;
status?: "sending" | "sent" | "failed";
};
type AppState = {
sessionId: string;
userId: string;
messages: ChatMessage[];
uploadedFiles: UploadedFile[];
uploading: boolean;
chatting: boolean;
lastError?: string;
};
```
状态约束:
- `uploading=true` 时不应再次触发上传
- `chatting=true` 时可选禁用发送(或允许排队)
- 任何失败都要更新 `lastError`
---
## 6. 接口调用示例
### 6.1 上传
```bash
curl -X POST http://localhost:8090/api/upload \
-F "session_id=sess_demo" \
-F "user_id=user_demo" \
-F "file=@./demo.pdf"
```
### 6.2 聊天
```bash
curl -X POST http://localhost:8090/api/chat \
-H "Content-Type: application/json" \
-d '{"text":"这份文档主要讲了什么?","session_id":"sess_demo","user_id":"user_demo"}'
```
---
## 7. 开发任务拆解(给下一个 LLM
1. 初始化 WebUI 工程(技术栈自选,建议 React + TypeScript
2. 实现全局状态管理(至少管理 session/user/messages/uploads
3. 实现 API Client 层:
- `uploadFile(formData)`
- `sendChat(payload)`
- 统一错误解析
4. 实现页面组件:
- `ChatPanel`
- `Composer`
- `UploadPanel`
- `SessionBadge`
5. 实现本地持久化:
- 启动时恢复 `session_id``user_id`
- 重置会话功能
6. 完成联调与自测。
---
## 8. 验收标准
必须全部满足:
1. 纯文本聊天可用(无文件也能正常回复)。
2. 文档上传可用,返回并展示 `file_id`
3. 上传后同会话提问能基于文档回答。
4. 刷新页面后会话 ID 不丢失(可继续提问)。
5. 文件超限、空消息、网络失败均有可见错误反馈。
6. 同一会话多文件上传后,后续问答仍可使用文件上下文。
---
## 9. 已知限制与后续建议
当前后端限制(前端需知晓):
- 无鉴权机制
- 无流式输出
- 上传 MIME 未做白名单限制
- 无会话文件列表接口(前端只能依赖本地记录)
后续建议(非本期必做):
1. 新增后端 `GET /api/session/files` 以便页面恢复历史上传列表。
2. 增加鉴权中间件Bearer Token/JWT
3. 增加流式聊天接口SSE/WebSocket
4. 增加上传文件类型白名单和病毒扫描。
---
## 10. 对下一个 LLM 的执行指令模板
可直接复制给下一个 LLM:
```text
请基于 `doc/WebUI开发技术与需求说明.md` 实现 WebUI 前端,严格对接现有后端接口:
- POST /api/upload
- POST /api/chat
必须满足:
1) 纯文本聊天
2) 独立文档上传
3) 上传后同会话提问可利用文档上下文
4) session_id/user_id 持久化
5) 完整错误处理和可视化反馈
不允许修改后端接口语义;若需新增接口,请先输出变更提案,不直接改。
```