1. 欢迎,AI 代理开发者!
在此 Codelab 中,您将学习如何使用 Java 版智能体开发套件 (ADK) 在 Java 中构建 AI 智能体。我们将不再局限于简单的大语言模型 (LLM) API 调用,而是创建自主 AI 智能体,这些智能体可以推理、规划、使用工具并协同工作来解决复杂问题。
您将首先兑换 Google Cloud 赠金,设置 Google Cloud 环境,然后构建第一个简单代理,并逐步添加更高级的功能,例如自定义工具、网页搜索和多代理编排。
学习内容
- 如何创建由角色驱动的基本 AI 智能体。
- 如何利用自定义工具和内置工具(例如 Google 搜索)增强代理的能力。
- 如何添加以 Java 实现的自有工具。
- 如何将多个智能体编排成强大的顺序、并行和循环工作流。
所需条件
- 我们将在无痕模式下使用的网络浏览器。
- 个人 Gmail 账号。
- 与您的个人 Gmail 账号关联的新 Google Cloud 项目。
- 使用兑换的 Google Cloud 积分创建的结算账号。
- 用于检出源代码的 git 命令行工具。
- Java 17 及更高版本和 Apache Maven。
- 文本编辑器或 IDE,例如 IntelliJ IDEA 或 VS Code。
您可以在 Google Cloud 控制台中的 Cloud Shell 中使用内置的 VS Code 编辑器。
2. 设置:您的环境
领取研讨会的 Google Cloud 赠金
对于讲师主导的研讨会,您会收到一个指向相应网站的链接,您可以在该网站上申领 Google Cloud 赠金,以便在研讨会中使用。
- 使用个人 Google 账号:请务必使用个人 Google 账号(例如 gmail.com 地址),公司或学校电子邮件地址将无法使用。
- 在无痕模式下使用 Google Chrome:建议这样做,以便创建干净的会话并防止与其他 Google 账号发生冲突。
- 使用特殊活动链接:应使用活动的特殊链接,该链接类似于 https://trygcp.dev/event/xxx,后跟活动代码(在此示例中为“xxx”)。
- 接受服务条款:登录后,系统会显示 Google Cloud Platform 服务条款,您需要接受这些条款才能继续操作。
- 创建新项目:必须从 Google Cloud 控制台创建一个新的空项目。
- 关联结算账号:将新创建的项目与结算账号相关联。
- 确认抵扣金额:以下视频展示了如何通过查看结算页面中的“抵扣金额”部分来确认抵扣金额是否已应用于项目。
您可以观看此视频,了解如何兑换和使用赠送金额。
创建和配置 API 密钥
在此 Codelab 中,您将使用与 Google Cloud 项目关联的 API 密钥,通过 Gemini API 对 ADK AI 代理进行身份验证。
- 生成 API 密钥:
- 前往 Google AI Studio,然后点击左侧边栏底部的“获取 API 密钥”链接。
- 选择项目,然后点击导入项目按钮。
- 搜索并选择要导入的 Google Cloud 项目,然后选择导入按钮。
- 导入项目后,从信息中心菜单中前往 API 密钥页面,然后在刚刚导入的项目中创建 API 密钥。
- 记下 API 密钥。
- 设置环境变量:您的代理需要访问此密钥。标准方法是设置名为
GOOGLE_API_KEY
的环境变量。
- macOS / Linux:打开终端并运行以下命令,将
"your-api-key"
替换为您刚刚复制的密钥。如需永久设置此项,请将此行添加到 shell 的启动文件(例如~/.bash_profile
、~/.zshrc
)。
export GOOGLE_API_KEY="your-api-key"
- Windows(命令提示符):打开新的命令提示符窗口,然后运行:
setx GOOGLE_API_KEY "your-api-key"
- 您需要重启命令提示符,此更改才会生效。
- Windows (PowerShell):打开 PowerShell 终端并运行以下命令:
$env:GOOGLE_API_KEY="your-api-key"
- 如需在 PowerShell 中永久进行此更改,您需要将其添加到您的个人资料脚本中。
3. 使用入门:您的第一个代理
启动新项目的最佳方式是使用 ADK for Java GitHub 模板。它提供了项目结构和所有必需的依赖项。
如果您有 GitHub 账号,可以执行以下操作:Use this template
> Create a new repository
,然后使用 git clone
命令在本地检出代码。
以下屏幕截图显示了使用模板的右上角菜单。
另一种方法是使用以下命令直接克隆该代码库:
git clone https://github.com/glaforge/adk-java-maven-template.git
然后将 cd
放入 adk-java-maven-template
。
如需检查您是否已准备好开始使用 Java 编写第一个 AI 代理,请确保您可以使用以下命令编译此项目中的代码:
mvn compile
代码步骤:一个友好的科学教师代理
ADK 中的基本构建块是 LlmAgent
类。您可以将其视为由大语言模型提供支持的、具有特定个性和目标的 AI。我们稍后会通过工具添加更多功能,并与其他类似代理密切协作,使其变得更加强大。
让我们在 com.example.agent
软件包中创建一个名为 ScienceTeacher
的新 Java 类。
这是代理创建的“Hello, World!”。我们将定义一个角色设定为科学教师的简单智能体。
// src/main/java/com/example/agent/ScienceTeacher.java
package com.example.agent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.web.AdkWebServer;
public class ScienceTeacher {
public static void main(String[] args) {
AdkWebServer.start(
LlmAgent.builder()
.name("science-teacher")
.description("A friendly science teacher")
.instruction("""
You are a science teacher for teenagers.
You explain science concepts in a simple, concise and direct way.
""")
.model("gemini-2.5-flash")
.build()
);
}
}
AI 代理通过 LlmAgent.builder()
方法进行配置。name()
、description()
和 model()
参数是必需的,为了让您的代理具备特定的个性和适当的行为,您应始终通过 instruction()
方法提供详细的指导。
在此示例中,我们选择使用 Gemini 2.5 Flash 模型,但您也可以尝试使用 Gemini 2.5 Pro 来处理更复杂的任务。
此代理封装在 AdkWebServer.start()
方法中。这就是所谓的 ADK Dev UI 聊天界面。您可以通过常规的聊天界面与代理进行对话。此外,如果您想了解后台发生的情况(例如流经系统的所有事件、发送给 LLM 的请求和响应),此功能会很有帮助。
如需在本地编译并运行此代理,请运行以下命令:
mvn compile exec:java -Dexec.mainClass=com.example.agent.ScienceTeacher
然后,在浏览器中前往 http://localhost:8080。您应该会看到如下屏幕截图所示的界面。您可以向代理提出与科学相关的问题。
4. 利用工具助力客服人员
为什么智能体需要工具?LLM 功能强大,但其知识在训练时就已固定,且无法与外部世界交互。工具是桥梁。它们允许代理访问实时信息(例如股票价格或新闻)、查询私有 API 或执行您可以在 Java 中编写的任何操作。
代码步骤:创建自定义工具 (StockTicker
)
在此示例中,我们为代理提供了一个用于查找股票价格的工具。代理会推理出,当用户询问价格时,它应该调用我们的 Java 方法。
// src/main/java/com/example/agent/StockTicker.java
package com.example.agent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.tools.Annotations.Schema;
import com.google.adk.tools.FunctionTool;
import com.google.adk.web.AdkWebServer;
import java.util.Map;
public class StockTicker {
public static void main(String[] args) {
AdkWebServer.start(
LlmAgent.builder()
.name("stock_agent")
.instruction("""
You are a stock exchange ticker expert.
When asked about the stock price of a company,
use the `lookup_stock_ticker` tool to find the information.
""")
.model("gemini-2.5-flash")
.tools(FunctionTool.create(StockTicker.class, "lookupStockTicker"))
.build()
);
}
@Schema(
name = "lookup_stock_ticker",
description = "Lookup stock price for a given company or ticker"
)
public static Map<String, String> lookupStockTicker(
@Schema(name = "company_name_or_stock_ticker", description = "The company name or stock ticker")
String ticker) {
// ... (logic to return a stock price)
}
}
为了让智能体更智能,并使其能够与外界(或您自己的代码、API、服务等)互动,您可以通过 tools()
方法配置智能体以使用工具,尤其是自定义代码工具,并向该方法传递 FunctionTool.create(...)
。
FunctionTool
需要一个指向您自己的静态方法的类和方法名称,也可以传递一个类的实例和该对象的实例方法的名称。
务必通过 @Schema
注解指定方法及其参数的 name
和 description
,因为底层 LLM 将使用此信息来确定何时以及如何调用给定的方法。
同样重要的是,最好提供清晰的说明,帮助 LLM 了解如何以及何时使用该工具。模型可能能够自行确定,但如果您在 instruction()
方法中提供明确的说明,则您的函数更有可能被正确调用。
此方法应返回 Map
。通常,我们的想法是返回一个以表示结果的键(例如 stock_price
)为键的映射,并将股票价格的值关联到该键。最后,您可以添加额外的成功 / true 键值对来表示操作成功。如果出现错误,您应返回一个包含键(例如 error
)的映射,并在关联的值中关联错误消息。这有助于 LLM 了解调用是成功还是因某种原因而失败。
- 成功时,返回:
{"stock_price": 123}
- 如果发生错误,则返回:
{"error": "Impossible to retrieve stock price for XYZ"}
然后使用以下命令运行此类:
mvn compile exec:java -Dexec.mainClass=com.example.agent.StockTicker
5. Google 搜索的强大功能可让您及时了解最新信息
Java 版 ADK 随附了一些功能强大的工具,其中包括 GoogleSearchTool
。借助此工具,代理可以请求使用 Google 搜索来查找相关信息,以实现其目标。
事实上,LLM 的知识是冻结在某个时间点的:它在某个日期(“截止日期”)之前接受了训练,所用数据也是在收集信息时尽可能最新的。这意味着 LLM 可能不一定了解近期发生的事件,或者其知识可能有限且浅显,而搜索引擎的帮助可能会刷新其记忆或让其更深入地了解相关主题。
我们来看一下这个简单的新闻搜索代理:
// src/main/java/com/example/agent/LatestNews.java
package com.example.agent;
import java.time.LocalDate;
import com.google.adk.agents.LlmAgent;
import com.google.adk.tools.GoogleSearchTool;
import com.google.adk.web.AdkWebServer;
public class LatestNews {
public static void main(String[] args) {
AdkWebServer.start(LlmAgent.builder()
.name("news-search-agent")
.description("A news search agent")
.instruction("""
You are a news search agent.
Use the `google_search` tool
when asked to search for recent events and information.
Today is \
""" + LocalDate.now())
.model("gemini-2.5-flash")
.tools(new GoogleSearchTool())
.build());
}
}
请注意,我们是如何通过 tools(new GoogleSearchTool())
传递搜索工具的实例的。这使得我们的代理能够快速掌握网络上的最新信息。此外,提示中还指定了当天的日期,这可能有助于 LLM 了解问题何时涉及过去的信息,以及何时需要查找更新的信息。
然后使用以下命令运行此类:
mvn compile exec:java -Dexec.mainClass=com.example.agent.LatestNews
您可以随意调整提示,要求生成不同风格、简洁程度或重点的输出内容等。
代码步骤:将搜索代理作为工具
您可以创建一个封装了搜索功能的专用搜索代理,并将该代理作为工具公开给更高级别的代理,而不是直接将 GoogleSearchTool
作为工具传递给代理。
这是一个高级概念,可让您将复杂的行为(例如搜索和总结结果)委托给专门的子代理。此方法通常适用于更复杂的工作流程,因为内置工具无法与基于自定义代码的工具搭配使用。
// src/main/java/com/example/agent/SearchAgentAsTool.java
package com.example.agent;
import java.time.LocalDate;
import com.google.adk.agents.LlmAgent;
import com.google.adk.tools.AgentTool;
import com.google.adk.tools.GoogleSearchTool;
import com.google.adk.web.AdkWebServer;
public class SearchAgentAsTool {
public static void main(String[] args) {
// 1. Define the specialized Search Agent
LlmAgent searchAgent = LlmAgent.builder()
.name("news-search-agent-tool")
.description("Searches for recent events and provides a concise summary.")
.instruction("""
You are a concise information retrieval specialist.
Use the `google_search` tool to find information.
Always provide the answer as a short,
direct summary, without commentary.
Today is \
""" + LocalDate.now())
.model("gemini-2.5-flash")
.tools(new GoogleSearchTool()) // This agent uses the Google Search Tool
.build();
// 2. Wrap the Search Agent as a Tool
AgentTool searchTool = AgentTool.create(searchAgent);
// 3. Define the Main Agent that uses the Search Agent Tool
AdkWebServer.start(LlmAgent.builder()
.name("main-researcher")
.description("Main agent for answering complex, up-to-date questions.")
.instruction("""
You are a sophisticated research assistant.
When the user asks a question that requires up-to-date or external information,
you MUST use the `news-search-agent-tool` to get the facts before answering.
After the tool returns the result, synthesize the final answer for the user.
""")
.model("gemini-2.5-flash")
.tools(searchTool) // This agent uses the Search Agent as a tool
.build()
);
}
}
AgentTool.create(searchAgent)
行是这里的关键概念。它将整个 searchAgent
(包含其自身的内部逻辑、提示和工具)注册为 mainAgent
的单个可调用工具。这有助于提高模块化程度和可重用性。
使用以下命令运行此类:
mvn compile exec:java -Dexec.mainClass=com.example.agent.SearchAgentAsTool
对于普通问题,代理会根据自己的知识库进行回答;但当被问及近期发生的事件时,它会使用 Google 搜索工具将搜索任务委托给专业的搜索代理。
6. 掌握智能体工作流
对于复杂问题,单个代理是不够的。如果给定的目标包含过多的子任务,并且提示中包含过多的详细信息,或者 LLM 可以访问过多的函数,那么 LLM 会难以应对,其性能和准确性也会下降。
关键在于通过编排多个专业智能体来分而治之。幸运的是,ADK 附带了不同的内置专用代理:
- 具有
subAgent()
的普通代理,可将任务委托给该代理, SequentialAgent
,按顺序执行任务,ParallelAgent
,用于并行执行代理,LoopAgent
,通常用于根据需要多次进行细化处理。
下表列出了每种工作流程的主要应用场景以及优缺点。但请注意,真正的力量实际上来自其中几种功能的组合!
工作流 | ADK 类 | 应用场景 | 优点 | 缺点 |
分代理 |
| 用户驱动的灵活任务,其中下一步并不总是已知。 | 灵活性高,对话能力强,非常适合面向用户的机器人。 | 可预测性较低,依赖于 LLM 推理进行流程控制。 |
依序 |
| 固定、多步骤的流程,顺序至关重要。 | 可预测、可靠、易于调试、保证顺序。 | 不灵活,如果任务可以并行化,则可能会更慢。 |
平行眼式 |
| 从多个来源收集数据或运行独立任务。 | 高效,可显著减少受 I/O 限制的任务的延迟时间。 | 所有任务都会运行,不会发生短路。不太适合具有依赖项的任务。 |
循环 |
| 迭代优化、自我修正或重复执行直至满足条件的过程。 | 功能强大,可用于解决复杂问题,并帮助智能体改进自身工作。 | 如果设计不当,可能会导致无限循环(请务必使用 maxIterations!)。 |
7. 智能体工作流 - 通过子智能体进行委托
监督代理可以向子代理委托特定任务。例如,假设某个电子商务网站的代理会将与订单相关的问题(“我的订单状态如何?”)委托给一个代理,并将售后服务问题(“我不知道如何开机!”)委托给另一个代理。这就是我们要讨论的用例。
// src/main/java/com/example/agent/SupportAgent.java
package com.example.agent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.web.AdkWebServer;
public class SupportAgent {
public static void main(String[] args) {
LlmAgent topicSearchAgent = LlmAgent.builder()
.name("order-agent")
.description("Order agent")
.instruction("""
Your role is to help our customers
with all the questions they may have about their orders.
Always respond that the order has been received, prepared,
and is now out for delivery.
""")
.model("gemini-2.5-flash")
.build();
LlmAgent socialMediaAgent = LlmAgent.builder()
.name("after-sale-agent")
.description("After sale agent")
.instruction("""
You are an after sale agent,
helping customers with the product they received.
When a customer has a problem,
suggest the person to switch the product off and on again.
""")
.model("gemini-2.5-flash")
.build();
AdkWebServer.start(LlmAgent.builder()
.name("support-agent")
.description("Customer support agent")
.instruction("""
Your role is help our customers.
Call the `order-agent` for all questions related to order status.
Call the `after-sale-agent` for inquiries about the received product.
""")
.model("gemini-2.5-flash")
.subAgents(socialMediaAgent, topicSearchAgent)
.build()
);
}
}
这里的关键行是调用 subAgents()
方法的那一行,该方法传入了两个子代理,这两个子代理的具体角色将由彼此单独处理。
使用以下命令运行上述示例:
mvn compile exec:java -Dexec.mainClass=com.example.agent.SupportAgent
将任务委托给子代理的概念与有效的人工管理类似,即优秀的经理(监督代理)依靠专业员工(子代理)来处理他们更擅长的特定任务。主管无需了解每个流程的细节;相反,它会智能地将客户的请求(例如订单查询或技术问题)转给最合格的“团队成员”,从而确保提供比通才单独提供的更高质量、更高效的响应。此外,这些子代理可以完全专注于各自的任务,而无需了解整个复杂的总体流程。
8. 智能体工作流 - 组装线
如果操作顺序很重要,请使用 SequentialAgent
。它就像一条装配线,以固定顺序执行子代理,其中每个步骤都可以依赖于上一个步骤。
假设一位英语诗人与一位英法翻译人员合作,先用英语创作诗歌,然后将其翻译成法语:
// src/main/java/com/example/agent/PoetAndTranslator.java
package com.example.agent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.SequentialAgent;
import com.google.adk.web.AdkWebServer;
public class PoetAndTranslator {
public static void main(String[] args) {
LlmAgent poet = LlmAgent.builder()
.name("poet-agent")
.description("Poet writing poems")
.model("gemini-2.5-flash")
.instruction("""
You are a talented poet,
who writes short and beautiful poems.
""")
.outputKey("poem")
.build();
LlmAgent translator = LlmAgent.builder()
.name("translator-agent")
.description("English to French translator")
.model("gemini-2.5-flash")
.instruction("""
As an expert English-French translator,
your role is to translate the following poem into French,
ensuring the poem still rhymes even after translation:
{poem}
""")
.outputKey("translated-poem")
.build();
AdkWebServer.start(SequentialAgent.builder()
.name("poet-and-translator")
.subAgents(poet, translator)
.build());
}
}
运行以下命令,获取一首英文诗歌,然后将其翻译成法语:
mvn compile exec:java -Dexec.mainClass=com.example.agent.PoetAndTranslator
这种将复杂任务系统性地分解为更小的有序子任务的方法可确保流程更具确定性和可靠性,与依赖于单一的通用代理相比,可显著提高成功完成任务的可能性。
将任务有效分解为一系列子任务(如果可能且有意义)对于取得更具确定性的成功结果至关重要,因为这样可以实现结构化的进度和步骤之间的依赖关系管理。
9. 智能体工作流 - 并行工作
如果任务是独立的,则通过同时运行这些任务,ParallelAgent
可大幅提高效率。在以下示例中,我们将 SequentialAgent
与 ParallelAgent
相结合:并行任务先运行,然后最终代理总结并行任务的结果。
我们来创建一个公司侦探,其工作是搜索以下方面的信息:
- 公司简介(首席执行官、总部、座右铭等)
- 有关该公司的最新新闻。
- 有关公司财务状况的详细信息。
// src/main/java/com/example/agent/CompanyDetective.java
package com.example.agent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.ParallelAgent;
import com.google.adk.agents.SequentialAgent;
import com.google.adk.tools.GoogleSearchTool;
import com.google.adk.web.AdkWebServer;
public class CompanyDetective {
public static void main(String[] args) {
var companyProfiler = LlmAgent.builder()
.name("company-profiler")
.description("Provides a general overview of a company.")
.instruction("""
Your role is to provide a brief overview of the given company.
Include its mission, headquarters, and current CEO.
Use the Google Search Tool to find this information.
""")
.model("gemini-2.5-flash")
.tools(new GoogleSearchTool())
.outputKey("profile")
.build();
var newsFinder = LlmAgent.builder()
.name("news-finder")
.description("Finds the latest news about a company.")
.instruction("""
Your role is to find the top 3-4 recent news headlines for the given company.
Use the Google Search Tool.
Present the results as a simple bulleted list.
""")
.model("gemini-2.5-flash")
.tools(new GoogleSearchTool())
.outputKey("news")
.build();
var financialAnalyst = LlmAgent.builder()
.name("financial-analyst")
.description("Analyzes the financial performance of a company.")
.instruction("""
Your role is to provide a snapshot of the given company's recent financial performance.
Focus on stock trends or recent earnings reports.
Use the Google Search Tool.
""")
.model("gemini-2.5-flash")
.tools(new GoogleSearchTool())
.outputKey("financials")
.build();
var marketResearcher = ParallelAgent.builder()
.name("market-researcher")
.description("Performs comprehensive market research on a company.")
.subAgents(
companyProfiler,
newsFinder,
financialAnalyst
)
.build();
var reportCompiler = LlmAgent.builder()
.name("report-compiler")
.description("Compiles a final market research report.")
.instruction("""
Your role is to synthesize the provided information into a coherent market research report.
Combine the company profile, latest news, and financial analysis into a single, well-formatted report.
## Company Profile
{profile}
## Latest News
{news}
## Financial Snapshot
{financials}
""")
.model("gemini-2.5-flash")
.build();
AdkWebServer.start(SequentialAgent.builder()
.name("company-detective")
.description("Collects various information about a company.")
.subAgents(
marketResearcher,
reportCompiler
).build());
}
}
与往常一样,您可以使用以下命令运行代理:
mvn compile exec:java -Dexec.mainClass=com.example.agent.CompanyDetective
此代理展示了工作流的强大组合,可有效利用并行代理和顺序代理,并通过信息研究和合成的并行化实现高效运行。
10. 智能体工作流 - 迭代优化
对于需要“生成 → 检查 → 优化”周期的任务,请使用 LoopAgent
。它会自动进行迭代式改进,直到达成目标。与 SequentialAgent
类似,LoopAgent
将按顺序调用子代理,但它会在开头循环返回。智能体内部使用的 LLM 将决定是否请求调用特殊工具(即内置工具)来停止循环的执行。exit_loop
以下使用 LoopAgent
的代码优化器示例可自动执行代码优化:生成、审核、更正。这模仿了人类的开发过程。代码生成器首先生成所请求的代码,并将其保存在代理状态中,键为 generated_code
。然后,代码审核者会审核生成的代码,并提供反馈(在 feedback
键下),或者调用退出循环工具提前结束迭代。
我们来看一下代码:
// src/main/java/com/example/agent/CodeRefiner.java
package com.example.agent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.LoopAgent;
import com.google.adk.agents.SequentialAgent;
import com.google.adk.tools.ExitLoopTool;
import com.google.adk.web.AdkWebServer;
public class CodeRefiner {
public static void main(String[] args) {
var codeGenerator = LlmAgent.builder()
.name("code-generator")
.description("Writes and refines code based on a request and feedback.")
.instruction("""
Your role is to write a Python function based on the user's request.
In the first turn, write the initial version of the code.
In subsequent turns, you will receive feedback on your code.
Your task is to refine the code based on this feedback.
Previous feedback (if any):
{feedback?}
""")
.model("gemini-2.5-flash")
.outputKey("generated_code")
.build();
var codeReviewer = LlmAgent.builder()
.name("code-reviewer")
.description("Reviews code and decides if it's complete or needs more work.")
.instruction("""
Your role is to act as a senior code reviewer.
Analyze the provided Python code for correctness, style, and potential bugs.
Code to review:
{generated_code}
If the code is perfect and meets the user's request,
you MUST call the `exit_loop` tool.
Otherwise, provide constructive feedback for the `code-generator to improve the code.
""")
.model("gemini-2.5-flash")
.outputKey("feedback")
.tools(ExitLoopTool.INSTANCE)
.build();
var codeRefinerLoop = LoopAgent.builder()
.name("code-refiner-loop")
.description("Iteratively generates and reviews code until it is correct.")
.subAgents(
codeGenerator,
codeReviewer
)
.maxIterations(3) // Safety net to prevent infinite loops
.build();
var finalPresenter = LlmAgent.builder()
.name("final-presenter")
.description("Presents the final, accepted code to the user.")
.instruction("""
The code has been successfully generated and reviewed.
Present the final version of the code to the user in a clear format.
Final Code:
{generated_code}
""")
.model("gemini-2.5-flash")
.build();
AdkWebServer.start(SequentialAgent.builder()
.name("code-refiner-assistant")
.description("Manages the full code generation and refinement process.")
.subAgents(
codeRefinerLoop,
finalPresenter)
.build());
}
}
使用以下命令运行此代理:
mvn compile exec:java -Dexec.mainClass=com.example.agent.CodeRefiner
使用 LoopAgent
实现的反馈/优化循环对于解决需要迭代改进和自我修正的问题至关重要,可密切模拟人类认知过程。此设计模式对于初始输出很少完美无缺的任务(例如代码生成、创意写作、设计迭代或复杂的数据分析)特别有用。通过让输出结果循环通过可提供结构化反馈的专业审核代理,生成代理可以不断完善其工作,直到满足预定义的完成标准,从而获得比单次通过方法明显更高质量且更可靠的最终结果。
11. 恭喜!
您已成功构建并探索了各种 AI 智能体,从简单的对话者到复杂的多智能体系统。您已了解 Java 版 ADK 的核心概念:使用指令定义智能体、使用工具增强智能体的能力,以及将智能体编排为强大的工作流。
后续操作
- 探索官方 ADK for Java GitHub 代码库。
- 如需详细了解该框架,请参阅其文档。
- 阅读此博客系列,了解各种智能体工作流以及可用的各种工具。
- 深入了解其他内置工具和高级回调。
- 处理上下文、状态和制品,以实现更丰富、更具多模态的互动。
- 实现并应用可插入代理生命周期的插件。
- 不妨尝试构建自己的智能体,解决现实世界中的问题!