czyli jak nauczyć SI robić to, czego potrzebujemy — na nasze polecenie, z naszą logiką
W ostatnim wpisie opowiadałem o tym, skąd w ogóle Semantic Kernel się wziął i czemu warto się nim zainteresować. Dziś schodzimy poziom głębiej i odpowiemy sobie na pytanie: jak nauczyć naszą sztuczną inteligencję czynić dobro — czyli jak tworzyć i wykorzystywać pluginy.
Zanim przejdziemy do kodu — trochę kontekstu.
W największym skrócie — pluginy to funkcje, które możesz zarejestrować w Semantic Kernel i potem wywoływać w kontekście. Nie różnią się wiele od zwykłych funkcji programistycznych… poza tym, że potrafią korzystać z mocy LLM (czyli dużych modeli językowych).
To funkcje oparte na promptach, czyli tekstach z "inputami" do wypełnienia. Przykład:
Zadanie: Podsumuj tekst. Tekst: {{$input}} Podsumowanie:
Taką funkcję tworzymy za pomocą kernel.CreateSemanticFunction(...)
. Idealnie nadaje się do pisania streszczeń, generowania treści, tłumaczeń itp.
Czyli nasze własne, klasyczne funkcje w C#:
[KernelFunction] public static string UpperCase(string input) => input.ToUpperInvariant();
Możemy ich używać do obliczeń, formatowania danych, walidacji i dowolnej logiki, której LLM nie musi się uczyć — bo przecież my to wiemy!
To nie tyle osobny rodzaj funkcji, co sposób na ich wielokrotne użycie. Prompt templates zapisujemy np. w plikach .txt
albo .skprompt.txt
, które potem łatwo podpinamy pod Semantic Kernel.
Pliki mogą mieć parametr {{$input}}
, ale również dodatkowe zmienne — np. {{$language}}
, {{$tone}}
itd. Potem wystarczy je załadować:
kernel.ImportSemanticPluginFromDirectory("Plugins", "MyPlugin")
I gotowe!
Stwórzmy prosty plugin, który tłumaczy teksty na inne języki.
Struktura katalogów:
Plugins/ └── TranslatorPlugin/ └── Translate.skprompt.txt
Zawartość Translate.skprompt.txt
:
Przetłumacz tekst na {{$language}}: {{$input}} Tłumaczenie:
W kodzie:
var plugin = kernel.ImportSemanticPluginFromDirectory("Plugins", "TranslatorPlugin"); var result = await kernel.InvokeAsync(plugin["Translate"], new() { ["input"] = "Cześć, jak się masz?", ["language"] = "angielski" }); Console.WriteLine(result);
W praktyce nie zatrzymujemy się na jednej funkcji. Często robimy coś takiego:
[1] Użytkownik zadaje pytanie → [2] Funkcja A buduje prompt → [3] Funkcja B przetwarza prompt → [4] Funkcja C analizuje wynik → [5] Funkcja D formatuje odpowiedź
Czyli tzw. chaining — funkcje wywoływane są jedna po drugiej, często korzystając z tego samego SKContext
.
Możesz to zrobić manualnie:
var context = kernel.CreateNewContext(); context["input"] = "Jak działa Semantic Kernel?"; await kernel.InvokeAsync(plugin["AnalyzeQuestion"], context); await kernel.InvokeAsync(plugin["GeneratePrompt"], context); await kernel.InvokeAsync(plugin["GetAnswer"], context);
Albo — zautomatyzować to, używając planera (ale o tym innym razem 👀).
Potrzebuję... | Typ funkcji |
---|---|
Logiki biznesowej | 🛠 Native function |
Generowania/interpretowania tekstu | ✨ Prompt function |
Łatwej reużywalności promptów | 🧩 Prompt template |
Skomplikowanego przepływu danych | 🔁 Chaining (manualnie lub planer) |
Automatyczne tłumaczenia
Spersonalizowane odpowiedzi na pytania użytkowników
Tworzenie raportów lub streszczeń
Łączenie klasycznego C# z mocą LLM
W następnym wpisie przyjrzymy się wbudowanym pluginom, które Semantic Kernel udostępnia od ręki. Dzięki nim możesz od razu korzystać np. z wysyłania maili, zarządzania plikami czy konwersji dat — bez pisania ani linijki promptu!
Do przeczytania!
👉Masz pytania albo chcesz przykład w Twoim kontekście? Daj znać przez formularz kontaktowy!