AIエージェントにCLIツールを提供する際、単に`--help`で全コマンドを並べるだけでは不十分である。2026年現在、組織全体でエージェントが動き始めると、ツール数が20〜30に達した時点で「エージェントが選択に失敗する」「コンテキストが肥大化する」「機密コマンドを誤実行する」などの問題が噴出する。本記事では、renue CLI(new-cli)の実装をもとに、AIエージェント向けCLIを本番品質で設計するためのパターンを解説する。50以上のドメインと数百のコマンドを持つ本番CLIが、どのようにエージェントと人間の両方から安全に利用されているかを明らかにする。
なぜAIエージェント向けCLI設計が重要か
AIエージェント向けCLIは、人間向けCLIとは設計要件が大きく異なる。以下の問題が現実に発生する。
| 問題 | 症状 | 原因 |
|---|---|---|
| 1. コンテキスト肥大化 | エージェントが遅くなる / コスト増 | 全コマンドのhelpをプロンプトに入れる |
| 2. 選択失敗 | 似たコマンドを誤実行 | 20以上のツールから正しいものを選べない |
| 3. 権限過剰 | 誤って破壊的コマンド実行 | read系とwrite系の区別がない |
| 4. 機密露出 | 管理コマンドがエージェントに見える | 人間専用コマンドを隠せない |
| 5. バージョンずれ | エージェントが存在しないコマンドを叩く | ソースとマニフェストの同期不備 |
これらを解決するには、CLIを「人間向け」と「エージェント向け」で明確に区別する必要がある。
本番品質AIエージェントCLIに必要な5レイヤー
レイヤー1: プロファイル別パック分割
renue CLI(new-cli)は、CLIの全コマンドを「パック」と呼ばれるカテゴリに分割し、用途別の「プロファイル」でパックを組み合わせる設計を取っている。
パックの例
- core: 認証・基本操作(誰でも必要な最小セット)
- pmo: プロジェクト管理、タスク、課題、議事録
- ecommerce: 広告運用、クリエイティブ、マーケティング
- hiring: 採用、スカウト、候補者管理
- finance: 経理、売上、請求、貢献度
- admin: インフラ、運用、キルスイッチ、緊急操作
プロファイルの例
export const PROFILES = {
core: {
name: "core",
packs: ["core"],
agentWorkflowBudget: 12,
maxManifestBytes: 12288,
rawAccess: false,
description: "Bootstrap and auth only",
},
pmo: {
name: "pmo",
packs: ["core", "pmo"],
agentWorkflowBudget: 40,
maxManifestBytes: 24576,
rawAccess: false,
description: "Default internal operations profile",
},
ecommerce: {
name: "ecommerce",
packs: ["core", "ecommerce"],
agentWorkflowBudget: 20,
maxManifestBytes: 16384,
rawAccess: false,
description: "E-commerce only — excludes PMO, HR, finance, admin",
},
// ...
}
この設計により、「ECサイト運用のエージェント」には広告・クリエイティブ関連のコマンドだけを渡し、PMO/HR/financeは隠すことができる。エージェントは自分の担当領域のコマンドだけを見るため、選択ミスが激減する。
レイヤー2: マニフェスト予算とスキル予算
プロファイルには「エージェントに渡せる最大コマンド数(`agentWorkflowBudget`)」と「最大マニフェストサイズ(`maxManifestBytes`)」の2つの予算を設定する。これは2026年時点のAIエージェント設計で最重要の概念の一つである。
なぜ予算が必要か
- コンテキストウィンドウ節約: コマンド情報をLLMに渡すコストを制限
- 選択精度の維持: ツールが20を超えると選択精度が急激に下がる(業界調査)
- 予期せぬ肥大化の防止: 新しいコマンドを追加したときに気付かず予算超過するのを防ぐ
予算チェックの実装
export function checkProfileBudget(profileName) {
const profile = getProfile(profileName)
const agentCommands = getAgentVisibleCommands(profileName)
const violations = []
const manifestJson = JSON.stringify(
agentCommands.map((cmd) => ({
id: cmd.id,
description: cmd.description,
domain: cmd.domain,
command: cmd.command,
})),
)
const manifestBytes = new TextEncoder().encode(manifestJson).length
if (profile.agentWorkflowBudget !== null &&
agentCommands.length > profile.agentWorkflowBudget) {
violations.push(
`Skill count ${agentCommands.length} exceeds budget ${profile.agentWorkflowBudget}`,
)
}
if (profile.maxManifestBytes !== null &&
manifestBytes > profile.maxManifestBytes) {
violations.push(
`Manifest size ${manifestBytes} bytes exceeds budget ${profile.maxManifestBytes}`,
)
}
return { profile: profileName, passed: violations.length === 0, violations }
}
このチェックをCIに組み込むことで、コマンド追加時に自動的に予算超過を検出できる。「うっかり20コマンドを超えた」事故を防げる。
レイヤー3: raw access による人間専用コマンドの分離
renue CLIには`renue raw
rawAccess設計の原則
- rawAccess: false — エージェントに見せる標準コマンドだけ
- rawAccess: true — raw access含む全コマンド(admin/fullプロファイルのみ)
- admin プロファイル: エージェントには絶対に露出しない
- full プロファイル: 人間専用の脱出ハッチ。エージェントに出力されない
この分離のメリット
- 「キルスイッチ」「データ削除」「インフラ操作」などの破壊的コマンドをエージェントから隠せる
- 人間は必要に応じてfullプロファイルでCLIを起動して全コマンドにアクセスできる
- 監査ログで「誰がrawアクセスを使ったか」が明確になる
レイヤー4: 自動マニフェスト生成 — ソースコードが真実
エージェントが存在しないコマンドを叩く事故は、CLIソースとマニフェスト(エージェントに渡すコマンド一覧)の同期ずれで発生する。renue CLIでは以下の仕組みで同期を担保している。
descriptors.tsによる一元管理
全コマンドは`packages/commands/src/catalog/descriptors.ts`にdescriptorとして登録される。ここに登録されていないコマンドはどのプロファイルにも含まれない。
getAgentVisibleCommands()による動的フィルタ
プロファイル名からエージェント向けコマンドリストを動的に生成する。これにより、profiles.tsとdescriptors.tsを正とし、マニフェストは常に最新状態を反映する。
CIでの整合性チェック
- 全プロファイルの予算チェックをCIに組み込む
- descriptorの漏れをテストで検出
- `renue agent agent-manifest --profile=xxx` で人間が手動確認できる
レイヤー5: コマンドオーバーライド機構
標準のdescriptorを上書きするための`overrides.ts`を用意する。特定プロファイルだけで動作を変えたい、エージェントから見えるdescriptionを短縮したい、といったケースに対応する。
オーバーライドの典型例
- エージェント向けにはdescriptionを短く(マニフェストバイト数節約)
- 人間向けには詳細なdescription
- プロファイル別に利用可能オプションを制限
オーバーライドも一箇所にまとめることで、「どこで何が変わっているか」が常に追跡可能な状態を保てる。
コマンドの命名規則
renue CLIでは`renue
命名の例
- `renue employees employees-list` (従業員一覧)
- `renue projects projects-get` (プロジェクト取得)
- `renue slack slack-send-message` (Slack送信)
- `renue strapi articles-update` (記事更新)
- `renue ads-google google-ads-keywords-add` (Google Adsキーワード追加)
命名規則の重要性
一貫性があるとエージェントが「発見可能」になる。`renue employees employees-list`を知っていれば、「projectsにも projects-list があるだろう」と推測できる。逆に `renue employees list` のような短縮形を混在させると、エージェントが発明した存在しないコマンドを叩く事故が頻発する。renue CLIではこのアンチパターンを明確に禁止している。
50+ドメインの整理パターン
renue CLIは2026年時点で50以上のドメインを持つ。これだけの規模になると、ドメイン名も体系的に整理する必要がある。
ドメイン命名のカテゴリ
- リソース系: employees, projects, tasks, issues, contracts
- 広告系: ads, ads-google, ads-meta, ads-tiktok, ads-x, ads-line
- マーケティング系: brand, competitive-research, creatives, landing-pages
- 財務系: contributions, personnel, revenues, freee
- HR系: hiring, recruitment, scout-records, scout-assets
- 連携系: slack, calendar, github, analytics, strapi
- エージェント系: agent, claude-monitor, ai-terminal, daily-reports
- インフラ系(raw): raw infra, raw ops, raw data
接頭辞による分類(`ads-*`, `project-*`等)で関連ドメインをグループ化する。
エージェントからの検索性を高める設計
ツール数が20を超えると、エージェントが「正しいコマンドを見つけられない」問題が顕在化する。これに対する設計パターンを紹介する。
descriptionの書き方
- 動詞から始める(取得する / 作成する / 更新する)
- 対象を明確化(どのリソースか)
- キーワードを含める(エージェントの検索マッチ精度向上)
- 副作用を明記する(読み取り専用 / 書き込み / 破壊的)
良い例と悪い例
- ❌
"プロジェクト関連"— 曖昧すぎる - ❌
"Get projects"— 英語・具体性不足 - ✅
"プロジェクト一覧を取得する(読み取り専用)" - ✅
"プロジェクトの状態を更新する(書き込み)"
renue CLIの実装特徴 — Monorepo構成
renue CLIは以下のMonorepo構成を取っている。
- packages/commands/: コマンド定義
- packages/cli/: CLI本体(Commander.js等)
- packages/client/: バックエンドAPIクライアント(自動生成)
- packages/commands/src/domains/: ドメイン別コマンド実装(50+ファイル)
- packages/commands/src/catalog/: プロファイル・予算・マニフェスト管理
配布フロー
- ソース修正 + descriptors.tsにdescriptor追加
- PR作成 → mainにマージ
- release.ymlが自動実行 → GitHub Package Registryに公開
- `npm install -g @renueinc/new-cli` で更新
- `renue skills add` でSkills同期
npm link禁止という運用ルール
renue CLIは「npm linkやローカルビルド直リンクは禁止」という明確なルールを設けている。
禁止の理由
ソースコードに`.command()`で定義されているがdescriptorsに未登録のコマンドが多数ある。ローカルビルド直リンクだと「ソースにあるのに動かない」状態が発生し、AIエージェントがソースを読んで存在しないコマンドを叩き続ける事故が多発した。正式リリース版を使えば`--help`に出るコマンド = 使えるコマンドが一致する。
この運用の教訓
AIエージェントは「ソースコードに存在する」と「実際に動く」を区別できない。descriptorベースの公式リリースのみを真実とする運用が必須である。
skills add による同期
renue CLIには `renue skills add` コマンドがあり、最新のCLIマニフェストを取得してClaude Code/Codex/Cursor等のAIエージェントが使うskills定義を同期する。これにより、CLIを更新すればエージェントも即座に最新状態になる。
renueの実装特徴まとめ
renueは「Self-DX First」の方針のもと、renue CLIを自社プロダクトとして開発・運用している。社内12業務を553のAIツールで自動化済み(2026年1月時点)であり、renue CLIはその中核基盤である(全て公開情報)。
公開されている技術スタック
- 言語: TypeScript
- パッケージ管理: Yarn + Monorepo(workspaces)
- CLIフレームワーク: 独自(Commander.jsベース)
- 配布: GitHub Package Registry (`@renueinc/new-cli`)
- テスト: Vitest
- CI/CD: GitHub Actions
導入時のよくある失敗パターン
- 全コマンドを1プロファイルで提供: コンテキスト肥大化でエージェントが選択失敗
- 予算チェックをCIに入れない: 気付かないうちに20コマンドを超える
- 人間専用コマンドを隠さない: エージェントが誤って破壊的操作を実行
- descriptorを経由しない登録: ソースにあるのに動かないコマンドが発生
- 命名規則が不統一: エージェントが存在しないコマンドを発明する
- descriptionが英語だけ: 日本語プロンプトからマッチしない
- npm linkを許容: ローカルと本番で動作が異なる
他の選択肢との比較
| 選択肢 | プロファイル管理 | 予算チェック | raw access分離 |
|---|---|---|---|
| Anthropic Skills | SKILL.md単位 | 手動 | 無し |
| MCP Server | サーバー単位 | 無し | サーバー分離で実現 |
| OpenAI Function Calling | 関数配列 | 無し | APIで制御 |
| renue CLI方式 | プロファイル×パック | バイト数/件数両方 | rawAccessフラグ |
renue CLI方式の強みは「1つのCLIバイナリで複数プロファイルを運用できる」点と「予算チェックがCIレベルで強制される」点にある。
よくある質問
プロファイルを何個作るべき?
6〜8個が目安。少なすぎるとコンテキスト肥大化、多すぎると運用が複雑化する。業務領域(PMO/EC/HR/Finance)と権限レベル(core/admin/full)の掛け合わせで6個程度になるのが自然。
予算の数値はどう決める?
エージェントワークフロー予算は最低12〜最大40が目安。マニフェストバイト数は12KB〜24KBが標準。これらはLLMのコンテキストウィンドウとの兼ね合いで決める。大きすぎると他の情報を入れる余地がなくなる。
既存のMCP ServerとCLIのどちらを選ぶべき?
補完関係にある。MCP ServerはAI統合の標準プロトコル、CLIは汎用的な自動化ツール。両方を提供し、エージェントにはMCPで、人間と自動化スクリプトにはCLIで提供するのが現実的。
コマンド数が50を超えるとどうなる?
プロファイル分割が必須になる。50を1プロファイルに入れると、LLMが選択を誤る頻度が急激に上がる。renue CLIも50+ドメインをプロファイルで切り分けて運用している。
AIエージェントがコマンドを発明する問題はどう防ぐ?
System Promptで「descriptorに存在するコマンドのみ使う」ことを明示する + `renue
