見出し画像

AIエージェントと実現するペアプログラミングの現在地

「仕様を書いて、あとは任せる」。
そんな夢のような日が、もう目の前に来ていました。
IDEの中で自律する エージェント が、設計から実装、起動確認までやり切る——AIDD Level.3です。


AIDD Level.3とは:自律するAIがあなたの相棒になる

現代のソフトウェア開発において、人工知能、つまりAIはすでに 不可欠な存在 となっていますよね。ほんの数年前までは、一部の実験的なツールでしかなかったAIが、今では開発者の生産性を飛躍的に高める 強力なブースター へと進化しました。実際、Stack Overflowが2024年に行った調査によると、回答者の76%がすでにAIツールを開発で利用しているか、利用を計画していると答えています。この驚異的な普及の背景には、OpenAIのChatGPT、AnthropicのClaude、GoogleのGeminiといった生成AIのブレイクスルーがあるのは、あなたもご存じの通りです。

このような背景の中、AIによる開発支援は、まったく新しいステージへと足を踏み入れました。それが、わたしがお話ししたい AIDD Level.3、つまり エージェント の登場です。

Level.1/2との連続と断絶

これまでのAIアシスタンスを少し振り返ってみましょう。

Level.1は、ChatGPTのようなブラウザベースのチャットインターフェースでした。 あなた が手動で関連する情報をすべてコピー&ペーストして、AIにコンテキスト(文脈)として提供する必要がありました。

Level.2は、CursorやGitHub CopilotのようなIDE(統合開発環境)に統合されたツールです。AIがプロジェクトのコンテキストをある程度自動で読み取り、コードの補完や特定の範囲の修正を手伝ってくれるようになりました。それでも、あくまで主導権は あなた にあり、明確な指示を与えて多くの部分を制御していました。

そしてLevel.3では、AIが 自律的に意思決定して動く ようになります。プロンプトで「こうしてほしい」という要件を渡すと、エージェントは自分で関連ファイルを探し出して開き、変更点を見つけ、必要であれば設定ファイルまで修正し、最後はアプリケーションの起動確認まで試みます。

IDEの画面では、その一連の「思考と行動」がリアルタイムでストリーミング表示されます。 あなた の役割は、その流れを見守り、必要に応じて 監督(Supervised) し、時には 介入(Intervene) することに変わるのです。まるで、 あなた の隣に座って一緒にコードを書く、優秀なペアプログラマーがやってきたかのようです。

何を解決してくれるのか

この自律型のエージェントは、開発におけるいくつかの大きな課題を解決してくれます。

  • 仕様から実装までの「移送コスト」を削る: 「こうしたい」という自然言語で書かれたアイデアや仕様を、AIが直接コードに落とし込んでくれます。

  • 文脈の探索と編集を「自動ルーティング」: 機能追加には、コンポーネント、状態管理、スタイルの変更など、複数のファイルを横断する作業がつきものですが、エージェントはそれらを自動で特定し、一貫性のある変更を行ってくれます。

  • 実行・確認までの「反復ループ」を短縮: コードを書き、サーバーを起動し、動作を確認するというサイクルを高速化します。エージェントは実装後に起動確認まで試み、変更の差分(diff)を提示し、 あなた の最終判断を仰ぐのです。

AIがこのように自律的な行動をできるのは、大規模言語モデル(LLM)が、コード、書籍、ウェブサイトなど、膨大なデータから言語の統計的な関係性を学習しているからです。この能力が、AIエージェントの賢明な意思決定の土台となっているのですね。

実践!To-Doアプリへの新機能追加:優先度フラグの実装

それでは、具体的な例を通して、AIエージェントがどのように機能するのかを一緒に体験してみましょう。今回は、オープンソースの To-DoMVCアプリ をCursorというIDEで開いて、「優先度フラグ」機能を追加するタスクに挑戦します。

プロンプトで仕様を伝える

まず、 あなた がAIエージェントに与えるプロンプト、つまり「お願いごと」は、とてもシンプルです。

