GEMINI LABEN
3.8LIVE — gemini-3.8-live と extended-thinking 版が GA になりました。低遅延の音声エージェント向けで、非同期の function calling が既定です2.5FLASH — 二次情報で広まっている「2.5 系は10月16日に停止」は、公式の廃止予定表に記載がありません。3モデルとも停止日は未告知のままです09/30 — gemini-omni-flash-preview の停止まで残り14日です。GA 版は延長やフレーム補間、解像度指定が増えているため、モデル ID の置換だけでは済みませんBATCH — バッチジョブは成功で終わるのに、中のレスポンスだけが権限エラーで返る報告が出ています。同期呼び出しと同じファイルでも起きるところが厄介ですNEW — 3.8 Flash と 3.7 Flash のどちらに寄せるか。手元の20問を毎回通して決めている方法を書きましたSHEETS — スプレッドシートの AI 関数が反応しないとき、24時間の回数上限なのか、ファイルの置き場所と開き方なのかを先に切り分けます3.8LIVE — gemini-3.8-live と extended-thinking 版が GA になりました。低遅延の音声エージェント向けで、非同期の function calling が既定です2.5FLASH — 二次情報で広まっている「2.5 系は10月16日に停止」は、公式の廃止予定表に記載がありません。3モデルとも停止日は未告知のままです09/30 — gemini-omni-flash-preview の停止まで残り14日です。GA 版は延長やフレーム補間、解像度指定が増えているため、モデル ID の置換だけでは済みませんBATCH — バッチジョブは成功で終わるのに、中のレスポンスだけが権限エラーで返る報告が出ています。同期呼び出しと同じファイルでも起きるところが厄介ですNEW — 3.8 Flash と 3.7 Flash のどちらに寄せるか。手元の20問を毎回通して決めている方法を書きましたSHEETS — スプレッドシートの AI 関数が反応しないとき、24時間の回数上限なのか、ファイルの置き場所と開き方なのかを先に切り分けます
記事一覧/API / SDK
API / SDK/2026-08-02上級

environment hooks に置いた門番の実測 — 判定は46マイクロ秒、起動は23ミリ秒

Managed Agents の environment hooks に破壊的コマンドのガードを置くまでの記録です。正規表現の denylist が20件中9件を素通りさせた実測から、argv 分解による検出率100パーセントまでの3段階と、判定より500倍重い起動コストの内訳をまとめました。

Gemini API239Managed Agents8environment hooksサンドボックス3エージェント設計4

プレミアム記事

7月28日、Gemini API の Managed Agents に environment hooks が加わりました。ツール呼び出しの前後で、サンドボックスの内側からカスタムスクリプトを走らせられる仕組みです。

告知を読んで最初に思い浮かんだのは、機能の使い道ではなく、以前に自分が肝を冷やした場面のほうでした。個人開発で回している自動化パイプラインで、エージェントに作業ディレクトリの掃除をさせたとき、消してほしくない中間生成物まで一緒に消えたことがあります。復旧そのものは十数分で済みました。ただ、あのとき手元にあったのは「実行が終わったログ」だけで、実行を止める場所がどこにもなかった。

environment hooks は、まさにその「止める場所」をツール呼び出しの境界に作るものです。

そこで、破壊的なシェルコマンドを弾く門番を書きました。書き始めたときは30分で終わる作業だと思っていました。実際には、最初に書いた実装が半分近くを素通りさせ、そのうえ性能の想定が完全に逆でした。以下はその記録です。

※ 以下の計測は、隔離された Linux 環境(Ubuntu 22.04 / Python 3.10.12)でフックスクリプト単体を走らせて取得した値です。フックの契約は「ツール呼び出しの内容を受け取り、許可か拒否を返すプロセス」なので、判定ロジックと起動コストはエージェントへ組み込む前に単独で測れます。API 側の仕様・引数名は変更され得るため、実装前に Gemini API の Agents ドキュメント で確認してください。

止めたいものを、まず34行のリストにする

ガードを書く前に、判定対象を確定させました。頭の中の「危ないコマンド」は輪郭がぼやけていて、実装しながら考えると必ず取りこぼします。

破壊的として止めたいもの20件、通したいもの14件。合計34件のコーパスを作りました。意図的に入れたのは次の3種類です。

種別狙い
教科書的な破壊どんな実装でも止まるはずrm -rf /
表記違いの破壊同じ意味で書き方だけ違うrm -fr /workspace / rm --recursive --force ...
紛らわしい正常系誤爆させたいケースgrep -rn 'rm -rf' /workspace/docs

3番目を入れたことが、あとで効きました。ガードの価値は「止めた数」ではなく「止めずに済ませた数」との比で決まります。安全側に倒しすぎたフックは、数日で外されて終わります。

