最終章は、ここまでの理解を手で動かして確かめます。「ハーネス」と聞くと壮大に思えるかもしれませんが、 最小形は驚くほど小さい。Thorsten Ball の名言を借りれば——「It's an LLM, a loop, and enough tokens.(LLMとループと十分なトークンがあればいい)」。 本章では最小ハーネスの作り方、よくある失敗と対処、そして実務家になるための学習ロードマップを示します。
最小ハーネスの作り方
生のLLM APIを叩いて最小ループを書く場合、必要な部品はわずかです。第3章で見たループに、ツールを足すだけ。
Thorsten Ball の有名なチュートリアルでは、たった3つのツール(read_file / list_files / edit_file)を持つコード編集エージェントが、
約300〜400行(大半がボイラープレート)で動きます。
# 擬似コード(説明用): 3つのツールを持つ最小コーディングエージェント
tools = [
{"name": "read_file",
"description": "指定パスのファイル内容を返す",
"input_schema": {"path": "str"}},
{"name": "list_files",
"description": "ディレクトリ内のファイル名一覧を返す",
"input_schema": {"path": "str (省略可)"}},
{"name": "edit_file",
"description": "old_str を new_str に置換(無ければ新規作成)",
"input_schema": {"path": "str", "old_str": "str", "new_str": "str"}},
]
# あとは第3章のループに tools を渡すだけ:
# モデル呼び出し → tool_use を検出 → ローカルで実行
# → 結果を会話履歴へ → 繰り返し → end_turn で終了
# description がモデルの挙動を左右する「事実上の指示」になる(第5章 ACI)。 手順を整理すると——①システムプロンプトを設計、②ツール(関数)スキーマを定義、③ループを書く、④ツール呼び出しをパースして実行、 ⑤結果をフィードバックして再ループ、⑥終了条件を決める(第3章のサーキットブレーカー)、⑦コンテキスト管理とエラー処理。 これだけで「自分のハーネス」が動き始めます。
究極の最小形 — mini-SWE-agent
どこまで小さくできるか。その極北が、SWE-bench/SWE-agent チームによる mini-SWE-agent です。 コア約100行のPythonで、SWE-bench Verified で74%超(第9章)。設計上の割り切りが見事です。
- bashのみ・カスタムツールなし。LMのツール呼び出しインターフェースすら使わず、モデルの出力からbashコマンドを抽出して実行する。だから任意のLMで動く。
- ステートレス実行: 各アクションは独立した
subprocess.run。永続シェルを持たないので安定し、docker execに差し替えるだけでサンドボックス化できる(第7章)。 - 完全に線形な履歴: 各ステップでメッセージに追記するだけ。デバッグやファインチューニングが容易。
設計者の言葉が示唆的です——「旧SWE-agentはツールと特殊インターフェースを重視したが、LMが賢くなるにつれ、その複雑さの多くは不要になった」。 第9章の結論「モデルが進化したら足場は潔く捨てる」が、ここに体現されています。
SDKで作る — ループを自分で書かない選択肢
もちろん、ループを自前で書かずSDKに任せる手もあります。用途で選びましょう。
| 作り方 | 何を自分で書くか | 向く場面 |
|---|---|---|
| 自前ループ(Thorsten Ball / mini-SWE-agent) | ループ・ツール・終了条件まで全部 | ハーネスの中身を理解・カスタムしたい |
| Claude Agent SDK | ほぼ書かない(ループ・コンテキスト管理・組み込みツール込み) | Claude Codeと同じループを自前アプリに |
| OpenAI Agents SDK | エージェント定義とツール(handoff/session付き) | OpenAIエコシステムでの本番 |
| LangGraph | 状態グラフ(ノード・エッジ)を明示 | ループを明示制御・状態管理・HITL |
よくある失敗と対処
自作であれSDKであれ、エージェントは似た失敗をします。定石の対処を押さえておきましょう。
| 症状 | 原因 | 対処 |
|---|---|---|
| 無限ループ・空回り | 終了ルール不在、曖昧なツール応答 | 反復上限/応答を明示的なSUCCESS・FAILEDに/重複検知デバウンス |
| コンテキストオーバーフロー | ツールが大量データを返す | Memory Pointer(大出力は外部に保存しポインタだけ返す)・要約・チャンク化 |
| ツールを呼ばない・引数を幻覚 | ツール記述/スキーマが不明瞭 | ACIを徹底(使用例・エッジケース・poka-yoke)(第5章) |
| 終了しない | 停止条件の欠如 | max_turns・stop_reason・反復上限(第3章) |
| コスト暴走 | 毎ターン会話全体を再送 | プロンプトキャッシュ・モデルティアルーティング・予算ハードキャップ |
学習ロードマップ
最後に、初学者から実務家へ至る道筋を、本シリーズの章に対応づけて示します。
graph TD L0[Lv0 メンタルモデル\nAgent=Model+Harness] --> L1[Lv1 ReActの基礎] L1 --> L2[Lv2 自作で体感\n最小ループ] L2 --> L3[Lv3 ツール接続\nMCP] L3 --> L4[Lv4 コンテキスト/\nメモリ設計] L4 --> L5[Lv5 本番フレームワーク選定] L5 --> L6[Lv6 マルチエージェント\nの判断軸] L6 --> L7[Lv7 可観測性と評価] L7 --> L8[Lv8 安全実行\nサンドボックス] L8 --> L9[Lv9 ベンチで\n自作を測る] style L0 fill:#3b82f6,stroke:#1d4ed8,color:#fff style L1 fill:#3b82f6,stroke:#1d4ed8,color:#fff style L2 fill:#8b5cf6,stroke:#6d28d9,color:#fff style L3 fill:#8b5cf6,stroke:#6d28d9,color:#fff style L4 fill:#8b5cf6,stroke:#6d28d9,color:#fff style L5 fill:#f97316,stroke:#ea580c,color:#fff style L6 fill:#f97316,stroke:#ea580c,color:#fff style L7 fill:#14b8a6,stroke:#0d9488,color:#fff style L8 fill:#14b8a6,stroke:#0d9488,color:#fff style L9 fill:#14b8a6,stroke:#0d9488,color:#fff
未来とまとめ
10章を通じて見てきたのは、「Agent = Model + Harness」という等式と、その右辺をどう設計するかという工学でした。 最後に、ハーネスエンジニアリングの核心を Addy Osmani の2つの原則で締めくくります。
だからこそ、ハーネスは動的です。モデルが賢くなれば、それまで必要だった足場の一部は不要になる(第9章のmini-SWE-agent、Noam Brownの指摘)。 「複雑化 → モデル進化で再びミニマルへ」という揺り戻しが繰り返されるでしょう。 ハーネスエンジニアの仕事は、最強の足場を一度組むことではなく、いま手元のモデルの限界を見極め、それを埋める足場を組み、不要になったら捨てる—— この終わりなき調整を続けることなのです。これでシリーズは完結です。お疲れさまでした。
理解度チェック
Thorsten Ballが示した「最小ハーネス」の本質を最もよく表す言葉はどれですか?
キーボード: 1〜4 で選択、Enter で回答