新しい機能として、To-Doに優先度フラグを追加しましょう。
このフラグは、新しいTo-Doを作成する際と、既存のTo-Doの両方に視覚的にアイコンとして表示されるようにしてください。
フラグをクリックすると、そのTo-Doが高優先度になるようにします。

どうですか?実装の詳細は一切考える必要がありません。さらに、今回はヒントとして、関連しそうなファイル、例えば item コンポーネントや input コンポーネントを手動でコンテキストとして追加してみます。これで、エージェントは最初から的を絞って作業に取り掛かりやすくなるわけです。

ここまでが、わたしたち人間の仕事。ここからが、エージェントの出番です。

エージェントの「思考」とファイル探索

プロンプトを受け取ったエージェントは、まず 思考を開始します。このとき、内部ではClaude Sonnetのような、複雑なタスクの解決が得意な「シンキングモデル」が選択されることがあります。

次に、エージェントは あなた が手動で追加したファイルだけでなく、プロジェクト全体から他の関連ファイルを自動的に読み込み始めます。まるで、経験豊富な開発者がプロジェクト全体の構造を瞬時に把握し、どこをどう変更すべきかを見定めているかのようです。

そして、エージェントは具体的な編集計画を自分で立て、実行に移します。

  • constant.js ファイルに、新しいアクションタイプとして togglePriority を追加する。

  • reducer.js ファイルに、togglePriority アクションを受け取った際の、状態を切り替えるためのロジックを実装する。

  • 新しいTo-Doを作成する input コンポーネントに、フラグアイコン付きのボタンを追加する。

  • 各To-Do item コンポーネントにも、フラグアイコンを表示するように更新する。

  • header.jsx の中で input コンポーネントを呼び出している箇所に、新しい priority パラメータを追加する必要があることを見つけ出し、修正する。

  • フラグアイコンが綺麗に表示されるように、スタイリングのためのCSSを新設、または更新する。

この一連の作業は、AIが単に指示されたことだけを行うのではなく、 プロジェクト全体を理解し、自律的に行動している 確かな証拠です。

実装中のESLintエラーは“判定して”進める

とても興味深いのは、編集の途中でESLint(コードの静的解析ツール)がエラーを示す赤い波線を表示したときの対応です。エージェントは、そのエラーが設定ファイルに起因するものなのか、それともコードの品質に関わる問題なのかを 自ら見極めます

今回のケースでは、設定の問題であると判断し、機能の実装を優先して続行しました。流れを止めない、この柔軟な判断力には驚かされますね。

自動起動と検証の試行、そして報告

コードの実装が完了すると、エージェントはさらに驚くべき行動に出ます。なんと、 アプリケーションを起動し、機能が正しく動作するかどうかを自動的にチェックしようと試みる のです。

エージェントは開発サーバーの状態を確認し、適切なURLを見つけ出します。そして、Puppeteerのようなツールを使い、実際のブラウザでそのURLにアクセスしようとします。これは、単にコードを生成するだけでなく、それが 「実際に動くか」 という点まで検証しようとする、エージェントの自律性の高さを物語っています。

残念ながら、今回の試行ではPuppeteerでのアクセスは失敗してしまいましたが、エージェントはそこで諦めません。代わりに、コードの実装は完了したことを あなた に報告し、手動での確認を促しました。

さらに、エージェントは実装した変更について、非常に 詳細なサマリ を提供してくれます。

  • 「優先度フラグ」の切り替え機能が、新しいTo-Do入力と個々のアイテムに追加されたこと。

  • 視覚的なデザインを考慮したスタイルが追加されたこと。

  • 修正されたファイルの明確な一覧

  • そして、新しいTo-Doのデータ構造がどう変わったか、具体的に highPriority フィールドが追加されたことを教えてくれます。

// 新しいTo-Doデータ構造の例
{
  id: "some-uuid",
  title: "AIエージェントとペアプログラミング",
  completed: false,
  highPriority: true // 新しく追加されたフィールドです
}

