Gemini CLI の概要
Gemini CLI は、Google の Gemini API を活用した強力なコマンドラインツールです。このツールは、開発者が効率的にプロジェクトを管理し、コードベースを調査するための直感的なインターフェースを提供します。
本記事では、Gemini CLI を使って Gemini CLI のソースコードを調査していきます。
調査結果のまとめ
Gemini CLI でできること
- フォルダ構成やコードの全体像を自動解析
- ファイルの中身を読み取り、機能や構造を要約
- キーワード・関数使用箇所の横断検索
- シェルコマンドの実行やテストの起動
- Web検索や外部ドキュメントの取得
- 簡単なコード修正やファイル生成の提案
Gemini CLI の限界・注意点
- 大規模プロジェクトでは一部情報が読み込まれないことがある
- 複雑なリファクタリングや型推論を伴う編集は苦手
- ファイル名や構成に依存した見落としが発生する可能性あり
- 組み込みツールの実装を見誤ることがある(例:WebSearch)
改善ポイント
- export GEMINI_API_KEY="YOUR_API_KEY" で高機能モデルを利用することで、より正確な解析や探索が可能になり、上記の限界や注意点は解決される可能性がある
- vscode + github copilot chat で Claude Sonnet4 を指定して実行すると、google_web_search ツールの実装場所を正しく探し出し実装内容も的確に回答できていた
Gemini CLI のソースコードの取得
調査したいソースコードを取得し、そのディレクトリに移動する
git clone https://github.com/google-gemini/gemini-cli.git
cd gemini-cli
Gemini CLI の実行
githubから直接実行
npx https://github.com/google-gemini/gemini-cli
installして実行
npm install -g @google/gemini-cli
gemini
Webブラウザが起動して google sign-in が促されるのでログインして Gemini CLI を起動する
ここから Gemini CLI で Gemini CLI を調査する
Gemini CLI のフォルダ構成
Gemini CLI のフォルダ構成を調査する
Geminiでのフォルダ構成調査
> このシステムのフォルダ構成を説明しなさい
✦ はい、承知いたしました。このプロジェクトのフォルダ構成について説明します。
これは gemini-cli というコマンドラインツールを開発するためのモノレポ(複数のパッケージを一つのリポジトリで管理する手法)構成のプロジェクトです。
主要なディレクトリとその役割は以下の通りです。
* `/` (ルートディレクトリ)
* プロジェクト全体に関する設定ファイルが置かれています。
* package.json: プロジェクト全体の依存関係やスクリプトを定義します。
* tsconfig.json: TypeScriptのコンパイラ設定です。
* eslint.config.js, .prettierrc.json: コードの品質とフォーマットを統一するための設定です。
* GEMINI.md: このAIアシスタント(私)がプロジェクトを理解し、正しく動作するためのルールが書かれています。
* `packages/`
* このプロジェクトの心臓部であり、実際のソースコードが含まれています。
* cli/: ユーザーが直接利用するコマンドラインインターフェース(CLI)のパッケージです。UIの描画やコマンドの解釈などを行います。
* core/: CLIのコアとなるロジックを持つパッケージです。AIモデルとの通信や、私が使用するツール(ファイル操作、シェルコマンド実行など)の実装が含まれています。
* `docs/`
* プロジェクトのドキュメントが格納されています。アーキテクチャ、各機能の使い方、コマンド一覧などがMarkdown形式で記述されています。
* `.github/`
* GitHubに関連する設定ファイルが置かれています。
* workflows/: CI/CD(継続的インテグレーション/継続的デプロイ)のための設定(例: ci.yml)があり、コードがプッシュされたときに自動でテストを実行します。
* `integration-tests/`
* 各ツールや機能が正しく連携して動作するかを確認するための結合テストのコードが置かれています。
* `scripts/`
* プロジェクトのビルド、開発環境のセットアップ、リリース準備などを行うための補助的なスクリプト群です。
* `.gcp/`
* Google Cloud Platform (GCP) を利用したデプロイやビルドに関する設定ファイルが置かれているようです。
簡単にまとめると、`packages/` にあるソースコードがプロダクト本体で、それ以外のディレクトリは開発、テスト、ドキュメント、デプロイなどをサポートするためのものです。
Geminiの調査結果について
eslint-rules
などツール用のフォルダの説明は省かれているが基本的に Gemini の調査内容に問題はない
Gemini CLI のアーキテクチャ調査
gemini cli のアーキテクチャを確認する
Geminiでのアーキテクチャ調査
> このシステムのアーキテクチャをソースコードもつかってざっくり動作を説明しなさい
✦ 承知いたしました。このシステムのアーキテクチャと動作の概要を、ソースコードを交えて説明します。
まず、アーキテクチャの基本を理解するために、公式のドキュメントを読んでみます。
╭───────────────────────────────────╮
│ ✔ ReadFile docs/architecture.md │
╰───────────────────────────────────╯
✦ ドキュメントの内容とソースコードを元に、システムのアーキテクチャと動作の概要を説明します。
このシステムは、大きく分けて2つの主要なパッケージで構成されています。
1. `packages/cli` (フロントエンド): ユーザーが直接操作するコマンドラインインターフェース部分です。
2. `packages/core` (バックエンド): Gemini APIとの通信や、ファイル操作などのツール実行を担う中心的なロジック部分です。
動作フロー
ユーザーがコマンドを入力してから応答が表示されるまでの流れは、以下のようになります。
1. ユーザー入力とUIの受付 (packages/cli)
まず、ユーザーがターミナルでコマンドを入力します。このUI部分は、Reactベースの ink というライブラリで構築されています。
* 起点となるファイル: packages/cli/src/gemini.tsx
このファイルの App コンポーネントが、チャット画面の描画やユーザーからの入力の管理を行っています。
2. Coreパッケージへの処理依頼
ユーザーが入力したプロンプトは、packages/cli から packages/core へと渡されます。core パッケージが、実際の頭脳部分の役割を果たします。
* `core`パッケージの入り口: packages/core/index.ts
ここから core の機能が呼び出されます。
3. Gemini APIとの通信 (packages/core)
core パッケージは、受け取ったプロンプトや会話履歴、そして利用可能なツールの一覧をまとめて、GoogleのGemini APIに送信します。
* API通信を担うファイル: packages/core/src/code_assist/server.ts
このファイル内の processRequest のような関数で、@google/genai ライブラリを使い、実際にAPIリクエストが行われます。
1 // packages/core/src/code_assist/server.ts の中のようなコード(イメージ)
2 import { GoogleGenerativeAI } from "@google/genai";
3
4 // ...
5
6 async function processRequest(prompt: string, history: any[], tools: any[]) {
7 const genAI = new GoogleGenerativeAI(apiKey);
8 const model = genAI.getGenerativeModel({ model: "gemini-pro", tools });
9
10 const chat = model.startChat({ history });
11 const result = await chat.sendMessage(prompt);
12 return result.response;
13 }
4. ツール実行 (Function Calling)
Geminiモデルが、ファイルの一覧取得や内容の読み取りが必要だと判断した場合、「ツールを使ってください」という特別な応答を返します。core
パッケージはこの応答を受け取り、対応するツールを実行します。
* ツールが定義されている場所: packages/core/src/tools/
例えば、fs.ts (ファイルシステム) や shell.ts (シェルコマンド) といったツールがここに定義されています。
core はツールの実行結果を再度Gemini APIに送信し、モデルは最終的な人間向けの応答を生成します。
5. 結果の表示 (packages/cli)
core パッケージから返ってきた最終的な応答を、packages/cli が受け取り、きれいにフォーマットしてターミナルに表示します。
まとめ
このように、gemini-cli は以下の流れで動作しています。
1. CLI (`cli`): ユーザーとの対話を受け持つ「顔」。
2. Core (`core`): Gemini APIと通信し、必要に応じてツールを実行する「頭脳」。
3. Tools (`tools`): ファイル操作など、ローカル環境と連携するための「手足」。
このモジュール化されたアーキテクチャにより、UIとコアロジックが分離され、開発や拡張がしやすくなっています。
図でアーキテクチャを確認する
> では調査した内容のソースコードの実装を読み解き、人間が読みやすい図として出力しなさい。mermaid が好ましい
✦ 承知いたしました。ここまでの調査内容とソースコードの理解に基づき、gemini-cli のアーキテクチャと処理の流れを Mermaid.js を使った図で表現します。
1 sequenceDiagram
2 actor User
3 participant CLI_Package as packages/cli<br>(React/Ink UI)
4 participant Core_Package as packages/core<br>(Backend Logic)
5 participant Tools as core/src/tools<br>(File System, Shell, etc.)
6 participant Gemini_API as Google Gemini API
7
8 User->>CLI_Package: プロンプトを入力
9 CLI_Package->>Core_Package: ユーザープロンプトを渡す (processRequest)
10 Core_Package->>Gemini_API: プロンプト、会話履歴、ツール定義を送信
11 Gemini_API-->>Core_Package: 応答 (テキスト or ツール実行リクエスト)
12
13 alt テキスト応答の場合
14 Core_Package-->>CLI_Package: 最終的なテキスト応答を返す
15 CLI_Package-->>User: 応答をフォーマットして表示
16 else ツール実行リクエストの場合 (Function Calling)
17 Core_Package->>Tools: 該当ツールを実行 (例: list_directory)
18 Note right of Core_Package: ファイル一覧取得などを実行
19 Tools-->>Core_Package: ツールの実行結果を返す
20 Core_Package->>Gemini_API: ツール実行結果を送信
21 Gemini_API-->>Core_Package: 実行結果を踏まえた最終応答を生成
22 Core_Package-->>CLI_Package: 最終的なテキスト応答を返す
23 CLI_Package-->>User: 応答をフォーマットして表示
24 end
図の解説
この図は、gemini-cli の主要なコンポーネント間のやり取りを時系列で示しています。
1. User (利用者): ターミナルでコマンド(プロンプト)を入力します。
2. CLI\_Package (`packages/cli`): ユーザーからの入力を受け付け、最終的な結果を表示するUI層です。ReactベースのInkで構築されています。
3. Core\_Package (`packages/core`): アプリケーションのバックエンドロジックを担当します。ユーザーの入力を処理し、Gemini APIとの通信を管理します。
4. Tools (`core/src/tools`): ファイルシステム操作やシェルコマンド実行など、ローカル環境と対話するための具体的な機能群です。core パッケージから呼び出されます。
5. Gemini\_API: Googleの生成AIモデルです。自然言語の応答を生成したり、必要に応じてツールの実行をリクエストしたりします。
処理は、ユーザーの入力から始まり、cli -> core -> Gemini API へと流れます。Gemini APIがツールの実行を要求した場合(Function Calling)、core は対応する Tools
を実行し、その結果を再度APIに送って最終的な答えを得ます。最後に、その答えが core -> cli -> User へと返されます。
mermaid の図
Geminiの調査結果について
Geminiの調査結果に問題はないようだ。
以前調査したBrowser-useの実装方法と似ており、Browser-use が
Geminiが呼び出すツールの調査
Geminiが呼び出すツール (tools) を調査する
Geminiで調査
> geminiが呼び出して利用するツールの内容をすべて紹介してください。機能について具体的に実装を確認したうえで何をすることができるのか、そしてどのような場合に利用されるのかを説明しなさい
✦ はい、承知いたしました。
packages/core/src/tools/ ディレクトリ内のソースコードをすべて確認し、Geminiが利用する各ツールの機能、実装の要点、そして具体的な利用シナリオをまとめました。
これらのツールは、Geminiが単なる対話AIではなく、ユーザーのローカル環境と連携して具体的な開発タスクを実行するための「手足」となる重要な機能です。
---
1. ファイルシステム操作ツール
これらのツールは、ローカルのファイルやディレクトリを操作する基本的な機能を提供します。主にNode.jsのfsモジュールをラップして作られています。
list_directory
* 機能: 指定されたディレクトリ内にあるファイルとサブディレクトリの一覧を取得します。
* 実装のポイント:
* Node.jsのfs.readdirSyncを内部で利用しています。
* .gitignoreを解釈して、バージョン管理されていないファイルや無視すべきファイルを結果から除外する機能があります。
* 利用シナリオ:
* ユーザーが「このプロジェクトのフォルダ構成を教えて」と尋ねた場合。
* 特定のディレクトリにどのようなファイルがあるかを確認し、次の操作(ファイル読み込みなど)を計画する場合。
read_file
* 機能: 指定された単一のファイルの内容を読み取ります。テキストファイルだけでなく、画像やPDFも限定的に扱えます。
* 実装のポイント:
* テキストファイルはNode.jsのfs.createReadStreamを使い、行単位での読み込み(オフセットや行数制限)に対応しています。これにより巨大なファイルの一部だけを効率的に読むことができます。
* 画像やPDFなどのバイナリファイルはfs.readFileSyncで読み込み、Base64エンコードしてモデルに渡せる形式に変換します。
* 利用シナリオ:
* ユーザーが「main.tsのコードを見せて」と特定のファイルの内容を知りたい場合。
* バグ修正や機能追加の際に、対象となるソースコードの現状を把握するために使います。
write_file
* 機能: 指定されたパスに、指定された内容で新しいファイルを作成、または既存のファイルを上書きします。
* 実装のポイント:
* Node.jsのfs.writeFileSyncを利用したシンプルな実装です。
* 書き込み先のディレクトリが存在しない場合は、fs.mkdirSyncで再帰的に作成します。
* 利用シナリオ:
* ユーザーが「新しいコンポーネント Button.tsx を作成して」と依頼した場合。
* テストコードを新しく生成する場合。
replace
* 機能: ファイル内の特定の文字列(old_string)を、新しい文字列(new_string)に置換します。
* 実装のポイント:
* read_fileでファイル全体を読み込み、JavaScriptのString.prototype.replace()またはString.prototype.replaceAll()で置換処理を行い、write_fileで書き戻します。
* 誤った置換を防ぐため、置換対象の文字列(old_string)には、変更箇所の前後数行の文脈を含めることが強く推奨されています。これにより、意図した箇所だけを正確に変更します。
* 利用シナリオ:
* リファクタリングで変数名や関数名を一括変更する場合。
* 非推奨のAPIを新しいAPIに書き換えるなど、定型的なコード修正を行う場合。
read_many_files
* 機能: globパターン(例: src/**/*.ts)に一致する複数のファイルを一度に読み込み、その内容を連結して返します。
* 実装のポイント:
* globライブラリを使って対象ファイルを検索し、それぞれのファイルをread_fileで読み込んでいます。
* ファイルごとに「--- {filePath} ---」というセパレータを挿入し、どの内容がどのファイルのものかモデルが識別できるように工夫されています。
* 利用シナリオ:
* ユーザーが「このプロジェクトのすべてのテストコードをレビューして」といった広範囲な依頼をした場合。
* プロジェクト全体のコードから、特定の機能がどのように実装されているか広範囲に調査する場合。
search_file_content
* 機能: 指定された正規表現パターンに一致する箇所を、プロジェクト内のファイルから検索します。
* 実装のポイント:
* 内部でglobを使いファイルを検索し、各ファイルを1行ずつ読みながら正規表現でマッチング処理を行います。
* 一致した行のファイルパス、行番号、行の内容をセットで返します。
* 利用シナリオ:
* ユーザーが「api.fetchを呼び出している箇所をすべて教えて」と、特定の関数や変数が使われている場所を探したい場合。
* エラーログに出力された特定のエラーメッセージが、コードのどこに起因するかを調査する場合。
glob
* 機能: globパターン(ワイルドカードを使ったファイルパス検索)に一致するファイルのリストを返します。
* 実装のポイント:
* globというnpmライブラリをそのまま利用しています。
* list_directoryと違い、再帰的に深い階層のファイルも一度に検索できます。
* 利用シナリオ:
* 「プロジェクト内のすべての.test.tsファイルを探して」といった、特定の拡張子や命名規則を持つファイル群を特定する場合。
---
2. シェルコマンド実行ツール
run_shell_command
* 機能: 任意のシェルコマンドを実行し、その標準出力、標準エラー、終了コードを返します。
* 実装のポイント:
* Node.jsのchild_process.spawnを使い、bash -c経由でコマンドを実行します。これにより、パイプやリダイレクトを含む複雑なコマンドも実行可能です。
* バックグラウンド実行(コマンド末尾の&)にも対応しています。
* 安全性のため、このツールはユーザーの明示的な許可がなければ実行されません。
* 利用シナリオ:
* npm installやnpm run testなど、プロジェクトの依存関係のインストールやテストの実行。
* git statusやgit diffを実行して、リポジトリの状態を確認する。
* データベースのマイグレーションスクリプトを実行するなど、開発ワークフローの一部を自動化する。
---
3. Web検索・コンテンツ取得ツール
google_web_search
* 機能: Google検索を実行し、検索結果(タイトル、URL、スニペット)のリストを返します。
* 実装のポイント:
* Gemini APIに組み込まれているGoogle検索機能(Function Calling)を利用しています。
* 利用シナリオ:
* ユーザーが「最新のReactのバージョンを教えて」と外部の情報を必要とする質問をした場合。
* エラーメッセージでググって解決策を探す場合。
* 利用したいライブラリの公式ドキュメントを探す場合。
web_fetch
* 機能: 指定されたURLのWebページの内容を取得します。
* 実装のポイント:
* 内部でnode-fetchのようなHTTPクライアントを使い、URLにGETリクエストを送信してHTMLなどのコンテンツを取得します。
* 利用シナリオ:
* google_web_searchで見つけた記事やドキュメントのURLを渡し、その詳細な内容を読み込んで要約や分析を行う場合。
---
4. 状態管理ツール
save_memory
* 機能: Geminiが対話の中で記憶しておくべき短い情報(事実)を保存します。
* 実装のポイント:
* ユーザーのホームディレクトリ以下の設定ファイル(例: ~/.gemini/memory.json)などに、キーバリュー形式で情報を永続化していると考えられます。
* 利用シナリオ:
* ユーザーが「僕の好きなフレームワークはVue.jsだと覚えておいて」と指示した場合。
* プロジェクト特有のルール(「このプロジェクトではpnpmを使う」など)を記憶させ、以降の対話でそのルールを前提とした応答をさせるために使います。
Geminiの調査結果について
Geminiの調査結果は正しいようだ
Geminiが呼び出すツールの実装を調査
ツールの実装を調査したい。例として google_web_search ツールの実装を知りたい
Geminiで調査
> google_web_searchについての具体的な実装ファイルと実装内容を簡単に紹介しなさい
✦ 承知いたしました。google_web_searchツールについて、具体的な実装ファイルと内容を簡単に紹介します。
まず、該当するソースコードを特定し、その内容を読み込みます。
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✔ ReadFile ...ackages/src/tools/google_web_search.ts │
│ │
│ File not found. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ おっと、失礼しました。google_web_search.ts というファイルは存在しないようです。
これは私の推測ですが、google_web_search は他のツール(fsやshellなど)のように packages/core/src/tools/ 内に独立したファイルとして実装されているわけではないようです。
ドキュメントや他のツールの実装から判断すると、google_web_search は Google Generative AI SDK(`@google/genai`)に元々組み込まれているネイティブな関数呼び出し(Function
Calling)機能として提供されている可能性が非常に高いです。
実装の仕組み(推定)
1. ツール定義:
packages/core/src/code_assist/server.ts のような場所で、Geminiモデルに渡すツールリストの中に、Googleから提供されているGoogleSearchツールをインスタンス化して含めます。
1 // packages/core/src/code_assist/server.ts の中のようなコード(イメージ)
2 import { GoogleGenerativeAI } from "@google/genai";
3 import { GoogleSearch }s from "@google/generative-ai/server";
4
5 // ...
6
7 const genAI = new GoogleGenerativeAI(apiKey);
8
9 // 利用可能なツールとしてGoogleSearchを定義
10 const tools = [new GoogleSearch()];
11
12 const model = genAI.getGenerativeModel({
13 model: "gemini-pro",
14 tools: {
15 functionDeclarations: tools, // SDKに組み込みのツールを渡す
16 },
17 });
18
19 // ...
2. モデルによる呼び出し:
ユーザーがWeb検索を必要とするような質問(例:「今日の天気は?」)をすると、Geminiモデルは応答として「GoogleSearchツールをこのクエリで実行してください」という指示を返します。
3. SDKによる自動実行:
@google/genai SDKは、このモデルからの指示を自動的に解釈します。SDKの内部でGoogle検索APIが呼び出され、検索が実行されます。
4. 結果の返却:
SDKは検索結果を取得し、それを自動的に次のモデルへの入力として送信します。モデルはその検索結果を元に、最終的な人間向けの回答を生成します。
まとめ
google_web_searchは、gemini-cliのプロジェクト内でファイルとしてコードが実装されているわけではなく、`@google/genai` SDKが提供する組み込みの機能です。
ℹ ⚡ Slow response times detected. Automatically switching from gemini-2.5-pro to gemini-2.5-flash for faster responses for the remainder of this session.
⚡ To avoid this you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
⚡ You can switch authentication methods by typing /auth
開発者は、その機能を「有効化」してモデルに渡すだけで、検索の実行から結果の送信までをSDKが裏側で自動的に処理してくれます。これにより、開発者は検索機能の実装の詳細を気にすることなく、簡単に
Web検索能力をAIに付与できるというわけです。
Geminiは google_web_search ツールの実装を探し出すことができなかった。
マニュアル調査
packages/core/src/tools/web-search.ts
ファイルで WebSearchTool クラスとして実装されている
Gemini API へリクエストを送って Google Search 機能を利用している。
const response = await geminiClient.generateContent(
[{ role: 'user', parts: [{ text: params.query }] }],
{ tools: [{ googleSearch: {} }] }, // Google検索ツールを有効化
signal,
);
Geminiの出力の分析結果
-
正しかった点
- Gemini APIがGoogle Searchツールを内包する機能を持っているという推測は正しい
- @google/genai SDK を通じて function calling の形でツールを利用しているという設計の認識も正確
- ツールを「渡す」ことによって自動的に機能が有効になるという点も正しい
-
誤っていた/不完全だった点
- ファイル探索が不十分
google_web_search.ts というファイルしか探しておらず、類似ファイル (web-search.ts) を発見できていない - 実装の存在を否定してしまった
実際には実装ファイルが存在しているのに、「組み込み機能でコードとしては存在しない」と判断してしまっている - Gemini CLIの探索範囲に限界があった
モジュール構成の柔軟性に対応しきれず、期待するファイル名のみに依存している
- ファイル探索が不十分
ツール登録
ツールを登録している実装場所を調査する
Geminiで調査
> ではtoolsを登録している場所は?
✦ 承知いたしました。ツールが登録されている場所についてですね。
これまでの調査と、GEMINI.md の「Core package」の説明(「Tool registration and execution logic」)から、ツールの登録は packages/core パッケージ内で行われていると推測できます。特に、Gemini
APIとの通信を担う packages/core/src/code_assist/server.ts が最も有力な候補です。
このファイル内で、GoogleGenerativeAI の getGenerativeModel メソッドにツールが渡されているはずです。
具体的な実装を確認するため、packages/core/src/code_assist/server.ts の内容を読み込みます。
╭────────────────────────────────────────────────────────╮
│ ✔ ReadFile ...ackages/core/src/code_assist/server.ts │
╰────────────────────────────────────────────────────────╯
✦ このファイルは、CodeAssistServer クラスを定義しており、Google Cloud の cloudcode-pa.googleapis.com エンドポイントと通信するためのロジックを含んでいます。これは、Gemini API
の直接的な呼び出しではなく、Google Cloud の Code Assist サービスを介した通信を行っているようです。
このファイル自体には、具体的なツールの登録ロジック(new GoogleSearch() のようなコード)は見当たりません。これは、CodeAssistServer
がより高レベルの抽象化を提供しており、ツールの登録は別の場所で行われていることを示唆しています。
ツールの登録場所の再調査
GEMINI.md の「Core package」の説明を再度確認すると、「Tool registration and execution logic」とあります。
packages/core/src/ ディレクトリ内で、ContentGenerator インターフェースを実装しているクラスや、@google/genai をインポートしている他のファイルを探すのが良さそうです。
特に、ContentGenerator を実装しているファイルや、generateContent メソッドを呼び出している箇所に注目します。
packages/core/src/core/contentGenerator.ts を見てみましょう。
╭────────────────────────────────────────────────────────╮
│ ✔ ReadFile ...ages/core/src/core/contentGenerator.ts │
╰────────────────────────────────────────────────────────╯
✦ packages/core/src/core/contentGenerator.ts は、ContentGenerator インターフェースを定義し、createContentGenerator 関数でその実装を生成しています。
この createContentGenerator 関数の中に、new GoogleGenAI(...) の呼び出しがあります。そして、googleGenAI.models が返されています。
@google/genai ライブラリの GoogleGenAI クラスのコンストラクタには、tools オプションを渡すことができます。しかし、ここでは直接渡されていません。
さらに、createCodeAssistContentGenerator という関数がインポートされています。これは ../code_assist/codeAssist.js から来ています。
packages/core/src/code_assist/codeAssist.ts を見てみましょう。
╭────────────────────────────────────────────────────────╮
│ ✔ ReadFile ...ges/core/src/code_assist/codeAssist.ts │
╰────────────────────────────────────────────────────────╯
✦ createCodeAssistContentGenerator は CodeAssistServer をインスタンス化しています。
ここまでの調査で分かったことは以下の通りです。
1. `CodeAssistServer` は直接ツールを登録していない。
2. `createContentGenerator` 関数が `GoogleGenAI` のインスタンスを生成している。
3. `GoogleGenAI` のコンストラクタには `tools` オプションがあるが、ここでは直接渡されていない。
これは、ツールの登録が以下のいずれかの方法で行われている可能性が高いことを示唆しています。
* `GoogleGenAI` の `models` プロパティが、内部的にツールを管理している。
* `GoogleGenAI` のインスタンス生成後に、別途ツールが追加されている。
* `GoogleGenAI` のコンストラクタに渡される `httpOptions` など、間接的な方法でツールが設定されている。
* `GoogleSearch` のような組み込みツールは、`GoogleGenAI` のインスタンスが生成されると自動的に利用可能になる。
特に、google_web_search の場合は、@google/genai SDKに組み込まれている機能であるため、明示的な登録コードは不要で、GoogleGenAI
のインスタンスが生成されると自動的に利用可能になる可能性が高いです。
他のカスタムツール(list_directoryなど)については、packages/core/src/core/contentGenerator.ts の createContentGenerator 関数が googleGenAI.models を返していることから、googleGenAI.models
が GenerateContentParameters を受け取る際に、カスタムツールも一緒に渡されている可能性があります。
結論として、カスタムツールの登録は、generateContent メソッドの呼び出し時に GenerateContentParameters の一部として渡されている可能性が高いです。
packages/core/src/core/contentGenerator.ts の ContentGenerator インターフェースの generateContent メソッドの定義を見てください。
1 export interface ContentGenerator {
2 generateContent(
3 request: GenerateContentParameters,
4 ): Promise<GenerateContentResponse>;
GenerateContentParameters は @google/genai から来ています。この型定義の中に、ツールに関する情報が含まれているはずです。
最終的な結論として、カスタムツールは `generateContent` メソッドの `GenerateContentParameters` 引数の一部として、動的にモデルに渡されていると考えられます。そして、google_web_search
のような組み込みツールは、GoogleGenAI のインスタンスが生成されると自動的に利用可能になる、という二段階の仕組みになっていると推測されます。
Using 1 GEMINI.md file
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ > Type your message or @path/to/file │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
マニュアル調査結果
ツールの登録は packages/core/src/config/config.ts
で実装されている
ツールに関連した情報は https://github.com/google-gemini/gemini-cli/blob/main/docs/core/tools-api.md
に記載されている
export function createToolRegistry(config: Config): Promise<ToolRegistry> {
const registry = new ToolRegistry(config);
const targetDir = config.getTargetDir();
const tools = config.getCoreTools()
? new Set(config.getCoreTools())
: undefined;
const excludeTools = config.getExcludeTools()
? new Set(config.getExcludeTools())
: undefined;
// helper to create & register core tools that are enabled
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const registerCoreTool = (ToolClass: any, ...args: unknown[]) => {
// check both the tool name (.Name) and the class name (.name)
if (
// coreTools contain tool name
(!tools || tools.has(ToolClass.Name) || tools.has(ToolClass.name)) &&
// excludeTools don't contain tool name
(!excludeTools ||
(!excludeTools.has(ToolClass.Name) &&
!excludeTools.has(ToolClass.name)))
) {
registry.registerTool(new ToolClass(...args));
}
};
registerCoreTool(LSTool, targetDir, config);
registerCoreTool(ReadFileTool, targetDir, config);
registerCoreTool(GrepTool, targetDir);
registerCoreTool(GlobTool, targetDir, config);
registerCoreTool(EditTool, config);
registerCoreTool(WriteFileTool, config);
registerCoreTool(WebFetchTool, config);
registerCoreTool(ReadManyFilesTool, targetDir, config);
registerCoreTool(ShellTool, config);
registerCoreTool(MemoryTool);
registerCoreTool(WebSearchTool, config);
return (async () => {
await registry.discoverTools();
return registry;
})();
}
Geminiの出力の分析結果
-
正しかった点
- 抽象構造の理解
CodeAssistServer は上位抽象レイヤーであり、ツールの登録自体は行っていないと判断した - ツール登録の候補箇所の推定
contentGenerator.ts における generateContent メソッドや GoogleGenAI の tools オプションに注目した点は妥当な推論 - 組み込みツールの扱いの理解
GoogleSearch のような組み込みツールは GoogleGenAI インスタンスの生成時に自動で利用可能になるという認識は正しい - 間接的な登録の可能性を考慮
明示的でない登録(たとえば generateContent のパラメータ経由や内部的な管理)も視野に入れていた - コードの文脈からの仮説構築
ソースコードを読み進め、登録処理が別ファイルにある可能性を論理的に導いた
- 抽象構造の理解
-
間違っていた点
- 実際の登録実装箇所の見落とし
本当の登録処理である config.ts の createToolRegistry() に到達できなかった - ファイル探索の範囲が不十分
config.ts や ToolRegistry に関する探索や逆引きが行われていなかった - 明示的登録処理の否定(または未言及)
実際には registerTool(new ToolClass(...)) という明確な登録処理が存在していたが、それを発見・記述していない - generateContent パラメータによる動的登録への過剰な依存
実装では静的な登録(createToolRegistry())が行われているのに、動的登録の可能性に偏りすぎた推論をしている - ドキュメントとの接続が不十分
tools-api.md のような公式ドキュメントの存在を指摘・参照していない
- 実際の登録実装箇所の見落とし
参考: VSCode + GitHub Copilot Chat + Claude Sonnect 4
Gemini では見つけられなかった google_web_search の実装箇所を VSCode + GitHub Copilot Chat + Claude Sonnect 4 に調査させた結果、望ましい結果が得られた。高機能なLLMをを用いることで Gemini CLI での調査結果も改善されると期待したい
google_web_searchについての具体的な実装ファイルと実装内容を簡単に紹介しなさい
`google_web_search` ツールの実装について、実際のソースコードを確認して詳細を調査します。 次に、ツールの登録場所を確認しましょう。 これで `google_web_search` ツールの実装について詳細な情報を取得できました。以下に詳細を説明します。
## Google Web Search ツールの実装詳細
### 実装ファイル
`google_web_search` ツールは web-search.ts ファイルで **WebSearchTool** クラスとして実装されています。
### 主要な実装内容
#### 1. クラス構造
```typescript
export class WebSearchTool extends BaseTool<WebSearchToolParams, WebSearchToolResult>
```
- `BaseTool` を継承したクラス
- ツール名は `'google_web_search'` として定義
- パラメータとして検索クエリ(`query`)を受け取る
#### 2. 核となる実装部分
ツールの実行時には、Gemini API に対して以下のようなリクエストを送信します:
```typescript
const response = await geminiClient.generateContent(
[{ role: 'user', parts: [{ text: params.query }] }],
{ tools: [{ googleSearch: {} }] }, // Google検索ツールを有効化
signal,
);
```
この実装では:
- Gemini API の `generateContent` メソッドを呼び出し
- `tools: [{ googleSearch: {} }]` オプションを指定してGoogle検索機能を有効化
- 検索クエリをユーザーメッセージとして送信
#### 3. 結果の処理
検索結果は以下のように処理されます:
- **検索結果テキスト**: Gemini APIからの応答テキストを取得
- **ソース情報**: `groundingMetadata` から検索ソースの詳細(URL、タイトル)を抽出
- **引用の追加**: 検索結果テキストに引用番号を自動挿入
- **ソースリスト**: 検索結果の最後にソース一覧を付与
#### 4. ツールの登録
config.ts ファイルで、以下のようにツールが登録されています:
```typescript
import { WebSearchTool } from '../tools/web-search.js';
// ...
registerCoreTool(WebSearchTool, config);
```
### 利用シナリオ
- ユーザーが最新の技術情報を検索したい場合
- エラーメッセージの解決策を探す場合
- ライブラリの公式ドキュメントを探す場合
この実装により、Gemini CLI は Gemini API の内蔵Google検索機能を活用して、リアルタイムでWeb検索を実行し、信頼性の高い情報源とともに結果を提供することができます。