はじめに
第1回では、AIエージェントの基本的な概念と活用が期待される領域について解説しました。続く第2回では、PoC(概念実証)から実用化に向けた開発の実践論について取り上げました。第3回となる本稿では、AIエージェント活用の具体例として、コーディングエージェントの内部構造を詳しく解説します。
Anthropic社のClaude CodeやOpenAI社のCodex、GitHub社のGitHub Copilot、Anomaly社のOSSであるOpenCodeなど、「コーディングエージェント」と呼ばれるAIエージェントはこの1年で実用レベルに到達しました。これらのAIエージェントは、代表的なユースケースの1つとなっており、この記事をご覧の方も日常的に利用しているのではないでしょうか。
コーディングエージェントは、ユーザーの指示をもとにコードを書き、テストを実行します。もしエラーが発生すれば、エージェント自身で修正を試みます。そして、数十ファイルにまたがるリファクタリングや、既存のコードベースを理解した上での機能追加など、人間が数時間以上費やす作業を代行します。その結果、最終的に動作するコードとして仕上げることが可能です。
高度なコーディング代行を支える要因は、大きく分けて2つあります。1つは、テストやビルドの成否を通じて、エージェント自身が出力の正しさを検証できるというソフトウェア開発固有の特性です。もう1つは、数十分から数時間にわたる長時間タスクの実行を安定させる仕組みが、モデルの外側に組み込まれていることです。この仕組みは「エージェントハーネス」と呼ばれています。
本稿では、エージェントハーネスの定義や構成要素について解説します。解説にあたっては、LangChainが公開しているオープンソースのエージェントハーネス「DeepAgents」[1]と筆者の業務エージェント開発経験をベースに進めます。
エージェントハーネスとは何か
LLMだけでは長時間に及ぶタスクの実行が難しい
LLMは、一問一答のタスクでは高い性能を発揮します。しかし、タスクの実行が長時間に及ぶと、特有の課題が浮き彫りになります。
前提として、モデルが一度に扱える情報量である「コンテキストウィンドウ」には上限があります。ツール呼び出しを数十回、数百回と繰り返すと、入出力内容がコンテキストに蓄積されます。その結果、古い情報から順に押し出しされ、当初の目的や途中経過が失われることがあります。
また、ツールの実行中にエラーが起きた際、モデル単体では元のエージェントループへと適切に復帰できない場合もあります。
これらの課題は「モデルの賢さ」とは別の問題です。どれほど優れたモデルであっても、有限のコンテキスト内でタスクを長時間安定して実行し続けるには、モデルの外側で、コンテキストの状態やツール実行を管理する仕組みが不可欠です。
エージェントハーネスの定義
Google DeepMindのStaff Engineerであり、元Hugging FaceのTechnical Leadを務めたPhilipp Schmid氏は、エージェントハーネスを「AIモデルを包み込み、長時間実行されるタスクを管理するためのインフラストラクチャ」と定義しています[2]。つまり、エージェントハーネスはエージェントそのものではなく、エージェントが安定動作するための「土台」を指します。この関係をPCの構成に例えると、図1のような対応関係になります。
[2] Philipp Schmid, "The Agent Harness"
CPUがどれほど高速でも、OSがなければアプリケーションは動作しません。同様に、LLMがどれほど優秀でも、ハーネスがなければ長時間のタスク実行は安定しないのです。
ハーネスの3つの役割
OSの役割になぞらえると、エージェントハーネスが担う役割は、主に3つに集約されます。
1つ目は「コンテキスト管理」です。これはOSにおけるメモリ管理に相当します。コンテキストウィンドウの使用量を監視し、不要になった古い会話が要約・圧縮します。大きなツール出力を一時的にファイルへ退避し、必要なときだけ読み込むといった処理もここに含まれます。
2つ目は「ツール実行管理」で、OSのI/O管理にあたります。エージェントが利用できるツール(ファイル操作、Web検索、コマンド実行など)を提供し、ツール実行時のエラーを捕捉してモデルが理解できる形で返します。危険な操作に対するアクセス制御もここに含まれます。
3つ目は「タスク計画」で、OSのプロセス管理に近い役割です。複雑なタスクを小さなステップに分解し、独立した作業を子エージェント(サブプロセス)に委譲します。タスク全体の進捗の追跡や完了の管理も担います。
いずれもモデルの「中」ではなく「外」で行われる処理です。
