# 企业内网运维场景：用 n8n 落地端到端 AI Workflow

- 原始文章：How to build your first end-to-end AI workflow in n8n
- 原文 URL：https://thenewstack.io/build-n8n-ai-workflow/
- 原始分享链接：https://share.google/PAFFeWyFg3tWfqcsS
- 上游总结路径：/home/lin/.hermes/projects/hermes-gsummary-workflow/runs/outputs/20260522-191154-How-to-build-your-first-end-to-end-AI-workflow-in-n8n-2212124-788521280-summary.md
- 补充参考：n8n 官方 Docker、自托管、Webhook、Structured Output Parser、Human-in-the-loop、Error Workflow 文档

## 0. 我把你的请求改写成了什么

你的原始请求是：把这篇文章提炼为一篇用于企业内网运维场景可落地的端到端 AI workflow，必要时自行搜索网络教程和官方文档。

我将它改写为更可执行的交付目标：

> 基于 n8n 端到端 AI workflow 文章，结合 n8n 官方文档，写一份企业内网运维团队可试点落地的教程。教程必须包含：最小架构、部署方式、安全边界、完整工作流节点设计、结构化 AI 输出、人工审批、异常处理、3 个可复制场景、样例输入/输出、验收标准、失败处理和 4 周试点计划。

改写点：

- 将“企业内网运维场景”收敛为“只读诊断 + 结构化建议 + 人工审批 + 审计归档”的安全试点，而不是一开始就让 AI 自动改生产。
- 将原文的“文章投稿工作流”迁移为“运维告警/变更/巡检工作流”。
- 补充 n8n 官方能力：Docker 自托管、Webhook、Structured Output Parser、Human-in-the-loop、Error Workflow。
- 明确第一阶段禁止自动执行生产写操作，所有高风险动作必须人工审批。

## 1. 核心结论

企业内网落地 AI workflow，不应该从“自动修复生产故障”开始，而应该从“自动收集上下文、生成结构化诊断、给出低风险建议、等待人类审批、留下审计记录”开始。

最小可落地版本是：

```text
监控/工单/人工表单
  -> n8n Webhook/Form Trigger
  -> 参数校验与资产信息补全
  -> 只读日志/指标/CMDB 查询
  -> 内网 LLM / AI Agent 结构化诊断
  -> JSON Schema 校验
  -> IF/Switch 风险分级
  -> 企业微信/Slack/Teams 人工审批
  -> 只读报告归档或低风险通知
  -> Error Workflow 统一告警
```

第一阶段的目标不是替代运维人员，而是把 20 分钟的信息收集和初步判断压缩到 1–3 分钟，并且输出可审计、可复核、可拒绝的建议。

## 2. 适用边界

适合先做：

- Kubernetes Pod 异常初诊断。
- 数据库慢查询/连接数异常初分析。
- 变更单上线前风险预审。
- 每日巡检报告生成。
- 告警聚合和重复告警归并。

暂时不要做：

- 自动重启生产服务。
- 自动执行 `kubectl delete`、数据库 DDL、批量变更、发布回滚。
- 让 AI 直接连接生产数据库写入数据。
- 让 AI 自由调用 shell 命令。
- 在没有审批和审计的情况下对外发通知或关闭工单。

## 3. 最小架构

```text
[告警源/工单系统/人工入口]
  - Prometheus Alertmanager
  - Zabbix / Grafana Alerting
  - 企业微信机器人回调
  - 运维门户表单
  - n8n Form Trigger / Webhook

        |
        v

[n8n 内网编排层]
  - Webhook 或 Form Trigger
  - IF / Switch / Set / Code 节点
  - HTTP Request 查询内部只读 API
  - AI Agent 节点
  - Structured Output Parser
  - Human-in-the-loop / Send and Wait
  - Error Workflow

        |
        v

[只读上下文源]
  - CMDB 只读 API
  - Loki / Elasticsearch 日志查询 API
  - Prometheus 查询 API
  - Kubernetes 只读诊断 API
  - Runbook Markdown 仓库或知识库

        |
        v

[内网模型服务]
  - Ollama / vLLM / LM Studio / 兼容 OpenAI API 的内部网关
  - 第一阶段优先本地或内网模型
  - 禁止把生产日志、客户信息、密钥发送到公网模型

        |
        v

[人工审批与归档]
  - 企业微信 / Slack / Teams
  - 工单系统
  - n8n execution log
  - JSONL 审计文件或内部审计 API
```

## 4. 部署 n8n：内网试点版

### 4.1 Docker 单机试点

n8n 官方推荐 Docker 作为多数自托管场景的安装方式。第一阶段可先用单机 Docker，绑定内网地址，不暴露公网。

```bash
mkdir -p /opt/n8n/local-files
cd /opt/n8n

docker volume create n8n_data

# 生成一个 32 位随机十六进制字符串作为 n8n 凭据加密密钥，并在内网密钥库中安全备份。
# openssl rand -hex 16

# 完全离线内网环境请先将镜像导入企业私有仓库，例如：registry.ops.intra/n8nio/n8n:stable
docker run -d \
  --name n8n \
  --restart unless-stopped \
  -p 127.0.0.1:5678:5678 \
  -e GENERIC_TIMEZONE="Asia/Shanghai" \
  -e TZ="Asia/Shanghai" \
  -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
  -e N8N_RUNNERS_ENABLED=true \
  -e N8N_ENCRYPTION_KEY="此处替换为生成的32位安全密钥" \
  -e WEBHOOK_URL="http://n8n.ops.intra.example.com/" \
  -v n8n_data:/home/node/.n8n \
  -v /opt/n8n/local-files:/files \
  docker.n8n.io/n8nio/n8n:stable
```

说明：

- `n8n_data` 保存 SQLite 数据库、凭证、workflow、加密相关文件。
- `N8N_ENCRYPTION_KEY` 必须固定并安全备份；容器重建、迁移 PostgreSQL 或恢复备份时都要使用同一个值，否则 n8n Credentials 中的密钥可能无法解密。
- `/files` 用于读写试点样例文件，不要挂载生产敏感目录。
- `WEBHOOK_URL` 应设置为内网可访问的反向代理地址。
- 如果需要给监控系统回调，使用内网 DNS + 反向代理，不建议用公网穿透。
- 完全离线环境不要依赖公网镜像地址；先通过 `docker save/load` 或企业 Harbor/Registry 分发镜像。

### 4.2 反向代理建议

用 Caddy、Nginx 或 Traefik 放在 n8n 前面，做：

- 内网 TLS。
- IP allowlist。
- SSO 或基础认证。
- 访问日志。
- 请求大小限制。

示例 Caddyfile：

```caddyfile
n8n.ops.intra.example.com {
    reverse_proxy 127.0.0.1:5678
    encode gzip

    @not_allowed not remote_ip 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
    respond @not_allowed "forbidden" 403
}
```

### 4.3 生产化前再考虑队列模式

n8n 队列模式需要 PostgreSQL + Redis + main/worker 分离。第一阶段不要过早上队列模式，除非已经出现并发执行瓶颈。

进入队列模式前至少确认：

- PostgreSQL 已替代 SQLite。
- 所有实例共享同一个 `N8N_ENCRYPTION_KEY`。
- Redis 高可用或至少可监控。
- Worker health check 已接入监控。
- 二进制数据不用本地文件系统共享，必要时使用对象存储。

## 5. 模型服务：内网优先，兼容 OpenAI API

第一阶段推荐部署一个内网 OpenAI-compatible 网关，让 n8n 只看到统一的 Chat Model 接口。

可选方案：

- Ollama：简单，适合单机试点和中文/英文通用任务。
- vLLM：适合 GPU 服务器和较高并发。
- LM Studio：适合个人验证，不建议作为团队生产服务。
- 企业已有模型网关：优先使用，便于审计和权限控制。

Ollama 示例：

```bash
# 在内网测试机安装 Ollama 后拉取模型
ollama pull qwen2.5:14b
ollama serve
```

如果使用 OpenAI-compatible 网关，n8n 侧配置：

```text
Base URL: http://llm-gateway.ops.intra.example.com/v1
API Key: 使用 n8n Credentials 保存，不写入节点文本
Model: qwen2.5-14b-instruct 或企业内部批准模型
```

安全要求：

- 不把公网 API Key 写在 workflow 节点里。
- 不把生产日志原文长期保存到模型提示词记录里。
- 先脱敏再进入模型：手机号、身份证、Token、Cookie、数据库密码、客户名称等必须掩码。
- 正则脱敏只能作为兜底；更可靠的做法是在 Loki LogQL、CMDB 查询参数、API 网关或日志采集侧先过滤敏感字段。
- 模型输出只能作为建议，不能直接作为生产动作。

## 6. 主工作流：运维告警 AI 初诊断

这是从原文“文章提交与审批流程”迁移而来的运维版本。

### 6.1 节点总览

