🍦

AI活用のプロトタイプ実装で「全体最適」を先に攻略し、開発者体験が爆上がりした話

に公開

こんにちは!普段Ruby on Railsを使って開発をしているourly株式会社の@ourly_nobuoです。

先日、弊社PMのnaotoさんが公開した記事 プロトタイプは“最初のデッサン”──モナリザ式で進めたらプロジェクトが速くなった は読んでいただけましたでしょうか?

開発プロセスにおいて、いきなり完成品を目指すのではなく、まずは 全体のデッサン(プロトタイプ) を描いてから本実装に入ろう、というアプローチについての記事でした。

今回はその 続編(実践編) です!
現場のエンジニア視点で、「プロトタイプ→本実装の流れが、開発をどう加速させるのか?」その構造的な理由と、AI時代におけるこの手法の必然性についてお話しします。

なぜ「いきなり本実装」は苦しいのか?

私たちはこれまで、タスクを細かく分解し、最初から本番品質のコードを順に実装していました。しかし、この手法にはエンジニアの脳を疲弊させる構造的な原因がありました。

それは、モナリザの絵を描くことに例えると、「全体のバランス(全体最適)」と「細部の書き込み(部分最適)」を同時に行おうとしているからです。

「目」を完璧に描いてから「鼻」を描くと、顔は歪む

いきなり本実装を行う時、私たちの脳内では以下のようなマルチタスクが発生しています。

  1. 全体最適の視点(構図・バランス):
  • 「APIとして正しいレスポンス構造になっているか?」
  • 「システム全体として期待する挙動(仕様)を満たせているか?」
  1. 部分最適の視点(細部の書き込み):
  • 「ロジックは正しいか?」
  • 「クラス設計や命名はクリーンか?」
  • 「テストコードは網羅できているか?」

いきなり本実装をするというのは、 「キャンバスの左上で『完璧に美しい目』を描き、次にその横で『完璧に美しい鼻』を描く」 ようなものです。

一つ一つのパーツ(メソッドやクラス)は最高品質かもしれません。しかし、最後にすべてを描き終えて全体を見た時、 「あれ、顔全体のバランスがおかしい…」「鼻の大きさが他のパーツと合っていない…」 という悲劇が起こります。


全体最適に失敗したモナリザ

実装が進めば進むほど、先に描いた「完璧な目」が制約となり、後から全体のバランスを修正するのが困難になる。この 「積み上げるほど身動きが取れなくなる感覚」 こそが、開発の苦しさの正体でした。

積み上がるほどに、全体最適の維持が大変になる

Beforeとして、プロトタイプなしで機能ごとにタスク分解して実装を進めていた頃の失敗例をお話しします。

ある時、「ユーザーの権限や既読状態に応じて出し分けを行う、記事一覧取得API」を開発していました。私は「部分最適(コード品質)」を重視し、処理を細かくメソッドに分割して実装を進めました。

  • fetch_target_articles: 対象記事の取得
  • calculate_read_status: 既読状態の計算
  • filter_by_permissions: 権限によるフィルタリング

最初のメソッド(fetch_target_articles)を作った時点では、まだ全体は見えていません。
次のメソッド(calculate_read_status)を作る時、 「あれ、さっき作ったメソッドの返り値、この計算に使えるんだっけ?」 と全体との整合性を確認しに戻ります。

さらに次のメソッド(filter_by_permissions)を作る時も、 「このフィルタリング条件、最初の取得ロジックと競合しないか?」 と再び全体を見に行きます。

このように、メソッドを一つ作るたびに 「部分最適」と「全体最適」の視点を行ったり来たり しなければなりません。全体最適の考慮ポイントが、実装が進むにつれて雪だるま式に増えていき、 最終的に脳のキャパシティを超えてしまいます。

その結果、最後にこれらを繋ぎ合わせたメイン処理を実装し、動作確認をしてみると…

「あれ、特定の条件下だけ、記事データが空で返ってくる…」

苦労して積み上げたにも関わらず、 「全体最適(期待する挙動)」 が満たせていなかったのです。

結局、原因調査のために綺麗なコードを崩し、構造自体を見直すことになりました。「部分最適」を積み上げても、必ずしも「全体最適」にはならないことを痛感した出来事でした。


アイスを上に乗せること自体の難易度はそこまで変わらないが、バランスを維持する難易度が上がっていく

AIの登場で「プロトタイプ」のコスパが爆上がりした

ここで、「プロトタイプを作るなんて昔からある手法じゃん」と思われた方もいるかもしれません。
おっしゃる通りです。しかし、私が今回あえてこの記事を書いた理由は、AI(LLM)の登場によって、この手法のコストパフォーマンスが劇的に変化したからです。

以前であれば、プロトタイプコードを書くこと自体にもそれなりの時間がかかりました。だからこそ「二度手間」という批判ももっともでした。

しかし現在は違います。
AIを使えば、 「構造は気にしないから、とにかく動くコード」 は、人間が考えるよりも速く、一瞬で生成されます。

AIという強力な相棒がいる今だからこそ、 「爆速で全体像(デッサン)を描いて検証し、本実装の品質に注力する」 というスタイルが、最も合理的な選択肢になったのです。

実践フロー:AIと共に「全体像」を先に作る

現在は、以下のようなフローで開発を進めています。

  1. APIとDB定義を行う:
  • まずは「必要なデータが揃っているか」を重視して定義します。
  • 正規化や細かい命名のブラッシュアップはこの時点では後回しです。
  1. プロトタイプ実装:
  • 構造やコードの綺麗さは無視して、最速でAPIを作ります(AI活用)。
  • このコードはあくまで検証用であり、mainブランチにはマージしません
  1. 全体の動作確認:
  • 実際に動くものベースで「全体最適(仕様・挙動)」を確認します。
  1. 本実装へ:
  • プロトタイプを参考にしながら、設計・実装・テストを行います。

具体例:構造を無視した「動く」コード

プロトタイプ実装では、メソッド分割やクラス設計は後回しにします。
先ほどの失敗例のような機能であれば、あえてコントローラーにベタ書きして、処理の流れを一目瞭然にします。

※ 実際の業務コードでは、以下の例よりも遥かに複雑なロジックや分岐が含まれ、コード量も膨大になりますが、ここではイメージしやすくするために簡略化しています。

# ⚠️ プロトタイプ段階のコード(構造化は後回し)

def index
  # メソッド分割せず、処理の流れを上から下へ一気に書く
  
  # 1. データ取得
  articles = Article.where(status: 'published')

  # 2. ロジック適用(複雑な計算もここでやっちゃう)
  response = articles.map do |article|
    # 仕様: 権限がない場合は、特定のフラグを落とす
    # 本来はPolicyクラスなどで管理すべきだが、今はロジックの正しさだけを確認
    can_view = current_user.can_view?(article)
    
    # ここで「全体最適(仕様)」の検証に集中する
    # 「メソッド分割した時に変数が渡せてなかった」みたいなミスが起きない
    {
      id: article.id,
      title: can_view ? article.title : "閲覧不可",
      status: article.status,
      # 複雑な集計ロジックもRubyで愚直に書いて確認
      is_popular: article.read_logs.count > 100
    }
  end

  # 3. フィルタリング
  if params[:tab] == 'engineer'
    response = response.select { |r| r[:status] == 'tech' }
  end

  render json: { articles: response }
end

このように一箇所に処理をまとめることで、データの流れが可視化され、 「全体として正しく動くか」 の検証が容易になります。

もし仕様ミスがあっても、修正するのはAIに書かせたプロトタイプコードなので、痛みはありません。こうして、まずは 「全体最適」 を確定させてしまいます。

本実装への移行:ストレスフリーな開発へ

全体としての整合性(動作)が確認できたら、いよいよ本実装です。
ここで「コードを書き直す」わけですが、これは苦痛な作業ではありません。むしろ楽しい作業です。

なぜなら、「個別のロジックが保証されている(=全体整合性がとれている)」 からです。
「全体の振る舞いはあってるかな…」という不安がない状態で、以下のようなエンジニアリングの本質的な品質向上に100%の力を注ぐことができます。

  • 「この処理は再利用できそうだからServiceに切り出そう」
  • 「ここはN+1になるからpreloadしておこう」
  • 「テストコードでこの境界値を網羅しておこう」

重要なのは、 「プロトタイプと本実装で、部分最適の振る舞いを変えない(=全体最適を担保するため)」 ことです。
プロトタイプの段階で「これでやればうまく動く」というものがある前提で、目の前のクラス設計やコード品質を上げるという「部分最適」に、安心して没頭できるのです。

「動くものを、美しくする」
このプロセスこそが、エンジニアにとってクリエイティブで楽しい時間だと私は感じています!

まとめ

プロトタイプ先行開発を取り入れたことで、開発体験が劇的に改善しました。

これまでは、「全体としての振る舞いの整合性」と「コード品質」を同時にジャグリングしながら、暗闇の中を手探りで進むような辛さがありました。

しかし今は、AIを使って「動く全体像」という地図を瞬時に手に入れてから実装をスタートできます。
「ゴールはここにある」と分かった状態で、安心して設計や品質向上に集中できる。この 「圧倒的な精神的楽さ」 こそが、結果として開発スピードを最大化させる要因だと実感しています。

ourly tech blog

Discussion