OpenAI Assistants API, konuşma geçmişini ve dosya bağlamını siz yönetmek zorunda kalmadan kalıcı yapay zeka asistanları oluşturmanızı sağlar. Thread, Message, Run kavramlarıyla durum yönetimi tamamen API tarafında tutulur.

Asistan Oluşturma

// dotnet add package OpenAI
using OpenAI.Assistants;

var assistantClient = new AssistantClient("sk-...");

var asistan = await assistantClient.CreateAssistantAsync("gpt-4o", new AssistantCreationOptions
{
    Name         = ".NET Kod Asistanı",
    Instructions = """
        Sen deneyimli bir .NET geliştiricisisin.
        Kullanıcının C# ve ASP.NET Core sorularını yanıtla.
        Kod örneklerini her zaman çalışır halde ver.
        Açıklamaları kısa ve net tut.
        """,
    Tools        = { new CodeInterpreterToolDefinition() }
});

Console.WriteLine($"Asistan oluşturuldu: {asistan.Value.Id}");

Thread ve Mesaj Yönetimi

// Thread: bir kullanıcı oturumu
var thread = await assistantClient.CreateThreadAsync();

// Mesaj ekle
await assistantClient.CreateMessageAsync(thread.Value.Id,
    MessageRole.User,
    new MessageContent[] { MessageContent.FromText("Generic repository pattern nasıl uygulanır?") });

// İkinci mesaj (konuşma devam eder)
await assistantClient.CreateMessageAsync(thread.Value.Id,
    MessageRole.User,
    new MessageContent[] { MessageContent.FromText("Unit of Work ile birlikte nasıl kullanılır?") });

Run: Asistanı Çalıştırma ve Streaming

// Streaming run — token token yanıt
await foreach (var guncelleme in assistantClient.CreateRunStreamingAsync(
    thread.Value.Id, asistan.Value.Id))
{
    if (guncelleme is MessageContentUpdate icerikGuncelleme)
        Console.Write(icerikGuncelleme.Text);
}
Console.WriteLine();

// Polling ile (streaming yerine)
var run = await assistantClient.CreateRunAsync(thread.Value.Id, asistan.Value.Id);

while (run.Value.Status != RunStatus.Completed)
{
    await Task.Delay(1000);
    run = await assistantClient.GetRunAsync(thread.Value.Id, run.Value.Id);

    if (run.Value.Status == RunStatus.Failed)
        throw new Exception($"Run başarısız: {run.Value.LastError?.Message}");
}

// Mesajları al
var mesajlar = assistantClient.GetMessagesAsync(thread.Value.Id);
await foreach (var mesaj in mesajlar)
{
    if (mesaj.Role == MessageRole.Assistant)
        foreach (var parcalik in mesaj.Content)
            Console.WriteLine(parcalik.Text);
}

Dosya Yükleme ve File Search

using OpenAI.Files;

var fileClient = new FileClient("sk-...");

// Dosya yükle
using var dosyaAkisi = File.OpenRead("api-dokumantasyon.pdf");
var yuklenenDosya = await fileClient.UploadFileAsync(
    dosyaAkisi, "api-dokumantasyon.pdf", FileUploadPurpose.Assistants);

// Vector store oluştur ve dosyayı ekle
var vectorStoreClient = new VectorStoreClient("sk-...");
var vektorDepo = await vectorStoreClient.CreateVectorStoreAsync(
    new VectorStoreCreationOptions { Name = "API Docs" });

await vectorStoreClient.AddFileToVectorStoreAsync(
    vektorDepo.Value.Id, yuklenenDosya.Value.Id);

// File search destekli asistan
var dosyaAsistani = await assistantClient.CreateAssistantAsync("gpt-4o",
    new AssistantCreationOptions
    {
        Tools = { new FileSearchToolDefinition() },
        ToolResources = new ToolResources
        {
            FileSearch = new FileSearchResources
            {
                VectorStoreIds = { vektorDepo.Value.Id }
            }
        }
    });

ASP.NET Core'da Thread Yönetimi

// Controller — kullanıcı başına thread saklama
public class AsistanController(AssistantClient assistantClient, IDistributedCache cache) : ControllerBase
{
    private const string AsistanId = "asst_xxxxx"; // önceden oluşturulmuş

    [HttpPost("mesaj")]
    public async IAsyncEnumerable<string> MesajGonder(
        [FromBody] string soru,
        [FromHeader] string kullaniciId,
        [EnumeratorCancellation] CancellationToken ct)
    {
        // Thread ID'yi cache'den al veya yeni oluştur
        var threadId = await cache.GetStringAsync(kullaniciId, ct);
        if (threadId is null)
        {
            var thread = await assistantClient.CreateThreadAsync(cancellationToken: ct);
            threadId = thread.Value.Id;
            await cache.SetStringAsync(kullaniciId, threadId,
                new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24) },
                ct);
        }

        await assistantClient.CreateMessageAsync(threadId, MessageRole.User,
            new[] { MessageContent.FromText(soru) }, cancellationToken: ct);

        await foreach (var upd in assistantClient.CreateRunStreamingAsync(threadId, AsistanId, cancellationToken: ct))
            if (upd is MessageContentUpdate mu && mu.Text?.Length > 0)
                yield return mu.Text;
    }
}

Assistants API, konuşma geçmişi ve dosya yönetimini sizin yerinize üstlenerek çok turlu AI uygulamaları geliştirmeyi kolaylaştırır. Thread başına sohbet geçmişi, file search ve code interpreter araçları bir araya geldiğinde güçlü domain-specific asistanlar oluşturmak mümkündür.