Bitzsoft.Integrations.SemanticKernel
1.0.0-alpha.10
dotnet add package Bitzsoft.Integrations.SemanticKernel --version 1.0.0-alpha.10
NuGet\Install-Package Bitzsoft.Integrations.SemanticKernel -Version 1.0.0-alpha.10
<PackageReference Include="Bitzsoft.Integrations.SemanticKernel" Version="1.0.0-alpha.10" />
<PackageVersion Include="Bitzsoft.Integrations.SemanticKernel" Version="1.0.0-alpha.10" />
<PackageReference Include="Bitzsoft.Integrations.SemanticKernel" />
paket add Bitzsoft.Integrations.SemanticKernel --version 1.0.0-alpha.10
#r "nuget: Bitzsoft.Integrations.SemanticKernel, 1.0.0-alpha.10"
#:package Bitzsoft.Integrations.SemanticKernel@1.0.0-alpha.10
#addin nuget:?package=Bitzsoft.Integrations.SemanticKernel&version=1.0.0-alpha.10&prerelease
#tool nuget:?package=Bitzsoft.Integrations.SemanticKernel&version=1.0.0-alpha.10&prerelease
Bitzsoft.Integrations.SemanticKernel
Semantic Kernel 插件兼容编排层。它不再创建厂商客户端或持有 API Key,而是复用
Microsoft.Extensions.AI.IChatClient,让 OpenAI、智谱、Kimi、通义、DeepSeek 和
Claude 共用同一套租户、凭据、审计和遥测边界。
新 Agent、会话持久化和工具审批应使用 Bitzsoft.Integrations.AgentFramework。本包只
服务于仍需要 Semantic Kernel Kernel、[KernelFunction]、Plugin 或 Prompt API 的场景。
安装与兼容性
dotnet add package Bitzsoft.Integrations.AI
dotnet add package Bitzsoft.Integrations.SemanticKernel
- 目标框架:
net8.0;net10.0; - Semantic Kernel:稳定版;
- 模型协议和密钥管理:由已注册的
IChatClient负责; - Kernel 和插件:Scoped,不跨请求、租户或并发任务共享可变状态;
- 不提供
ApiKey、Endpoint、ProviderId或ModelId配置。
.NET 5 宿主应通过独立 .NET 8/10 AI 服务调用本能力。
注册
先注册模型,再注册兼容编排层:
// 模型注册负责 Provider、模型、租户凭据、审计和遥测。
services.AddBitzChatClient(options =>
{
options.ProviderId = "deepseek-prod";
options.ProfileId = "deepseek";
options.ModelId = "deepseek-chat";
});
// Semantic Kernel 只配置编排行为,不重复保存 Provider 配置或密钥。
services.AddBitzSemanticKernel(options =>
{
options.SystemPrompt = "只处理已授权的企业业务问题。";
options.MaxOutputTokens = 4096;
options.Temperature = 0.2f;
options.MaximumFunctionInvocationIterations = 5;
options.MaximumConsecutiveFunctionErrors = 1;
});
默认 ISemanticKernelClient 使用默认 IChatClient。命名管道使用完全相同的 Key:
// 聊天客户端和编排客户端使用完全相同的命名 Key。
services.AddBitzChatClient("analysis", options =>
{
options.ProviderId = "openai-prod";
options.ProfileId = "openai-responses";
options.ModelId = "approved-reasoning-model";
});
// 命名编排管道会解析同名 Keyed IChatClient。
services.AddBitzSemanticKernel("analysis", options =>
{
options.SystemPrompt = "执行只读分析并给出证据。";
options.Temperature = 0;
});
// 从业务 Scope 获取命名编排客户端。
var client = serviceProvider
.GetRequiredKeyedService<ISemanticKernelClient>("analysis");
必须在当前 IntegrationContext 中调用。模型密钥由
IIntegrationCredentialResolver 使用 AI:{ProviderId} 凭据键按租户、地域和环境解析;
本包看不到也不缓存密钥。
完整最小示例
以下示例使用进程内凭据 Store,只适用于本地开发和测试:
using Bitzsoft.Integrations.AI;
using Bitzsoft.Integrations.Core;
using Bitzsoft.Integrations.SemanticKernel;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
// 仅开发/测试:生产环境应注册对接 Vault、KMS 或云密钥服务的解析器。
services.AddInMemoryIntegrationCredentials();
// 注册租户感知模型。API Key 不写入 Options。
services.AddBitzChatClient(options =>
{
options.ProviderId = "deepseek-dev";
options.ProfileId = "deepseek";
options.ModelId = "deepseek-chat";
});
// 注册 Scoped Kernel 兼容层和允许暴露的只读插件。
services.AddBitzSemanticKernel(options =>
{
options.SystemPrompt = "只回答当前租户已授权的业务问题。";
options.MaximumFunctionInvocationIterations = 3;
});
services.AddBitzSemanticKernelPlugin<
Bitzsoft.Integrations.SemanticKernel.Plugins.DateTimePlugin>(
"date_time");
await using var provider = services.BuildServiceProvider(
new ServiceProviderOptions { ValidateScopes = true });
// 写入 tenant-a 的开发密钥;using 确保调用方持有的密钥快照被清理。
var credentialStore = provider.GetRequiredService<
InMemoryIntegrationCredentialStore>();
using (var credential = new IntegrationCredential(
[
new(AICredentialFieldNames.ApiKey, "<从 User Secrets 读取的开发密钥>")
]))
{
credentialStore.Set(
new IntegrationCredentialKey(
tenantId: "tenant-a",
providerKey: "AI:deepseek-dev",
environment: IntegrationEnvironments.Development),
credential);
}
// 每个业务请求建立自己的 Scope 和 IntegrationContext。
using var scope = provider.CreateScope();
var contextAccessor = scope.ServiceProvider.GetRequiredService<
IIntegrationContextAccessor>();
using (contextAccessor.Push(new IntegrationContext(
tenantId: "tenant-a",
environment: IntegrationEnvironments.Development)))
{
var kernelClient = scope.ServiceProvider
.GetRequiredService<ISemanticKernelClient>();
// 只会向模型暴露当前管道显式注册的 date_time 插件。
var answer = await kernelClient.SendMessageWithFunctionCallingAsync(
"今天的日期是什么?");
Console.WriteLine(answer);
}
基础与流式调用
using (contextAccessor.Push(new IntegrationContext(
tenantId: "tenant-a",
region: "cn",
environment: IntegrationEnvironments.Production)))
{
var answer = await client.SendMessageAsync(
"总结今天的业务异常",
cancellationToken: cancellationToken);
await foreach (var text in client.SendMessageStreamAsync(
"生成处置建议",
cancellationToken: cancellationToken))
{
await output.WriteAsync(text, cancellationToken);
}
}
单次 systemPrompt 覆盖为空或空白时使用配置默认值。空用户消息会快速失败。
显式插件
插件必须在启动时明确注册,不扫描程序集,也不自动暴露任意 public 方法:
public sealed class OrderQueryPlugin(IOrderReader reader)
{
[KernelFunction("query_order")]
[Description("按订单号读取当前租户的订单状态")]
public Task<OrderStatus> QueryOrderAsync(
string orderId,
CancellationToken cancellationToken)
=> reader.GetRequiredAsync(orderId, cancellationToken);
}
services.AddBitzSemanticKernelPlugin<OrderQueryPlugin>("orders");
命名管道的插件需要指定管道名:
services.AddBitzSemanticKernelPlugin<OrderQueryPlugin>(
pipelineName: "analysis",
pluginName: "orders");
插件名只允许 ASCII 字母、数字和下划线;同一管道重复名称会在解析时失败。插件实例由当前 Scope 的 DI 创建,因此插件内部仍必须从当前身份和租户重新执行授权,不能把“模型选择了该 工具”当作业务授权。
函数调用
var answer = await client.SendMessageWithFunctionCallingAsync(
"查询订单 A-100 的状态",
cancellationToken: cancellationToken);
该方法只把当前命名管道显式注册的插件暴露给模型,并限制最大迭代数和连续错误数。它会自动 执行模型选择的函数,因此只适合只读、幂等或已在插件内部完成审批的工具。
付款、删除、发信、签章、提交审批等有副作用操作,应使用
Bitzsoft.Integrations.AgentFramework 的 ApprovalRequiredAIFunction 与
ToolApprovalAgent;不要把高风险函数直接注册到本兼容层。
Prompt、Plugin Description、函数参数和函数结果都属于不可信输入。插件必须执行:
- 当前用户、租户、资源和操作级授权;
- 参数长度、格式、枚举和资源归属校验;
- SQL、Shell、HTML、路径和模板上下文的编码或参数化;
- 幂等键、超时、取消、速率限制和副作用审计。
直接使用 Kernel
client.Kernel 是当前 Scope 独享实例:
var result = await client.Kernel.InvokePromptAsync(
"将 {{$input}} 转换为正式商务语言",
new KernelArguments { ["input"] = sourceText },
cancellationToken);
兼容层会向 Kernel 提供不含凭据的 ChatClientMetadata。即使宿主自定义
IChatClient 没有实现元数据查询,也会使用无 endpoint/模型的安全回退值,因此
InvokePromptAsync 不会因 metadata 为空而失败。
不要缓存 Kernel 到 Singleton,也不要把它带出当前 Scope。若运行时动态添加插件,变更只对 当前实例有效;生产系统仍建议使用启动期显式注册,以便审计和部署复现。
审计与可观测性
聊天调用经过底层 Bitzsoft.Integrations.AI 管道,统一使用 OpenTelemetry、
Microsoft.Extensions.AI 日志和 Bitzsoft.Integrations.RequestLogging。本包不重复写
第二份模型请求日志。
RequestLogging 不强制截断请求或响应,兆级内容可完整交给宿主 Store。生产 Store 应自行
设计大字段或对象存储、加密、脱敏、访问控制、保留期限和删除流程。不要在普通应用日志中
输出 Prompt、函数参数、函数结果或模型完整响应。
与 Agent Framework 的边界
| 场景 | 推荐包 |
|---|---|
| Provider-neutral 聊天和 Embedding | Bitzsoft.Integrations.AI |
| 既有 Semantic Kernel Plugin / Prompt | Bitzsoft.Integrations.SemanticKernel |
| Agent、工具审批、持久化 Session | Bitzsoft.Integrations.AgentFramework |
| RAG、Qdrant、引用与访问控制 | Bitzsoft.Integrations.RAG |
| MCP Client / Server | Bitzsoft.Integrations.McpServer |
不要同时让 Semantic Kernel 与 Agent Framework 自动执行同一组工具,否则会产生重复函数 循环、审批绕过和不一致的会话状态。
从旧封装迁移
旧的 AddSemanticKernel、SemanticKernelOptions.ApiKey/Endpoint/ModelId 和运行时
ImportPluginFromType 已删除。迁移步骤:
- 使用
AddBitzChatClient注册 Provider、模型和凭据; - 使用
AddBitzSemanticKernel注册编排参数; - 使用
AddBitzSemanticKernelPlugin<T>显式注册插件; - 把 Singleton 消费方改为 Scoped 或在每次请求中创建 Scope;
- 对有副作用工具迁移到 Agent Framework 审批链。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Bitzsoft.Integrations.AI.Abstractions (>= 1.0.0-alpha.10)
- Microsoft.Extensions.AI (>= 10.8.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- Microsoft.SemanticKernel (>= 1.78.0)
-
net8.0
- Bitzsoft.Integrations.AI.Abstractions (>= 1.0.0-alpha.10)
- Microsoft.Extensions.AI (>= 10.8.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- Microsoft.SemanticKernel (>= 1.78.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Bitzsoft.Integrations.SemanticKernel:
| Package | Downloads |
|---|---|
|
Bitzsoft.Integrations.All
Bitzsoft 第三方集成聚合包 — net5.0 包含传统连接器,net8.0+ 额外包含受上游 TFM 限制的 AI 模块 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-alpha.10 | 43 | 7/26/2026 |
| 1.0.0-alpha.9 | 72 | 7/12/2026 |
| 1.0.0-alpha.8 | 311 | 7/1/2026 |
| 1.0.0-alpha.7 | 83 | 6/16/2026 |
| 1.0.0-alpha.6 | 75 | 6/16/2026 |
| 1.0.0-alpha.5 | 69 | 6/14/2026 |
| 1.0.0-alpha.3 | 76 | 6/7/2026 |
| 1.0.0-alpha.2 | 71 | 5/29/2026 |
| 1.0.0-alpha.1 | 62 | 5/28/2026 |