OpenAI, .NET için resmi bir SDK yayınladı. Bu SDK; chat tamamlama, streaming, tool calling ve structured outputs gibi tüm temel özellikleri doğrudan ve tip güvenli bir şekilde kullanmanızı sağlar.
Kurulum
// dotnet add package OpenAI
using OpenAI.Chat;
var client = new ChatClient("gpt-4o", "sk-...");
Temel Chat Tamamlama
// Tek mesaj
var tamamlama = await client.CompleteChatAsync(
"C# record type'larının avantajları nelerdir?");
Console.WriteLine(tamamlama.Value.Content[0].Text);
// Sistem ve kullanıcı mesajları
var mesajlar = new List<ChatMessage>
{
new SystemChatMessage("Sen .NET uzmanı bir asistansın. Kısa ve net yanıtlar ver."),
new UserChatMessage("async/await nedir?"),
new AssistantChatMessage("async/await, .NET'te asenkron programlamayı kolaylaştıran C# keyword'leridir. Task döndüren metotları await ile bekletebilirsiniz."),
new UserChatMessage("ConfigureAwait(false) ne zaman kullanılır?")
};
var yanit = await client.CompleteChatAsync(mesajlar);
Console.WriteLine(yanit.Value.Content[0].Text);
Streaming ile Gerçek Zamanlı Yanıt
// Token token çıktı — uzun cevaplar için ideal
await foreach (var guncelleme in client.CompleteChatStreamingAsync(
"Dependency Injection pattern'ını tüm detaylarıyla açıkla"))
{
foreach (var parcalik in guncelleme.ContentUpdate)
Console.Write(parcalik.Text);
}
Console.WriteLine();
// ASP.NET Core'da streaming endpoint
app.MapPost("/api/chat", async (ChatRequest req, ChatClient chat) =>
{
var stream = chat.CompleteChatStreamingAsync(req.Message);
return Results.Extensions.SseStream(async (writer, ct) =>
{
await foreach (var update in stream.WithCancellation(ct))
foreach (var part in update.ContentUpdate)
if (part.Text is { Length: > 0 })
await writer.WriteAsync(part.Text);
});
});
Tool Calling: Fonksiyon Çağrısı
// Araç tanımı
var havaDurumuAraci = ChatTool.CreateFunctionTool(
functionName: "hava_durumu_getir",
functionDescription: "Belirtilen şehrin anlık hava durumunu getirir",
functionParameters: BinaryData.FromString("""
{
"type": "object",
"properties": {
"sehir": {
"type": "string",
"description": "Hava durumu sorgulanacak şehir"
},
"birim": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Sıcaklık birimi"
}
},
"required": ["sehir"]
}
"""));
var secenekler = new ChatCompletionOptions();
secenekler.Tools.Add(havaDurumuAraci);
var konusma = new List<ChatMessage>
{
new UserChatMessage("İstanbul'un hava durumu nasıl?")
};
var yanit = await client.CompleteChatAsync(konusma, secenekler);
// Model araç çağrısı yaptıysa
if (yanit.Value.FinishReason == ChatFinishReason.ToolCalls)
{
konusma.Add(new AssistantChatMessage(yanit.Value));
foreach (var aracCagrisi in yanit.Value.ToolCalls)
{
// JSON parametrelerini parse et
using var doc = JsonDocument.Parse(aracCagrisi.FunctionArguments);
var sehir = doc.RootElement.GetProperty("sehir").GetString();
// Gerçek API çağrısını simüle et
var havaVerisi = await HavaDurumuApiAsync(sehir!);
konusma.Add(new ToolChatMessage(aracCagrisi.Id, havaVerisi));
}
// Son yanıtı al
var sonYanit = await client.CompleteChatAsync(konusma, secenekler);
Console.WriteLine(sonYanit.Value.Content[0].Text);
}
Structured Outputs: JSON �?ema ile Tip Güvenli Çıktı
var jsonSecenekler = new ChatCompletionOptions
{
ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
jsonSchemaFormatName: "blog_ozeti",
jsonSchema: BinaryData.FromString("""
{
"type": "object",
"properties": {
"baslik": { "type": "string" },
"ozet": { "type": "string" },
"etiketler": { "type": "array", "items": { "type": "string" } },
"okumaSuresi": { "type": "integer" },
"zorlukSeviyesi": { "type": "string", "enum": ["baslangic", "orta", "ileri"] }
},
"required": ["baslik", "ozet", "etiketler", "okumaSuresi", "zorlukSeviyesi"],
"additionalProperties": false
}
"""),
jsonSchemaIsStrict: true)
};
var analizYanit = await client.CompleteChatAsync(
$"Bu blog yazısını analiz et:\n\n{blogIcerigi}",
jsonSecenekler);
var ozet = JsonSerializer.Deserialize<BlogOzeti>(
analizYanit.Value.Content[0].Text)!;
Console.WriteLine($"Başlık: {ozet.Baslik}");
Console.WriteLine($"Okuma süresi: {ozet.OkumaSuresi} dakika");
Console.WriteLine($"Etiketler: {string.Join(", ", ozet.Etiketler)}");
Hata Yönetimi
try
{
var yanit = await client.CompleteChatAsync(kullaniciMesaji);
return yanit.Value.Content[0].Text;
}
catch (ClientResultException ex) when (ex.Status == 429)
{
// Rate limit — exponential backoff ile tekrar dene
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, yenilemeSayisi)));
throw;
}
catch (ClientResultException ex) when (ex.Status == 400)
{
// Geçersiz istek veya içerik politikası ihlali
logger.LogWarning("İstek reddedildi: {Error}", ex.Message);
return "Bu içerik yanıtlanamıyor.";
}
Resmi OpenAI .NET SDK, type-safe ve modern bir API sunarken Microsoft.Extensions.AI ile birlikte kullanıldığında sağlayıcı bağımsızlığını da koruyor. Tool calling ve structured outputs kombinasyonu, LLM çıktılarını uygulama mantığınızla güvenilir şekilde entegre etmenin en sağlam yoludur.