サイトを回している自動タスクは、実行の設定がコンソール側に、スキルがリポジトリ側に置いてあります。作業のたびに「いまどちらが正なのか」を思い出すところから始まっておりまして、朝の数分がいつもそこで溶けておりました。
ant CLI の v1.30.0 に入った ant apply は、この分裂をそのまま解いてくれそうに見えます。エージェント・環境・スキル・メモリストア・デプロイメントをリポジトリのファイルとして書き、走らせると計画(plan)が出て、承認すると適用されます。構成が git の履歴に乗る——それだけで、思い出す作業がなくなります。
ただ、移し始める前に一度だけ手が止まりました。すでにコンソールで作ってある資産は、どう引き取られるのでしょうか。ここを読み違えると、同じエージェントが二つに増えます。
まず --dry-run を読みます
いきなり適用せず、計画だけを読みます。
# 何も変えずに、詳細な計画を出して終了する
ant apply --dry-run .対話端末で ant apply を走らせると、作成・更新の一覧が出て承認を待ちます。d と答えると、新規なら各フィールドの中身が、更新ならフィールド単位の差分が見られます。--dry-run はその詳細な計画を出したうえで、何も変えずに終わります。lockfile も書きません。
ひとつだけ注意が要ります。--dry-run は計画が塞がっているときでも終了コード 0 で終わります。CI で「計画が通ったこと」の判定に使うと、通っていないものを通ったと読んでしまいます。プルリクエストに計画を貼るための情報提供、と割り切っておくのが安全です。
拒んでくれるのは、lockfile が知っている資源だけです
ここが今回いちばん読み違えやすい箇所でした。
ファイルから作った資源を、あとからコンソール側で編集・アーカイブ・削除した場合、次の ant apply は This plan cannot be applied: と理由を表示し、refusing to apply で止まります。上書きしたいときだけ --force を渡します。手元の宣言と実物がずれたことを、CLI がきちんと教えてくれるわけです。
いっぽう、コンソールで作った資源を、あとから同じ内容のファイルとして書いて適用すると、二つ目が作られます。ant apply は既存の資源を取り込めません。管理されるのは lockfile に載っているものだけで、それ以外は「まだ存在しない資源の宣言」として読まれます。
拒否は lockfile の内側だけの話で、外にあるものは黙って複製されます。 この一文を先に飲み込んでおくと、移行の順番を間違えずに済みます。
逃げ道は用意されています。コンソールの Export as code で書き出すと、その中に claude-lock.json が同梱されています。それを使って適用すれば、新規作成ではなく、コンソールで組み立てた資源そのものの更新になります。私はこの一点を知らないまま移していたら、走っているデプロイの隣に、同じ名前で何もしないエージェントを増やしていたはずです。
claude-lock.json は成果物ではなく、正本です
最初の適用でリポジトリのルートに claude-lock.json が書かれます。中身はおおむね次のかたちです。
{
"version": 1,
"origin": {
"base_url": "https://api.anthropic.com",
"organization_id": "YOUR_ORGANIZATION_ID",
"workspace_id": "YOUR_WORKSPACE_ID"
},
"resources": {
"./agents/release-notes.md": {
"kind": "agent",
"id": "agent_XXXXXXXXXXXXXXXX",
"version": "1",
"hash": "…",
"remote_hash": "…"
}
}
}hash は最後に送った内容の指紋、remote_hash は API が返した内容の指紋です。この二つがあるおかげで、あとの実行が「ファイルが編集された」のか「ファイルの外で資源が変えられた」のかを見分けられます。
運用として決めておきたいことは三つあります。
第一に、走らせる場所をリポジトリのルートに固定します。lockfile は実行したディレクトリに書かれ、以降は上位へ遡って探されます。第二に、適用が途中で失敗した実行でも lockfile をコミットします。部分適用でも、作られたところまでは記録されているためです。第三に、組織やワークスペースを分けているなら lockfile も分け、--lock-file で明示します。資格情報が lockfile に記録された組織・ワークスペースと一致しない場合、ant apply は実行を拒みます。
二つ目が生まれる入り口は、だいたいこの五つです
| 入り口 | 起きること | 手当て |
|---|---|---|
| コンソールの資産をファイルに書き写す | 取り込まれず、二つ目が作られる | Export as code の claude-lock.json ごと持ってくる |
| ファイル名の変更・ディレクトリ移動 | 新しい資源の宣言として作成され、古い方は残る | 名前を戻すか、--prune で古い方を片づける |
| ファイルの削除 | 資源は残り、警告が出るだけ | --prune(スキルは削除、それ以外はアーカイブ) |
CI で引数なしの ant apply --yes | lockfile が知るファイルだけ照合し、新規追加を飛ばす | ディレクトリを明示して ant apply --yes . |
claude-lock.json のコミット忘れ | 次の実行が同じ資源を見つけられず、作り直す | ファイルと同じコミットに含める |
五つのうち四つは、ファイルを丁寧に書いていても踏みます。原因が記述の側ではなく、どこに身元が記録されているかの側にあるからです。いま思えば、私が迷っていたのも書き方ではなく置き場所のほうだったのかもしれません。
相互参照は ID ではなく、相対パスで書きます
資源どうしの参照は、API が ID を求める場所にファイルへの相対パスを書きます。ant apply が依存の順に作り、実際の ID を埋めてくれます。
---
name: Release notes writer
model: claude-opus-5
tools:
- type: agent_toolset_20260401
skills:
- ../skills/release-notes
---
あなたはリリースノートの下書きを作ります。変更点を三つの短い節にまとめてください。デプロイメントも同じ書き方です。フロントマターがリクエストボディに、本文が各セッションを始める最初のメッセージになります。
---
name: Nightly release notes
agent: ../agents/release-notes.md
environment_id: ../environments/cloud.yaml
schedule:
type: cron
expression: "0 3 * * *"
timezone: Asia/Tokyo
---
未反映のコミットからリリースノートの下書きを作ってください。パスで書いておくと、参照先を編集した同じ実行で、参照している側も新しい版に留められます。ID を直書きすると、この追随が効きません。管理外の資源を指したいときだけ、agent_... や skill_... の ID をそのまま書きます。
ファイルの種類は、①ファイル内の type フィールド、②直上のディレクトリ名(agents/ environments/ memory_stores/ deployments/)、③environment_staging.md のような接頭辞つきのファイル名、の順に判定されます。どれにも当てはまらないファイルは走査時に飛ばされます。README や CI の設定を巻き込まないための仕組みですが、裏を返せば、整理のつもりでファイルを agents/ の外へ出した瞬間に、そのファイルは見られなくなります。
手元で回す手順と、CI で回す手順は分けて書きます
端末がない環境では確認を求められないため、ant apply は計画を出したところで停止します。CI では次のように置きます。
# プルリクエスト: 計画をレビュー用に出すだけ(情報提供・常に 0 で終了)
ant apply --dry-run .
# マージ後の既定ブランチ: ディレクトリを明示して適用する
ant apply --yes .同時に二つ走らせないことも決めておきます。lockfile にロックの仕組みはありません。認証は保存した API キーではなく Workload Identity Federation を使い、lockfile に記録された組織とワークスペースに届く身元で走らせます。
私は無人で走る処理をいくつも抱えておりますが、こういう仕組みで痛い目を見るのは、たいてい「手元では通ったのに CI では別のことが起きた」場面でした。手元の一回と CI の毎回は、別々の手順書に書き残すようにしております。 面倒に見えて、この分割がいちばん事故を減らしてくれるのだと感じています。
最初に置く一枚
全部をいっぺんに移す必要はありません。いま動いているエージェントのうち、いちばん触る回数が少ないものを一枚のファイルに書き写し、ant apply --dry-run の計画を読むところで止めてみてください。計画に create と出るなら、それは取り込みではなく新規作成です。そこで初めて、Export as code から始めるか、新しく一本立てるかを選べます。
私もまだ移行の途中で、コンソールに残したままのものがあります。同じところで迷っている方の手がかりになれば幸いです。お読みいただきありがとうございました。