hanzalah5/sentinel

GitHub: hanzalah5/sentinel

一款基于 LangGraph 与 Gemini 的智能体事件响应系统,自动接收生产告警并生成经过验证的根因分析假设。

Stars: 0 | Forks: 0

# Sentinel [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/hanzalah5/sentinel/actions/workflows/ci.yml)  [![License: MIT](https://img.shields.io/badge/License-MIT-informational.svg)](LICENSE) **一个智能体事件响应与根因分析副驾驶。** Sentinel 接收生产 警报,像资深 SRE 那样进行调查——关联信号,形成 排序且有证据支持的根因假设——并(在后续迭代中)在人工审批关卡之后提出 修复方案。 本项目的工程重点**不是**“一个谈论事件的 LLM”。 而是一个生产级的 agent *系统*:在所有边界处进行类型检查,端到端追踪, 在 CI 中评估,并有意识地划定范围。 ## 架构(迭代 1) ``` ┌─────────────────────────────────────────────┐ POST /investigate │ FastAPI app │ (Alert JSON) ────────► │ CorrelationIdMiddleware → typed endpoint │ │ │ │ │ ▼ │ │ InvestigationService │ │ │ (correlation id + Langfuse cb) │ │ ▼ │ │ LangGraph: [triage_and_hypothesize] │ │ │ │ │ ▼ │ │ Gemini .with_structured_output(...) │ └────────────┼─────────────────────────────────┘ ▼ RootCauseHypothesis (validated) ──► Langfuse trace ``` **此处重要的设计选择** - **结构化输出,而非 JSON 解析。** 模型被强制返回 `RootCauseHypothesis` ——验证发生在模型边界,因此格式错误的 响应是一个被捕获的错误,而不是下游的意外。 - **可观测性先于功能。** 追踪和 correlation ID 在最初的 迭代中就被接入;每个请求及其 trace 共享一个 `correlation_id`。 - **存活 ≠ 就绪。** 只要进程启动,`/healthz` 就保持绿色(通过); `/readyz` 只有在 agent 实际连接好(存在 Gemini 密钥)时才会通过。 - **提供者接缝(Provider seam)。** Agent 依赖于来自 `get_chat_model()` 工厂的 `BaseChatModel` ——后续迭代可以在不触及 graph 的情况下切换为具备成本/延迟感知的路由。 ## 技术栈 | 关注点 | 选择 | |---|---| | 编排 | LangGraph(目前为单节点,有扩展空间) | | LLM | 通过 `langchain-google-genai` 使用 Google Gemini | | 类型安全的 I/O | Pydantic v2 + 结构化输出 | | API | FastAPI | | 摄入 | Redis Streams ——消费者组,至少一次交付,死信队列 | | 可观测性 | Langfuse (v3) + 结构化 `structlog` 日志,共享 correlation ID | | 工具 | `uv`, `ruff`, `mypy --strict`, `pytest` | | 打包 / 部署 | Docker + Docker Compose | | CI | GitHub Actions:lint → format-check → type-check → test | ## 快速开始 需要 Python 3.12 和 [`uv`](https://docs.astral.sh/uv/)。 ``` # 1. 安装依赖(创建 .venv,解析 lockfile) uv sync # 2. 配置(测试可选;实际调用必需) cp .env.example .env # then set GOOGLE_API_KEY # 3. 质量门禁 — 全部离线运行,无需 API key uv run ruff check . uv run mypy src tests uv run pytest # 4. 本地运行 API uv run uvicorn sentinel.api.app:create_app --factory --reload --port 8000 ``` (如果您安装了 `make`:`make check` 运行 lint + typecheck + test;`make run` 启动 API。) ### 试一试 ``` curl -s http://localhost:8000/healthz curl -s -X POST http://localhost:8000/investigate \ -H 'Content-Type: application/json' \ -d '{ "alert_id": "alert-1024", "title": "High p99 latency on checkout-api", "description": "p99 latency rose to 2.4s; DB connection pool saturation warnings.", "severity": "critical", "service": "checkout-api", "source": "prometheus", "fired_at": "2026-07-12T09:31:00Z", "labels": {"region": "us-east-1"} }' ``` 交互式 API 文档位于 `http://localhost:8000/docs`。 ### 摄入流水线(事件驱动路径) 无需直接调用 `/investigate`,警报可以通过 Redis Streams 流转: ``` # Terminal 1 — 启动 Redis + 应用 + consumer worker docker compose up --build # Terminal 2 — 向 stream 重放合成事件 uv run python -m sentinel.ingestion.generator --count 20 --rate 2 --seed 42 # (或:make seed) ``` Worker 消费每条警报,运行调查,且仅在成功时 ACK。 失败的警报会被重试;反复失败(或无法解析)的警报会进入 死信流 `sentinel:alerts:dlq`。要在 Docker 外部运行 worker(需要一个 可达的 `REDIS_URL` 和 `GOOGLE_API_KEY`):`make worker`。 ### Docker ``` docker compose up --build # redis + app (:8000) + ingestion worker ``` ## 配置 所有设置均从环境变量或本地 `.env` 文件加载(参见 `.env.example`)。 | 变量 | 默认值 | 用途 | |---|---|---| | `GOOGLE_API_KEY` | — | Gemini 密钥。如果没有它,`/investigate` 将返回 `503`。 | | `GEMINI_MODEL` | `gemini-2.5-flash` | 模型 ID。 | | `LLM_TEMPERATURE` | `0.1` | 采样温度。 | | `LANGFUSE_PUBLIC_KEY` / `LANGFUSE_SECRET_KEY` | — | 当两者都设置时启用追踪。 | | `LANGFUSE_HOST` | `https://cloud.langfuse.com` | Langfuse 端点。 | | `LOG_LEVEL` / `JSON_LOGS` | `INFO` / `true` | 日志记录。 | ## 刻意裁剪与路线图 范围本身就是一种功能。迭代 1 提供了一个完整且经过插桩的切片;下面的一切 都被有意推迟到首次*需要*它的那个迭代(包括基础设施)。 - [x] **迭代 2 —— 摄入:** Redis Streams 警报队列 + 可重放的合成 事件生成器,以至少一次交付方式消费,带有有界重试,以及 死信流。 - [ ] **迭代 3 —— Runbook RAG:** Postgres + pgvector 检索,以将假设建立在实际的 runbook 基础之上。 - [ ] **迭代 4 —— 持久化 HITL:** LangGraph checkpointer + `interrupt()`;修复 暂停以等待人工审批,并在做出决定后恢复。 - [ ] **迭代 5 —— 评估即 CI:** 一个带标签的事件集,用于对根因准确性进行评分, 在出现回归时阻止合并。 - [ ] **迭代 6 —— 成本路由与加固:** 廉价模型分诊 + 前沿模型 推理,语义缓存,速率限制,仪表板,部署。 ## 项目布局 ``` src/sentinel/ config.py # pydantic-settings logging.py # structlog + correlation-id contextvar contracts.py # Alert, RootCauseHypothesis, InvestigationResult, ... llm.py # get_chat_model() provider seam (Gemini) observability.py # Langfuse v3 client + LangChain callback handler service.py # InvestigationService: run graph, package result agent/ state.py # typed graph state graph.py # the LangGraph investigation graph ingestion/ streams.py # AlertStream: Redis Streams + consumer-group wrapper worker.py # IngestionWorker: at-least-once consume, retry, dead-letter generator.py # synthetic-incident generator CLI api/ middleware.py # CorrelationIdMiddleware app.py # FastAPI factory, lifespan, endpoints tests/ # offline suite (fake model + fakeredis), keyless ```
标签:AIOps, LangGraph, 事故响应, 搜索引擎查询, 根因分析, 请求拦截, 运维工具, 逆向工具