Skip to content

Instantly share code, notes, and snippets.

@kaorun55
Last active June 29, 2025 14:45
Show Gist options
  • Select an option

  • Save kaorun55/bbc146a7999b8f9568b804cffa607d26 to your computer and use it in GitHub Desktop.

Select an option

Save kaorun55/bbc146a7999b8f9568b804cffa607d26 to your computer and use it in GitHub Desktop.
Gemini CLI コード生成AIの自律動作分析

Gemini CLI コード生成AIの自律動作分析

概要

Gemini CLIは、GoogleのGemini APIを活用した自律的なコード生成エージェントです。Claude Codeに似たCLIツールとして、ユーザーの要求に基づいて自動的にコードを理解、生成、修正することができます。

アーキテクチャ概要

プロジェクト構造

Gemini CLIはモノレポ構造を採用し、2つの主要パッケージから構成されています:

  1. CLIパッケージ (packages/cli/)

    • ユーザーインターフェース(React + Ink)
    • 認証、設定管理、UI表示
  2. Coreパッケージ (packages/core/)

    • AIエージェントのコア機能
    • ツールシステム
    • Gemini APIとの通信管理

自律動作の仕組み

1. システムプロンプトによる認知フレームワーク

/packages/core/src/core/prompts.tsに定義されたシステムプロンプトが、AIの行動パターンを決定します:

  • プロアクティブな実行: 「ユーザーのリクエストを徹底的に実行し、合理的で直接的に示唆される後続アクションも含める」
  • 構造化されたワークフロー: 理解→計画→実装→検証のサイクル
  • コンテキスト認識: 既存のコードパターンやプロジェクトの慣習を尊重

2. 会話管理システム

GeminiChatクラスが会話コンテキストを管理:

  • 履歴管理: 詳細な履歴と要約履歴の両方を保持
  • ストリーミングサポート: リアルタイムでの応答生成
  • 思考プロセス: 内部推論の特別な処理
  • 自動関数呼び出し: マルチターン会話でのツール呼び出しサポート

3. ツールスケジューラー

CoreToolSchedulerが自律的なツール実行を調整:

// 実行フロー
1. 検証フェーズ: ツールのパラメータ検証
2. 承認管理: 必要に応じてユーザー確認
3. 並列実行: 複数ツールの同時実行
4. ライブ出力: 長時間実行操作のストリーミング出力

4. ツールシステム

AIに具体的な能力を提供するツール群:

ファイルシステムツール

  • edit.ts: ファイルの部分編集
  • write-file.ts: ファイルの作成/上書き
  • read-file.ts: ファイル内容の読み取り
  • ls.ts: ディレクトリ内容の一覧
  • glob.ts: ファイルパターンマッチング
  • grep.ts: ファイル内容の検索

実行ツール

  • shell.ts: シェルコマンドの実行
  • mcp-client.ts: 外部ツールとの連携

その他のツール

  • web-fetch.ts: Web コンテンツの取得
  • web-search.ts: Web 検索
  • memoryTool.ts: セッション間での永続的なメモリ

自律動作の主要パターン

1. 自己主導的な探索

AIは以下の方法でコードベースを能動的に探索します:

  • 複数のツールを並列で使用して効率化
  • プロジェクト構造のメンタルモデルを構築
  • コンテキストに基づいた賢明な判断

2. 継続的な実行

  • タスクが完了するまで継続
  • マルチステップ操作の自律的な処理
  • ツール実行結果に基づく自己修正

3. インテリジェントなツール選択

  • タスクに基づいて使用するツールを決定
  • 効率的なツールスケジューリング(並列 vs 逐次)
  • ツールの失敗を優雅に処理

4. エラー回復メカニズム

Edit ツールの自己修正機能

// エスケープ文字や空白の不一致を自動的に処理
ensureCorrectEdit(options: EnsureCorrectEditOptions)
  • エスケープ文字の問題(\\n vs \n)を自動修正
  • 空白の不一致を検出して修正
  • 単純な修正で失敗した場合はLLMベースの修正を試行

Shell ツールのプロセス管理

  • バックグラウンドプロセスの追跡
  • 適切なクリーンアップのためのプロセスグループ処理
  • プラットフォーム固有の処理(Windows vs Unix)

5. フィードバック統合

すべてのツールは構造化された結果を返します:

interface ToolResult {
  llmContent: string;      // AIの理解のための詳細情報
  returnDisplay: string;   // ユーザー向けの表示
}

安全性とコントロール機構