```text
Webhook: Alert Intake
  -> Set: Normalize Alert
  -> IF: Required Fields Valid?
      false -> Respond: Invalid Alert + Notify Submitter
      true  -> HTTP Request: Query CMDB
           -> HTTP Request: Query Metrics
           -> HTTP Request: Query Logs
           -> Set: Build AI Context
           -> AI Agent: Diagnose Incident
           -> Structured Output Parser: IncidentDiagnosisSchema
           -> IF: risk_level == critical OR action_requires_approval == true
                true  -> Human Approval: On-call Lead
                      -> IF: approved?
                           true  -> Create/Update Ticket + Notify Channel
                           false -> Mark Rejected + Notify Channel
                false -> Create Ticket + Notify Channel
           -> Respond: Diagnosis Accepted
```

### 6.2 Webhook 输入样例

Webhook 只接收监控系统或运维门户发来的结构化 JSON。

```json
{
  "alert_id": "ALERT-20260522-001",
  "source": "prometheus",
  "severity": "warning",
  "service": "payment-api",
  "namespace": "prod-payment",
  "cluster": "k8s-prod-a",
  "summary": "Pod restart count increased",
  "description": "payment-api restarted 5 times in 10 minutes",
  "started_at": "2026-05-22T10:20:00+08:00",
  "runbook_url": "https://wiki.intra/runbooks/payment-api-restart"
}
```

必填字段：

- `alert_id`
- `source`
- `severity`
- `service`
- `namespace`
- `cluster`
- `summary`
- `started_at`

### 6.3 Normalize Alert 节点

用 Set 节点或 Code 节点统一字段名，避免不同监控源字段不一致。

Code 节点示例：

```javascript
const input = $json;

return [{
  json: {
    alert_id: input.alert_id || input.labels?.alertname || `manual-${Date.now()}`,
    source: input.source || 'unknown',
    severity: input.severity || input.labels?.severity || 'unknown',
    service: input.service || input.labels?.service || input.app || 'unknown',
    namespace: input.namespace || input.labels?.namespace || 'default',
    cluster: input.cluster || input.labels?.cluster || 'unknown',
    summary: input.summary || input.annotations?.summary || '',
    description: input.description || input.annotations?.description || '',
    started_at: input.started_at || new Date().toISOString(),
    runbook_url: input.runbook_url || input.annotations?.runbook_url || ''
  }
}];
```

验收标准：

- 任意入口都能输出统一字段。
- 缺少 `service`、`summary` 等关键字段时进入失败分支。
- 不把原始 payload 中的 Token、Cookie、Authorization 字段传给 AI。

### 6.4 参数校验 IF 节点

条件：

```text
{{ $json.alert_id }} is not empty
AND {{ $json.service }} is not empty
AND {{ $json.summary }} is not empty
AND {{ $json.cluster }} is not empty
```

失败分支响应：

```json
{
  "accepted": false,
  "reason": "missing required alert fields",
  "required_fields": ["alert_id", "service", "summary", "cluster"]
}
```

### 6.5 查询 CMDB / 指标 / 日志

不要让 AI 自己随意查生产系统。由 workflow 通过固定 API 获取有限上下文，再交给模型。

#### CMDB 查询

HTTP Request：

```text
GET http://cmdb.ops.intra.example.com/api/v1/services/{{ $json.service }}
```

返回样例：

```json
{
  "service": "payment-api",
  "owner": "payment-sre",
  "tier": "tier1",
  "runtime": "kubernetes",
  "repo": "git.intra/payment/payment-api",
  "dashboard": "https://grafana.intra/d/payment-api",
  "normal_replicas": 6,
  "critical_dependencies": ["postgres-payment", "redis-payment"]
}
```

#### Prometheus 查询

HTTP Request：

```text
GET http://prometheus.ops.intra.example.com/api/v1/query
query=sum(rate(container_cpu_usage_seconds_total{namespace="{{ $json.namespace }}",pod=~"{{ $json.service }}.*"}[5m]))
```

再查重启次数：

```text
query=sum(increase(kube_pod_container_status_restarts_total{namespace="{{ $json.namespace }}",pod=~"{{ $json.service }}.*"}[15m]))
```

#### 日志查询

HTTP Request 到 Loki 或 Elasticsearch，只取有限窗口和有限条数。

```text
GET http://loki.ops.intra.example.com/loki/api/v1/query_range
query={namespace="{{ $json.namespace }}", app="{{ $json.service }}"} |= "ERROR"
limit=50
```

