先说一个很多国内开发者可能都会碰到的现实困境:Semantic Kernel本身直接开箱可用的,只有OpenAI和Azure OpenAI两个连接器。对于无法直接访问国外大模型服务的开发者来说,这确实是个绕不开的门槛。但好消息是,SK在设计之初就考虑到了可扩展性,接入国内大模型(像通义千问、智谱清言这些)是完全可行的。接下来就以智谱AI的大模型为例,把整个过程拆解清楚。
由于SK官方只提供了两种连接器,想在本地利用智谱的模型能力,主要有四种路径可以走:
- 指定自定义的
Endpoint(服务端点) - 指定自定义的
OpenAIClient(客户端实例) - 使用像OneApi这样的统一接口层进行袋里
- 自行开发连接器(这里不展开,重点讲前三种)
注册智谱大模型
使用智谱大模型
#r "nuget: Microsoft.SemanticKernel"
指定自定义Endpoint
需要注意的是,这种方式目前属于实验性功能,使用前必须手动禁用相关的编译警告:#pragma warning disable SKEXP0010。完整代码示例如下:
#pragma warning disable SKEXP0010
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.Extensions.DependencyInjection;
// 引入交互式的内核命名空间,以便用户输入
using PolyglotKernel= Microsoft.DotNet.Interactive.Kernel;
var zhipuApiKey = await PolyglotKernel.GetInputAsync("请输入您的智谱API Key:");
// Create kernel builder
var builder = Kernel.CreateBuilder();
var zhipuEndpoint = new Uri("https://open.bigmodel.cn/api/paas/v4/");
builder.AddOpenAIChatCompletion(
modelId: "glm-4-flash",
// 可选模型编码:glm-4-plus、glm-4-0520、glm-4 、glm-4-air、glm-4-airx、glm-4-long、 glm-4-flash(免费)
apiKey: zhipuApiKey,
endpoint: zhipuEndpoint
);
// Build kernel
var kernel = builder.Build();
var response = await kernel.InvokePromptAsync("介绍下智谱AI的产品和服务");
response.Display();
指定自定义OpenAIClient
如果你希望对客户端有更细粒度的控制,比如自定义超时或袋里策略,自定义OpenAIClient是更推荐的做法。
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.Extensions.DependencyInjection;
using OpenAI;
using System.ClientModel;
// 引入交互式的内核命名空间,以便用户输入
using PolyglotKernel= Microsoft.DotNet.Interactive.Kernel;
var zhipuApiKey = await PolyglotKernel.GetInputAsync("请输入您的智谱API Key:");
// Create kernel builder
var builder = Kernel.CreateBuilder();
var zhipuEndpoint = new Uri("https://open.bigmodel.cn/api/paas/v4/");
OpenAIClientOptions clientOptions = new OpenAIClientOptions();
clientOptions.Endpoint = zhipuEndpoint;
// 创建自定义的OpenAI客户端
OpenAIClient client = new(new ApiKeyCredential(zhipuApiKey), clientOptions);
// Add OpenAI Chat completion
builder.AddOpenAIChatCompletion(
modelId: "glm-4-flash",
// 可选模型编码:glm-4-plus、glm-4-0520、glm-4 、glm-4-air、glm-4-airx、glm-4-long、 glm-4-flash(免费)
openAIClient: client
);
// Build kernel
var kernel = builder.Build();
var response = await kernel.InvokePromptAsync("智谱AI有哪些模型,请直接返回模型列表。");
response.Display();
使用OneApi对接流行大模型
OneApi的出现,很好地解决了不同模型间API差异带来的痛苦。它的原理很简单:开发者只需要遵循统一的OpenAI格式即可完成调用。本质上就是把OpenAI的网址换成OneApi系统的地址,把API Key换成在OneApi里分配的令牌。OneApi会在后台完成袋里转发,甚至还能帮你完成非标准格式的请求和返回体转换。整体的交互流程如下图所示:
graph LR
A(用户)
A --->|使用 One API 分发的 key 进行请求| B(One API)
B -->|中继请求| C(OpenAI)
B -->|中继请求| D(Azure)
B -->|中继请求| E(其他 OpenAI API 格式下游渠道)
B -->|中继并修改请求体和返回体| F(非 OpenAI API 格式下游渠道)
image-20250318165305625
使用Docker安装OneApi
用SQLite部署的方式非常轻量,一条命令就能搞定:
docker run --name one-api -d --restart always -p 3000:3000 -e TZ=Asia/Shanghai -v /home/data/one-api:/data justsong/one-api
部署成功后,用docker ps | grep one-api可以快速确认容器是否正常运行:
$ docker ps | grep one-api
12f025568eab justsong/one-api "/one-api" 3 minutes ago Up 3 minutes 0.0.0.0:3000->3000/tcp one-api
接下来直接访问 https://localhost:3000/ 就能打开OneApi的管理界面。默认的管理员账号密码是 root/123456,登录后就可以配置你想要对接的模型了。
#r "nuget: Microsoft.SemanticKernel"
对接OneAPI
有了OneApi之后,代码端的变化就很小了,本质上还是用OpenAI的接口协议去调用,只是地址和Key换了:
#pragma warning disable SKEXP0010
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.Extensions.DependencyInjection;
// 引入交互式的内核命名空间,以便用户输入
using PolyglotKernel= Microsoft.DotNet.Interactive.Kernel;
// var oneApiKey = await PolyglotKernel.GetInputAsync("请输入您的OneAPI Key:"); //这里就是oneapi的key
var oneApiKey = "sk-9y9939P3ufwHaltcB95d91F3D9D64303Ad799e991f4700F1";
// Create kernel builder
var builder = Kernel.CreateBuilder();
var oneApiEndpoint = new Uri("https://localhost:3000/v1");
// modelId,是oneapi的设置
builder.AddOpenAIChatCompletion(
modelId: "lite",
apiKey: oneApiKey,
endpoint: oneApiEndpoint
);
// Build kernel
var kernel = builder.Build();
var response = await kernel.InvokePromptAsync("介绍下OneApi的使用场景和优势");
response.Display();
t: oneApiEndpoint); // Build kernel var kernel = builder.Build(); var response = await kernel.InvokePromptAsync(“介绍下OneApi的使用场景和优势”); response.Display();