Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Feb 6, 2026 - 日記

Agentic CLI Design: CLIをAIエージェント向けプロトコルとして設計する7つの原則

English version

Agentic CLI Design: CLIをAIエージェント向けプロトコルとして設計する7つの原則 cover image

CLIツールは長年、人間が端末で操作するためのインターフェースとして設計されてきました。しかし、LLM (大規模言語モデル)やAIエージェント (自律的にツールを呼び出してタスクを進めるプログラム)が普及した今、CLIには新しい役割が求められています。それは「エージェントが安全・確実・反復可能に呼び出せるプロトコル/API」としての設計です。

自分も最近、エージェントにCLIを回させる機会が増えました。人間相手なら気にならない「確認プロンプトで止まる」「ログがstdoutに混ざってパースできない」「同じ操作を再実行して事故る」が、エージェント相手だと普通に起きます。

本記事では、私が提唱する「Agentic CLI Design」という設計概論をまとめます。CLIを「人間が操作するUI」から「エージェントが呼び出すプロトコル」へと再定義し、失敗前提・再実行前提・非対話前提で成立させるための7つの設計原則です。

Agentic CLI Designとは

Agentic CLI Designは、LLM/エージェントが非対話・反復・失敗前提の環境で、CLIを安全に確実に実行できるよう設計されたCLIの設計原則です。

人間向けの「手触り」や「使いやすさ」より、機械が読み・判断し・再実行し・復旧できることを最適化します。

成功条件

エージェントが以下の条件を満たせることが、Agentic CLI Designの成功条件です:

  • 迷わず: 選択肢が明示され、次のアクションを判断できる
  • 壊さず: 安全側デフォルトで、破壊操作には明示的な確認が必要
  • 詰まらず: 非対話で完走でき、タイムアウト/リトライ方針が明確
  • 何度でも: 冪等性があり、再実行しても安全
  • 自己修復しながら: 観測性があり、エラーから復旧手順を判断できる

7つの原則

Agentic CLI Designは、以下の7つの原則(原則1〜原則7)で構成されます。

原則1: Machine-readable(機械可読が主)

原則: 出力は構造化され、機械が確実にパースできる形式を提供する。

設計チェック:

  • --json / --output json|yaml|text オプションがある
  • 標準出力(stdout)=結果 / 標準エラー出力(stderr)=ログ・進捗 を厳守(混ぜない)
  • エラーも構造化(可能ならJSONで)
  • スキーマは安定(破壊的変更は schemaVersion 等で管理)

:

Kubernetes のCLIであるkubectl は、JSON出力をサポートしています。 AWS CLI--output json を持っています。

1
2
3
4
5
# 成功時の構造化出力
kubectl get pods -o json

# JSON出力を使う例
aws ec2 describe-instances --output json 2>&1

人間向けの「見やすい表」は二の次です。エージェントはJSONやYAMLを確実にパースできる必要があります。

最小推奨レスポンス(JSON):

成功時:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "ok": true,
  "type": "items.list",
  "schemaVersion": 1,
  "data": {
    "items": [
      {"id": "...", "createdAt": "2026-02-05T08:00:00Z"}
    ],
    "nextCursor": "..."
  }
}

失敗時:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "ok": false,
  "type": "items.list",
  "schemaVersion": 1,
  "error": {
    "code": "rate_limited",
    "message": "...",
    "retryAfterMs": 1200
  }
}

原則2: Non-interactive by default(非対話がデフォルト)

原則: 対話プロンプトを前提にせず、ヘッドレス環境(画面や対話操作なしで動くCI、ジョブランナー)でも完走できる。

設計チェック:

  • --yes / --force / --no-confirm / --non-interactive オプションがある
  • TTYが無い環境でも必ず完走できる
  • 対話が必要な場合は、明示的にオプトイン

:

Terraform のように、実行前提のオプションが揃っているとエージェント運用が楽になります。

1
2
3
4
5
# 対話なしで実行
terraform apply -auto-approve

# 非対話モードを明示
apt-get install -y package-name

エージェントは「Y/N?」のプロンプトに答えられません。すべての選択は事前にオプションで指定できる必要があります。 また、TTY(対話端末)が無い環境でも止まらないことが重要です。

認証(OAuth/headless)の要点:

  • 可能なら Device Authorization Grant(RFC 8628)を第一候補
  • auth status --json を用意して、エージェントが前提確認できる
  • auth export / auth import で headless 環境への移行を支援
  • --non-interactive 時は「聞き返さずにエラー + 次の手順」を返す

原則3: Idempotent & Replayable(冪等・再実行耐性)

原則: 同じコマンドを複数回実行しても安全で、結果が予測可能。

冪等(べきとう)とは、同じ操作を何度繰り返しても結果が変わらない性質です。エージェントはタイムアウトやネットワーク断で「同じコマンドをもう一度叩く」ことがあります。そのときに事故らない設計が必要です。