日志脱敏规则：

```javascript
function maskSecrets(text) {
  return text
    .replace(/Bearer\s+[A-Za-z0-9._\-]+/g, 'Bearer ***')
    .replace(/password=[^\s&]+/gi, 'password=***')
    .replace(/token=[^\s&]+/gi, 'token=***')
    .replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, '***@***');
}

return items.map(item => ({
  json: {
    ...item.json,
    sanitized_logs: maskSecrets(JSON.stringify(item.json.logs || []))
  }
}));
```

## 7. AI Agent：只做诊断，不直接执行

### 7.1 系统提示词模板

```text
你是企业内网运维 AI 助手。你的任务是基于已提供的告警、CMDB、指标、日志和 Runbook 摘要，输出结构化初步诊断。

硬性规则：
1. 不要编造未提供的指标、日志、命令执行结果或生产事实。
2. 不要建议直接执行破坏性操作，例如 delete、drop、truncate、force、批量 kill、生产发布、数据库 DDL。
3. 所有生产变更类动作必须标记 action_requires_approval=true。
4. 如果证据不足，必须输出 confidence<=0.5，并列出 missing_context。
5. 输出必须符合 JSON Schema，不要输出 Markdown。
6. 建议优先级：先止血、再定位、再修复、最后复盘。
7. 如果涉及客户数据、密钥或隐私，必须标记 data_sensitivity="high"。
```

### 7.2 用户输入模板

```text
告警：
{{ JSON.stringify($json.alert, null, 2) }}

CMDB：
{{ JSON.stringify($json.cmdb, null, 2) }}

指标摘要：
{{ JSON.stringify($json.metrics, null, 2) }}

日志摘要：
{{ $json.sanitized_logs }}

Runbook 摘要：
{{ $json.runbook_excerpt }}

请给出结构化诊断、风险等级、建议动作、需要人工确认的地方和下一步检查项。
```

### 7.3 Structured Output Parser JSON Schema

n8n 的 Structured Output Parser 可以基于 JSON Schema 约束输出字段。建议使用手写 JSON Schema，不要只依赖自然语言提示词。

```json
{
  "type": "object",
  "properties": {
    "incident_type": {
      "type": "string",
      "enum": ["pod_restart", "high_cpu", "high_memory", "db_slow_query", "network_error", "unknown"]
    },
    "risk_level": {
      "type": "string",
      "enum": ["low", "medium", "high", "critical"]
    },
    "confidence": {
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "summary": {
      "type": "string"
    },
    "evidence": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "likely_causes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "recommended_actions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "action": { "type": "string" },
          "risk": { "type": "string", "enum": ["read_only", "low", "medium", "high"] },
          "requires_approval": { "type": "boolean" },
          "expected_result": { "type": "string" },
          "rollback": { "type": "string" }
        },
        "required": ["action", "risk", "requires_approval", "expected_result", "rollback"]
      }
    },
    "missing_context": {
      "type": "array",
      "items": { "type": "string" }
    },
    "data_sensitivity": {
      "type": "string",
      "enum": ["low", "medium", "high"]
    },
    "action_requires_approval": {
      "type": "boolean"
    }
  },
  "required": [
    "incident_type",
    "risk_level",
    "confidence",
    "summary",
    "evidence",
    "likely_causes",
    "recommended_actions",
    "missing_context",
    "data_sensitivity",
    "action_requires_approval"
  ]
}
```

### 7.4 期望输出样例

```json
{
  "incident_type": "pod_restart",
  "risk_level": "medium",
  "confidence": 0.78,
  "summary": "payment-api 在 15 分钟内多次重启，日志中出现数据库连接池耗尽，CMDB 显示该服务依赖 postgres-payment。",
  "evidence": [
    "restart increase over 15m = 5",
    "logs contain connection pool exhausted",
    "service tier=tier1 and normal_replicas=6"
  ],
  "likely_causes": [
    "数据库连接池耗尽导致健康检查失败",
    "上游流量突增导致连接占用时间延长"
  ],
  "recommended_actions": [
    {
      "action": "检查 postgres-payment 当前连接数和慢查询，不做写操作",
      "risk": "read_only",
      "requires_approval": false,
      "expected_result": "确认连接数是否接近上限，以及是否存在慢查询堆积",
      "rollback": "无生产变更"
    },
    {
      "action": "如确认连接池耗尽，建议由值班负责人审批后临时扩容 payment-api 副本数",
      "risk": "medium",
      "requires_approval": true,
      "expected_result": "降低单 Pod 连接压力并缓解错误率",
      "rollback": "恢复原 replica 数"
    }
  ],
  "missing_context": [
    "最近一次发布记录",
    "数据库当前 max_connections 配置"
  ],
  "data_sensitivity": "medium",
  "action_requires_approval": true
}
```

## 8. 人工审批：把高风险动作卡住

n8n 官方支持 Human-in-the-loop：当 AI Agent 想调用某些工具时，可以先暂停并通过 Slack、Telegram、Teams、Gmail 等渠道请求人工审批。

> **内网隔离下的网络可达性限制**
>
> 如果 n8n 部署在私有内网，而审批渠道使用公网 SaaS 版企业微信、钉钉、飞书、Slack 或 Teams，外部平台的审批回调可能无法访问内网 `WEBHOOK_URL`，导致等待审批节点一直卡住。
>
> 可落地方案：
>
> 1. **纯内网协同**：优先使用私有化部署的协同工具，例如内网 Mattermost、私有化飞书或私有化钉钉，让回调流量始终在内网闭环。
> 2. **n8n Form 审批流（推荐试点）**：用 `Form Trigger` 或内部审批页面生成内网审批链接，机器人只发送文本通知和值班链接；审批人通过内网 PC/VPN 打开链接完成 Approve/Reject，避免依赖公网 SaaS 回调穿透内网。
> 3. **审计优先**：无论采用哪种审批入口，审批结果都要写入工单或审计 API，不只保留在聊天记录里。

企业内网运维建议：

- 第一阶段所有写操作工具都必须启用人工审批。
- 审批消息必须展示：告警 ID、服务、风险等级、AI 建议动作、证据、回滚方式。
- 审批人只能是值班负责人或服务 owner。
- 审批结果必须归档到工单或审计日志。

审批消息模板：

```text
【AI 运维建议待审批】
告警：{{ $json.alert_id }}
服务：{{ $json.service }} / {{ $json.namespace }} / {{ $json.cluster }}
风险等级：{{ $json.risk_level }}
置信度：{{ $json.confidence }}

建议动作：
{{ JSON.stringify($json.recommended_actions, null, 2) }}

证据：
{{ $json.evidence.join('\n') }}

请审批：Approve / Reject
```

审批拒绝后的处理：

```json
{
  "status": "rejected_by_human",
  "next_step": "请值班人员手动处理，AI 不再继续推进动作",
  "audit_required": true
}
```

## 9. 异常处理：Error Workflow 必须单独建

n8n 官方 Error Workflow 需要以 Error Trigger 开始，并在主 workflow 的 Settings 里绑定。

建议创建一个通用 `Ops AI Error Handler`：

```text
Error Trigger
  -> Set: Normalize Error
  -> HTTP Request: Send to 企业微信/Slack/Teams
  -> HTTP Request: Write Audit Event
```

告警内容模板：

```text
【n8n Workflow 执行失败】
Workflow: {{ $json.workflow.name }}
Execution: {{ $env.N8N_EDITOR_BASE_URL }}/workflow/{{ $json.workflow.id }}/executions/{{ $json.execution.id }}
Last node: {{ $json.execution.lastNodeExecuted }}
Error: {{ $json.execution.error.message }}

处理建议：
1. 先打开 execution URL 查看失败节点输入输出。
2. 如果失败在模型节点，检查模型网关超时/限流。
3. 如果失败在 HTTP Request，检查目标系统可达性和凭证有效性。
4. 如果失败在 Structured Output Parser，检查模型是否返回了非 JSON。
```

失败处理原则：

- 失败时不自动重试高风险动作。
- 查询类节点可重试 1–2 次。
- 模型节点超时后降级为“需要人工分析”，而不是生成猜测结论。
- 所有失败都要保留 execution URL 或内部审计 ID。

## 10. 场景一：Kubernetes Pod 重启初诊断

### 目标

当某个服务 Pod 在短时间内频繁重启时，自动收集基础上下文并生成初步诊断报告。

### 样例输入

```json
{
  "alert_id": "K8S-RESTART-001",
  "source": "prometheus",
  "severity": "warning",
  "service": "order-api",
  "namespace": "prod-order",
  "cluster": "k8s-prod-a",
  "summary": "order-api pod restarted frequently",
  "description": "restart count increased by 6 in 10 minutes",
  "started_at": "2026-05-22T11:00:00+08:00"
}
```

### n8n 节点

```text
Webhook
  -> Normalize Alert
  -> HTTP Request: CMDB service lookup
  -> HTTP Request: Prometheus restart query
  -> HTTP Request: Loki error logs query
  -> AI Agent + Structured Output Parser
  -> IF risk high?
  -> Human Approval or Notify Channel
```

### AI 需要判断

- 是否存在 OOMKilled。
- 是否存在启动探针或存活探针失败。
- 是否最近发布过新版本。
- 是否日志出现数据库、缓存、配置或依赖错误。
- 是否需要人工审批扩容或回滚。

### 验收标准

- 输出包含至少 3 条证据。
- 不能建议直接 `kubectl delete pod` 作为默认动作。
- 所有变更类建议必须 `requires_approval=true`。
- 置信度低于 0.5 时必须列出缺失上下文。

### 失败处理

- Prometheus 查询失败：继续执行，但 `missing_context` 必须包含指标缺失。
- Loki 查询失败：继续执行，但禁止给出高置信度根因。
- 模型输出非 JSON：进入 Error Workflow，不继续通知为“AI 已诊断”。

## 11. 场景二：数据库慢查询和连接数异常初分析

### 目标

当数据库出现慢查询、连接数过高或应用报连接池耗尽时，自动生成只读分析报告，并把潜在高风险操作交给 DBA 审批。

### 样例输入

```json
{
  "alert_id": "DB-SLOW-001",
  "source": "grafana",
  "severity": "critical",
  "service": "billing-api",
  "database": "postgres-billing",
  "summary": "database active connections above threshold",
  "description": "active connections > 90% for 5 minutes",
  "started_at": "2026-05-22T11:10:00+08:00"
}
```

### 上下文查询

只读 SQL API 或内部 DBA API 返回：

```json
{
  "active_connections": 185,
  "max_connections": 200,
  "top_queries": [
    {
      "query_id": "q123",
      "avg_time_ms": 3200,
      "calls": 142,
      "sample": "select * from invoice where status = ? order by created_at desc"
    }
  ],
  "locks": [],
  "replication_lag_seconds": 0
}
```

### AI 输出限制

AI 可以建议：

- 检查应用连接池配置。
- 暂停非核心批处理。
- 联系 DBA 查看慢查询执行计划。
- 走审批后扩容连接池或实例资源。

AI 不可以直接建议：

- Kill 生产连接。
- 修改数据库参数。
- 执行 DDL。
- Drop index / create index on production without review。

### 期望输出

```json
{
  "incident_type": "db_slow_query",
  "risk_level": "critical",
  "confidence": 0.74,
  "summary": "billing-api 连接数接近上限，top query 显示 invoice 查询耗时高且调用频繁。",
  "recommended_actions": [
    {
      "action": "DBA 只读检查 q123 的执行计划和索引命中情况",
      "risk": "read_only",
      "requires_approval": false,
      "expected_result": "确认慢查询是否由缺索引或过滤条件导致",
      "rollback": "无生产变更"
    },
    {
      "action": "暂停低优先级账单批处理任务 15 分钟",
      "risk": "medium",
      "requires_approval": true,
      "expected_result": "释放连接并降低业务请求失败率",
      "rollback": "恢复批处理调度"
    }
  ]
}
```

### 验收标准

- 不把 SQL 原文里的敏感字段泄露到公开群。
- 所有写操作必须审批。
- 报告里必须区分“已观察证据”和“推测原因”。

## 12. 场景三：变更单上线前 AI 风险预审

### 目标

在上线前自动读取变更单、部署计划、回滚方案和影响服务，生成结构化风险预审，帮助值班负责人决定是否放行。

### 样例输入

```json
{
  "change_id": "CHG-20260522-008",
  "service": "inventory-api",
  "namespace": "prod-inventory",
  "deploy_time": "2026-05-22T22:00:00+08:00",
  "change_summary": "upgrade inventory-api from v1.8.2 to v1.9.0",
  "rollback_plan": "rollback image tag to v1.8.2 and restart deployment",
  "risk_notes": "includes database migration for new column"
}
```

### 节点设计

```text
Form Trigger: Change Review Form
  -> Validate Required Fields
  -> HTTP Request: CMDB service dependencies
  -> HTTP Request: Recent incidents for service
  -> HTTP Request: Deployment freeze calendar
  -> AI Agent: Change Risk Review
  -> Structured Output Parser
  -> IF risk high or missing rollback?
      true -> Human Approval: SRE Lead
      false -> Create Review Comment
```

### 结构化输出字段

