サイトを公開しました。AIプロダクト開発の実践知を、わかりやすく発信していきます。
記事一覧へ
AIエージェント開発10 min read

AIエージェント開発で暴走・無限ループを防ぐ設計

AIエージェントが同じツール実行を繰り返したり、終了条件を見失ったりする原因を、ステップ制限、権限管理、ログ、承認フローの観点から整理します。

AIエージェント開発で暴走・無限ループを防ぐ設計のサムネイル

結論

AIエージェントの暴走や無限ループは、モデルの性能だけで防ぐものではありません。

実装側で「何回まで動いてよいか」「どのツールを使ってよいか」「何をもって完了とするか」「危険な操作を誰が承認するか」を決めておく必要があります。

最初に入れるべき対策は次の5つです。

対策 目的
最大ステップ数 終了できないループを強制的に止める
同一操作の検知 同じツール呼び出しの繰り返しを止める
ツール権限の分離 読み取り、作成、削除などの危険度を分ける
人間の承認 破壊的操作や外部送信を自動実行させない
実行ログ 何が起きたかを後から調査できるようにする

AIエージェントのループを制限し、人間の承認ゲートで安全に止める設計図

この記事の対象読者

この記事は、次のような人向けです。

  • AIエージェントにツール実行をさせたい開発者
  • 自動実行の安全設計に不安がある人
  • 同じ処理を繰り返すエージェントの止め方を知りたい人
  • 社内ツール、GitHub操作、ファイル操作などをエージェントに任せる前に設計を整理したい人

なぜAIエージェントは暴走しやすいのか

AIエージェントは、目的を受け取り、必要なツールを選び、実行結果を見て次の行動を決めます。

この流れ自体は便利ですが、終了条件が曖昧だと、モデルは「まだ何かできる」と判断して作業を続けることがあります。

よくある原因は次の通りです。

原因 起きること
終了条件が曖昧 いつ完了してよいか判断できない
ツール結果が曖昧 成功したのか失敗したのか分からず再実行する
ステップ制限がない 失敗しても延々と別案を試す
同一操作の検知がない 同じ検索、同じAPI呼び出しを繰り返す
権限が広すぎる 不要な書き込みや削除まで実行できてしまう

重要なのは、AIエージェントに「賢く止まってほしい」と期待するだけでは不十分だという点です。

止まる条件は、アプリ側で設計します。

基本構成

AIエージェントの実行ループは、最低限次のように分けて考えます。

要素 役割
目的 エージェントが達成すべきゴール
状態 これまでの入力、ツール実行、結果
ツール 検索、DB参照、ファイル操作、外部APIなど
判断 次に何をするか、終了するか
制限 最大回数、権限、承認条件
ログ 実行履歴、失敗理由、停止理由

このうち、暴走対策で特に重要なのは「制限」と「ログ」です。

最大ステップ数を決める

最初に入れるべき対策は、最大ステップ数です。

たとえば、1回の依頼でツール実行は最大10回まで、外部API呼び出しは最大3回まで、というように上限を決めます。

const maxSteps = 10;

for (let step = 0; step < maxSteps; step += 1) {
  const action = await decideNextAction(state);

  if (action.type === "finish") {
    return action.result;
  }

  const result = await runTool(action);
  state.history.push({ action, result });
}

return {
  status: "stopped",
  reason: "max_steps_reached",
};

最大ステップ数に到達したら、無理に続けず、途中結果と停止理由を人間に返します。

同じ操作の繰り返しを検知する

最大ステップ数だけでは、無駄な操作を減らせません。

たとえば、同じキーワードで検索を繰り返す、同じAPIを同じ引数で呼ぶ、といった動きは早めに止めるべきです。

検知するもの
同じツール名 searchDocs を何度も呼ぶ
同じ引数 同じクエリで検索する
同じ失敗 404や権限エラーを繰り返す
変化のない結果 前回と同じ結果しか返っていない

実装では、ツール名と引数をキーにして履歴を持つと扱いやすくなります。

function actionKey(action: ToolAction) {
  return `${action.tool}:${JSON.stringify(action.args)}`;
}

const repeatedCount = history.filter(
  (item) => actionKey(item.action) === actionKey(nextAction),
).length;

if (repeatedCount >= 2) {
  return {
    status: "stopped",
    reason: "repeated_action_detected",
  };
}

ツール権限を分ける

すべてのツールを同じ扱いにすると危険です。

読み取り専用ツールと、書き込み・削除・外部送信を行うツールは分けて設計します。

ツール種別 推奨制御
読み取り 検索、ファイル参照、DB参照 自動実行可。ただし回数制限を入れる
作成 Issue作成、下書き作成 内容をログに残す。必要に応じて承認
更新 ファイル編集、DB更新 原則、人間の承認を挟む
削除 ファイル削除、データ削除 自動実行させない
外部送信 メール、Webhook、SNS投稿 宛先と内容を人間が確認する

最初は読み取り中心にし、書き込み系は承認制にするのが安全です。

人間の承認を挟むポイント

AIエージェントにすべてを自動実行させる必要はありません。

特に次の操作は、承認を挟む設計にします。

  • ファイルを作成・編集・削除する
  • GitHub IssueやPRを作成する
  • 外部APIへ大量にリクエストを送る
  • ユーザーに通知を送る
  • 本番環境の設定を変更する
  • 課金や公開に関係する操作をする

承認画面やログには、少なくとも次の情報を出します。

表示する情報 理由
実行したい操作 人間が判断しやすくする
対象ファイルや対象URL 影響範囲を明確にする
変更前後の要約 実行結果を予測しやすくする
失敗時の戻し方 安全に試せるようにする

ログに残す項目

暴走対策では、ログがないと原因を調べられません。

最低限、次の項目を残します。

ログ項目 目的
requestId 1回の依頼を追跡する
step 何回目の判断かを見る
selectedTool どのツールを選んだかを見る
toolArgsSummary 引数の概要を確認する
resultStatus 成功、失敗、空結果を分ける
stopReason なぜ止まったかを見る
durationMs 遅い処理を見つける

APIキー、個人情報、長い入力全文をそのままログに出してはいけません。

実装前チェックリスト

AIエージェントを動かす前に、次を確認します。

  • 最大ステップ数を決めている
  • ツールごとの実行回数制限を決めている
  • 同一操作の繰り返しを検知できる
  • 書き込み、削除、外部送信には承認を挟む
  • 停止理由をユーザーに返せる
  • 実行ログに秘密情報を出していない
  • 失敗時に途中結果を確認できる

関連記事

まとめ

AIエージェントの暴走対策は、モデルの出力を信じることではなく、実行環境を制御することです。

最大ステップ数、同一操作検知、権限分離、承認フロー、ログを最初から設計に入れることで、自動化の便利さを保ちながら危険な動きを抑えられます。