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

7.6 KiB
Raw Blame History

LaodingBot WebUI 开发技术与需求说明

版本: v1.0
目标读者: 下一个执行 WebUI 开发任务的 LLM / 前端工程师
依据: 当前后端已落地代码(internal/transport/webui/bot.gocmd/bot/main.gointernal/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_iduser_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:

{
  "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:
{
  "text": "请总结我上传的文档",
  "session_id": "sess_xxx",
  "user_id": "user_xxx"
}

响应 200:

{
  "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_iduser_id
  5. 上传结果区(展示 file_id、文件名、大小、时间)
  6. 错误提示区(接口失败、文件超限、网络错误)

4.2 会话策略

必须:

  • 首次进入页面时生成并持久化 session_iduser_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. 前端状态模型(建议)

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 上传

curl -X POST http://localhost:8090/api/upload \
  -F "session_id=sess_demo" \
  -F "user_id=user_demo" \
  -F "file=@./demo.pdf"

6.2 聊天

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_iduser_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:

请基于 `doc/WebUI开发技术与需求说明.md` 实现 WebUI 前端,严格对接现有后端接口:
- POST /api/upload
- POST /api/chat

必须满足:
1) 纯文本聊天
2) 独立文档上传
3) 上传后同会话提问可利用文档上下文
4) session_id/user_id 持久化
5) 完整错误处理和可视化反馈

不允许修改后端接口语义;若需新增接口,请先输出变更提案,不直接改。