更新于 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("获取城市天气")]public async Task<string> GetWeatherAsync([Description("城市名称")] string city){// 在这里调用你的天气 APIvar temp = 22; // 占位符return $"Weather in {city}: {temp}°C and clear";}}// 注册插件var weather = new WeatherPlugin;kernel.Plugins.AddFromObject(weather, pluginName: "weather");weather.GetWeatherAsync 作为工具,允许模型将响应建立在真实数据的基础上。{topic},{audience})并验证输入。var prompt = @"你是一个分类引擎。任务:将 `message` 分类为 [Billing, Tech Support, Sales] 中的一个。返回严格的 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 = "总结附加的策略,对风险进行分类,并通过电子邮件发送报告";// 假设我们有插件: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 = @"你严格从提供的上下文中回答。如果缺少,请说你不知道。包括像 [source i] 这样的内联引用,使用从 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);