1. Merhaba, yapay zeka temsilci geliştiricileri!
Bu codelab'de, Java için Agents Development Kit (ADK)'yi kullanarak Java'da yapay zeka aracı oluşturmayı öğreneceksiniz. Basit Büyük Dil Modeli (LLM) API çağrılarının ötesine geçerek karmaşık sorunları çözmek için akıl yürütebilen, plan yapabilen, araçları kullanabilen ve birlikte çalışabilen bağımsız yapay zeka aracıları oluşturacağız.
Öncelikle Google Cloud kredilerini kullanacak, Google Cloud ortamınızı kuracak, ardından ilk basit aracınızı oluşturacak ve özel araçlar, web araması ve çoklu aracı düzenleme gibi daha gelişmiş özellikleri kademeli olarak ekleyeceksiniz.

Neler öğreneceksiniz?
- Temel, karaktere dayalı bir yapay zeka aracısı oluşturma
- Temsilcileri özel ve yerleşik araçlarla (ör. Google Arama) güçlendirme
- Java'da uygulanan kendi araçlarınızı ekleme
- Birden fazla aracıyı güçlü sıralı, paralel ve döngüsel iş akışları halinde düzenleme
İhtiyacınız olanlar
- Gizli modda kullanacağımız bir web tarayıcısı.
- Kişisel bir Gmail hesabı
- Kişisel Gmail hesabınızla ilişkili yeni bir Google Cloud projesi.
- Kullanılan Google Cloud kredileriyle oluşturulmuş bir faturalandırma hesabı.
- Kaynak kodu incelemek için kullanılan git komut satırı aracı.
- Java 17+ ve Apache Maven.
- IntelliJ IDEA veya VS Code gibi bir metin düzenleyici ya da IDE.
Google Cloud Console'daki Cloud Shell'de yerleşik VS Code düzenleyiciyi kullanabilirsiniz.
2. Kurulum: Ortamınız
Çalıştay için Google Cloud kredilerini kullanma