この詳細な報告があれば、 あなた はAIが何を行い、プロジェクトにどんな影響を与えたのかを瞬時に理解できます。もちろん、Gitの差分(diffs)を確認すれば、より細かい変更内容をいつでもチェックできるので安心です。

ちなみに、実装直後のフラグのスタイルは完璧ではありませんでした。しかし、 あなた がそのスクリーンショットをチャットに添付し、「To-Doアイテムのスタイルがずれています」と伝えると、AIはすぐにCSSを更新し、 かなり良い結果 を出してくれました。このように、AIエージェントとのやり取りは、まるで人間同士の共同作業のように、フィードバックを元に改善を重ねていけるのです。

監督可能な自律:IDEが「流れ」と「差分」を見せる

このエージェントモードの最大の利点は、AIがまさに あなた のペアプログラマーのように機能しながらも、 あなた がそのプロセスを完全にコントロールできる点にあります。

進捗ストリームと介入ポイント

エージェントの思考、実行したコマンド、そして実際のコード編集は、すべてIDEのタイムライン上でリアルタイムに可視化されます。もしAIが不適切な方向に進んでいると感じたら、 あなた はいつでも「ストップ」ボタンを押して、別の指示を与えることが可能です。

生成されたコードの差分は、ファイル単位はもちろん、 行単位 で確認し、適用するかどうかを選べます。もちろん、「全て承認」して一気に取り込むこともできます。この 監督と介入の自由度 が、AIエージェントとの協業を非常に効率的で安心感のあるものにしているのです。

完了通知で“席を外せる”自由

CursorのようなIDEには、エージェントの応答が完了したときに音を鳴らす設定(「completion sound」)があります。これをオンにしておけば、少し長めの実装タスクをAIに任せている間に、 あなた はコーヒーを淹れたり、別のタスクに少し集中したりと、席を離れることができます。

そして、完了の音が鳴ったら、作業結果を確認に戻ればいい。この「委任して離れる (delegate and disengage)」というアプローチは、 あなた の時間管理を劇的に改善してくれるでしょう。

コンテキストに即した問題解決:ESLintエラーの修正例

AIエージェントは、新機能の実装だけでなく、開発中に発生する様々な問題の診断と修正にも優れています。

例えば、コンポーネントファイルのインポート文に表示される、あの嫌な赤い波線。ESLintのエラーです。ある時、このエラーの修正をエージェントに頼んでみました。するとエージェントは、エラーメッセージを解析し、プロジェクトの設定ファイルである .eslintrcparserOptions を追加するという解決策を導き出しました。これは、ESLintにJSX記法を含む現代的なJavaScriptを正しく解析するように指示する修正です。

そして驚くべきことに、この修正は わずか45秒 で適用されました。修正が完了すると、あれほど気になっていた赤い波線はすっかり消え去っていました。この迅速な対応は、AIがコンテキストを深く理解し、的確な問題解決ができることを見事に示しています。設定系のトラブルシューティングという、開発者の 認知的な負荷 を大きく下げてくれる、素晴らしい効能ですね。

どこまで任せ、どこで止めるか:AIとの上手な付き合い方

これほど強力なAIエージェントですが、万能ではありません。うまく付き合っていくためには、何を得意とし、何を人間が担当すべきかを見極めることが大切です。

スコープは「一息で終わる粒度」に

AIにタスクを任せるときは、具体的で、スコープが限定された「一息で終わる粒度」にするのが成功のコツです。

  • UIの1画面、または1機能の追加(例:今回の優先度フラグ)

  • 既存ロジックの純粋関数的な置き換え(例:Reducerの分岐処理の追加)

  • スタイルの局所的な変更(例:コンポーネントスコープのCSS修正)

一方で、アプリケーション全体の状態設計の再定義、ルーティングの刷新、設計思想の転換といった、 横断的で広範囲な変更 を一度に任せるのはまだ難しいかもしれません。そういった場合は、まず人間がタスクを小さなステップに分割し、段階的に適用していくのが安全な進め方です。

リスク管理と早期検知

