更新於 2025年9月24日
9 分鐘
# .NETdotnet add package Microsoft.SemanticKernel# 可選:連接器和規劃器因版本而異using Microsoft.SemanticKernel;using Microsoft.SemanticKernel.Connectors.OpenAI;var builder = Kernel.CreateBuilder;// 選擇您的提供者:OpenAI 或 Azure OpenAIbuilder.AddOpenAIChatCompletion(modelId: "gpt-4o-mini", // 或您偏好的模型apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));var kernel = builder.Build;using Microsoft.SemanticKernel.SemanticFunctions;var prompt = @"您是一位簡潔的解釋者。請用 3 個要點向初學者解釋「{topic}」的概念。";var explainFunc = kernel.CreateFunctionFromPrompt(prompt);var result = await explainFunc.InvokeAsync(kernel, new { ["topic"] = "vector embeddings" });Console.WriteLine(result);public class WeatherPlugin{[KernelFunction, Description("Get weather for a city")]public async Task<string> GetWeatherAsync([Description("City name")] string city){// Call your weather API herevar temp = 22; // placeholderreturn $"Weather in {city}: {temp}°C and clear";}}// 註冊外掛程式var weather = new WeatherPlugin;kernel.Plugins.AddFromObject(weather, pluginName: "weather");weather.GetWeatherAsync 作為工具調用,從而使模型能夠根據真實資料來確定回應。{topic}、{audience})並驗證輸入。var prompt = @"您是一個分類引擎。任務:將 `message` 分類為 [帳單、技術支援、銷售] 之一。傳回嚴格的 JSON:{ \"label\": string, \"confidence\": number }message: {message}";var classify = kernel.CreateFunctionFromPrompt(prompt);var output = await classify.InvokeAsync(kernel, new { ["message"] = "I can’t log into my account." });Console.WriteLine(output); // {"label":"Tech Support","confidence":0.89}using Microsoft.SemanticKernel.Memory;var memory = new MemoryBuilder.WithMemoryStore(new VolatileMemoryStore) // 替換為向量資料庫(Qdrant、Pinecone、Azure AI Search).WithTextEmbeddingGeneration(new OpenAITextEmbeddingGeneration("text-embedding-3-small", Environment.GetEnvironmentVariable("OPENAI_API_KEY"))).Build;await memory.SaveInformationAsync(collection: "policies", id: "refund-policy",text: "Customers can request a refund within 30 days of purchase with proof of receipt.");// 稍後:檢索並塞入提示var results = memory.SearchAsync("refund window", collection: "policies", limit: 3, minRelevanceScore: 0.7);await foreach (var item in results){Console.WriteLine($"Relevant: {item.Metadata.Text}");}// 1) 像以前一樣定義外掛程式(語義 + 原生)// 2) 使用規劃器(API 介面可能因版本而異)var goal = "Summarize the attached policy, classify risk, and email a report";// 假設我們有外掛程式:files、summarize、classify、email// 規劃器將組裝一個計劃:files.Load → summarize.Run → classify.Run → email.Send// 依序執行計劃,驗證步驟之間的 JSON 輸出var kernel = Kernel.CreateBuilder.AddOpenAIChatCompletion("gpt-4o-mini", apiKey).Build;var fastKernel = Kernel.CreateBuilder.AddOpenAIChatCompletion("gpt-4o-mini", apiKey) // 速度最佳化.Build;// 將較簡單的提示路由到 fastKernel;將複雜的任務路由到 kernelTryParse 閘道。record Classification(string label, double confidence);bool TryParseClassification(string text, out Classification cls){try { cls = System.Text.Json.JsonSerializer.Deserialize<Classification>(text)!; return true; }catch { cls = default!; return false; }}retrieve(context) → answer(question, context) 帶有引用。// 1) 將文件提取到記憶中await memory.SaveInformationAsync("handbook", "vacation-policy","Employees accrue 1.5 days of PTO per month and can carry over 5 days.");// 2) 檢索問題的上下文var top = memory.SearchAsync("carry over PTO", "handbook", limit: 3, minRelevanceScore: 0.75);var contexts = new List<string>;await foreach (var r in top) contexts.Add(r.Metadata.Text);// 3) 詢問上下文並請求引用var qaPrompt = @"You answer strictly from the provided context. If missing, say you don't know.Include inline citations like [source i] using the index of context items starting at 1.Context:1) {{ctx1}}2) {{ctx2}}Question: {{q}}";var qa = kernel.CreateFunctionFromPrompt(qaPrompt);var variables = new KernelArguments{["ctx1"] = contexts.ElementAtOrDefault(0) ?? "",["ctx2"] = contexts.ElementAtOrDefault(1) ?? "",["q"] = "How many PTO days can I carry over?"};var answer = await qa.InvokeAsync(kernel, variables);Console.WriteLine(answer);