Eğitmen yönetiminde bir atölye çalışmasına katıldıysanız atölye çalışmasında kullanmak üzere Google Cloud kredisi talep edebileceğiniz web sitesinin bağlantısını almış olmanız gerekir.
- Kişisel bir Google Hesabı kullanın: Kurumsal veya okul e-posta adresleri çalışmayacağından kişisel bir Google Hesabı (ör. gmail.com adresi) kullanmanız önemlidir.
- Google Chrome'u gizli modda kullanın: Temiz bir oturum oluşturmak ve diğer Google Hesaplarıyla çakışmaları önlemek için bu yöntem önerilir.
- Özel etkinlik bağlantısını kullanın: Etkinlik için özel bir bağlantı (ör. https://trygcp.dev/event/xxx) ve ardından bir etkinlik kodu (bu örnekte "xxx") kullanılmalıdır.
- Hizmet şartlarını kabul etme: Oturum açtıktan sonra, devam etmek için kabul etmeniz gereken Google Cloud Platform hizmet şartları gösterilir.
- Yeni proje oluşturma: Google Cloud Console'da yeni ve boş bir proje oluşturulmalıdır.
- Faturalandırma hesabı bağlama: Yeni oluşturulan projeyi bir faturalandırma hesabına bağlayın.
- Krediyi onaylama: Aşağıdaki videoda, faturalandırma sayfasındaki "krediler" bölümünü kontrol ederek kredinin projeye uygulandığını nasıl onaylayacağınız gösterilmektedir.
Kredileri nasıl kullanacağınızı ve uygulayacağınızı açıklayan bu videoyu inceleyebilirsiniz.
API Anahtarınızı Oluşturma ve Yapılandırma
Bu codelab'de ADK yapay zeka aracılarınızın kimliğini Gemini API ile doğrulamak için Google Cloud projenizle ilişkili bir API anahtarı kullanacaksınız.
- API anahtarı oluşturma:
- Google AI Studio'ya gidin ve sol taraftaki panelin en altındaki "API anahtarı al" bağlantısını tıklayın.
- Projeler'i seçin ve Projeleri içe aktar düğmesini tıklayın.
- İçe aktarmak istediğiniz Google Cloud projesini arayıp seçin, ardından İçe aktar düğmesini seçin.
- Proje içe aktarıldıktan sonra Kontrol Paneli menüsünden API Anahtarları sayfasına gidin ve az önce içe aktardığınız projede bir API anahtarı oluşturun.
- API anahtarını not edin.
- Ortam değişkenini ayarlayın: Aracınızın bu anahtara erişmesi gerekir. Standart yöntem,
GOOGLE_API_KEYadlı bir ortam değişkeni ayarlamaktır.
- macOS / Linux: Terminalinizi açın ve aşağıdaki komutu çalıştırın.
"your-api-key"ifadesini az önce kopyaladığınız anahtarla değiştirin. Bunu kalıcı hale getirmek için bu satırı kabuğunuzun başlangıç dosyasına (ör.~/.bash_profile,~/.zshrc).
export GOOGLE_API_KEY="your-api-key"
- Windows (Komut İstemi): Yeni bir komut istemi açın ve şu komutu çalıştırın:
setx GOOGLE_API_KEY "your-api-key"
- Bu değişikliğin geçerli olması için komut istemini yeniden başlatmanız gerekir.
- Windows (PowerShell): PowerShell terminalini açıp şunu çalıştırın:
$env:GOOGLE_API_KEY="your-api-key"
- Bu değişikliği PowerShell'de kalıcı hale getirmek için profil komut dosyanıza eklemeniz gerekir.
3. Başlangıç: İlk Temsilciniz

Yeni bir projeye başlamanın en iyi yolu Java için ADK GitHub şablonunu kullanmaktır. Proje yapısını ve gerekli tüm bağımlılıkları sağlar.
GitHub hesabınız varsa şunları yapabilirsiniz: Use this template > Create a new repository, ardından git clone komutuyla kodu yerel olarak kontrol edin.
Şablonu kullanmak için sağ üstteki menüyü gösteren ekran görüntüsünü aşağıda bulabilirsiniz.

Diğer yaklaşım ise bu depoyu doğrudan klonlamaktır:
git clone https://github.com/glaforge/adk-java-maven-template.git
Ardından cd aracını adk-java-maven-template içine yerleştirin.
Java'da ilk yapay zeka aracınızı kodlamaya başlamaya hazır olduğunuzu kontrol etmek için bu projedeki kodu aşağıdakilerle derleyebildiğinizden emin olun:
mvn compile
Code Step: A Friendly Science Teacher Agent
ADK'daki temel yapı taşı LlmAgent sınıfıdır. Bunu, Büyük Dil Modeli tarafından desteklenen, belirli bir kişiliğe ve amaca sahip bir yapay zeka olarak düşünebilirsiniz. Daha sonra araçlar aracılığıyla daha fazla özellik ekleyecek ve benzer diğer temsilcilerle birlikte çalışarak daha güçlü hale getireceğiz.
com.example.agent paketinde yeni bir Java sınıfı oluşturalım ve buna ScienceTeacher adını verelim.
Bu, "Merhaba Dünya!" ifadesinin aracı oluşturma bağlamındaki karşılığıdır. Bilim öğretmeni kişiliğine sahip basit bir aracı tanımlıyoruz.
// 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()
);
}
}
Yapay zeka aracısı, LlmAgent.builder() yöntemiyle yapılandırılır. name(), description() ve model() parametreleri zorunludur. Aracınıza belirli bir kişilik ve uygun davranış kazandırmak için instruction() yöntemiyle her zaman ayrıntılı talimatlar vermelisiniz.
Burada Gemini 2.5 Flash modelini kullanmayı tercih ettik ancak daha karmaşık görevler için Gemini 2.5 Pro'yu da deneyebilirsiniz.
Bu temsilci, AdkWebServer.start() yöntemiyle sarmalanmıştır. Bu, ADK Dev UI adlı sohbet arayüzüdür. Bu sayede, temsilciyle normal bir sohbet arayüzü üzerinden konuşabilirsiniz. Ayrıca, sistemden geçen tüm etkinlikler, LLM'ye gönderilen istekler ve yanıtlar gibi arka planda neler olduğunu anlamak istiyorsanız bu araçtan büyük ölçüde yararlanabilirsiniz.
Bu aracıyı yerel olarak derleyip çalıştırmak için aşağıdaki komutu çalıştırın:
mvn compile exec:java -Dexec.mainClass=com.example.agent.ScienceTeacher
Ardından tarayıcınızda http://localhost:8080 adresine gidin. Kullanıcı arayüzünü aşağıdaki ekran görüntüsünde gösterildiği gibi görmelisiniz. Temsilcinize bilimle ilgili sorular sorun.