AIが生成したコードを受け入れる際には、いくつかの点に注意してレビューすることが、品質を保つ上で重要になります。

  • 設定変更の波及効果: ESLint、TypeScript、ビルド設定などの変更は、プロジェクト全体に影響を及ぼす可能性があります。設定ファイルの差分は特に注意深くレビューしましょう。

  • スタイル崩れ: 見た目の変化は、スクリーンショットを撮って比較したり、StorybookのようなUIコンポーネント開発ツールや、ビジュアルリグレッションテストで即座に検知する仕組みがあると安心です。

  • 外部連携の失敗: Puppeteerのような外部ツールとの連携が失敗した場合は、それが「人間が確認すべき」という合図だと捉えましょう。

レビュー基準:人間の最後の砦

最終的にコードを承認し、リポジトリにコミットするのは あなた の責任です。AIが書いたコードであっても、人間が書いたコードと同じ基準でレビューしましょう。

  • 読みやすさ: 変数名や関数名は適切か?コードは適切に分割されているか?

  • テスト: 新しい機能に対するテストは書かれているか?既存のテストは壊れていないか?

  • アクセシビリティ: 適切なラベルやフォーカス管理がされているか?

  • パフォーマンス: 無駄な再レンダリングを引き起こしていないか?

これらの人間ならではの視点を持ち続けることが、AIとの協業を成功させる鍵となります。

プロンプトの型:すぐに使えるテンプレート

AIエージェントとの対話をよりスムーズにするために、いくつかの「型」を知っておくと便利です。以下に、わたしがよく使うテンプレートを紹介しますね。

機能追加テンプレート

目的:
To-Do に優先度フラグを追加したい。新規入力欄と既存アイテムの双方にフラグアイコンを表示し、クリックで高優先度をトグルする。

要件:
- フラグは視覚的に分かりやすいスタイルにすること。
- データ構造に `highPriority: boolean` を追加すること。
- 既存の機能(編集、完了、削除)を壊さないこと。

制約:
- 既存の `state/reducer` 構造を尊重すること。
- 命名は既存のコーディング規則に合わせること。
- 必要な場合のみ設定ファイルを変更し、その理由をログに残すこと。

文脈ファイル:
@components/item.jsx
@components/input.jsx
@state/reducer.js
@constants.js

バグ修正テンプレート

現象:
コンポーネント先頭の `import` 文にESLintの赤波線が表示されている。

期待する結果:
設定で解決可能であれば、`.eslintrc` または関連する設定ファイルのみを修正してほしい。JSXおよび最新のJavaScript構文に対応できるようにすること。

出力形式:
- 原因分析(1行で)
- 修正内容(差分の要約)
- 影響範囲(どのファイルやルールに影響するか)

実装の“芯”を押さえる:サンプル差分から学ぶ

エージェントが生成したコードの差分を読むことで、その「思考」の跡をたどることができます。今回の「優先度フラグ」機能で生成されうるコードの例をいくつか見てみましょう。

Reducerの分岐処理(例)

// reducer.js(抜粋)
// 目的:todoアイテムの `highPriority` プロパティをトグルするアクションを追加します

// 既存のアクション定数群に `togglePriority` が追加されていることが前提です
export function reducer(state, action) {
  switch (action.type) {
    // ...既存のcase分岐...

    case 'togglePriority': {
      // payloadで渡されたidに一致するアイテムだけ highPriority を反転させます
      const { id } = action.payload;
      return state.map(todo =>
        todo.id === id ? { ...todo, highPriority: !todo.highPriority } : todo
      );
    }

    // ...既存のcase分岐...
    default:
      return state;
  }
}

ESLint設定の修正(例)

{
  // .eslintrc(抜粋)
  // 目的:最新のJavaScriptとJSXの構文をESLintが正しく解釈できるようにします
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  }
}

アイコン付きボタンの実装(例)

// input.jsx(抜粋)
// 目的:新しいタスクを入力する欄に、優先度を設定するためのフラグボタンを追加します

