🤗

Gemini CLIをWindowsで使ってみた

はじめに

日本時間2025年6月25日夜に、GoogleからGemini CLIがリリースされました。
https://github.com/google-gemini/gemini-cli/
https://blog.google/technology/developers/introducing-gemini-cli-open-source-ai-agent/
前提条件としてNode.js version 18以上がインストールされていることなのですが、それさえあればWindows 11でも下記コマンドで起動することができます。

Gemini CLI起動コマンド
npx https://github.com/google-gemini/gemini-cli

AnthropicのClaude Codeや、OpenAIのCodex CLIは、Windows 11で使用する場合WSL(Windows Subsystem for Linux)上で動かす必要があり、使用のハードルが高く、macに比べて使えない機能もありました。(例:画像ファイルをターミナルでドラッグ&ドロップさせて参照させる)
一方で、Gemini CLIはWSLがなくても直接PowerShell上で動くので、使用のハードルがグッと下がったと言えます。

特徴

基本情報

  • 開発者向けのターミナル(コマンドライン)で直接使えるAIアシスタント
  • Gemini 2.5 Proモデルを搭載し、100万トークンという大規模なコンテキストウィンドウに対応
  • Apache 2.0ライセンスの完全なオープンソース

無料枠について

  • 個人のGoogleアカウントでログインするだけで無料で利用可能
  • 業界最大級の利用枠:1分間に60リクエスト、1日1,000リクエストまで無料
  • 通常は有料のGemini Code Assistライセンスも無料で付与

主な機能

  • コーディング支援だけでなく、コンテンツ生成、問題解決、リサーチ、タスク管理など幅広い用途に対応
  • Google検索との連携で最新情報を取得可能
  • Model Context Protocol (MCP)による拡張機能のサポート
  • カスタマイズ可能なプロンプトと設定

VS Codeとの連携

  • Gemini Code Assistと同じ技術基盤を共有
  • VS Codeでもエージェントモードを通じて、複数ステップの計画立案や自動エラー回復などの高度な機能を利用可能

つかってみた

まずは、PowerShellで下記コマンドを実行します。

Gemini CLI起動コマンド
npx https://github.com/google-gemini/gemini-cli

数分待って下記画面となります。

テーマ(文字の配色)を選択
次に下記画面となります。

認証方法を選択(Googleアカウント、Gemini API Key使用など)
で、使えるようになります。

プロンプトを入力してコード生成へ!
実際にGemini CLIを使用している様子は下記となります。
https://youtu.be/_xHwJLdYgOA

Claude Codeと比較してみる

まだ触りはじめた段階で第一所感ですが、現時点ではClaude Codeの方が既存コードの改修においては精度が高かったです。 ある程度の規模のリポジトリに対して、同じ障害内容を伝えて分析させましたが、Geminiだと改修箇所が1ファイルで片手落ちでしたが、Claude Codeは2ファイル見つけて正しく改修してくれました。Claude Codeの方がよくリポジトリ内を把握して原因分析してくれているように見えました。まぁ、この辺も日進月歩なのでGemini CLIもどんどん精度を上げていくと思いますが!

具体的には、Gemini CLIとClaude Codeそれぞれに同じプロンプトをインプットして障害の原因分析と改修をお願いしました。

プロンプト
ultrathink.
@001_template.png のテンプレート管理画面で「編集」をクリックする。
すると、テンプレート編集のモーダルが表示される。
そして、 @002_prompt_temaplate.png タブ「プロンプト」のアイコン「ペン」をクリックする。
@003_prompt_temaplate.png のようにプロンプトを変更して「保存」ボタンをクリックする。
@004_prompt_temaplate_saved.png のように「更新」ボタンをクリックする。
するとプロンプトが保存される認識だが、 @005_prompt_temaplate_reopen.png のように改めて開くとプロンプトが保存されておらず変更前が表示される。
原因を分析して改修してほしい。
この辺、テーブル「template」のカラム「blocks」にてJSON形式でデータが入っているように見える。

