Files
fire-safety-ymd/CONTEXT.md
T
2026-09-06 01:40:15 +08:00

102 lines
14 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.
# fire-safety-ymd 项目上下文
## 1. 项目目标
`fire-safety-ymd` 是一个面向森林防火场景的 Go 后端项目。目标调用链是:用户在业务应用中提问,后端维护会话并调用既有 SuperAgent 平台;SuperAgent 在需要业务事实时调用本项目提供的 MCP 工具;本项目从受控的 PostgreSQL/PostGIS 数据源查询消防资源和风险区域,再将结构化结果返回给 Agent 组织回答或辅助方案。
项目不自行训练或实现通用 Agent,也不允许大模型直接访问数据库。
用户对话的 Chat 凭证默认要求至少 32 个可打印 ASCII 字符。若已经交付的旧客户端只能继续发送短凭证,必须在受控测试/迁移窗口显式开启 `FIRE_SAFETY_CHAT_ALLOW_LEGACY_SHORT_TOKEN`;该开关默认关闭,新环境不得开启,轮换后恢复关闭。无论开关如何,Chat 凭证仍须非空、不超过 4096 字节且仅含 ASCII `0x21-0x7e`(无空格、控制字符或 Unicode);该兼容范围只适用于 Chat 原生 Bearer 与兼容入口 `xtoken`,MCP Token 仍要求至少 32 个字符,三种凭证必须不同。
## 2. 当前系统组成
| 路径或系统 | 当前职责 | 当前状态 |
| --- | --- | --- |
| `cmd/server` | Go 服务进程入口 | 已建立 |
| `internal/app` | 应用装配、readiness 和 HTTP 生命周期 | 已建立;按开关装配原生/兼容 Chat、可选 `/chat` 测试页面、SuperAgent 和 MCP/PostGIS |
| `internal/config` | 环境配置入口 | 已包含 HTTP、SuperAgent(含默认关闭的 IncludeTrace)、Chat 兼容 App ID/页面开关/legacy 短凭证开关、MCP 与 PostGIS 配置校验和凭证分离门禁 |
| `internal/handler` | HTTP/MCP 入站协议层 | `GET /health` 已启用;默认关闭的原生 `/api/chat`、可选 DashScope 风格 `completion`、可选 `/chat` 页面/资源和 `/mcp` 已实现 |
| `internal/service` | 业务用例编排 | 已实现单进程聊天会话/并发 Run 控制,以及地名候选、有界空间查询、可信数据库全范围/镇街白名单和结果语义 |
| `internal/domain` | 森林防火领域模型与规则 | 已包含点位、水源、候选设施、通道、队伍和风险区模型 |
| `internal/repository` | PostgreSQL/PostGIS 持久化适配 | 已实现 pgxpool、只读固定 SQL 与 schema/SRID readiness;实库 SRID 元数据、严格 readiness 和 7 个工具真实查询已验证 |
| `cmd/postgis-srid-migrate` | 显式 SRID 元数据迁移 | 已执行;默认只读预检,写入需独立迁移凭证和明确 CRS 确认 |
| `internal/integration/superagent` | SuperAgent Open API 出站适配 | 已实现并通过模拟 Provider 测试;`FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE` 默认 false,支持无 Trace 严格完成判定 |
| `cmd/superagent-probe` | 无业务数据的显式连通性探针 | 已实现;需要项目专属测试配置 |
| `cmd/postgis-probe` | 不读取业务行的 PostGIS readiness 探针 | 已实现;需要只读数据库配置 |
| `Dockerfile` / `compose.yaml` | 测试环境容器构建与单实例进程托管 | 已建立;容器内监听 8080,只发布宿主机回环端口 16587;页面开关默认关闭;目标机镜像已构建,容器启动和 health 待重建后验证 |
| `pkg` | 可被外部 module 复用的稳定 Go API | 当前为空 |
| `docs/import` | 字段/表映射、通用模板和本地数据库样例 | 样例 SQL 含受限数据并被 Git 忽略,不会执行 |
| SuperAgent | 对话理解、工具选择和答案组织 | 对话客户端按仓库内 2026-07-12 协议基线实现;默认请求 `include_trace=false`,无 Trace 只隐藏工具/步骤轨迹,不禁止 Agent 调用 MCP;同一 Key 的 `include_trace=true` 曾因应用策略关闭返回 403 `open_agent_trace_disabled`,改为 false 返回 HTTP 200;同一 SuperAgent 中 `th-hotel-simple-superagent` 已稳定启用/调用,证明其兼容档案不依赖版本配置;公网消防 `/mcp` 已收到一次请求并到达 Go,但消防兼容档案待部署验证,公网消防链路尚未完成完整多工具对话 |
| PostgreSQL/PostGIS | 消防空间业务事实的预期权威来源 | 8 表共 4,055 条记录;4,048 条非空几何已标记 EPSG:4326,严格 readiness 与本地真实工具冒烟均通过;35 条无效几何按当前策略排除并告警 |
## 3. 技术栈
### 已采用
- Go module:`fire-safety-ymd`(临时 module 名)。
- 本地工具链:Go `1.26.6`。
- HTTP:Go 标准库 `net/http`。
- 测试:Go 标准库 `testing`、`httptest`。
- 配置:环境变量;支持 HTTP、SuperAgent、Chat、MCP 与 PostGIS 配置,并默认关闭 Chat 及两个外部方向;SuperAgent Trace 请求默认关闭,可通过 `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE` 显式开启。
- Chat API:标准库 HTTP/SSE;原生 `/api/chat` 使用静态联调 Bearer,可选 `completion` 兼容入口使用同一信任方向的 `xtoken`;默认要求 Chat 凭证至少 32 个可打印 ASCII 字符,受控迁移时可通过默认关闭的 `FIRE_SAFETY_CHAT_ALLOW_LEGACY_SHORT_TOKEN` 兼容已交付短凭证;两者共享精确 Origin、严格 JSON、总超时、有界单进程会话和同会话并发冲突。兼容入口只在严格成功后发送正文。可选测试页面由 `FIRE_SAFETY_CHAT_PAGE_ENABLED` 控制,提供 `/chat`(开启时 308 到 `/chat/`)、`/chat/`、`/chat/app.css` 和 `/chat/app.js`;页面只在内存中使用用户手动输入的 `xtoken`,复用兼容 SSE 的 `session_id`,不嵌入或持久化 Token。
- SuperAgent:标准库 HTTP/SSE 客户端,分离 Session 创建和消息发送,支持按配置选择 Trace/无 Trace、严格完成判定与既有 Run 断流恢复。无 Trace 要求最终 AI 消息 `finish_reason=stop`、非空顶层 `message.final` 和顶层 `end`;Trace 模式额外要求 `run.completed(status=success)`。
- MCP:标准库 HTTP/JSON-RPC,服务端固定返回版本标识 `2025-06-18`,同步 JSON 响应,独立 Bearer 和 7 个只读工具;按已稳定接通的 `th-hotel-simple-superagent` 兼容档案处理,initialize 中的 `protocolVersion` 和后续 `MCP-Protocol-Version` Header 都不作为版本拒绝门禁,SuperAgent 无需也不能配置版本。固定返回该版本不表示支持任意其他版本,也不是追求最新协议。地名工具只搜索现有业务记录并要求用户确认候选。
- PostgreSQL:`github.com/jackc/pgx/v5 v5.10.0` 原生连接池;连接默认只读并设置 statement timeout。
- PostGIS:`ST_Covers`、`ST_DWithin`、`ST_Distance` 和 `ST_ClosestPoint`;只在实库确认 EPSG:4326 后启用。
- 部署:多阶段 Docker 镜像与单实例 Compose;Secret 通过未提交的 `.env` 在运行时注入,容器内 8080 只发布到宿主机 `127.0.0.1:16587`,由宿主机 Nginx 终止 TLS。Docker build 的 Go module proxy 可按环境覆盖,但默认使用官方代理、保留 checksum 校验,且所选构建代理在运行容器内强制清空。Nginx 示例精确反代 `/chat`、`/chat/`、页面 CSS/JavaScript、兼容 completion 和 `/mcp`;页面仍由 Go 开关控制。
### 计划但尚未接入或确认
- PostgreSQL/PostGIS 的适用索引和生产查询计划验证。
- SuperAgent 到 `/mcp` 的 proven-profile 兼容实现部署后重测,以及 TLS、网络白名单、Token 和完整工具调用链联调;版本 Header 不需要配置,也不是验收门禁。无 Trace 模式已具备本地模拟验证,公网完整 MCP 对话仍待确认。
- 任意地址/山名的外部地理编码、别名词典和大数据量地名索引。
- 用户聊天的真实身份认证、动态授权、共享/持久会话、主动取消和限流策略;首版默认关闭的静态 Bearer + 内存会话 API 以及默认关闭的静态测试页面已实现。legacy 短凭证仅限受控测试/迁移窗口,轮换后须关闭兼容开关。
- 最终用户鉴权、动态角色/区域或租户隔离、持久审计与完整可观测性方案。
- 正式前端身份接入;当前 `/chat` 页面仅用于受控测试,现有第三方客户端仅通过受限 DashScope 风格协议适配。Trace 是否开放由 SuperAgent 外部应用策略决定,不能仅凭客户端参数绕过。
## 4. 已知业务数据范围
当前资料描述 8 类森林防火空间资源:
| 资源 | 预期 PostgreSQL 表 | 预期几何形态 |
| --- | --- | --- |
| 蓄水池 | `st_2_xianyouxushuichiguan` | 点 |
| 防火通道 | `st_2_xianyoufanghuotongdao` | 线;样例为 MultiLineString,原始数据混合二维与 Z 维度 |
| 水源地 | `st_2_mpslfh_t_slfh_syd` | 点 |
| 林区工矿企业 | `st_2_linqugongkuangqiye` | 面 |
| 防火网格 | `st_2_fanghuowangge` | 面 |
| 防火瞭望哨 | `st_2_fanghuoliaowangshao` | 点 |
| 防火检查站 | `st_2_fanghuojianchazhan` | 点 |
| 墓地坟区 | `st_2_mudifenqu_mian` | 面 |
仓库中的两份 Excel 是字段与数据表映射资料,不是可查询的业务数据库。`docs/import/db-samples/*.sql` 是含敏感字段的本地参考输入,已被 Git 忽略且不得由开发 Agent 执行。用户在 2026-09-04 的现场导入中确认,防火通道原始数据同时包含二维和带 Z 维度的几何:`geometry(GEOMETRY)` 导入到第 256 条附近时报 `Geometry has Z dimension but column does not`,将该原始列改为不限定 typmod 的 `geometry` 后重导成功。2026-09-05 的初始只读 audit 覆盖 8 表共 4,055 条记录:4,048 条非空几何均标记 SRID 0,7 条为空,35 条面几何无效,仅防火网格表存在 GiST 几何索引;类型和经纬度数值范围符合预期。数据提供方随后确认 8 表源数据均为 EPSG:4326、无坐标偏移,并允许 MCP 二维计算忽略 Z,但原始 Z 仍须保留。项目使用独立 `admin` 迁移凭证在单个事务中补齐了 4,048 条几何的 SRID 4326 元数据:7 张二维表改为 `geometry(Geometry,4326)`,防火通道保持裸 `geometry` 且 2 条 Z 几何未变;迁移前后无 SRID WKB 指纹、行数、类型、有效性和维度一致,随后只读严格 readiness 通过。无效几何仍不自动修复,查询排除并明确告警。
## 5. 目标职责边界
- 用户侧应用:采集用户输入并展示结果;仓库提供默认关闭的 `/chat` 受控测试页面,正式用户端形态仍待确认。
- 本 Go 服务:鉴权上下文、会话转发、MCP 工具、数据查询、权限、安全和审计。
- SuperAgent:理解自然语言、决定是否调用工具、组织自然语言结果;页面和第三方客户端都通过同一兼容 completion SSE 入口发起对话。上游无 Trace 仅减少轨迹返回,不改变 Agent 选择或调用 MCP 的能力;是否调用成功需看 MCP 日志和结果。
- MCP 工具:提供固定的森林防火领域查询,不开放任意 SQL 或跨权限访问。
- PostgreSQL/PostGIS:保存和计算可信空间事实;资源是否可用仍取决于明确状态和数据时效。
## 6. 当前开发方向与非目标
当前阶段已有可运行、可测试、文档自解释的 Go 基线、SuperAgent Open API Adapter、默认关闭的原生用户对话 API、可选 DashScope 风格兼容入口、默认关闭的 `/chat` 测试页面,以及空间只读 MCP/PostGIS 实现。对话入口使用独立静态联调凭证和单进程内存会话;页面不嵌入或持久化 Token,使用者手动输入 `xtoken` 并复用同页面内存中的 `session_id`。SuperAgent Open API 默认通过 `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE=false` 使用无 Trace 流:严格成功要求最终 AI 消息 `finish_reason=stop`、非空顶层 `message.final` 和顶层 `end`;无 Trace 不代表 Agent 不能调用 MCP。若设置 true,则仍要求 `run.completed(status=success)`,且外部应用策略必须允许 Trace。当前同一 Key 的 true 请求因 `open_agent_trace_disabled` 返回 403;false 模式下真实探针和本地兼容 Chat SSE 均已严格成功。仓库已有多阶段 Docker/Compose 基线以及精确路径、无 Secret 的 Nginx HTTPS 反向代理示例,模板公开反代 `/chat`、`/chat/`、`/chat/app.css`、`/chat/app.js`、兼容 completion 和 `/mcp`,页面是否可用由 Go 开关控制。目标机镜像构建和 Nginx 语法检查已由现场截图证明通过,容器稳定运行、页面公网响应和 TLS 实际状态仍待验证。2026-09-05 22:35 的现场日志已证明公网 MCP 完成 `fire_safety_search_place_candidates` 一次成功调用(此前的 initialize/notifications/tools/list 也有日志),但其余消防工具和完整多工具链仍待验收。同一 SuperAgent 中 `th-hotel-simple-superagent` 已稳定启用/调用,为本项目提供了 proven-profile 兼容参照,但不能替代消防 endpoint 的完整验收。部署后通过 `direct_success` 或 `compatibility_success` 日志分类确认实际请求,不记录客户端原始版本值。MCP 默认关闭,实库严格 readiness 和全部 7 个工具的本地真实查询已通过。下一阶段先在测试服务器重建包含无 Trace 配置的服务,验证页面开关、静态资源、兼容 Chat 首轮/多轮和公网 TLS,再完成真实消防 Profile 的完整 MCP 工具链联调。
本阶段不实现:
- 面向真实用户的认证、动态权限、持久会话和已验证生产能力;当前对话 API 与 `/chat` 页面只用于受控联调。
- PostgreSQL/PostGIS 数据导入或索引 DDL;SRID 元数据迁移是已经显式执行的一次受控运维操作,不是应用运行时行为。
- 用户登录、权限模型、审计存储和生产部署。
- 面向真实火情的自动决策或路径规划。
- 队伍实时定位、集结点管理和资源调度。
## 7. 新 Agent 阅读顺序
1. `AGENTS.md`
2. `CONTEXT.md`
3. `PROJECT_STATE.md`
4. `docs/project/README.md`
5. `docs/project/ai-nses-project-overlay.md`
6. 与任务相关的后端或安全规范