Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Semantic Kernel & SignalR İle Birlikte Canlı AI Yanıtlarını Gösteren Kendi Chat Uygulamamızı Yazalım

Merhaba,

Malumunuz, günümüz, anlık olarak yazılımsal ilkelerin sınırlarını aşan eşsiz devrimlerin söz konusu olduğu ilginç bir tarihsel döneme şahitlik etmektedir. Artık yazılımlar, salt algoritmalara dayalı ve önceden tarif edilebilir işleyiş mantıklarından ziyade kompleks bir altyapıya ve şuurumsu bir davranışa sahip yapay zekâlardan meydana gelmekte ya da hiç yoktan ucundan kıyısından yapay zeka desteğiyle varlıklarına, dünden ciddi farkla bu gün devam ederek geleneksel dönemlere nazaran radikal bir evrimleşme sürecinde ilerlemektedirler. Evet, bu bir dönüşümdür. Belki dışardan bakınca zahiren gibi gözükebilir ama esasında olayın kimyası dönüşmekte ve dönüşürken de ister istemez birçok teamül ile birlikte alışkanlıklar da değişmektedir. Bu dönüşüm; sadece yazılımların gereksinimlerini değiştirmekle kalmamakta, bir yandan da biz geliştiricilerin problem çözme biçimlerine de dokunuş yaparak, şekillendirmektedir.

Artık bir yazılım geliştiricisi için mesele yalnızca belirli algoritmaları tasarlamak ve inşa etmekten ibaret değildir. Aynı zamanda bu algoritma süreçlerindeki verileri yönetecek, işleyecek ve özellikle karar süreçlerini yönlendirecek yapay zekâ modellerini eğitmek ve dinamik sistemler inşa etmek gibi çok boyutlu bir sürecin zanaatkarı olması ve klasik tekniklerin ötesine geçmesi gerekmektedir. Evet, şahsen benim bizlerden beklentim budur. Bu geçiş, yakında ortalama bir yazılımda olmazsa olmaz denebilecek yapay zekâ sohbet uygulamalarının niteliksel olarak yazılımlara dahil edilmesiyle kendini mutlak gösterecektir. Kullanıcı deneyimini iyileştirmek için AI modelleriyle olan etkileşim sonucunda cevapların ‘canlı’ olarak ekrana yansıtılması büyük fark yaratacak ve birçok yazılımcıdan beklenen beceri olarak karşımıza çıkacaktır. Bizler bu içeriğimizde bu farkı .NET geliştiricileri olarak nasıl kendi uygulamalarımıza katabileceğimizi inceleyecek ve canlı AI yanıtlarını web uygulamasında yayınlayan kendi chat uygulamamızın nasıl geliştirileceğine odaklanacağız.

İçeriğimiz sürecinde OpenRouter üzerinden Google: Gemini Pro 2.0 Experimental (free) modelini kullanıyor olacağız.

OpenRouter, farklı yapay zekâ modellerine tek bir API üzerinden erişim sağlayan ve böylece özellikle yapay zekâ destekli uygulamalar geliştirenler için büyük kolaylıklar sunan bir yönlendirme platformudur. Bu platform sayesinde OpenAI, Anthropic, Mistral, Google Gemini, Meta vs. gibi farklı LLM provider’larını tek bir API çağrısıyla kullanabilir ve olası model değiştirme ihtiyaçlarına karşın kodu baştan yazmaktansa OpenRouter API parametresine küçük bir dokunuşta bulunarak anında istenilen modele geçiş yapılabilir. Ayrıca daha pahalı bir model yerine benzer işlev gören uygun fiyatlı alternatifleri de deneyerek maliyet optimizasyonu yapılabileceği gibi, bir yandan da farklı modellerin güçlü ve zayıf yönlerini merkezi bir şekilde test ederek projenizin gereksinimlerine uygun olanı seçip performansta artış ile birlikte esneklikte sağlanabilmektedir.

OpenRouter’ın sunmuş olduğu merkezi LLM hizmeti sayesinde kullanılan AI modelinde bir çökme durumu meydana gelir ya da kullanılamamazlık söz konusu olursa direkt platform üzerinden alternatif bir modelle hızlıca işlevselliğe devam edebilir ve böylece servis sürekliliğini de olabildiğince garanti altına alabilirsiniz. Evet, tüm bunlar tek bir API anahtarı ile gerçekleştirilmektedir.