4. Temsilcilere araçlarla güç verme

Temsilciler neden araçlara ihtiyaç duyar? LLM'ler güçlüdür ancak bilgileri zaman içinde değişmez ve dış dünyayla etkileşimde bulunamazlar. Araçlar köprüdür. Bu işlevler, bir temsilcinin gerçek zamanlı bilgilere (ör. hisse senedi fiyatları veya haberler) erişmesine, özel API'leri sorgulamasına ya da Java'da kodlayabileceğiniz herhangi bir işlemi gerçekleştirmesine olanak tanır.
Kod Adımı: Özel Araç Oluşturma (StockTicker)
Burada, temsilcimize hisse senedi fiyatlarını arayabileceği bir araç veriyoruz. Aracı, kullanıcı fiyat istediğinde Java yöntemimizin çağrılması gerektiğini belirtiyor.
// 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)
}
}
Aracıları daha akıllı hale getirmek ve dünyayla (veya kendi kodunuz, API'leriniz, hizmetleriniz vb. ile) etkileşim kurmalarını sağlamak için aracı, tools() yöntemini kullanarak araçları ve özellikle özel kod araçlarını kullanacak şekilde yapılandırabilirsiniz. Bu yönteme FunctionTool.create(...) iletilir.
FunctionTool, kendi statik yönteminizi işaret eden bir sınıf ve yöntem adı gerektirir. Ayrıca bir sınıfın örneğini ve bu nesnenin bir örnek yönteminin adını da iletebilirsiniz.
Bu bilgiler, temel LLM tarafından belirli bir yöntemi ne zaman ve nasıl çağırması gerektiğini belirlemek için kullanılacağından, hem yöntemin hem de parametrelerinin name ve description değerlerini @Schema notuyla belirtmek önemlidir.
Aynı derecede önemli olan bir diğer nokta da LLM'ye aracı nasıl ve ne zaman kullanacağıyla ilgili net talimatlar vererek yardımcı olmaktır. Model bunu kendi başına da anlayabilir ancak instruction() yönteminde açık açıklamalar yaparsanız işlevinizin uygun şekilde çağrılma olasılığı daha yüksek olur.
Bu yöntem Map döndürmelidir. Genellikle amaç, sonucu temsil eden bir anahtara sahip bir harita (ör. stock_price) döndürmek ve hisse senedi fiyatının değerini bu anahtarla ilişkilendirmektir. Son olarak, işlemin başarısını belirtmek için ek bir başarı / doğru anahtar çifti ekleyebilirsiniz. Hata durumunda ise örneğin error adlı bir anahtara sahip bir harita döndürmeli ve hata mesajını ilişkili değerle ilişkilendirmelisiniz. Bu, LLM'nin çağrının başarılı olup olmadığını veya bir nedenden dolayı başarısız olup olmadığını anlamasına yardımcı olur.
- Başarılı olursa döndürülür:
{"stock_price": 123} - Hata durumunda döndürülecek değer:
{"error": "Impossible to retrieve stock price for XYZ"}
Ardından, aşağıdaki komutla bu sınıfı çalıştırın:
mvn compile exec:java -Dexec.mainClass=com.example.agent.StockTicker
5. Google Arama'nın güncel bilgiler için sunduğu avantajlar

Java için ADK, GoogleSearchTool dahil olmak üzere bir dizi güçlü araçla birlikte gelir. Bu araçla, temsilciniz hedefine ulaşmak için alakalı bilgiler bulmak üzere Google Arama'nın kullanılmasını isteyebilir.
Aslında, LLM'lerin bilgisi zaman içinde sabitlenir: Bilgilerin toplandığı zamanki kadar güncel olan verilerle belirli bir tarihe ("kesme tarihi") kadar eğitilir. Bu nedenle, LLM'ler son olaylar hakkında bilgi sahibi olmayabilir veya bilgileri sınırlı ve yüzeysel olabilir. Bir arama motorunun yardımıyla hafızalarını tazeleyebilir ya da konu hakkında daha fazla şey öğrenebilirler.
Şu basit haber arama aracısına göz atalım:
// 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());
}
}
Arama aracının bir örneğini tools(new GoogleSearchTool()) ile nasıl ilettiğimize dikkat edin. Bu, aracımızın web'de bulunan en son bilgilerden haberdar olmasını sağlar. Ayrıca, istemde günün tarihi belirtildi. Bu, soruların geçmiş bilgilerle ilgili olup olmadığını ve daha yeni bilgilerin aranmasının gerekip gerekmediğini anlamasına yardımcı olabilir.
Ardından, aşağıdaki komutla bu sınıfı çalıştırın:
mvn compile exec:java -Dexec.mainClass=com.example.agent.LatestNews
İstemi değiştirebilir, stil, özlük veya odak açısından farklı sonuçlar isteyebilirsiniz.
Kod Adımı: Araç olarak Arama Aracısı
GoogleSearchTool öğesini doğrudan bir araca aktarmak yerine, arama işlevini kapsayan özel bir arama aracısı oluşturabilir ve bu aracıyı daha üst düzey bir aracıya araç olarak sunabilirsiniz.
Bu, karmaşık davranışları (ör. arama yapma ve sonuçları özetleme) özel bir alt aracıya devretmenize olanak tanıyan gelişmiş bir kavramdır. Yerleşik araçlar, özel kod tabanlı araçlarla kullanılamadığından bu yaklaşım genellikle daha karmaşık iş akışları için faydalıdır.
// 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()
);
}
}
Buradaki temel kavram AgentTool.create(searchAgent) satırıdır. searchAgent'nın tamamını (kendi dahili mantığı, istemi ve araçlarıyla birlikte) mainAgent için tek bir çağrılabilir araç olarak kaydeder. Bu, modülerliği ve yeniden kullanılabilirliği teşvik eder.
Bu sınıfı aşağıdaki komutla çalıştırın:
mvn compile exec:java -Dexec.mainClass=com.example.agent.SearchAgentAsTool
Sıradan sorulara kendi bilgi tabanından yanıt veren temsilci, son olaylarla ilgili sorular sorulduğunda ise Google Arama aracını kullanarak aramayı uzman arama temsilcisine devreder.
6. Temsilci tabanlı iş akışlarında uzmanlaşma
Karmaşık sorunlar için tek bir temsilci yeterli değildir. Çok fazla alt görev içeren, çok fazla ayrıntı içeren büyük bir istemle açıklanan veya çok sayıda işleve erişimi olan bir hedef verildiğinde LLM'ler zorlanır ve performansları ile doğrulukları düşer.
Buradaki anahtar nokta, birden fazla uzmanlaşmış aracı düzenleyerek böl ve yönet stratejisini uygulamaktır. Neyse ki ADK, farklı yerleşik uzmanlaşmış aracılarla birlikte gelir:
- Görevleri devredecek
subAgent()ile normal temsilci, SequentialAgent, görevleri sırayla yapmak için,ParallelAgent, aracıları paralel olarak yürütmek içinLoopAgent, genellikle gerektiği kadar çok kez iyileştirme sürecinden geçmek için kullanılır.
Temel kullanım alanları ve her iş akışının avantajları ile dezavantajları için lütfen aşağıdaki tabloya göz atın. Ancak asıl gücün, bunların birkaçının birleşiminden geleceğini unutmayın.
İş akışı (Workflow) | ADK Class | Kullanım Alanı | Artıları | Eksileri |
Alt Temsilciler |
| Bir sonraki adımın her zaman bilinmediği, kullanıcı odaklı ve esnek görevler. | Yüksek esneklik, sohbet edilebilir, kullanıcıya yönelik botlar için idealdir. | Daha az tahmin edilebilir, akış kontrolü için LLM muhakemesine dayanır. |
Sıralı |
| Sıranın önemli olduğu sabit, çok adımlı süreçler. | Öngörülebilir, güvenilir, hata ayıklaması kolay, sırayı garanti eder. | Esnek değildir, görevler paralelleştirilebiliyorsa daha yavaş olabilir. |
Paralel |
| Birden fazla kaynaktan veri toplama veya bağımsız görevler çalıştırma | Son derece verimlidir ve G/Ç'ye bağlı görevlerde gecikmeyi önemli ölçüde azaltır. | Tüm görevler çalışır, kısa devre olmaz. Bağımlılıkları olan görevler için daha az uygundur. |
Döngü |
| İterasyonlu iyileştirme, kendi kendini düzeltme veya bir koşul karşılanana kadar tekrarlanan süreçler. | Karmaşık sorunları çözmek için güçlüdür ve temsilcilerin kendi çalışmalarını iyileştirmesini sağlar. | Dikkatli tasarlanmazsa sonsuz döngülere yol açabilir (her zaman maxIterations kullanılmalıdır). |
7. Temsilci tabanlı iş akışları: Alt temsilcilerle görevlendirme