それぞれの思考過程と対応内容は下記となります。Claude Codeは自動でToDoを作って確実に分析と改修をしているように見えますね。Geminiもプロンプト次第で同じような挙動になるかもしれません。

Gemini CLI の思考過程と対応内容
Gemini CLI の思考過程と対応内容
 ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
 │ ✔  ReadManyFiles Will attempt to read and concatenate files using patterns: `001_template.png`, `002_prompt_temaplate.png`, `003_prompt_temaplate.png`, `004_prompt_temaplate_saved.png`, `… │
 │                                                                                                                                                                                              │
 │    ### ReadManyFiles Result (Target Dir: `C:\temp\AI-OCR_v2`)                                                                                                                                │
 │                                                                                                                                                                                              │
 │    Successfully read and concatenated content from **5 file(s)**.                                                                                                                            │
 │                                                                                                                                                                                              │
 │    **Processed Files:**                                                                                                                                                                      │
 │    - `001_template.png`                                                                                                                                                                      │
 │    - `002_prompt_temaplate.png`                                                                                                                                                              │
 │    - `003_prompt_temaplate.png`                                                                                                                                                              │
 │    - `004_prompt_temaplate_saved.png`                                                                                                                                                        │
 │    - `005_prompt_temaplate_reopen.png`                                                                                                                                                       │
 ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ 承知いたしました。プロンプトテンプレートの編集内容が保存されない問題ですね。原因を調査し、修正します。


  まず、関連する可能性のあるファイルを特定するために、ファイル名に "template" を含むファイルを検索します。
 ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
 │ ✔  FindFiles '**/*template*'                                                                                                                                                      │
 │                                                                                                                                                                                   │
 │    Found 10 matching file(s)                                                                                                                                                      │
 ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ プロンプトテンプレートが保存されない問題について、承知いたしました。原因を調査し、修正します。

  まず、関連しそうなファイルとして、以下のものが挙げられます。


   * frontend/src/pages/TemplatesPage.tsx: テンプレート管理のメインページ
   * frontend/src/components/PromptTemplateEditor.tsx: プロンプトテンプレートのエディタコンポーネント
   * backend/src/templates/templates.service.ts: テンプレートロジックを処理するバックエンドサービス
   * backend/src/templates/templates.controller.ts: テンプレート関連のAPIリクエストを処理するコントローラ
   * backend/src/entities/template.entity.ts: blocksカラムを含むテンプレートのエンティティ定義
   * backend/src/entities/prompt-template.entity.ts: プロンプトテンプレートのエンティティ定義


  問題は、フロントエンドからのデータ送信か、バックエンドでのデータ処理・保存方法にある可能性が高いと考えられます。


  まずは、frontend/src/components/PromptTemplateEditor.tsx を読み、エディタの動作を理解することから始めます。
 ╭─────────────────────────────────────────────────╮
 │ ✔  ReadFile frontend\\PromptTemplateEditor.tsx  │
 ╰─────────────────────────────────────────────────╯
✦ PromptTemplateEditor.tsx を確認しました。savePrompt 関数内で onChange コールバックが呼び出され、更新されたプロンプトのリストが渡されています。コンポーネント自体のロジックは正しそうです。


  問題は、このコンポーネントの親、つまり TemplatesPage.tsx が onChange イベントをどのように処理しているかにある可能性が高いです。TemplatesPage.tsx
  で状態が適切に更新されていないか、最終的な「更新」ボタンがクリックされたときに変更されたプロンプトがバックエンドに送信されていない可能性があります。


  frontend/src/pages/TemplatesPage.tsx を調べて、PromptTemplateEditor がどのように使用され、onChange イベントがどのように処理されているかを確認します。
 ╭──────────────────────────────────────────────────────╮
 │ ✔  ReadFile ...frontend\src\pages\TemplatesPage.tsx  │
 ╰──────────────────────────────────────────────────────╯
✦ TemplatesPage.tsx を確認したところ、handleEdit 関数がプロンプトの変更をバックエンドに送信していないことが原因であると判明しました。handleEdit 関数は、テンプレートの
  name、description、blocks のみを送信しており、更新された prompts の状態が含まれていません。


  この問題を修正するために、handleEdit 関数を修正し、templateApi.update の呼び出しに prompts を含めるようにします。具体的には、promptTemplates: prompts を更新データに追加します。


  以下の様にfrontend/src/pages/TemplatesPage.tsxを修正します。
 ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
 │ ✔  Edit ...frontend\src\pages\TemplatesPage.tsx:       // テンプレートの全情報を一度に更新... =>       // テンプレートの全情報を一度に更新...                                     │
 │                                                                                                                                                                                   │
 │    166    await templateApi.update(editDialog.id, {                                                                                                                               │
 │    167      name: formData.name,                                                                                                                                                  │
 │    168      description: formData.description,                                                                                                                                    │
 │    169  -   blocks: formData.blocks                                                                                                                                               │
 │    169  +   blocks: formData.blocks,                                                                                                                                              │
 │    170  +   promptTemplates: prompts,                                                                                                                                             │
 │    171    });                                                                                                                                                                     │
 │    172                                                                                                                                                                            │
 │    173    setEditDialog(null);                                                                                                                                                    │
 ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ 修正が完了しました。handleEdit 関数に promptTemplates: prompts を追加し、プロンプトの変更がバックエンドに送信されるようにしました。


  これにより、プロンプトテンプレートの編集内容が正しく保存されるはずです。
Claude Code の思考過程と対応内容
Claude Code の思考過程と対応内容
✻ Thinking…

  画像を見て問題を理解する:

  1. 001_template.png - テンプレート管理画面でテンプレートの一覧が表示されている
  2. 002_prompt_temaplate.png - 編集モーダルの「プロンプト」タブで、プロンプトテンプレートの編集画面が表示。ユーザーブロックに「領収書基本情報(receipt_main)」と表示されている
  3. 003_prompt_temaplate.png - プロンプト編集画面でプロンプト内容を「あああの情報を抽出してください」と変更し、「## 重要事項」セクションが追加されている
  4. 004_prompt_temaplate_saved.png - 「保存」ボタンをクリックした後の画面。プロンプトタブに戻った状態
  5. 005_prompt_temaplate_reopen.png - 再度開くと、プロンプト内容が元の「領収書の情報を抽出してください」に戻っている

  問題: プロンプトテンプレートの変更が保存されていない。

  考えられる原因:
  1. フロントエンドでプロンプトの変更がテンプレートのblocksデータに正しく反映されていない
  2. バックエンドAPIで保存処理が正しく行われていない
  3. プロンプトテンプレートとブロック定義の連携に問題がある

  テーブル「templates」のカラム「blocks」にJSON形式でデータが入っているとのことなので、プロンプト内容もこのJSON内に保存されている可能性が高い。

  I'll investigate the key areas that might be causing the save failure. I'll start by examining the frontend editing component's data handling, tracing how changes are captured and prepared for
  transmission. Next, I'll look into the backend API's update mechanism, checking if the received data is being correctly processed and stored in the templates table. The interaction between the prompt
  template and block definitions seems critical, so I'll verify their synchronization process carefully.

● 画像から、プロンプト編集後に保存しても変更が保持されない問題を確認しました。この問題を調査・修正します。

● Update Todos
  ⎿  ☐ プロンプト保存が機能しない問題の調査
     ☐ フロントエンドのプロンプト編集・保存処理の分析
     ☐ バックエンドAPIのテンプレート更新処理確認
     ☐ プロンプト保存ロジックの修正実装
     ☐ プロンプト保存機能のテスト確認

✻ Thinking…

  まず、フロントエンドのプロンプト編集関連のコンポーネントを探す必要がある。画像から判断すると、テンプレート編集ダイアログの中にプロンプトタブがあるようだ。

  TemplatesPageやTemplateDialogなどのコンポーネントを探し、プロンプト編集がどのように実装されているか確認する。

● まず、フロントエンドのプロンプト編集関連のコンポーネントを調査します。

● Task(プロンプト保存処理の調査)
  ⎿  Done (11 tool uses · 53.3k tokens · 1m 32.9s)

✻ Thinking…

  TemplatesPageコンポーネントとPromptTemplateEditorコンポーネントの詳細を確認して、どのように修正すべきか検討する必要がある。

  問題の根本原因は:
  1. TemplatesPageのhandleEdit関数でプロンプトの保存処理が実装されていない
  2. APIにcreatePromptTemplate関数が不足している
  3. プロンプトの変更はUIレベルでのみ動作し、バックエンドに保存されていない

  修正のアプローチ:
  1. APIにcreatePromptTemplate関数を追加
  2. TemplatesPageのhandleEdit関数でプロンプトの保存処理を実装
  3. 既存のプロンプトの更新と新規プロンプトの作成を適切に処理

● 調査結果から、プロンプトの変更がバックエンドに保存されていない問題が確認できました。関連ファイルを詳しく確認します。

● Update Todos
  ⎿  ☒ プロンプト保存が機能しない問題の調査
     ☐ フロントエンドのプロンプト編集・保存処理の分析
     ☐ バックエンドAPIのテンプレート更新処理確認
     ☐ プロンプト保存ロジックの修正実装
     ☐ プロンプト保存機能のテスト確認

✻ Thinking…

  TemplatesPageのコードを読んで、プロンプトの保存処理の実装方法を確認する必要がある。
  特に以下を確認:
  1. handleEdit関数でプロンプトがどのように扱われているか
  2. formDataの構造
  3. プロンプトの状態管理

  その後、APIファイルも確認して、createPromptTemplate関数を追加する必要がある。

● Read(frontend/src/pages/TemplatesPage.tsx)
  ⎿  Read 100 lines (ctrl+r to expand)

✻ Thinking…

  コードを見ると、handleEdit関数(159-180行目)ではテンプレートの基本情報とblocksのみを更新している。プロンプトの保存処理が全く実装されていない。

  また、openEditDialog関数(192-201行目)では、プロンプトをsetPrompts(template.promptTemplates || [])で状態に設定しているが、これは編集ダイアログ内でのみ使用されており、保存時には使われていない。

  次に、PromptTemplateEditorコンポーネントとAPIファイルを確認して、プロンプトの保存処理の実装方法を検討する。

● Read(frontend/src/pages/TemplatesPage.tsx)
  ⎿  Read 81 lines (ctrl+r to expand)

✻ Thinking…

  コードを見ると、488-496行目でPromptTemplateEditorコンポーネントが使用されている。prompts状態をonChangeで更新しているが、実際の保存処理(handleEdit関数)ではこのprompts状態が使われていない。

  次に、APIファイルを確認して、プロンプトテンプレートの作成・更新・削除のAPIがどのように実装されているか、またcreatePromptTemplate関数が本当に不足しているか確認する。

● Read(frontend/src/services/api.ts)
  ⎿  Read 27 lines (ctrl+r to expand)

✻ Thinking…

  APIファイルを確認すると、確かにupdatePromptTemplateとdeletePromptTemplateはあるが、createPromptTemplate関数が不足している。

  次に、バックエンドのAPIエンドポイントを確認して、プロンプトテンプレートの作成APIが存在するか確認する必要がある。また、ブロックとプロンプトの関係についても理解する必要がある。

  templateApi.updateでテンプレートを更新する際に、プロンプトも一緒に保存する必要があるのか、それとも別々のAPIコールで保存する必要があるのかを確認する。

● Update Todos
  ⎿  ☒ プロンプト保存が機能しない問題の調査
     ☒ フロントエンドのプロンプト編集・保存処理の分析
     ☐ バックエンドAPIのテンプレート更新処理確認
     ☐ プロンプト保存ロジックの修正実装
     ☐ プロンプト保存機能のテスト確認

✻ Thinking…

  バックエンドのプロンプトテンプレート関連のAPIコントローラーを確認する必要がある。特に、PromptTemplatesControllerやTemplatesControllerの実装を確認して、プロンプトテンプレートの作成・更新・削除のエンドポ
  イントがどのように実装されているか確認する。

● Task(バックエンドAPI調査)
  ⎿  Done (11 tool uses · 50.9k tokens · 1m 30.8s)

✻ Thinking…

  バックエンドAPIの調査結果から、プロンプトテンプレートの作成APIがPOST
  /api/v1/templates/:id/promptsとして実装されていることが確認できた。しかし、フロントエンドのapi.tsにはこのエンドポイントへのアクセス関数が定義されていない。

  問題の解決方法:
  1. フロントエンドのapi.tsにcreatePromptTemplate関数を追加
  2. TemplatesPageのhandleEdit関数でプロンプトの保存処理を実装
  3. 既存のプロンプトと新規プロンプトを適切に処理

  実装のステップ:
  1. api.tsにcreatePromptTemplate関数を追加
  2. TemplatesPageで、テンプレート更新時にプロンプトも同時に保存する処理を追加
  3. 既存プロンプトの更新、新規プロンプトの作成、削除されたプロンプトの削除を適切に処理

● Update Todos
  ⎿  ☒ プロンプト保存が機能しない問題の調査
     ☒ フロントエンドのプロンプト編集・保存処理の分析
     ☒ バックエンドAPIのテンプレート更新処理確認
     ☐ プロンプト保存ロジックの修正実装
     ☐ プロンプト保存機能のテスト確認

✻ Thinking…

  調査が完了したので、修正実装を開始する。

  1. api.tsにcreatePromptTemplate関数を追加
  2. TemplatesPageのhandleEdit関数を修正してプロンプトも保存する

  まず、api.tsファイルを修正する。

● 問題の原因が判明しました。プロンプトの変更が保存されていない理由は以下の通りです:

  1. フロントエンドのAPI関数が不足: createPromptTemplate関数が未実装
  2. 保存処理の欠如: handleEdit関数でプロンプトの保存処理が実装されていない

  修正を実装します。

  まず、API関数を追加します:

● Update(frontend/src/services/api.ts)
  ⎿  Updated frontend/src/services/api.ts with 7 additions
       236        api.get(`/api/v1/workflows/states/${stateId}/actions`),
       237    };
       238
       239 +  export const createPromptTemplate = (
       240 +    templateId: string,
       241 +    prompts: Partial<PromptTemplate>[],
       242 +  ) => {
       243 +    return api.post(`/api/v1/templates/${templateId}/prompts`, prompts);
       244 +  };
       245 +
       246    export const updatePromptTemplate = (
       247      promptId: string,
       248      prompt: Partial<PromptTemplate>,

✻ Thinking…

  次に、TemplatesPageのhandleEdit関数を修正して、プロンプトの保存処理を追加する必要がある。

  プロンプトの保存処理では以下を考慮する必要がある:
  1. 既存のプロンプトの更新
  2. 新規プロンプトの作成
  3. 削除されたプロンプトの削除

  まず、プロンプトの状態を確認して、どのプロンプトが新規/更新/削除されたかを判定する必要がある。

● 次に、TemplatesPageのhandleEdit関数を修正してプロンプトの保存処理を追加します:

● Read(frontend/src/pages/TemplatesPage.tsx)
  ⎿  Read 30 lines (ctrl+r to expand)

✻ Thinking…

  apiファイルのインポートを確認する必要がある。

● Read(frontend/src/pages/TemplatesPage.tsx)
  ⎿  Read 20 lines (ctrl+r to expand)

✻ Thinking…

  api関数のインポートを追加する必要がある。

● Update(frontend/src/pages/TemplatesPage.tsx)
  ⎿  Updated frontend/src/pages/TemplatesPage.tsx with 1 addition and 1 removal
       36      FileCopy,
       37    } from '@mui/icons-material';
       38    import { useAuth } from '../contexts/AuthContext';
       39 -  import { templateApi } from '../services/api';
       39 +  import { templateApi, createPromptTemplate, updatePromptTemplate, deletePromptTemplate } from '../services/api';
       40    import PromptTemplateEditor from '../components/PromptTemplateEditor';
       41    import BlockDefinitionEditor from '../components/BlockDefinitionEditor';
       42

✻ Thinking…

  次に、handleEdit関数を修正してプロンプトの保存処理を追加する。編集ダイアログで管理しているprompts状態を使用して、プロンプトの作成・更新・削除を処理する必要がある。

  まず、既存のプロンプトを保持するための状態を追加し、新規・更新・削除を判定できるようにする必要がある。

● Update(frontend/src/pages/TemplatesPage.tsx)
  ⎿  Updated frontend/src/pages/TemplatesPage.tsx with 43 additions
       169            blocks: formData.blocks
       170          });
       171
       172 +        // プロンプトの保存処理
       173 +        const originalPrompts = editDialog.promptTemplates || [];
       174 +        const currentPrompts = prompts;
       175 +
       176 +        // 既存プロンプトのIDリスト
       177 +        const originalIds = originalPrompts.map(p => p.id);
       178 +        const currentIds = currentPrompts.filter(p => p.id).map(p => p.id);
       179 +
       180 +        // 削除されたプロンプトを処理
       181 +        const deletedIds = originalIds.filter(id => !currentIds.includes(id));
       182 +        for (const id of deletedIds) {
       183 +          await deletePromptTemplate(id);
       184 +        }
       185 +
       186 +        // 新規プロンプトと更新プロンプトを分離
       187 +        const newPrompts = currentPrompts.filter(p => !p.id);
       188 +        const existingPrompts = currentPrompts.filter(p => p.id);
       189 +
       190 +        // 既存プロンプトを更新
       191 +        for (const prompt of existingPrompts) {
       192 +          const originalPrompt = originalPrompts.find(p => p.id === prompt.id);
       193 +          if (originalPrompt && JSON.stringify(originalPrompt) !== JSON.stringify(prompt)) {
       194 +            await updatePromptTemplate(prompt.id, {
       195 +              role: prompt.role,
       196 +              content: prompt.content,
       197 +              blockId: prompt.blockId,
       198 +              sequenceOrder: prompt.sequenceOrder,
       199 +              isActive: prompt.isActive
       200 +            });
       201 +          }
       202 +        }
       203 +
       204 +        // 新規プロンプトを作成
       205 +        if (newPrompts.length > 0) {
       206 +          await createPromptTemplate(editDialog.id, newPrompts.map(p => ({
       207 +            role: p.role,
       208 +            content: p.content,
       209 +            blockId: p.blockId,
       210 +            sequenceOrder: p.sequenceOrder,
       211 +            isActive: p.isActive
       212 +          })));
       213 +        }
       214 +
       215          setEditDialog(null);
       216          await loadTemplates();
       217        } catch (err: any) {

✻ Thinking…

  これで修正が完了した。次に、handleCreate関数も同様に修正する必要があるかもしれない。新規テンプレート作成時にもプロンプトを保存する必要があるか確認する。

  まず、TypeScriptの型エラーがないか確認するために、ビルドを実行して確認する必要がある。

● Bash(cd /workspace/frontend && npm run build)
  ⎿  No (tell Claude what to do differently)

Gemini CLIは TemplatesPage.tsx のみを改修したのに対して、Claude Codeは TemplatesPage.tsxapi.ts を改修してくれました。また、 TemplatesPage.tsx の改修内容もClaude Codeが正確でした。

おわりに

Gemini CLIがリリースされて、嬉しくなって速報で記事を書きました。この記事の内容もまだまだ試行回数が少ない中の見解なので、今後変わるかもです。Claude Codeと比較しながらより良い使い分けを模索できたらと考えています!

Accenture Japan (有志)

Discussion