Skip to main content
Glama
batpepe

opsagent

by batpepe

ai-automation-lab

CI

Python n8n MCP pytest ArgoCD

一个针对我自己的 K3s 集群运行的告警分诊代理。当 Alertmanager 触发时,它会使用对集群遥测数据的只读访问权限进行调查,并返回一个人类可以据此行动的排序假设。然后它会记录自己的判断是否正确。

最后一点才是关键。把告警输入语言模型只是一个周末项目。衡量输出是否正确、限制其成本,并证明它无法触及任何不该触及的东西,才是真正的工作。

这是系列中的第三个实验室项目:devops-homelab-k3s-hybrid-cloud 是它所监控的平台,而 qa-engineering-lab 是发现该平台六个真实缺陷的测试套件。

架构

flowchart TB
    subgraph cluster["K3s cluster"]
        AM["Alertmanager"] -->|webhook| N8N["n8n<br/>workflows deployed from git"]
        N8N -->|"POST /investigations"| AGENT["opsagent<br/>FastAPI + agent loop"]

        AGENT -->|"read-only ServiceAccount"| TOOLS["tool layer"]
        TOOLS --> K8S["Kubernetes API<br/>pods, events, deploys"]
        TOOLS --> LOKI["Loki<br/>container logs"]
        TOOLS --> PROM["Prometheus<br/>PromQL"]
        TOOLS --> ARGO["ArgoCD<br/>sync history"]

        TOOLS -->|redaction| AGENT
        AGENT --> PG[("PostgreSQL<br/>investigations, cost, verdicts")]
    end

    AGENT -->|"redacted prompt"| LLM["LLM provider<br/>mock by default"]
    N8N --> TG["Telegram"]
    N8N --> GH["GitHub issue<br/>new alert class only"]
    HUMAN["me"] -->|"actual root cause"| PG
    PG --> EVAL["accuracy report"]

两个属性是结构性的,而非约定性的。工具输出在到达模型之前会经过脱敏处理,因此即使代理行为异常,也不会有未脱敏的内容离开集群。而且模型从不执行任何操作:它只读取、推理和提出建议。修复操作不在 v1 范围内。

Related MCP server: kubeview-mcp

状态

按阶段逐步构建,下表如实反映了当前状态。

阶段

交付内容

状态

0

仓库骨架、工具链、CI

已完成

1

将 n8n 作为 GitOps 工作负载,工作流导出/导入 CLI

工具已完成,部署待定

2

基于 MCP 的集群工具层,脱敏

已完成

3

代理:提供程序抽象、护栏、持久化

计划中

4

Alertmanager 到 Telegram,解决方案捕获

计划中

5

指标、Grafana 仪表板、报告页面、运行手册

计划中

6

故障注入和准确率评估

计划中

7

每日摘要、清单审查机器人、CVE 分诊

计划中

完整的细分,包括每个阶段的完成定义以及我反对的简报部分,请参阅 plan.md。

运行

这里不需要 API 密钥、数据库或集群访问权限。默认提供程序是一个确定性的模拟实现,CI 也使用它。

uv sync
uv run pytest
uv run opsagent show-config
environment=local
log_level=INFO
log_json=None

质量门禁,即相同的四次 CI 运行:

uv run ruff check .
uv run mypy
uv run pytest
uv run opsagent n8n validate

工作流同步需要运行中的实例和 API 密钥,因此这是从全新克隆中无法直接运行的一项:

opsagent n8n export    # instance to git, produces a reviewable diff
opsagent n8n diff      # compare, exits non-zero on drift, used as a CI gate
opsagent n8n import    # git to instance, reconciles activation state
opsagent n8n validate  # offline checks, no API key needed

手动驱动工具

工具层在成为代理的依赖之前是一个 MCP 服务器,因此可以在编辑器会话中针对真实集群使用这些工具。注册它:

{
  "mcpServers": {
    "opsagent": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/ai-automation-lab", "python", "-m", "opsagent.mcp"],
      "env": { "OPSAGENT_LOKI_URL": "http://localhost:3100" }
    }
  }
}

它会读取当前激活的 kubeconfig 上下文,因此请将其指向只读上下文。这六个工具是 get_pod_status、get_events、query_logs、query_metrics、get_recent_deploys 和 get_runbook。每个结果都会携带被脱敏的值的数量以及是否被截断,因此调用者绝不会将部分答案误认为完整答案。

值得捍卫的设计决策

该仓库零 API 密钥、零成本运行。 克隆此仓库的审查者得到的是一个可运行的系统,而不是描述系统的 README。这迫使提供程序抽象从一开始就存在,而不是事后添加。

脱敏位于工具边界,而不是提示词之前。 将其放在代理中意味着工具层的每个未来调用者都必须记得脱敏。将其放在工具中则意味着不可能忘记,而且它是仓库中测试最充分的代码。

脱敏保留身份而不是抹除身份。 相同的地址总是变成相同的 <ip-1>,因此模型仍然可以推断出 <ip-1> 处的 Pod 无法访问 <ip-2>,并在日志摘录和事件之间建立关联。将所有内容都掩码为 <redacted> 会破坏根本原因所依赖的结构。

代理的 ServiceAccount 无法读取密钥,也无法写入任何内容。 第 6 阶段的故障注入工具需要写权限来故意破坏东西,因此它使用自己独立的凭据。代理永远不会获得该凭据。

日志行是不可信的输入。 任何能向我读取的日志中写入内容的人都可以向我的代理写入指令。这已包含在威胁模型中,第 6 阶段会衡量实际发生的情况,而不是假设提示词始终有效。

文档

文档

内容

plan.md

阶段、完成定义、数据模型、未决问题

docs/adr/

决策及被否决的备选方案

docs/assumptions.md

所有假设而非验证的内容

docs/threat-model.md

信任边界、RBAC 范围、提示注入

docs/cost-model.md

每次调查的 Token 和成本核算

docs/eval-report.md

准确率数据,包括未命中的情况

作者

Kostiantyn Osmakov cv.batpepe.online | @batpepe

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol (MCP) server that provides safe, read-only access to Kubernetes resources for debugging and inspection. Built with security in mind, it offers comprehensive cluster visibility without modification capabilities.
    43
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    A read-only kubectl MCP server for AI assistants. The kubectl verb is hardcoded in each tool (get/describe/logs/events) and user input only fills argument values — no mutation path even with malicious input, and Secret/ConfigMap values are never returned (metadata only). Returns structured JSON, plus one-shot k8s_triage (health scan) and k8s_inventory (cluster snapshot).
    6
    1
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Read-only MCP server that exposes Kubernetes platform state (tenants, pods, SLOs, ArgoCD applications, chaos schedules, and catalog services) to AI agents, enabling natural language queries about cluster health and configuration.
    6
    -