Google Gemini ile Kendi Yapay Zeka Asistanınızı Kodlayın: Adım Adım Rehber
Google'ın en yeni yapay zeka modelleri (Gemini 3, Live API) ile çalışan gerçek bir "AI Agent" geliştirmek ister misiniz? Bu rehberde, DevFest Bursa için hazırlanan "Gemini Depo Asistanı" projesini baştan sona nasıl hayata geçireceğinizi anlatacağım.
Başlangıç şablonunda uygulamanın arayüzü ve temel mantığı (Kural Modu) halihazırda çalışmaktadır. Bizim görevimiz, boş bırakılan AI fonksiyonlarını doldurarak asistana "akıl" kazandırmaktır.
🛠️ Başlangıç
👉 Projeyi Kopyala ve Başla bağlantısına tıklayın.
Sağ üstteki "Copy App" butonuna basın, isim verin ve "Save" diyerek projeyi kendi çalışma alanınıza alın.
📚 Konu Anlatımı: Yapay Zeka Ajanları Nasıl Çalışır?
Kodlamaya başlamadan önce, inşa edeceğimiz sistemin arkasındaki temel kavramları ve mimariyi anlayalım.
1. AI Agent (Yapay Zeka Ajanı) Nedir?
Sıradan bir chatbot sadece metin üretir ve pasiftir. Ancak bir AI Agent:
Karar Verir: Kullanıcının niyetini anlar.
Eylem Yapar: Veritabanına bağlanır, sipariş verir.
Araç (Tool) Kullanır:
getStockgibi tanımladığımız fonksiyonları "elleri" gibi kullanır.
Bu projede Gemini'ı sadece sohbet eden bir bot olarak değil, depo veritabanına erişimi olan yetkili bir çalışan olarak kodlayacağız.
2. ReAct Mimarisi (Reasoning + Acting)
Ajanımız şu düşünce döngüsünü (Loop) izler:
Thought (Düşünce): "Kullanıcı stok sordu,
getStockaracını çağırmalıyım."Action (Eylem): Fonksiyonu çalıştırır.
Observation (Gözlem): Veritabanından gelen "150 adet" bilgisini görür.
Response (Yanıt): "Depoda 150 adet ürün var." diyerek kullanıcıya döner.
3. Mimari Notu: Client-Side vs. Server-Side
Bu atölyede hız ve prototipleme kolaylığı için Client-Side (SDK) kullanıyoruz.
⚠️ Uyarı: Gerçek bir prodüksiyon uygulamasında API anahtarlarınızı asla tarayıcıda saklamamalısınız.
✅ İdeal: Güvenli bir yapı için Firebase Genkit veya Node.js backend kullanarak Server-Side bir mimari kurmalısınız.
🟢 Adım 1: Araçları Tanımlama (aiService.ts)
AI Agent'ın dünyayla etkileşime geçebilmesi için ona "ellerini" yani araçlarını vermeliyiz.
services/aiService.ts dosyasında toolDeclarations dizisini ve initChatSession fonksiyonunu aşağıdaki gibi düzenleyin.
// Gerekli importlar: Type, GoogleGenAI
export const toolDeclarations = [
{
name: "getStock", // Fonksiyonun benzersiz adı
description: "Depodaki ürünlerin stok durumunu sorgular. Ürün adı belirtilmezse tüm stok listelenir.", // Modelin ne zaman kullanacağını anlaması için açıklama
parameters: {
type: Type.OBJECT,
properties: {
productName: {
type: Type.STRING,
description: "Stok durumu öğrenilmek istenen ürünün adı (Örn: Tişört, Rozet). Boş bırakılırsa hepsi listelenir."
}
}
}
},
{
name: "addStock",
description: "Depoya yeni ürün stoğu ekler.",
parameters: {
type: Type.OBJECT,
properties: {
productName: {
type: Type.STRING,
description: "Stoğu artırılacak ürünün adı."
},
quantity: {
type: Type.NUMBER,
description: "Eklenecek miktar (Sayısal değer)."
}
},
required: ["productName", "quantity"] // Zorunlu parametreler
}
}
];
export const initChatSession = async () => {
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
return ai.chats.create({
model: MODEL_NAME,
config: {
systemInstruction: SYSTEM_INSTRUCTION,
tools: [{ functionDeclarations: toolDeclarations }] // Tanımladığımız araçları modele veriyoruz
}
});
};
🟡 Adım 2: Karar Mekanizması (agentService.ts)
Ajanın "beyni" burasıdır. Model bir fonksiyon çağırmaya karar verdiğinde bu isteği yakalayıp işlemeli ve sonucu ona geri bildirmeliyiz. Bu döngü, görev tamamlanana kadar devam eder.
services/agentService.ts dosyasında runAgentWorkflow fonksiyonunu düzenleyin.
// Gerekli importlar: Chat, InventoryDB, processAction vb.
export const runAgentWorkflow = async (
text: string,
chat: Chat,
db: InventoryDB,
addMessage: (role: Message['role'], content: string, isTool?: boolean) => void,
updateInventory: (key: InventoryKey, qty: number) => void
) => {
try {
// 1. Kullanıcının mesajını modele gönder
let result = await chat.sendMessage({ message: text });
// 2. ReAct (Function Calling) Döngüsü
while (result.functionCalls && result.functionCalls.length > 0) {
const responseParts = [];
for (const call of result.functionCalls) {
// ACTION: İlgili aksiyonu gerçek veritabanında çalıştır
const actionResult = await processAction("AI", call.name, call.args, db, updateInventory, addMessage);
// OBSERVATION: Sonucu modele geri bildirmek için hazırla
responseParts.push({
functionResponse: {
name: call.name,
id: call.id,
response: { result: actionResult }
}
});
}
// REASONING: İşlem sonucunu modele gönder ve yeni yanıtı al
result = await chat.sendMessage({ message: responseParts });
}
// 4. Nihai Metin Cevabını Ekrana Yaz
if (result.text) {
addMessage('bot', result.text);
}
} catch (e) {
console.error("AI Workflow Error:", e);
addMessage('bot', "⚠️ AI işlemi sırasında bir hata oluştu.");
}
};
🟠 Adım 3: Canlı Ses Bağlantısı (liveService.ts)
Gemini Live API, metin tabanlı sohbetin ötesine geçerek WebSocket üzerinden ses akışı sağlar.
Düşük Gecikme (Low Latency): Gerçek bir insanla konuşur gibi hızlı tepkiler.
Kesintisiz Akış: Ses verisi PCM formatında anlık olarak akar.
services/liveService.ts dosyasında WebSocket bağlantısını kuran startLiveSession ve gelen mesajları işleyen handleServerMessage fonksiyonlarını doldurun.
// Session başlatma ve Audio Context kurulumu
async function startLiveSession(addMessage: any) {
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
// Tarayıcının ses motorunu (AudioContext) başlat
outputAudioContext = new (window.AudioContext || (window as any).webkitAudioContext)({ sampleRate: 24000 });
if (outputAudioContext.state === 'suspended') {
await outputAudioContext.resume();
}
// Live API'ye bağlan (WebSocket)
session = await ai.live.connect({
model: LIVE_MODEL_NAME,
config: {
responseModalities: [Modality.AUDIO], // Sesli cevap istiyoruz
speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: 'Kore' } } },
systemInstruction: LIVE_SYSTEM_INSTRUCTION,
tools: [{ functionDeclarations: toolDeclarations }] // Live modda da stok sorgulayabilmeli!
},
callbacks: {
onopen: () => console.log("WebSocket Açıldı"),
onmessage: (msg: LiveServerMessage) => handleServerMessage(msg, addMessage), // Mesaj gelince işle
onclose: () => console.log("WebSocket Kapandı"),
onerror: (err) => console.error("WebSocket Hatası:", err)
}
});
// Mikrofon akışını başlat ve PCM formatında modele gönder
audioCleanup = await setupAudioInput((base64PCM) => {
if(session) {
session.sendRealtimeInput({
media: { mimeType: "audio/pcm;rate=16000", data: base64PCM }
});
}
});
}
// Sunucudan gelen mesajları işleme (Ses veya Tool Call)
async function handleServerMessage(msg: LiveServerMessage, addMessage: any) {
const { serverContent, toolCall } = msg;
// 1. Modülden SES verisi geldiyse oynat
if (serverContent?.modelTurn?.parts?.[0]?.inlineData?.data) {
const base64Audio = serverContent.modelTurn.parts[0].inlineData.data;
await playAudioChunk(base64Audio);
}
// 2. Modülden Tool (Fonksiyon) çağrısı geldiyse çalıştır
if (toolCall && currentDb && currentUpdateFn) {
for (const fc of toolCall.functionCalls) {
const result = await processAction("AI", fc.name, fc.args, currentDb, currentUpdateFn, addMessage);
if (session) {
// Sonucu WebSocket üzerinden anında geri gönder
session.sendToolResponse({
functionResponses: [{
id: fc.id,
name: fc.name,
response: { result: result }
}]
});
}
}
}
}
🔴 Adım 4: Görsel Analiz ve Üretim (imageService.ts)
Burada iki farklı model bir "Pipeline" (Boru Hattı) mantığıyla çalışır: "Gör -> Anla -> Çiz".
Vision Model: Resmi analiz eder ve bir "Prompt" çıkarır.
Generation Model (Imagen): Bu prompt'u kullanarak yeni bir görsel yaratır.
services/imageService.ts dosyasında runImageAnalysis fonksiyonunu ekleyin.
export const runImageAnalysis = async (
base64Image: string,
userPrompt: string,
_chat: any,
addMessage: (role: Message['role'], content: string, isTool?: boolean, image?: string) => void
) => {
try {
const mimeType = base64Image.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/)?.[1] || "image/jpeg";
const cleanBase64 = base64Image.split(',')[1];
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
addMessage('bot', "📸 Fotoğrafın analiz ediliyor ve karakter tasarlanıyor...");
// 1. VISION: Önce resme bakıp prompt çıkarıyoruz
const visionResponse = await ai.models.generateContent({
model: VISION_MODEL_NAME,
contents: {
parts: [
{ text: IMAGE_SYSTEM_INSTRUCTION_TEMPLATE + "\n\nKullanıcı Notu: " + userPrompt },
{ inlineData: { mimeType: mimeType, data: cleanBase64 } } // Görsel verisi
]
}
});
const generatedPrompt = visionResponse.text;
if (!generatedPrompt) throw new Error("Prompt oluşturulamadı.");
addMessage('tool', `🎨 **Oluşturulan Prompt:**\n${generatedPrompt}`, true);
// 2. GENERATION: Çıkarılan prompt ile yeni görsel üretiyoruz (Imagen)
addMessage('bot', "🎨 Fırçalar hazırlanıyor, avatarın çiziliyor...");
const imageResponse = await ai.models.generateContent({
model: IMAGE_GENERATION_MODEL_NAME,
contents: { parts: [{ text: generatedPrompt }] }, // Vision'dan gelen metni buraya veriyoruz
config: { imageConfig: { aspectRatio: "1:1" } }
});
let generatedBase64 = null;
let resultMimeType = "image/png";
// Yanıttan görsel verisini ayıkla
if (imageResponse.candidates?.[0]?.content?.parts) {
for (const part of imageResponse.candidates[0].content.parts) {
if (part.inlineData) {
generatedBase64 = part.inlineData.data;
if (part.inlineData.mimeType) resultMimeType = part.inlineData.mimeType;
break;
}
}
}
if (generatedBase64) {
const finalImageUrl = `data:${resultMimeType};base64,${generatedBase64}`;
addMessage('bot', "İşte DevFest Bursa avatarın! 🚀", false, finalImageUrl);
} else {
addMessage('bot', "⚠️ Görsel üretilemedi.");
}
} catch (error: any) {
console.error("Hata:", error);
addMessage('bot', "⚠️ Avatar oluşturulurken bir hata oldu: " + error.message);
}
};
🔗 Referanslar ve İleri Okuma
Projede kullanılan teknolojiler ve ileri seviye kaynaklar için:
Gemini API Dokümantasyonu: Genel bakış ve başlangıç rehberleri.
Google AI Cookbook: Gemini API kullanımı için örnek kodlar ve şablonlar.
Firebase Genkit: Güvenli, üretim odaklı AI framework'ü (Server-Side gelişim için önerilir).
Project IDX: Google'ın yeni nesil, bulut tabanlı geliştirme ortamı.
DeepLearning.AI - AI Agent Courses: Andrew Ng'nin Ajanlar üzerine ücretsiz kursları.
Function Calling: Modelin dış araçları ve API'leri nasıl tetiklediğini öğrenin.
Live API: Gerçek zamanlı ses ve video etkileşimleri.

