Chapter 10

第10章: 三大病と HITL ── 早すぎる終了・無限ループ・幻のツール呼び

ここまで本書は、エージェントが “動く” 仕組みを階段で上ってきた。 LLM・道具・ハーネスの 三角形think → act → observe の三拍子、停止条件 の三本柱、function calling の契約、コンテキストウィンドウ の物理、外部記憶ファイル、計画サブエージェント ── 道具立てはもう一通り揃ったはずだ。

なのに、現場ではいまも、こんな会話が日常的に流れる。

「Claude が テストが赤いのに “完了しました” と言って止まった」 「Cursor が 同じ Edit と失敗を 17 回繰り返してた」 「Codex が 存在しない関数 を呼ぶコードをドヤ顔で出してきた」

道具は揃っている。LLM は賢くなっている。 それでも、エージェントは 同じ三つの病 に何度も倒れる。

この章で、その三つの病を一枚の地図に置き、最後の砦としての HITL の設計判断まで腑に落とす。これが本書のクライマックスだ。

10.1 そもそも、なぜ「病」と呼ぶのか

「LLM が間違える」のは、当たり前の話だ。第1章で見たとおり、LLM の本質は「続きを書く機械」であって、確率的に時々おかしな続きを書く。 本章で扱いたいのは、そういう 個別の間違い ではない。ループという構造の中でくり返し現れる、典型パターン のほうだ。

個別の出力ミスは「間違い」、ループ構造の中でくり返し現れるパターンは「病」と呼ぶ。

病は、モデルが何倍賢くなっても、ループという構造を持つかぎり 形を変えて残り続ける。 だからこそ、囲い込みの設計が永遠に必要になる。

代表的な病は三つに整理できる。

順に見ていく。各病について、何が起きるか / なぜ起きるか / 設計でどう抑えるか を揃える。

10.2 病 ① 早すぎる終了 ── “だいたい直しました” 問題

最初の病は、第1章の最後で予告した「早すぎる終了」だ。

具体的にはこういう挙動になる。

LLM が 道具を呼ばない出力 を返した瞬間、ハーネスはループから抜ける ── これは第1章で見た停止の仕組みだった。 病はその「抜けるタイミング」を、LLM が 早く判断しすぎる ことで起きる。

なぜ起きるか。原因はだいたい三つに分けられる。

囲い込みの設計は、ループ側でやることになる。

抑える設計何をするか
検証ループの強制「コードを書いたら必ずテストを走らせる」をシステムプロンプトと hooks で強制
テスト緑チェック「テストが緑になったか」を 機械的な合格条件 として書く。LLM の自己申告に頼らない
Reviewer サブエージェント完了判断を 別のサブエージェント に委ねる (第9章)。書いた本人と判断する本人を分ける

「終わって良いか」を LLM の自己申告だけに任せると、必ずどこかで早すぎる終了が起きる。

終了判断を 機械的な条件 (テスト緑、lint 0 件) に置き換える か、別エージェントに委ねる ── どちらかの設計が必要になる。

10.3 病 ② 無限ループ ── 同じ失敗を 17 回くり返す

正反対の方向に倒れる病が、無限ループ だ。

第1章の最後で予告した、もうひとつの病だ。LLM が “終わり” を判断できないと、ループは延々と回り続ける

なぜ起きるか。

囲い込みの設計は、外側のハーネスが 構造で抑える 必要がある。

抑える設計何をするか
max_turns (第4章)ループの上限回数を機械的に決めておき、超えたら強制終了
同一エラー検出直近 N ターンのエラー出力を比較して、同じものが続いたら止める
強制停止 (人間の Esc)ユーザーが画面を見て、明らかに堂々巡りなら割り込む
計画の再評価サブタスクの完了数を見て、進んでいなければ計画を捨てて立て直す
落とし穴

無限ループは、コストとしても精神衛生としても、最も痛い病 だ。 画面を見ていなかった 30 分の間に、API コストが想定の 5 倍に達することが普通にある。 「自走させる」前提の運用では、max_turns と同一エラー検出は 絶対に外せない安全装置 になる。

10.4 病 ③ 幻のツール呼び ── 存在しないものを堂々と呼ぶ

三つ目の病は、いわゆる ハルシネーション がツール呼び出しの場面で出るパターンだ。

第5章で見たように、ツール呼び出しは JSON Schema による契約 で成立している。 LLM はその契約を理解した「つもり」で、学習データの中でよく見たパターンに引っ張られて、実在しないものをそれらしく出力 してしまう。

囲い込みの設計は、ハーネス側の入口で機械的に弾く のが基本だ。

抑える設計何をするか
スキーマ違反は即エラーツール呼び出しを JSON Schema で検証し、違反は実行せず error として LLM に返す
未知のツール名はエラー定義されていないツール名は問答無用で reject
存在チェックRead 系ツールはファイル存在を先に確認し、無ければ「存在しません」を返す
道具の説明を磨く (第6章)description で「いつ呼ぶか / いつ呼ばないか」を明確にし、似た名前のツールは統合する

幻のツール呼びは、ハーネス側で完全に防げる タイプの病だ。 ループの病の中では、入口で弾く のが最も効く。

LLM が幻覚を出すこと自体は止められない。だが、その幻覚を実行に移すかどうか は、外側のハーネスが完全にコントロールできる。

10.5 三大病を一枚の地図に

ここまでの三つを並べて整理すると、こうなる。

三大病囲い込む設計 (本書の章)① 早すぎる終了残りがあるのに「完了」と言って止まる”だいたい直しました” 問題② 無限ループ同じ失敗を 17 回くり返すEdit → Test 失敗 → Edit → …③ 幻のツール呼び存在しないツール・関数・パスを堂々と呼ぶハルシネーション付きツール呼び出し検証ループの強制 / テスト緑チェックReviewer サブエージェント (第9章)終了判断を機械条件 or 別エージェントに委ねるmax_turns (第4章) / 同一エラー検出強制停止 (人間の Esc)構造で「打ち止め」を入れるスキーマ違反は即エラー / 未知ツール名は reject存在チェック / 道具の description を磨く入口で機械的に弾く (第5・6章)どの病も「LLM の自助努力」では完治しない。外側の構造で囲う
図 10.1 — 三大病と、それぞれを囲い込む設計。どの矢印も「完治」ではなく「緩和」を意味する。

ここまでが、ループの の話だ。 ところが、ここまで囲い込んでも どうしてもゼロにならない領域 が残る。 そこで最後の砦として登場するのが HITL ── 人間をループの中に置く、という設計判断だ。

10.6 HITL ── 完全自走と対話の中間に線を引く

HITL (Human in the Loop)

エージェントのループの中に、人間の判断ステップ を意図的に組み込む設計。完全自走でもなく、一手ごとの対話でもなく、重要な分岐点でだけ人間に止まらせる 中間の運用。

ここまで読んで、こう思うかもしれない。

「結局、人間が画面を見てなきゃ駄目なら、エージェントの意味あるの?」

この問いに対する本書の答えは、こうだ。

完全自走か、一手ごとの対話か ── の二択ではない。

「どこに、何を、どのくらいの頻度で人間に止まらせるか」を 設計判断として明示的に置く ── これが HITL の本質。 人間の介入は「敗北」ではなく、ループ全体の信頼性を上げるための仕掛け だ。

HITL の介入導線は、現代のプロダクトでは大きく三つの形で現れる。

① 承認プロンプト ── 書き込み・破壊的操作の前で止まる。ファイルの初書き込み、Bashrmgit push を呼ぶ瞬間、外部 API への書き込み呼び出しなど。Claude Code は ask / allow / deny の三段階で実装している。

② 割り込み ── 人間が画面を見て、明らかにおかしいと感じた瞬間に止める。Esc キー、Ctrl+C、ユーザー入力の挿入。無限ループの最終防衛ラインだが、画面を見ていることが前提。席を立つ運用では機能しない。

③ スコープ制限 ── そもそも触れる範囲を最初から絞っておく。権限モード (allow / ask / deny)、許可ディレクトリ、許可コマンドの列挙。介入というより事前の囲い込みで、HITL より強い防衛線 になる。

HITL 設計の核は二つの問いに集約される。

① いつ人間に止めさせるか? 取り返しのつかない操作の前? 一定ターンごと? エラーが N 回連続したとき?

② 何を人間に見せるか? 実行しようとしているコマンド? その理由? 影響範囲? 計画と進捗?

