资讯中心

config.json 文件是固定名称,存储描述信息,比如需要的变量名称、描述等。下面是一个 completion 类型的插件配置文件示例,除了一些跟提示模板相关的配置,还有一些聊天的配置,如最大 t

📅 2026/7/2 6:01:05
config.json 文件是固定名称,存储描述信息,比如需要的变量名称、描述等。下面是一个 completion 类型的插件配置文件示例,除了一些跟提示模板相关的配置,还有一些聊天的配置,如最大 t
{ schema: 1, type: completion, description: 根据用户问题写一首简短而有趣的诗., completion: { max_tokens: 200, temperature: 0.5, top_p: 0.0, presence_penalty: 0.0, frequency_penalty: 0.0 }, input: { parameters: [ { name: input, description: 诗的主题, defaultValue: } ] } }创建插件目录和文件后在代码中以提示模板的方式加载// 加载插件表示该插件是提示模板 builder.Plugins.AddFromPromptDirectory(./plugins/WriterPlugin); var kernel builder.Build(); Console.WriteLine(输入诗的主题); var input Console.ReadLine(); // WriterPlugin 插件名称与插件目录一致插件目录下可以有多个子模板目录。 FunctionResult result await kernel.InvokeAsync(WriterPlugin, ShortPoem, new() { { input, input } }); Console.WriteLine(result.GetValuestring());输入问题以及 AI 回复输入诗的主题 春天 春天春天你是生命的诗篇 万物复苏爱的季节。 郁郁葱葱的小草中 是你轻响的诗人的脚步音。 春天春天你是花芯的深渊 桃红柳绿或妩媚或清纯。 在温暖的微风中 是你舞动的裙摆。 春天春天你是蓝空的情儿 百鸟鸣叫放歌天际无边。 在你湛蓝的天幕下 是你独角戏的绚烂瞬间。 春天春天你是河流的眼睛 如阿瞒甘霖滋养大地生灵。 你的涓涓细流 是你悠悠的歌声。 春天春天你是生命的诗篇 用温暖的手指照亮这灰色的世间。 你的绽放微笑与欢欣 就是我心中永恒的春天。插件文件的编写可参考官方文档https://learn.microsoft.com/en-us/semantic-kernel/prompts/saving-prompts-as-files?tabsCsharp根据 AI 自动调用插件函数使用 Semantic Kernel 加载插件类后Semantic Kernel 可以自动根据 AI 对话调用这些插件类中的函数。比如有一个插件类型用于修改或获取灯的状态。代码如下public class LightPlugin { public bool IsOn { get; set; } false; [KernelFunction] [Description(获取灯的状态.)] public string GetState() IsOn ? 亮 : 暗; [KernelFunction] [Description(修改灯的状态.)] public string ChangeState(bool newState) { this.IsOn newState; var state GetState(); Console.WriteLine($[灯的状态是 {state}]); return state; } }每个函数都使用了[Description]特性设置了注释信息这些注释信息非常重要AI 靠这些注释理解函数的功能作用。然后加载插件类并在聊天中被 Semantic Kernel 调用// 加载插件类 builder.Plugins.AddFromTypeLightPlugin(); var kernel builder.Build(); var history new ChatHistory(); // 聊天服务 var chatCompletionService kernel.GetRequiredServiceIChatCompletionService(); while (true) { Console.Write(User ); var userInput Console.ReadLine(); // 添加到聊天记录中 history.AddUserMessage(userInput); // 开启函数调用 OpenAIPromptExecutionSettings openAIPromptExecutionSettings new() { ToolCallBehavior ToolCallBehavior.AutoInvokeKernelFunctions }; // 获取函数 var result await chatCompletionService.GetChatMessageContentAsync( history, executionSettings: openAIPromptExecutionSettings, kernel: kernel); Console.WriteLine(Assistant result); // 添加到聊天记录中 history.AddMessage(result.Role, result.Content ?? string.Empty); }可以先断点调试 LightPlugin 中的函数然后在控制台输入问题让 AI 调用本地函数User 灯的状态 Assistant 当前灯的状态是暗的。 User 开灯 [灯的状态是 亮] Assistant 灯已经开启现在是亮的状态。 User 关灯 [灯的状态是 暗]读者可以在官方文档了解更多https://learn.microsoft.com/en-us/semantic-kernel/agents/plugins/using-the-kernelfunction-decorator?tabsCsharp由于几乎没有文档资料说明原理因此建议读者去研究源码这里就不再赘述了。聊天中明确调用函数我们可以在提示模板中明确调用一个函数。定义一个插件类型 ConversationSummaryPlugin其功能十分简单将历史记录直接返回input 参数表示历史记录。public class ConversationSummaryPlugin { [KernelFunction, Description(给你一份很长的谈话记录总结一下谈话内容.)] public async Taskstring SummarizeConversationAsync( [Description(长对话记录\r\n.)] string input, Kernel kernel) { await Task.CompletedTask; return input; } }为了在聊天记录中使用该插件函数我们需要在提示模板中使用{{ConversationSummaryPlugin.SummarizeConversation $history}}其中$history是自定义的变量名称名称可以随意只要是个字符串即可。var chat kernel.CreateFunctionFromPrompt( {{ConversationSummaryPlugin.SummarizeConversation $history}} User: {{$request}} Assistant: );完整代码如下// 加载总结插件 builder.Plugins.AddFromTypeConversationSummaryPlugin(); var kernel builder.Build(); var chat kernel.CreateFunctionFromPrompt( {{ConversationSummaryPlugin.SummarizeConversation $history}} User: {{$request}} Assistant: ); var history new ChatHistory(); while (true) { Console.Write(User ); var request Console.ReadLine(); // 添加到聊天记录中 history.AddUserMessage(request); // 流式对话 var chatResult kernel.InvokeStreamingAsyncStreamingChatMessageContent( chat, new KernelArguments { { request, request }, { history, string.Join(\n, history.Select(x x.Role : x.Content)) } }); string message ; await foreach (var chunk in chatResult) { if (chunk.Role.HasValue) { Console.Write(chunk.Role ); } message chunk; Console.Write(chunk); } Console.WriteLine(); history.AddAssistantMessage(message); }由于模板的开头是{{ConversationSummaryPlugin.SummarizeConversation $history}}因此每次聊天之前都会先调用该函数。比如输入吃饭睡觉打豆豆的时候首先执行 ConversationSummaryPlugin.SummarizeConversation 函数然后将返回结果存储到模板中。最后生成的提示词对比如下{{ConversationSummaryPlugin.SummarizeConversation $history}} User: {{$request}} Assistant: user: 吃饭睡觉打豆豆 User: 吃饭睡觉打豆豆 Assistant:可以看到调用函数返回结果后提示词字符串前面自动使用 User 角色。实现总结Semantic Kernel 中有很多文本处理工具比如TextChunker类型可以帮助我们提取文本中的行、段。设定场景如下用户提问一大段文本然后我们使用 AI 总结这段文本。Semantic Kernel 有一些工具但是不多而且是针对英文开发的。设定一个场景用户可以每行输入一句话当用户使用000结束输入后每句话都推送给 AI 总结不是全部放在一起总结。这个示例的代码比较长建议读者在 vs 中调试代码慢慢阅读。// 总结内容的最大 token const int MaxTokens 1024; // 提示模板 const string SummarizeConversationDefinition 开始内容总结: {{$request}} 最后对内容进行总结。 在“内容到总结”中总结对话找出讨论的要点和得出的任何结论。 不要加入其他常识。 摘要是纯文本形式在完整的句子中没有标记或标记。 开始总结: ; // 配置 PromptExecutionSettings promptExecutionSettings new() { ExtensionData new Dictionarystring, object() { { Temperature, 0.1 }, { TopP, 0.5 }, { MaxTokens, MaxTokens } } }; // 这里不使用 kernel.CreateFunctionFromPrompt 了 // KernelFunctionFactory 可以帮助我们通过代码的方式配置提示词 var func KernelFunctionFactory.CreateFromPrompt( SummarizeConversationDefinition, // 提示词 description: 给出一段对话记录总结这部分对话., // 描述 executionSettings: promptExecutionSettings); // 配置 #pragma warning disable SKEXP0055 // 类型仅用于评估在将来的更新中可能会被更改或删除。取消此诊断以继续。 var request ; while (true) { Console.Write(User ); var input Console.ReadLine(); if (input 000) { break; } request Environment.NewLine; request input; } // SK 提供的文本拆分器将文本分成一行行的 Liststring lines TextChunker.SplitPlainTextLines(request, MaxTokens); // 将文本拆成段落 Liststring paragraphs TextChunker.SplitPlainTextParagraphs(lines, MaxTokens); string[] results new string[paragraphs.Count]; for (int i 0; i results.Length; i) { // 一段段地总结 results[i] (await func.InvokeAsync(kernel, new() { [request] paragraphs[i] }).ConfigureAwait(false)) .GetValuestring() ?? string.Empty; } Console.WriteLine($ 总结如下 {string.Join(\n, results)} );输入一堆内容后新的一行使用000结束提问让 AI 总结用户的话。不过经过调试发现TextChunker 对这段文本的处理似乎不佳因为文本这么多行只识别为一行、一段。可能跟 TextChunker 分隔符有关SK 主要是面向英语的。本小节的演示效果不佳不过主要目的是让用户了解KernelFunctionFactory.CreateFromPrompt可以更加方便创建提示模板、使用 PromptExecutionSettings 配置温度、使用 TextChunker 切割文本。配置 PromptExecutionSettings 时出现了三个参数其中 MaxTokens 表示机器人回复最大的 tokens 数量这样可以避免机器人废话太多。其它两个参数的作用是Temperature值范围在 0-2 之间简单来说temperature的参数值越小模型就会返回越确定的一个结果。值越大AI 的想象力越强越可能偏离现实。一般诗歌、科幻这些可以设置大一些让 AI 实现天马行空的回复。TopP与 Temperature 不同的另一种方法称为核抽样其中模型考虑了具有 TopP 概率质量的令牌的结果。因此0.1 意味着只考虑构成前10% 概率质量的令牌的结果。一般建议是改变其中一个参数就行不用两个都调整。更多相关的参数配置请查看 https://learn.microsoft.com/en-us/azure/ai-services/openai/reference配置提示词前面提到了一个新的创建函数的用法var func KernelFunctionFactory.CreateFromPrompt( SummarizeConversationDefinition, // 提示词 description: 给出一段对话记录总结这部分对话., // 描述 executionSettings: promptExecutionSettings); // 配置创建提示模板时可以使用 PromptTemplateConfig 类型 调整控制提示符行为的参数。// 总结内容的最大 token const int MaxTokens 1024; // 提示模板 const string SummarizeConversationDefinition ...; var func kernel.CreateFunctionFromPrompt(new PromptTemplateConfig { // Name 不支持中文和特殊字符 Name chat, Description 给出一段对话记录总结这部分对话., Template SummarizeConversationDefinition, TemplateFormat semantic-kernel, InputVariables new ListInputVariable { new InputVariable{Name request, Description 用户的问题, IsRequired true } }, ExecutionSettings new Dictionarystring, PromptExecutionSettings { { default, new OpenAIPromptExecutionSettings() { MaxTokens MaxTokens, Temperature 0 } }, } });ExecutionSettings 部分的配置可以针对使用的模型起效这里的配置不会全部同时起效会根据实际使用的模型起效。ExecutionSettings new Dictionarystring, PromptExecutionSettings { { 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 } } }聊到这里重新说一下前面使用文件配置提示模板文件的两者是相似的。我们也可以使用文件的形式存储与代码一致的配置其目录文件结构如下└─── chat | └─── config.json └─── skprompt.txt模板文件由 config.json 和 skprompt.txt 组成skprompt.txt 中配置提示词跟 PromptTemplateConfig 的 Template 字段配置一致。config.json 中涉及的内容比较多你可以对照下面的 json 跟 实现总结 一节的代码两者几乎是一模一样的。{ schema: 1, type: completion, description: 给出一段对话记录总结这部分对话, execution_settings: { default: { max_tokens: 1000, temperature: 0 }, gpt-3.5-turbo: { model_id: gpt-3.5-turbo-0613, max_tokens: 4000, temperature: 0.1 }, gpt-4: { model_id: gpt-4-1106-preview, max_tokens: 8000, temperature: 0.3 } }, input_variables: [ { name: request, description: 用户的问题., required: true }, { name: history, description: 用户的问题., required: true } ] }