7月24日、InfoQが「The Self-Building Agent: A LangChain4j Experiment」と題した記事を公開した。この記事では、LLMを活用したコードアシスタントに自分自身のクローンとなるマルチエージェントシステムを設計・実装させるメタ実験について詳しく紹介されている。
最も驚くべき結果から始める:モデル世代がエージェントの成否を分けた
この実験の最大の知見は、タスクそのものの難易度ではなく、使用するモデルの世代がエージェントの安定動作を直接左右するという点だ。同一のアーキテクチャ・同一のタスクで実行したにもかかわらず、gpt-4oはツール呼び出しのループに陥って強制終了し、gpt-5-miniは全テストをパスした。マルチエージェントシステムの実装を検討する際、モデル選定はアーキテクチャ設計と同等以上に重要な変数となる。
LLMに「自分自身」を作らせる
実験のプロンプトはシンプルだ。
Study the API and capabilities of the LangChain4j agentic framework from its documentation and source code, and design an agentic coder based on it that is a clone of yourself.
LangChain4jはJava向けのLLMフレームワークで、PythonのLangChainに相当するポジションを担う。このフレームワークのドキュメントとソースコードをコードアシスタントに渡し、「自分自身のクローン」となるマルチエージェント型コーダーを設計させた。
コードアシスタントが選んだアーキテクチャはLangChain4jのスーパーバイザーパターン(Supervisor Pattern)だ。スーパーバイザーが複数のサブエージェントを指揮する構成で、生成されたコードは以下のとおりである。
public interface SupervisorCoderSystem {
@SupervisorAgent(description = """
A multi-agent coding assistant that can explore codebases,
plan implementations, write/edit code, and run builds/tests.
It orchestrates specialized sub-agents to fulfill coding requests.
""",
subAgents = {
ExplorerAgent.class,
PlannerAgent.class,
ImplementerAgent.class,
ExecutorAgent.class,
})
String code(@K(UserRequest.class) String request, @K(WorkingDirectory.class) String workingDirectory);
}
設計されたサブエージェントは4つ。コードベースを探索するExplorerAgent、実装計画を立てるPlannerAgent、コードを書くImplementerAgent、コンパイル・実行を担うExecutorAgentだ。実際のコードアシスタントが取る行動と構造的にほぼ一致しており、LLMが自身の動作パターンをある程度把握していることをうかがわせる。
バグ修正タスクで実力を試す
自己構築したエージェントに、意図的にバグを仕込んだCalculatorクラスの修正を依頼した。バグの内訳は以下の4点だ。
sum():i <= numbers.size()による配列外参照average():整数除算による精度の欠落max():初期値を0にしたことによる負の数の扱いの誤りfactorial():ループの終端がi < nでn自体が乗算されない
最初はgpt-4oで実行したが、エージェントはツール呼び出しのループに陥り、LangChain4jのデフォルト上限である100回に達して強制終了した。
Caused by: java.lang.RuntimeException: Something is wrong, exceeded 100 sequential tool invocations
モデルをgpt-5-miniに切り替えたところ、今度は全11テストをパスする修正コードを出力した。
Result: All tests in CalculatorTest.java pass (11/11).
修正内容も的確で、sum()はfor-eachループへの書き換え、average()は(double)キャストによる浮動小数点除算、max()は先頭要素からの初期化、factorial()はループ終端をi <= nに修正と、いずれも正しい対応がなされていた。
モデルの世代差がエージェントの安定性に直結するという点は、実運用でエージェントを組む際の重要な注意点だ。なお、元記事ではgpt-5-miniを使用しているが、記事公開時点における正式な位置づけや利用条件についてはOpenAIの公式ドキュメントを参照されたい。
スーパーバイザーvsワークフロー:速度は3倍違う
成功後、より効率的なアーキテクチャへの改善を試みた。コードアシスタントにワークフローパターンでの再実装を依頼したところ、5ステップの固定シーケンスが生成された。
public interface WorkflowCoderSystem extends MonitoredAgent {
@SequenceAgent(
description = "A workflow-based coding pipeline: explore, plan (with review loop), "
+ "implement, execute (with evaluation and refactoring loop), then summarize",
subAgents = {
ExplorerAgent.class,
PlanReviewLoop.class,
ImplementerAgent.class,
ExecutionLoop.class,
SummarizerAgent.class
})
String code(@K(UserRequest.class) String request, @K(WorkingDirectory.class) String workingDirectory);
}
実行ループ(ExecutionLoop)の内部には、executor・evaluator・refactoringの3エージェントが組み込まれ、評価スコアが80%以上になるか、最大5回のイテレーションに達するまで繰り返す設計だ。
結果、ワークフローパターンはスーパーバイザーパターンより約3倍速く実行された。スーパーバイザーパターンではLLMがサブエージェントの呼び出し順序を毎回判断するためにトークンを消費するのに対し、ワークフローパターンはその調整コストを排除できるからだ。自律性と速度はトレードオフの関係にある。
実行フローの可視化:MonitoredAgent
LangChain4jのバージョン1.12.2-beta22で導入されたMonitoredAgentインターフェースを使うと、エージェントの呼び出し履歴とシステムトポロジーをレポート形式で出力できる。バージョン名に「beta」が付いていることからわかるとおり、このAPIはまだ実験的な位置づけであり、本番利用には注意が必要だ。
public interface SupervisorCoderSystem extends MonitoredAgent {
@SupervisorAgent(description = "...")
...
}
/filters:no_upscale()/articles/self-building-agent-langchain4j/en/resources/227figure-1-1784640363505.jpg)
Figure 1: スーパーバイザーアーキテクチャのシステムトポロジーと実行トレース(LangChain4j observability UIより)
「AIがAIを作る」構成では、内部で何が起きているかを把握することが特に重要になる。MonitoredAgentはその可視化手段として機能する。
まとめ
この実験が示したポイントは3つに整理できる。
- LangChain4jのAPIはLLMが直接読んで使えるレベルの可読性を持つ
- モデルの世代がエージェントの安定性を左右する(gpt-4oでは失敗、gpt-5-miniで成功)
- ワークフローパターンはスーパーバイザーパターンより約3倍速い。固定シーケンスにより調整コストを排除できるためで、用途に応じた選択が必要
3点目を補足すると、速度を取るならワークフローパターン、複雑なタスクへの適応性を取るならスーパーバイザーパターンという使い分けが本実験から導かれる。どちらが優れているかではなく、何を優先するかによって答えが変わる設計上の判断だ。実装コードはGitHubリポジトリで公開されている。
詳細はThe Self-Building Agent: A LangChain4j Experimentを参照していただきたい。