Meerkat: AIエージェントでログ分析のパラダイムを変える
ルールベースのアラートの限界を超え、AIエージェントが直接インフラを分析するMeerkatの設計哲学と実装ストーリー
問題意識
夜中に鳴るPagerDutyのアラート。「CPU 90%超過」。 目を覚ましてダッシュボードを確認すると、昨日から動いていたバッチ作業が原因で、 30分後には自動で下がる予定です。 このような誤報が積み重なると、本当の問題が来たときに鈍感になります。
Meerkatはこの問題を根本的に解決しようと始まりました。 ルールベースのアラートの代わりにAIエージェントが直接ログとメトリクスを読み、 PrometheusやLokiなどのツールを呼び出して原因を推論します。 ログはベクトル化して意味検索が可能なように保存し、 AnalyzerとVectorsの2つのサービスに分けて独立して拡張できるようにしています。
核心設計: 2つのサービス、2つの責任
MeerkatはAnalyzerとVectorsの2つのサービスで構成されています。 この分離は意図的な設計です。
Vectorsはログを受け取り、意味のある形で保存することに専念します。 OpenTelemetry OTLPで入ってきたログをテンプレート抽出で重複を除去し、 OpenAIの埋め込みを経てMilvusにベクトルとして保存します。 1つのサービスが1日に数万件のログを残しても、実際には数十個のユニークなテンプレートだけがベクトル化されるため、 保存コストと検索効率が大幅に改善されます。
AnalyzerはAI分析とワーカー管理に専念します。 HTTP APIでリクエストを受け取り、非同期ワーカープールで処理し、 必要に応じてVectorsに意味検索をリクエストします。 2つのサービスはgRPCで通信し、各自独立してスケールアウトできます。
graph LR
subgraph "データフロー"
App[アプリケーション] -- OTLP Logs --> Vectors
Vectors -- 埋め込み保存 --> Milvus[(Milvus)]
Client[ユーザー/ウェブフック] -- 分析リクエスト --> Analyzer
Analyzer -- 意味検索 --> Vectors
Analyzer -- メトリクス/ログクエリ --> Prometheus
Analyzer -- LLM呼び出し --> OpenAI
end
テンプレート抽出がもたらす効果
テンプレート抽出はログの重複を除去する核心技術です。 例えば「User 123 logged in」と「User 456 logged in」は同じテンプレート「User * logged in」として抽出されます。 これにより、ログの多様性を維持しつつもベクトル化するユニークな項目の数を大幅に減らすことができます。
テンプレート抽出方式は以下の通りです。
| フィルターモード | 動作 | 使用例 |
|---|---|---|
| all | すべてのログをベクトル化 | 小規模サービス、開発環境 |
| severity | 指定レベル以上のみ処理 | 運用環境、エラー中心モニタリング |
| template (デフォルト) | Drainアルゴリズムで重複除去 | 大規模サービス、コスト最適化 |
3つのモードを提供し、サービスの規模や要求に応じて選択できるようにしました。 allモードはすべてのログをベクトル化しますがコストがかかり、 severityモードはエラーや警告などの重要なログのみを処理してコストを削減します。 templateモードはDrainアルゴリズムでログをテンプレートとして抽出し、保存スペースと検索効率を最大化します。
AIがツールを使用するということ
Analyzerの核心はLLMにツールを提供し、自ら使用させることです。 Prometheus、Loki、VictoriaLogsクエリとVectors意味検索、 4つのツールを提供します。
「エラースパイクを分析して」といったリクエストが来ると、このような流れになります。 まずVectorsで該当サービスの最近のエラーログを検索し、 Prometheusでエラー率の推移を確認した後、 Lokiで特定のエラーメッセージの頻度を分析します。 そして総合して「Redis接続タイムアウトによるエラースパイク、 14:23に開始され14:45に自動復旧」といった結論を導き出します。
ツールの結果は3万文字に制限し、 エラーはクエリ文法エラー、接続失敗、クエリ失敗に分類します。 LLMが「これは私のクエリが間違っているので修正して再度」または 「Prometheusが応答しないのでLokiに行こう」といった判断をさせるのです。
sequenceDiagram
participant User as ユーザー
participant Analyzer as Analyzer
participant LLM as LLM
participant Tools as ツール
User->>Analyzer: 分析リクエスト
Analyzer->>LLM: コンテキスト + 使用可能なツール一覧
loop エージェントループ
LLM-->>Analyzer: ツール呼び出しまたは最終回答
alt ツール呼び出し
Analyzer->>Tools: Prometheus/Loki/Vectorsクエリ
Tools-->>Analyzer: 結果
else 最終回答
Analyzer-->>User: 分析完了
end
end
運用環境での考慮
ワーカープールはバッファードチャネルサイズ1000、ワーカー10個で構成されています。 キューが満杯になると429エラーを即座に返してバックプレッシャーを提供します。 同一トリガーとクエリに対する重複分析は 5分ウィンドウ内で自動ブロックされます。
デプロイはHelm Chartで管理し、 ConfigMapには設定とシステムプロンプトを、 SecretにはAPIキーとDBパスワードを分離して保存します。 ただしワーカープールのキューがインメモリチャネルであるため、 サーバー再起動時にqueued作業が失われるという限界があります。 今後は持続性キューの適用を計画しています。
結びに
Meerkatは単にLLM APIを呼び出すことを超えました。 ツールを使用するAIエージェントアーキテクチャと意味ベースのログ検索、 非同期ワーカープールを組み合わせて 実際の運用環境で使えるプラットフォームを作りました。 ルールベースのアラートが限界に達したチームに 自然言語一言でインフラ状況を把握できる新しいインフラ可視性を提示すること、 それがこのプロジェクトが追求する価値です。