TypeScript AI SDK Karşılaştırması: Agent Geliştirme için Vercel AI SDK vs OpenAI Agents SDK
Agent geliştirmek için TypeScript SDK karşılaştırması: Vercel AI SDK, OpenAI Agents SDK ve AWS Bedrock entegrasyonu, kod örnekleri ve karar frameworkleri ile.
TypeScript’te AI agent geliştirmeye başlarken ilk karar sıkıcı olanı: tool çağrılarını, streamingi ve provider kimlik bilgilerini hangi SDK taşıyacak. Üç cevap öne çıkıyor ve her biri farklı bir şeyi optimize ediyor. Vercel AI SDK, providera özgü yüzeyi taşınabilirlik karşılığında bırakıyor; OpenAI Agents SDK multi-agent orkestrasyonunu çalışma zamanına gömüyor; direkt provider SDK’leri ise her ayarı açıkta bırakıyor.
Çoğu TypeScript ve Next.js kod tabanında varsayılan Vercel AI SDK. Asıl soru bu varsayılanın nerede yetersiz kaldığı: yoğun multi-agent orkestrasyonu ve hiçbir soyutlamanın henüz açmadığı bir özelliğe ihtiyaç duyan tek providerlı servisler.
TypeScript AI SDK Ekosistemi#
Üçü de soyutlamayı farklı bir seviyeye yerleştiriyor:
- Vercel AI SDK: 70’den fazla provider desteği ile provider-agnostic birleşik arayüz
- OpenAI Agents SDK: Native handofflarla multi-agent sistemler için özel olarak tasarlanmış
- Direkt Provider SDK’leri: Providera özgü özelliklerle maksimum kontrol
Zorluk, gereksinimlerinizi doğru seviyeyle eşleştirmek.
Vercel AI SDK: Provider-Agnostic Yaklaşım#
Vercel AI SDK birleşik arayüz yaklaşımını benimsiyor. Bir kez yaz, herhangi bir providera deploy et. Bu esneklik, gereksinimler değiştiğinde veya güvenilirlik için fallback providerlara ihtiyaç duyduğunuzda önem kazanıyor.
Temel Mimari#
SDK, sorumlulukları temiz bir şekilde ayırıyor:
- AI SDK Core: Sunucu tarafı işlemleri (
generateText,streamText,generateObject) - AI SDK UI: Chat arayüzleri için React hookları (
useChat,useCompletion) - AI SDK RSC: React Server Components entegrasyonu
Zod ile Tool Tanımlama#
Toollar type-safe Zod şemalarıyla tanımlanıyor. SDK parametre doğrulamasını otomatik olarak yapıyor:
import { tool, generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
const weatherTool = tool({
description: 'Bir şehir için güncel hava durumunu getir',
parameters: z.object({
city: z.string().describe('Şehir adı'),
unit: z.enum(['celsius', 'fahrenheit']).default('celsius'),
}),
execute: async ({ city, unit }) => {
// API çağrınız burada
const response = await fetch(
`https://api.weather.example/v1/current?city=${city}&unit=${unit}`
);
return response.json();
},
});
const searchTool = tool({
description: 'Web üzerinde bilgi ara',
parameters: z.object({
query: z.string().describe('Arama sorgusu'),
limit: z.number().optional().default(5),
}),
execute: async ({ query, limit }) => {
// Arama implementasyonu
return { results: [`Sonuç: ${query}`], count: limit };
},
});
maxSteps ile Agent Döngüsü#
Çok turlu tool kullanımı için maxSteps parametresi otomatik tool çalıştırma döngüleri sağlıyor:
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o'),
messages,
system: 'Hava durumu ve arama yeteneklerine sahip yardımcı bir asistansın.',
tools: {
weather: weatherTool,
search: searchTool,
},
maxSteps: 5, // 5 tura kadar tool çalıştırmaya izin ver
});
return result.toDataStreamResponse();
}
SDK tüm döngüyü yönetiyor: LLM’i çağır, tool çağrılarını tespit et, toolları çalıştır, sonuçları ekle, tamamlanana veya maxSteps’e ulaşılana kadar tekrarla.
Provider Değiştirme Patternı#
Birleşik arayüzün karşılığını aldığı yer provider değiştirme. Aynı kod, farklı backend:
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
import { generateText } from 'ai';
// Providerları yapılandır
const bedrock = createAmazonBedrock({ region: 'us-east-1' });
// Provider kayıt defteri
const providers = {
'gpt-4o': openai('gpt-4o'),
'gpt-4o-mini': openai('gpt-4o-mini'),
'claude-sonnet': anthropic('claude-sonnet-4-6-20250217'),
'claude-haiku': anthropic('claude-haiku-4-5-20241022'),
'gemini-flash': google('gemini-2.5-flash'),
'bedrock-claude': bedrock('anthropic.claude-sonnet-4-6-20250217-v1:0'),
};
// Aynı fonksiyon herhangi bir provider ile çalışıyor
async function generate(prompt: string, providerId: keyof typeof providers) {
const { text, usage } = await generateText({
model: providers[providerId],
prompt,
});
return { text, usage };
}
// Değiştirmek çok basit
const openaiResult = await generate('Kuantum bilişimi açıkla', 'gpt-4o');
const claudeResult = await generate('Kuantum bilişimi açıkla', 'claude-sonnet');
React Entegrasyonu ile Streaming#
AI SDK UI, streaming karmaşıklığını yöneten hooklar sağlıyor:
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export const runtime = 'edge';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o'),
messages,
tools: {
calculate: tool({
description: 'Aritmetik işlem yap',
parameters: z.object({ expression: z.string() }),
execute: async ({ expression }) => {
// Productionda güvenli bir matematik parser kullanın
return { result: eval(expression) };
},
}),
},
maxSteps: 3,
});
return result.toDataStreamResponse();
}
// components/Chat.tsx
'use client';
import { useChat } from 'ai/react';
export function Chat() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
api: '/api/chat',
});
return (
<div className="flex flex-col h-screen">
<div className="flex-1 overflow-y-auto p-4">
{messages.map((m) => (
<div key={m.id} className={`mb-4 ${m.role === 'user' ? 'text-right' : ''}`}>
<span className="font-bold">{m.role}:</span> {m.content}
</div>
))}
</div>
<form onSubmit={handleSubmit} className="p-4 border-t">
<input
value={input}
onChange={handleInputChange}
disabled={isLoading}
className="w-full p-2 border rounded"
placeholder="Mesaj yazın..."
/>
</form>
</div>
);
}
OpenAI Agents SDK: Multi-Agent Uzmanı#
OpenAI’nin Agents SDK’si farklı bir yaklaşım benimsiyor. Provider soyutlaması yerine, agent orkestrasyon patternlerine odaklanıyor: uzman agentlar arası handofflar, doğrulama için guardraillar ve yerleşik tracing.
Temel Kavramlar#
SDK dört anahtar kavram sunuyor:
- Agentlar: Talimatlar, toollar ve handoff yeteneği olan LLM’ler
- Handofflar: Konuşma sahipliğini aktaran özel tool çağrıları
- Guardraillar: Agent çalıştırmasıyla paralel çalışan input/output doğrulaması
- Tracing: Yerleşik debug ve izleme
Handofflarla Multi-Agent#
Handoff patternı, birbirine devredebilen uzman agentları mümkün kılıyor:
import { Agent, run, tool } from '@openai/agents';
import { z } from 'zod';
// Uzman toolları tanımla
const getWeatherTool = tool({
name: 'get_weather',
description: 'Bir şehir için hava durumu getir',
parameters: z.object({
city: z.string(),
}),
execute: async ({ city }) => {
return `${city} hava durumu: 22C, güneşli`;
},
});
const searchDatabaseTool = tool({
name: 'search_database',
description: 'Dahili veritabanında ara',
parameters: z.object({
query: z.string(),
}),
execute: async ({ query }) => {
return `${query} için 3 sonuç bulundu`;
},
});
// Uzman agentlar oluştur
const weatherAgent = new Agent({
name: 'Hava Durumu Uzmanı',
instructions: 'Bir hava durumu uzmanısın. Detaylı hava bilgisi sağla.',
tools: [getWeatherTool],
handoffDescription: 'Hava durumuyla ilgili sorular için uzman',
});
const dataAgent = new Agent({
name: 'Veri Uzmanı',
instructions: 'Bir veri uzmanısın. Veritabanı bilgilerini ara ve analiz et.',
tools: [searchDatabaseTool],
handoffDescription: 'Veritabanı sorguları ve veri analizi için uzman',
});
// Handofflarla triaj agentı oluştur
const triageAgent = new Agent({
name: 'Triaj Agent',
instructions: `Soruları uzmanlara yönlendiren yardımcı bir asistansın.
- Hava durumu soruları için Hava Durumu Uzmanına devret
- Veri/veritabanı soruları için Veri Uzmanına devret
- Genel soruları doğrudan yanıtla`,
handoffs: [weatherAgent, dataAgent],
});
// Agent iş akışını çalıştır
async function handleQuery(userMessage: string) {
const result = await run(triageAgent, userMessage);
return {
finalOutput: result.finalOutput,
agentPath: result.history
.filter(h => h.type === 'handoff')
.map(h => h.agent),
};
}
Agent Döngüsü#
SDK sofistike bir çalıştırma döngüsünü yönetiyor:
Karmaşık Tool Şemaları#
SDK, otomatik doğrulamayla iç içe şemaları yönetiyor:
const createOrderTool = tool({
name: 'create_order',
description: 'Yeni bir müşteri siparişi oluştur',
parameters: z.object({
customerId: z.string().uuid(),
items: z.array(z.object({
productId: z.string(),
quantity: z.number().int().positive(),
price: z.number().positive(),
})),
shippingAddress: z.object({
street: z.string(),
city: z.string(),
country: z.string(),
postalCode: z.string(),
}),
priority: z.enum(['standard', 'express', 'overnight']).default('standard'),
}),
execute: async ({ customerId, items, shippingAddress, priority }) => {
const order = await orderService.create({
customerId,
items,
shippingAddress,
priority,
});
return {
orderId: order.id,
status: 'created',
estimatedDelivery: order.estimatedDelivery,
};
},
});
AWS Bedrock Entegrasyonu#
AWS altyapısına yatırım yapmış takımlar için Bedrock, IAM, VPC entegrasyonu ve uyumluluk kontrolleri gibi kurumsal özelliklerle birden fazla temel modele erişim sağlıyor.
Bedrock Provider ile AI SDK#
En temiz yaklaşım AI SDK’nin Bedrock providerını kullanıyor:
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
import { generateText, streamText } from 'ai';
const bedrock = createAmazonBedrock({
region: 'us-east-1',
// Varsayılan olarak AWS credential chain kullanır
});
// Bedrock üzerinden Claude
const claudeModel = bedrock('anthropic.claude-sonnet-4-6-20250217-v1:0');
// Bedrock üzerinden Llama
const llamaModel = bedrock('meta.llama3-70b-instruct-v1:0');
// Amazon Nova (multi-region kullanılabilirlik için cross-region inference ID kullan)
const novaModel = bedrock('amazon.nova-pro-v1:0');
// Alternatif: bedrock('us.amazon.nova-pro-v1:0') cross-region inference için
async function generateWithBedrock(prompt: string) {
const { text, usage } = await generateText({
model: claudeModel,
prompt,
maxTokens: 1024,
});
return { text, usage };
}
Lambda Entegrasyonu#
Bedrock, IAM role credentialları kullanarak Lambda ile doğal olarak çalışıyor:
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
import { generateText } from 'ai';
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
const bedrock = createAmazonBedrock({
region: process.env.AWS_REGION || 'us-east-1',
credentialProvider: fromNodeProviderChain(),
});
export const handler = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
const { prompt } = JSON.parse(event.body || '{}');
const { text } = await generateText({
model: bedrock('anthropic.claude-sonnet-4-6-20250217-v1:0'),
prompt,
});
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ response: text }),
};
};
Pratik Karşılaştırma#
Özellik Matrisi#
| Özellik | Vercel AI SDK | OpenAI Agents SDK | Direkt SDK’ler |
|---|---|---|---|
| Multi-Provider | 70+ provider | Adapter gerekli | Tek |
| Tool Calling | Birinci sınıf | Birinci sınıf | Providera özgü |
| Streaming | Yerleşik | Yerleşik | Providera özgü |
| Multi-Agent | Kompozisyon ile | Native handoff | Manuel |
| Edge Runtime | Tam destek | Kısmi | Değişken |
| React Entegrasyonu | Native hooklar | Manuel | Manuel |
| Type Safety | Tam TypeScript | Tam TypeScript | Değişken |
| Gözlemlenebilirlik | DevTools + OTEL | Yerleşik tracing | Manuel |
Kurulum Eforu#
İlk çalışan implementasyona ulaşmak için gereken göreli efor:
| Görev | AI SDK | OpenAI Agents | Direkt SDK |
|---|---|---|---|
| Temel chat | Düşük | Düşük | Orta |
| Streaming UI | Düşük | Orta | Yüksek |
| Tool calling | Düşük | Düşük | Orta |
| Multi-agent | Orta | Düşük | Yüksek |
| Provider değiştirme | Düşük | Orta | Yüksek |
Son satır, projenin ilerleyen dönemlerinde karşınıza çıkan satır. Birleşik bir API’de provider değiştirmek kayıt defterinde bir düzenleme; direkt SDK’lerde eklediğiniz her provider için çağrı katmanını yeniden yazmak demek.
Maliyet Tarafı#
Tüm SDK’ler ücretsiz. Maliyetler API kullanımından geliyor:
| Model | Provider | Input (1M başına) | Output (1M başına) |
|---|---|---|---|
| GPT-4o | OpenAI | $2.50 | $10.00 |
| GPT-4o-mini | OpenAI | $0.15 | $0.60 |
| Claude Sonnet 4.6 | Anthropic/Bedrock | $3.00 | $15.00 |
| Claude Haiku 4.5 | Anthropic/Bedrock | $1.00 | $5.00 |
| Llama 3.3 70B | Bedrock | $0.72 | $0.72 |
Karar Ağacı#
Doğru SDK, elinizdeki gereksinimlere göre değişiyor:
Vercel AI SDK Ne Zaman Uygun#
- Next.js veya React ile geliştiriyorsanız
- Birden fazla AI provider desteklemeniz gerekiyorsa
- Hazır streaming UI istiyorsanız
- Type-safe, birleşik API’ye değer veriyorsanız
- Edge runtime uyumluluğuna ihtiyacınız varsa
- Provider değiştirebilecek ürünler geliştiriyorsanız
OpenAI Agents SDK Ne Zaman Uygun#
- Karmaşık multi-agent sistemler geliştiriyorsanız
- Native handoff patternlerine ihtiyacınız varsa
- Yerleşik guardraillar istiyorsanız
- Açık tracing ve debug tercih ediyorsanız
- Çoğunlukla OpenAI modellerini kullanıyorsanız
- Python agent frameworklerinden geliyorsanız
Direkt SDK’ler Ne Zaman Uygun#
- Providera özgü özelliklere ihtiyacınız varsa
- Maksimum performans kritikse
- Tek provider ile basit kullanım senaryosu varsa
- Minimum bağımlılıklarla çalışmak istiyorsanız
- Başkaları için SDK veya kütüphane geliştiriyorsanız
AI SDK ile Bedrock Ne Zaman Uygun#
- AWS-native altyapı varsa
- Kurumsal güvenliğe ihtiyacınız varsa (VPC, IAM)
- Doğrudan Anthropic faturası olmadan Claude istiyorsanız
- Düzenlenmiş sektörler için geliştiriyorsanız
- Tek platformda model çeşitliliğine ihtiyacınız varsa
Production Patternleri#
Katmanlı Model Yönlendirme#
Model yeteneğini sorgu karmaşıklığına eşleştirin:
const modelTiers = {
simple: openai('gpt-4o-mini'),
standard: openai('gpt-4o'),
complex: anthropic('claude-sonnet-4-6-20250217'),
};
function classifyComplexity(input: string): keyof typeof modelTiers {
if (input.length < 50 && !input.includes('analiz')) return 'simple';
if (input.includes('karşılaştır') || input.includes('tasarla')) return 'complex';
return 'standard';
}
async function smartGenerate(input: string) {
const tier = classifyComplexity(input);
return generateText({ model: modelTiers[tier], prompt: input });
}
Bunun ne kadar tasarruf sağladığı tamamen trafik dağılımınıza bağlı. Bir sayı varsaymadan önce kısa, arama tipi sorguların payını ölçün.
Fallback Zinciri#
Yüksek kullanılabilirlik için birden fazla providerı zincirleyin:
const providerChain = [
openai('gpt-4o'),
anthropic('claude-sonnet-4-6-20250217'),
bedrock('anthropic.claude-sonnet-4-5-20250929-v1:0'),
];
async function generateWithFallback(prompt: string) {
for (const model of providerChain) {
try {
return await generateText({ model, prompt });
} catch (error) {
console.log(`Provider başarısız, sonrakini deniyorum: ${error.message}`);
continue;
}
}
throw new Error('Tüm providerlar başarısız oldu');
}
Gözlemlenebilirlik Kurulumu#
Productionda kritik metrikleri izleyin:
import { trace, SpanStatusCode } from '@opentelemetry/api';
const tracer = trace.getTracer('ai-agent');
async function generateWithTracing(prompt: string) {
return tracer.startActiveSpan('ai.generate', async (span) => {
try {
span.setAttributes({
'ai.model': 'gpt-4o',
'ai.prompt.length': prompt.length,
});
const { text, usage } = await generateText({
model: openai('gpt-4o'),
prompt,
});
span.setAttributes({
'ai.completion.tokens': usage.completionTokens,
'ai.prompt.tokens': usage.promptTokens,
'ai.total.tokens': usage.totalTokens,
});
span.setStatus({ code: SpanStatusCode.OK });
return { text, usage };
} catch (error) {
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
throw error;
} finally {
span.end();
}
});
}
Yaygın Tuzaklar#
Sınırsız Agent Döngüleri#
Adım limitleri olmadan agentlar süresiz çalışabilir:
// Problem: Sınır yok
const result = streamText({
model: openai('gpt-4'),
tools: myTools,
// maxSteps yok - sonsuza kadar dönebilir
});
// Çözüm: Her zaman limit belirle
const result = streamText({
model: openai('gpt-4'),
tools: myTools,
maxSteps: 10, // Açık sınır
});
Streamleri Bloklama#
Tam yanıtları beklemek streaming avantajlarını yok eder:
// Problem: Tamamlanana kadar bloklar
const result = await streamText({ model, prompt });
const fullText = await result.text;
return new Response(fullText);
// Çözüm: Streami ilet
const result = streamText({ model, prompt });
return result.toDataStreamResponse();
Context Limitlerini Görmezden Gelme#
Büyük konuşma geçmişleri context pencerelerini aşıyor:
// Problem: Sınırsız context
const messages = tumKonusmaGecmisi;
await generateText({ model, messages });
// Çözüm: Contexti aktif olarak yönet
const maxTokens = 100000;
const trimmedMessages = trimToFitContext(messages, maxTokens);
await generateText({ model, messages: trimmedMessages });
Varsayılan Nerede Geçerli#
Vercel AI SDK varsayılanı, agentınız toolların bağlandığı tek bir döngüden ibaret olduğu sürece geçerli; ürün işlerinin çoğu da böyle. Provider kayıt defteri, streaming taşıması ve React hookları tek pakette geldiği için provider değişikliği kayıt defterinde bir düzenleme olarak kalıyor.
İki durumda bundan sapın. Birkaç uzman agentın konuşmayı birbirine devretmesi gerekiyorsa OpenAI Agents SDK, elde yazılmış yönlendirme yerine handoff, guardrail ve tracing veriyor. Tek providera bağlıysanız ve hiçbir soyutlamanın henüz açmadığı bir yeteneğe ihtiyacınız varsa, o providerın kendi SDK’si bir wrapperla boğuşmaktan daha ucuza geliyor.
Her iki durumda da, agent soyutlamalarına bağlanmadan önce iki toollu bir generateText() çağrısı kurgunun işe yarayıp yaramadığını göstermeye yeter.
Kaynaklar#
- Vercel AI SDK Dokümantasyonu (yeni sekmede açılır) - Resmi AI SDK dokümantasyonu: Core, UI, RSC, providerlar ve streaming
- Vercel AI SDK: Agentlar (yeni sekmede açılır) - Agent döngüsü patternleri, tool calling ve çok adımlı orkestrasyon
- OpenAI Agents SDK (yeni sekmede açılır) - Handofflar ve guardraillarla multi-agent sistemler için OpenAI SDK’si
- Anthropic Client SDK’ları (yeni sekmede açılır) - Claude API entegrasyonu için resmi TypeScript SDK’si
- Vercel AI SDK: Tool Calling (yeni sekmede açılır) - AI SDK agentlarında tool tanımlama ve çalıştırma
İlgili yazılar
Middy'nin middleware kalıplarıyla Lambda geliştirmesini nasıl dönüştürdüğünü, tekrarlayan şablonlardan temiz, sürdürülebilir serverless fonksiyonlara geçişi keşfedin
lambda · middleware · serverless +5
Amazon SNS ve SQS ile güvenli cross-account event dağıtımı: IAM policy'leri, KMS şifreleme, AWS CDK kurulumu ve production'da karşılaşılan yaygın sorunlar.
aws · sns · sqs +6
Middy builder pattern, Zod validation, feature flags ve secrets management ile sürdürülebilir, type-safe Lambda middleware nasıl inşa edilir öğren.
lambda · middleware · typescript +7
AWS CDK, DynamoDB ve Lambda ile production-grade link kısaltıcı kurulumu. Mimari kararlar, proje yapısı ve ölçekte ayakta kalan şema seçimleri.
aws-cdk · lambda · dynamodb +5
Bir Lambda filosu Middy'nin statik middleware modelini ne zaman aşar, projeye özel bir motor istek başına konfigürasyonu nasıl çözer, bakımı neye mal olur
lambda · middleware · performance +6