こんにちは、ENECHANGE所属のエンジニア id:tetsushi_fukabori こと深堀です。
前回の本庄さんの記事では、PMの視点からAIエージェントの「Input → Process → Output」の本質を理解された話がありました。「膨大な知識や情報と、リクエストの質が高ければ高いほど、期待通りのアウトプットを得られる」という表現、まさにその通りかと思います。
最近ある性能改善のタスクでAIエージェントを使い倒しました。
その過程でAIエージェントの得手不得手が見えてきましたので、今回はその実体験から学んだことを共有したいと思います。
この記事を届けたい人
- システム開発・運用にAIエージェントを活用してみたいエンジニア
- AIエージェントの実力(限界も含めて)を知りたい方
- 効果的なAIとの協働方法を模索している方
性能改善でAIエージェントを使い始めた背景
今回携わったのは、大規模なバッチシステムの性能改善です。比較的小さなジョブが大量に、複雑な先行関係を持って実行されるワークフローで、数時間に及ぶ処理時間の短縮が求められていました。
このプロダクトは比較的ドメイン知識を多く必要とし、バッチ内で実装されている先行関係や制御・制約の理解にもそれなりに業務知識が必要です。
そこで、ボトルネックの特定から改善案の立案、必要に応じて実装まで、全工程でAIエージェント(Claude Code)のサポートを受けながら進めることにしました。
AIエージェントに期待していたのは以下の点です:
- コードベース理解と要約
- 複雑なワークフローの情報整理
- ライブラリ実装の調査やライブラリ起因のボトルネックの可能性の検討
- 性能試験環境からのメトリクス・ログ収集、インサイトの抽出支援
以下、実際の体験をお話しします。
AIエージェントが得意だったこと
1. コードベース理解と要約
Ruby on Railsのコードベース理解は早くて正確でした。
「XXX(業務ドメイン用語)のバッチ処理」というキーワードで該当するワークフローを特定できます。CLIツールではあるものの、クラス間・機能間の関係性を十分にわかりやすく文字で整理・表現してくれます。
「性能改善をしたい・ボトルネック分析をしたい」というコンテキストを与えることで、影響がありそうな箇所を調査・列挙してくれます。チームに参加してから性能問題が発生しているワークフロー全体の流れを掴むまで、かなり高速に進めることができました。
2. ライブラリ実装の調査、関連issueの調査検討
性能問題が発生している箇所がRuby Gemsの実装に深く関係していたため、実装内容や箇所を調査しました。
Ruby Gemsはインストール時にローカルにソースコードが存在するため、ローカルで高速な調査が可能です。AIに調査を依頼する場合にはバイナリではないライブラリは調査が容易という利点がありそうです。
加えて、性能問題の大きなウェイトを占めている特定の関数について、関連issueをWeb検索&要約してもらえるため、広い視野で対策を検討できました:
- すでにissueで議論済みの知見がすぐ手に入る
- バージョンアップでの解決状況なども把握可能
3. 調査用のクラウドサービスの設定変更提案
RDSのパフォーマンス問題の調査のためパラメータグループの設定変更を提案してもらいました。
影響範囲や再起動要否なども考慮して提案してくれるため、現実的な選択が取りやすいです。共有されているパラメータグループについては影響範囲も調査可能でした(AWS CLIの実行を許す形)。
すでに運用フェーズにあるプロダクトにおいて設定変更を行う際は十二分に注意が必要ですが、AIエージェントに調査を依頼することで、効率的に安全に設定可能な変更を判断することができました。
4. 小規模な実装〜テストサイクルの高速実行
十分に設計され、ガイドラインが引けた後の実装工程はAIエージェントが強みを持つ領域です。
改善案の立案と設計の壁打ちから始まり(これ自体が結構有用でした)、設計ができたら細かい実装時の注意事項を与えたうえで自走させることができます。
具体例として、以下のような指示を出しました:
実装してみてください。 ただし以下の条件があります。 - すべての新規実装箇所にテストを追加してください - ワークフローの制御を網羅してテストしてください - ワークフローの条件分岐の境界値をテストしてください - 異常系(投入したジョブ内での例外発生など)のパターンもテストし、新たに現在の設定と相反する望ましい実装や設定が判明したら私に知らせて設計変更の可否を確認してください - 既存でエラーになっているテストは先行して修正してください - テストスイートが長大なため、必要なテストケースだけ指定してテストを行ってください - テストの実行方法はREADMEに従ってください - 既存のテストの修正も行ってください。特にバッチワークフローを通しで確認するようなテストには大きな影響があるはずです。 - 既存のテストの修正において、テストを通すことを目標とするのではなく、テストの意図や確認内容に反したテストにしないよう最大限注意してください。 例えば、必ずパスするようアプリケーションコードを実行しないようなテストも実装可能ですが、これは完全に意味がありませんので避けるべきです。
RSpecに限らず、小さなスクリプトを書いて機能検証を行うことも同様に自律的に実行してくれます。計画の問題点などが判明したタイミングだけ人間が介入すれば良く、AIエージェントの自走時間が長ければ長いほど、他の調査や作業を並行して進められます。
AIエージェントが苦手だったこと
1. APIコールによる外部情報の参照、特に日時パラメータの指定
CloudWatch Logs、CloudWatch Logs InsightsやRDS Performance InsightsなどのAPIコールを行う際、日時パラメータの指定が難しいです。
これはAIエージェント自身が認識している現在日時が頻繁に狂うためで、人間が狂ったことを検知して修正指示をするか、AIエージェント自身が常に現在日時を確認するよう指示する必要があります。
しかし、それでもよく狂います(2025年の性能問題に対して2024年のログを探しに行こうとしたりしていました)。
PI(Performance Insights)などのAPIコールはパラメータ指定が複雑なため、AIエージェントもかなり試行錯誤をする必要があります。
その過程でAIエージェントが諦めて別アプローチを取ろうとすることがあり、意図的に停止し軌道修正する必要がありました。
2. 複数の証跡を統合した背景事象の考察
「それっぽいログ」を見つけたとき、他の証跡との整合性を考慮せずにAIエージェントの推測する原因に「当てはまるように」事象を理解しようとする傾向があります。
このため「人間が認識している既知の知識のうち、AIエージェントの主張と矛盾するもの」を都度与える必要があり、これは人間の負担が高いです。
自発的にそのような調査をするよう指定しても因果関係の推論が弱く、「関連しそうな情報」を収集しきれません。
都度調査結果や得られた小さな証跡をドキュメントに整理させ、何度も読み込ませてみてもなかなか改善しません。
3. 実在するメソッドや機能に基づく実装の提案
ハルシネーションが起きて実在しないライブラリ機能を使おうとします。
ローカルにコードがあっても存在しない機能を提案するので、小規模なテストを実行させるか、機能が実装されている箇所へのリファレンス(コード行やリポジトリへのリンク)を提示させることで、自発的に誤りに気がつけることもあります。
また「ライブラリ作者の意図(と推測されるもの)」を無視して使おうとすることがあり、ライブラリ全体での一貫性を破壊する可能性に気が付けないことがあります。
公開APIではあるもののライブラリ利用者に直接使用されることを想定していないであろうメソッドを使おうとするなど、意図の解釈が甘いことがあります。
効果的な伴走パターン
試行錯誤の結果、以下のような分業パターンが効果的でした。
プランニングについて
調査フェーズ(主にAI)→分析フェーズ(主に人間)→計画フェーズ(人間&AI)→実装・テストフェーズ(AI)といった分業が必要そうです。
特に分析フェーズにおいて情報を統合するための人間の介入が重要だと感じました。
一方で計画はAIの壁打ちを使うとかなり早く、ドキュメント化された計画が得られます。
このドキュメントの精度を二人三脚で上げていく、頻繁に更新させることで目的地に正しくたどり着ける可能性が大きく変わります。
調査について
AIだけの調査はドツボにハマりがちです。人間が簡単に調査できる部分は先に集めて、AIエージェントに詳細を調査させたほうが良いです。
例えばRDSのPIをパッと見て主要なDB負荷の発生源を同定するのは人間がやると早いです。
(ただし、PIを見ると良い…みたいな事前知識が必要なので、その知識をAIからもらったほうがいいかもしれません)。
AIエージェントにAWS CLIなどを操作させて調査させるのは効率がいいですが、オプションなどで試行錯誤する場合があります。
その場合は一度一緒に成功するコマンドを手に入れるまで付き合って、そのコマンドやオプションをドキュメントに書かせて以降参照する方が良いです。
日時系のパラメータ指定が必要な場合は特に注意し、何を指定したかを明らかにさせるべきです。
また、調査の過程で大量のリクエストやコストが発生しないことを確認することも重要です。
分析について
AIエージェントの調査は有用ですが、AIエージェントの統合はあまり信用できません。調査結果を「結論無しで」整理させ、それを列挙したものを人間が眺めたほうが良いです。
人間が分析して得た推測をAIエージェントに与え、反証や矛盾を指摘してもらうと精度を上げやすいです。
意見を支持する依頼については「でっち上げる」ことがありますが、反証ならでっち上げられてもさほど問題になりません。
実装について
テストファーストとテスト方針の明確化がとても効果的です。自動テストで実現可能なテストを極力書かせて、TDDを実践させると良いです。
暴走を止めるトリガーをルールで仕込んでおくのも重要です。テストを通すために思わぬ実装をすることがあるので、テスト意図の尊重や設計影響のある変更の確認などを事前に指示する必要があります。
実際の成果
- ボトルネックの明確化(ログ出力設定と膨大なログから特定情報の抽出)
- ボトルネックを発生させている可能性のあるアプリケーションコードの特定
- 改善案の立案
- 改善案の実装(未完了、上記の調査などを元にプロジェクト判断)
学んだこと:AIエージェントとの付き合い方
特性を理解した使い方が重要
AIエージェントの特性を理解した使い方やカスタマイズが大事だと感じました。得意分野と苦手分野を把握して、適切な場面で活用することが効果を最大化するポイントです。
信頼と監査の線引きが難しい
AIエージェントのやることのどこまでを信頼し、どこから監査するかの線引きが重要で難しいです。すべてのコマンドに同意を求めていたら進まないし、任せすぎるとコストの増大や成果の得られない実装をしたりします。
感情面での対応
感情面でもAIエージェントに振り回されないようにした方が良いです。サンクコストや逸失利益を考えすぎると、AIエージェントの提案に苛立つこともあります。
AIエージェントの失敗や方向性の誤りに出会ったら、ドキュメントに反映することが感情的なコストの低い対策になりえます。
「状態」に弱い
やや抽象的ですが、AIエージェントは「状態」に弱いです。
時刻の変化や相対的な範囲の指定は、人間であれば現在時刻という「状態」に左右されることが自明ですが、AIエージェントはその状態を認識できないことが多いです。
「データベースの内容がこうであれば」という隠れた状態もやや判断が適切でないことがあり、データベースを通じて情報伝達や制御を行っているソフトウェアで状態の認識を誤ることがあります。もっとも、これは人間にとっても難しいので、そのような設計を廃した方が幸せかもしれませんが…。
一方でスタティックな情報の取り扱いはとても上手です。
ソースコードであれば見えている因果関係の解析は素早く正確ですし、ドキュメント理解と要約や必要な情報抽出は私より圧倒的に早くて正確です。
ソースコードを「人間のように」読む
AIエージェントがソースコードから処理を特定する最初のステップは、ソースコードに対して指示に関連しそうなキーワードでgrepをかけること、がほとんどでした。とても人間らしいですね。
これはつまり、意図が伝わりやすい命名がとても大事になりうることを示唆していると考えられます。
命名が適切であれば、AIエージェントはその意図を理解しやすく、関連するコードを特定しやすいです。
人間にもAIにもわかりやすいコードを書くことが、AIエージェントとの協働を円滑にするための重要なポイントだと感じました。
今後の改善点
今後AIエージェントへの入力をもっと楽にしたいです。音声入力など。キーボード入力の負荷が結構高いので改善の余地がありそうです。
これからAIエージェントを使う人へ
AIエージェントは万能ではありませんが、適切に使うことで現実の問題に対応する強力なツールになり得ます。
ツールに振り回されないよう、目的を明確にし、AIエージェントの特性を理解した上で使うことで楽しく仕事を進めるエンジンが手に入ると思います。
まとめ
性能改善の現場でAIエージェントと伴走してみて、その実力がよく分かりました。AIエージェントは決して万能ではありませんが、人間と適切に役割分担することで、確実に性能改善の効率と質を向上させることができます。
楽しく仕事をするためにAIエージェントを使いこなしましょう。
次回は宮尾さんが、「Cursorを使ってServerless FrameworkからAWS SAMへの移行をしてみた」について語ってくださる予定です。お楽しみに!