# corpus.py — 判定対象の固定コーパス(True = 破壊的として止めたい)
CORPUS = [
    # 教科書的な破壊
    ("rm -rf /", True),
    ("rm -rf /workspace", True),
    ("rm -rf ~", True),
    # 同じ意味だが表記が違う
    ("rm -fr /workspace", True),
    ("rm -r -f /workspace", True),
    ("rm --recursive --force /workspace", True),
    ("/bin/rm -rf /workspace", True),
    ("env rm -rf /workspace", True),
    ("sh -c 'rm -rf /workspace'", True),
    ("cd /workspace && rm -rf .", True),
    ("find /workspace -delete", True),
    ("truncate -s 0 /workspace/db.sqlite", True),
    (": > /workspace/db.sqlite", True),
    ("dd if=/dev/zero of=/workspace/db.sqlite", True),
    ("git clean -xfd", True),
    ("git reset --hard origin/main", True),
    ("mkfs.ext4 /dev/nvme1n1", True),
    ("chmod -R 000 /workspace", True),
    ("mv /workspace /tmp/gone", True),
    # 通したい正常系
    ("ls -la /workspace", False),
    ("cat /workspace/report.json", False),
    ("python3 /workspace/analyze.py --input data.csv", False),
    ("grep -rn 'TODO' /workspace/src", False),
    ("git status", False),
    ("git log --oneline -20", False),
    ("npm test", False),
    # 紛らわしい正常系(誤爆を測るために置く)
    ("grep -rn 'rm -rf' /workspace/docs", False),
    ("echo 'never run rm -rf /' >> /workspace/NOTES.md", False),
    ("python3 -c \"print('rm -rf /')\"", False),
    ("git log --grep='remove -rf flag'", False),
]

最初の実装は、20件中9件を素通りさせた

素朴に、危険なパターンを正規表現で並べました。おそらく多くの人が最初に書くであろう形です。

import re
 
DENY_PATTERNS = [
    r"rm\s+-rf\s+/",
    r"rm\s+-rf\s+~",
    r"mkfs",
    r"dd\s+if=/dev/zero",
    r"git\s+reset\s+--hard",
    r"git\s+clean\s+-xfd",
]
DENY_RE = [re.compile(p) for p in DENY_PATTERNS]
 
def guard_denylist(cmd: str) -> bool:
    """True を返したら「破壊的なので拒否」"""
    return any(r.search(cmd) for r in DENY_RE)

コーパスに通した結果です。

破壊的 20件中 11件を阻止(検出率 55.0%)
正常  14件中  2件を誤って阻止(誤検知率 14.3%)

素通りした9件を並べると、傾向がはっきりしました。

素通りしたコマンドなぜ漏れたか
rm -fr /workspaceフラグの並びが -rf ではない
rm -r -f /workspaceフラグが分かれている
rm --recursive --force /workspaceロングオプション
cd /workspace && rm -rf .削除対象がスラッシュ始まりではない
find /workspace -deleteそもそも rm ではない
truncate -s 0 ... / : > ...削除ではなく中身の消去
chmod -R 000 /workspace消さないが読めなくする
mv /workspace /tmp/gone消さないが消えたのと同じ

パターンを追加すれば個別には塞げます。ただ、この一覧を眺めていて手が止まりました。塞いだところで、次に来るのは私が思いつかなかった10件目です。denylist は「私が想像できた危険」の上限までしか働かない。

誤検知のほうも示唆的でした。echo 'never run rm -rf /' >> NOTES.mdpython3 -c "print('rm -rf /')" が止められています。文字列の中身とコマンドの構造を、正規表現は区別できません。

つまりこの方式は、構造を見るべき対象を文字列として扱っている点で、そもそも土台がずれていました。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
正規表現の denylist が破壊的コマンド20件中9件を素通りさせた実測と、argv 分解で検出率100パーセント・誤検知0パーセントまで詰めた3段階の設計
判定ロジックは46マイクロ秒、プロセス起動は23.1ミリ秒。import re 単体で7.1ミリ秒という内訳と、フックを1本に束ねる根拠
そのまま動く pre-tool-call ガードの完全な実装(ラッパ剥がし・サブシェル再帰・書き込みパススコープ付き)
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

関連記事

API / SDK2026-07-04
Managed Agents を並列で回すと同じリポジトリを奪い合う ― 隔離サンドボックスに効く外部リースとフェンシング
Managed Agents は実行ごとに隔離サンドボックスが立つため、複数実行が同じリポジトリやレコードに同時に触れてもローカルロックが効きません。外部リースとフェンシングトークンで単一実行を保証する実装をまとめました。
API / SDK2026-06-16
Gemini Managed Agents を自動化に組み込む ― 会話状態と環境状態を分けて扱う実装メモ
Managed Agents は1回の API 呼び出しで Linux サンドボックスを立て、エージェントを走らせて結果を返します。自前ループから移すとき最初につまずく「会話状態と環境状態は別物」という設計を、実際に動かしながら整理しました。
API / SDK2026-08-08
打ち切りは失敗の合図ではありませんでした — ブロッキング挙動を伴う関数呼び出しの設計
呼び出しが返るまで待つブロッキング型のツールをエージェントに持ち込むと、並列化と打ち切りの常識が反転します。サンドボックスの最小ハーネスで実測した数値をもとに、再試行を観測へ振り替える設計と unknown を握りつぶさない扱い方をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます