土曜の朝、6月15日の課金変更を前に、手元の自動実行まわりを棚卸ししていました。cron に登録した定期ジョブ、GitHub Actions の schedule、実行のたびに環境変数へ流し込むクレデンシャル。一覧にしてみると、「動いてはいるけれど、人に説明できる状態ではない」ものが思った以上に多いことに気づきます。
ちょうどそこへ、6月12日付の Claude Developer Platform の更新が目に入りました。Managed Agents へのスケジュールデプロイ、vault による環境変数クレデンシャル、そしてセッションスレッドの Webhook イベント。この3つは、私が個人開発の自動化で自前に組んできた仕組みと、ほとんど一対一で対応しています。せっかくの週末ですから、「何を移し、何を残すか」の線を引いてしまうことにしました。その判断基準ごと、ここに残します。
新しい3機能は、自前運用の「どの層」と対応するのか
自前のエージェント定期実行は、突き詰めると3つの層でできています。起動の層、保管の層、観測の層です。今回の更新は、それぞれにマネージドの選択肢を用意した格好になります。
- 起動の層 — cron や GitHub Actions の schedule が担ってきた「決まった時刻にエージェントを立ち上げる」仕事。スケジュールデプロイがここに対応します
- 保管の層 —
.envファイルや環境変数に直接置いてきた API キー・トークン類。vault の環境変数クレデンシャルがここに入ります - 観測の層 — 実行ログを後から掘る、あるいはポーリングで状態を見にいく監視。セッションスレッドの Webhook イベントは、これをイベント駆動へ裏返す位置づけです
発表から確実に読み取れるのはこの対応関係までで、設定の細部は実際にドキュメントと突き合わせながら進めることになります。ただ、移行を判断するだけなら「どの層を任せられる可能性が出てきたか」という地図があれば十分でした。
どのジョブなら移して良いのか — 私の線引きは冪等性です
最初に決めたのは、機能の新しさに判断を引っ張られないことです。移す・残すの基準は一つに絞りました。そのジョブは、失敗しても次回の実行が拾い直せる設計になっているか。つまり冪等性です。
私の手元でいえば、日次の集計レポート生成は移せる候補です。今日の実行が落ちても、明日の実行が同じ集計をやり直すだけで、誰も困りません。一方で、前回の結果に積み上げていく逐次型のジョブや、ローカルマシンの中のファイル・アプリに触る工程は自前に残します。
理由は単純で、マネージドへ移すほど「失敗の瞬間に手元の環境で介入する」という選択肢が細るからです。冪等なジョブはそもそも介入が要らないので、この制約が痛くありません。逐次型のジョブは、失敗時に人が状態を確かめて継ぎ直す前提で組んであるはずなので、介入手段が近くにある自前側が向いています。
個人開発では、失敗からの復旧に使える人手が自分ひとりしかありません。介入の要らないジョブから先に移すのは、その意味でも理にかなっていると感じています。
定期実行の一覧をまだ作っていない方は、まずここから始めるのが良いと思います。
# 定期実行の棚卸し: cron と GitHub Actions の schedule を一覧にする
crontab -l 2>/dev/null | grep -v '^#'
grep -rn "schedule:" .github/workflows/*.yml 2>/dev/nullこの出力に「冪等/逐次」の印を付けるだけで、移行候補の地図ができあがります。
vault へ移す前に、権限の棚卸しを済ませておく
クレデンシャルの保管場所を vault へ移す作業は、それ自体は引っ越しにすぎません。注意したいのは、古い権限設計の問題を、新しい保管庫へそのまま運び込んでしまうことです。
これは5月の終わりに痛感したことでした。自動 push 用の fine-grained PAT を作り直した直後、1つのリポジトリだけ対象選択から漏れていて、その日の自動実行が 403 で止まったのです。保管のやり方がどれだけ整っていても、権限の中身が追いついていなければ意味がありません。このときの切り分けは Claude Code から git push すると 403 Write access to repository not granted が出るときの対処 に書いた通りです。
そこで vault への移行は、次の順番で小さな行事として段取りを組みました。
- 使用箇所の一覧を作る — どのジョブが・どのクレデンシャルを・何の操作に使っているかを3列で書き出します
- 最小権限で作り直す — 一覧にない権限を含むトークンは、移行を機に権限を削って再発行します
- ローテーション日をカレンダーに置く — 「気が向いたら回す」をやめて、日付で管理します
- 旧クレデンシャルの失効確認をもって完了とする — 新しい側が動いた時点ではまだ半分で、古い側が無効になって初めて移行完了です
Webhook の受け口は、分岐を書かないところから始めます
セッションスレッドの Webhook イベントは、3つの中で私がいちばん楽しみにしている機能です。ただ、ここでは過去の失敗から学んだ手順を守ります。新しいイベントソースをつなぐときは、最初の数日、分類も通知も書かずに生のペイロードを貯めて観察することです。
以前、Stripe の Webhook ハンドラー内の例外処理が甘く、HTTP 500 を返し続けてリトライが積み上がったことがありました(このときの顛末は Claude in Chrome で Stripe Webhook の HTTP 500 エラーを解決した実践レポート に残しています)。あの経験からの教訓は、受け口は何が来ても素早く正常応答を返せるほど堅く、中の処理は薄く守られているべきだ、ということでした。
そこで受け口の初期形は、Cloudflare Workers でこれだけにします。何が来ても即座に 200 を返し、生のまま KV に記録するだけです。
export default {
async fetch(request, env) {
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const raw = await request.text();
const key = `webhook:${Date.now()}:${crypto.randomUUID()}`;
// スキーマの仮定を置かず、まず生のまま14日だけ保存する
await env.WEBHOOK_LOG.put(key, raw, { expirationTtl: 60 * 60 * 24 * 14 });
// 重い処理を挟まず、すぐ応答を返す
return new Response("ok", { status: 200 });
},
};数日分のペイロードが貯まったら、観察した実物に合わせて最小限の分岐を足します。私がまず欲しいのは「失敗イベントだけ Slack に流す」ことなので、次の形へ育てる予定です。
export default {
async fetch(request, env, ctx) {
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const raw = await request.text();
const key = `webhook:${Date.now()}:${crypto.randomUUID()}`;
await env.WEBHOOK_LOG.put(key, raw, { expirationTtl: 60 * 60 * 24 * 14 });
let evt = null;
try {
evt = JSON.parse(raw);
} catch (_) {
// JSON 以外が届いても落とさない。記録だけ残して正常応答する
}
const kind = evt?.type ?? "unknown";
if (kind.includes("failed") || kind.includes("error")) {
// 応答をブロックせずに通知する
ctx.waitUntil(notifySlack(env, `エージェント実行の失敗イベント: ${kind}`));
}
return new Response("ok", { status: 200 });
},
};
async function notifySlack(env, text) {
await fetch(env.SLACK_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text }),
});
}evt?.type というフィールド名すら、観察を終えるまでは仮置きです。実際のペイロードで名前が違っていれば、ここを1行直すだけで済みます。分岐を後回しにする設計は遠回りに見えますが、私はこのやり方が結局いちばん手戻りが少ないと感じています。
6月15日の課金変更と、この更新はどうつながるのか
今回の更新を「どの財布で動くか」という面から見ておくことも、この週末に限っては大切です。6月15日から、Agent SDK・headless 実行・GitHub Actions 連携などはサブスクリプションの上限から外れ、API レート準拠の月次クレジット(繰越なし)へ移行します。私が工程をどう色分けしたかは 月次クレジット移行を前に、自動パイプラインの工程配分を見直した記録 に書きました。
Managed Agents は Developer Platform 側のプロダクトですから、冪等ジョブをスケジュールデプロイへ移すという判断は、そのジョブの消費を月次クレジットから切り離して API 利用側へ付け替える判断でもあります。クレジットを対話や開発の本業に温存したい方にとって、定期ジョブの逃がし先が一つ増えた——そう捉えると、今回の更新の位置づけが分かりやすいはずです。
週末のうちに作っておく「3行の棚卸し」
新機能を触る前に、紙の上で済むことが3つあります。私と同じように自前運用を抱えている方は、この3行から始めてみてください。
- 定期実行ジョブを列挙し、冪等か逐次かで色分けする — 移行候補になるのは冪等側だけです
- クレデンシャルの使用箇所一覧を作る — vault への引っ越しは、権限の棚卸しとセットで初めて意味を持ちます
- イベントの受け口をまだ持っていなければ、生ログを貯めるだけの Worker を先に置く — 分岐は観察のあとです
私自身の棚卸しの結果は、移すのは日次集計の1本だけ、残りは当面自前に残すという地味な結論になりました。それでも、「説明できる状態」になった定期実行の一覧は、この先の判断をずっと軽くしてくれます。同じように個人開発の自動運用を整えている方の参考になれば幸いです。