先に結論
AIエージェントが、同じ処理を繰り返し、時間やトークンだけを消費する。
こうした「進展のない反復」が Doom Loop です。OpenRouterの公式資料でも、同じツール呼び出しや文章を繰り返し、前に進まない状態として説明されています。
エージェントを作るときは、成功する手順と合わせて、行き詰まったときに止まる条件も設計したいです。
1. 「もう一度」が問題を解決しないことがある
例えば、存在しないファイルを読み込もうとしてエラーになった場合。
ファイル名を確認すればよいのに、同じパスで読み込みを繰り返してしまう。
コード修正でも、こんな状態が考えられます。
- 修正する
- テストが失敗する
- 修正を戻す
- また同じ修正をする
処理は動いています。でも、問題は解決に近づいていません。
2. 再試行とDoom Loopを分けて考える
一時的な通信エラーなら、少し待って再試行する意味があります。
一方、権限不足や入力の間違いは、同じ条件で繰り返しても改善しにくいです。
再試行する前に、**「次は成功する可能性がある理由」**を確認したいです。
待てば状況が変わるのか。入力を直したのか。別の手段に切り替えたのか。
条件が変わらないまま回数だけ増えていたら、行き詰まりを疑います。
3. 指紋化と循環検出は、見つけるための道具
前回紹介した Tool-Call Fingerprinting は、ツール名と引数から同じ呼び出しを識別する方法です。
Repetition Cycle Detection は、履歴から同じ呼び出し列の繰り返しを探します。
Doom Loop は、それらで検出したい「進展のない状態」です。
ただ、引数が少しずつ変わるループもあります。呼び出しの一致だけでなく、新しい情報が得られたか、未解決の問題が減ったかも見る必要があります。
4. 止める仕組みは、実行側にも置く
「同じことを繰り返さないで」と指示するだけでは、停止を保証できません。
実装では、次のような条件を組み合わせます。
| 条件 | 目的 |
|---|---|
| 同じ処理が続いたら警告 | 方針変更を促す |
| 進展がなければ中断 | 無駄な反復を抑える |
| 回数・時間・コストに上限 | 検出漏れでも実行を止める |
LangGraphにも、停止条件に到達しないままステップ数の上限に達するとエラーになる仕組みがあります。ただし、正常な長い処理でも上限に達することはあります。
5. ブロックした後にも、出口が必要
同じツール呼び出しを拒否しても、エージェントがその拒否を受けて再試行し続ける可能性があります。
OpenRouterの資料でも、ブロックだけでは再試行が続き得るため、停止条件を併せて設ける必要性が説明されています。
停止時には、試したこと、失敗理由、再開に必要な情報を残す。
そこまで設計すると、人が状況を確認して、次の一手を選びやすくなります。