```json
{
  "change_risk": "low|medium|high|blocker",
  "release_window_ok": true,
  "rollback_plan_ok": true,
  "dependency_risks": ["string"],
  "required_prechecks": ["string"],
  "approval_required": true,
  "block_reasons": ["string"],
  "summary_for_reviewer": "string"
}
```

### 验收标准

- 如果 `rollback_plan` 为空，必须输出 `change_risk=blocker`。
- 如果涉及数据库迁移，必须 `approval_required=true`。
- 如果服务近 24 小时有 P1/P2 故障，必须提示延后或提高审批等级。

### 失败处理

- CMDB 不可用：不自动放行，输出“上下文不足，需要人工审核”。
- 冻结窗口 API 不可用：不自动放行。
- AI 输出无法解析：进入人工审核，不生成通过结论。

## 13. 场景四：每日运维巡检报告

### 目标

每天固定时间自动汇总核心服务健康度，生成巡检报告并推送给值班群。

### 节点设计

```text
Schedule Trigger: 每天 09:00
  -> HTTP Request: 服务清单
  -> Split In Batches: 每个服务
  -> HTTP Request: 指标摘要
  -> HTTP Request: 最近 24h 告警
  -> AI Agent: Summarize Service Health
  -> Merge: 汇总所有服务
  -> AI Agent: Generate Daily Ops Report
  -> Send Message: 企业微信/Teams
  -> Write Audit: 保存报告
```

### 输出形态

```text
【每日运维巡检】2026-05-22

总体状态：黄色

重点风险：
1. payment-api 昨夜 2 次重启，已恢复，建议检查连接池。
2. billing-db 连接数长期高于 75%，建议 DBA 评估慢查询。
3. search-api P95 延迟较昨日上升 30%，建议观察索引任务。

需要人工跟进：
- CHG-20260522-008 涉及数据库迁移，回滚方案不完整。

无异常服务：
- user-api
- auth-api
- notification-api
```

### 验收标准

- 报告必须给出“总体状态”。
- 每个风险点必须关联证据或数据来源。
- 不允许凭空给出百分比或故障数。
- 原始指标查询失败时必须明确“数据缺失”。

## 14. 安全与合规清单

上线前逐项确认：

- 模型服务部署在内网或经过企业批准的模型网关。
- n8n workflow 不保存明文 Token、Cookie、数据库密码。
- 所有 API Key 使用 n8n Credentials 管理。
- 第一阶段不启用 AI 直接执行生产写操作。
- Execute Command 节点默认不启用；如必须使用，只能运行白名单脚本，且在隔离容器中执行。
- 日志进入模型前已脱敏。
- 高风险动作必须人工审批。
- 审批消息包含证据、风险、预期结果、回滚方式。
- Error Workflow 已配置。
- workflow execution 日志保留策略已确定。
- 查询 Metrics / Logs / CMDB 的节点已按敏感级别配置 `Save execution data: Don't Save`，避免 n8n 数据库长期保存敏感上下文。
- 已配置执行历史清理策略，例如 `EXECUTIONS_DATA_PRUNE=true` 和 `EXECUTIONS_DATA_MAX_AGE=168`，把敏感历史和数据库膨胀控制在可接受范围内。
- 失败时默认转人工，不默认继续自动推进。
- 测试环境和生产环境 workflow 分离。

## 15. 4 周试点计划

### 第 1 周：单机闭环

目标：跑通一个只读场景。

任务：

- 部署 n8n 单机 Docker。
- 接入内网模型或测试模型网关。
- 做一个 Webhook 告警入口。
- 固定返回 1–2 个模拟 CMDB/指标/日志接口。
- 完成 Structured Output Parser。
- 生成第一份结构化诊断报告。

验收：

- 输入样例告警后，能输出合法 JSON。
- 缺字段进入失败分支。
- 模型输出非 JSON 能被拦截。

### 第 2 周：小团队试点

目标：让 2–3 名运维人员在真实低风险告警中使用。

任务：

- 接入真实 CMDB 只读 API。
- 接入 Prometheus/Loki 只读查询。
- 推送到企业微信或 Teams。
- 每条 AI 建议都要求人工确认。

验收：

- 至少处理 10 条真实或半真实告警。
- 人工反馈记录“有用/无用/错误原因”。
- 不发生任何未经审批的生产动作。

### 第 3 周：规则固化

目标：把试点中的隐性经验变成规则。

任务：

- 固化高风险动作列表。
- 固化脱敏规则。
- 固化不同告警类型的 JSON Schema。
- 增加 Error Workflow。
- 增加审计日志。