export function Input({ onAdd }) {
  // このコンポーネント内でフラグの状態を一時的に保持します
  const [priority, setPriority] = useState(false);

  return (
    <div className="input-row">
      {/* タスク名を入力するテキストフィールド */}
      <input aria-label="新しいタスク" /* ... */ />

      {/* 優先度フラグボタン:クリックでオン/オフを切り替えます */}
      <button
        type="button"
        aria-pressed={priority}
        title={priority ? '高優先度を解除' : '高優先度にする'}
        onClick={() => setPriority(p => !p)}
      >
        {/* スクリーンリーダーなどへの配慮も忘れません */}
        <span role="img" aria-hidden="true">🚩</span>
      </button>

      {/* タスクを追加するボタン */}
      <button onClick={() => onAdd(/* 入力値 */, { highPriority: priority })}>
        追加
      </button>
    </div>
  );
}

コメントは、コードが「何をしているか(What)」ではなく、「なぜそうしているのか(Why)」 を簡潔に説明することで、未来の あなた やチームメイトの助けになります。

messes(ごちゃまぜ)との上手な付き合い方

AIエージェントはまだ完璧ではありません。時には、AIが残した「messes(ごちゃまぜ)」を あなた が後片付けする必要があるかもしれません。でも、心配はいりません。そのためのテクニックもちゃんとあります。

  • 小さく巻き戻す: Chatでの「全承認」は便利ですが、基本は ファイル単位、あるいは行単位 で変更を受け入れる癖をつけましょう。少しでも怪しいと感じる変更は、別のコミットに分けることで、後から安全に巻き戻せます。

  • 壊れやすい場所を先回りして確認する: 型定義ファイル(DTOやPropsなど)、グローバルなCSS、ビルド設定などは、変更の影響範囲が広くなりがちです。これらのファイルに変更があった場合は、特に注意深くレビューしましょう。

  • 自動修正の限界を見抜く: AIは要件を「達成」することに集中しますが、その結果が既存のUXやパフォーマンス、アクセシビリティを損なっていないか、長期的な視点で見て保守しやすいコードになっているか、といった点は あなた が最終的に判断する必要があります。

AIの進化のペースを考えれば、これらの「messes」をクリーンアップする労力は、AIがもたらす生産性向上のメリットに比べれば、きっと小さなものになっていくでしょう。

まとめ

AIDD Level.3 の核心は、AIに手を動かさせつつ、人は監督と意思決定に集中する という新しい協業スタイルにあります。

エージェントは、仕様の解釈から実装、設定修正、そして起動確認まで、これまで人間がファイル間を何度も行き来していた作業を、 自律的に横断 してくれます。そして、その過程と結果を差分とログとして提示し、最後の判断を あなた に委ねてくれるのです。

もちろん完璧ではなく、時には後片付けも必要です。それでも、「文脈の探索→実装→検証」という開発の反復ループを大胆に短縮できるメリットは、計り知れません。MicrosoftのCTO、Kevin Scott氏が「2030年までにプログラミングコードの95%がAIによって生成される」と予測していることからも、この変化の波の大きさがうかがえます。

AIエージェントは、 あなた の想像力をコードに変え、退屈な繰り返しの作業から解放してくれます。この強力なパートナーを使いこなすことは、 あなた のキャリアを「未来志向」にするための、とても重要な一歩になるはずです。

未来のコーディングは、きっと あなた とAIエージェントの共同作業から生まれるに違いありません。


まずは「優先度フラグ」のような 一画面・一機能 から、AIに任せてみませんか?
この記事のプロンプトの型を使い、diffをレビューする体験 をチームで共有するのが近道です。
今日試してみるその一回が、明日の 自律ペアプログラミング を当たり前にしていきます。


知識は武器とかけまして、レゴブロックと解く、その心は?
知識のひとつひとつは小さなレゴブロック
でも、組み合わせれば世界を変えるアイディアをカタチにする武器になる!

またKnowledge Oasisでお会いしましょう
案内人はkoふみでした

いいなと思ったら応援しよう!