Claude Code を対話的に使うことには、もうすっかり慣れた。claude を起動してタスクを伝えれば、コードを読み、修正し、テストを直してくれる。けれど、ふと気づくのです。「テスト失敗の修正」「PR のタイポチェック」「毎朝のデータ集計レポート」といった同じ作業を、週に何度も手で起動していることに。これ、自動化できないのでしょうか。
調べてみると「ヘッドレスモード」「-p フラグ」「GitHub Actions で定期実行」といった断片情報は見つかります。ところが、いざ自分の定型業務に当てはめようとすると手が止まる。一番のひっかかりは「怖さ」です。無人で動く AI が、見ていないところで勝手にファイルを書き換えたり、危険なコマンドを実行したりしたらどうしよう。対話モードなら都度「実行していいですか?」と聞いてくれる安心感がありますが、自動化はその確認を外すことが前提になります。任せきる踏ん切りがつかないのは、当然なのです。
この不安は「権限と出力を設計で絞る」ことで解消できます。Claude Code には、使えるツールを明示的に許可リストで縛る仕組み(--allowedTools)と、許可リスト外をすべて拒否するロックダウンモード(--permission-mode dontAsk)が用意されています。出力も --output-format json で機械可読にできるため、次の処理へ確実に渡せます。つまり「何を許すか」を先に決めてしまえば、AI が暴走できる範囲そのものを設計で潰せるのです。
本記事では、対話で検証してからヘッドレスに移す段階的な昇格パス、暴走させないための権限ロックダウン設計、出力をパイプラインに繋ぐ構造化、cron・GitHub Actions へのトリガー化、そして本番運用で詰まる冪等性・コスト・失敗ハンドリングまでを、エンジニア向けに実装手順として解説します。読み終えたとき、「自分のこの業務は、この設定で安全に自動化できる」と判断できる状態を目指します。
なお、本記事のフラグ・出力仕様はClaude Code 公式ドキュメント(ヘッドレス実行)に基づいています。Claude Code は更新が速いため、本番投入前には最新の公式リファレンスで確認してください。
Claude Codeの業務自動化とは — 対話モードとヘッドレスモードの違い
「業務自動化」という言葉は広いので、本記事ではまず定義を一つに絞ります。ここでいう業務自動化とは、Claude Code を非対話的に1回完結で実行し、その実行をスクリプトや cron・CI に組み込んで、繰り返し・無人で回せる状態にすることを指します。逆にいえば、自動化の最小単位は「人間が見ていなくても完結する1回の実行」です。これを作れれば、あとはいつ起動するかを決めるだけになります。
対話モードと-p(ヘッドレス)モードの違い
普段使っている claude の起動は対話モードです。セッションが立ち上がり、こちらが指示を出すと、Claude が必要に応じて「このコマンドを実行していいですか?」と確認しながら作業を進めます。人間が常に隣にいて、その場で判断できることが前提の使い方です。
一方、-p(--print)フラグを付けると、Claude Code は非対話モードで動きます。プロンプトを引数で渡すと、Claude はタスクを実行し、結果を標準出力に書き出して終了します。途中で人間に質問することはありません。
claude -p "What does the auth module do?"
この「質問せず、1回で完結し、結果を標準出力に返す」性質こそが、自動化に向いている理由です。標準出力に返るということは、> でファイルに書けますし、| で次のコマンドに渡せます。cron で起動すれば毎朝勝手に動き、GitHub Actions に置けば PR のたびに動く。対話モードのままでは、この「機械に組み込む」が成立しません。
逆にいうと、非対話モードでは人間が割り込めないため、「実行していいですか?」の確認も効きません。だからこそ、後述する権限設計が自動化の安全性を左右します。ここが本記事の核になります。
業務自動化に向く定型作業と、向かない作業の線引き
すべての作業を自動化すればよいわけではありません。ヘッドレス実行に向くのは、入力が定型で、成功・失敗の判定基準が明確で、間違えても取り返しがつく作業です。具体的には以下のようなものが好相性です。
- テスト失敗の自動修正: 失敗するテストを起点に、原因箇所を直させる。CI で走らせ、人間が PR でレビューする前提なら安全
- PR の差分レビュー・タイポチェック:
git diffを渡して、タイポや明らかな問題を指摘させる。読み取りだけで完結する - 定型レポートの生成: ログやデータを渡し、決まったフォーマットで要約・整形させる
- 定期的なデータ集計: 毎朝・毎週、決まったソースを集計して所定の場所に出力させる
逆に、自動化を慎重にすべき・避けるべきなのは次のような作業です。
- 判断の影響が大きく、取り返しがつきにくい作業(本番データの変更、外部への通知送信、デプロイの実行など)。これらは無人で任せず、人間の承認ゲートを挟む
- 入力が毎回大きく変わり、正解の判定基準が曖昧な作業。非決定的な出力をそのまま下流に流すとパイプラインが壊れやすい
「間違えても、人間がレビューで気づける」「最悪やり直せる」範囲から始めるのが鉄則です。最初は読み取り中心のタスク(レビュー・要約)から入り、書き込みを伴うタスクは権限を絞った上で段階的に広げていきます。その「段階的に広げる」道筋を、次に具体化します。
自動化への昇格パス — 対話で検証してからヘッドレスに移す手順

自動化でやりがちな失敗は、いきなり cron や CI に乗せてしまうことです。非対話実行は人間が割り込めないため、プロンプトが曖昧だったり権限設定が甘かったりすると、無人のまま意図しない動きをして初めて気づくことになります。
おすすめは、対話で1回やらせて確認 → 同じタスクを -p で非対話再現 → スクリプト化 → トリガー化という段階的な昇格です。各段階でチェックポイントを設けることで、「ここまでは確実に動く」と確認しながら無人運用へ近づけます。
ステップ1: 対話で意図どおり動くか確認する
まずは普段どおり対話モードで、自動化したいタスクを Claude にやらせてみます。ここで確認するのは次の点です。
- 期待した成果物(修正・レポート・要約)が得られるか
- どのツール(Read / Edit / Bash など)を使ったか。後で許可リストに何を入れるべきかの材料になる
- プロンプトに曖昧さがないか。「いい感じに直して」のような指示は非対話では危険なので、具体的な完了条件に書き換える
対話で安定して再現できないタスクは、非対話にしてもうまくいきません。プロンプトと期待値をここで固めます。
ステップ2: -pで同じタスクを非対話再現する
意図どおり動くプロンプトが固まったら、同じタスクを -p で実行してみます。このとき --bare を付けることを強くおすすめします。
claude --bare -p "Summarize this file" --allowedTools "Read"
--bare(ベアモード)は、hooks・skills・plugins・MCP サーバー・auto memory・CLAUDE.md の自動読み込みをスキップします。これがない場合、claude -p は対話セッションと同じコンテキスト(作業ディレクトリや ~/.claude に設定されたすべて)を読み込みます。自分のローカル設定に依存したまま自動化を組むと、CI や別マシンで「自分の環境では動いたのに」という再現性の問題を起こします。ベアモードは明示的に渡したフラグだけを有効にするため、どのマシンでも同じ結果になります。公式ドキュメントでも、ベアモードは「スクリプトおよび SDK 呼び出しの推奨モード」と位置づけられています。
なお、ベアモードでは認証情報も明示的に渡す必要があります。OAuth やキーチェーン読み取りをスキップするため、Anthropic 認証は ANTHROPIC_API_KEY 環境変数か --settings に渡す JSON の apiKeyHelper から取得します。CI のシークレットに API キーを入れて環境変数で渡す構成が基本になります。
ステップ3: 標準入力パイプとファイル参照でデータを渡す
自動化では「処理対象のデータをどう渡すか」が鍵になります。非対話モードは標準入力を読み取るので、他の CLI ツールと同じようにパイプで渡せます。
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
この例では、ビルドエラーのログを Claude にパイプし、根本原因の説明をファイルにリダイレクトしています。パイプで渡すと Claude はそのファイルを Read ツールで開く必要がないため、読み取り権限を持たせなくて済む、という副次的なメリットもあります。
ただし、パイプには制限があります。公式ドキュメントによれば、Claude Code v2.1.128 以降、パイプされた標準入力は 10MB に制限されています。これを超えると、Claude Code は明確なエラーと 0 以外の終了ステータスで終了します。大きなログやデータを扱う場合は、パイプで流し込むのではなく、内容をファイルに書き出し、プロンプト内でそのファイルパスを参照させる方式に切り替えてください。
複数ステップの会話を続けたい場合は、--continue で最新の会話を、--resume でセッション ID を指定して特定の会話を続けられます。後者は session_id をキャプチャしておく必要があります。
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
ここまでで「非対話で、再現性高く、データを渡して実行する」土台ができました。次は、この実行を無人で回す前に絶対に固めておくべき権限設計です。
暴走させない権限設計 — allowedToolsとpermission-modeでロックダウンする

