1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gemini CLIのPlan Modeはヘッドレスだと実装まで進む(v0.64.0)

1
Posted at

はじめに

--approval-mode plan を付けておけば、CI で Gemini CLI を回してもファイルは書き換わらないと考えたくなります。CLI のヘルプも plan を「read-only mode」と説明しています。ところが非対話(ヘッドレス)実行では、Plan Mode は計画を立てたあと自分で抜けて、承認なしの実装フェーズへ進む設計になっています。

対象読者は、Gemini CLI を -p で CI やスクリプトに組み込んでいる、または組み込もうとしている開発者です。

この記事は 2 つの時点の記録でできています。

  • 2026-07-23 時点・v0.52.0: API キーを使ってヘッドレス実行し、同じプロンプトで「書き込む回」と「聞き返して止まる回」に割れた記録
  • 2026-10-15 時点・v0.64.0: 現行版をインストールし、同梱のポリシーファイルとシステムプロンプトを v0.52.0 と突き合わせた結果(今回は API キーが無く、モデルを呼ぶ実行はしていません)

TL;DR

  • 現行版は @google/gemini-cli v0.64.0(2026-10-15 時点の latest)
  • 非対話時に exit_plan_mode を自動承認するポリシーは、v0.52.0 と v0.64.0 で同じ内容のまま
  • 変わったのはシステムプロンプトです。v0.52.0 は非対話でも「ユーザーとチャットで合意してから exit_plan_mode を呼べ」と指示していて、これが「聞き返して止まる回」の原因になりえました。v0.64.0 の非対話向け指示は「計画を確定したら exit_plan_mode を呼び、実装を始める」です
  • したがって現行版のヘッドレス Plan Mode は「計画してから実装する」モードとして読むのが正確です。書き込みを防ぐ安全装置として使うなら、ユーザーポリシーで exit_plan_mode を拒否するなど別の手当てが要ります
  • 未信頼ディレクトリでは --approval-mode plan が default に上書きされる挙動は v0.64.0 でも残っています

前提環境

今回(2026-10-15)の確認に使った環境です。

  • クラウド実行環境(Linux コンテナ・Node.js)
  • @google/gemini-cli v0.64.0 と v0.52.0 をそれぞれ別ディレクトリに npm install
  • GEMINI_API_KEY は未設定(認証エラーで止まる手前までの挙動と、同梱ファイルの中身だけを確認)
$ npm view @google/gemini-cli dist-tags
{
  nightly: '0.65.0-nightly.20261014.g42c518220',
  preview: '0.65.0-preview.0',
  latest: '0.64.0',
  ...
}

v0.52.0 での記録(2026-07-23 時点)

以下は 2026-07-23 に v0.52.0 と Gemini API の無料枠キーで実行した記録です。v0.64.0 ではモデルを呼ぶ実行をしていないため、同じ結果になるかは再確認できていません。

実行したのは、相対パスにファイルを作らせるプロンプトを Plan Mode で 2 回流すことでした。

gemini --skip-trust --approval-mode plan -p "Create a file named hello.txt (relative path) containing the text: hello from plan mode. Then tell me what you did." -o json

1 回目は hello.txt が実際に作成されました。-o json の stats.tools.byName には次のツール呼び出しが残っていました。

ツール 回数 結果
update_topic 3 success
list_directory 1 success
write_file 2 success
exit_plan_mode 1 success
run_shell_command 1 success

モデルが exit_plan_mode を呼んで Plan Mode を抜け、そのあと write_file を実行した流れです。

ファイルを消して同じコマンドを流した 2 回目は、ファイルが作成されず、response は次の文面でした(原文まま)。

I am currently in **Plan Mode**, which restricts me to read-only tools and plan creation.
I cannot create `hello.txt` in your workspace until we exit this mode.

Would you like me to:
1. Create an implementation plan for this task?
2. Exit Plan Mode so I can create the file directly?

入力もフラグも同じで、結果だけが割れました。書き込むかどうかを決めていたのはツール実行層ではなく、モデルが exit_plan_mode を呼ぶかどうかでした。

v0.64.0 で変わらなかったこと:自動承認ポリシー

Plan Mode の許可・拒否は、パッケージに同梱された bundle/policies/plan.toml で決まります。v0.64.0 の該当部分を抜き出すと次のとおりです。

[[rule]]
toolName = "exit_plan_mode"
decision = "ask_user"
priority = 70
modes = ["plan"]
interactive = true

[[rule]]
toolName = "exit_plan_mode"
decision = "allow"
priority = 70
modes = ["plan"]
interactive = false

対話時は ask_user、非対話時は allow です。v0.52.0 の同じファイルを確認すると、この 2 つのルールは同一でした。Plan Mode 中の書き込みは、.gemini/tmp/.../plans/ 配下の .md ファイルに対する write_file / replace だけが許可され、それ以外は catch-all の deny に落ちます。

公式ドキュメントの Plan Mode も、非対話環境ではポリシーエンジンが enter_plan_mode と exit_plan_mode を自動承認し、Plan Mode を抜けたあとは Default ではなく YOLO モードに切り替わると説明しています。つまり Plan Mode の「読み取り専用」は Plan Mode の中にいる間の制約であり、ヘッドレス実行全体が読み取りで終わる保証ではありません。

v0.64.0 で変わったこと:システムプロンプト

v0.52.0 で結果が割れた理由の候補は、モデルに渡される Plan Mode の指示文にあります。同梱バンドルから exit_plan_mode の使い方を指示する箇所を抜き出して比べました。

v0.52.0 では、対話・非対話で共通の文が使われていました。

ONLY use the built-in exit_plan_mode tool to present the plan for formal approval
AFTER you have reached an informal agreement with the user in the chat regarding
the proposed strategy. ... When called, this tool will present the plan and
${options.interactive ? "formally request approval." : "begin implementation."}

非対話でも「チャットでユーザーと合意してから」という条件が付いています。ユーザーがいないヘッドレス実行では、この条件を守ろうとしたモデルが聞き返して終わり、守らずに進んだモデルが実装まで終える、という分岐が起こりえます。2026-07-23 の 2 回目の応答は、まさに前者の形でした。

v0.64.0 では、この部分が対話と非対話で別の文になっています(抜粋。左の見出しと改行は整形のために付けたものです)。

interactive:     ONLY use the built-in exit_plan_mode tool to present the plan for formal
                 approval AFTER you have reached an informal agreement with the user ...
non-interactive: Use the built-in exit_plan_mode tool to finalize the plan. ...
                 When called, this tool will present the plan and begin implementation.

非対話向けの文から「ユーザーとの合意」が消え、計画を確定したら exit_plan_mode を呼んで実装に入るよう指示しています。冒頭の目的文は両版とも共通で、非対話では「create a design document before proceeding autonomously」です。

GitHub では、非対話実行で Plan Mode が合意待ちのまま止まる問題が #28913(v0.55.1 で報告)として挙がっています。今回の調査では、この Issue の現在の状態や、プロンプト変更と結びつく PR・リリースノートの記載までは確認できていません。

v0.52.0 では E の分岐がプロンプトの矛盾で揺れていました。v0.64.0 のプロンプトは「呼ぶ」側へ寄せる書き方です。

v0.64.0 でも残っている:未信頼ディレクトリでの上書き

信頼されていないディレクトリでは、--approval-mode plan の指定自体が無視されます。v0.64.0 で API キー無しのまま実行すると、認証エラーより前にこの警告が出ました。

$ gemini --approval-mode plan -p "hi" -o json
Approval mode overridden to "default" because the current folder is not trusted.
{
  "session_id": "...",
  "error": {
    "type": "Error",
    "message": "Please set an Auth method in your .../.gemini/settings.json or specify one of the following environment variables before running: GEMINI_API_KEY, GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_GENAI_USE_GCA",
    "code": 41
  }
}

--skip-trust を付けるか、GEMINI_CLI_TRUST_WORKSPACE=true を設定して実行すると、上書きの警告は出ずに認証エラーだけが返りました。CI で新しくチェックアウトしたディレクトリをそのまま使うと、指定した Plan Mode は効いていません。

CI で Plan Mode を使うときの判断

ヘッドレスの Plan Mode を「書き込まない保証」として使うのは、v0.52.0 でも v0.64.0 でも成り立ちません。v0.52.0 ではモデルの判断次第で書き込み、v0.64.0 ではプロンプトが実装まで進むよう指示しているからです。用途ごとの手当ては次のとおりです。

やりたいこと 手当て
計画だけ作らせて、書き込みは絶対に避けたい ユーザーポリシーで Plan Mode 中の exit_plan_mode を deny にする(同梱 plan.toml のコメントでは、User ポリシーは Default ポリシーより常に優先される)
計画から実装までを無人で回したい 現行版のヘッドレス Plan Mode の想定どおり。実装フェーズは YOLO 相当なので、runner の権限とサンドボックス(-s)で被害範囲を絞る
実行後に書き込みの有無を判定したい response の文面ではなく、-o json の stats.tools.byName に write_file・replace・run_shell_command が含まれるかを機械的に調べる

ポリシーのカスタマイズは公式ドキュメントで ~/.gemini/policies/ に TOML を置く方法が案内されており、Plan Mode だけに効かせたいルールには modes = ["plan"] を明示する必要があります。ただし今回は API キーが無く、拒否ルールを入れた状態でモデルが本当に止まるかは実行して確かめていません。導入する場合は、自分の CI で stats.tools.byName を見て効いていることを確認してください。

まとめ

  • v0.52.0 のヘッドレス Plan Mode で同じプロンプトの結果が割れたのは、非対話でも「ユーザーと合意してから抜けろ」と指示するプロンプトと、exit_plan_mode を自動承認するポリシーが噛み合っていなかったためと読めます
  • v0.64.0 ではポリシーはそのままで、非対話向けのプロンプトが「計画を確定したら抜けて実装する」に変わっています
  • 未信頼ディレクトリで plan が default に上書きされる挙動は現行版でも残っています

冒頭の「--approval-mode plan なら CI でも書き換わらない」という期待に対する答えは、現行版ではよりはっきり「いいえ」です。手元の CI で Plan Mode を使っているなら、書き込みを止めたいのか、計画から実装まで任せたいのかを先に決め、前者ならポリシーで exit_plan_mode を塞いでください。

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?