Created
March 21, 2026 10:07
-
-
Save potix2/6044bd9d8b5fc724429583c32930bec0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # AIエージェントが使いやすいCLI設計条件 — 2026年版 | |
| ## 背景:なぜ今CLIが再注目されているか | |
| 2025〜2026年にかけて、Claude Code・Codex CLI・Gemini CLIなどの**Agentic CLI**が爆発的に普及した。同時に「MCP (Model Context Protocol) サーバーを構築したが、結局よく設計されたCLIに置き換えた」というチームが続出している。Peter Steinberger(OpenClaw作者、2026年のGitHub最多貢献者)の「*mcp were a mistake. bash is better.*」という発言が象徴するように、**CLIこそがAIエージェントと世界をつなぐ本命インターフェース**という認識が定着しつつある。 | |
| 以下、2026年時点で業界コンセンサスが形成されつつある設計条件を7つの柱で整理する。 | |
| ----- | |
| ## 1. 構造化出力をデフォルトにする | |
| **原則: すべてのコマンドで `--json` (または `--output json`) を保証する** | |
| エージェントは人間向けの装飾テーブルやカラー出力をパースできない。 | |
| |観点 |Human DX |Agent DX | | |
| |-------|------------|-------------------| | |
| |デフォルト出力|整形テーブル |JSON / JSONL | | |
| |カラー |ANSI色付き |`NO_COLOR=1` で無効化可能| | |
| |プログレス表示|スピナー、プログレスバー|stderr へのイベントストリーム | | |
| **具体的な条件:** | |
| - JSON を stdout、メッセージ・ログを stderr に分離する | |
| - フィールド名・型をコマンド間で一貫させる | |
| - `--quiet` フラグでパイプ向けの裸出力を提供する | |
| ----- | |
| ## 2. 出力フォーマットをAPIコントラクトとして扱う | |
| **原則: CLI出力はバージョン管理されたAPIサーフェスである** | |
| Kubernetes が v1.18 で `--export` フラグを削除した際、Helmチャート・CI/CDパイプラインが大量に壊れた。Terraform は state ファイルに `version` フィールドを明示し、互換性を安全に管理している。 | |
| **具体的な条件:** | |
| - JSON Schema や CUE でスキーマを定義し、CIで破壊的変更を検知する | |
| - セマンティックバージョニング: 追加フィールドはマイナー、削除・変更はメジャーバンプ | |
| - 出力スキーマのリグレッションテストをCI基盤に組み込む | |
| - 破壊的変更が不可避な場合、ツール内にマイグレーションパスを組み込む | |
| ```yaml | |
| # CIでの出力スキーマ検証の例 | |
| - run: mycli show --output json > show-output.json | |
| - run: cue vet schema.cue show-output.json | |
| ``` | |
| ----- | |
| ## 3. 非対話性を保証する(Escape Hatch の設計) | |
| **原則: エージェントはプロンプトに答えられない。すべてのコマンドにマシンフレンドリーな迂回路を用意する** | |
| AWS CLI v2 がデフォルトページャーを `less` に変更した際、数千のCIジョブがインタラクティブ入力待ちで停止した。 | |
| **3層の迂回路:** | |
| |レイヤー |例 |用途 | | |
| |-----|---------------------------------|---------------| | |
| |明示フラグ|`--no-prompt`, `--yes`, `--force`|コマンド単位の制御 | | |
| |環境変数 |`NO_COLOR=1`, `MYCLI_PROFILE=dev`|グローバルコンテキスト設定 | | |
| |TTY検出|stdin が TTY でなければ自動で非対話モード |ヘッドレス環境のフォールバック| | |
| **優先順位モデル:** `明示フラグ > 環境変数 > TTY自動検出` | |
| ----- | |
| ## 4. べき等性(Idempotency)と意味的Exit Codeの設計 | |
| **原則: 同じ操作を2回実行しても安全。状態変化はフォローアップコマンドで観測可能にする** | |
| エージェントは人間と違い、コマンドをチェインし、並列実行し、失敗時にリトライする。しかもexit codeだけでなく、後続コマンドで結果を確認する傾向がある。 | |
| ```bash | |
| # 脆い: リトライで壊れる | |
| $ myctl create namespace prod | |
| Error: namespace "prod" already exists | |
| # 堅牢: べき等 | |
| $ myctl ensure namespace prod | |
| namespace "prod" already exists (no changes) | |
| ``` | |
| **Exit Code設計:** | |
| |範囲 |意味 | | |
| |-----|-----------------------------------| | |
| |0 |成功 | | |
| |1-2 |ユーザー修正可能なエラー | | |
| |3-125|アプリケーション固有エラー(5 = already exists 等)| | |
| **ポイント:** | |
| - 宣言的コマンド(`ensure`, `apply`, `sync`)は命令的コマンド(`create`, `delete`)より本質的にエージェント安全 | |
| - べき等にできない操作は、コンフリクトを型付きエラーとして返す | |
| - `kubectl apply` のモデルが良い参考 | |
| ----- | |
| ## 5. `--help` をコントラクトとして設計する | |
| **原則: エージェントが未知のCLIに遭遇したとき、最初に実行するのは `--help`** | |
| helpテキストはエージェントにとって「ツール記述 + パラメータ仕様 + 使用ガイド」のすべてを兼ねる。 | |
| **良いhelpの条件:** | |
| - 使い方(Usage)、全引数・フラグ、出力モード、exit code を網羅する | |
| - 具体的な使用例(Examples)を含める | |
| - 環境変数の一覧を「Environment」セクションに記載する | |
| - バージョン間で安定させる(helpテキスト自体もコントラクト) | |
| ```bash | |
| # Bad: エージェントは何もわからない | |
| $ myctl deploy --help | |
| Usage: myctl deploy [flags] | |
| # Good: エージェントが自律的に学習できる | |
| $ myctl deploy --help | |
| Deploy a service to the target environment. | |
| Usage: myctl deploy <service> [flags] | |
| Flags: | |
| --env string Target environment (staging|production) [required] | |
| --dry-run Preview changes without applying | |
| --output string Output format: json, table (default: table) | |
| --timeout int Timeout in seconds (default: 300) | |
| Exit Codes: | |
| 0 Success | |
| 1 Invalid arguments | |
| 5 Service already running (no changes) | |
| Examples: | |
| myctl deploy api --env staging --dry-run --output json | |
| ``` | |
| ----- | |
| ## 6. フィードバックループを短くする | |
| **原則: トークンはエージェントの通貨。無駄なトークン消費を避け、早期に正しいフィードバックを返す** | |
| ### 早期バリデーション(Dry Run / Validate) | |
| ```bash | |
| ansible-playbook nginx.yml --syntax-check # 構文チェック | |
| ansible-playbook nginx.yml --check --diff # 変更プレビュー | |
| ``` | |
| 破壊的操作の前に `--dry-run` で安全確認できることが必須。`validate` と `run` を分離する設計が望ましい。 | |
| ### 進捗レポーティング | |
| 長時間タスクは stderr にイベントストリームを出力する。エージェントは出力を読み、失敗を早期検知し、中断タイミングを推定できる。 | |
| ### グレースフルターミネーション | |
| `SIGTERM` を適切にハンドリングし、状態を一貫した形でクリーンアップする。エージェントがツールの一貫性を信頼できなければ、全体の信頼性が低下する。 | |
| ----- | |
| ## 7. MCPとの共存戦略 | |
| **原則: まずCLIを堅牢に設計し、MCP はその上のディスカバリ層として位置づける** | |
| 2026年の実践的コンセンサスは「MCP vs CLI」ではなく「CLIをMCPでラップする」方向に収束しつつある。 | |
| **MCPが追加する価値:** | |
| - 動的なケイパビリティディスカバリ(エージェントが実行時にツール機能を発見) | |
| - 入力の事前バリデーション(スキーマベース) | |
| - ベスポーク統合なしに、MCP対応の全エージェントから即座に利用可能 | |
| **実装順序:** | |
| 1. CLIのエスケープハッチ・構造化出力・exit codeを完成させる | |
| 1. bats-core 等でCLIのリグレッションテストを確立する | |
| 1. fastMCP 等のフレームワークでMCPサーバーをCLIのラッパーとして構築する | |
| ```json | |
| { | |
| "name": "deploy", | |
| "description": "Deploy the application to a chosen environment", | |
| "inputSchema": { | |
| "type": "object", | |
| "properties": { | |
| "environment": { "type": "string", "enum": ["staging", "production"] }, | |
| "force": { "type": "boolean", "default": false } | |
| }, | |
| "required": ["environment"] | |
| } | |
| } | |
| ``` | |
| ----- | |
| ## チェックリスト | |
| |# |条件 |状態| | |
| |--|-------------------------------|--| | |
| |1 |`--json` フラグで全コマンドが構造化出力可能 |☐ | | |
| |2 |JSON は stdout、メッセージは stderr |☐ | | |
| |3 |意味的 exit code(0/1だけでなく) |☐ | | |
| |4 |べき等な操作(または明示的コンフリクトハンドリング) |☐ | | |
| |5 |例付きの包括的 `--help` |☐ | | |
| |6 |破壊的コマンドに `--dry-run` |☐ | | |
| |7 |`--yes` / `--force` でプロンプトをバイパス|☐ | | |
| |8 |`--quiet` でパイプ向け裸出力 |☐ | | |
| |9 |コマンド間で一貫したフィールド名と型 |☐ | | |
| |10|一貫した名詞-動詞階層(例: `noun verb`) |☐ | | |
| |11|エラーコード付きのアクショナブルなエラーメッセージ |☐ | | |
| |12|バッチ操作のサポート |☐ | | |
| |13|TTY検出による非対話自動切替 |☐ | | |
| |14|出力スキーマのCI検証 |☐ | | |
| |15|MCP ディスカバリ対応 |☐ | | |
| ----- | |
| ## 2026年の新しい潮流 | |
| ### CLI-Anything(2026年3月〜) | |
| 香港大学発のOSSプロジェクト。任意のGUIソフトウェアのソースコードを解析し、AIエージェントが使えるCLIを自動生成する。GIMP、Blender、LibreOffice等に対応。「今日のソフトウェアは人間向け。明日のユーザーはエージェント」というビジョンを体現。生成されるCLIはすべて上記の設計原則(デフォルトテーブル + `--json`、永続状態、undo/redo)に従う一貫した設計。 | |
| ### テレメトリのエージェント対応 | |
| エージェントは人間と異なる利用パターンを示す(全機能を一度に採用、高速チェイン、並列実行)。テレメトリでエージェント起因のエラー率・タイムアウトを追跡し、デフォルト値や出力形式の改善に活かす流れ。`MYCLI_NO_TELEMETRY=1` によるオプトアウトは必須。 | |
| ----- | |
| ## 参考ソース | |
| - InfoQ「Keep the Terminal Relevant: Patterns for AI Agent Driven CLIs」(2025.8) | |
| - DEV Community「Writing CLI Tools That AI Agents Actually Want to Use」(2026.2) | |
| - nibzard「Designing CLI Tools for AI Agents」(2026.2) | |
| - Medium「Why CLIs Beat MCP for AI Agents」(2026.3) | |
| - CLI-Anything (GitHub, 2026.3) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment