Xでシェア

Writing / AIエージェント

N° 02

AIコーディングエージェントは内部で何をしているのか|モデル・コンテキスト・ツール実行の仕組み

AIコーディングエージェントは、モデルが一度に完成コードを生成する仕組みではありません。モデル、コンテキスト、ツール、実行環境、安全機構が連携し、判断・実行・観察を繰り返すシステムです。本記事では、ユーザー登録APIへ重複チェックを追加する例を通して、その内部構造、失敗する理由、安全な使い方を解説します。

はじめに:AIは一度に完成コードを出しているわけではない

AIコーディングエージェントに「ユーザー登録APIにメールアドレスの重複チェックを追加して、テストも実装してください」と依頼すると、しばらくファイルを調べ、コードを書き換え、テストを実行し、失敗すればさらに修正します。

この様子を見ると、AIがリポジトリ全体を理解し、人間のようにターミナルを操作しているように感じるかもしれません。しかし、実際の仕組みはもう少し分業的です。

plaintext
ユーザーの依頼
      ↓
モデルが次の行動を判断
      ↓
ツール・コマンドを実行
      ↓
結果をモデルへ返す
      ↓
完了したか判断
   ↙         ↘
 継続         終了

AIコーディングエージェントは、単体のAIモデルではありません。モデル、指示、コンテキスト管理、ファイル操作ツール、コマンド実行環境、安全機構、反復制御を組み合わせたシステムです。

中心となる考え方は単純です。

AIコーディングエージェントは、モデルが一度に正解のコードを生成する仕組みではない。状況を判断し、情報を集め、ツールを呼び出し、結果を観察しながら次の行動を決める反復システムである。

この記事で扱うのは、モデルの非公開な思考過程やTransformerの数式ではありません。外部から観察できる入力、ツール要求、実行結果、次の操作というシステム構造です。

1. チャット型AIとコーディングエージェントの違い

一般的なチャット型AIの基本形は、文章を受け取り、文章を返すことです。

plaintext
ユーザー
  ↓ 質問
モデル
  ↓ 回答
ユーザー

コードを生成できても、それをファイルへ保存し、テストを実行し、結果を貼り直すのは通常ユーザーです。モデルの回答と実際の開発環境の間に、人間がいます。

コーディングエージェントでは、モデルの出力が自然言語の回答だけでなく、「ファイルを検索する」「このファイルを読む」「パッチを適用する」「テストを実行する」といった操作の要求になります。

plaintext
ユーザー
  ↓ 依頼
エージェント
  ├─ ファイルを検索
  ├─ 関連コードを読む
  ├─ ファイルを変更
  ├─ テストを実行
  └─ 結果を確認

つまり、エージェントは新しい種類の知能を指すというより、モデルにツールと反復実行の仕組みを与えたシステムです。実際、Codexはコードの読み取り・変更・実行を行うコーディングエージェントとして説明され、クラウド版ではリポジトリを読み込んだサンドボックス内でタスクを実行します。OpenAIのCodex紹介

違いを決めるのはコード生成能力だけではありません。モデルの判断を現実の操作へ変換し、その結果を次の判断材料として戻せるかどうかです。

2. 全体像:エージェントを構成する7つの要素

コーディングエージェントは、概念的には次の7要素から構成されます。

  1. ユーザーの依頼:目的、制約、完了条件
  2. AIモデル:現在の情報から次の行動を選ぶ判断エンジン
  3. コンテキスト:モデルが現在参照できる指示、コード、履歴、実行結果
  4. ツール定義:検索、読み取り、編集、シェルなど、選択可能な操作
  5. 実行環境:ファイル操作やコマンドを実際に動かすホスト、コンテナ、サンドボックス
  6. 実行結果:ファイル内容、終了コード、テストログ、エラー
  7. エージェントループ:判断、実行、観察、終了判定を繰り返す制御
plaintext
┌────────────────────────────┐
│ ユーザーの依頼                                                              │
│ 「重複チェックを追加して」                                            │
└──────────────┬─────────────┘
               ↓
┌────────────────────────────┐
│ コンテキスト                                                                 │
│ 指示・履歴・コード・実行結果                                         │
└──────────────┬─────────────┘
               ↓
┌────────────────────────────┐
│ AIモデル                                                                       │
│ 次に何をするかを判断                                                     │
└──────────────┬─────────────┘
               ↓
┌────────────────────────────┐
│ ツール呼び出し                                                              │
│ search / read / edit / shell                                            │
└──────────────┬─────────────┘
               ↓
