初始化第一版
This commit is contained in:
commit
8a6c31c14d
83 files changed
+14302
No files matched your search
@@ -0,0 +1,59 @@
|
||||
# 演练方案证据查询流程
|
||||
|
||||
## 目标
|
||||
|
||||
本流程说明 SuperAgent 如何从用户确认的地名候选或演练点坐标取得结构化事实,再组织“候选方案”。MCP 返回证据和限制,不自动选择地点或作出现场指挥决定。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant SA as SuperAgent
|
||||
participant MCP as fire-safety-ymd MCP
|
||||
participant PG as PostGIS
|
||||
|
||||
U->>SA: 提供地名或演练点坐标与分析目标
|
||||
alt 只提供地名
|
||||
SA->>MCP: search_place_candidates
|
||||
MCP->>PG: 在获授权业务记录中做有界名称匹配
|
||||
PG-->>MCP: 记录点/代表点候选
|
||||
MCP-->>SA: 候选 + 匹配类型 + location_kind + warning
|
||||
SA-->>U: 展示候选并请求确认
|
||||
U->>SA: 确认一个候选坐标或改为地图选点
|
||||
else 已提供明确坐标
|
||||
SA->>SA: 校验 WGS84 坐标格式
|
||||
end
|
||||
SA->>MCP: resolve_incident_context
|
||||
MCP->>PG: 查询覆盖网格(可信数据库全范围或镇街白名单内)
|
||||
PG-->>MCP: 网格事实
|
||||
MCP-->>SA: 网格 + 数据限制
|
||||
par 候选资源
|
||||
SA->>MCP: find_nearby_water_sources
|
||||
SA->>MCP: find_command_post_candidates
|
||||
SA->>MCP: list_nearby_access_lines
|
||||
and 责任与风险
|
||||
SA->>MCP: get_responsible_units
|
||||
SA->>MCP: find_nearby_risk_areas
|
||||
end
|
||||
MCP-->>SA: 结构化候选、来源、距离、warning
|
||||
SA-->>U: 区分数据库事实、未知项和需现场确认的候选方案
|
||||
```
|
||||
|
||||
## 对原始四类问题的支持度
|
||||
|
||||
| 问题 | 当前输出 | 结论边界 |
|
||||
| --- | --- | --- |
|
||||
| 指挥部设置到哪个 | 检查站/瞭望哨空间候选 | 不能自动定点;需核验安全、上风向、通信、容量和可达性 |
|
||||
| 水源地在哪里 | 水源地/蓄水池坐标、距离、容量和源状态(有值时) | 不能宣称当前有水、可取水或道路可达 |
|
||||
| 上山路线怎么规划 | 附近防火通道及最近接入点 | 当前不支持路线;缺少拓扑、坡度、宽度、路面、车辆限制、实时封路、火势和天气 |
|
||||
| 各队伍在哪里集结 | 覆盖网格记录的责任中队名称 | 当前不支持实时位置或集结点;缺少正式集结点、队伍位置、战备和装备数据 |
|
||||
|
||||
## Agent 回答要求
|
||||
|
||||
- 明确标注“数据库事实”“基于距离的候选”“当前数据不支持”和“必须现场确认”。
|
||||
- 只有地名时先调用地名候选工具;零结果时请用户补充名称或地图选点,多结果时列出候选,禁止静默选择第一条。
|
||||
- 所有空间工具都会排除无效几何;收到 `source_records_with_invalid_geometries_are_excluded` 时,零结果只能表述为“有效记录中未找到”,不能断言数据库不存在相关资源或责任区域。
|
||||
- `location_kind=representative_point` 只帮助识别线面记录,不得未经确认直接用于后续距离分析;记录点同样应回显名称和位置供用户确认。
|
||||
- 无结果时报告 `no_results`,不得自行补造附近资源。
|
||||
- 工具失败、超时或权限范围外时,不使用模型常识替代数据库事实。
|
||||
- 不把联系人、电话或内部物理表名转述给普通用户。
|
||||
- 涉及真实火情时,AI 结果只作辅助,不替代报警、撤离和现场指挥。
|
||||
@@ -0,0 +1,83 @@
|
||||
# 用户对话 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)。
|
||||
Reference in new issue
Block a user