Bir yönetici temsilci, belirli görevleri alt temsilcilere devredebilir. Örneğin, siparişle ilgili soruları bir temsilciye ("Siparişimin durumu nedir?"), satış sonrası hizmet sorularını ise başka bir temsilciye ("Nasıl açacağımı bilmiyorum!") yönlendiren bir e-ticaret web sitesinin temsilcisini düşünün. Bu, ele alacağımız kullanım alanıdır.
// 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()
);
}
}
Buradaki önemli nokta, subAgents() yönteminin çağrıldığı ve her birinin belirli rolünün ayrı ayrı ele alınacağı iki alt aracının iletildiği yerdir.
Yukarıdaki örneği aşağıdaki komutla çalıştırın:
mvn compile exec:java -Dexec.mainClass=com.example.agent.SupportAgent
Görevleri alt aracılara devretme kavramı, etkili insan yönetimiyle benzerlik gösterir. İyi bir yönetici (gözetmen aracı), uzmanlığı daha yüksek olan belirli görevleri yerine getirmeleri için uzmanlaşmış çalışanlara (alt aracılar) güvenir. Yöneticinin her sürecin ayrıntılarını bilmesi gerekmez. Bunun yerine, müşterinin talebini (ör. sipariş sorgusu veya teknik sorun) en nitelikli "ekip üyesine" akıllıca yönlendirerek tek bir uzmanın tek başına sağlayabileceğinden daha kaliteli ve verimli bir yanıt verilmesini sağlar. Ayrıca bu alt aracılar, karmaşık ve kapsamlı sürecin tamamını anlamalarına gerek kalmadan kendi görevlerine tamamen odaklanabilir.
8. Temsilci tabanlı iş akışları: Üretim hattı