┌────────────────────────────┐
│ 実行結果                                                                       │
│ ファイル内容・テスト結果など                                         │
└──────────────┬─────────────┘
               └──── 次の判断へ

ここで最も重要なのは、「モデル」と「エージェントシステム」を分けることです。モデルは判断を出力しますが、ファイル権限の確認、プロセスの起動、タイムアウト、結果の収集は周囲のプログラムが担当します。

3. モデル:次の行動を決める判断エンジン

モデルは、現在コンテキストに入っている情報をもとに、主に次のことを判断します。

  • ユーザーが求めている成果は何か
  • どの情報が不足しているか
  • どのファイルを探すべきか
  • どのツールを使うべきか
  • どの変更を加えるべきか
  • 結果を受けて次に何をするか
  • 作業を終了してよいか

モデルがOSのファイルAPIやシェルを直接操作しているわけではありません。たとえば、概念的には次のような構造化された出力を返します。

json
{
  "tool": "search_files",
  "arguments": {
    "query": "createUser"
  }
}

エージェントプログラムはこの出力を解析し、ツール名と引数を検証して検索処理を実行します。得られた結果は、新しいメッセージやツール結果としてモデルへ返されます。

モデルの出力は確率的であるため、同じ依頼でも探索順序や修正方針が変わることがあります。また、情報が不足していても仮説を立てて先へ進むことがあります。高性能なモデルでも、古いファイルだけを渡されたり、重要な制約が伝わっていなかったりすれば、誤った前提から妥当そうなコードを生成します。

したがって、モデルは「リポジトリのすべてを知っている頭脳」ではなく、「現在渡されている情報から次の操作を選ぶ判断エンジン」と考えるのが正確です。

4. コンテキスト:モデルが現在参照できる作業領域

コンテキストとは、ある時点のモデル入力に含まれる情報です。典型的には次のような内容があります。

  • システム側のルール
  • ユーザーの依頼と会話履歴
  • プロジェクト固有の指示ファイル
  • エージェントが作成した計画
  • 読み込んだソースコード
  • ファイル名や文字列検索の結果
  • Git差分や履歴
  • コマンドの標準出力と標準エラー
  • テスト、ビルド、Linter、型チェックの結果
plaintext
┌ システム指示
├ ユーザーの依頼
├ プロジェクトルール
├ 読み込んだコード
├ 検索結果
├ コマンド結果
├ テスト結果
└ 直前までの作業履歴
          ↓
       AIモデル

モデルが一度に参照できる情報量、すなわちコンテキストウィンドウには上限があります。大規模なリポジトリでは、すべてのファイルを毎回モデルへ渡す方法は現実的ではありません。通常は、ファイル一覧や文字列検索で候補を絞り、関連性が高いファイルや必要な範囲だけを読み込みます。

plaintext
リポジトリ全体
    ↓ 検索・絞り込み
関連しそうなファイル
    ↓ 必要箇所を読み込み
モデルのコンテキスト

サンプルの依頼なら、エージェントはまず登録APIのルートやハンドラーを探し、そこからサービス、Repository、エラー変換、既存テストへ探索を広げるでしょう。最初から全体を完全に把握しているのではなく、検索結果を手がかりに局所的な地図を作っています。

この探索に失敗すると、既存の共通処理を見つけず重複実装したり、別ディレクトリのテストを見落としたり、プロジェクト独自の命名規則を無視したりします。READMEと実装が食い違っている場合、READMEだけを読んだモデルは古い前提で進むかもしれません。

ここで「モデル能力不足」と「コンテキスト不足」を区別する必要があります。正しい情報がコンテキストに入っていなければ、高性能なモデルでも正しい判断は難しくなります。一方、必要な情報がすべて入っているのに関係を誤解した場合は、推論や結果解釈の問題です。

5. ツール呼び出し:文章生成を実際の操作につなげる

ツールは、モデルの判断を外部世界の操作へ接続します。代表的なものは次のように分類できます。

  • 読み取り系:ファイル一覧、文字列検索、ファイル読み取り、Git差分
  • 書き込み系:ファイル作成、部分編集、パッチ適用、削除
  • 実行系:シェル、テスト、ビルド、Linter、Formatter、型チェック
  • 外部連携系:GitHub、ブラウザ、データベース、社内API、MCPサーバー

モデルには、利用可能なツールの名前、説明、入力形式などが提示されます。

json
{
  "name": "read_file",
  "description": "指定されたファイルの内容を読み取る",
  "parameters": {
    "type": "object",
    "properties": {
      "path": {
        "type": "string"
      }
    },
    "required": ["path"]
  }
}

モデルは定義を参照し、ユーザーへ回答するか、ツール利用を要求するかを選びます。Function Callingやtool useと呼ばれる仕組みの要点は、モデルが関数そのものを実行するのではなく、「このツールをこの引数で呼びたい」という構造化データを返すことです。

plaintext
AIモデル
「read_fileをこのpathで呼びたい」
        ↓
エージェントプログラム
・入力を検証
・権限を確認
        ↓
実際のツール
        ↓
結果またはエラー
        ↓
AIモデル

MCPでも、ツールは名前、説明、入力スキーマを持ち、クライアントがtools/callを送って結果を受け取る形で定義されています。MCP Tools仕様

MCPはエージェントループそのものではありません。アプリケーションが外部の情報源や操作を共通形式で公開するための接続規約です。どのツールをモデルへ見せるか、呼び出しを承認するか、結果を次の入力へどう組み込むかは、ホスト側の責任です。

6. コマンド実行:AIがターミナルを使っているように見える仕組み

モデルが次のツール呼び出しを返したとします。

json
{
  "tool": "shell",
  "arguments": {
    "command": "npm test"
  }
}

この文字列を実際のシェルへ渡すのはエージェントプログラムです。

plaintext
AIモデル
「npm testを実行したい」
        ↓
エージェントプログラム
・引数を検証
・権限を確認
        ↓
実行環境
npm test
        ↓
終了コード・ログ
        ↓
AIモデル
「失敗原因を調べる」

モデルへ戻される情報には、実行コマンド、終了コード、標準出力、標準エラー、タイムアウト、権限エラーなどが含まれます。製品によっては実行時間や変更ファイルの情報も付加されます。

たとえば、次の結果が返ったとします。

plaintext
FAIL src/services/user.test.ts
Expected status: 409
Received status: 500

モデルは「重複例外がHTTP 409へ変換されていない」という仮説を立て、エラーハンドラーを検索できます。ただし、これは観察に基づく推測です。DB接続失敗やテストデータの競合が真因なのに、短いログだけを見て例外マッピングを変更する可能性もあります。

コマンドを実行したことと、結果を正しく解釈したことは別です。終了コード、完全なエラー、関連ログ、再現性を確認する工程が必要になります。

7. 結果確認のループ:エージェントらしさの正体

エージェントらしさの中心は、単発のコード生成ではなく反復です。

plaintext
判断する
  ↓
操作する
  ↓
結果を観察する
  ↓
状況を更新する
  ↓
次の操作を決める

制御プログラムの視点では、ループは概念的に次のようになります。

python
while not finished:
    context = collect_current_context()
    action = model.decide(context, available_tools)

    if action is a tool call:
        result = execute_with_policy(action)
        append_result_to_context(result)
    else:
        return action.final_response

「ユーザー登録APIにメールアドレスの重複チェックを追加して、テストも実装してください」という依頼なら、行動列の一例は次の通りです。

  1. ディレクトリ構造を確認する
  2. ユーザー登録処理を検索する
  3. UserServiceを読む
  4. UserRepositoryを読む
  5. 既存の例外処理を探す
  6. 既存テストの書き方を確認する
  7. 重複チェックと例外変換を実装する
  8. テストを追加する
  9. 関連テストを実行する
  10. 失敗ログを読む
  11. 原因と考えた箇所を修正する
  12. テストを再実行する
  13. Linterや型チェックを実行する
  14. Git差分を確認する
  15. 変更内容と確認結果を報告する

各ステップで、直前の結果が次の判断を変えます。RepositoryにすでにfindByEmailがあれば再利用し、なければ既存の問い合わせパターンを探します。重複時の共通例外があれば使い、新設が必要ならHTTP層との責任分界を確認します。テストが409ではなく500を返せば、実装だけでなく例外ハンドラーも探索対象になります。

ただし、ループが存在するだけで検証が保証されるわけではありません。モデルが「変更できたので完了」と判断すれば、テストを実行せず終了することもあります。製品側の指示、利用可能なツール、時間やステップ数の制限、ユーザーが示した完了条件によって行動は変わります。

終了条件には、変更の完了、テスト成功、差分確認のほか、権限不足、環境不備、ユーザー判断の必要性、タイムアウト、最大ステップ到達などがあります。優れたエージェントには、進み続ける能力だけでなく、検証して終了する能力と、安全に停止する能力が必要です。

8. なぜエージェントは間違えるのか

失敗を「AIが賢くないから」でまとめず、ループのどこで問題が起きたかを考えると診断しやすくなります。

依頼または終了条件が曖昧

「APIをいい感じに直して」では、対象範囲も期待する振る舞いも不明です。エージェントは仮のゴールを作るため、ユーザーの意図とずれやすくなります。

必要なファイルを発見できていない

検索語や探索範囲が不適切なら、共通処理、プロジェクトルール、統合テストを見落とします。これはコード生成以前の探索失敗です。

コンテキストから重要情報が外れた

長い作業では、古いログやコードが要約・省略されたり、初期の制約が参照しにくくなったりします。その結果、途中で禁止されていた変更へ進むことがあります。

ツール結果を誤解した

テストの失敗箇所と根本原因は一致しないことがあります。最初のスタックトレースだけで判断すると、関係のないコードを修正しかねません。

確認工程を省略した

実装が構文上もっともらしくても、型チェック、テスト、ビルド、差分確認を行わなければ、完了を裏付ける観察がありません。

環境または権限に制約がある

ネットワーク、環境変数、DB、依存パッケージ、書き込み権限が不足していれば、検証できません。重要なのは「テスト未実施」と「テスト成功」を区別して報告させることです。

9. 安全性:コマンドを実行できることのリスク

ファイルを変更し、コマンドや外部ツールを実行できることは、エージェントの強みであると同時にリスクです。誤った判断や悪意ある入力により、不要な削除、機密情報の読み取り、認証情報のログ出力、意図しない外部通信、依存関係の追加、本番環境の操作などが起こり得ます。

対策をモデルの自制だけに依存してはいけません。システム側で次の制限を設けます。

  • サンドボックスまたは読み取り専用モード
  • 書き込み可能なディレクトリの限定
  • ネットワークの無効化または許可リスト
  • 危険な操作の事前承認
  • 利用可能なツールと認証情報の最小化
  • タイムアウトと実行回数の上限
  • Git差分、ログ、監査記録による確認
  • 本番用資格情報と開発環境の分離

OpenAIのCodexに関する安全性資料でも、サンドボックスが書き込み範囲やネットワーク到達性を定め、承認ポリシーが境界外の操作をいつ止めるか決めるという役割分担が示されています。Running Codex safely at OpenAI

安全性の原則は、強いモデルに信頼を寄せることではなく、失敗しても被害が限定される権限設計を行うことです。MCPのツール仕様も、人間が呼び出しを拒否できることや、操作を明示するUIを推奨しています。MCP Tools仕様

10. 利用者は何を意識すべきか

良い指示は、長い指示ではなく、探索と終了判定に必要な情報がある指示です。少なくとも、目的、対象範囲、制約、設計方針、完了条件、実行すべき確認を伝えます。

悪い例は次の通りです。

plaintext
このAPIを直して。

より良い例では、期待する振る舞いと検証方法を明示します。

plaintext
ユーザー登録APIにメールアドレスの重複チェックを追加してください。

既存のRepositoryと例外処理のパターンを再利用し、
重複時はHTTP 409を返してください。

実装後は関連する単体テストを追加し、
テストとLinterを実行してください。
データベーススキーマは変更しないでください。

最後に、変更したファイルと実行した確認、
未確認事項があればその理由を報告してください。

大きな依頼は、調査、実装、検証という境界で分けると監督しやすくなります。重要な変更では、まず実装方針と対象ファイルを報告させ、合意後に編集させる方法も有効です。

結果を受け取ったら、少なくとも差分、実行したコマンド、成功したテスト、未実施の確認を見ます。「テストを追加した」は「テストが成功した」と同義ではなく、「テストが成功した」も「要件を満たした」と常に同義ではありません。人間は、要件と差分の対応、セキュリティ、データ移行、運用への影響など、エージェントが観察できなかった境界を確認します。

11. まとめ:AIコーディングエージェントは反復する開発システム

AIコーディングエージェントでは、モデルがユーザーの意図と現在のコンテキストから次の行動を選びます。エージェントプログラムがツールやコマンドを実行し、その結果をモデルへ返します。モデルは新しい観察をもとに、探索、編集、検証、終了のいずれへ進むかを再判断します。

複数ステップの作業を可能にするのは、この判断・実行・観察のループです。精度はモデル性能だけでなく、必要なコードがコンテキストに入ったか、適切なツールがあるか、結果を正しく解釈したか、完了条件が明確かによって変わります。

そして、操作能力が高いほど、サンドボックス、最小権限、承認、差分確認が重要になります。

AIコーディングエージェントを使いこなすには、魔法のような自動化として見るのではなく、モデル、コンテキスト、ツール、実行結果が循環する開発システムとして理解することが重要です。