1. Добро пожаловать, разработчики ИИ-агентов!
В этой лабораторной работе вы научитесь создавать агентов ИИ на Java с помощью Agents Development Kit (ADK) для Java . Мы выйдем за рамки простых вызовов API LLM и создадим автономных агентов ИИ, которые смогут рассуждать, планировать, использовать инструменты и работать сообща для решения сложных задач.
Вы начнете с погашения кредитов Google Cloud, настройки своей среды Google Cloud, затем создадите своего первого простого агента и постепенно добавите более продвинутые возможности, такие как пользовательские инструменты, веб-поиск и многоагентная оркестровка.

Чему вы научитесь
- Как создать простого ИИ-агента, управляемого личностью.
- Как предоставить агентам специальные и встроенные инструменты (например, Google Search).
- Как добавить собственные инструменты, реализованные на Java.
- Как объединить несколько агентов в мощные последовательные, параллельные и циклические рабочие процессы.
Что вам понадобится
- Веб-браузер, который мы будем использовать в режиме инкогнито.
- Личный аккаунт Gmail.
- Новый проект Google Cloud, связанный с вашим личным аккаунтом Gmail.
- Платежный аккаунт, созданный с использованием погашенных кредитов Google Cloud.
- Инструмент командной строки git для проверки исходного кода.
- Java 17+ и Apache Maven.
- Текстовый редактор или IDE, например IntelliJ IDEA или VS Code.
Встроенный редактор VS Code можно использовать в Cloud Shell, в консоли Google Cloud.
2. Настройка: ваша среда
Получение кредитов Google Cloud для участия в семинаре

За участие в семинаре под руководством инструктора вы получите ссылку на веб-сайт, где вы сможете запросить облачные кредиты Google для использования во время семинара.
- Используйте личную учетную запись Google : важно использовать личную учетную запись Google (например, адрес gmail.com), так как корпоративные или школьные адреса электронной почты не подойдут .
- Используйте Google Chrome в режиме инкогнито : это рекомендуется для создания чистого сеанса и предотвращения конфликтов с другими учетными записями Google.
- Используйте специальную ссылку на событие : следует использовать специальную ссылку на событие, которая выглядит примерно так: https://trygcp.dev/event/xxx, за которой следует код события (в данном примере «xxx»).
- Примите условия обслуживания : после входа в систему вам будут представлены условия обслуживания Google Cloud Platform, которые вам необходимо принять для продолжения.
- Создайте новый проект : необходимо создать новый пустой проект из Google Cloud Console .
- Привязать платежный аккаунт : привязать недавно созданный проект к платежному аккаунту.
- Подтверждение кредита : в следующем видео показано, как подтвердить, что кредит применен к проекту, проверив раздел «Кредиты» на странице выставления счетов.
Не забудьте посмотреть это видео , в котором объясняется, как использовать и использовать кредиты.
Создайте и настройте свой ключ API
Для аутентификации ваших агентов ADK AI с API Gemini для этой лабораторной работы вам понадобится ключ API, связанный с вашим проектом Google Cloud.
- Сгенерируйте ключ API:
- Перейдите в Google AI Studio и нажмите ссылку «Получить ключ API» в нижней части левой панели.
- Выберите Проекты , а затем нажмите кнопку Импорт проектов .
- Найдите и выберите проект Google Cloud, который вы хотите импортировать, затем нажмите кнопку Импорт .
- После импорта проекта перейдите на страницу «Ключи API» из меню панели инструментов и создайте ключ API в только что импортированном проекте.
- Запишите ключ API .
- Установите переменную среды: вашему агенту необходим доступ к этому ключу. Стандартный способ — установить переменную среды с именем
GOOGLE_API_KEY.
- macOS / Linux: Откройте терминал и выполните следующую команду, заменив
"your-api-key"на только что скопированный ключ. Чтобы сделать это постоянным, добавьте эту строку в файл запуска вашей оболочки (например,~/.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, убедитесь, что вы можете скомпилировать код в этом проекте с помощью:
mvn compile
Шаг кода: дружелюбный агент учителя естественных наук
Базовым строительным блоком ADK является класс LlmAgent . Представьте его как ИИ с определённой личностью и целью, управляемый большой языковой моделью. Позже мы добавим дополнительные возможности с помощью инструментов и сделаем его ещё мощнее, тесно взаимодействуя с другими подобными агентами.
Давайте создадим новый класс Java в пакете com.example.agent и назовем его ScienceTeacher .
Это «Привет, мир!» в создании агента. Мы создаём простого агента в образе учителя естественных наук.
// 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()
);
}
}
ИИ-агент настраивается с помощью метода 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 необходимы класс и имя метода, указывающие на ваш собственный статический метод. Также можно передать экземпляр класса и имя метода экземпляра этого объекта.
Важно указать name и description как метода, так и его параметров с помощью аннотации @Schema , поскольку эта информация будет использоваться базовой LLM для определения того, когда и как следует вызывать данный метод.
Не менее важно помочь LLM, дав чёткие инструкции о том, как и когда использовать инструмент. Модель, возможно, разберётся в этом сама, но если вы дадите подробные объяснения в методе instruction() , ваша функция будет вызываться правильно, то вероятность её вызова повысится.
Этот метод должен возвращать Map . Обычно идея заключается в том, чтобы вернуть карту с ключом, представляющим результат, например, stock_price , и связать с ним значение цены акций. В конечном итоге можно добавить дополнительную пару ключей «успех/истина» для подтверждения успешного выполнения операции. В случае ошибки следует вернуть карту с ключом, например, 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 для получения актуальной информации