Özetle; OpenRouter, yapay zekâ modellerinin uygulama kapsamında oldukça az maliyetle kolayca yönetilmesine ve sistem sürekliliğinin sağlanmasına imkan veren oldukça değerli bir platformdur.

Semantic Kernel İle SignalR Uygulaması

Evet, artık örnek çalışmamıza geçebiliriz… Bunun için aşağıdaki her bir basamağın adım adım takip edilmesi yeterli olacaktır. O halde hadi başlayalım…

  • Adım 1 (Semantic Kernel Kütüphanesinin Kurulması ve Temel Yapılandırmanın Sağlanması) – Backend
    İlk olarak bir Asp.NET Core projesi oluşturalım ve içerisine Microsoft.SemanticKernel.Connectors.OpenAI kütüphanesini kuralım.

    Install-Package Microsoft.SemanticKernel.Connectors.OpenAI

    Ve akabinde aşağıdaki temel yapılandırmalarda bulunarak uygulama boyunca kullanacağımız ana zemini oluşturalım;

    using Microsoft.SemanticKernel;
    using OpenAI;
    using System.ClientModel;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddOpenAIChatCompletion(
        modelId: "google/gemini-2.0-pro-exp-02-05:free",
        openAIClient: new OpenAIClient(
            credential: new ApiKeyCredential("sk-or-v1-0959a8d8aed****d06e78ff68ceaa"),
            options: new OpenAIClientOptions
            {
                Endpoint = new Uri("https://openrouter.ai/api/v1")
            })
        );
    
    builder.Services.AddCors(options =>
        options.AddDefaultPolicy(policy => policy.AllowAnyMethod()
                                           .AllowAnyHeader()
                                           .AllowCredentials()
                                           .SetIsOriginAllowed(s => true)));
    
    builder.Services.AddSignalR();
    
    var app = builder.Build();
    app.UseCors();
    
    app.MapGet("/", () => "Hello World!");
    
    app.Run();
    

    Şimdi burada yaptığımız çalışmaları ele almamız gerekirse eğer; görüldüğü üzere OpenRouter üzerinden bir AI modeline bağlanıyorken Microsoft.SemanticKernel.Connectors.OpenAI kütüphanesini kullanmamız yeterlidir. Sanki Open AI kullanıyormuş gibi AddOpenAIChatCompletion aracılığıyla temel yapılandırmada bulunmamız ve kullanılacak model id ve credential bilgilerini vermemiz gerekmektedir. Bizler yukarıdaki satırlarda bahsettiğimiz üzere Google: Gemini Pro 2.0 Experimental (free) modelini kullanacağımızdan dolayı bu modelin id’sini ilgili parametreye belirtmiş bulunuyoruz. model id’yi nereden bulacaz la hoca? derseniz bunun için OpenRouter üzerinden ilgili modelin detayına girip aşağıdaki görselde olduğu gibi vurgulanan alandan model id değerini almamız yeterli olacaktır;Semantic Kernel & SignalR İle Birlikte Canlı AI Yanıtlarını Gösteren Kendi Chat Uygulamamızı YazalımEe peki credential‘da kullanılan key’i nereden bulacağız? diye sorarsanız, bu değeri de yine yukarıdaki görselde tee sağ tarafta API sekmesini görüyorsunuz… İşte bu sekmeye geldiğinizde ‘Create API key’ butonunu göreceksiniz. İşte buradan oluşturup, elde edebilirsiniz…

    Bunların dışında yapılan diğer yapılandırmalara göz atarsak eğer; malum default CORS politikalarını ayarlamış bulunuyoruz. Çünkü günün sonunda AI modelle yapılan haberleşme neticesinde elde edilen cevapları bir web uygulaması üzerinde SignalR ile anlık olarak yayınlayacağız. O yüzden, bu açıdan ilgili politikaların bu duruma elverişli olması gerekmektedir. Bir yandan da AddSignalR servisini ekleyerek uygulamaya SignalR altyapısını dahil etmiş bulunuyoruz.

    Evet, artık hasbel kader ilerlemeye hazırız diyebiliriz 🙂

  • Adım 2 (SignalR AIHub’ının Oluşturulması ve Temel Yapılandırmaların Sağlanması) – Backend
    Şimdi de uygulamada kullanacağımız SignalR altyapısını inşa edeceğiz. Bunun için öncelikle aşağıdaki gibi bir Hub sınıfı tasarlamamız gerekmektedir;

        public class AIHub : Hub
        {
    
        }
    

    Bu sınıf, çalışmamızın devamında AI modelinden üretilecek olan anlık cevabı parça parça mesaj olarak client’a gönderecektir.

    Velhasıl, oluşturulan bu Hub’ı aşağıdaki gibi uygulamaya dahil ederek, bir endpoint verelim;

    .
    .
    .
    var app = builder.Build();
    app.UseCors();
    
    app.MapGet("/", () => "Hello World!");
    
    app.MapHub<AIHub>("ai-hub");
    
    app.Run();
    
  • Adım 3 (Modelden Üretilen Cevabı Client’a Server-to-Client Modeliyle Stream Edecek Servisi Oluşturma) – Backend
    Şimdi de, AI modelinde kullanıcıdan gelen prompt’a karşılık üretilecek cevabı client’a parça parça gönderelim. Bunun için aşağıdaki gibi bir servis oluşturalım.

        public class AIService(IHubContext<AIHub> hubContext, IChatCompletionService chatCompletionService)
        {
            public async Task GetMessageStreamAsync(string prompt, string connectionId, CancellationToken? cancellationToken = default!)
            {
                await foreach (var response in chatCompletionService.GetStreamingChatMessageContentsAsync(prompt))
                {
                    cancellationToken?.ThrowIfCancellationRequested();
    
                    await hubContext.Clients.Client(connectionId).SendAsync("ReceiveMessage", response.ToString());
                }
            }
        }
    

    Görüldüğü üzere yukarıda, prompt AI modele gönderilmekte ve modelden stream bir şekilde gelen mesaj elde edilerek, bir yandan da client’a gelen her parça adım adım gönderilmektedir. Tabi burada teknik olarak IHubContext Interface’i İle Hub Dışı İleti Gönderme tekniğini kullanarak bir önceki adımda oluşturduğumuz Hub’ı kullandığımızı da söylemekte fayda görmekteyim. Ayrıca dikkat ederseniz, üretilecek cevap sadece client’tan gelecek olan connection id bilgisine karşılık client’a(yani yine o client’a) gönderilmektedir.

    Velhasıl, oluşturulan bu servisi kullanabilmek için IoC Container’a aşağıdaki gibi singleton olarak ekleyelim;

    .
    .
    .
    builder.Services.AddSingleton<AIService>();
    
  • Adım 4 (Chat Endpoint’ini Oluşturma) – Backend
    Evet, backend açısından yapmamız gereken son hamle ise chat endpoint’inin oluşturulmasıdır. Bunun için aşağıdaki gibi bir çalışma yapmamız yeterli olacaktır;

    .
    .
    .
    app.MapPost("/chat", async (AIService aiService, ChatRequestVM chatRequest, CancellationToken cancellationToken)
        => await aiService.GetMessageStreamAsync(chatRequest.Prompt, chatRequest.ConnectionId, cancellationToken));
    

    Burada kullandığımız viewmodel’ın içeriği ise aşağıdaki gibidir;

        public record ChatRequestVM(string Prompt, string ConnectionId)
        {
    
        }
    
  • Adım 5 (UI Ortamının Hazırlanması ve @microsoft/signalr Kütüphanesinin İndirilip, Entegre Edilmesi) – Client
    Evet, artık frontend kısmını geliştirmeye odaklanabiliriz. Artık backend AI modelle haberleşebilmekte ve kullanıcı tarafından gönderilen prompt eşliğinde üretilecek cevabı bizlere adım adım gönderebilmektedir. (İnşallah 😂) Artık bizler bir UI çalışması ile gelen bu verileri SignalR eşliğinde realtime’da tüketecek ve anlık chat çalışmasını görsel olarak gerçekleştireceğiz. Bunun için solution dizinine UI adında bir klasör ekleyerek içerisinde önce npm init komutuyla bir proje altyapısı oluşturalım, ardından da npm install @microsoft/signalr talimatıyla SignalR’ın kütüphanesini yükleyelim.

    Devamında ise ilgili klasör içerisine index.html ve app.js isimli dosyaları oluşturup, ekleyelim ve index.html içeriğini aşağıdaki gibi tasarlayalım.

    <!DOCTYPE html>
    <html lang="tr">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Custom Chat</title>
        <link href="style.css" rel="stylesheet" />
    </head>
    
    <body>
        <div class="chat-container">
            <div class="chat-header">Custom ChatGPT <span id="connectionId"></span></div>
            <div class="chat-box" id="chat-box"></div>
            <div class="chat-input">
                <input type="text" id="user-input" placeholder="Mesajınızı yazın...">
                <button onclick="sendPrompt()">Gönder</button>
            </div>
        </div>
        <script src="node_modules/@microsoft/signalr/dist/browser/signalr.min.js"></script>
        <script src="app.js"></script>
    </body>
    
    </html>
    

    Semantic Kernel & SignalR İle Birlikte Canlı AI Yanıtlarını Gösteren Kendi Chat Uygulamamızı YazalımBurada 20 ve 21. satırlarda görüldüğü üzere hem signalr.min.js hem de app.js dosyaları ilgili html dosyasına eklenmiş vaziyettedir. Artık bizler tüm client işlemleri için app.js‘e odaklanıp, işlemlerimizi yürütebiliriz.

  • Adım 6 (AI Modelinden Gelen Mesajların Client’ta Toparlanıp, Gösterilmesi) – Client
    Şimdi de, backend’den gelecek olan mesaj parçalarını tek tek toparlayalım ve chat görünümü verecek şekilde JavaScript’le aşağıdaki çalışmayı gerçekleştirelim;

    var hubConnection = new signalR.HubConnectionBuilder()
        .withUrl("https://localhost:7118/ai-hub")
        .build();
    
    hubConnection.start()
        .then(() =>
            document.getElementById("connectionId").innerHTML = `(${hubConnection.connectionId})`)
        .catch(err =>
            console.error(err.toString()));
    
    hubConnection.on("ReceiveMessage", responseMessage => {
        const aiMessage = `${responseMessage}`;
        chatBox.innerHTML += aiMessage;
        chatBox.scrollTop = chatBox.scrollHeight;
    });
    
    const input = document.getElementById("user-input");
    const chatBox = document.getElementById("chat-box");
    
    function sendPrompt() {
        if (input.value.trim() === "") return;
    
        const userMessage = `<div><strong>Sen:</strong> ${input.value}</div>`;
        chatBox.innerHTML += userMessage;
        chatBox.scrollTop = chatBox.scrollHeight;
    
        fetch("https://localhost:7118/chat", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({ prompt: input.value, connectionId: hubConnection.connectionId })
        })
            .then(response => response.json())
            .then(data => console.log("Success : ", data))
            .catch(error => console.error("Error", error));
        input.value = "";
    }
    

    Burada dikkat ederseniz jQuery’ye vs. bulaşmaksızın salt JavaScript ile oldukça sade bir SignalR client çalışması gerçekleştirmiş bulunuyoruz. Şimdi yapılanları incelersek eğer; ilk olarak, client’ları birbirlerinden ayırt edebilmek için 7. satırda olduğu gibi Hub’a bağlandıkları an connection id bilgileri alınmakta ve bir yandan da ekranda uygun bir yere yazdırılmaktadır. 11 ile 15. satır aralığında ise backend’den gelecek olan AI verileri chat bölümüne eklenerek, görsel olarak sohbet havası katılmaktadır. sendPrompt fonksiyonun da ise kullanıcıdan alınan prompt önceki adımlarda oluşturduğumuz API’ye gönderilmekte ve AI modelinin cevap üretip stream edeceği süreç böylece başlatılmaktadır.

  • Adım 7 (Test)
    Evet, tüm adımlardaki işlevleri harfiyen yaptığımıza göre artık teste geçebiliriz. Bunun için API uygulamasını derleyip, çalıştıralım ve ardından oluşturduğumuz client üzerinden aşağıdaki ekran görüntüsünde olduğu gibi bir prompt gönderip, neticeyi gözlemleyelim.Semantic Kernel & SignalR İle Birlikte Canlı AI Yanıtlarını Gösteren Kendi Chat Uygulamamızı YazalımGörüldüğü üzere Semantic Kernel sayesinde uygulamamıza entegre ettiğimiz bir AI model’le yaptığımız iletişim sayesinde özelleştrilmiş bir chat yapısı inşa etmiş olduk 🙂 Tamam, tasarım biraz daha özenli olabilirdi belki ama bu konuda beni bilenler açısından şükürlük bi görselimiz de yok değil diyebiliriz. 🙂