ここが本記事の核心であり、冒頭で挙げた「勝手にファイルを壊すのが怖くて任せきれない」というペインポイントへの直接の回答です。対話モードでは Claude が危険な操作の前に確認してくれますが、非対話モードではその確認が効きません。だからこそ、何を許すかを事前に許可リストで決め、それ以外は実行させない設計を、起動前に固めておく必要があります。
考え方はシンプルです。最小権限から始め、必要な分だけ開ける。読み取りだけで足りるなら Read だけ、git の差分を見るだけなら git diff だけ。許可していないものは Claude が実行しようとした時点で中止されます。この「許可していなければ動けない」状態を作ることが、無人運用の安全境界になります。
allowedToolsの権限ルール構文
--allowedTools は、Claude が確認なしで使えるツールを明示します。ツール名をカンマ区切りで並べるのが基本です。
claude -p "Run the test suite and fix any failures" \
--allowedTools "Bash,Read,Edit"
さらに、Bash コマンドは中身まで絞り込めます。--allowedTools はパーミッションルール構文を使うため、Bash(git diff *) のように書くと「git diff で始まるコマンドだけ」を許可できます。
claude -p "Look at my staged changes and create an appropriate commit" \
--allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"
ここで注意すべき落とし穴があります。スペースが意味を持つ点です。末尾の *(半角スペース+アスタリスク)はプレフィックスマッチを有効にし、Bash(git diff *) は git diff で始まるコマンドにマッチします。ところがスペースを抜いて Bash(git diff*) と書くと、git diff-index のような別コマンドにもマッチしてしまいます。意図より広い範囲を許可してしまう典型的なミスなので、許可ルールを書くときはスペースの有無を必ず確認してください。
パーミッションモードの使い分け
ツールを個別に列挙する代わりに、セッション全体の振る舞いを --permission-mode で指定する方法があります。自動化では特に次の2つを押さえます。
モード | 振る舞い | 向いている用途 |
|---|---|---|
|
| ロックダウンした CI 実行。許可したもの以外は一切動かさせたくないとき |
| ファイル書き込みをプロンプトなしで許可し、 | ファイル編集を任せたいが、ネットワークや任意コマンドは握らせたくないとき |
dontAsk は「明示的に許可したもの以外は全拒否」なので、無人実行で最も安全側に倒せるモードです。読み取り中心のレビュー自動化など、許可範囲が狭く決まっているタスクに向きます。
claude -p "Apply the lint fixes" --permission-mode acceptEdits
acceptEdits は便利ですが、ファイル書き込みを自動承認する点には注意が必要です。公式ドキュメントが明記しているとおり、その他のシェルコマンドとネットワークリクエストは --allowedTools か permissions.allow ルールがない限り、実行が試みられた時点で中止されます。つまり「ファイルは書けるが、勝手に外部通信や任意コマンドは打てない」境界になっており、編集タスクには使いやすい一方、本当に書き込みを任せてよいスコープかは事前に見極めてください。
実務的な勘所として、無人実行では権限を渡しすぎないこと、そして1回の起動で完結する設計にすることが安定につながります。権限の許可範囲が広いほど、想定外の入力に対する暴走の余地も広がります。「このタスクに本当に必要な最小ツール集合は何か」を毎回問い直すのが、結局いちばん事故を減らします。
bareで実行環境を固定し再現性を担保する
権限設計と並んで重要なのが、実行環境を固定することです。前述の --bare は起動高速化のためだけのフラグではなく、安全性・再現性の観点でも効いてきます。
ベアモードは hooks・skills・plugins・MCP サーバー・auto memory・CLAUDE.md を読み込みません。これは裏を返せば、チームメイトの ~/.claude に設定されたフックや、プロジェクトの .mcp.json の MCP サーバーが、CI で勝手に実行されないということです。自動化のスクリプトを書いた本人の環境では意図どおり動いても、別の人の設定や MCP サーバーが混ざると、想定外のツールが有効になってしまう恐れがあります。ベアモードなら、明示的に渡したフラグだけが有効になるため、「許可した範囲」を環境差で破られる心配がありません。
CI とスクリプトで --bare を基本にすることで、「権限設計どおりの範囲でしか動かない」状態を、どのマシンでも担保できます。権限ロックダウンと環境固定はセットで考えるのが安全です。
出力を機械可読にする — output-format jsonとjson-schemaでパイプラインに繋ぐ
自動化は「Claude の出力を次の処理に確実に渡せる」ことが前提になります。デフォルトのテキスト出力は人間が読むには十分ですが、機械的に処理しようとすると、自然言語の中から必要な値を取り出すのが難しい。そこで出力を構造化します。
text / json / stream-json の使い分け
--output-format で応答の返し方を制御できます。公式ドキュメントが示す3種類は次のとおりです。
text(デフォルト): プレーンテキスト出力。人間が読む・単純にファイルへリダイレクトするだけなら十分json: 結果・セッション ID・メタデータを含む構造化 JSON。テキスト結果はresultフィールドに入る。自動化では基本これを使うstream-json: 改行区切り JSON。リアルタイムにトークンやイベントを処理したいときに使う
claude -p "Summarize this project" --output-format json
json を使う最大の理由は、結果だけでなくメタデータが取れることです。後述するコスト追跡(total_cost_usd)やセッション ID の取得は、この json 出力があって初めて成立します。自動化では原則 --output-format json を付けると考えてよいでしょう。
json-schemaで構造化出力を固定し後続処理を安定させる
JSON で返せても、result の中身が自然言語のままだと、結局そこからパースが必要になります。出力の構造そのものを固定したい場合は、--json-schema に JSON Schema を渡します。
claude -p "Extract the main function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'
このとき構造化された出力は structured_output フィールドに入ります(result ではない点に注意)。スキーマで「文字列の配列を functions に入れる」と指定しておけば、Claude の出力が毎回その形に揃うため、後続処理は型を前提にできます。AI の出力は本質的に非決定的ですが、スキーマで器を固定することで、下流のパイプラインが壊れにくくなります。「出力が想定の形と違ってスクリプトが落ちる」という自動化の典型的な不安定要因を、ここで先回りして潰せます。
jqでのパースとファイル出力の実例
実際の抽出は jq で行います。テキスト結果が欲しいだけなら .result を、スキーマ指定時の構造化出力なら .structured_output を抜き出します。
# テキスト結果を抽出
claude -p "Summarize this project" --output-format json | jq -r '.result'
# 構造化された出力を抽出
claude -p "Extract function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'
stream-json を使う場合は、各行がイベントを表す JSON オブジェクトになります。--verbose と --include-partial-messages を併用し、jq でテキストデルタだけを拾えば、生成中のトークンをリアルタイムに流せます。
claude -p "Write a poem" --output-format stream-json --verbose --include-partial-messages | \
jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
ここまでで「権限を絞り、出力を構造化して次工程に渡せる」1回の実行が完成しました。残るは、この実行を「いつ起動するか」です。
トリガーに乗せる — cron・GitHub Actions・loopで繰り返し実行する

スクリプト化したヘッドレス実行を、どのタイミングで起動するか。選択肢は大きく3系統あります。(a) OS の cron / launchd で定期起動する、(b) GitHub Actions のスケジュールや PR イベントで CI 起動する、(c) Claude Code 自身のスケジュール機能やセッション内ループで回す、です。自分の業務がどれに当てはまるかで選びます。
OSのcron / launchdで定期起動する
「毎朝9時にデータを集計する」「毎週月曜にレポートを生成する」といった時刻ドリブンの無人バッチには、OS の cron(Linux)や launchd(macOS)が素直です。ヘッドレス実行をシェルスクリプトでラップし、cron に登録するだけで成立します。
# 例: 毎朝のログ要約を生成して所定の場所に出力する
cat /var/log/app/today.log | claude --bare -p \
"本日のエラーログを重大度別に3行で要約してください" \
--allowedTools "Read" \
--output-format json | jq -r '.result' > /reports/daily-summary.txt
cron 方式のメリットは、外部サービスに依存せず手元で完結することです。ただし注意点として、起動するマシンが動き続けている必要があり、API キーなどの認証情報を環境変数で確実に渡す設計が必須になります。--bare で環境を固定し、--allowedTools で権限を絞ったうえで cron に乗せるのが基本形です。
なお、Claude Code 自体にもスケジュールタスク機能が用意されており、標準の5フィールド cron 構文(分・時・日・月・曜日)を自然言語プロンプトと組み合わせて定期実行できます。cron 式はローカルタイムゾーンで解釈されます。OS の cron を自前で書くか、Claude Code の機能に任せるかは、運用の好みで選んでよいでしょう(DevelopersIO の解説)。
GitHub ActionsでCI/イベント起動する
「PR が出るたびに差分をレビューさせる」「main へのマージ前にタイポをチェックする」といったイベントドリブンの自動化は、GitHub Actions が適しています。schedule トリガーで cron 的な定期実行も、pull_request トリガーでイベント駆動も組めます(GitHub Actions Scheduled の解説)。
PR の差分をレビューさせる最小形は、package.json のスクリプトとして次のように書けます。公式ドキュメントの例をベースにしています。
{
"scripts": {
"lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo in this diff, report filename:line on one line and the issue on the next. return nothing else.\""
}
}
差分をパイプで渡しているため Claude は読み取り権限を必要とせず、エスケープしたダブルクォートで Windows でも動くようにしています。これを CI のステップから呼べば、PR ごとのタイポチェックが無人で回ります。
CI で特に有効なのが、設定の読み込み失敗を検知してジョブを落とす仕掛けです。stream-json 出力の最初に流れる system/init イベントには、読み込まれたプラグインの情報(plugins)と、読み込み時エラー(plugin_errors)が含まれます。期待したプラグインが plugins に存在しない、あるいは plugin_errors が空でない場合に CI を失敗させれば、「設定が欠けたまま自動化が動いてしまう」事故を防げます。無人運用では「動いたけど中身が違った」が一番怖いので、起動時の前提チェックを CI に組み込んでおく価値は高いです。
トリガー選定の判断軸
3系統をどう使い分けるか、判断軸を整理します。
トリガー | 起動契機 | 向いている業務 | 主な制約 |
|---|---|---|---|
OS cron / launchd | 時刻(定期) | 定期監視・定型レポート・毎朝の集計 | 起動マシンを動かし続ける必要がある |
GitHub Actions(schedule) | 時刻(定期・クラウド) | 定期実行をローカルマシンに依存させたくないとき | リポジトリ前提・実行環境のシークレット管理が必要 |
GitHub Actions(pull_request 等) | イベント駆動 | PR レビュー・差分チェック・マージ前検証 | イベントが発生したときだけ動く |
Claude Code スケジュール / | 時刻 / セッション内ループ | 簡易な定期チェック・一時的なポーリング | セッション前提のものは無人バッチには不向き |
ざっくりした選び方は次のとおりです。時刻で定期的に回したいなら cron 系、PR やプッシュに反応させたいなら GitHub Actions のイベント駆動、ローカルマシンの稼働に依存させたくないならクラウド側(GitHub Actions やクラウド実行)。自分の定型業務が「いつ動いてほしいか」を起点に選べば、迷いは小さくなります。
トリガーまで決まれば、自動化の骨格は完成です。ただし、無人で回し続けるには、もう一段「壊れない運用」の設計が要ります。
本番運用で詰まる落とし穴 — 冪等性・コスト・失敗ハンドリング

一度動いたからといって、本番に乗せて回し続けると別の問題が出てきます。同じジョブが二重に走ったり、コストが想定外に膨らんだり、失敗が黙って握り潰されたり。ここでは、無人運用を継続するための非機能要件を3つ、先回りして押さえます。これらを潰せば、「任せきる踏ん切りがつかない」の最後の不安が解消されます。
冪等性 — 同じジョブが複数回走っても安全にする
cron の重複起動、CI のリトライ、手動再実行など、同じジョブが複数回走る状況は現実に起こります。このとき何度走っても結果が壊れないこと、つまり冪等性が無人運用の前提になります。
具体的な作り込みとしては、
- 処理済みかをジョブ側で確認する: 「今日のレポートはもう生成済みか」をファイルの存在やフラグで先にチェックし、済んでいればスキップする
- 差分検知で対象を絞る: 「前回処理した時点からの新規分だけ」を対象にする。毎回全件を処理し直さない
- 出力先を上書き前提にする: 追記ではなく所定パスへの上書きにし、二重実行でも内容が重複しないようにする
Claude の出力は非決定的なので、「2回走ったら2回とも微妙に違う結果が両方残る」事態は避けたい。ジョブのトリガーが重複しうる前提で、処理側を冪等に設計しておくと安心です。
コストの可観測性 — total_cost_usdで呼び出しごとに支出を追う
無人で回す自動化で見落としがちなのが、コストです。毎時起動するジョブが、いつの間にか想定の何倍も API コストを使っていた、という事態は避けたい。ここで効くのが --output-format json です。
公式ドキュメントによれば、--output-format json を使うと応答ペイロードに total_cost_usd とモデルごとのコスト内訳が含まれます。これにより、スクリプトの呼び出し元は使用状況ダッシュボードを見に行かなくても、呼び出しごとの支出をその場で追跡できます。
result=$(cat input.txt | claude --bare -p "..." --output-format json)
cost=$(echo "$result" | jq -r '.total_cost_usd')
echo "$(date -Iseconds) cost=$cost" >> /var/log/claude-cost.log
# しきい値を超えたらアラートを出す等の処理をここに足せる
呼び出しごとにコストをログへ書き出しておけば、日次・週次で集計して予算超過を検知できます。無人運用では「気づいたら高額」が起こりやすいので、コストを観測可能にしておくこと自体が安全装置になります。
なお、サブスクリプションプランでの claude -p / Agent SDK の利用枠については、2026年6月15日以降、対話利用とは別の月次 Agent SDK クレジットから消費される旨が公式ドキュメントに記載されています。自動化を本格運用する前に、自分のプランでの利用枠と課金体系を公式の案内で確認しておくと、想定外の枠超過を防げます。
失敗ハンドリング — リトライイベント・終了コード・タイムアウト
無人運用では、失敗を「黙って握り潰さない」ことが重要です。3つの観点で備えます。
リトライの観測: API リクエストが再試行可能なエラーで失敗すると、Claude Code は再試行前に system/api_retry イベントを発行します。このイベントには現在の試行番号(attempt)、最大リトライ数(max_retries)、次の試行までの待機ミリ秒(retry_delay_ms)、エラーカテゴリ(error)などが含まれます。stream-json でこれを観測すれば、リトライが頻発していないか、どんなエラーで再試行しているか(rate_limit なのか overloaded なのか等)を運用ログに残せます。
終了コードでジョブの成否を判定する: 前述のとおり、標準入力が 10MB 制限を超えた場合などは 0 以外の終了ステータスで終わります。シェルスクリプト側で終了コードを必ずチェックし、非ゼロなら後続処理を止める・通知するようにします。
cat input.txt | claude --bare -p "..." --output-format json > out.json
if [ $? -ne 0 ]; then
echo "claude run failed" >&2
exit 1
fi
タイムアウトを設ける: AI の実行時間は入力次第でぶれます。cron や CI で無制限に待たせると、ジョブが詰まったまま次の起動と重なる恐れがあります。timeout コマンドなどで上限を設け、超過したら失敗扱いにする方針を決めておきます。
これら3つ — 冪等性・コスト可観測性・失敗ハンドリング — は、いずれも「公式ドキュメントのフラグ説明だけでは見えにくいが、無人で回し続けると必ず当たる壁」です。本番投入の前にチェックリストとして潰しておくと、安心して任せられます。
まとめ — 小さく始めて段階的に自動化を広げる
ここまで、Claude Code の業務自動化を「対話で検証 → ヘッドレス(-p)→ 権限ロックダウン → 構造化出力 → トリガー → 本番運用チェック」という一本の流れで見てきました。要点を振り返ります。
- 自動化の単位は
-pでの1回完結実行。対話で意図を固めてから非対話に移す --bareで環境を固定し、どのマシンでも同じ範囲でしか動かないようにする--allowedToolsと--permission-mode dontAskで最小権限から始め、許可したもの以外は実行させない--output-format jsonと--json-schemaで出力を機械可読・構造固定にし、下流を安定させる- cron / GitHub Actions / スケジュール機能から、業務の起動契機に合うトリガーを選ぶ
- 冪等性・コスト可観測性・失敗ハンドリングを本番投入前に潰す
最初の一歩は、できるだけ小さく取ることをおすすめします。たとえば「PR 差分のタイポチェックを、Read も不要なパイプ渡しで、CI に1つ置く」だけでよいのです。差分は git diff で渡し、権限は最小、出力は人間がレビューで確認する。これなら万一おかしな指摘が出ても実害はなく、自動化を任せる感覚を安全に掴めます。
そこで「壊れない」という手応えが得られたら、レポート生成、テスト修正、定期集計へと、権限と対象を一段ずつ広げていきます。いきなり本番データの変更や外部通知を任せるのではなく、「間違えても取り返せる範囲」から「人間の承認を挟む範囲」へ、段階的に。この記事を読み終えたいま、あなたは「自分のこの業務は、この権限設定・この出力フォーマット・このトリガーで安全に自動化できる」と判断する材料を手にしています。明日、まず1つ、小さな自動化を作ってみてください。
よくある質問(FAQ)
Q. ヘッドレス実行(-p)と対話モードはどう使い分けるべきですか?
A. 人間がその場で判断しながら進める探索的な作業は対話モード、入力が定型で完了条件が明確な繰り返し作業はヘッドレス(-p)モードが向きます。実務では「対話で1回やらせて意図を固め、安定したら同じタスクを -p で再現してスクリプト化する」という流れが安全です。なお、ユーザーが呼び出すスキル(/code-review 等)や組み込みコマンドは対話モードでのみ利用できるため、-p では実行したいタスクを自然言語で記述します。
Q. 自動化で勝手にコードが壊れないようにするには?
A. 権限を許可リストで絞るのが基本です。--allowedTools "Read" のように必要最小限のツールだけを許可し、CI では --permission-mode dontAsk(許可リスト外は全拒否)でロックダウンします。Bash(git diff *) のようにコマンド単位で絞る際は、末尾スペースの有無でマッチ範囲が変わる点に注意してください。さらに --bare で他人の設定や MCP を読み込ませないことで、許可範囲を環境差で破られないようにできます。
Q. 定期実行のコストはどう抑えればよいですか?
A. --output-format json の応答に含まれる total_cost_usd を呼び出しごとにログへ記録し、日次・週次で集計して予算超過を検知します。加えて、冪等性を持たせて不要な再実行を減らす、--bare で余計なコンテキスト読み込みを省く、といった工夫が効きます。サブスクリプションプランでの -p 利用枠は2026年6月15日以降の課金体系の変更があるため、本格運用前にプランの利用枠を確認してください。
Q. Docker サンドボックスのような隔離環境で動かすべきですか?
A. 書き込みや任意コマンド実行を伴う自動化を本番リポジトリで直接走らせるのが不安な場合、コンテナ等の隔離環境で実行するのは有効な選択肢です。隔離環境であれば、万一意図しない操作が起きても影響範囲をその環境内に閉じ込められます。権限ロックダウン(--allowedTools / dontAsk)と隔離環境は排他ではなく、両方を組み合わせることで多層の安全境界を作れます。まずは権限設計で絞り、影響が大きい操作を含む自動化では隔離環境の併用を検討する、という順序がおすすめです。
Q. Agent SDK(Python/TypeScript)と -p のどちらを使うべきですか?
A. シェルスクリプトや cron・CI に組み込むだけなら、CLI の claude -p が手軽で十分です。一方、ツール承認のコールバックをプログラムで制御したい、ネイティブなメッセージオブジェクトを扱いたい、アプリケーションに深く組み込みたい、といった要件があれば Python / TypeScript の Agent SDK が適しています。-p は同じ Agent SDK のエージェントループを CLI から呼ぶ薄いインターフェースなので、まず -p で自動化の形を固め、より細かい制御が必要になった段階で SDK へ移行する、という進め方が無理がありません。