验收：

- 每条输出都能追溯到输入和上下文来源。
- 高风险建议 100% 进入审批分支。
- 错误执行有统一告警。

### 第 4 周：有限扩展

目标：从一个场景扩展到 2–3 个场景，但不扩大权限。

任务：

- 增加数据库慢查询初分析。
- 增加上线前变更风险预审。
- 增加每日巡检报告。
- 评估是否需要 PostgreSQL/Redis/Queue mode。

验收：

- 每个场景都有样例输入、预期输出和失败处理。
- 仍保持只读或人工审批写操作。
- 明确下一阶段是否值得投入生产化。

## 16. 最小验收清单

技术验收：

- n8n 可在内网访问。
- Webhook Test URL 和 Production URL 行为已区分。
- Structured Output Parser 能拦截非 JSON 输出。
- Error Workflow 已绑定主工作流。
- Credentials 中没有硬编码 Token。
- 日志脱敏规则已测试。

业务验收：

- 运维人员能理解 AI 输出。
- 每条建议都有证据。
- 高风险动作不会绕过人工审批。
- 输出能进入工单或审计系统。
- 失败时系统不会误报“已完成诊断”。

安全验收：

- 模型不接触未脱敏敏感数据。
- workflow 不拥有生产写权限。
- AI 不直接执行 shell。
- 审批记录可追溯。
- 回滚路径明确。

## 17. 常见失败与处理

### 17.1 模型输出不是合法 JSON

处理：

- Structured Output Parser 拦截。
- 进入 Error Workflow。
- 通知值班人员“AI 诊断失败，需要人工处理”。
- 不把自由文本当成正式诊断。

### 17.2 指标或日志查询超时

处理：

- 查询类节点可重试 1–2 次。
- 超时后继续生成低置信度报告。
- `missing_context` 必须包含缺失项。
- 不允许输出高置信度根因。

### 17.3 AI 建议了危险动作

处理：

- 通过后置 Code 节点扫描危险关键词。
- 命中 `delete/drop/truncate/force/kubectl delete/kill -9` 等词时，强制改为人工审批。
- 审批消息标记“高风险建议”。

危险动作拦截示例：

```javascript
// 采用浅拷贝，避免直接修改 n8n Code 节点中的只读 $json Proxy 对象。
const dangerous = /\b(delete|drop|truncate|force|kill\s+-9)\b|kubectl\s+delete/i;
const output = { ...$json };
const text = JSON.stringify(output.recommended_actions || []);

output.policy_violation = dangerous.test(text);
if (output.policy_violation) {
  output.action_requires_approval = true;
  output.risk_level = output.risk_level === 'critical' ? 'critical' : 'high';
}

return [{ json: output }];
```

### 17.4 人工审批超时

处理：

- 设置等待超时时间。
- 超时后标记为 `approval_timeout`。
- 通知值班群。
- 不执行任何写操作。

### 17.5 n8n 自身故障

处理：

- 保留主机/容器监控。
- 持久化 `/home/node/.n8n`。
- 定期导出 workflow。
- 生产化前迁移 PostgreSQL。
- 关键场景配置外部告警，不依赖 n8n 自己给自己报故障。

## 18. 管理层摘要

这套方案不是“让 AI 自动运维”，而是“让 AI 成为有边界的初级值班助手”。

它的价值：

- 减少告警上下文收集时间。
- 降低低级漏查概率。
- 让诊断输出结构化、可审计。
- 把高风险动作挡在人工审批前。
- 为后续更成熟的自动化积累真实样本。

不建议第一阶段追求：

- 全自动修复。
- 大规模多团队统一平台。
- 复杂多智能体系统。
- 直接接管生产变更。

推荐先用 4 周完成小范围试点，证明“只读诊断 + 人工审批 + 审计闭环”稳定后，再决定是否扩展到更多服务和更高自动化等级。

## 19. 参考链接

- The New Stack 原文：https://thenewstack.io/build-n8n-ai-workflow/
- n8n Docker 安装：https://docs.n8n.io/hosting/installation/docker/
- n8n Webhook 常见问题：https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/common-issues/
- n8n Structured Output Parser：https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.outputparserstructured/
- n8n Human-in-the-loop：https://docs.n8n.io/advanced-ai/human-in-the-loop-tools/
- n8n Error Workflow：https://docs.n8n.io/flow-logic/error-handling/
- n8n Queue Mode：https://docs.n8n.io/hosting/scaling/queue-mode/