自律動作にもかかわらず、システムには安全対策が組み込まれています:

  1. ユーザー確認: 重要な操作には承認が必要
  2. キャンセルサポート: いつでも中断可能
  3. サンドボックス化: 制限された環境での実行をサポート
  4. エラー回復: 失敗の優雅な処理
  5. チェックポイント: ファイル変更の状態保存

自律的コード生成のワークフロー

  1. ユーザー入力 → CLIがコマンド/リクエストを受信
  2. プロンプト構築 → Coreが以下を含むプロンプトを構築:
    • システム指示
    • 利用可能なツールスキーマ
    • 会話履歴
  3. AI意思決定 → Geminiモデルが:
    • リクエストを分析
    • 使用するツールを決定
    • 関数呼び出しを返す
  4. ツール実行 → Coreが:
    • ツールパラメータを検証
    • 必要に応じてユーザー確認を取得
    • ツールを実行(ファイル操作、シェルコマンドなど)
    • 結果をAIに返す
  5. 反復プロセス → AIはタスクが完了するまで継続

メモリシステム

memoryTool.tsにより、AIはセッション間で情報を保持できます:

  • ~/.gemini/GEMINI.mdに永続的に保存
  • マークダウン形式で人間が読める形式
  • 起動時に自動的にロード
  • パーソナライズされた支援を可能に

関数呼び出しメカニズム

Gemini CLIにおける関数(ツール)呼び出しは、以下のステップで実行されます:

1. ツール宣言とスキーマ定義

各ツールはToolインターフェースを実装し、以下の要素を持ちます:

// ツールのスキーマ定義例(read-file.ts)
get schema(): FunctionDeclaration {
  return {
    name: 'read_file',
    description: 'ファイルの内容を読み取る',
    parameters: {
      properties: {
        absolute_path: { type: 'string', pattern: '^/' },
        offset: { type: 'number' },
        limit: { type: 'number' }
      },
      required: ['absolute_path'],
      type: 'object'
    }
  };
}

2. ツール登録とGemini APIへの提供

// ツールをGemini APIに登録
const toolDeclarations = toolRegistry.getFunctionDeclarations();
const tools: Tool[] = [{ functionDeclarations: toolDeclarations }];

// チャットセッション作成時に渡される
new GeminiChat(config, contentGenerator, {
  systemInstruction,
  tools,  // すべてのツール宣言を含む
}, history);

3. Geminiからの関数呼び出しリクエスト

Geminiモデルは、ツールを使用したい場合、レスポンスにfunctionCallsを含めます:

// Geminiからの関数呼び出し形式
{
  functionCalls: [{
    id?: string,           // オプショナルな呼び出しID
    name: string,          // 呼び出すツール名
    args: Record<string, unknown>  // ツールへの引数
  }]
}

4. ツール実行フロー

CoreToolSchedulerが実行ライフサイクルを管理:

// ステートマシン
validating  awaiting_approval  scheduled  executing  success/error/cancelled

// 実行プロセス
1. スケジュール: schedule()メソッドで登録
2. 検証: パラメータのJSONスキーマ検証
3. 承認: 必要に応じてユーザー確認
4. 実行: tool.execute()メソッドの呼び出し
5. 結果変換: FunctionResponse形式に変換

5. 結果のフィードバック

ツール実行結果はGeminiが理解できる形式に変換されます:

// ツール結果の構造
interface ToolResult {
  llmContent: PartListUnion;      // LLM用の詳細内容
  returnDisplay: ToolResultDisplay; // ユーザー表示用
}

// Geminiへの応答形式
{
  functionResponse: {
    id: callId,
    name: toolName,
    response: { output: stringifiedContent }
  }
}

6. 自動的な関数チェーン

Geminiは複数のツールを連続して呼び出すことができます:

  • 並列実行: 独立したツールは同時に実行
  • 順次実行: 依存関係のあるツールは順番に実行
  • 結果の統合: すべての結果を履歴に追加してAIが継続処理

この仕組みにより、Geminiは複雑なタスクを自律的に分解し、必要なツールを適切に選択・実行することができます。

7. functionCallsの具体的な実装箇所

Gemini APIからの関数呼び出しは以下の箇所で処理されています:

メインの処理場所

/packages/core/src/core/turn.ts - Line 206

// Gemini APIからのストリーミングレスポンス処理
const functionCalls = resp.functionCalls ?? [];
for (const fnCall of functionCalls) {
  const event = this.handlePendingFunctionCall(fnCall);
  if (event) {
    yield event;
  }
}

関数呼び出しの変換処理

/packages/core/src/core/turn.ts - Lines 261-281

private handlePendingFunctionCall(fnCall: FunctionCall): ServerGeminiStreamEvent | null {
  const callId = fnCall.id ?? 
    `${fnCall.name}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
  const name = fnCall.name || 'undefined_tool_name';
  const args = (fnCall.args || {}) as Record<string, unknown>;

  const toolCallRequest: ToolCallRequestInfo = {
    callId,
    name,
    args,
    isClientInitiated: false,
  };

  this.pendingToolCalls.push(toolCallRequest);
  return { type: GeminiEventType.ToolCallRequest, value: toolCallRequest };
}

処理フロー

  1. 受信: Gemini APIのレスポンス内のfunctionCallsプロパティから取得
  2. ループ処理: 複数の関数呼び出しを順次処理
  3. ID生成: 呼び出しIDがない場合は自動生成
  4. イベント発行: ToolCallRequestイベントとして下流に伝播
  5. スケジューリング: CoreToolSchedulerがイベントを受けて実行管理

この実装により、Gemini APIが判断したツール呼び出しが自動的に実行され、結果がAIにフィードバックされます。

8. Gemini APIからのレスポンス形式

GeminiがツールUseの必要性を判断した場合、以下のような形式のレスポンスが返されます:

基本的なレスポンス構造

interface GenerateContentResponse {
  candidates?: Candidate[];
  promptFeedback?: GenerateContentResponsePromptFeedback;
  usageMetadata?: GenerateContentResponseUsageMetadata;
  
  // トップレベルのプロパティ
  text?: string;
  functionCalls?: FunctionCall[];  // ← ここにツール呼び出しが含まれる
  automaticFunctionCallingHistory?: Content[];
}

FunctionCall の構造

interface FunctionCall {
  id?: string;              // オプショナルな呼び出しID
  name: string;             // 呼び出すツール名
  args: Record<string, unknown>;  // ツールへの引数
  isClientInitiated?: boolean;    // クライアント起動かどうか
}

具体的なレスポンス例

  1. ツール呼び出しのみの場合:
{
  "functionCalls": [
    {
      "id": "fc1",
      "name": "read-file",
      "args": {
        "absolute_path": "/src/index.ts"
      }
    },
    {
      "name": "grep",
      "args": {
        "pattern": "TODO",
        "path": "./src"
      }
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 100,
    "candidatesTokenCount": 200,
    "totalTokenCount": 300
  }
}
  1. テキストとツール呼び出しの混在:
{
  "candidates": [{
    "content": {
      "parts": [{
        "text": "まず、そのファイルの内容を確認させていただきます..."
      }],
      "role": "model"
    }
  }],
  "functionCalls": [{
    "name": "read-file",
    "args": {
      "absolute_path": "/example.txt"
    }
  }]
}

ストリーミングレスポンスの場合

ストリーミングでは、複数のチャンクに分かれて送信されます:

// チャンク1: テキストコンテンツ
{
  "candidates": [{
    "content": {
      "parts": [{ "text": "お手伝いさせていただきます..." }]
    }
  }]
}

// チャンク2: 関数呼び出し
{
  "functionCalls": [{
    "name": "shell",
    "args": { "command": "npm test" }
  }]
}

処理の流れ

  1. レスポンス受信: Gemini APIからfunctionCallsを含むレスポンスを受信
  2. 抽出: resp.functionCalls配列から個々の関数呼び出しを取得
  3. 変換: 各呼び出しをToolCallRequestInfo形式に変換
  4. 実行: CoreToolSchedulerでツールを実行
  5. 結果返却: 実行結果をfunctionResponse形式でGeminiに返す

この仕組みにより、Geminiは必要に応じて複数のツールを組み合わせて使用し、複雑なタスクを段階的に解決できます。

まとめ

Gemini CLIは、以下の要素の組み合わせにより自律的なコード生成を実現しています:

  1. 包括的なシステムプロンプト: AIの行動ガイドライン
  2. 豊富なツールセット: 具体的な操作能力
  3. インテリジェントなスケジューリング: 効率的なタスク実行
  4. エラー回復機能: 自動的な問題解決
  5. 永続的なメモリ: セッション間での学習
  6. 洗練された関数呼び出しメカニズム: Gemini APIとの緊密な統合

この設計により、AIは最小限の人間の介入で複雑なソフトウェアエンジニアリングタスクを実行できます。同時に、ユーザーの制御と安全性を維持する確認システムを通じて、安全な動作を保証しています。

Gemini CLIは、「AI フレンドリー」なツール設計により、明確なフィードバック、エッジケースの優雅な処理、成功と失敗の両方からの学習を可能にし、自律的でありながら信頼性の高い環境を作り出しています。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment