メインコンテンツへスキップ
ブログ一覧

Claude Managed Agents API実践ガイド — セルフホストCLI運用者が語る「どこまで移行すべきか」の判断フロー

(更新: 2026年04月25日)
Claude CodeAIエージェントAnthropic API自律開発アーキテクチャ設計

Managed Agents APIとは何か — 3行で理解する全体像

2026年4月8日、AnthropicはClaude Managed Agents APIをパブリックベータとして公開した。ウェイトリスト不要、全APIアカウントから即利用可能だ。

従来のMessages APIとの決定的な違い

Messages APIは「1リクエスト送って1レスポンスを受け取る」ステートレスなモデルだ。エージェントループ、ツール実行、状態管理はすべて開発者が自前で構築する必要がある。一方Managed Agentsは、ステートフルなエージェントを丸ごとAnthropicのクラウドにホスティングする。コンテナの中でClaude がbashを叩き、ファイルを読み書きし、Web検索まで自律的にこなす。

筆者は1年以上、Claude CLI spawnベースの自律デーモン(slaveと呼んでいる)を24時間365日稼働させてきた。daemon.tsでジョブループを回し、claude-runner.tsでCLIプロセスを起動し、queue.tsでジョブ管理する — この3ファイルで担ってきた責務が、Managed Agents APIでは丸ごとAnthropicのインフラに吸収される。

Agent・Environment・Session・Eventsの4層モデル

Managed Agentsは4つの概念で成り立つ。

概念 役割
Agent モデル・システムプロンプト・利用ツールの定義。一度作ればIDで再利用
Environment コンテナテンプレート。パッケージ、ネットワーク設定を指定
Session AgentとEnvironmentを組み合わせた実行インスタンス
Events アプリとエージェント間のメッセージ(SSEストリーム)

全エンドポイントに managed-agents-2026-04-01 ベータヘッダーが必須だが、SDKを使えば自動付与される。

最小構成は、わずか3ステップで動く。

python
from anthropic import Anthropic

client = Anthropic()

# 1. Agent定義
agent = client.beta.agents.create(
    name="Coding Assistant",
    model="claude-opus-4-7",
    system="You are a helpful coding assistant.",
    tools=[{"type": "agent_toolset_20260401"}],
)

# 2. Environment作成
environment = client.beta.environments.create(
    name="dev-env",
    config={"type": "cloud", "networking": {"type": "unrestricted"}},
)

# 3. Session開始
session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    title="My first session",
)

agent_toolset_20260401 を指定すると、bash・ファイル操作・Web検索など全ビルトインツールが有効になる。AgentもEnvironmentもIDで再利用できるため、実運用では一度作成したら使い回す形になる。


セキュアサンドボックスとカスタムツール — 実行環境の設計

Environmentの作成と再利用パターン

Environmentは「コンテナのテンプレート」だ。ネットワークアクセスの制御やパッケージの事前インストールを定義し、IDで参照する。複数のSessionが同一Environmentを共有しつつ、各Sessionは独立したコンテナインスタンスを取得する。ここを混同すると設計を誤るので注意してほしい。

ツールの細かな制御も可能だ。全ツール有効がデフォルトだが、configs で個別に無効化できる。

python
agent = client.beta.agents.create(
    name="Restricted Agent",
    model="claude-opus-4-7",
    tools=[{
        "type": "agent_toolset_20260401",
        "configs": [
            {"name": "web_fetch", "enabled": False},
            {"name": "web_search", "enabled": False},
        ],
    }],
)

逆に、デフォルトを全無効にして必要なものだけ有効化するアプローチもある。

json
{
  "type": "agent_toolset_20260401",
  "default_config": { "enabled": false },
  "configs": [
    { "name": "bash", "enabled": true },
    { "name": "read", "enabled": true },
    { "name": "write", "enabled": true }
  ]
}

カスタムツールで外部システムと接続する

ビルトインツールに加え、カスタムツール(Custom Tools)で任意の外部連携を追加できる。Messages APIの tool_use と同じ考え方で、スキーマを宣言すればClaudeがいつ呼ぶかを自律的に判断する。

python
agent = client.beta.agents.create(
    name="Deploy Agent",
    model="claude-opus-4-7",
    tools=[
        {"type": "agent_toolset_20260401"},
        {
            "type": "custom",
            "name": "deploy_to_production",
            "description": "Deploy the current build to production. Requires human approval.",
            "input_schema": {
                "type": "object",
                "properties": {
                    "service": {"type": "string", "description": "Service name to deploy"},
                    "version": {"type": "string", "description": "Version tag"},
                },
                "required": ["service", "version"],
            },
        },
    ],
)

Vaultによるユーザー認証情報の安全な管理

