LLM-in-the-loopとは、最適化や改善のループの内側に大規模言語モデル(LLM)を「案を出す役」「良し悪しを付ける役」として組み込み、人手で回していた試行錯誤を自動で回し続ける設計を指します。ただ「LLM ループ」という言葉は、エージェントの実行ループや、LLMが同じ文を延々と繰り返す「無限ループ」を指すこともあります。この記事では3つのループを切り分けたうえで、OPROやAlphaEvolveの測定値、動く最小実装、そして無限ループを生成側とエージェント側に分けた止め方を、公式の推奨値と論文の測定値で示します。
まとめ
「LLMのループ」は、エージェントループ(思考→行動→観察を繰り返す実行の輪)、LLM-in-the-loop(最適化ループの提案者・評価者としてLLMを置く輪)、Human-in-the-Loop(人が承認・修正で介入する輪)の3つに分かれます。LLM-in-the-loopはプロンプトやコードなどの候補を、正答率や実行結果などで評価しながら改善する構成に使え、Google DeepMindのOPROは人手設計のプロンプトをGSM8Kで最大8%上回りました。
「LLMの無限ループ」は原因の違う2種類があり、止め方も違います。
- 生成の反復(同じ文や「Wait」を繰り返す)は、greedy decoding(毎回いちばん確率の高いトークンを選ぶ方式)や低温度、小型・蒸留モデルで起きやすい。モデル提供元の推奨サンプリング設定とpresence_penaltyで抑え、生成トークン数に上限を置きます。Ollamaとllama.cppの基盤設定では生成数の既定値が-1ですが、終了トークンなどでも停止します。反復が長引く場合に備え、生成数の上限を明示します。
- エージェントの反復(同じツール呼び出しや再試行を繰り返す)では、モデルの出力と制御フローの相互作用が問題になります。サンプリング設定の変更だけでは停止を保証できません。反復上限・無改善打ち切り・コスト上限をループの外側に置きます。
LLMのループが指す3つの意味
「LLM loop」で検索すると、次の3系統の話題が混ざって出てきます。設計の議論を始める前に、どのループの話かを揃えてください(社内向けLLMの開発・運用サイクルを、ベンダーが「LLM Loop」という独自のサービス名で呼ぶ例もありますが、以下の技術用語とは別物です)。
| 類型 | ループを回す主体 | LLMの役割 | 代表例 |
|---|---|---|---|
| エージェントループ | エージェントの実行基盤 | 次の行動を決める | ReAct |
| LLM-in-the-loop | 最適化アルゴリズム | 案の生成・採点 | OPRO、AlphaEvolve、GEPA |
| Human-in-the-Loop | 業務フロー | 人の承認を待つ側 | ツール実行前の承認 |
エージェントループ:思考・行動・観察を繰り返す実行の輪
AIエージェントの実行モデルです。LLMが次の行動を決め(Thought)、ツールを呼び(Action)、結果を読む(Observation)を、タスクが終わるまで繰り返します。各周回でLLMは「呼び出される側」で、設計の焦点はツール定義と停止条件に置かれます。思考と行動を交互に回す型はReActパターンの仕組みと採用判断に、ループの終わらせ方とSDKごとの反復上限はエージェントループの止まる条件とSDK別の反復上限にまとめています。
LLM-in-the-loop:最適化ループの評価者・生成者としてのLLM
こちらは最適化アルゴリズムが主役で、LLMはその内側の部品です。従来は数値の目的関数と探索アルゴリズムで回していたループのうち、「案を出す」「点を付ける」工程をLLMが受け持ちます。評価も生成も自然言語で書けるため、「読みやすい文章」「誤読されにくい指示文」のように微分できず数式にも落ちない目的でもループが回せます。後述するOPROはこの型の代表例で、勾配を持たないプロンプト文字列を探索対象にしています。
Human-in-the-Loopとの役割分担
人が承認・修正で介入するヒューマンインザループ(HITL)は、LLM-in-the-loopの対抗馬ではなく、その外側に置くガードレールです。LLMは自動で何度でも反復できますが、結果の採否と責任の所在は人が決める必要があります。ループの内側は自動で回し、外側の採否は人が握る分担にします。医療・与信・人事のように誤判定の代償が大きい領域では、LLMの評価をそのまま採用せず、上位候補だけを人のレビューに回します。
LLM-in-the-loop最適化の構成要素|提案者と評価者の2役
ループ内でLLMに与える役割は、突き詰めると「提案者」と「評価者」の2つです。片方だけをLLMにし、もう片方を正解データや実行結果で置き換える構成も成り立ちます。
提案者としてのLLM:OPROが示した効き目
Google DeepMindのOPRO(Optimization by PROmpting)は、最適化問題を自然言語でLLMに説明し、これまでの解とスコアをプロンプトに並べて「もっと良い解を出せ」と求める手法です(arXiv 2309.03409、ICLR 2024採択)。勾配は使いません。論文はプロンプト最適化を主な対象とし、OPROが見つけた指示文が人手設計のプロンプトをGSM8Kで最大8%、Big-Bench Hardのタスクで最大50%上回ったと報告しています。過去の試行と点数を見せれば、LLMは次に試す方向を推測できるということです。
評価者としてのLLM:LLM-as-a-Judgeの精度とバイアス
点を付ける側にLLMを置くのがLLM-as-a-Judgeです。MT-BenchとChatbot Arenaの研究(arXiv 2306.05685)では、GPT-4の判定と人間の好みの一致率が80%を超え、人間同士の一致率と同じ水準でした。一方で同じ論文は、提示順で勝敗が動くposition biasと、長い回答を高く付けるverbosity biasを確認しています。自分自身が生成した回答を好むself-enhancement biasについては、データが少なく存在を確定できないと留保しています。まず回答順を入れ替えて2回評価し、判定が逆転したら保留または引き分けにします。長さによる偏りは冗長な回答との対照例で点検し、別系列の評価モデルを使う場合も、人手評価との一致を確認してください。
LLM-in-the-loopの最小実装と停止条件(Python)
OPRO型のループは30行ほどで骨格が書けます。「上位案とスコアを見せて新しい案を出させ、採点し、履歴に積む」を繰り返し、反復上限・無改善打ち切り・各周回後の予算閾値チェックで停止します。以下はそのまま実行できる形にしてあり、llm()とevaluate()だけをダミーにしています。トークン数も文字数から作ったダミー値で、予算は各周回の後に判定するため厳密な上限ではありません。実運用では評価側の消費も集計し、呼び出し前に残予算と最大消費量を確認します。実運用ではllm()をモデルAPIの呼び出しに、evaluate()を検証セットの正答率やLLM-as-a-Judgeの採点に差し替えます。
import random
MAX_STEPS = 30 # 反復上限
PATIENCE = 5 # 無改善打ち切り
BUDGET_TOKENS = 20000 # コスト上限(累積トークン)
def llm(prompt):
"""LLM呼び出しの差し替え口。ここではダミーとして既存案に語を1つ足す"""
words = ["ステップごとに", "検算して", "簡潔に", "単位を付けて", "根拠を示して"]
best = prompt.split("案: ")[1].split("\n")[0]
return best + random.choice(words), len(prompt) // 2 # (案, 消費トークン)
def evaluate(candidate):
"""検証セットの正答率の代わり。ここでは含まれる指示語の数で採点"""
return sum(w in candidate for w in ["検算", "単位", "根拠"]) / 3
random.seed(0)
seed = "答えてください"
history = [(seed, evaluate(seed))]
used, stale, reason = 0, 0, "max_steps"
for step in range(MAX_STEPS):
top = sorted(history, key=lambda x: -x[1])[:5]
prompt = "\n".join(f"案: {c}\nスコア: {s:.3f}" for c, s in top)
candidate, cost = llm(prompt)
used += cost
score = evaluate(candidate)
stale = 0 if score > top[0][1] else stale + 1
history.append((candidate, score))
if stale >= PATIENCE:
reason = "no_improvement"; break
if used >= BUDGET_TOKENS:
reason = "budget"; break
best = max(history, key=lambda x: x[1])
print(f"stop={reason} steps={step + 1} tokens={used} best={best[1]:.3f} {best[0]}")
Python 3で実行するとstop=no_improvement steps=10 tokens=644 best=0.667と出て、10周目で無改善打ち切りが働きます。止まった理由(reason)を必ず結果と一緒に記録してください。上限で止まったのか、改善が尽きて止まったのかで、次に上限を上げるべきかの判断が変わります。プロンプト最適化を自前で書かずに済ませたい場合は、この輪をフレームワークにしたDSPyのチュートリアルが、最適化器の差し替えで同じことをします。改善の方針を自然言語の反省文としてループに戻す設計は、Reflexionによる自己修正ループと同じ考え方です。
成果が測定されたLLM-in-the-loopの実例
「本当に効くのか」には、すでに数字が出ています。
AlphaEvolve:進化計算におけるLLMのコード改変と評価
Google DeepMindが2025年5月14日に公表したAlphaEvolveは、Gemini FlashとGemini Proにコードの改変案を書かせ、自動評価器が採点し、成績の良いものを次世代の親に選ぶ進化的ループで、Googleの計算基盤にも実際に適用されています。
| 適用先 | 公表された成果 |
|---|---|
| Borg(データセンターのスケジューラ) | 全社計算資源の0.7%を回収(1年以上稼働) |
| 4×4複素行列の積 | スカラー乗算48回(Strassen 1969を更新) |
| FlashAttentionカーネル | 最大32.5%高速化 |
| Gemini自身の学習 | 学習時間を1%短縮 |
| 未解決の数学問題50超 | 約75%で既知最良を再発見、20%で更新 |
見るべきは最下段です。既知最良を更新できたのは20%で、約75%は既知の水準の再発見でした。LLM-in-the-loopは探索を安く大量に回す道具で、未知の解を確実に生む仕組みではありません。導入の可否は「評価器を自動化できるか」「試行を安く積めるか」で見積もります。
GEPA:GRPOとの性能・ロールアウト数の比較
GEPA(arXiv 2507.19457、2025年7月投稿・2026年2月改訂)は、実行トレースを自然言語で振り返らせてプロンプトを進化させる手法です。論文は、強化学習のGRPOを平均6%・最大20%上回りながら、必要なロールアウト回数が最大35分の1だったと報告しています。プロンプト最適化器のMIPROv2に対しても10%超(AIME-2025で+12%)上回りました。勾配計算を伴う学習ループに比べ、言語による反省は試行回数あたりの改善量が大きく、ここがLLM-in-the-loopを選ぶ経済的な理由になります。
LLMの無限ループは「生成の反復」と「エージェントの反復」の2種類
「LLMが無限ループする」と言われる現象には、原因の違う2種類があります。ここを取り違えると、効かない対策に時間を使います。
| 項目 | 生成の反復 | エージェントの反復 |
|---|---|---|
| 見える症状 | 同じ文・語を出し続ける | 同じツール呼び出しを繰り返す |
| 起きる場所 | 1回の生成(デコーディング)の中 | 複数回のモデル呼び出しの間 |
| 主な原因 | greedy・低温度・小型モデル | 実効的な上限の欠如 |
| 効く対策 | 推奨サンプリング・presence_penalty・最大トークン | 反復上限・無改善打ち切り・コスト上限 |
| 単独では停止を保証しない対策 | 外側のループ回数だけの制限 | temperature・ペナルティの調整だけ |
生成の反復ループが起きる原因:greedyと小型・蒸留モデル
確率の高いトークンを選び続けるデコードは反復を生みます。この指摘は2019年のHoltzmanらの論文(The Curious Case of Neural Text Degeneration、ICLR 2020)が出しており、GPT-2 Large(762M)で最大200トークンの文章を5,000件生成した実験では、表1の反復率がgreedyで73.66%、ビーム幅16のbeam searchで28.94%でした。同論文が代わりに提案したのが、累積確率pまでの候補からサンプリングするNucleus Sampling(top_p)です。
推論モデルでも同じことが起きます。2026年のICML Spotlight論文Wait, Wait, Wait… Why Do Reasoning Models Loop?は、公開推論モデルが低温度でループしやすく、温度を上げるほどループが減ることを示しました。AIMEなどの数学問題を使った実験で、温度0の生成中に同じ30-gramが20回以上現れる割合は、OpenThinker3-1.5Bで30%、その教師モデルQwQ-32Bで4%です。大きいモデルほどループが少なく、蒸留した小型の生徒モデルは教師がほとんどループしない問題でもループします。著者は原因を学習の誤差に置き、温度を上げるのは誤差が大きいときの応急処置(stopgap)にすぎないと結論しています。
実務での意味は2つです。小型モデルや蒸留モデルをローカルで動かすときほど反復は起きやすく、温度0で再現性を取りにいく設定は推論モデルでは裏目に出ます。
生成の反復ループを止める設定:Qwen3の推奨値と生成上限
最初に見るのは、モデル提供元が出している推奨サンプリング設定です。Qwen3の公式モデルカードは、thinkingモードでTemperature=0.6・TopP=0.95・TopK=20・MinP=0を推奨し、「greedy decodingは性能低下と終わらない反復(endless repetitions)を招くので使わない」と明記しています。non-thinkingモードの推奨はTemperature=0.7・TopP=0.8です。反復が残る場合はpresence_penaltyを0〜2の範囲で上げられますが、高くすると言語の混在や性能の軽い低下が時々起きる、という注意も付いています。Qwenが配布する公式GGUFの設定ファイル(params)には、既定でpresence_penalty 1.5とnum_predict 32768が入っています。
次に、実行環境の基盤設定を確認します。下表はモデル固有の設定やリクエストで上書きする前の既定値です。Qwen公式GGUFのparamsのように、配布モデル側でペナルティや生成上限が指定されている場合は、実効値を確認してください。
| 設定 | Ollama v0.40.6 | llama.cpp(master) |
|---|---|---|
| 反復ペナルティ | repeat_penalty 1.0(無効) | –repeat-penalty 1.00(無効) |
| ペナルティの参照範囲 | repeat_last_n 64 | –repeat-last-n 64 |
| presence_penalty | 0.0 | –presence-penalty 0.00 |
| 生成トークン数の上限 | num_predict -1(無制限) | -n -1(無制限) |
| 既定のコンテキスト長 | VRAMに応じ4k/32k/256k | モデル既定 |
Ollamaの値はv0.40.6のソース(api/types.go)のDefaultOptions、llama.cppの値はllama-serverのREADMEで確認しました(OllamaのModelfileのドキュメントはnum_ctxの既定を2048と書いていますが、ソースとContext lengthのページはVRAM連動の値です)。生成上限がない場合の停止時点は、終了トークンや停止文字列、コンテキストシフトの設定によって変わります。コンテキスト長だけを停止保証にせず、生成数の上限を指定してください。モデルを自分で登録するときは、ModelfileにQwenの推奨値と上限を書いておきます。
FROM ./Qwen3-0.6B-Q8_0.gguf
PARAMETER temperature 0.6
PARAMETER top_p 0.95
PARAMETER top_k 20
PARAMETER min_p 0
PARAMETER presence_penalty 1.5
PARAMETER num_predict 4096
llama.cppでは同じ指定をコマンドラインで渡します。
./llama-cli -m Qwen3-0.6B-Q8_0.gguf \
--temp 0.6 --top-p 0.95 --top-k 20 --min-p 0 \
--presence-penalty 1.5 -n 4096
APIで使う場合、OpenAIのChat Completionsのpresence_penaltyとfrequency_penaltyは−2〜2の範囲で既定値0です(公式OpenAPI定義)。Responses APIのリファレンスには両パラメータの記載が無いため、移行時は同じ指定が通るかを確かめてください。2019年のCTRL論文(arXiv 1909.05858)の「greedy+ペナルティθ≈1.2」は、greedyを禁じるQwen3のような推論モデルには当てはまりません。推奨値を先に使い、ペナルティは残った反復に足すものとして扱います。
エージェントの無限ループ:IAL-Scanが見つけた6パターン
エージェント側の無限ループは、2026年7月の論文When Agents Do Not Stop: Uncovering Infinite Agentic Loops in LLM Agents(Hou、Wang、Zhao、Wang)がまとまった実データを出しています。静的解析ツールIAL-Scanで6,549件のLLMエージェントのリポジトリを調べ、報告74件のうち手作業で確認できた68件(47プロジェクト)を無限ループの不具合と認定しました(適合率91.9%)。68件の内訳は次のとおりです。
| パターン | 件数 | 割合 |
|---|---|---|
| 上限のない再試行(解析・検証の失敗で再度LLMを呼ぶ) | 17 | 25.0% |
| 上限のないツール呼び出しの反復 | 16 | 23.5% |
| 発話回数の上限がないマルチエージェント対話 | 14 | 20.6% |
| 実効的な上限のないワークフローの循環 | 9 | 13.2% |
| 上限のないメッセージの再投入 | 7 | 10.3% |
| 実行・委譲・評価者からの差し戻し | 5 | 7.4% |
68件のうち65件(95.6%)がAPI費用の枯渇につながる構造で、68件すべてで実効的な上限(strong bound)が欠けていました。フレームワーク別ではLangGraphが23件、AutoGen AgentChatが22件です。SDKにも上限はありますが、効き方はばらばらです。OpenAI Agents SDKの既定max_turnsは10で、超えると例外になります。一方LangGraphの既定recursion_limitは10007で、終了条件の無いグラフはほぼ止まらないと考えてください。「既定25」と書いた解説は古い版の値です。
エージェントループの停止設計:反復・無改善・コストの上限
エージェント側の暴走を確実に打ち切るには、サンプリングの調整に加えて、実行経路を覆う回数や時間の上限が必要です。同じ検索を繰り返す、検証に落ちて再生成を繰り返す、といった循環は、各回の出力が多少変わっても続くからです。設計時に次の3つの上限をループの外側から与えます。
- 反復上限:1タスクあたりの最大周回数。到達したら結果の良否にかかわらず打ち切り、上限で止まったことを記録する。
- 無改善打ち切り:スコアや状態が一定周回(上のコード例では5周)変わらなければ終了する。ツール名・引数のハッシュ比較は、同一呼び出しの反復を検出する補助策です。同じ引数でも外部状態や結果が変わる場合があるため、スコアや状態の無改善判定とは分けて扱います。
- コスト上限:累積トークン数・料金の閾値。常駐させるエージェントでは、これが最後の防衛線になる。
IAL-Scanの6パターンのうち「上限のない再試行」は、JSONの解析失敗などを受けてwhile Trueで再生成する実装が典型です。再試行にも回数上限を付け、上限に達したら別の手段(構造化出力の強制、人へのエスカレーション)に切り替えます。履歴を積み上げ続けるとコンテキストが膨らんで判断が鈍るため、直近n周だけを残すか要約して圧縮する運用も要ります(コンテキストエンジニアリングの領域です)。業務システムへ組み込むエージェントでこうした停止設計まで含めて相談したい場合は、AIエージェント開発の支援内容をご覧ください。
LLM最適化とベイズ最適化・強化学習の使い分け
目的関数を数値で定義でき、評価を安く繰り返せるタスク、たとえばハイパーパラメータ探索や連続値のチューニングでは、LLM最適化(LLM-in-the-loop)より先に、ベイズ最適化などの数値探索手法を比較対象にします。LLMを使う場合は、同じ評価予算での到達スコアと総費用を比較し、追加する利点を確認します。
LLM-in-the-loopが向くのは、候補が自然言語やコードで表され、評価を自動化でき、LLMの提案が探索効率を上げる場合です。ただし、自然言語のプロンプトにもベイズ最適化を適用する研究があり、対象が文章やコードというだけで従来手法を除外することはできません。境界にあるタスクでは、GEPAが強化学習と比べたように、試行回数あたりの改善量で選びます。評価の設計そのものはLLM評価の指標とデータセット設計で扱っています。なお「LLM最適化」をAI検索での露出対策(LLMO)の意味で探している場合は、この記事とは別の話題です。
よくある質問
LLM-in-the-loopとHuman-in-the-Loopの違いは何ですか?
ループの内側で判断を下す主体が違います。Human-in-the-Loopは人が評価・承認・修正を担い、LLM-in-the-loopはその判断をLLMに置き換えます。実務では排他ではなく、内側の試行錯誤をLLMに任せ、最終的な採否を人が握る二重構造にするのが一般的です。
ローカルLLMが同じ文章を繰り返すのはなぜですか?
greedyや低温度で動かしていること、小型・蒸留モデルであることが主な原因です。Ollamaやllama.cppの基盤設定では反復ペナルティが無効で、生成数の明示的な上限もないため、反復が長引く場合があります。ただし、モデル固有の設定や終了トークンなどでも挙動は変わります。モデルカードの推奨サンプリング設定(Qwen3ならthinkingモードで温度0.6・top_p 0.95・top_k 20)に戻し、presence_penaltyと生成トークン数の上限を設定してください。
推論モデルが考え続けて回答を返さないときはどうすればよいですか?
温度0やgreedyで動かしていないかを最初に確認します。推論モデルは低温度で同じ思考を繰り返しやすく、Qwen3は公式にgreedyの使用を禁じています。推奨温度に戻したうえで、思考に使えるトークン数に上限を置いてください。温度を上げても学習側の原因は消えないので、同じ問題で繰り返すなら、より大きいモデルや蒸留していないモデルへの切り替えを検討します。
エージェントのループ回数の上限はどれくらいに設定すべきですか?
SDKの既定値は、OpenAI Agents SDKのmax_turnsが10、LangGraphのrecursion_limitが10007と大きく違います。既定に任せず、代表タスクで正常完了に必要な反復数と費用を測り、許容予算に収まる上限を明示し、無改善が続いたら早期終了させます。上限に達したときに結果を捨てるのか途中経過を返すのかも、先に決めておいてください。
LLM-as-a-Judgeの評価スコアは信頼できますか?
MT-Benchの研究では、GPT-4の判定と人間の好みの一致率が80%を超え、人間同士の一致率と同じ水準でした。ただし提示順と回答の長さによるバイアスが確認され、自己贔屓の可能性も検討されているため、順序を入れ替えて複数回評価する、生成側と評価側で別系列のモデルを使う、といった補正を前提に組み込んでください。