明志唯新

Semantic Kernel dotnet 1.0 RC3 发布

发表于

Semantic Kernel dotnet 1.0 每天一个RC 版,让人应接不暇。dotnet-1.0.0-rc3 刚刚发布,Semantic Kernel 团队貌似在全力准备 12月15日发布 1.0 正式版。

让我们看一下这个版本的主要变更吧:

重命名

  • Azure Cognitive 改名为 Azure AI Search
  • KernelBuilderWithServices/WithPlugins 回调的方法,改为 Services/Plugins 属性。这样做虽然降低了流畅性,但它使之与 ASP.NET 当前使用的最佳实践模式保持一致,减少了嵌套,避免了关于回调何时被调用的混淆,避免了与异步相关的问题,并且使得在构建之前向构建器添加插件的语法与构建之后向 Kernel 添加插件的语法非常接近。
  • KernelBuilder 相关的 With 前缀的方法重命名为 Add(例如,WithOpenAIChatCompletion),以提高与当前 ASP.NET 实践的一致性,以及在使用 builder.AddXx 和 builder.Services.AddXx 时的一致性。
  • KernelKernelPluginFactory 相关的 AddPluginFromObject 方法 重命名为 AddFromType

增强

  • 修正了 AzureOpenAITextEmbeddingGenerationmodelId 参数顺序
  • 确保 KernelPromptTemplate 不会将已解析的提示变量重新添加回集合,以防止参数集合 KernelArguments 发生变异。
  • Kernel prompt template 开始初步支持处理字符串以外的类型,包括 int、decimal、bool、object 等,甚至于复杂类型。

限制: 鉴于 Kernel prompt template 正在修改以支持基元操作,目前可以合理地预期提示中会出现类似这样的表达方式:{{p.f a=28}},其中数字 28 没有使用单引号或双引号包围,并且最终作为整数参数传递给函数,避免了不必要的字符串到整数的转换。然而,支持这种表达式将需要对 CodeTokenizer类进行修改,这个部分 Semantic Kernel 团队将在后续PR中跟踪处理。

  • Kernel prompt template 在缺少参数或具有 null 值的参数将作为 null 参数(而不是空字符串)传递给方法调用。常规提示变量,如 {{$foo}} 的行为保持不变,只是在提示中插入一个空字符串。此更改可确保 Kernel prompt template 与 handlebars prompt template 的行为一致。
  • 为了支持泛行函数结果 FunctionResult<T> 的情况,为 KernelKernelFunction 增加了支持泛行结果的 Task<TResult?> InvokeAsync<TResult> 扩展方法:
var result = await kernel.InvokeAsync(functions["Function1"]);
var customType = result.GetValue<MyCustomType>()!;
Console.WriteLine(customType.Number); // 2
Console.WriteLine(customType.Text); // From Function1 + From Function2

将可以变成:

var customType = await kernel.InvokeAsync<MyCustomType>(functions["Function1"]);
Console.WriteLine(customType.Number); // 2
Console.WriteLine(customType.Text); // From Function1 + From Function2
  • 增加了 IKernelBuilder 接口。它由 KernelBuilder 实现,并通过 IServiceCollection 上的一个新的 AddKernel 扩展方法返回,该方法向容器中添加了一个单例 KernelPluginCollection 和一个瞬态 KernelIKernelBuilder 既有 Services 属性也有 Plugins 属性,并且还有 Build 方法,但如果在从 AddKernel 返回的实例上使用 Build 方法,它会抛出一个异常,因为这可能导致人们不小心多次构建容器。
  • KernelBuilder 上的所有扩展方法都更改为 IKernelBuilder

重要行为变化

  • 作为服务添加的插件现在会自动在 Kernel 构建过程中被解析。如果显式提供了集合,Kernel 会首先使用该集合;如果没有提供,它将尝试从服务中获取一个集合;如果还找不到,它将尝试从服务中获取所有的 IKernelPlugins

其他

  • AddFromType 中移除 new() 约束,改用 ActivatorUtilities.CreateInstanceKernelBuilder.Plugins 属性和 builder 拥有相同的 IServiceCollection,因此 AddFromType 可以利用它和 CreateInstance,从服务提供者中解析插件对象的构造函数参数。例如,HttpPlugin 有一个接受 HttpClient 的构造函数,如此一来在 Build 过程中的构建插件时,使用 builder.Plugins.AddFromType() 就会在容器中找到 HttpClient 并自动使用它。
  • 移除了 WithLoggerFactoryWithCulture。后者基本上从未被使用,它更像是 Kernel 上的 Data 属性和事件处理程序,可以很容易地在 Kernel 实例上进行修改,不需要任何构建器支持。WithLoggerFactory 虽然被频繁使用,但主要是因为测试中使用的模式,而且可以通过 AddLogging 轻松替代。
  • 增加了更多面对 Handlebars planner 的单元测试,将代码覆盖率提升到了71%以上
  • 修复了 FunctionCallingStepwisePlanner 的计划生成的prompt
  • 修复了将 StandardizedPrompt 与 Kernel/Function 的 InvokeAsync 结合使用时,ChatCompletions 未能正确解析的 bug
  • 删除了一些容易引起混淆的示例
  • 其他的一些小 bug 的修复和代码优化

结语

最近 Semantic Kernel 团队非常拼命的努力推进 1.0 正式版的进程,虽然看起来发布版本的速度有点过于频繁,但是从每次的变更内容来看,整体都在为了让开发者更容易上手,更容易开发稳定高效的智能应用而奋进,且已经看到了明显的进步。

以目前的变更速度,我建议大家先不要过频跟进新版本,可以等待一下更稳定的1.0 RC或者正式版之后再整体升级,以避免一些工作的浪费。

参考源: