Google I/O 2026 で発表された Managed Agents が、Gemini API の公開プレビューとして使えるようになりました。1回の API 呼び出しで、Google がホストする隔離された Linux サンドボックスの中にエージェントが立ち上がり、推論・ツール実行・コード実行までこなして結果を返してくる、という触れ込みです。
私自身、個人開発のかたわらでブログの定期更新や画像資産の整理といった処理を、自前のエージェントループとスケジュール実行で回しています。発表を読んだときの率直な気持ちは、期待半分、警戒半分でした。「ループの面倒な部分を全部引き受けてくれるなら、それに越したことはない」という期待と、「動いている自動化を安易に動かすと、たいてい痛い目を見る」という経験則です。
そこで、いま手元で動いている処理を一つずつ眺めながら、「これは Managed Agents に移せるのか、移すべきなのか」を考えてみました。結論から言うと、全部を移す判断にはなりませんでしたが、判断の軸は3つの質問に集約できました。ここから先は、その整理の記録です。
自前のエージェントループは、実は「ループ」以外が本体です
エージェントループそのものは、書いてみると意外なほど短いコードです。モデルを呼び、function call が返ってきたら対応する関数を実行し、結果を渡してまた呼ぶ。骨格だけなら30行ほどで書けます。
次のコードは、リリースノートを確認するツールを1つだけ持つ最小のループです。Gemini が必要に応じてツールを呼び、最終的な報告テキストを返したら終了します。
from google import genai
from google.genai import types
client = genai.Client() # GEMINI_API_KEY を環境変数から読み込みます
def check_release_notes(product: str) -> dict:
"""リリースノートの最新エントリを返します(実際は RSS や DB を参照します)"""
return {"product": product, "latest": "1.4.2", "breaking_changes": False}
tool = types.Tool(function_declarations=[
types.FunctionDeclaration(
name="check_release_notes",
description="製品名からリリースノートの最新エントリを取得します",
parameters=types.Schema(
type=types.Type.OBJECT,
properties={"product": types.Schema(type=types.Type.STRING)},
required=["product"],
),
)
])
contents = [types.Content(
role="user",
parts=[types.Part(text="依存ライブラリ foo の最新リリースに破壊的変更がないか確認し、1段落で報告してください")],
)]
for _ in range(5): # 暴走防止の上限つきループ
response = client.models.generate_content(
model="gemini-3.5-flash",
contents=contents,
config=types.GenerateContentConfig(tools=[tool]),
)
if not response.function_calls:
print(response.text)
break
contents.append(response.candidates[0].content)
for call in response.function_calls:
result = check_release_notes(**call.args)
contents.append(types.Content(
role="user",
parts=[types.Part.from_function_response(name=call.name, response=result)],
))骨格をこれだけ短く見せたのには理由があります。実運用では、この骨格の周りに「本体」と呼ぶべき層が付いてくるからです。指数バックオフ付きのリトライ。途中経過のログと永続化。実行環境(cron なりコンテナなり)の維持。API キーの管理。タイムアウトと多重起動の防止。私の手元のループも、エージェントの思考に関わる部分より、この運用層のコードのほうがずっと長くなっています。
ループ周辺の本番設計は ADKに頼らない Gemini API カスタムエージェントループ設計ガイド — ツール呼び出し・メモリ・並列実行の本番実装 に詳しく書きましたが、一言でまとめると「ループは簡単、運用が本体」。これが今回の出発点になります。
Managed Agents が肩代わりするのは運用層のどこまでか
公開されている説明を読み解くと、Managed Agents が引き受けてくれるのは次の範囲です。エージェントの実行環境、つまり隔離された Linux サンドボックスの用意と破棄。推論からツール実行・コード実行までを繰り返すループの進行管理。そして実行中の状態の保持。先ほど「本体」と呼んだ運用層のうち、実行環境の維持とループの進行管理が、まるごと API の向こう側に移ることになります。
一方で、こちら側に残るものもはっきりしています。タスクの定義、つまり何をさせたいかの記述。結果の受け取りと、出てきたものが正しいかどうかの検証。失敗したときのハンドリング。そしてコストの管理。エージェントが「どう動くか」は任せられても、「何のために動かし、結果をどう使うか」は引き続き自分の仕事です。
この線引きを眺めたとき、私は cron の管理から解放されることよりも、「検証と失敗時のハンドリングは残る」という事実のほうが重要だと感じました。自動化の運用で実際に時間を取られるのは、環境の維持ではなく、失敗したときの調査だからです。だからこそ、移す・移さないは「便利そうかどうか」ではなく、次の3つの質問で判断することにしました。
質問1 — その処理は、実行環境そのものに意味がありますか
最初の質問は、処理がどこで動く必要があるか、です。
私の手元には、ローカルのワークスペースにあるファイルを読み書きする処理がいくつもあります。画像資産のフォルダを走査して分類する。リポジトリを clone して記事を push する。実行ログを所定のフォルダに追記する。こうした処理は、実行環境が自分の管理する場所にあること自体に意味があります。サンドボックスへ移すには資格情報やファイルの受け渡しを設計し直す必要があり、私の見立てでは移行コストが利得を上回ります。
逆に、「入力を渡す → 調べる・変換する → 結果を返す」で完結する処理は、どこで動いても同じです。公開リリースノートの監視、Web 上の情報の調査と要約、データの変換とレポート生成。この種の処理は Managed Agents のサンドボックスと相性が良く、コード実行を伴う変換処理ではむしろ、隔離環境で動くこと自体が安全性の向上になります。モデルが生成したコードを自分のマシンでそのまま実行するのは、それなりに神経を使う行為ですから。
質問2 — 状態の正本はどちらに置きますか
2つ目の質問は、エージェントが持つ「状態」を誰が所有するか、です。
Managed Agents はステートフルなエージェントを構築できるとされています。会話や作業の文脈をサンドボックス側が保持してくれるのは、複数ステップにまたがる長いタスクでは大きな利点です。ただ、私は公開プレビュー段階のサービスに「状態の正本」を預ける気にはなれません。プレビューの API は仕様が変わるものです。つい先日も、Interactions API の旧スキーマが廃止され、outputs から steps への移行 が必要になったばかりでした。
そこで私の基準はこうなりました。状態が一過性のもの、つまりそのタスクの実行中だけ意味を持つなら、サンドボックスに任せてよい。状態が資産、つまり次回以降の実行や他の処理から参照されるなら、正本は自分のデータベースやファイルに置き、エージェントには毎回必要な分だけを渡す。後者の設計を守っておけば、仮に Managed Agents 側の仕様が変わっても、失うのは実行中のタスク1回分で済みます。
質問3 — 失敗したとき、誰がどの粒度で拾えますか
3つ目の質問が、私にとっては決定打でした。失敗時にどこまで細かく回収できるか、です。
自前のループは、失敗の粒度が細かく見えます。どのツール呼び出しで、どんな引数で、何が返って止まったのか。ログを仕込んだ分だけ追跡できますし、途中から再開する設計も自由に作れます。つい先日の Gemini の大規模障害のときも、手元のパイプラインはリトライ、フォールバック、それでも駄目ならログに記録して静かに終了、という段階的な退避で乗り切れました。これはループの各段に自分のフックを持っていたからできたことです。
Managed Agents に移すと、この粒度は API が見せてくれる範囲に制約されます。エージェント内部のステップをどこまで観測できるかは今後の進化に期待したいところですが、少なくとも設計の前提としては「中間状態には介入できない」と置くのが安全だと考えています。そうすると、移してよいのは失敗してもまるごとやり直せる処理、つまり冪等にできる処理に絞られます。外部に副作用を出しながら進む処理のように、途中まで進んだ状態に価値や危険が残るものは、回収手段を自分で持てる自前ループに残します。
なお、Managed Agents のような「投げて完了を待つ」型の処理を増やすほど、完了通知の設計が効いてきます。長時間処理の完了待ちをポーリングからイベント駆動へ切り替える設計は 深夜のポーリングをやめる — Gemini Batch API を Webhook 駆動に作り替えた設計記録 に書きましたので、併せて参考にしていただければと思います。
プレビュー段階のものを本番の隣に置くための小さな工夫
3つの質問を通過して「移せる」と判定した処理についても、プレビュー段階のうちは一枚だけ防御層を挟むことにしています。といっても大げさなものではなく、Managed Agents の呼び出しを薄いラッパー関数に閉じ込め、そこに2つの仕事だけを持たせる構成です。1つは、呼び出しが失敗したら従来の自前ループで同じタスクを実行するフォールバック。もう1つは、返ってきた結果のスキーマ検証です。
この形にしておくと、プレビュー特有の仕様変更が来ても影響範囲はラッパー1ファイルに収まります。また、同じタスクを Managed Agents と自前ループの両方で実行して結果を突き合わせる、という品質比較も同じ場所でできます。料金についても、プレビュー期間中は想定外の課金パターンがないか、他の処理と分けて集計できるようにしておくと安心です。
まずは「サンドボックス向きの1本」を選ぶところから
整理を終えて、私の手元で最初の移行候補になったのは「公開リリースノートの監視と要約」でした。実行環境に依存せず(質問1)、状態は毎回使い捨てで(質問2)、失敗しても次の実行でやり直せばよい(質問3)。3つの質問をすべて「移せる」で通過する、ほとんど教科書のような候補です。
もしお手元に自前のエージェントループやスケジュール処理があるなら、次の一歩としておすすめしたいのは、処理の一覧にこの3つの質問への答えを書き込んでみることです。全部移すか全部残すかの二択ではなく、「移せる1本」を見つけて並行運用から始める。動いている自動化を壊さずに新しい仕組みを評価するには、私はこの進め方が一番堅実だと考えています。
同じように自動化の置き場所を考えている方の参考になれば幸いです。