設計チェック:

  • 送信/作成は dedupe-key / client-request-id を受け付ける
  • “作成済み"の挙動を選べる: --if-exists skip|update|error
  • 取得はページングを明示: --limit --cursor --all

:

1
2
3
4
5
6
7
8
# 冪等な作成(既に存在する場合はスキップ)
kubectl apply -f deployment.yaml

# HTTP APIを叩くCLIなら、リクエストID(重複防止キー)を明示する
curl -sS -X POST https://api.example.com/v1/items \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 01JHXXXX...' \
  -d '{"name":"example"}'

エージェントはネットワークエラーやタイムアウトで同じコマンドを再実行する可能性があります。再実行しても安全な設計が必要です。

原則4: Safe-by-default(安全側デフォルト)

原則: 破壊操作はデフォルトで実行されず、明示的な確認が必要。

設計チェック:

  • 破壊操作は --dry-run / --confirm <id> を強制できる
  • 削除は --force 必須など、デフォルトで事故が起きない
  • 権限/スコープは最小化し、足りないときは"次の手順"を返す

:

1
2
3
4
5
6
7
8
# dry-runで事前確認
terraform plan

# 実行には明示的な承認が必要
terraform apply

# 破壊操作の前にプレビューを用意する
kubectl diff -f deployment.yaml

エージェントは「うっかり」削除することがあります。破壊操作には複数段階の確認が必要です。

原則5: Observable & Debuggable(観測性・デバッグ容易性)

原則: 実行状況を観測でき、エラー時に復旧手順を判断できる。

設計チェック:

  • --verbose / --debug / --log-format json がある
  • --trace-id で相関IDを渡せる
  • 終了コードを分類して自動リカバリしやすく
    • 例: 0=成功 / 2=引数エラー / 3=認証エラー / 4=リトライ推奨

:

1
2
3
4
5
6
7
8
9
# 詳細ログを出力
kubectl apply -f deployment.yaml --v=9

# 終了コードで判断
if [ $? -eq 4 ]; then
  echo "Retryable error, waiting..."
  sleep 5
  retry_command
fi

エージェントはエラーメッセージから「次の一手」を判断します。終了コードとエラーの構造化が重要です。

終了コードの推奨分類:

  • 0: 成功
  • 2: 引数エラー / 使い方エラー
  • 3: 認証 / 権限エラー
  • 4: リトライ推奨(rate limit / transient)

原則6: Context-efficient(コンテキスト節約)

原則: LLMのコンテキストウィンドウを無駄に消費しない。

設計チェック:

  • --fields/--select(投影)で必要なフィールドのみ取得
  • --output ndjsonNDJSON 、1行1JSONのストリーミング形式)で大量データを扱う
  • デフォルトはサマリ、詳細は get/--include-* で明示
  • サーバサイド絞り込み(since/until/query/type…)を厚く

:

1
2
3
4
5
# 必要なフィールドのみ取得
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase

# ページングで大量データを扱う
aws s3api list-objects-v2 --bucket my-bucket --max-items 100

エージェントは大量のデータをコンテキストウィンドウ(LLMが一度に参照できる入力の上限)に詰め込むと、トークン(ざっくり言うと文字数に近い単位)の制限に引っかかります。必要最小限のデータのみ取得できる設計が必要です。

原則7: Introspectable(自己記述できるCLI)

原則: CLI自身が仕様を機械可読で吐き、エージェントが自己発見できる。

設計チェック:

  • commands --json(コマンド一覧・引数一覧)がある
  • schema --command ... --output json-schema(コマンド単位のJSON Schema 、JSONの構造定義)がある
  • --help --json(例、終了コード、エラー語彙)がある
  • --output json のトップレベル固定フィールド例:
    • schemaVersion, type, ok

:

1
2
3
4
# これは「こういう自己記述があると嬉しい」という設計例
tool commands --output json
tool schema --command items.list --output json-schema
tool help items.list --output json

Model Context Protocol (MCP)はツール定義からスキーマが分かりますが、CLIはブラックボックスになりがちです。CLI自身が仕様を機械可読で吐くことで、エージェントが自己発見できるようになります。

