前の記事では、AIへ複数のToolを渡すとき、プロンプトで「このToolは使わないで」と指示するだけでは、実行可能な操作そのものは消えないことを扱いました。

今回は、それを本番サーバーの運用に当てはめます。

AI Agentにサーバーの障害調査や復旧を任せようとすると、Shellを使わせる構成はかなり自然です。

AI Agent

Shell

journalctl / docker / systemctl / curl / ps ...

production server

Shellがあれば、Agentは状況を見ながらコマンドを組み合わせられます。事前に用意していなかった調査方法にも進めるため、障害対応との相性はよく見えます。

ただ、本番環境でShellが使えるということは、調査用コマンドだけが使えるという意味ではありません。

Agentが動いているユーザーの権限次第では、ファイルの変更、プロセスの停止、ネットワーク通信、認証情報の読み取りなども同じ環境から可能になります。

そこで考えたいのが、本番サーバーをAIに操作させたいとしても、Shellまで必要なのかという点です。

Shellを渡すと「未知の操作」を組み立てられる

Shellの大きな利点は、事前に操作手順を決め切らなくてよいことです。

たとえばWebサービスの応答が遅くなったとします。

人間が調査するときも、最初から原因が分かっているとは限りません。

CPU使用率を見る

メモリを確認する

プロセスを見る

コンテナの状態を見る

ログを読む

接続中のportを確認する

設定ファイルを確認する

途中で見つかった情報によって次の操作が変わります。

Shellを使えるAgentなら、たとえば次のような既存コマンドを組み合わせて調査できます。

ps aux
free -h
ss -lntp
docker ps
docker inspect example-app
docker logs example-app
journalctl -u nginx -n 200

「ログを取得するTool」「プロセスを確認するTool」「portを確認するTool」を一つずつ事前実装しなくても、OSにすでに存在する仕組みを利用できます。

未知の障害を探索するとき、この自由度には明確な価値があります。

操作が決まっているならShellである必要はない

一方、Agentへ任せたい処理が最初から分かっているケースもあります。

たとえばSaaSの運用で、

コンテナの状態を確認する
CPU使用率を取得する
メモリ使用率を取得する
直近のログを読む
必要ならコンテナを再起動する

だけを実行したいとします。

これなら、Shellの代わりに次のようなToolを用意できます。

get_cpu_usage()
get_memory_usage()
get_container_status()
read_service_logs(service, lines)
restart_container(id)

構成も変わります。

AI Agent

Agent Tool Gateway
   ├─ get_cpu_usage()
   ├─ get_memory_usage()
   ├─ get_container_status()
   ├─ read_service_logs()
   └─ restart_container()

internal API / infrastructure

Agentはdockersystemctlを直接実行しません。

restart_container()を受け取ったアプリケーションが対象を確認し、許可されたコンテナだけを再起動します。

この構成では、そもそもAgentにrmiptables、任意のcurlなどを実行する経路がありません。

Shellと限定Toolでは得意な仕事が違う

2つの設計を単純化すると、次の違いがあります。

観点Shell限定したFunction / API
未知の障害調査強い事前定義した範囲に限定される
既存CLIの利用そのまま使えるWrapperやAPIが必要
新しい操作への対応Tool追加なしでも対応しやすいToolの追加実装が必要
操作可能範囲広くなりやすいFunction単位で決めやすい
引数の制約コマンド文字列では難しいSchemaで定義しやすい
認可OS権限などと組み合わせるApplication Logicへ組み込みやすい
監査コマンド単位の記録が必要操作の意味を記録しやすい
実装コスト既存環境を利用しやすいToolの実装と保守が必要

Shellが優れている、Functionが優れているという比較ではありません。

Agentにその場で調査方法を考えさせたいのか、決められた運用操作を実行させたいのかで向いている構成が変わります。

Function Callingにすれば安全になるわけでもない

ShellをやめてFunction Callingにすれば安全、と考えるのも危険です。

たとえばAgentへ次のToolだけを渡したとします。

restart_container(id)

任意のShellコマンドは実行できなくなりました。

それでもAgentが対象を間違えれば、正常に動いている本番コンテナを再起動する可能性があります。

DNSを変更できるToolなら、さらに影響は大きくなります。

update_dns_record(host, value)

このFunctionにはShellがありません。それでも使い方を誤ればサービス全体へ影響します。

そのため、Function側ではAIから渡された引数をそのまま信用せず、通常のアプリケーションと同じように実行条件を確認します。

restart_container("prod-api-01")

入力形式を確認

対象リソースを確認

実行者の権限を確認

environmentを確認

必要ならHuman Approval

実行

監査ログへ記録

Function Callingで狭くできるのは、主にAgentが選択できる操作の種類です。

その操作を実行してよいかどうかは、別に確認する必要があります。

readとwriteを最初から分けておく

本番運用では、すべてのToolを同じ扱いにする必要もありません。

たとえば次のように分けられます。

read
- get_metrics
- get_container_status
- read_logs
- get_deploy_history

write
- restart_container
- rollback_deployment
- update_config

監視や原因調査に必要なのは、read系のToolが中心です。

Alert

AI Agent

metricsを確認

logsを確認

deploy historyを確認

原因候補と対応案を出す

ここまでなら、本番環境へ変更を加えるToolは必要ありません。

修復まで自動化する場合だけwrite系を追加できます。

原因調査

restart_containerを提案

Human Approval

restart_containerを実行

復旧確認

環境ごとにPolicyを変えることもできます。

staging
→ restart_containerを自動実行可能

production
→ restart_containerはHuman Approvalが必要

Agentを導入したからといって、調査から修復まで全部を自律実行させる必要はありません。

本番障害の調査だけAIに任せる構成もある

本番サーバーへAIを導入すると聞くと、自動復旧まで想像しやすいですが、実際には調査だけでもかなり使えます。

監視システム

障害を検知

AI Agent
   ├─ metrics
   ├─ logs
   └─ deploy history

原因候補

修復案

Human

たとえば、

5分前のdeploy直後からHTTP 500が増加。
appコンテナのmemory使用量に大きな変化はない。
nginxではupstream connection refusedが増えている。

候補:
appコンテナが正常にlistenしていない可能性があります。

確認候補:
- appコンテナのhealth check
- application log
- 直前deployとの差分

というところまでAIが調べ、人間が最終的な操作を行う構成です。

この用途なら、Agentへwrite権限を与えない選択ができます。

本番運用でAIを使うことと、AIへ本番環境の変更権限を渡すことは同じではありません。

Shellを使うなら「本番サーバーのroot Shell」にする必要はない

未知の障害を調査するためShellを使いたい場合でも、無制限に実行できるShellへ直結する必要はありません。

たとえば次のような制約を組み合わせられます。

  • filesystemをread-onlyにする
  • 書き込み可能なdirectoryを限定する
  • sudoを使わせない
  • Agent専用ユーザーで実行する
  • containerやsandbox内に隔離する
  • network accessを必要な宛先だけに限定する
  • SecretをAgentの実行環境から分離する
  • 特定の操作をapproval対象にする
  • 実行コマンドと結果を記録する

2026年8月28日時点のOpenAIのShell Toolでも、任意のShellコマンドを扱えるため、実行環境をsandbox化し、コマンドのallowlist / denylistやTool実行ログを組み合わせることが案内されています。

OpenAI管理のcontainerではnetwork_policyを設定でき、allowlistを使って接続先domainを限定できます。

Codexも、sandboxとapprovalを別の仕組みとして扱っています。

sandboxは「Agentが自動で操作できる技術的な範囲」を決め、approvalは「その範囲を越えるとき、人間へ確認するか」を決めます。

この設計はCodexだけに限った話ではありません。

Shellを使うAgent Harnessを自作するときも、

Agent

Sandbox

限定されたShell

Production resources

のように、Agentと本番環境の間へ境界を置けます。

network accessはShellとは別に考える

Shellが使えるからといって、外部networkまで必要とは限りません。

障害調査で必要なのが、

journalctl
docker logs
ps
free
ss

程度なら、外部への接続を許可しなくても調査できる場合があります。

逆に、

curl https://example.com

や外部APIへのアクセスを許可すると、取得できる情報だけでなく、外部へ送信できる情報も増えます。

特にAgentが次の3つを同時に持っている場合は注意が必要です。

外部から情報を読む
+
Secretを読める
+
外部へ通信できる

Webページだけでなく、ログやIssue、ユーザー入力などにも第三者が書き込んだ文字列が含まれることがあります。

そこへAIを誘導する命令が埋め込まれていた場合、Prompt Injectionの入力経路になり得ます。

OpenAIもAgentのPrompt Injection対策について、悪意ある入力を完全に検出することだけに依存せず、仮にAgentが誘導された場合でも被害を制限できるよう、利用可能なCapabilityを制約する考え方を説明しています。

Shellを禁止すればPrompt Injectionが解決するわけではありません。

Functionしか持たないAgentでも、許可されているFunctionを誤用する可能性は残ります。

ただし、

read_logs()
get_metrics()

しか使えないAgentと、

shell
filesystem
secret access
outbound network

を持つAgentでは、誘導されたときに実行できる操作の範囲が違います。

専用のAI用APIを一から作らなくてもよい

Function方式には、Toolを一つずつ実装するコストがあります。

Shellなら、

journalctl -u nginx -n 200

