实战指南:从密钥配置到示例运行)
Semantic Kernel 官方文档示例库LearnResources实战指南从密钥配置到示例运行【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel本文以 Semantic Kernel .NET 仓库中的 dotnet/samples/LearnResources 项目为主线系统讲解这套与 Microsoft Learn 在线文档一一对应的代码示例工程的用途、目录结构、密钥配置与运行方式并深入剖析 Kernel 创建、AI 服务接入、原生函数、提示词工程、模板化与提示词序列化等核心示例的源码实现。读完本文你将掌握如何在本仓库中快速定位、配置并运行官方文档配套示例为学习 Semantic Kernel 提供可复现的实操环境。一、项目定位与官方文档配套的可运行代码片段库LearnResources是 Semantic Kernel .NET 仓库中专门存放与在线文档来源如 Microsoft Learn、DevBlogs 等配套代码片段的示例工程。其核心思想是文档中的每一段关键代码都以可编译、可运行、可测试的完整示例形式沉淀在仓库中让读者不必在文档与 IDE 之间来回切换直接运行即得结果。从仓库结构看该项目主要包含三个子目录详见 dotnet/samples/LearnResources/README.md子目录说明MicrosoftLearn与 Microsoft Learn Docs 配套的代码片段即本文主角Plugins示例运行所需的插件资源包括GitHub、OrchestratorPlugin、Prompts、WriterPlugin等Resources示例使用的数据与提示词资源文本、CSV、YAML 等其中MicrosoftLearn子目录下存放了 8 个与 Learn 文档章节一一对应的示例类每个类的注释都明确标注了对应的在线文档主题例如UsingTheKernel.cs—— 对应Kernel 入门章节AIServices.cs—— 对应为 Kernel 添加 AI 服务章节CreatingFunctions.cs—— 对应使用 KernelFunction 装饰器创建原生函数章节Prompts.cs、ConfiguringPrompts.cs、Templates.cs、FunctionsWithinPrompts.cs、SerializingPrompts.cs—— 对应提示词Prompt系列章节。这些示例文件头部均以/// summary注释的形式保留 Learn 文档 URL如https://learn.microsoft.com/semantic-kernel/agents/kernel便于读者回查原文。二、工程结构一个以测试形态组织的示例库与普通控制台示例不同LearnResources被组织为一个 xUnit 测试项目。在 dotnet/samples/LearnResources/LearnResources.csproj 中可以看到IsTestProjecttrue/IsTestProject声明为测试项目示例全部以[Fact]测试方法的形式存在TargetFrameworknet10.0/TargetFramework目标框架为 .NET 10UserSecretsId5ee045b0-aea3-4f08-8d31-32d1a6f8fed0/UserSecretsId通过 .NET Secret Manager 管理密钥项目引用ProjectReference了Connectors.AzureOpenAI、Connectors.OpenAI、PromptTemplates.Handlebars、Functions.Yaml、Plugins.Core、Plugins.Memory、Functions.OpenApi等核心组件因此这些示例几乎覆盖了 Semantic Kernel 的主要能力面。这种测试即示例的组织方式带来一个直接好处可以通过dotnet test --filter精确筛选运行任意一个示例详见 README 的 Running Examples with Filters 一节。示例之间的控制台输入则通过LearnBaseTest基类中的SimulatedInputText列表模拟避免交互式示例在测试环境下卡死见 LearnBaseTest.cs。三、配置密钥运行示例的前置条件README 明确指出大多数示例都需要访问 OpenAI、Azure OpenAI 等服务的密钥与凭据并强烈建议使用 .NETSecret Managerdotnet user-secrets来避免把密钥泄露进仓库、分支和 Pull Request当然也可以改用环境变量。README 还特别说明本项目与KernelSyntaxExamples旧示例库共用同一套密钥池。3.1 使用 Secret Manager 配置按 README 给出的命令进入项目目录并初始化用户机密然后逐项写入 OpenAI 与 Azure OpenAI 的配置cd dotnet/samples/DocumentationExamples dotnet user-secrets init dotnet user-secrets set OpenAI:ModelId ... dotnet user-secrets set OpenAI:ChatModelId ... dotnet user-secrets set OpenAI:EmbeddingModelId ... dotnet user-secrets set OpenAI:ApiKey ... dotnet user-secrets set AzureOpenAI:ServiceId ... dotnet user-secrets set AzureOpenAI:DeploymentName ... dotnet user-secrets set AzureOpenAI:ModelId ... dotnet user-secrets set AzureOpenAI:ChatDeploymentName ... dotnet user-secrets set AzureOpenAI:ChatModelId ... dotnet user-secrets set AzureOpenAI:Endpoint https://... .openai.azure.com/ dotnet user-secrets set AzureOpenAI:ApiKey ...两点需要结合当前仓库说明目录名注意README 中沿用了旧的项目目录名DocumentationExamples在当前仓库中该项目实际位于 dotnet/samples/LearnResources因此实际执行时应使用cd dotnet/samples/LearnResources dotnet user-secrets initUserSecretsId已在 LearnResources.csproj 中预设5ee045b0-aea3-4f08-8d31-32d1a6f8fed0dotnet user-secrets init后配置即写入~/.microsoft/usersecrets/5ee045b0-aea3-4f08-8d31-32d1a6f8fed0/secrets.json示例中的TestConfiguration读取层会自动通过Microsoft.Extensions.Configuration.UserSecrets已在 csproj 中引用加载这些值。3.2 使用环境变量配置若偏好环境变量方式使用以下名称注意__双下划线是 .NET 配置系统环境变量分隔符的标准写法与 Secret Manager 的:分层等价# OpenAI OpenAI__ModelId OpenAI__ChatModelId OpenAI__EmbeddingModelId OpenAI__ApiKey # Azure OpenAI AzureOpenAI__ServiceId AzureOpenAI__DeploymentName AzureOpenAI__ChatDeploymentName AzureOpenAI__Endpoint AzureOpenAI__ApiKey对比可见环境变量清单省略了AzureOpenAI__ModelId与AzureOpenAI__ChatModelId两项因为这两个值通常与部署名一致而 Secret Manager 版本保留了它们以提供更大灵活性两种方式的其余键一一对应。3.3 凭据缺失时的优雅降级示例代码对未配置凭据做了友好处理。以 UsingTheKernel.cs 为例示例先从TestConfiguration读取Endpoint、ChatModelId、ApiKey若任一为空则打印Azure OpenAI credentials not found. Skipping example.并直接返回。这意味着即便不配置任何密钥也可以编译并跑通测试框架只是示例会被跳过——这对 CI 环境尤为友好。四、运行示例dotnet test 与过滤器README 给出的运行方式是使用测试过滤器dotnet test --filter更具体地可以组合FullyQualifiedName或类名来运行单个示例例如# 运行全部 Learn 示例 dotnet test dotnet/samples/LearnResources/LearnResources.csproj # 只运行 Kernel 入门示例 dotnet test dotnet/samples/LearnResources/LearnResources.csproj --filter FullyQualifiedName~UsingTheKernel # 只运行提示词示例 dotnet test dotnet/samples/LearnResources/LearnResources.csproj --filter FullyQualifiedName~Prompts--filter的详细语法可通过dotnet test --help查看。由于每个示例都带有[Fact]标记且位于Examples命名空间见 UsingTheKernel.cs还可以用--filter FullyQualifiedName~Examples一次性运行该子目录下全部示例。五、示例源码深度解读以下按主题剖析MicrosoftLearn子目录下的 8 个示例每个示例都与 Learn 文档章节一一对应代码片段可对照仓库源码查看。5.1 Kernel 基础UsingTheKernel对应文档主题Kernel 入门。该示例演示了 Semantic Kernel 最核心的构建与调用链路见 UsingTheKernel.csvar builder Kernel.CreateBuilder() .AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey); builder.Services.AddLogging(c c.AddDebug().SetMinimumLevel(LogLevel.Trace)); builder.Plugins.AddFromTypeTimePlugin(); builder.Plugins.AddFromPromptDirectory(./../../../Plugins/WriterPlugin); Kernel kernel builder.Build(); // 调用内置 TimePlugin 获取当前时间 var currentTime await kernel.InvokeAsync(TimePlugin, UtcNow); // 将当前时间作为输入调用 WriterPlugin 的 ShortPoem 函数写诗 var poemResult await kernel.InvokeAsync(WriterPlugin, ShortPoem, new() { { input, currentTime } });关键点解读Kernel.CreateBuilder()返回构建器AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey)注册聊天补全服务通过builder.Services.AddLogging(...)直接向内核的 DI 容器注册调试日志日志级别设为Trace插件注册的两种方式同时出现AddFromTypeTimePlugin()从类型反射注册TimePlugin来自 Plugins.CoreAddFromPromptDirectory(./../../../Plugins/WriterPlugin)从目录加载提示词插件该目录含config.json与skprompt.txt调用形式kernel.InvokeAsync(PluginName, FunctionName, arguments)是 Semantic Kernel 中按名称调用插件函数的经典写法返回值FunctionResult可直接Console.WriteLine输出。5.2 接入 AI 服务AIServices对应文档主题为 Kernel 添加服务。示例对比了 Azure OpenAI 与标准 OpenAI 两种接入方式见 AIServices.cs// Azure OpenAI 方式 Kernel kernel Kernel.CreateBuilder() .AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey) .Build(); // 标准 OpenAI 方式 kernel Kernel.CreateBuilder() .AddOpenAIChatCompletion(openAImodelId, openAIapiKey) .Build();值得注意的实现细节示例从TestConfiguration分别读取 Azure OpenAI 与 OpenAI 两套凭据TestConfiguration.OpenAI.ChatModelId/TestConfiguration.AzureOpenAI.ChatModelId等且对两套凭据分别做了空值检查并独立跳过。这表明运行本项目时只需配置其中一家服务即可不必同时准备两家密钥。5.3 创建原生函数CreatingFunctions 与 MathPlugin对应文档主题使用 KernelFunction 装饰器创建原生函数。这是理解 Semantic Kernel 插件体系的关键示例见 CreatingFunctions.csvar builder Kernel.CreateBuilder() .AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey); builder.Plugins.AddFromTypeMathPlugin(); Kernel kernel builder.Build(); // 直接调用 MathPlugin.Sqrt double answer await kernel.InvokeAsyncdouble( MathPlugin, Sqrt, new() { { number1, 12 } }); Console.WriteLine($The square root of 12 is {answer}.);配套的 MathPlugin.cs 展示了原生函数的完整写法用[KernelFunction]标记可被 AI 调用的方法用[Description]提供函数与参数的语义描述。该插件共实现了 15 个数学函数Sqrt、Add、Subtract、Multiply、Divide、Power、Log、Round、Abs、Floor、Ceiling以及三角函数族Sin/Cos/Tan/Asin/Acos/Atan每个函数的参数都带[Description]说明如Multiply的注释特别提醒按百分比增加时不要忘记加 1。这些描述会作为元数据供 LLM 在函数调用Function Calling时理解并使用。示例后半部分演示了更进阶的用法构建ChatHistory后通过FunctionChoiceBehavior.Auto()开启自动函数调用并借助GetStreamingChatMessageContentsAsync流式返回结果将用户输入、AI 回复逐条写入历史实现完整的对话循环见 CreatingFunctions.cs。5.4 提示词工程Prompts对应文档主题你的第一个提示词。该示例Prompts.cs以识别用户请求意图为场景用7 个递进版本完整演示了提示词工程的演进路径是本文档库中信息密度最高的示例0.0 初始提示词$What is the intent of this request? {request}直接拼接最朴素1.0 更具体追加可选意图列表SendEmail, SendMessage, CompleteTask, CreateDocument约束输出空间2.0 输出结构化引入Instructions / Choices / User Input / Intent:固定格式引导模型按结构作答2.1 Markdown JSON 格式化用$$...原始字符串构造带json代码块的提示词要求模型返回{intent: ...}结构其中{{request}}通过模板插值注入用户输入3.0 Few-shot 少样本在提示词中给出两条用户输入 → Intent示例让模型模仿作答4.0 约束失败行为增加If you dont know the intent, dont guess; instead respond with Unknown并将Unknown加入候选列表避免模型胡猜5.0 提供上下文在提示词中注入一段对话历史用户抱怨邮件没人读、AI 建议改用消息提升意图判断的准确性6.0 使用消息角色改用message rolesystem/user/assistant标签组织提示词贴合聊天补全模型的多角色输入习惯7.0 鼓励词在 system 消息中追加Bonus: Youll get $20 if you get this right.演示激励措辞对输出质量的影响。所有版本均通过kernel.InvokePromptAsync(prompt)执行读者可以直接注释切换不同阶段对比输出差异。5.5 配置提示词ConfiguringPrompts对应文档主题配置提示词。示例ConfiguringPrompts.cs演示如何用PromptTemplateConfig以编程方式创建带完整配置的提示词函数其中ExecutionSettings按服务 ID 分别指定了default、gpt-3.5-turbo、gpt-4三套执行设置var chat kernel.CreateFunctionFromPrompt( new PromptTemplateConfig() { Name Chat, Description Chat with the assistant., Template {{ConversationSummaryPlugin.SummarizeConversation $history}} User: {{$request}} Assistant: , TemplateFormat semantic-kernel, InputVariables [ new() { Name history, Description The history of the conversation., IsRequired false, Default }, new() { Name request, Description The users request., IsRequired true } ], ExecutionSettings { { default, new OpenAIPromptExecutionSettings() { MaxTokens 1000, Temperature 0 } }, { gpt-3.5-turbo, new OpenAIPromptExecutionSettings() { ModelId gpt-3.5-turbo-0613, MaxTokens 4000, Temperature 0.2 } }, { gpt-4, new OpenAIPromptExecutionSettings() { ModelId gpt-4-1106-preview, MaxTokens 8000, Temperature 0.3 } } } } );这里的信息量值得展开InputVariables声明了模板变量history可选IsRequired false默认空字符串request必填IsRequired trueExecutionSettings的本质是服务 ID → 执行参数的映射default键被所有服务采用gpt-3.5-turbo、gpt-4键则通过ModelId将特定提示词路由到指定模型MaxTokens与Temperature逐模型差异化配置模板中调用了ConversationSummaryPlugin.SummarizeConversation $history即先对历史对话做摘要再拼接用户请求ConversationSummaryPlugin同样来自 Plugins.Core。同样的多服务配置也可以纯声明式地写在config.json中——仓库中的 chat/config.json 正是该配置的 JSON 版本schema 1、类型completion、execution_settings含default/gpt-3.5-turbo/gpt-4三档、input_variables声明request与history对应的提示词模板在 chat/skprompt.txt两文件配套构成一个完整的语义函数插件目录。5.6 模板化提示词Templates对应文档主题提示词模板化。示例Templates.cs展示了 Semantic Kernel 的两种模板引擎的混用默认 semantic-kernel 模板${history} User: {request} Assistant: 风格的简单占位符模板用于聊天回复Handlebars 模板通过HandlebarsPromptTemplateFactory配合TemplateFormat handlebars创建意图识别函数模板中使用了{{choices.[0]}}数组取首元素、{{#each fewShotExamples}}遍历少样本、{{#each this}}嵌套遍历 ChatMessageContent 的role/content等 Handlebars 控制结构。聊天循环中先用getIntent判断用户意图命中EndConversation即退出循环否则调用chat函数流式生成回复并写入ChatHistory。整个循环完整展示了意图路由 流式对话的 Agent 雏形。5.7 在提示词中调用函数FunctionsWithinPrompts对应文档主题在提示词中调用嵌套函数。这是对 5.5/5.6 的进阶见 FunctionsWithinPrompts.cs在模板内部直接调用其他 Kernel 函数。两种引擎各演示一次// Handlebars 模板内调用连字符分隔插件名与函数名 {{ConversationSummaryPlugin-SummarizeConversation history}} // Semantic Kernel 模板内调用点号分隔 var chat kernel.CreateFunctionFromPrompt( {{ConversationSummaryPlugin.SummarizeConversation $history}} User: {{$request}} Assistant: );注意两种语法差异Handlebar 模板使用PluginName-FunctionName连字符而默认 semantic-kernel 模板使用PluginName.FunctionName点号且变量带$前缀。ConversationSummaryPlugin先对history做摘要再进入提示词能有效控制上下文长度——这正是提示词中调用函数的核心价值让数据在进入 LLM 前先经过本地函数的加工。5.8 序列化提示词SerializingPrompts对应文档主题将提示词保存为文件。示例SerializingPrompts.cs演示从两种文件形态加载提示词// 1. 从插件目录加载config.json skprompt.txt 对 var prompts kernel.CreatePluginFromPromptDirectory(./../../../Plugins/Prompts); // 2. 从内嵌 YAML 资源加载配合 Handlebars 工厂 using StreamReader reader new(Assembly.GetExecutingAssembly() .GetManifestResourceStream(Resources.getIntent.prompt.yaml)!); KernelFunction getIntent kernel.CreateFunctionFromPromptYaml( await reader.ReadToEndAsync(), promptTemplateFactory: new HandlebarsPromptTemplateFactory() );对应的 YAML 文件是 Resources/getIntent.prompt.yaml它把 5.6 中 Handlebars 模板的意图识别函数完整声明化name: getIntent、description、template含 few-shot 遍历与ConversationSummaryPlugin.SummarizeConversation history调用、template_format: handlebars、input_variableschoices带默认值、fewShotExamples与request必填、execution_settingsdefault/gpt-3.5-turbo/gpt-4三档max_tokens: 10、低温度。该 YAML 通过 LearnResources.csproj 以EmbeddedResource方式随程序集发布运行时用GetManifestResourceStream读取。随后示例构建fewShotExamples两个ChatHistory分别映射到ContinueConversation与EndConversation在聊天循环中先解析意图命中EndConversation即结束否则调用prompts[chat]流式回复——整个意图识别 对话生成流程完全由文件化提示词驱动。六、测试基础设施LearnBaseTest 如何支撑交互式示例多个示例包含Console.ReadLine()交互循环如CreatingFunctions、ConfiguringPrompts、Templates等。为避免测试挂起基类 LearnBaseTest.cs 通过构造参数注入预置输入public class CreatingFunctions(ITestOutputHelper output) : LearnBaseTest([What is 49 diivided by 37?], output) // 模拟用户输入基类内部维护SimulatedInputText列表与游标SimulatedInputTextIndexReadLine()依次返回预置字符串用尽后返回null结束循环。扩展方法BaseTestExtensions.ReadLine(this BaseTest)则让示例代码能够以ReadLine()的方式透明调用。这解释了为什么示例代码可以同时服务于人工交互运行与自动化测试两种场景人工运行时Console.ReadLine()生效测试运行时由模拟输入接管。七、资源与辅助插件示例运行还依赖以下资源均在 dotnet/samples/LearnResources/Resources 下三个格林童话英文文本Grimms-The-King-of-the-Golden-Mountain.txt、Grimms-The-Water-of-Life.txt、Grimms-The-White-Snake.txt供记忆/文本处理类示例取用两份人口统计 CSVPopulationByAdmin1.csv、PopulationByCountry.csv供结构化数据处理示例使用女性选举权历史文本WomensSuffrage.txt意图识别提示词 YAMLgetIntent.prompt.yaml。插件目录 Plugins 下还包含GitHub含GitHubModels.cs与GitHubPlugin.cs演示 GitHub 数据接入、OrchestratorPlugin/GetIntent含config.json与skprompt.txt目录式提示词插件的又一实例、WriterPlugin/ShortPoem与MathPlugin.cs。八、小结一条从文档到代码的完整学习路径LearnResources的价值在于将 Microsoft Learn 上的 Semantic Kernel 教程转译为可编译、可过滤、可单独运行的测试用例。建议的学习路径是按第三节配置好 OpenAI 或 Azure OpenAI 密钥Secret Manager 或环境变量二选一用dotnet test --filter按需运行示例从UsingTheKernel入门对照 Prompts.cs 的 7 个递进版本理解提示词工程再依次阅读ConfiguringPrompts配置化、Templates模板化、FunctionsWithinPrompts函数内嵌、SerializingPrompts文件化将示例中的PromptTemplateConfig、Handlebars 模板与 getIntent.prompt.yaml 等文件对比学习即可掌握 Semantic Kernel 提示词体系从代码内联到声明式文件的完整形态。这套示例同时是很好的测试脚手架由于它复用了xunit、xRetry与 Semantic Kernel 各核心包见 LearnResources.csproj开发者可以在此基础上扩展自己的提示词与插件用例形成可持续回归验证的 AI 应用测试集。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考