1. 1. 准备工作

欢迎!在本 Codelab 中,您将学习如何使用热门的 LangChain4j 框架及其新的 Google GenAI 模块,以 Java 构建智能体 AI 应用。
智能体 AI 是指 LLM 不仅能响应提示,还能配备工具、记忆和规划功能,以自主完成复杂的、多步骤的目标。
您将从简单的配置开始,逐步构建具有本地工具和结构化输出的智能体,最后探索高级多智能体编排模式,最终构建一个以目标为导向的行动规划 (GOAP) 智能体系统。
您将执行的操作
- 配置新的
GoogleGenAiChatModel以连接到 Gemini。 - 启用请求/响应日志记录,以便轻松调试。
- 使用工具 授予 Gemini 对本地 Java 代码的访问权限。
- 强制 Gemini 使用 结构化输出 格式 (POJO)。
- 使用
@Agent注解定义和构建单一用途的智能体 。 - 编排顺序 和并行 多智能体工作流。
- 构建一个以目标为导向的行动规划 (GOAP) 系统,该系统可以动态规划智能体执行。
所需条件
- Java 开发套件 (JDK) 17 或更高版本。
- 已安装 Maven 3.5+。
- 来自 Google AI Studio 的 Gemini API 密钥。
2. 2. 设置:项目和 API 密钥
首先,我们需要创建一个新的 Maven 项目并配置 Gemini API 密钥。
创建 Maven 项目
为您的项目创建一个新目录,并使用 pom.xml 文件对其进行初始化。
将以下依赖项添加到 pom.xml。请注意,我们使用的是 LangChain4j Google GenAI 和智能体模块的最新版本 1.16.1-beta26 :
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>gemini-agents-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<langchain4j.version>1.16.1-beta26</langchain4j.version>
</properties>
<dependencies>
<!-- LangChain4j Google GenAI Integration -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-google-genai</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- LangChain4j Agentic Framework Core -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-agentic</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- LangChain4j Agentic Patterns (needed for GOAP) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-agentic-patterns</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- SLF4J Logger for logging requests/responses -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.12</version>
</dependency>
</dependencies>
</project>
获取 Gemini API 密钥
- 前往 Google AI Studio。
- 点击获取 API 密钥 。
- 创建新密钥(或选择现有密钥)。
- 在终端中将其设置为环境变量:
export GEMINI_API_KEY="your-api-key-here"
3. 3. 配置 Gemini 聊天模型
现在,我们来创建一个简单的“Hello World”应用,该应用会实例化 GoogleGenAiChatModel 并发送测试提示。
新的 GoogleGenAiChatModel 使用统一的 Google GenAI SDK,该 SDK 提供对 Gemini 模型的统一访问。
在 src/main/java/com/example/HelloWorld.java 中创建一个名为 HelloWorld.java 的类:
package com.example;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.google.genai.GoogleGenAiChatModel;
public class HelloWorld {
public static void main(String[] args) {
// 1. Configure the Gemini model
ChatModel model = GoogleGenAiChatModel.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.modelName("gemini-3.5-flash")
// Enable logging for both requests and responses
.logRequestsAndResponses(true)
.build();
// 2. Invoke the model
String response = model.chat("Hello Gemini! Explain 'Agentic AI' in one sentence.");
// 3. Print response
System.out.println("\n--- Gemini Response ---");
System.out.println(response);
}
}
运行此类。由于启用了 logRequestsAndResponses(true),您将看到详细的 SLF4J 日志,其中详细说明了发送到 Google API 的确切请求载荷、收到的原始 JSON 响应,以及打印的输出:
--- Gemini Response ---
**Agentic AI** refers to autonomous artificial intelligence systems that can proactively plan, make decisions, use tools, and execute multi-step tasks to achieve specific goals with minimal human supervision.
4. 4. 定义本地 Java 工具
LLM 功能强大,但受其训练数据的限制。我们可以通过向其提供工具 (也称为函数调用)来扩展其功能。
在 LangChain4j 中,工具是简单的 Java 类,其中的方法使用 @Tool 进行注解。
我们来编写一个简单的工具,用于计算两个日期之间的天数。在 src/main/java/com/example/DateTools.java 中创建 DateTools.java:
package com.example;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class DateTools {
@Tool("Calculates the number of days between two dates")
public long daysBetween(
@P("The start date in ISO format (YYYY-MM-DD)") String startDate,
@P("The end date in ISO format (YYYY-MM-DD)") String endDate) {
LocalDate start = LocalDate.parse(startDate);
LocalDate end = LocalDate.parse(endDate);
return ChronoUnit.DAYS.between(start, end);
}
}
如需使用此工具,我们将定义一个 AI 服务 。在 LangChain4j 智能体框架中,我们可以使用 AgenticServices.agentBuilder() 构建它。
在 src/main/java/com/example/ToolDemo.java 中创建 ToolDemo.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.google.genai.GoogleGenAiChatModel;
import dev.langchain4j.service.V;
public class ToolDemo {
public interface DateAssistant {
@Agent
String ask(@V("prompt") String prompt);
}
public static void main(String[] args) {
ChatModel model = GoogleGenAiChatModel.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.modelName("gemini-3.5-flash")
.build();
// Build the assistant and register our DateTools
DateAssistant assistant = AiServices.builder(DateAssistant.class)
.chatModel(model)
.tools(new DateTools())
.build();
String response = assistant.ask("How many days are there between 2026-01-01 and 2026-06-30?");
System.out.println("Response: " + response);
}
}
运行此代码时,Gemini 会分析提示,意识到需要调用 daysBetween,生成工具调用请求,LangChain4j 会执行您的本地 Java 方法,将结果发送回 Gemini,而 Gemini 会格式化最终的自然语言响应。
您应该会看到类似于以下内容的输出:
Response: There are 180 days between 2026-01-01 and 2026-06-30.
5. 5. 定义结构化输出
通常,您希望 LLM 以特定的结构化格式(例如与架构匹配的 JSON)而非纯文本返回数据。
当您将 POJO 或 Java record 指定为智能体或服务方法的返回值类型时,LangChain4j 会自动处理此问题。
我们来定义一个表示图书提取的 Java record:
在 src/main/java/com/example/Book.java 中创建 Book.java:
package com.example;
public record Book(String title, String author, int publicationYear) {}
现在,创建一个返回 Book 的智能体接口。在 src/main/java/com/example/StructuredOutputDemo.java 中创建 StructuredOutputDemo.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.google.genai.GoogleGenAiChatModel;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public class StructuredOutputDemo {
public interface BookExtractor {
@UserMessage("Extract book details from: {{text}}")
Book extract(@V("text") String text);
}
public static void main(String[] args) {
ChatModel model = GoogleGenAiChatModel.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.modelName("gemini-3.5-flash")
.build();
BookExtractor extractor = AiServices.builder(BookExtractor.class)
.chatModel(model)
.build();
String text = "I just finished reading 'Project Hail Mary' by Andy Weir, published in 2021. It was amazing!";
Book book = extractor.extract(text);
System.out.println("Extracted POJO: " + book);
}
}
Gemini 3.5 Flash 支持严格的 JSON 架构输出。LangChain4j 会根据您的 Book 记录生成 JSON 架构,指示 Gemini 填充该架构,并将 JSON 响应反序列化回 Book 记录。
您应该会看到类似于以下内容的输出:
Extracted POJO: Book[title=Project Hail Mary, author=Andy Weir, publicationYear=2021]
6. 6. 创建您的第一个智能体
在 langchain4j-agentic 框架中,智能体 是使用接口方法的 @Agent 注解定义的。此注解提供了一个名称/说明,可供编排系统(如规划器)使用。
我们来创建一个简单的智能体,该智能体接受一个主题,并根据该主题撰写一个非常短的故事。
在 src/main/java/com/example/CreativeWriter.java 中创建 CreativeWriter.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface CreativeWriter {
@SystemMessage("You are a creative writer. Generate a draft of a story no more than 3 sentences long.")
@UserMessage("Write a story about {{topic}}.")
@Agent(description = "Generates a story based on the given topic", outputKey = "story")
String writeStory(@V("topic") String topic);
}
我们来单独测试此智能体。在 src/main/java/com/example/AgentDemo.java 中创建 AgentDemo.java:
package com.example;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.google.genai.GoogleGenAiChatModel;
public class AgentDemo {
public static void main(String[] args) {
ChatModel model = GoogleGenAiChatModel.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.modelName("gemini-3.5-flash")
.build();
CreativeWriter writer = AgenticServices.agentBuilder(CreativeWriter.class)
.chatModel(model)
.build();
String story = writer.writeStory("a lonely robot on Mars");
System.out.println("Generated Story:\n" + story);
}
}
您应该会看到类似于以下内容的输出:
Generated Story:
For eighty years, the rusty little rover trundled across the crimson dunes, diligently collecting soil samples for a home world that had long since gone dark. Each evening, it pointed its high-gain antenna toward the fading blue speck of Earth and beamed its lonely coordinates into the silent cosmos. Receiving only static in return, the robot tucked its camera arm close against the freezing Martian wind and sang a quiet lullaby to the empty stars.
通过添加 @Agent 注解,此类现在已准备好参与更复杂的工作流,例如顺序链接。
7. 7. 编排多智能体工作流:顺序
一种常见的智能体模式是顺序工作流,即智能体按预定义的顺序执行。一个智能体的输出将作为下一个智能体的输入传递。
我们来定义第二个智能体 StyleEditor,它将编辑 CreativeWriter 撰写的故事,以符合特定风格(例如喜剧、戏剧)。
在 src/main/java/com/example/StyleEditor.java 中创建 StyleEditor.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface StyleEditor {
@SystemMessage("You are a professional editor. Analyze and rewrite the story to align with the style requested.")
@UserMessage("Rewrite this story: '{{story}}' into a {{style}} style.")
@Agent(description = "Edits a story to fit a specific style", outputKey = "edited_story")
String editStory(@V("story") String story, @V("style") String style);
}
现在,我们使用 AgenticServices.sequenceBuilder() 按顺序连接 CreativeWriter 和 StyleEditor。
我们将使用一个表示序列的 UntypedAgent,这样我们就可以通过共享映射传递输入和收集输出。
在 src/main/java/com/example/SequentialWorkflowDemo.java 中创建 SequentialWorkflowDemo.java:
package com.example;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.agentic.UntypedAgent;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.google.genai.GoogleGenAiChatModel;
import java.util.Map;
public class SequentialWorkflowDemo {
public static void main(String[] args) {
ChatModel model = GoogleGenAiChatModel.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.modelName("gemini-3.5-flash")
.build();
// 1. Build the sub-agents
CreativeWriter writer = AgenticServices.agentBuilder(CreativeWriter.class)
.chatModel(model)
.outputKey("story") // Output goes into AgenticScope as "story"
.build();
StyleEditor editor = AgenticServices.agentBuilder(StyleEditor.class)
.chatModel(model)
.outputKey("edited_story") // Output goes into AgenticScope as "edited_story"
.build();
// 2. Build the sequence
UntypedAgent workflow = AgenticServices.sequenceBuilder()
.subAgents(writer, editor)
.outputKey("edited_story") // Final output of workflow
.build();
// 3. Run the workflow with inputs
Map<String, Object> inputs = Map.of(
"topic", "a cat learning to fly",
"style", "Shakespearean"
);
String result = (String) workflow.invoke(inputs);
System.out.println("Final Edited Story:\n" + result);
}
}
您应该会看到类似于以下内容的输出:
Final Edited Story:
For years had Barnaby with envy watched
The soaring sparrows with a green-eyed spite,
Convinced that heavy gravity was but
An idle law he deigned to tolerate.
But lo! Upon the rare and azure moon,
He scaled the summit of the ancient oak,
Closed fast his eyes, and leapt with blind belief.
While the dread squirrel shrieked in sheer dismay,
No downward plunge befell the daring beast;
For summer's zephyr bore his belly up,
And through the vault of night's celestial sphere,
He rowed his velvet paws among the stars.
智能体范围简介
在执行期间,LangChain4j 会管理 AgenticScope 。
- 输入映射
{"topic": "...", "style": "..."}会写入到范围。 CreativeWriter执行。它需要topic,并从范围中读取该主题。它输出story,并将其保存回范围。StyleEditor执行。它需要story(由撰稿人生成)和style(来自初始输入)。它将edited_story输出到范围。- 工作流完成并返回
edited_story的值。
8. 8. 编排多智能体工作流:并行
在某些情况下,子智能体可以独立处理相同的输入,并且其任务可以并行执行。
例如,我们来创建一个旅行顾问,该顾问会向电影专家和餐饮专家咨询有关某个城市的建议,然后将这些建议合并。
在 src/main/java/com/example/MovieExpert.java 中创建 MovieExpert.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import java.util.List;
public interface MovieExpert {
@UserMessage("Suggest 2 movies filmed in {{city}}.")
@Agent(description = "Suggests movies filmed in a city")
List<String> findMovies(@V("city") String city);
}
在 src/main/java/com/example/DiningExpert.java 中创建 DiningExpert.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import java.util.List;
public interface DiningExpert {
@UserMessage("Suggest 2 local dishes to try in {{city}}.")
@Agent(description = "Suggests local dishes to try in a city")
List<String> findDishes(@V("city") String city);
}
现在,我们来构建并行智能体系统。我们将为顶级协调器定义一个接口:TravelAdvisorAgent。
在 src/main/java/com/example/TravelAdvisorAgent.java 中创建 TravelAdvisorAgent.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.V;
import java.util.Map;
public interface TravelAdvisorAgent {
@Agent
Map<String, Object> planTrip(@V("city") String city);
}
在 src/main/java/com/example/ParallelWorkflowDemo.java 中创建 ParallelWorkflowDemo.java 以将其关联在一起:
package com.example;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.google.genai.GoogleGenAiChatModel;
import java.util.List;
import java.util.Map;
public class ParallelWorkflowDemo {
public static void main(String[] args) {
ChatModel model = GoogleGenAiChatModel.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.modelName("gemini-3.5-flash")
.build();
// 1. Build independent agents
MovieExpert movieExpert = AgenticServices.agentBuilder(MovieExpert.class)
.chatModel(model)
.outputKey("movies")
.build();
DiningExpert diningExpert = AgenticServices.agentBuilder(DiningExpert.class)
.chatModel(model)
.outputKey("dishes")
.build();
// 2. Build the Parallel agent
TravelAdvisorAgent travelAdvisor = AgenticServices.parallelBuilder(TravelAdvisorAgent.class)
.subAgents(movieExpert, diningExpert)
.output(scope -> {
// Combine the independent outputs in the AgenticScope
List<String> movies = scope.readState("movies", List.of());
List<String> dishes = scope.readState("dishes", List.of());
return Map.of("movies", movies, "dishes", dishes);
})
.build();
// 3. Invoke
Map<String, Object> plan = travelAdvisor.planTrip("Tokyo");
System.out.println("Tokyo Trip Plan:\n" + plan);
}
}
您应该会看到类似于以下内容的输出:
Tokyo Trip Plan:
{movies=[Lost in Translation, Tokyo Story], dishes=[Monjayaki, Edomae-zushi]}
In this parallel workflow, `movieExpert` and `diningExpert` execute concurrently. The `output(...)` configuration defines how to gather their respective results from the `AgenticScope` and merge them into the final result.
## 9. Build Goal-Oriented Agents (GOAP)
Duration: 07:00
Sequential and Parallel workflows are structured and predictable, but rigid. What if we want the system to figure out the path to the goal autonomously, but in a **deterministic, algorithmic way** rather than trusting an LLM to loop (like ReAct)?
This is where **Goal-Oriented Action Planning (GOAP)** shines.
By looking at the declared inputs and outputs of each agent, the `GoalOrientedPlanner` builds a dependency graph. When you invoke the system with a goal, it calculates the shortest path from the current state (available variables) to that goal.
Let's build a Horoscope & News combined writer. It requires 4 agents:
1. `PersonExtractor`: extracts person details from prompt.
2. `SignExtractor`: extracts zodiac sign from prompt.
3. `HoroscopeGenerator`: generates horoscope given person and sign.
4. `AmusingWriter`: writes a funny story combining a horoscope and a news story.
We will also define a `StoryFinder` that uses a mock search tool.
### 1. Define Model Classes
Create `Person.java` in `src/main/java/com/example/Person.java`:
```java
package com.example;
public record Person(String name) {
@Override public String toString() { return name; }
}
在 src/main/java/com/example/Sign.java 中创建 Sign.java:
package com.example;
public record Sign(String signName) {
@Override public String toString() { return signName; }
}
2. 定义子智能体
在 src/main/java/com/example/HoroscopeGenerator.java 中创建 HoroscopeGenerator.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface HoroscopeGenerator {
@UserMessage("Generate a funny horoscope for {{person}} who is a {{sign}}.")
@Agent(description = "Generates horoscopes based on name and zodiac sign")
String horoscope(@V("person") Person person, @V("sign") Sign sign);
}
在 src/main/java/com/example/PersonExtractor.java 中创建 PersonExtractor.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface PersonExtractor {
@UserMessage("Extract the person name from: {{prompt}}")
@Agent(description = "Extracts a person from user's prompt")
Person extractPerson(@V("prompt") String prompt);
}
在 src/main/java/com/example/SignExtractor.java 中创建 SignExtractor.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface SignExtractor {
@UserMessage("Extract the zodiac sign from: {{prompt}}")
@Agent(description = "Extracts a zodiac sign from user's prompt")
Sign extractSign(@V("prompt") String prompt);
}
在 src/main/java/com/example/AmusingWriter.java 中创建 AmusingWriter.java:
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface AmusingWriter {
@UserMessage("Create an amusing writeup for {{person}} based on their horoscope: {{horoscope}} and current news story: {{story}}.")
@Agent(description = "Create an amusing writeup combining horoscope and news")
String write(@V("person") Person person, @V("horoscope") String horoscope, @V("story") String story);
}
3. 定义故事查找工具
我们将创建一个简单的搜索工具类,该类会返回模拟故事。在 src/main/java/com/example/MockSearchTool.java 中创建 MockSearchTool.java:
package com.example;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
public class MockSearchTool {
@Tool("Searches the web for news stories related to a zodiac sign")
public String searchNews(@P("The zodiac sign") String sign) {
return "Breaking news: A massive cheese festival was announced for " + sign + " natives today!";
}
}
创建使用此工具的 src/main/java/com/example/StoryFinder.java 智能体:StoryFinder.java
package com.example;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface StoryFinder {
@UserMessage("Find a funny story for zodiac sign {{sign}} using search tool.")
@Agent(description = "Finds a news story on the internet about a zodiac sign")
String findStory(@V("sign") Sign sign);
}
4. 构建和运行 GOAP 智能体系统
在 src/main/java/com/example/GoapDemo.java 中创建 GoapDemo.java:
package com.example;
import dev.langchain4j.agentic.AgenticServices;
import dev.langchain4j.agentic.UntypedAgent;
import dev.langchain4j.agentic.patterns.goap.GoalOrientedPlanner;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.google.genai.GoogleGenAiChatModel;
import java.util.Map;
public class GoapDemo {
public static void main(String[] args) {
ChatModel model = GoogleGenAiChatModel.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.modelName("gemini-3.5-flash")
.build();
// Instantiate sub-agents with output keys matching the inputs of other agents
HoroscopeGenerator horoscopeGen = AgenticServices.agentBuilder(HoroscopeGenerator.class)
.chatModel(model).outputKey("horoscope").build();
PersonExtractor personExt = AgenticServices.agentBuilder(PersonExtractor.class)
.chatModel(model).outputKey("person").build();
SignExtractor signExt = AgenticServices.agentBuilder(SignExtractor.class)
.chatModel(model).outputKey("sign").build();
StoryFinder storyFinder = AgenticServices.agentBuilder(StoryFinder.class)
.chatModel(model).tools(new MockSearchTool()).outputKey("story").build();
AmusingWriter writer = AgenticServices.agentBuilder(AmusingWriter.class)
.chatModel(model).outputKey("writeup").build();
// Build the GOAP Planner agentic system
UntypedAgent horoscopeNewsAgent = AgenticServices.plannerBuilder()
.subAgents(horoscopeGen, personExt, signExt, storyFinder, writer)
.outputKey("writeup") // The Goal we want to achieve
.planner(GoalOrientedPlanner::new) // Register the GOAP Planner
.build();
// Input provides only "prompt"
Map<String, Object> inputs = Map.of(
"prompt", "My name is Alice and my zodiac sign is Leo"
);
System.out.println("Invoking GOAP Agentic System...");
String result = (String) horoscopeNewsAgent.invoke(inputs);
System.out.println("\n--- Final Writeup ---");
System.out.println(result);
}
}
GOAP 的解决方案:
调用时:
- 系统检测到初始状态仅包含
prompt。 - 所需目标是
writeup。 - 它会构建依赖关系图并计算路径:
prompt->PersonExtractor->personprompt->SignExtractor->signperson+sign->HoroscopeGenerator->horoscopesign->StoryFinder->storyperson+horoscope+story->AmusingWriter->writeup
- 计算出的执行顺序为:
[PersonExtractor, SignExtractor, HoroscopeGenerator, StoryFinder, AmusingWriter]。 - 它会按顺序执行每个分代理并返回最终结果。
您应该会看到一个输出,其中显示了执行路径和最终撰写内容,类似于:
Invoking GOAP Agentic System...
[com.example.GoapDemo.main()] INFO dev.langchain4j.agentic.patterns.goap.GoalOrientedSearchGraph - Agents path sequence: [extractPerson, extractSign, findStory, horoscope, write]
--- Final Writeup ---
**The Cosmic Registry's Weekly Forecast & Special Event Guide for: Alice, the Leo Lioness**
Alice, the universe looked at your astrological chart this week and frankly, it's asking for your autograph. Your main-character energy is currently so potent that secondary characters are practically fading into the background.
But the biggest cosmic news of the week? The universe has finally recognized your royal status with the announcement of a **Massive Cheese Festival**...
9. 10. 清理
如需清理资源,请执行以下操作:
- 如果您不再使用 Google AI Studio 中的任何 API 密钥,请务必将其删除。
- 在终端中取消设置环境变量:
unset GEMINI_API_KEY
10. 11. 恭喜
恭喜!您已使用 LangChain4j 和新的 Google GenAI 模块成功构建了一系列智能体 AI 应用。
如需进一步提升技能,我们建议您查看官方 LangChain4j Google GenAI 模块文档,详细了解如何使用 LangChain4j 创建智能体。
要点回顾
- 如何配置
GoogleGenAiChatModel。 - 如何使用本地 Java 工具和请求/响应日志记录。
- 如何输出结构化 POJO 数据。
- 如何使用
@Agent构建单一用途的智能体。 - 如何编排顺序、并行和以目标为导向的行动规划 (GOAP) 智能体工作流。