ADK для Java включает в себя ряд мощных инструментов, среди которых — GoogleSearchTool . С помощью этого инструмента ваш агент может запросить использование Google Search для поиска релевантной информации и достижения своей цели.
Действительно, знания 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()) . Это позволяет нашему агенту быстро получать доступ к последней информации, которую можно найти в интернете. Кроме того, в подсказке указана дата, которая может помочь магистрам права понять, когда вопросы касаются информации из прошлого, а требуется поиск более актуальной информации.
Затем запустите этот класс с помощью следующей команды:
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. Освоение агентских рабочих процессов
Для решения сложных задач одного агента недостаточно. Когда перед студентами ставят цель, состоящую из слишком большого количества подзадач, с обширным подсказкой, объясняющей слишком много деталей, или с доступом к огромному количеству функций, они испытывают трудности, а их производительность и точность снижаются.
Ключ к успеху — принцип «разделяй и властвуй», основанный на использовании нескольких специализированных агентов. К счастью, ADK включает в себя несколько встроенных специализированных агентов:
- Обычный агент с
subAgent()для делегирования задач, -
SequentialAgent, для выполнения задач в определенной последовательности, -
ParallelAgent, для параллельного выполнения агентов, -
LoopAgent, обычно для прохождения процесса уточнения столько раз, сколько необходимо.
Каковы основные варианты использования, а также плюсы и минусы каждого рабочего процесса? Взгляните на таблицу ниже. Но знайте, что настоящий эффект достигается при сочетании нескольких из них!
Рабочий процесс | Класс АДК | Вариант использования | Плюсы | Минусы |
Субагенты | | Управляемые пользователем гибкие задачи, где следующий шаг не всегда известен. | Высокая гибкость, диалоговый подход, отлично подходит для ботов, взаимодействующих с пользователем. | Менее предсказуем, полагается на рассуждения LLM для управления потоком. |
Последовательный | | Фиксированные, многоэтапные процессы, в которых порядок имеет решающее значение. | Предсказуемый, надежный, легко отлаживаемый, гарантирует порядок. | Негибкий, может работать медленнее, если задачи можно распараллелить. |
Параллельный | | Сбор данных из нескольких источников или выполнение независимых задач. | Высокая эффективность, значительно сокращает задержку для задач, связанных с вводом-выводом. | Все задачи выполняются; без коротких замыканий. Менее подходит для задач с зависимостями. |
Петля | | Итеративное уточнение, самокоррекция или процессы, которые повторяются до тех пор, пока не будет выполнено условие. | Эффективен для комплексного решения проблем, позволяет агентам улучшить свою работу. | Может привести к бесконечным циклам, если проект не был тщательно спроектирован (всегда используйте 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 orderAgent = 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 afterSaleAgent = 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 to 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(afterSaleAgent, orderAgent)
.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. Поздравляем!
Вы успешно создали и исследовали различные ИИ-агенты, от простых диалоговых агентов до сложных многоагентных систем. Вы изучили основные концепции ADK для Java: определение агентов с помощью инструкций, предоставление им инструментов и организация их в мощные рабочие процессы.
Что дальше?
- Изучите официальный репозиторий ADK для Java на GitHub .
- Дополнительную информацию о фреймворке можно найти в его документации .
- Узнайте в этой серии блогов о различных рабочих процессах агентов и о различных доступных инструментах .
- Изучите подробнее другие встроенные инструменты и расширенные обратные вызовы.
- Управляйте контекстом, состоянием и артефактами для более содержательного и мультимодального взаимодействия.
- Внедряйте и применяйте плагины, которые подключаются к жизненному циклу ваших агентов.
- Попробуйте создать собственного агента, решающего реальную проблему!