Artık inşa ettiğimiz bu temel üzerine Semantic Kernel’ın yeteneklerinden faydalanarak belli başlı geliştirmelerde bulunabiliriz. Şimdi gelin bunla ilgili bir kaç dokunuşta bulunalım…

Chat’e History Object İle Memory Özelliği Ekleme

AI modelleriyle gerçekleştirilmiş bir chat uygulamasının olmazsa olmazı konunun bağlamının hatırlanmasıdır. Evet, hatırlarsanız eğer Semantic Kernel Nedir? (DeepSeek R1 Eşliğinde .NET Açısından Derinlemesine Değerlendirelim) başlıklı makalemizde History object’i ile context’i chat sürecinde memory’de tutabileceğimizi ve böylece önceki mesajlarında AI modeli tarafından hatırlanıp, iletişim sürecine dahil edilebileceğini ifade etmiştik. Aşağıdaki çalışmada yukarıda geliştirdiğimiz altyapıya history niteliği kazandırmakta ve böylece chat sürecinde bağlam hafızaya atılarak önceki prompt’lar ve cevapları o anki sürece dahil edilmektedir;

    public static class HistoryService
    {
        private static readonly Dictionary<string, ChatHistory> _chatHistories = new();
        public static ChatHistory GetChatHistory(string connectionId)
        {
            ChatHistory? chatHistory = null;
            if (_chatHistories.TryGetValue(connectionId, out chatHistory))
                return chatHistory;
            else
            {
                chatHistory = new();
                _chatHistories.Add(connectionId, chatHistory);
            }
            return chatHistory;
        }
    }