で済む処理でも、Functionとして公開するなら、

read_service_logs({
  service: "nginx",
  lines: 200
})

のような仕組みが必要です。

対象となる操作が数十、数百と増えれば、Toolそのものの設計と保守も無視できません。

ただし、既存の管理APIがあるなら再利用できます。

GET  /containers/:id/status
POST /containers/:id/restart
GET  /deployments
POST /deployments/:id/rollback

すでに人間向けの管理画面がこれらのAPIを利用しているなら、その一部をAgentから呼び出せるToolへ変換できます。

そのまま公開すると権限が広すぎる場合は、Agent用のGatewayを間に置く方法もあります。

AI Agent

Agent Tool Gateway

Authorization / Validation / Approval

Existing Internal APIs

Gateway側で、

このAgentはstatusを読める
restartはproductionでは承認が必要
rollbackは直近deployだけ許可
config変更は利用不可

といったルールを持たせます。

AI専用の運用基盤をすべて作り直すのではなく、既存の認証・認可・管理APIを利用できます。

ケースA:自宅サーバーの障害調査

個人で管理している自宅サーバーを考えます。

要件は次のようなものです。

Docker中心
管理者は自分だけ
未知の障害も調査したい
多少のリスクは許容できる

この環境で、

get_cpu_usage()
read_nginx_logs()
read_app_logs()
get_disk_usage()
get_port_status()
...

と一つずつToolを作るのは、運用コストの方が大きくなるかもしれません。

Agent専用ユーザーやcontainer、network制限などを組み合わせたShellを使い、必要な範囲で自由に調査させる方が実用的なケースです。

特に「何が壊れるか事前に分からない」環境では、Shellの探索能力を活かせます。

ケースB:SaaSの本番コンテナを再起動する

次は顧客が利用しているSaaSです。

Agentへ任せたい処理は、

container statusの確認
health checkの確認
restart

だけだとします。

この場合、Shellを公開する理由はあまりありません。

get_container_status(id)
get_container_health(id)
restart_container(id)

程度に絞れば目的を達成できます。

さらに、

get_container_status
get_container_health
→ 自動実行可能

restart_container
→ productionではHuman Approval

と分けられます。

操作内容が事前に分かっており、顧客影響も大きい環境では、限定したToolの方が設計しやすくなります。

ケースC:原因調査はAI、修復は人間

本番障害の原因調査にAIを使いたいものの、変更操作はまだ任せたくないケースです。

Agentには次の情報だけを渡します。

metrics
logs
deployment history
service status

Agentは原因候補を調べますが、再起動やrollbackは実行できません。

AI

調査

原因候補

修復案

Human

既存の運用手順で修復

この構成なら、AIによる調査能力を利用しながら、本番環境へのwrite Capabilityを増やさずに済みます。

運用をAI Agent化するときの最初の段階としても採用しやすい形です。

どこまで渡すかは「必要な探索範囲」から決める

本番サーバーへAgentを接続するとき、判断材料を並べると次のようになります。

状況構成候補
操作内容が数種類に決まっているFunction / Internal API
定型的な復旧処理を実行したいFunction + Authorization
本番への変更を伴うApproval + Audit
原因調査だけ任せたいread-only Tool
未知の障害を探索したい制限されたShell
多数の既存CLIを組み合わせたいShell / Agent Harness
外部networkが不要outbound networkを許可しない
一部の外部APIだけ必要allowlistで限定
Secretが不要Agent環境へ渡さない

NISTのleast privilegeも、ユーザーやプロセスへ、その処理に必要な最小限の権限やリソースだけを与える原則として定義しています。

Agentだから特別な考え方が必要というより、既存のセキュリティ設計をAgentにも適用できます。

Shellを渡すかどうかを最初に決めなくてよい

AI Agentの構成を考えると、

Shellを渡すか
Function Callingにするか

という二択から入りたくなります。

実際には、その前にAgentの仕事を分解した方が設計しやすくなります。

何を読む必要があるか

何を変更する必要があるか

未知の操作を組み立てる必要があるか

どの操作に人間の承認が必要か

どこまでnetwork accessが必要か

どのSecretへアクセスする必要があるか

ここまで決めると、Shellが必要な部分と、Functionで十分な部分が見えてきます。

未知の障害を探索させるなら、Shellを使う理由があります。

コンテナの状態確認と再起動だけなら、専用Toolで十分かもしれません。

原因調査だけなら、write Toolすら必要ない場合があります。

AI Agentへ与える権限は、「できると便利なこと」を全部並べて決めるものではありません。

そのAgentが仕事を完了するために、実際に必要な操作から決める。

本番サーバーへAIを接続するときも、この順番で考えると過剰なCapabilityを持たせにくくなります。