Slide 1

Slide 1 text

AI によるインシデント初動調査の自動化を行 う AI インシデントコマンダーを作った話 Hatena Engineer Seminar #36 プロダクトに組み込むAI編 azukiazusa

Slide 2

Slide 2 text

本日のアジェンダ 1. 導入(3分) AI インシデントコマンダーとは AI インシデントコマンダーを作った理由 2. システム設計(7分) アーキテクチャ Mastra によるワークフロー構築 3. AI エージェントを試作したうえでの今後の展望(5分) 評価の重要性 オブザーバビリティ

Slide 3

Slide 3 text

本日のアジェンダ 1. 導入(3分) AI インシデントコマンダーとは AI インシデントコマンダーを作った理由 2. システム設計(7分) アーキテクチャ Mastra によるワークフロー構築 3. AI エージェントを試作したうえでの今後の展望(5分) 評価の重要性 オブザーバビリティ

Slide 4

Slide 4 text

AI インシデントコマンダーとは Mackerel の監視アラート発生時に初動調査を自動化するAIエージェントシステム → 関連する情報を調査し、その結果をサマライズして Slack に投稿 1. Mackerelアラート発生時に自動で調 査開始 2. Slackからも @ai-incident- commander で調査依頼可能 プロトタイプ目的のため、社内でのみ利用 しています。

Slide 5

Slide 5 text

AI インシデントコマンダーを作った理由 障害対応でAIエージェントを使う検証を定常的に行いたい サーバー監視ツール Mackerel を開発しているので、障害対応の効率化は重要なテ ーマ 解決したい課題 障害対応は属人化しがち → 経験のあるメンバーがいない場合でも調査を開始できるようにしたい 障害対応の初動部分を自動化したい → ログ確認、メトリクス確認、過去事例の検索... → 意外と初動はルーティン的な作業が多い

Slide 6

Slide 6 text

本日のアジェンダ 1. 導入(3分) AI インシデントコマンダーとは AI インシデントコマンダーを作った理由 2. システム設計(7分) アーキテクチャ Mastra によるワークフロー構築 3. AI エージェントを試作したうえでの今後の展望(5分) 評価の重要性 オブザーバビリティ

Slide 7

Slide 7 text

システムアーキテクチャ AI エージェントによる分析処理は時間がかかるため、SQSキューでジョブを管理し て非同期に処理

Slide 8

Slide 8 text

AI フレームワークに Mastra を採用 TypeScript でワークフローを構築できるAIフレームワーク https://mastra.ai/

Slide 9

Slide 9 text

Mastra を採用した理由 1. スキルセットの適合 主流の AI エージェントフレームワークは Python/TypeScript が多い 普段は Web アプリケーションを開発しているので、チームメンバーが TypeScript に慣れていた 2. 豊富な活用事例 ドキュメントやサンプルが充実 Gatsby の開発チームが作成しているので、実績がある

Slide 10

Slide 10 text

Mastra Playground が便利 ワークフローをグ ラフとして可視化 各ステップの入出 力を確認できる

Slide 11

Slide 11 text

Mastra はワークフローで構築する 複雑なタスクの流れを構造化された手順で定義する仕組み 単一のエージェントの推論に頼らず、明確な実行順序を定義 タスクの分割方法、データの受け渡し、実行タイミングを制御 各ステップで入出力スキーマを定義し、型安全性を確保 ワークフローを使うタイミング 事前に明確に定義された、決まった実行順序のタスク ステップ間でのデータの流れや変換が必要な場合

Slide 12

Slide 12 text

ワークフロー設計

Slide 13

Slide 13 text

なぜワークフローに分けたのか コンテキストの分割 1つのエージェントがログ・メトリクスすべての情報を集めようとすると大量のコン テキストを消費 ワークフローに分けることで各エージェントが必要な情報だけに集中できる AI に渡すコンテキストを最適化する「コンテキストエンジニアリング」 スーパーバイザーパターン それぞれのエージェントの調査結果をまとめる要約エージェント 実際の障害対応のフローに近い

Slide 14

Slide 14 text

Mastra のワークフロー構造 1. createStep でステップを定義 ステップはワークフローの基本的な単位 2. createWorkflow でステップを組み合わせ .then() でステップをチェーン .parallel() (並列実行) .branch() (分岐処理) dowhile() (ルー プ処理)などもサポート 3. ワークフローを実行 Mastra Client SDK( @mastra/client-js )から Web API 経由でワークフ ローを実行

Slide 15

Slide 15 text

ステップの定義例 const bootstrapAlertInvestigation = createStep({ id: "bootstrap-alert-investigation", // zod スキーマで型安全性を確保 inputSchema: z.object({ alertId: z.string(), }), outputSchema: z.object({ alert: alertSchema, }), execute: async ({ inputData }) => { const mackerelClient = createMackerelClient(); const alert = await mackerelClient.getAlert(inputData.alertId); return { alert }; }, });

Slide 16

Slide 16 text

ワークフロー実装例 const alertInvestigationWorkflow = createWorkflow({ id: "alert-investigation-workflow", inputSchema: alertInputSchema, // ワークフローへの入力 outputSchema: analysisOutputSchema, // ワークフローの出力 }) .then(bootstrapAlertInvestigation) // アラート情報取得 .then(makeInvestigationDecision) // 調査判定 .then(alertInvestigationConditionWorkflow) // ネストされたワークフロー .commit(); // ワークフローを確定 .then() でステップをチェーン → 各ステップの出力が次の入力に .commit() で確定 → ワークフローを実行可能な状態に

Slide 17

Slide 17 text

.foreach で並列実行 前のステップが配列を返す場合、各要素に対してステップを並列実行 Step1: findLogGroups ↓ 出力 [group1, group2, group3, ..., group10] ↓ .foreach(analyzeLog, { concurrency: 5 }) ↓ 並列実行(最大5つ同時) ├─ analyzeLog(group1) → result1 ├─ analyzeLog(group2) → result2 ├─ analyzeLog(group3) → result3 ... ↓ 結果を集約 [result1, result2, result3, ..., result10]

Slide 18

Slide 18 text

.foreach の実装例 // ステップ1: ロググループを検索(配列を返す) const findLogGroups = createStep({ execute: async ({ inputData, mastra }) => { const agent = mastra?.getAgent("searchLogGroupAgent"); const response = await agent.generate([...]); return response.object.groups.map((group) => ({ group, alert: inputData.alert, userInput: inputData.userInput, })); }, }); // ワークフロー: 各ロググループを並列分析 const logAnalysisWorkflow = createWorkflow({...}) .then(findLogGroups) .foreach(analyzeLog, { concurrency: 5 }) .commit();

Slide 19

Slide 19 text

本日のアジェンダ 1. 導入(3分) AI インシデントコマンダーとは AI インシデントコマンダーを作った理由 2. システム設計(7分) アーキテクチャ Mastra によるワークフロー構築 3. AI エージェントを試作したうえでの今後の展望(5分) 評価の重要性 オブザーバビリティ

Slide 20

Slide 20 text

AI エージェントを試作して:評価の重要性 AI システムの評価があるかどうかが「動く」レベルのプロトタイプと、実際に運用できる システムの大きな違いになるだろう 評価の重要性は『AI エンジニアリング』全体を通じてのテーマ 評価が難しいゆえに、多くの人は伝聞(例:誰かが「モデル X は良 い」と言っていた)や、結果を目視で確認するといった安易な方法 に頼りがちです。これはさらなるリスクを孕み、アプリケーション の改善サイクルを遅らせる原因となります。結果の信頼性を高める ためには、体系的な評価に注力する必要があります。 Chip Huyen 著『AI エンジニアリング』 (オライリー・ジャパン)

Slide 21

Slide 21 text

評価がない AI システムは... テストコードがないアプリケーションに近い 場当たり的な変更 主観的な観察に頼る 改善サイクルが遅い 品質が保証できない

Slide 22

Slide 22 text

AI as a Judge(LLM as a Judge) AI 自身に評価させる手法 → 人間の評価と比較して高速かつ使いやすく、比較的安価。柔軟性が高く自動評価の手段 となりうる Mastra には Scorers と呼ばれる評価モジュールがある https://mastra.ai/docs/scorers/overview CI/CD(GitHub Actions)で評価を実行 本番環境で非同期で評価を実行することも可能(Live evaluations) ビルドインの scorers のほか、 createScorer でカスタム scorers を作成

Slide 23

Slide 23 text

Scorers の実装例 export const summarizeStepScorer = createScorer({ id: "summarize-step-quality-scorer", type: { input: incidentAnalysisOutputSchema, output: z.object({ summary: z.string() }), }, // 定量化された指標(0-1スコア)で評価 judge: { model: gemini25pro, instructions: ` あなたは調査サマリーの品質を評価する専門家です。 【評価観点(各0-1で評価)】 1. 問題特定精度: 解決すべき問題を正確に特定できているか 2. 根本原因分析: 問題の根本原因を適切に分析しているか 3. 解決策提案: 具体的で実行可能な解決策を提示しているか 4. Runbook優先活用: Runbookの情報を優先的に活用しているか 5. 出力構造準拠: 構造に従っているか `, } });

Slide 24

Slide 24 text

CIで実行するテストを書く(1/2) テストデータの準備 [ { "id": "test-001", "minScore": 0.7, "input": { "alert": { ... }, "metricsNote": "...", "log-analysis-workflow": [ ... ], "find-runbook": { ... } } }, ]

Slide 25

Slide 25 text

CIで実行するテストを書く(2/2) import { runEvals } from "@mastra/core/evals"; describe("Alert Investigation Workflow Evals", () => { it("should evaluate the workflow using Summarize Step Scorer", async () => { const result = await runEvals({ target: workflow, // 評価対象のワークフロー data: testCases, // テストデータ配列 scorers: { steps: { summarize: [summarizeStepScorer] // Scorer適用 } }, }); expect(result.scores["summarize-step-quality-scorer"]).toBeGreaterThanOrEqual(0.7); }); });

Slide 26

Slide 26 text

本番環境でのリアルタイム評価 const summarizeStep = createStep({ id: "summarize", // ... 通常のステップ定義 ... scorers: { qualityCheck: { scorer: summarizeStepScorer, sampling: { type: "ratio", rate: 0.5 }, // 50%をサンプリング } }, }); 非同期実行でレスポンスをブロックしない 結果は mastra_scorers テーブルに保存

Slide 27

Slide 27 text

ユーザーフィードバックも重要 「役に立った」 「役に立たなかった」ボタンだけでは嬉しい効果は得られない 書籍「AI エンジニアリング」で紹介されている手法 AI が生成した回答を再生成した割合 → 回答を再生成した場合、元の回答は不十分と判断された可能性が高い ユーザーが「いいえ、...」 「私が言いたかったのは...」で始めた場合 → モデルの応答が的を外れている可能性が高い GitHub Copilot: 提案したコードが accept / reject された割合 2つ結果を表示してどちらがよかったか選ばせる

Slide 28

Slide 28 text

AI のオブザーバビリティの重要性 従来のシステムは「入力Aに対して出力Bが出る」という決定論的な動きをするが、 AIエージェントは自ら考え、推論し、ツールを使い分け、試行錯誤するため、 「なぜ その行動をとったのか」がブラックボックス化しやすい エージェント間のやり取り、各エージェントの推論過程、ツールの使用履歴などを 可視化・追跡する仕組みが必要 実際にトレースを眺めて重複したプロンプトが渡されている箇所が発見できたこと もあった

Slide 29

Slide 29 text

OpenTelemetry によるトレースの活用 Mastra は OpenTelemetry によるトレースをサポート

Slide 30

Slide 30 text

はじめからワークフローを構築する必要はない エージェントフレームワーク(例:LangChain、Mastra)を使いたくなる気持ちは わかる(私もそうだった)が、最初からワークフローを設計するのは難しいし、そ の必要がある可能性は低い 評価やオブザーバビリティの仕組みが整っていないと、ワークフロー化の効 果がわからないし、デバッグも困難 まずは単一エージェントでプロトタイプを作成し、実際に使ってみてからワークフ ロー化を検討するのが良い

Slide 31

Slide 31 text

まとめ 障害対応の初動調査を自動化する AI インシデントコマンダーを開発した Mastra のワークフロー機能を活用して、複数の専門エージェントが協調動作するシ ステムを構築 AI エージェントシステムを構築した経験として、評価とオブザーバビリティの重要 性を実感した