İlk olarak görüldüğü üzere farklı client’ları birbirlerinden ayırt edebilmek için yukarıdaki HistoryService sınıfını tasarlıyoruz. Dikkat ederseniz, bir Dictionary içerisinde Hub ile bağlantı kurmuş olan tüm client’ların connection id değerlerine karşılık bir ChatHistory nesnesi tutuyoruz. GetChatHistory metodu sayesinde de, artık hangi connection id‘ye uygun History nesnesi lazımsa onu elde ediyoruz.

Devamında ise AIService‘i aşağıdaki gibi bu History yapılanmasıyla tekrardan restore edersek eğer;

    public class AIService(IHubContext<AIHub> hubContext, IChatCompletionService chatCompletionService)
    {
        public async Task GetMessageStreamAsync(string prompt, string connectionId, CancellationToken? cancellationToken = default!)
        {
            var history = HistoryService.GetChatHistory(connectionId);

            history.AddUserMessage(prompt);
            string responseContent = "";
            await foreach (var response in chatCompletionService.GetStreamingChatMessageContentsAsync(history))
            {
                cancellationToken?.ThrowIfCancellationRequested();

                await hubContext.Clients.Client(connectionId).SendAsync("ReceiveMessage", response.ToString());
                responseContent += response.ToString();
            }
            history.AddAssistantMessage(responseContent);
        }
    }

