New Relic - TECH PLAY - TECH PLAY

TECH PLAY

New Relic

イベント

該当するコンテンツが見つかりませんでした

マガジン

該当するコンテンツが見つかりませんでした

技術ブログ

New RelicのNerdGraph(GraphQL API)を使って、EC2インスタンスのメタ情報をCSVに出力するツールを作った際の記録です。AWSコンソールやOSへのログインを都度行わなくても、New Relicにすでに送られている監視データからEC2のインスタンスID・IPアドレス・リージョンなどの情報を一括取得する方法を紹介します。あわせて、User keyとLicense keyの使い分けや、クエリを変更すればEC2以外のリソースにも応用できる点についても触れています。
はじめに この記事は、BASE夏のブログリレー5日目の記事です。 こんにちは、BASE でバックエンドエンジニアをしている大塚です。 いきなりですが、エラーログアラート、通知チャンネルには流れてくるものの、日々の開発に追われて誰もすぐには見に行けない——そんな経験はないでしょうか? アラートに気づいた人がログを見にいき、該当コードを grep して……という初動調査は、慣れていても 30 分から 1 時間かかる作業です。 BASE ではエラーや例外を Sentry に集約しているのですが、この初動調査を AI エージェントに任せる Slack Bot「sentry-analyzer」を内製して運用しています。 Slack で Bot に調査を依頼すると、AI が Sentry・New Relic・アプリケーションコードを自動で調べて、原因の仮説と証跡をまとめたレポートをスレッドに返してくれます。 本記事では、sentry-analyzer の仕組みと設計上の工夫、運用して見えてきたことを紹介します。 sentry-analyzer とは sentry-analyzer とは、Sentry から通知されるエラーや例外の調査・修正をしてくれる Bot です。 使い方はシンプルで、Slack のエラー通知チャンネルで Bot に調査を依頼するだけです。さらに、Sentry のアラートが届いたスレッドには Bot が「🔍 調査を開始」ボタンを自動投稿するので、ボタン 1 つでも調査を始められます (工夫したポイントで後述)。 調査結果が Slack のスレッドに返信されてくる様子 すると Bot が裏側で次のような調査を自律的に行い、数分でレポートをスレッドに投稿します。 Sentry からイベント詳細 (スタックトレース、頻度、影響ユーザー数) を取得 New Relic に NRQL を発行して、エラーレート・レイテンシ・直近デプロイなどの関連メトリクスを確認 対象リポジトリのコードを Read / Grep して、スタックトレースが指す実装を読解 以上を突き合わせて、原因の仮説・影響範囲・修正の方向性をレポートにまとめる レポートは 2 層構成にしていて、要約は Slack のスレッドに、チャートやサマリーカード付きの詳細レポートは HTML に変換して社内ホスティングにアップロードし、URL をスレッドに添えます。 レポートを受け取って終わりではなく、そのまま 会話を続けられる のもポイントです。「この仮説の根拠をもっと詳しく」「別の時間帯も見て」とスレッドに返信すると、Bot は調査のコンテキストを保持したまま深掘りしてくれます。 さらに、調査の先にある「修正」まで踏み込んでいます。分析レポートの直後に表示されるボタンを押すか「修正して」とメンションすると、エージェントが分析コンテキストを引き継いでコードを修正し、 Draft PR の作成まで 行います (詳細は後述)。 アーキテクチャ sentry-analyzer は、社内のオペレーション向け AI エージェント群を集約したモノレポ base-operation-ai-agents の一員として、セルフホストの Coolify 上でコンテナとして稼働しています。エージェント本体は 1 つの Node.js プロセスで、構成要素は次のとおりです。 Slack 受け口 : Slack Bolt の Socket Mode。アウトバウンドの WebSocket だけで動くため、インバウンドのエンドポイント公開が不要 エージェント本体 : Claude Agent SDK。ただし SDK に直接依存するのはモノレポ共通の LLM 層 packages/llm だけで、エージェントはその薄いラッパー経由で実行する (後述) 外部データアクセス : Sentry / New Relic へのアクセスは in-process の自作 MCP ツール ( get_sentry_issue / execute_nrql など)、コード読解は SDK 組み込みの Read / Grep / Glob / Bash ツール コード参照 : 調査対象リポジトリのミラーは専用の同期サービス (repo-sync) が共有ボリューム上に定期同期しており、各エージェントはそれを参照してその場で grep できる セッション管理 : Slack のスレッド単位でセッション ID を保持 (TTL 1 時間)。スレッド返信時は SDK のセッション resume で会話を継続 エージェント基盤に Claude Agent SDK を選んだのは、 自前実装を最小にできる からです。LLM エージェントを作ろうとすると、ツール呼び出しのループ、会話履歴の管理、コンテキストの永続化と resume あたりを自分で書くことになりがちですが、SDK はこれらを丸ごと持っています。こちらで書いたのは Slack のハンドラ、MCP ツール、調査手順を記述したプロンプトが中心で、エージェントらしい部分のコードはほとんどありません。 調査の「賢さ」はモデルではなくプロンプト側に寄せています。調査手順はマークダウンのプロンプトテンプレートとして管理しており、「NRQL はこういうクエリをこの順で試す」「trace.id はこの点に注意」といった社内の可観測性ノウハウをここに蓄積しています。運用しながらこのファイルを育てることが、そのまま Bot の調査品質の改善になる構造です。 工夫したポイント 1. 修正 PR 自動作成 — エージェントの責務を「コード修正まで」に絞る 分析セッションは原因箇所と修正方針まで把握しているのに、そのコンテキストを捨てて人間がゼロから修正に着手するのはもったいない。そこで分析の延長で修正 Draft PR まで作れるようにしました。設計で特に意識したのは エージェントに渡す権限を最小にする ことです。 エージェントの責務は「使い捨ての git worktree 内でコードを修正し、PR タイトル・本文を生成する」まで git push と GitHub API 呼び出し (GitHub App 認証) は、エージェントではなくホスト側 (orchestrator) が実行する。認証トークンをエージェント環境に渡さない 修正は共有のコード参照ディレクトリではなく、依頼ごとに切る git worktree で行い、終わったら成功・失敗を問わず削除 さらに、自動生成されたコードがそのまま本番に向かわないよう、機械的なガードを何段か入れています。 ガード 内容 Draft PR 固定 自動マージ機構は持たない。人間がレビューして Ready 化する 変更量上限 一定のファイル数・行数を超える diff は PR を作らず報告のみ 保護パス CI 設定やインフラ定義、lockfile などへの変更はデフォルト拒否 出自明記 PR 本文に AI 生成である旨・元の Sentry Issue・依頼者を明記 トリガーは、曖昧なキーワード判定で自動発火させる形は採らず、 分析レポート直後に表示するボタン (確認ダイアログ付き) と、「修正して」「PR 作って」のような 明示的な依頼メンション の 2 つだけを入口にしています。言い回しの揺れによる誤爆を避けつつ、ボタンのおかげで機能の発見性も上がりました。 2. 使ってもらうための工夫 — アラートに Bot が先回りする 社内ツールは作っただけでは使われません。sentry-analyzer も当初は「メンションの書き方を知っている人だけが使える」状態で、アラートを見た人が Bot の存在を思い出せなければ、そこで初動は止まってしまいます。 そこで、Bot が参加しているチャンネルに Sentry のアラートが届いたら、Bot 自身がそのスレッドに使い方の案内と「🔍 調査を開始」ボタンを自動投稿するようにしました。調査の入口がアラートに必ず現れるので、メンションの書き方を覚えていなくてもボタン 1 つで初動が始まります。 地味ですが効いている配慮が 2 つあります。 分析できないアラートには案内を出さない : Issue ID が抽出できるアラートだけを案内対象にする。ボタンを押したのに「分析できませんでした」と返ってくる体験を作らない ボタン押下後はボタンを外し、「◯◯さんが調査を開始しました」に置き換える : 連打による二重実行を防ぎつつ、誰が調査を始めたかがスレッドに残る 修正 PR の作成をボタンにしたこと (前述) も同じ発想で、「機能があることに気づける導線を、使う場所のすぐそばに置く」ことを意識しています。 3. エージェントを単独で運用せず、社内共通基盤 (モノレポ) に乗せる 社内には sentry-analyzer 以外にも Slack で動くオペレーション向け AI エージェントがあり、それぞれが別リポジトリでデプロイ・環境変数・ログ・LLM 呼び出しを別々に作ると、運用も知見も分断されてしまいます。 実際、sentry-analyzer も過去には単独リポジトリ + EC2 (systemd 常駐) で運用しており、この分断を身をもって感じていました。そこでエージェント群は 1 つのモノレポ base-operation-ai-agents に集約していて、sentry-analyzer もその 1 エージェントとして動いています。 共通基盤に乗ることで得たものは大きく 3 つあります。 LLM 層の共有 : Claude Agent SDK への直接依存は共通パッケージ packages/llm の 1 箇所だけ、という境界規約を CI で検査。共通層は SDK をほぼ素通ししつつ、エラー分類 (型付き例外) と usage 記録だけを足す薄い設計で、SDK のバージョン追従や記録基盤の改善が全エージェントに一度に効く 可観測性 : 運用が軌道に乗ると「誰がどれくらい使っているのか」「1 回の調査に何ターン・いくらかかっているのか」が知りたくなりますが、以前はログが console.log のみで、これに答えられませんでした。いまは共通層が 1 実行ごとの usage (ターン数・トークン量・コスト)・モデル別内訳・ステップトレース (どのツールが何 ms 時点で動いたか) を共有 MySQL に記録し、社内の Web UI から閲覧できます。エラー時もメトリクスは取得されるので、失敗した調査のコストも記録に残ります デプロイの標準化 : push でコンテナイメージがビルドされ自動デプロイ。本番プロセス上でビルドしないので、EC2 時代に踏んだデプロイ事故 (後述) は構造ごと解消 調査対象リポジトリの同期 (repo-sync) のような周辺機能も共用になり、エージェントを増やすたびに作り直す必要がなくなりました。一方でエージェント同士は import し合わない疎結合を保っていて、各エージェントは独立したプロダクトとして開発できます。「共有するのは基盤と規約、プロダクトは独立」というバランスの良い運用ができていると感じています。 運用してみて 初動調査が「投げておけば進む」ものになった 一番大きい変化は、アラート対応の心理的なハードルが下がったことです。従来は「まとまった時間が取れたら見よう」と後回しになりがちだった調査が、Bot に投げておけばレポートが返ってくるので、とりあえず投げる → レポートを見て判断する、という流れになりました。レポートには NRQL の実行結果や該当コードの引用が証跡として付くので、そのままチームの議論の土台になります。 定量的な成果として、運用開始からの約 5 ヶ月で約 150 回の初動調査を実行しています(月 30 回ペース)。 人手なら 30 分〜1 時間かかっていた初動調査が、Bot なら数分でレポートが出てくるようになりました。調査時間そのものは計測していませんが、初動までの速さは体感でも大きく変わっています。 踏んだ罠: 本番サーバ上で npm ci をしてはいけない 順風満帆だったわけではなく、EC2 で運用していた時期にはデプロイ事故もやらかしています。dependabot の major バージョンアップ PR を短時間に連続マージした際、デプロイのたびに本番 EC2 上で npm ci + tsc を走らせる構成だったため、小さいインスタンスのメモリが枯渇。 npm ci が中途半端に死んで node_modules が壊れ、Bot が restart ループに陥りました。 さらに悪いことに、デプロイワークフローが SSM 実行結果のエラーを握り潰す実装になっており、GitHub Actions 上はすべて success 表示。Slack で Bot が無応答なことに気づくまで、数時間の停止を見逃しました。 学びはシンプルです。 本番サーバ上でビルドしない。ビルドして成果物だけ配る CI の success 表示は、実態を exit code に反映していなければ意味がない major バージョンアップの連続マージはそれ自体がリスク この事故は「独自構成の 1 台を独自運用し続けること」自体のリスクを実感させてくれて、共通基盤に乗せる判断を後押しする出来事にもなりました。 今後の展望 症状起点トリアージ : 実際の障害対応の入口は Sentry のアラートだけではなく、「商品ページちょっと重くない?」のような軽い違和感のつぶやきから始まることもあります。Sentry の Issue ID がなくても自然言語の症状記述から対象サービスを推定して初動調査を始められる「症状モード」を検討中です 品質評価の仕組み化 : プロンプトやモデルを変えたとき「調査品質が落ちていないか」を人の目視以外で判定できるよう、形式遵守 → 証跡との整合 (グラウンディング) → プロセス品質 → 結論の妥当性、と段階を分けた評価フレームワークを設計中です エージェント間のノウハウ共有 : モノレポに集まったことで、プロンプトの知見やサブエージェントのレシピをエージェント横断で共有する土台ができました。sentry-analyzer で貯めた調査ノウハウを他のエージェントにも還流させていきます 調査ノウハウの蓄積 : 調査手順のプロンプトテンプレートは、運用で得た知見を足すほど賢くなります。定期的な更新はできていませんが、長期で運用する上で必須の作業です おわりに sentry-analyzer は「エラーの初期調査のコスト削減」に大きく貢献していると感じています。 まだまだ改善の余地はありますが、我々と同じように「アラートは来るが初動が重い」チームの参考になれば幸いです。 明日は、matzzさんの記事です。お楽しみに!
この記事は、BASE夏のブログリレー1日目の記事です。 こんにちは。BASE ProductDiv ItemSection の Torata です。 直近半年で私が作った問い合わせ調査AIエージェントの取り組みを紹介しようと思います。技術的にはそこまで難しいことをしていないので、技術構成の話ではなく、導入にあたってぶつかった壁とそれをどう乗り越えたかを中心に書いていきます。 前提:BASEの問い合わせ対応の流れ 前提としてBASEの問い合わせがどのような流れで、私が作成したAIエージェントがどのフェーズにフォーカスしたものかを説明します。 BASEではショップオーナーや購入者(以下、あわせてユーザーと呼びます)から受け取った問い合わせをCSチームが一次受けしてくれます。 技術的な知見や権限が必要でCSチームでは解決できないものがエンジニアにエスカレーションされます。 このエンジニアへエスカレーションされた問い合わせをBASEではcs_qと呼んでおり、後述するcs_aというAIエージェントも含めたフローは以下のようになっています。 cs_qの業務負荷を減らすためにcs_aという相棒を作った ユーザーからの問い合わせというのは日々発生するものであり、プロダクトの規模が大きくなれば問い合わせの数も自然と増えていきます。 しかし、その問い合わせに対応するエンジニアの数が比例して増えるわけではありません。自然とcs_qの業務負荷が増え、通常の開発業務を圧迫するシーンもみられるようになってきました。 そこでcs_qの業務負荷を軽減するAIエージェントを作成しました。 cs_qをアシストするAIなのでcs_aと名付け、Slack Botとして問い合わせチケットの投稿に応じて自動で調査を行い、回答案を作ってくれます。ただし、cs_aの回答はあくまで下書きであり、エンジニアが内容を確認してからCSチームへ返信する運用にしています。 実際のSlack上でのやりとりはこのような様子です。 cs_aを導入してからの課題と取り組み cs_aを導入してすぐに効果が出たというわけではありませんでした。 ここからはcs_aを運用する中で出てきた課題と、それを解決するために行った取り組みについて紹介します。 調べられる範囲を広げる 導入当初、cs_aはコードのみを参照して回答をしていました。 しかし、それだとプロダクトに対する事前知識やユーザーの現在の状況といった問い合わせ業務に必要なコンテキストを踏まえた上での調査ができていませんでした。 そこでマルチエージェント型にし、問い合わせ内容に応じてNew Relicのログ、問い合わせを受けた機能の仕様書、CSチームの利用しているSOP(Standard Operating Procedures)、過去問い合わせをもとにしたナレッジを取得するようにしました。さらに、エージェントが取得できないデータに関しては問い合わせ担当者に必要な情報を尋ねるようにしました。 これにより、プロダクトの知識やユーザーの行動をもとにした調査ができるようになりました。 特にログを参照することで、ユーザーがコードでいうどこの分岐に入ったのかを特定できるようになり、調査精度が上がりました。 回答精度の低下に気づけるようにする 調べられる範囲を広げたことでcs_aが参照できるものが増えた一方、LLMの出力が揺らぐ要因も増えてしまいました。 プロンプトを少し変えたり新しく参照できる要素を増やすたびに、精度が落ちていないかドキドキして見守らなければいけないのは開発者にとって優しい状態ではありません。 そこで過去のcs_qを利用して、cs_aの回答を評価(eval)する仕組みを作りました。 過去のcs_qには、エンジニアが実際に行った回答や調査経緯が残っているので、そのまま正解データとして使えます。 LLMの評価において正解が用意されているのはとてもありがたいことです。またcs_qのチケットには事前にラベル付けがしてあったので、ラベルごとにケースを用意し、特定の領域でのみ精度が落ちているのを見逃さないようにすることもできました。 調査の筋道を見せる cs_aはさまざまなコンテキストから調査ができるようになり、安心して変更を加えられる状態も整いました。 するとcs_aは期待通りの調査結果を返してくれるようになりました。大量の文章とともに... Slack上で動くBotという性質上、文量が多いとSlackで表現できるマークダウンでは可読性が落ちてしまいます。かといって文量を少なくしてしまうと、調査結果が何をもとにしたものなのかをエンジニアが知ることができず、結果的にエンジニアが裏付けのために調査し直すような二度手間が発生してしまいました。 これを解決するために、社内用のHTMLホスティング環境を利用して、調査の筋道をHTMLで見られるようにしました。 この環境についてはCTOの記事でも説明されています。 devblog.thebase.in これにより可読性高く大量の情報をエンジニアがcs_aから得られるようになり、結果的にcs_aの調査結果の信頼性を上げることに繋がりました。 回答の7割が一致するようになった これらの活動により、一部の領域やカテゴリを除いたcs_qの7割で、cs_aの回答がエンジニアの回答とほぼ一致するようになりました。 問い合わせのSlackスレッドの中では、エンジニアが「cs_aの回答の通りです。」と返すだけで対応が完了するケースもちらほら出てくるようになりました。 それでも、エンジニアの工数は減っていなかった 回答を考えて書く作業はたしかに楽になりました。しかし、ユーザーからの問い合わせ内容を確認し、CSチームへ返信するという業務自体は何も変わっていません。 cs_aへ作業を任せることはできるようになりましたが、判断を任せることはまだできていないのです。 結果として、業務負荷は多少減ったものの、「劇的に楽になった」と言える状況にはまだ持っていくことができませんでした。 これから目指すもの 今後は判断をcs_aに任せることでcs_q対応が劇的に楽になったという状態を目指そうと思っています。 判断をcs_aに任せるということはcs_aを信頼するということです。 そのためにはCSチームと連携しながら、どういうタイミングでエンジニアに調査を依頼したいか、どういう状態ならAIに任せてもいいかといった基準を決め、その基準を誰でも見られる形にすることで、安心してcs_aの回答をそのまま利用できる状態にする必要があります。 これらを実現してcs_aの回答をそのまま使える範囲を広げ、エンジニアが対応するcs_qの件数自体を減らしていくことで、エンジニアが問い合わせの根本対応やユーザー体験を考えることに集中しやすい世界を作りたいと考えています。 まとめ cs_aを運用していく中で、CSチーム、調査担当者、cs_aの開発者のそれぞれにとって価値のある運用を目指した取り組みを紹介しました。 今後はこの取り組みの価値をより大きくしていけたらと思っています。 BASEではcs_a以外にもさまざまな業務をAIに任せようという動きが広まりつつあります。 興味のある方は、ぜひお気軽に採用情報をご確認ください。 binc.jp 明日は、Kondoさんの記事です。お楽しみに!

動画

該当するコンテンツが見つかりませんでした

書籍