エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

ほどほどに使う生成 AI

この記事はコンシューマーチームブログリレー4日目の記事です。

エムスリーエンジニアリングG コンシューマーチームの松原です。

今回はここ半年ほど開発支援として使っていた AI エージェントについて振り返ります。 自分の使い方としてはバリバリに使いこなしているわけではなく人並みに使っているというレベル感です。 それでも AI エージェントに助けられていると感じることがいくつもあったので、この記事でいくつか紹介したいと思います。

使用ツールの紹介

使っている AI エージェントですが、初期の頃は Cline を使っていて、Claude Code が盛り上がってきてからはほぼ Claude Code を使い続けています。その他にもチーム内では Devin が使われていたりして、様々なことに AI が使われてくるようになってきました。

当初は AI エージェントとのやりとりにのめり込みがちで、細かい修正を重ねて指示したり、完璧なコードを求めてしまい、結果的に時間を無駄にしたり、最初から自分で書いた方が早かったということもよくありました。しかし、完璧を求めずに「ほどほど」の状態で使うことで、むしろ効率的に開発支援を受けられることに気づきました。

以下、具体的な場面での学びを紹介します。

コーディングでの学び - 「ある程度」で一旦区切る

コーディングで AI エージェントを使う際、元から完璧なコード生成をしてもらうつもりはなくても、やりとりをしているとついここはこうして欲しいとか、ここはやめて欲しいとか依頼をしてしまいがちでした。特に少し前から API を移行するプロジェクトに携わっていたのですが、移行先のベースとなるコードがある状態であったため、最初の指示で割とそこそこのコードを生成してくれるのです。そこでつい欲張って、細かい修正を重ねて伝えてしまうのですね。

例えば今回でいうと Java から Ruby への移行であったので、Java のコードを元にかなりの部分を生成してくれました。まさに AI エージェント使ってくださいという内容のプロジェクトだったのですが、それでも生成されたコードに気になる部分はどうしてもあって、例えば Java コード側の調査があまくて少し移行漏れがあったり、既存コードに引っ張られて Ruby っぽくないコード(極端なときは get_ prefix のついたアクセサなど)が生成されたりしました。気になっていることはちょっとしたことで自分でやってもさっと直せるようなものなのですが、逆にもうちょっとでできる内容でもあるためつい修正依頼をしてしまいます。

ただ、これが泥沼の入り口で、細かい部分は指摘し出すとキリがなかったり、あっちを指摘して直ったと思ったらこっちが戻っているとか発生しがちで、時間とコストを無駄にしますし、フラストレーションも溜まってしまいます。

そのため最近はある程度の結果が出て、そのあとにも何度かやりとりをしているなと感じたら、一旦 AI とのやり取りを打ち切ってその続きは自分で書くようにしています。 ある程度まで書いてもらっているので、それだけでもゼロから書くより作業が進めやすくなっていますし、フラストレーションを感じずに進められて精神面にも良いです。

テストでの学び - 「書く」から「レビュー」へのモード変換

テストもコーディングと同じで、やはり満足するだけのテストを書いてもらうのは一度のやり取りで生成するのはかなり難しいです。 決まりきった状態の確認などであれば書けますが、複雑なロジックのテストとなると様子が変わってきて次のようなことも発生しがちです。

  • 本当にテストしたい重要な部分が抜けている
  • テストを通すために肝心な部分をモックしてしまう
  • 時には指示を無視して元のコードまで修正してしまう(これはこれで人間ぽさが現れているような気もして面白いのですが笑)

一方である程度の部分を生成してくれるだけでも助かるのも事実です。テストコードは確認したいパターンごとにお決まりの定型作業を書いて、コードが正しいことを確認する流れですが、正直なことを言うと自分はこの作業があまり得意ではありません。

例えば日付の範囲が重なっているかをチェックする次のようなテストをイメージしてください。パターン1だけイメージしやすさのためにテストコードを埋めていますが、それ以降はパターンを列挙しています。

RSpec.describe DateRange do
  describe '#overlaps?' do
    # 基準となる日付範囲を設定 (2024年1月10日から1月20日)
    subject(:range_a) { described_class.new(Date.new(2024, 1, 10), Date.new(2024, 1, 20)) }

    # --- パターン 1: 部分的に重なる(右側で一部がはみ出す) ---
    context 'when the other range starts within range_a' do
      let(:range_b) { described_class.new(Date.new(2024, 1, 15), Date.new(2024, 1, 25)) }

      it 'returns true' do
        expect(range_a.overlaps?(range_b)).to be true
      end
    end

    # --- パターン 2: 部分的に重なる(左側で一部がはみ出す) ---
    # --- パターン 3: 完全に内包する(range_aがrange_bを完全に含む) ---
    # --- パターン 4: 完全に重ならない(基準範囲より前にある) ---
    # --- 以下その他のパターン ---
  end
end

確認したいテストパターンを列挙できたら、あとはパターンごとに context ブロックを作り let で条件となるデータを揃え、it でのチェックを埋めるだけ。。。ではあるのですが、自分の場合やることがわかりきっていると思ってしまうとどうにもやる気が湧いてこなくなってしまいます。

そこでテストパターンとそれごとの条件やチェックする部分を一旦不完全でも良いので AI エージェントに生成してもらい、テストを書くというモードからレビューするというモードに変えてしまいます。モチベーションのわかない作業から全く別のチェックするという作業に変わることで気持ちの面でストレスなく作業を進めることに繋がっています。そのためテストについても細かいところまでは求めずに、一旦テストコードを生成してもらうというところまでで使っています。

レビューでの学び - AI の得意分野を理解した活用

コードレビューで AI を活用すると、細かい指摘やタイポ、変数名の問題などはそこそこ見つけてくれます。一方で、複雑なビジネスロジックや設計判断については、やはり限界があるなと感じていて、現段階で全てを AI に任せるのは難しそうです。 特に複雑な条件分岐がビジネス要件と整合しているかや、影響範囲の大きい部分を見切れていなかったり、エッジケースが適切に処理されているかといった、文脈に依存する複雑な判断が苦手なようです。

それでも、レビューにおける AI の価値は大きいと感じています。簡単な問題を AI がキャッチしてくれることで、人間のレビュアーはより重要な部分に集中力を向けることができます。 複雑な部分は結局人間がレビューしなければならない部分でもあるわけで、簡単な部分を AI にオフロードできるだけでも、レビュアーの認知負荷を軽減し、本当に重要な問題の発見確率を上げることができると考えています。

実際、「タイポや簡単な問題は AI がチェック済み」という前提でレビューできると、より本質的な問題に集中できるようになったと感じています。

振り返りと今後の展望

この半年間 AI エージェントを使ってきて、AI エージェントと「ほどほどに付き合う」だけでも十分に開発を支援してもらえることが分かりました。今なくなったら困るだろうなというレベルで助かっているのも実感できています。

もちろんもっと上手く AI エージェントを活用するための工夫も必要ですが、完璧を求めずに AI の得意不得意を理解していいとこ取りをしていくのも大切だなと感じました。

今回紹介したような基本的な開発支援だけでなく、今後はさらに AI による自律型の開発にも取り組んでいって開発効率を向上させていきたいです。

We are hiring!

エムスリーでは生成 AI を使って開発をよくしていきたい技術好きなエンジニアを募集しております。AI エージェントを活用した開発や、自律型 AI による開発効率化にご興味のある方は、ぜひお気軽にお問い合わせください。

jobs.m3.com