# AI智能巡检与故障归因平台 阶段1落地方案 ## 1. 目标重述 阶段 1 只做一条可验证主线闭环: 1. 外网巡检按周期执行。 2. 发现异常后固化截图和失败说明。 3. 按任务绑定的服务模板补采内网上下文。 4. 通过安全推送接口入库上下文。 5. 调用 AI 诊断得到结构化归因结果。 6. 在异常详情页和日报页完成交付。 不做多租户,不做自动修复,不做复杂大屏,不做脚本自动生成。 ## 2. 建议技术方案 为降低阶段 1 复杂度,建议采用单体应用 + 轻量 agent 的分层结构。 ### 2.1 技术栈 - 前端:`Next.js 15 + React + TypeScript + Ant Design` - 后端:`NestJS + TypeScript` - 数据库:`PostgreSQL` - 缓存/任务队列:`Redis + BullMQ` - 浏览器巡检:`Playwright` - ORM:`TypeORM` - 定时调度:`BullMQ repeatable jobs` 或 `Nest Schedule` - AI 调用:统一封装 `LLMProvider` - 日志:`Pino` - 鉴权:阶段 1 先做本地账号密码 + JWT Session 原因: - `Playwright` 适合实现步骤脚本、截图、状态码、DOM 检查。 - `NestJS + TypeORM` 便于按数据库方言切换到 `MariaDB / PostgreSQL兼容模式`。 - `BullMQ` 既能做定时调度,也能承接执行任务、诊断任务,避免后续重构。 - 单体后端能快速闭环,后续再拆服务。 ## 3. 系统架构 建议拆成 4 个运行单元: ### 3.1 Web 应用 职责: - 登录 - 首页总览 - 任务管理 - 模板管理 - 巡检记录列表 - 异常详情 - 日报页 ### 3.2 Platform API 职责: - 提供 `API-01` 到 `API-08` - 任务 CRUD - 调度注册 - 记录落库 - 诊断编排 - 报表聚合 ### 3.3 Inspector Worker 职责: - 消费巡检任务 - 使用 `Playwright` 执行步骤脚本 - 做异常检测 - 保存截图与执行日志 - 触发上下文采集 ### 3.4 Context Agent 职责: - 从模板生成指标查询和探测请求 - 汇总 `metrics / probes / logs` - 进行签名与加密 - 调用 `/agent/context/push` 阶段 1 可以先把 `Context Agent` 做成同仓库里的独立 Node 进程,既保留“内外网边界”的设计,又不把真实内网接入复杂化。 ## 4. 核心模块拆分 后端建议按模块组织: - `auth` - `dashboard` - `tasks` - `runs` - `scheduler` - `inspector` - `templates` - `context` - `security-push` - `diagnosis` - `reports` - `storage` 每个模块尽量遵循: - `controller`: 对外 API - `service`: 业务逻辑 - `repository`: 数据访问 - `dto`: 入参与出参校验 - `entity/model`: TypeORM Entity 或领域模型 ## 5. 关键数据流 ### 5.1 巡检执行链路 1. 创建任务 `inspection_task` 2. 调度器根据 `cron_expr` 投递执行任务 3. Worker 创建 `inspection_run`,状态为 `queued -> running` 4. Playwright 执行 `steps_json` 5. 检查状态码、关键元素、白屏 6. 成功则 `run_status=success` 7. 失败则保存截图、错误标签、失败说明 8. 触发上下文采集 9. 上下文 push 成功后触发诊断 10. 诊断完成后更新详情聚合数据 ### 5.2 AI 诊断链路 1. 读取 `inspection_run + context_payload` 2. 执行脱敏映射 3. 组装提示词模板 4. 调用模型,要求 JSON 输出 5. 校验字段完整性 6. 写入 `diagnosis_result` 7. 更新页面可见状态 ## 6. 数据库设计建议 在文档给出的 4 张核心表基础上,建议至少补齐以下表,避免后续状态无法闭环。 ### 6.1 inspection_task 保留文档字段,并补充: - `created_at` - `updated_at` - `created_by` - `last_run_at` ### 6.2 inspection_run 建议补充: - `status`:`queued/running/success/failed/partial` - `failure_reason` - `step_logs_json` - `watermarked_screenshots_json` - `context_status` - `diagnosis_status` 说明: 文档里同时出现了 `run_status` 和状态机中的 `queued/running/success/failed/partial`,实际落地时建议统一为 `status`,避免双状态冲突。 ### 6.3 context_payload 建议补充: - `id` - `task_id` - `run_id` - `payload_status`:`pending/accepted/rejected` - `encrypted_payload` - `signature` - `received_at` ### 6.4 diagnosis_result 建议补充: - `status`:`pending/success/failed` - `model_name` - `prompt_version` - `masked_context_json` - `raw_response` - `created_at` ### 6.5 probe_template 用于承接 P-04: - `id` - `service_key` - `template_name` - `probe_type`:`http/tcp` - `target` - `method` - `headers_json` - `timeout_ms` - `success_condition` - `threshold_json` ### 6.6 metric_template - `id` - `service_key` - `metric_name` - `promql` - `threshold_json` - `display_order` ### 6.7 daily_report - `id` - `report_date` - `report_text` - `items_json` - `created_at` ## 7. 步骤脚本设计 `steps_json` 不建议一开始支持自由脚本,阶段 1 应限制为声明式 DSL: ```json [ { "action": "goto", "url": "https://example.com", "timeoutMs": 10000 }, { "action": "waitForSelector", "selector": "input[name=q]", "timeoutMs": 5000 }, { "action": "input", "selector": "input[name=q]", "value": "test" }, { "action": "click", "selector": "button[type=submit]" }, { "action": "assertText", "selector": "body", "contains": "结果" } ] ``` 先只支持: - `goto` - `waitForSelector` - `click` - `input` - `assertText` - `assertVisible` - `sleep` - `screenshot` 这样可控、易验收,也符合文档“不得抢跑复杂能力”的原则。 ## 8. 异常检测策略 阶段 1 建议把异常检测收敛为 4 类: - `HTTP_4XX` - `HTTP_5XX` - `ELEMENT_MISSING` - `BLANK_PAGE` 判定逻辑: - HTTP:基于主请求状态码 - 关键元素缺失:`waitForSelector/assertVisible` 失败 - 白屏:`body.innerText` 长度过低且无核心元素 不要在阶段 1 加太多启发式规则,否则误报率和调试成本会上升。 ## 9. 安全推送落地方式 阶段 1 重点是“验签失败不能入库”和“链路可复现”。 建议: - 签名:`HMAC-SHA256(secret, trace_id + ts + payload_hash)` - 加密:阶段 1 可先使用 `AES-GCM` - 传输字段: - `encrypted_payload` - `sign` - `ts` - `trace_id` - 服务端校验: - 时间窗校验 - 签名校验 - 去重校验 如果当前阶段只是演示闭环,可以“真签名 + 真验签 + 简化加密实现”,但不要只做假字段。 ## 10. AI 归因设计 ### 10.1 输入结构 输入模型的上下文建议固定为: - 异常摘要 - 页面证据摘要 - 指标摘要 - 探测摘要 - 日志摘要 - 脱敏映射规则版本 ### 10.2 输出结构 强制模型输出: ```json { "root_cause": "可能为上游网关异常", "confidence": 0.82, "evidence_points": [ "外网访问返回 502", "应用存活探测失败", "CPU 正常但接口探活超时" ], "next_actions": [ "检查网关 upstream 配置", "核对应用实例健康状态" ], "report_text": "本次故障初步判断为..." } ``` ### 10.3 保守策略 - 模型输出先做 JSON Schema 校验 - 校验失败则标记 `diagnosis_result.status=failed` - 页面只展示“诊断失败”,不展示拼接伪结论 ## 11. 前端页面落地建议 ### 11.1 首页 P-02 组件: - 今日任务数 - 今日异常数 - 最近一次诊断结果 - 最近异常列表 阶段 1 重点是信息可读,不追求大屏。 ### 11.2 任务管理 P-03 能力: - 列表 - 新建/编辑弹窗 - 启停切换 - 手动执行 ### 11.3 模板配置 P-04 分成两个 Tab: - 指标模板 - 探测模板 ### 11.4 巡检记录 P-05 字段: - 任务名 - 开始时间 - 执行耗时 - 状态 - 异常标签 - trace_id ### 11.5 异常详情 P-06 建议三栏或纵向三块: 1. 外网证据 2. 内网上下文 3. AI 诊断 默认偏“技术排障视角”,因为这是阶段 1 的核心价值;后续可再补“领导汇报摘要卡片”。 ### 11.6 日报页 P-07 输出两部分: - 结构化表格 - 可复制自然语言摘要 这样兼顾技术复盘和领导汇报。 ## 12. API 与内部服务映射 ### 12.1 对外 API - `POST /api/tasks` - `GET /api/tasks` - `POST /api/runs/execute/:taskId` - `GET /api/runs` - `GET /api/runs/:runId` - `POST /agent/context/push` - `POST /api/diagnosis/run` - `GET /api/reports/daily` ### 12.2 建议补充 API 为了支撑页面,建议增加: - `PUT /api/tasks/:id` - `PATCH /api/tasks/:id/status` - `GET /api/templates/metrics` - `POST /api/templates/metrics` - `GET /api/templates/probes` - `POST /api/templates/probes` 这些属于页面所需的补全接口,不算越界扩展。 ## 13. 开发顺序建议 严格按文档的 S1-S6 推进,但工程上建议拆成下面 10 个开发包。 ### 包 1:工程骨架 - 前端、后端、worker 初始化 - TypeORM Entity 与数据库初始化脚本 - 本地开发环境 - 登录页、首页空态 ### 包 2:任务管理 - 任务表 - 任务 CRUD - 页面表单 - 启停状态 ### 包 3:调度与执行记录 - cron 注册 - 手动执行 - `inspection_run` 状态流转 - 列表查询 ### 包 4:Playwright 巡检 - DSL 解析 - 页面执行 - 日志记录 - 成功/失败收口 ### 包 5:异常证据 - 截图 - 水印 - 失败原因 - 详情页证据区 ### 包 6:模板与上下文补证据 - 指标模板 - 探测模板 - 模拟日志 - payload 打包 ### 包 7:安全推送 - 加密签名 - push 接口 - 验签入库 ### 包 8:AI 诊断 - 脱敏 - 提示词模板 - JSON 校验 - 结果落库和展示 ### 包 9:日报 - 按日聚合 - 固定结构文本 - 复制导出 ### 包 10:验收与样例数据 - 构造 502 页面 - 构造成功站点 - 预置任务模板 - 验收脚本 ## 14. 里程碑建议 如果 1 人主开发,建议按 3 周压缩版推进: - 第 1 周:S1 + S2 - 第 2 周:S3 + S4 - 第 3 周:S5 + S6 + 验收修复 如果 2 到 3 人并行: - A 负责前端页面与联调 - B 负责后端 API / 数据库 / 调度 - C 负责 Playwright / context agent / AI 诊断 ## 15. 当前最合理的保守实现 结合文档的“先主线、后增强”,我建议阶段 1 先这样收敛: - 只支持 1 个示例站点 - 只支持 1 个服务标识 `service_key` - 只支持 HTTP 探测 + 模拟 Prometheus 返回 - 日志先使用样例文本,不接真实日志平台 - AI 先使用单一诊断模板,不做多模型切换 - 详情页默认技术视角 - 日报同时输出表格摘要和自然语言摘要 ## 16. 我对文档的几个架构修正建议 ### 16.1 统一状态字段 文档里 `inspection_run.run_status` 与状态机表有轻微冲突,建议统一成: - `status`: `queued/running/success/failed/partial` ### 16.2 明确任务与模板关系 建议: - 一个任务绑定一个 `service_key` - 一个 `service_key` 可以关联多条指标模板和多条探测模板 这样比“任务直接挂一堆模板”更稳。 ### 16.3 详情页以 trace_id 聚合 不要只靠 `run_id` 聚合,因为后续上下文推送和诊断结果天然更适合用 `trace_id` 串联。 ### 16.4 日报生成做成可重放 日报不要只做实时拼接,建议落 `daily_report` 表,便于复查与导出。 ## 17. 下一步建议 如果直接开工,最推荐的顺序是: 1. 先搭 `NestJS + Next.js + PostgreSQL + Redis + Playwright` 基础工程。 2. 先完成 `S1-S2`,让任务创建、调度、手动执行、记录落库跑通。 3. 再接 `S3-S4`,把异常证据和上下文补证据补齐。 4. 最后接 `S5-S6`,把 AI 归因与日报交付收口。 这会是当前文档下最稳、最省返工的一条实现路径。