İşlem sırasının önemli olduğu durumlarda SequentialAgent kullanın. Bu, her adımın bir öncekine bağlı olabileceği, alt aracıları sabit bir sırada yürüten bir montaj hattına benzer.
İngilizce şiirler yazan bir şairin, İngilizce-Fransızca çeviri yapan bir çevirmenle işbirliği yaparak önce İngilizce şiirler yazdığını, ardından bunları Fransızcaya çevirdiğini düşünelim:
// 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());
}
}
Aşağıdaki komutla örneği çalıştırarak önce İngilizce, ardından Fransızca çevrilmiş bir şiir alın:
mvn compile exec:java -Dexec.mainClass=com.example.agent.PoetAndTranslator
Karmaşık görevlerin daha küçük ve sıralı alt görevlere ayrılması, daha belirleyici ve güvenilir bir süreç sağlar. Bu sayede, tek bir genel amaçlı aracı kullanmaya kıyasla başarılı bir sonuç elde etme olasılığı önemli ölçüde artar.
Bir görevi alt görevler dizisine etkili bir şekilde ayırmak (mümkün olduğunda ve mantıklı olduğunda), daha belirleyici ve başarılı sonuçlar elde etmek için çok önemlidir. Çünkü bu, adımlar arasında yapılandırılmış ilerleme ve bağımlılık yönetimine olanak tanır.
9. Temsilci tabanlı iş akışları: Paralel çalışma

