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 Google Cloud Platform hizmet şartları gösterilir. Devam etmek için bu şartları kabul etmeniz gerekir.
- 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ını 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_KEY
adlı 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 ADK for Java 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 diğer benzer 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 temsilci 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. Aracılara araçlarla güç verme
Temsilciler neden araçlara ihtiyaç duyar? LLM'ler güçlü olsa da bilgileri zaman içinde değişmez ve dış dünyayla etkileşim kuramazlar. 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önteminize 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öntemin ne zaman ve nasıl çağrılması gerektiğini belirlemek için kullanılacağından, hem yöntemin hem de parametrelerinin name
ve description
değerlerinin @Schema
ek açıklaması aracılığıyla belirtilmesi ö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, sonuçları temsil eden bir anahtara sahip bir harita (ör. stock_price
) döndürmek ve hisse senedi fiyatının değerini bu anahtarla ilişkilendirmek amaçlanır. 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 şu değer 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. Güncel bilgiler için Google Arama'nın gücü
Java için ADK, GoogleSearchTool
gibi 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. Arama motorunun yardımıyla hafızalarını tazeleyebilir ya da konu hakkında daha fazla bilgi edinebilirler.
Ş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 de 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, netlik veya odak gibi farklı sonuçlar isteyebilirsiniz.
Kod Adımı: Araç olarak Arama Temsilcisi
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
Temsilci, sıradan soruları kendi bilgi tabanından yanıtlar. Ancak son olaylarla ilgili sorular sorulduğunda, 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ıyla açıklanan büyük bir istem verilen veya çok sayıda işleve erişimi olan LLM'ler zorlanır, performansları ve 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 özel aracılarla birlikte gelir:
- Görevleri devretmek için
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 gerçek gücün aslında 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 ve ç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 kullanım alanını ele alacağız.
// 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()
);
}
}
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 şu 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önetimine benzer. İyi bir yönetici (gözetmen aracı), uzmanlığı daha yüksek olan belirli görevleri yerine getirmek 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 genel 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, önce İngilizce yazdığı şiirleri Fransızcaya çevirmek için İngilizce-Fransızca çeviri yapan bir çevirmenle işbirliği yaptığını 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 da tek bir genel amaçlı aracı kullanmaya kıyasla başarılı bir sonuç elde etme olasılığını önemli ölçüde artırır.
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 büyük bir verimlilik artışı sağlar. 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 LoopAgent
karakterini kullanan kod iyileştirme örneği, kod iyileştirmeyi otomatikleştirir: oluştur, incele, düzelt. Bu, insan gelişimini taklit eder. Kod üretici, ö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 (ör. kod oluşturma, yaratıcı yazma, tasarım yineleme veya karmaşık veri analizi) için faydalıdır. Çı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.