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, страница отчётов, runbook

Планируется

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> не может связаться с <ip-2>, и сопоставлять это с фрагментом лога и событием. Маскирование всего одним <redacted> уничтожило бы именно ту структуру, из которой складывается корневая причина.

Сервисный аккаунт агента не может читать секреты и не может ничего записывать. Механизм инъекции сбоев на этапе 6 требует доступа на запись, чтобы намеренно ломать систему, поэтому у него собственные отдельные учётные данные. Агент не получает их никогда.

Строки логов — это недоверенный ввод. Любой, кто может писать в лог, который я читаю, может писать инструкции моему агенту. Это учтено в модели угроз, и этап 6 измеряет, что происходит на самом деле, а не то, что предполагалось в промпте.

Документация

Документ

О чём рассказывает

plan.md

Этапы, определения готовности, модель данных, открытые вопросы

docs/adr/

Решения и отвергнутые альтернативы

docs/assumptions.md

Всё, что принято как допущение, а не проверено

docs/threat-model.md

Границы доверия, область действия RBAC, инъекции в промпт

docs/cost-model.md

Учёт токенов и затрат на каждое расследование

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
    -