Görevler birbirinden bağımsız olduğunda ParallelAgent, görevleri aynı anda çalıştırarak verimliliği büyük ölçüde artırır. Aşağıdaki örnekte, SequentialAgent ile ParallelAgent'yi bile birleştiriyoruz: Önce paralel görevler çalıştırılıyor, ardından nihai bir aracı paralel görevlerin sonucunu özetliyor.
Şu konularda bilgi arayacak bir şirket dedektifi oluşturalım:
- Şirketin profili (CEO, genel merkez, slogan vb.)
- Şirketle ilgili en son haberler.
- Şirketin mali durumuyla ilgili ayrıntılar.
// 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());
}
}
Aracıyı her zamanki gibi aşağıdaki komutla çalıştırabilirsiniz:
mvn compile exec:java -Dexec.mainClass=com.example.agent.CompanyDetective
Bu aracı, hem paralel hem de sıralı aracıların iyi bir şekilde kullanıldığı, güçlü bir iş akışı kombinasyonunu gösterir. Bilgi araştırması ve sentezinin paralelleştirilmesi sayesinde verimli bir şekilde çalışır.
10. Temsilci tabanlı iş akışları: Yinelemeli iyileştirme

"Oluştur → incele → iyileştir" döngüsü gerektiren görevler için LoopAgent kullanın. Bir hedef karşılanana kadar yinelemeli iyileştirmeyi otomatikleştirir. SequentialAgent'ya benzer şekilde, LoopAgent alt aracıları sırayla çağırır ancak başlangıca geri döner. Döngünün yürütülmesini durdurmak için exit_loop yerleşik aracına çağrı isteğinde bulunulup bulunulmayacağına karar verecek olan, temsilci tarafından dahili olarak kullanılan LLM'dir.
Aşağıdaki kod iyileştirme örneğinde LoopAgent kullanılarak kod iyileştirme işlemi (oluşturma, inceleme, düzeltme) otomatikleştirilir. Bu, insan gelişimini taklit eder. Kod oluşturucu, önce istenen kodu oluşturur ve generated_code anahtarı altında aracı durumuna kaydeder. Ardından bir kod inceleyici, oluşturulan kodu inceler ve feedback tuşu altında geri bildirim sağlar veya yinelemeyi erken sonlandırmak için bir çıkış döngüsü aracı çağırır.
Koda göz atalım:
// 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());
}
}
Bu aracı aşağıdaki komutla çalıştırın:
mvn compile exec:java -Dexec.mainClass=com.example.agent.CodeRefiner
LoopAgent kullanılarak uygulanan geri bildirim/iyileştirme döngüleri, yinelemeli iyileştirme ve kendi kendini düzeltme gerektiren sorunları çözmek için vazgeçilmezdir. Bu döngüler, insan bilişsel süreçlerini yakından taklit eder. Bu tasarım kalıbı, özellikle ilk çıktının nadiren mükemmel olduğu görevler için faydalıdır. Örneğin, kod oluşturma, yaratıcı yazma, tasarım yineleme veya karmaşık veri analizi gibi görevlerde kullanılabilir. Çıkışı, yapılandırılmış geri bildirim sağlayan özel bir inceleme aracısı üzerinden geçirerek, oluşturma aracısı önceden tanımlanmış bir tamamlama ölçütü karşılanana kadar çalışmasını sürekli olarak iyileştirebilir. Bu da tek geçişli bir yaklaşıma kıyasla belirgin şekilde daha yüksek kaliteli ve daha güvenilir nihai sonuçlar elde edilmesini sağlar.
11. Tebrikler!
Basit sohbet edenlerden karmaşık, çoklu temsilci sistemlerine kadar çeşitli yapay zeka temsilcilerini başarıyla oluşturup incelediniz. Java için ADK'nın temel kavramlarını (talimatlarla aracı tanımlama, araçlarla aracı güçlendirme ve aracıları güçlü iş akışları oluşturacak şekilde düzenleme) öğrendiniz.
Sırada ne var?
- Resmi Java için ADK GitHub deposunu inceleyin.
- Çerçeve hakkında daha fazla bilgiyi belgelerinde bulabilirsiniz.
- Bu blog serisinde çeşitli agentic iş akışları ve kullanabileceğiniz çeşitli araçlar hakkında bilgi edinin.
- Diğer yerleşik araçlar ve gelişmiş geri aramalar hakkında daha ayrıntılı bilgi edinin.
- Daha zengin ve çok formatlı etkileşimler için bağlamı, durumu ve yapay nesneleri yönetin.
- Aracılarınızın yaşam döngüsüne bağlanan eklentileri uygulayın.
- Gerçek hayattaki bir sorunu çözen kendi temsilcinizi oluşturmayı deneyin.