Evet, artık bu çalışma neticesinde chat sürecinde client’lar arasındaki farkı gözeterek konunun bağlamını AI modele hatırlatabilmekteyiz.Semantic Kernel & SignalR İle Birlikte Canlı AI Yanıtlarını Gösteren Kendi Chat Uygulamamızı Yazalım

Plugin İle Chat’e Özelleştirilmiş Davranış Ekleme

Semantic Kernel’ın en büyük özelliklerinden birisi plugin oluşturarak AI modellerinin davranışlarını uygulamamızın gereksinimlerine göre özelleştirebilmemizi sağlamasıdır. Bunu ilgili Semantic Kernel makalemizde özellikle vurguladığımızı anımsayacaksınız. Oluşturduğumuz plugin’ler sayesinde AI modele gelen prompt’lara karşın üretilecek cevaplarda otomatik bir şekilde bu eklentileri devreye sokarak hem AI modelin kapsamını belirleyebiliyor, hem de vereceği cevabı manipüle edebilme şansı elde ediyoruz. Yeter ki, bu özelliği kullanılan AI modeli destekliyor olsun. Evet, bizim bu içeriğimizde kullandığımız Google: Gemini Pro 2.0 Experimental (free) AI modelimiz prompt içeriğine uygun olarak otomatik plugin devreye sokabilme desteğine sahiptir. Şimdi gelin buna özel bir plugin oluşturalım ve ardından AI model’i otomatik bir şekilde plugin’i kullanacak şekilde yapılandıralım;