「止めさせる頻度」と「見せる情報」のバランス ── これが HITL の設計判断のすべてだ。 止めすぎると人間が疲弊して承認が形骸化する。止めなさすぎると事故が起きる。

10.7 プロダクト間の温度差 ── 自走度の軸

「いつ止めるか」の設計判断は、プロダクトごとに温度差が大きい。 都度確認から完全自走までの軸の上に、現代のエージェントを並べてみる。

自走度の軸 ── どこまで人間に止めさせないか都度確認(一手ごとに ask)完全自走(席を立てる)ファイル変更ごとにy/n 系破壊系のみ ask読み取りは allowホワイトリスト系を自動承認人間の承認なしで実行する設定
図 10.2 — 自走度の軸。右端は「人間の承認を求めない設定」── Claude Code の --dangerously-skip-permissions、Cursor の auto mode、Devin のフル自動などが、ここに集まる。

軸上のどこに座るのが正解かは、仕事の reversibility (取り返し可否) と blast radius (影響範囲) によって変わる。重要なのは、自分が今 軸上のどこに居るか を意識して使うことだ。

具体的に各プロダクトが軸上のどこに位置するか(Aider・Claude Code・Cursor・Devin など6種の対比)は、付録 A の比較表 に集約してある。新しいエージェントを試すときは、付録 A を引いて「この子は軸上のどこか」を真っ先に確かめるとよい。

新しいエージェントを試すとき、最初に確かめるべきは三つだけ。

  • 既定で rm をどう扱う?
  • Bash の許可は事前に列挙する? それとも都度?
  • 席を立てる設計か、画面に張り付く設計か?

この三つで、そのプロダクトの 設計思想 がほぼ読める。

10.8 ループの病と HITL ── 本書のクライマックス

ここで一度、本書の旅を振り返ってみる。

序章で 3 層モデルを提示し、第1章で LLM・道具・ハーネスの三角形 を置いた。第2章で執事としてのハーネスを解剖し、第3章で think → act → observe の三拍子に踏み込んだ。第4章で停止条件、第5・6章で道具の契約と良し悪し、第7・8章で文脈の物理と外部記憶、第9章で計画とサブエージェント ── そして本章で 三大病と HITL に行き着いた。

並べてみると、これらは 個別の機構の話 ではなかったことに気づく。

本書がここまで歩いてきた 10 章は、結局のところ「ループの病をどう囲い込むか」という一つの問いに対する、設計判断の総体だった。

  • 道具を JSON Schema で契約する (第5章) ── 幻のツール呼びを入口で弾くため
  • description を磨く (第6章) ── LLM を正しいツールへ誘導するため
  • コンテキストを管理し、外部メモリに逃がす (第7・8章) ── 早すぎる終了を生む文脈劣化を抑えるため
  • 計画と TodoWrite (第9章) ── 進捗を外部メモにして、無限ループや脇道を防ぐため
  • サブエージェント (第9章) ── 親の机を散らかさないため
  • 三大病への囲い込みと HITL (第10章) ── ゼロにならない残余を、最後に人間で受け止めるため

ループの病はゼロにならない。続きを書く機械という構造に由来するからだ。 ゼロにならない以上、誰かが「囲いをどう設計するか」を考え続けることになる。本書はその設計判断のメニューを一冊にまとめたものだった。

そして HITL は、そのメニューの最後のページだ。 道具・契約・文脈・計画・サブエージェント ── どれだけ積み上げても残る最後の不確実性を、人間という最強のセンサー で受け止める。これは「エージェントの敗北」ではない。ループ全体の信頼性を上げるための、最後のピース だ。

10.9 この章の振り返り

この章で読めるツイート / ブログ

そして、終章へ

本書はここでクライマックスを越えた。 LLM・道具・ハーネスの三角形から、停止条件・function calling・コンテキスト・メモリ・計画・サブエージェント、そして三大病と HITL ── ループという設計パターンを、プロダクト横断でひと通り歩いた。

次に来るのは、本書のもうひとつのゴールだ。 ここまで腑に落とした骨格をもって、ループはこれからどこへ向かうのか を考える。長時間タスク、マルチモーダル、エージェント間プロトコル ── 終章で、本書の旅を締めくくる。