Vaultは、ユーザーごとのアクセストークンを暗号化保管する仕組みだ。エージェントがGitHubやSlackなどの外部サービスにアクセスする際、Vault経由でトークンがインジェクトされる。

python
vault = client.beta.vaults.create(
    display_name="User credentials",
    metadata={"internal_user_id": "u_001", "team": "engineering"},
)

credential = client.beta.vaults.credentials.create(
    vault_id=vault.id,
    display_name="GitHub Token",
    auth={
        "type": "static_bearer",
        "mcp_server_url": "https://api.githubcopilot.com/mcp/",
        "token": GITHUB_TOKEN,
    },
)

# Session作成時にVaultを紐付け
session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    vault_ids=[vault.id],
)

セルフホストでは .env ファイルに全トークンを並べ、spawn時に getCleanEnv() でClaude関連の環境変数だけ除去する — という地味に面倒な管理をしていた。Vaultはこれをユーザー単位の暗号化ストアに置き換え、監査ログまで付けてくれる。正直、この機能だけでも移行する価値があると感じている。


Webhookでhuman-in-the-loopを実装する

Webhook設定とイベントの種類

エージェントが危険な操作(本番デプロイ、DB変更など)を行う前に人間の承認を挟みたい。Managed Agentsでは、Webhookとカスタムツールの組み合わせでこれを実現する。

Webhookの登録はAnthropicコンソールの Settings → Webhooks で行う。登録時に表示される署名シークレット(whsec_...)は一度しか表示されないので、必ずシークレットマネージャーに保存すること。

エージェントがカスタムツールを呼び出してアイドル状態になると、session.status_idled イベントがWebhook URLにPOSTされる。

承認フローの実装パターン

具体的な実装を見てみよう。カスタムツール escalate を定義し、Webhook受信側で承認判断を行う。

python
from fastapi import FastAPI, Header, HTTPException, Request
import hmac, hashlib, json

app = FastAPI()
WEBHOOK_SECRET = "whsec_..."  # シークレットマネージャーから読み込む

def verify_signature(body: bytes, sig: str) -> bool:
    expected = hmac.new(
        WEBHOOK_SECRET.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, sig)

@app.post("/webhooks/anthropic")
async def handle_webhook(req: Request, x_anthropic_signature: str = Header()):
    body = await req.body()
    if not verify_signature(body, x_anthropic_signature):
        raise HTTPException(401)

    event = json.loads(body)
    session_id = event["resource_id"]

    if event["event_type"] == "session.status_idled":
        events = client.beta.sessions.events.list(session_id=session_id)
        pending = [
            e for e in events.data
            if e.type == "agent.custom_tool_use" and e.name == "escalate"
        ]
        if pending:
            for tu in pending:
                # Slack通知 → 人間が承認 → 結果を返す
                enqueue_for_review(session_id, tu.id, tu.input)
    return {"ok": True}

承認完了後、結果をセッションに返す。

python
def submit_approval(session_id: str, tool_use_id: str, decision: str):
    client.beta.sessions.events.send(
        session_id=session_id,
        events=[{
            "type": "user.custom_tool_result",
            "custom_tool_use_id": tool_use_id,
            "content": [{"type": "text", "text": json.dumps({"approved": decision})}],
        }],
    )

セルフホストではSlack通知→手動確認→手動再開という非同期フローだった。Managed AgentsではセッションがWebhookの応答を待ってくれるため、承認フローがAPIレベルでブロッキングになる。セッションはアイドル中課金されないので、承認待ちのコストを気にする必要もない。


Memory APIでセッション間の記憶を持たせる

Memory APIの仕組みと保存戦略

Managed Agentsのセッションはデフォルトでステートレスだ。セッションが終われば学習内容は消える。Memory APIは、セッション間で情報を引き継ぐための永続ストレージを提供する。2026年4月23日にパブリックベータとして利用可能になった。

仕組みはシンプルだ。メモリストアを作成し、セッション作成時に resources として添付する。ストアはコンテナ内の /mnt/memory/ にマウントされ、エージェントが通常のファイルツールで読み書きする。

python
# メモリストア作成
store = client.beta.memory_stores.create(
    name="Project Context",
    description="過去のセッションで学んだプロジェクト固有の知識",
)

# 初期データの投入(オプション)
client.beta.memory_stores.memories.create(
    store.id,
    path="/conventions.md",
    content="デプロイ先は常にVercel。DBはSupabase。テストはvitest。",
)

# セッション作成時にメモリストアを添付
session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    resources=[{
        "type": "memory_store",
        "memory_store_id": store.id,
        "access": "read_write",
        "instructions": "タスク開始前に必ず確認すること。新しい学びがあれば書き込むこと。",
    }],
)

1セッションに最大8つのメモリストアを添付できる。個々のメモリは100KBが上限なので、大きなドキュメントではなく小さなファイルに分割するのがコツだ。

セッション横断のコンテキスト維持

セルフホストでは execution_logs テーブルに実行ログを保存し、次回セッションのプロンプトに履歴を注入していた。Memory APIはこれを宣言的に管理できるようにする。メモリへの全変更はバージョン管理され、監査ログが残り、特定時点へのロールバックも可能だ。

注意点として、read_write でマウントしたストアは、プロンプトインジェクション経由で汚染されるリスクがある。リファレンス情報は read_only で添付するのが安全だ。


コスト試算 — $0.08/session-hourは高いのか安いのか

課金モデルの詳細

Managed Agentsの課金は2軸で構成される。

項目 料金
セッションランタイム $0.08/時間(ミリ秒単位、running状態のみ)
トークン消費 通常のClaude API料金
Web検索 $0.01/回($10/1,000検索)

重要なのは、アイドル状態は無課金という点だ。Webhookで承認待ちしている間、セッションが一時停止している間、キューイング中 — いずれも課金されない。

レート制限は組織単位で、作成系300 req/min・読み取り系600 req/min。この数値は2026年4月時点のベータ値であり、今後変更される可能性がある。

セルフホストとの損益分岐点

筆者のslaveデーモンの運用コストと比較してみる。

項目 セルフホスト(slave) Managed Agents
インフラ Mac Studio(約30万円 + 電気代月3,000円程度) 不要
CLIサブスク Claude Pro/Max($100〜$200/月) 不要(API従量課金)
運用工数 launchd設定、レート制限対応、死活監視 ほぼゼロ
セッションランタイム 実質無料(ハード償却のみ) $0.08/h

24時間フル稼働させた場合、ランタイムだけで月$58。これにトークン料金が乗る。一方セルフホストは、CLIサブスクが定額なので使い放題だ。

損益分岐の目安: 1日数回・各数十分の不定期タスクならManaged Agentsが圧倒的にコスパがよい。逆に24/365で常時ジョブを流し続けるワークロードでは、セルフホストに大きなコスト優位がある。


移行判断フローチャート — セルフホストを残すべき領域

Managed Agentsに移行すべき5つのケース

  1. 不定期実行のタスク — ユーザーリクエスト起点で散発的に動くもの
  2. 短時間で完結するタスク — 数分〜30分程度で終わる処理
  3. 外部SaaS連携が多い — Vault+カスタムツールでセキュアに接続
  4. 承認フローが必須 — Webhook+カスタムツールでネイティブ対応
  5. マルチテナント — ユーザーごとにVault・メモリストアを分離できる

セルフホストを維持すべき3つのケース

  1. 24/365常時稼働 — セッション課金が膨らむ。CLIサブスク定額の方が有利
  2. ローカルファイルシステム操作が必須~/Repo/ 配下のgit操作、ローカルDB直接アクセスなど
  3. コスト最適化が最優先 — レート制限の自前制御、バックオフ戦略のチューニングが必要な場合

ハイブリッド構成の実践例

筆者のslaveデーモンを例にとると、以下のような分担が現実的だ。

パイプライン 移行先 理由
repo-watchdog セルフホスト維持 6時間ごとの定常監視、ローカルリポジトリ操作
hotel-enrichment セルフホスト維持 2時間ごとの常時稼働、ローカルDB操作
fix-feedback Managed Agents ユーザートリガー型、不定期、短時間
blog-writer Managed Agents 1日1回、Web検索中心、ローカル依存なし
dreamy-poster セルフホスト維持 外部API(Twitter/Gemini)の直接呼び出しが必要

判断フローは4ステップで考える。

  1. 実行頻度: 1日数回以下 → Managed Agents寄り
  2. 実行時間: 1時間未満 → Managed Agents寄り
  3. ローカルリソース依存: あり → セルフホスト維持
  4. 月間コスト試算: セルフホストの限界費用と比較

重要なのは二者択一ではないということだ。ワークロードの特性に応じて、セルフホストとManaged Agentsを併用するハイブリッド構成が最も実用的だ。


まとめ

Claude Managed Agents APIは、自前エージェントループの「インフラ層の苦労」を丸ごと引き受けてくれるサービスだ。Agent定義→Environment→Sessionの3ステップで本番グレードのエージェントが動き、Vault・Webhook・Memory APIなど運用に必要な機能が揃っている。

一方で、24/365常時稼働やローカルリソース操作が必須な用途ではセルフホストに分がある。まずは短時間・不定期なタスクからManaged Agentsに移行し、運用知見を貯めていくのが現実的な第一歩だろう。

もっと読む他の技術記事も読む
Claude CodeAIエージェントAnthropic API自律開発アーキテクチャ設計

公開: 2026年04月24日

最終更新: 2026年04月25日