Öncelikle plugin’i aşağıdaki gibi tasarlayalım.

    public class CalculatorPlugin
    {
        [KernelFunction("add")]
        [Description("İki sayısal değer üzerinde toplama işlemi gerçekleştirir.")]
        [return: Description("Toplam değeri döndürür.")]
        public int Add(int number1, int number2)
            => number1 + number2;
    }

Evet, basit bir toplama işlemi. Örnek verebilmek için gidip tulumbadan su çekmemi beklemiyordunuz herhalde 🙂

Şimdi bu plugin’i Semantic Kernel aracılığıyla uygulamaya dahil edelim.

.
.
.
builder.Services
    .AddKernel()
    .AddOpenAIChatCompletion(
        modelId: "google/gemini-2.0-pro-exp-02-05:free",
        openAIClient: new OpenAIClient(
            credential: new ApiKeyCredential("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"),
            options: new OpenAIClientOptions
            {
                Endpoint = new Uri("https://openrouter.ai/api/v1")
            })
    )
    .Plugins.AddFromType<CalculatorPlugin>();

Burada ufak ama gözden kaçabilecek bir noktaya dikkatinizi çekmek istiyorum. Oluşturulan plugin’i sisteme dahil edebilmek için .Plugins.AddFromType<CalculatorPlugin>() kodunu yazmamız gerekmektedir. Ee bunu da yazabilmek için AddOpenAIChatCompletion metodunu AddKernel() metodu üzerinden yapılandırmamız gerekmektedir. Aksi taktirde Plugins property’sine erişim söz konusu olmayacaktır.

Uygulamaya plugin’i ekledikten sonra AIService‘de aşağıdaki çalışmayı gerçekleştirerek chat sürecine de eklentiyi dahil edelim ve prompt içeriğine göre otomatik tetiklenebileceğinin yapılandırmasını gerçekleştirelim;

    public class AIService(IHubContext<AIHub> hubContext, IChatCompletionService chatCompletionService, Kernel kernel)
    {
        public async Task GetMessageStreamAsync(string prompt, string connectionId, CancellationToken? cancellationToken = default!)
        {
            OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
            {
                FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
            };

            var history = HistoryService.GetChatHistory(connectionId);

            history.AddUserMessage(prompt);
            string responseContent = "";
            await foreach (var response in chatCompletionService.GetStreamingChatMessageContentsAsync(history, executionSettings: openAIPromptExecutionSettings, kernel: kernel))
            {
                cancellationToken?.ThrowIfCancellationRequested();

                await hubContext.Clients.Client(connectionId).SendAsync("ReceiveMessage", response.ToString());
                responseContent += response.ToString();
            }
            history.AddAssistantMessage(responseContent);
        }
    }

Burada da dikkat edilirse eğer OpenAIPromptExecutionSettings referansı üzerinden eklentilerin otomatik çağrılabileceği yapılandırılmakta ve bu, GetStreamingChatMessageContentsAsync metodunun executionSettings parametresine verilerek AI modelinin davranışı şekillendirilmektedir. Ayrıca burada yine küçük bir detay var ki, o da, uygulamada kullanılan Kernel referansı dependency injection ile IoC container’dan talep edilmekte ve yine aynı metodun kernel parametresine verilmektedir. Aksi taktirde bu çalışma için türlü hatalar söz konusu olabilmektedir.

Şimdi yaptığımız bu çalışmayı derleyip teste tabi tutarsak aşağıdaki ekran görüntüsünde olduğu gibi prompt’un mahiyetine göre ilgili eklentinin çağrıldığını gözlemlemiş olacağız;Semantic Kernel & SignalR İle Birlikte Canlı AI Yanıtlarını Gösteren Kendi Chat Uygulamamızı YazalımDikkat ederseniz ilk prompt normal nazik bi soruyken, ikincisi ise yarı sayısal yarı metinsel bir toplama sorusudur. İşte bu soruda AI modeli tarafından eklentimiz devreye sokulup, çalıştırılmaktadır. Bunu da break point’in tetiklenmesinden anlamaktayız.

Ee bu kadar kâfi diyelim 🙂

Evet, görüldüğü üzere Asp.NET Core’da geliştirdiğimiz bir Web API aracılığıyla Semantic Kernel üzerinden rahatlıkla Google: Gemini Pro 2.0 Experimental (free) AI modeliyle entegrasyon gerçekleştirmiş ve bir yandan da kullanıcıdan gelen prompt’lara karşı üretilen cevapların stream’ini tüketerek SignalR eşliğinde bu mesajları bir UI uygulamasına aktararak doğal bir chat havası oluşturmuş bulunuyoruz. Tüm bu süreçte history nesnesiyle chat’in bağlamını client’a özel memory’e almış ve bir yandan da custom plugin oluşturarak prompt’un mahiyetine göre otomatik devreye girecek şekilde uygulamamızın gereksinimlerini gözeterek manipülasyonlar ve kapsam sınırlaması gerçekleştirmiş bulunuyoruz.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek çalışmaya aşağıdaki github adresinden erişebilirsiniz.
https://github.com/gncyyldz/SemanticKernel.SignalR.Streaming.Handler.Example

Bunlar da hoşunuza gidebilir...

3 Cevaplar

  1. Gökhan dedi ki:

    Hocam, Ollama kullanarak kendi sunucumuzda Docker ile uygun bir LLM çalıştırıp, API üzerinden bir chatbot konuşturma senaryosunu ele alabilir misiniz? Bu mümkün müdür?

    Ayrıca, bu chatbotu tawk.to gibi canlı destek sistemlerine benzer şekilde script kodunu web sitesine eklemenin yeterli olduğu şekilde bir web sitesine entegre etmek için nasıl bir yol izlememiz gerekir? Hangi teknolojilere veya altyapıya ihtiyaç duyarız?

    • Gençay dedi ki:

      Tabi ki de mümkündür, ki Semantic Kernel Nedir? (DeepSeek R1 Eşliğinde .NET Açısından Derinlemesine Değerlendirelim) ve .NET’te Microsoft.Extensions.AI Kütüphanesiyle LLM Kullanımı başlıklı içeriklerimizde Ollama üzerinden çalışma gerçekleştirdiğimizi göreceksiniz. Yani ha Ollama üzerinden modele bağlanmışsınız, ha OpenRouter üzerinden ha da farklı bir şekilde bağlanmışsınız fark etmiyor! AI modelle yapılandırmayı herhangi bir provider üzerinden sağladıktan sonra geri kalan mantık yine buradakiyle aşağı yukarı aynı olacaktır.

      Bahsettiğin script kodu olarak web sitelerine eklenebilir extension’ları widget tarzı bir çalışmayla düzenleyebilirsin. Bunun için ise ayrı bir makale ele almamız gerekecektir. Lakin olayı şöyle özetleyebilirim. Misal olarak;

      (function () {
          var script = document.createElement("script");
          script.src = "https://you-endpoint.com/api/script";
          script.async = true;
          document.body.appendChild(script);
      })();
      

      Bu kodu web sitesine gömen istediğin özelliği entegre edebilir. Senin tek yapman gereken verilen endpoint karşılığında gönderilecek içeriği ya da işlevselliği sunmaktır.

      Umarım bu özet az çok fikir verebilir.

      İyi çalışmalar.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir