JavaでサイクリックAIエージェントを実行する方法
LLMを使ったマルチエージェントシステムのチュートリアルは 대부분Pythonで書かれています。Javaでバックエンドを書いていて、コールチェーンよりも複雑なものを構築したい場合は、従来は独自の有限状態機械を発明するか、LangChain4jの上にブランチングをハックする必要がありますでした。
Pythonエコシステムでは、LangChainチームのLangGraphがそのようなタスクの標準になっています。それはシンプルな問題を解決します:実際の会話エージェントはほとんど直線的(DAG)には動作しません。エージェントはツールを呼び出したり、エラーを確認したり、ユーザーにclarificationを求めたり、サブタスクを再起動したりする必要があります。これらはサイクルです。
LangGraph4jプロジェクトは、このコンセプトをJavaの世界にもたらします。このライブラリはSpring AIやLangChain4jとうまく連携し、実際のデータベースへのステートの永続化をサポートし、複雑な実行グラフを構築する能力を提供します。
内部構造と動作原理
ライブラリのコアにはStateGraphクラスがあります。グラフを、ノード、エッジ、そしてステップ間で渡される共有ステートのセットとして記述します。
各ノードは現在のステートを受け取り、ロジックの一部を実行し(例えば、LLMを呼び出したりデータベースにアクセスしたり)、更新を含む辞書を返します。これらの更新はいわゆるリデューサーを通じて共有ステートとマージされます。例えば、新しいメッセージはリストの末尾に追加できますが、ステータスフラグは単に上書きされます。
基本的な例
これを使うにはJava 17以上が必要です。依存関係を追加してください:
<dependency>
<groupId>org.bsc.langgraph4j</groupId>
<artifactId>langgraph4j-core</artifactId>
<version>1.8.24</version>
</dependency>
メッセージ用の2つのノードと共有ステートを持つ最もシンプルなグラフを記述してみましょう:
import org.bsc.langgraph4j.StateGraph;
import org.bsc.langgraph4j.state.AgentState;
import org.bsc.langgraph4j.state.Channels;
import org.bsc.langgraph4j.state.Channel;
import static org.bsc.langgraph4j.action.AsyncNodeAction.node_async;
import static org.bsc.langgraph4j.StateGraph.START;
import static org.bsc.langgraph4j.StateGraph.END;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
// 1. Описываем структуру состояния
class SimpleState extends AgentState {
public static final String MESSAGES_KEY = "messages";
public static final Map<String, Channel<?>> SCHEMA = Map.of(
MESSAGES_KEY, Channels.appender(ArrayList::new)
);
public SimpleState(Map<String, Object> initData) {
super(initData);
}
public List<String> messages() {
return this.<List<String>>value("messages").orElse(List.of());
}
}
public class SimpleApp {
public static void main(String[] args) throws Exception {
// 2. Собираем граф
var graph = new StateGraph<>(SimpleState.SCHEMA, SimpleState::new)
.addNode("greeter", node_async(state ->
Map.of(SimpleState.MESSAGES_KEY, "Привет от первого узла!")))
.addNode("responder", node_async(state ->
Map.of(SimpleState.MESSAGES_KEY, "Ответ получен.")))
.addEdge(START, "greeter")
.addEdge("greeter", "responder")
.addEdge("responder", END)
.compile();
// 3. Запускаем стриминг шагов
for (var step : graph.stream(Map.of(SimpleState.MESSAGES_KEY, "Старт"))) {
System.out.println("Шаг выполнен: " + step);
}
}
}
ここでは、グラフは非同期ジェネレーターを返します。各ノードの実行後にグラフステートが得られるため、クライアントへのリアルタイムの進捗状況のストリーミングに便利です。
このプロジェクトが実践的に興味深い点
1. 条件付き遷移とサイクル
リニアチェーンは通常のコードで簡単に構築できます。グラフの真の力は条件付きエッジを追加したときに明らかになります。LLMの作業結果を見て次にどこに行くかを決定する関数をエッジにアタッチします:ツール呼び出しノードへ、再生成へ、またはダイアログの完了へ。
2. ステートの永続化とタイムトラベル
エージェントが複数の反復にわたってユーザーと通信したり、プロセスが何時間もかかる場合、すべてをJVMメモリに保持することは実行可能ではありません。
LangGraph4jにはチェックポイントモジュールが含まれています。PostgreSQL、Redis、MySQL、SQLite、OracleDB、Hazelcast、DynamoDB用の既製のアダプターが利用可能です。以下のことができます:
- 各ステップ後にステートを保存する;
- サービスの再起動後に特定のポイントから実行を再開する;
- グラフがアクションの人間の確認を待ってから続行するHuman-in-the-loopを実装する;
- グラフを以前の状態スナップショットに「巻き戻す」。
3. Spring AIとLangChain4jのネイティブ統合
別のAPIのためにモデル呼び出しを書き直す必要はありません。リポジトリにはすでに統合モジュールが含まれています。
LangGraph4jとLangChain4jでReActエージェントを実行する方法は次のとおりです:
var model = OllamaChatModel.builder()
.modelName("qwen2.5:7b")
.baseUrl("http://localhost:11434")
.build();
var agent = AgentExecutor.builder()
.chatModel(model)
.toolsFromObject(new TestTool())
.build()
.compile();
for (var item : agent.stream(Map.of("messages", "Проверь статус и верни число потоков"))) {
System.out.println(item);
}
Spring AIの場合、アノテーションとSpring beansを使用して、構文はほとんど同じです。
4. LangGraph Studioと可視化
可視性なしに複雑なグラフをデバッグすることは困難です。LangGraph4jはPlantUMLとMermaidフォーマットのグラフダイアグラムを生成できます。
著者はまた、LangGraph4j StudioというWebインターフェースを構築しました。これはSpring Boot、Quarkus、またはJettyアプリケーションに直接埋め込んで、ブラウザでグラフノードを視覚的に実行および検査できます。
注意点
このライブラリは積極的に開発中であり(このレビュー時点ではバージョン1.8.x)、マイナーアップデート間で一部のAPIが変更される可能性があります。
examplesフォルダの一部のチュートリアルはJava用のJupyterノートブックとしてフォーマットされています。これらの例を実行するには、ライブラリのコアは安定したJava 17+で正常に動作しますが、著者はJava 22を要求しています。
誰が使うべきか
Spring BootやQuarkusでエンタープライズサービスを構築していて、エージェントシナリオ(技術サポート、CI/CD自動化、マルチステージドキュメント処理)を実装したい場合は、LangGraph4jはLLM用の独自のタスクスケジューラを書く必要性を取り除きます。
このライブラリは、エージェントオーケストレーションのためだけにチームにPythonスタックへの切り替えを強制することなく、成熟したアーキテクチャ基盤を提供します。Ollama経由のローカルモデルと2〜3ノードのシンプルなグラフで実験を開始できます。
関連プロジェクト