Introspection(自己記述)コマンドの推奨セット:

  • tool commands --json
  • tool schema --command <subcommand...> --output json-schema
  • tool help --json(または各コマンドに --help --json

アンチパターン集

以下は、Agentic CLI Designの観点から「よく壊れるやつ」です。

stdoutにログ/進捗が混ざる

1
2
3
# ❌ 悪い例
echo "Processing..."
echo '{"result": "success"}'

エージェントはJSONをパースしようとして失敗します。ログはstderrに出力してください。

JSONの形が条件で変わる

1
2
3
# ❌ 悪い例
# 成功時: {"data": {...}}
# 失敗時: {"error": "..."}

ok フィールドで成功/失敗を明示し、構造を統一してください。

対話がデフォで、headlessで詰まる

1
2
# ❌ 悪い例
read -p "Continue? (y/n): " answer

CI環境やジョブランナーで詰まります。--yes オプションを用意してください。

破壊コマンドがデフォで実行できる

1
2
# ❌ 悪い例
rm -rf /data/*

--dry-run--confirm の2段階確認を用意してください。

--all が巨大JSON一発

1
2
# ❌ 悪い例
curl https://api.example.com/items?all=true

コンテキストウィンドウが爆発します。ページング(--limit / --cursor)を用意してください。

認証がブラウザ必須で、リモート/コンテナで破綻

1
2
# ❌ 悪い例
open https://auth.example.com/login

Device Authorization Grant (RFC 8628)を第一候補にしてください。

Scorecard(レビュー用チェックリスト)

以下は、Agentic CLI Designの7つの原則を0/1/2点で採点できるチェックリストです。他プロジェクトへ移植しやすいよう、具体的な項目で構成しています。

原則1: Machine-readable

  • --output json がある
  • stdout=結果 / stderr=ログ が守られている
  • エラーが構造化されている(JSON推奨)
  • schemaVersion がある/互換性方針が明文化されている

原則2: Non-interactive

  • --non-interactive がある(TTY無しで自動ONでもよい)
  • 対話が必要な操作は全てオプトイン(=デフォ対話しない)
  • --yes/--force/--no-confirm の語彙が統一されている

原則3: Idempotent & Replayable

  • 書き込み系に --client-request-id / --dedupe-key 相当がある
  • --if-exists の方針がある
  • --cursor/--limit/--all がある(--all は内部でページング)

原則4: Safe-by-default

  • 破壊操作は --dry-run 可能
  • 本実行には --confirm <id> / --force のような追加ガードがある

原則5: Observable & Debuggable

  • --debug がある(ログはstderr)
  • --log-format json がある
  • --trace-id を受け付ける
  • 終了コードの分類がある(2/3/4など)

原則6: Context-efficient

  • --fields/--select がある
  • --output ndjson がある
  • heavy field は --include-* でオプトイン

原則7: Introspectable

  • commands --json がある
  • schema --command ... --output json-schema がある

このScorecardは、CLIのレビューや受け入れ基準として使用できます。

AgentSkillを公開しました

この記事で書いた内容は「原則」なので、読むだけだと実装に落とし込むときに迷いがちです。 そこで、Agentic CLI DesignをサポートするAgentSkill(エージェント向けの取扱説明書)を公開しました。

入っているもの(だいたいこのあたりが揃っていると、エージェント運用が安定します):

  • タスク別のレシピ(最短のコマンド列)
  • ガードレール(--dry-run → 確認 → --confirm のような流れ)
  • 推奨デフォルト(--output json--non-interactive、ページング等)
  • 典型的な成功/失敗の出力例(JSON)
  • エラー時の復旧手順(リトライ、認証、権限不足など)

このAgentSkillを叩き台にして、あなたのCLI向けに「安全に使うための手順と語彙」を固めていくのが一番早いと思います。

CLI vs MCP: 棲み分けの考え方

Model Context Protocol(MCP)は、AIモデルと外部ツールを接続するための標準プロトコルです。MCPとCLIは競合するものではなく、以下のように棲み分けができます。

CLIが向いているケース

  • 既存のCLIツールが存在する: GitHub CLI (gh)、kubectl、aws cliなど
  • ステートレスな操作: 1回のコマンドで完結する操作
  • Unixパイプとの組み合わせ: 既存のシェルスクリプトとの統合

MCPが向いているケース

  • CLIツールが存在しない: 独自のサービスやAPI
  • ステートフルな操作: 複数回の呼び出しで状態を保持する必要がある
  • リアルタイムストリーミング: MCPはストリーミングレスポンスをサポート
  • カスタムビジネスロジック: ツールアクセスに独自のルールを適用したい

Agentic CLI Designは、既存のCLIツールをエージェント向けに最適化するための設計原則です。新しいツールを作る場合は、MCPとCLIの両方を検討してください。

まとめ

Agentic CLI Designは、CLIを「人間が操作するUI」から「エージェントが呼び出すプロトコル」へと再定義する設計概論です。

7つの原則(原則1〜原則7)を意識することで、エージェントが「迷わず・壊さず・詰まらず・何度でも・自己修復しながら」運用できるCLIを設計できます。

既存のCLIツール(gh、kubectl、aws cli等)をレビューする際も、このScorecardを使うことで、エージェント向けの改善点を発見できます。

興味のある方は、ぜひ自分のCLIツールをScorecardで採点してみてください。

参考リンク