92 lines
3.8 KiB
Markdown
92 lines
3.8 KiB
Markdown
# 前端对话组件(Chat Widget)
|
||
|
||
对应 EPIC #11「④ LLM 报警解释 / 交接班 / NL 查询」子任务 **#77**(0.5d):
|
||
驾驶舱/移动端**对话组件**及配套后端 API(标准库实现,无框架依赖)。
|
||
|
||
## 文件
|
||
|
||
```
|
||
web/chat/
|
||
├── chat_api.py 对话后端 API(http.server):场景分发 + 统一 JSON
|
||
├── chat_widget.html 前端对话组件(内联 HTML/CSS/JS,深色主题对齐驾驶舱)
|
||
├── assistant.html 增强版对话页(#133:引用溯源/路由分级/DLP 拦截反馈)
|
||
├── assistant.css 增强版样式
|
||
├── assistant.js 增强版逻辑(直连推理服务 /v1/chat/completions)
|
||
├── citations.json RAG 引用语料(scripts/build_citations.py 编译产物)
|
||
├── scripts/
|
||
│ └── build_citations.py 模板知识库文档 → 引用语料编译脚本
|
||
├── tests/
|
||
│ └── test_chat_api.py 场景分发 / 端点 / 错误处理测试
|
||
└── README.md
|
||
```
|
||
|
||
## 增强版对话页(issue #133 / PRD 5.4)
|
||
|
||
`assistant.html` 在 chat_widget 雏形上完善并直连已部署推理服务
|
||
(`http://39.101.182.167:30800`,OpenAI 兼容):
|
||
|
||
- **消息流 + 元信息**:每条回答带路由分级 / 模型 / 耗时;
|
||
- **RAG 引用溯源**(PRD 5.4 强制):`citations.json`(由
|
||
`python web/chat/scripts/build_citations.py` 从 `templates/*/rag-kb/documents/`
|
||
编译)关键词检索,回答下方列出「文档 + 章节 + 摘要」引用;未命中显式标注无引用;
|
||
- **路由分级提示**:镜像 `core/llm-gateway/router.py`——敏感/核心 → 本地
|
||
(数据不出厂),通用/脱敏 → 云端,DLP 命中 → 拦截(fail-closed);
|
||
- **DLP 拦截反馈**:镜像 `dlp.py` 的 `DLP_DEFAULT_RULES`(身份证/手机号/邮箱/
|
||
IPv4/访问密钥/密钥键值对/配方敏感词),命中即阻止外发并展示命中规则,
|
||
可选择「转本地模型处理」;
|
||
- **报警解释**(PRD 场景A):severity + 点位结构化输入 → 「原因 + 处置建议」,
|
||
P0 告警附「需值班长确认」提示(PRD 高利害人工确认);
|
||
- **交接班报告**(PRD 场景C):按 `handover_brief.ti.yaml` 章节模板
|
||
(生产概况/异常事项/安全注意事项/能耗/待办)生成,耗时展示(目标 ≤ 2 分钟)。
|
||
|
||
运行:`cd web/chat && python -m http.server 8082`,打开
|
||
`http://127.0.0.1:8082/assistant.html`(Chrome / Edge 最新两版)。
|
||
|
||
## 快速运行
|
||
|
||
```bash
|
||
# 启动对话 API 服务(默认 127.0.0.1:8080;runner 未注入时仅返回健康/页面)
|
||
python chat_api.py --host 127.0.0.1 --port 8080
|
||
```
|
||
|
||
浏览器打开 `http://127.0.0.1:8080/` 即见对话组件。
|
||
|
||
## API
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/` | 对话组件页面(chat_widget.html) |
|
||
| GET | `/api/health` | 健康检查 |
|
||
| POST | `/api/chat` | 对话接口(见下) |
|
||
|
||
`POST /api/chat` 请求体:
|
||
|
||
```json
|
||
{ "question": "氯气流量最近1小时趋势", "scenario": "nl_query", "confidence": 1.0 }
|
||
```
|
||
|
||
`scenario`:`alarm_explain`(报警解释)/ `shift_handover`(交接班摘要)/
|
||
`nl_query`(NL 查询,缺省);未知场景降级 `nl_query`。
|
||
|
||
响应(统一 JSON):
|
||
|
||
```json
|
||
{ "answer": "...", "route": "local", "answer_id": "...",
|
||
"scenario": "nl_query", "needs_human": false }
|
||
```
|
||
|
||
## 与场景层集成
|
||
|
||
`chat_api.dispatch(runner, request)` 按场景调用 runner 的
|
||
`explain_alarm / generate_handover / query_cockpit`(与
|
||
`templates/ti-cl4/llm-scenarios.TiScenarioRunner` 对接);
|
||
runner 可注入(`make_server(host, port, runner=...)`),便于联调与替换实现。
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
python -m unittest discover -s tests -p "test_*.py"
|
||
```
|
||
覆盖:三场景分发、空 question、未知场景降级、异常 → error JSON、
|
||
GET / 与 /api/health、POST /api/chat、非法 JSON 400、404。
|