Kernel/KernelFunction/KernelPlugin/KernelArguments 四大核心
源码级别解析 · .NET SDK v1.x
2026-03-22 | 每日技术深度解读
Semantic Kernel 是微软开发的轻量级 AI 编排框架
核心职责:
设计理念: Skills (Plugin) = Functions + Prompt Templates
| 概念 | 职责 | 类比 |
|---|---|---|
| Kernel | AI 编排容器,管理服务和插件 | IoC Container |
| KernelFunction | 可执行的 AI 函数(Native/Prompt) | Delegate/Func<T> |
| KernelPlugin | 函数集合,组织相关 Skills | Module/Namespace |
| KernelArguments | 参数容器,携带执行上下文 | Dictionary + Settings |
namespace Microsoft.SemanticKernel;
public sealed class Kernel : IDisposable
{
// 核心属性
public KernelPluginCollection Plugins { get; }
public IServiceProvider Services { get; }
public ILoggerFactory LoggerFactory { get; }
public CultureInfo Culture { get; set; }
// 核心方法
public static Kernel CreateBuilder() => new KernelBuilder();
public FunctionResult Invoke(
KernelFunction function,
KernelArguments? arguments = null);
public Task<FunctionResult> InvokeAsync(
KernelFunction function,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default);
public Task<FunctionResult> InvokePromptAsync(
string promptTemplate,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default);
}
public sealed class Kernel
{
private readonly IServiceProvider _serviceProvider;
private readonly KernelPluginCollection _plugins;
private readonly List<IFunctionInvocationFilter> _functionFilters;
internal Kernel(
IServiceProvider? serviceProvider = null,
IReadOnlyKernelPluginCollection? plugins = null)
{
this._serviceProvider = serviceProvider ?? EmptyServiceProvider.Instance;
this._plugins = new KernelPluginCollection(this, plugins);
this._functionFilters = new List<IFunctionInvocationFilter>();
// 从服务容器获取 Filters
var filters = this._serviceProvider
.GetServices<IFunctionInvocationFilter>();
this._functionFilters.AddRange(filters);
}
public void Dispose()
{
(this._serviceProvider as IDisposable)?.Dispose();
}
}
// 使用 KernelBuilder 构建
var kernel = Kernel.CreateBuilder()
.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4",
endpoint: "https://xxx.openai.azure.com/",
apiKey: "...")
.AddPlugin(new MathPlugin(), "MathPlugin")
.Build();
// KernelBuilder 实现
public sealed class KernelBuilder : IKernelBuilder
{
private readonly IServiceCollection _services = new ServiceCollection();
private readonly List<KernelPlugin> _plugins = new();
public IKernelBuilder AddPlugin(KernelPlugin plugin)
{
this._plugins.Add(plugin);
return this;
}
public Kernel Build()
{
var serviceProvider = this._services.BuildServiceProvider();
return new Kernel(serviceProvider, this._plugins);
}
}
public sealed class KernelPluginCollection
: ICollection<KernelPlugin>, IReadOnlyKernelPluginCollection
{
private readonly Kernel _kernel;
private readonly Dictionary<string, KernelPlugin> _plugins;
public void Add(KernelPlugin plugin)
{
Verify.NotNull(plugin);
VerifyPluginsNotReadOnly();
// 克隆所有函数,绑定到当前 Kernel
var clonedPlugin = plugin.CloneForKernel(this._kernel);
this._plugins[clonedPlugin.Name] = clonedPlugin;
}
public KernelPlugin this[string name] => this._plugins[name];
public bool TryGetPlugin(string name, [NotNullWhen(true)] out KernelPlugin? plugin)
=> this._plugins.TryGetValue(name, out plugin);
public KernelFunction GetFunction(string pluginName, string functionName)
{
var plugin = this[pluginName];
return plugin[functionName];
}
}
public async Task<FunctionResult> InvokeAsync(
KernelFunction function,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default)
{
Verify.NotNull(function);
arguments ??= new KernelArguments();
// 创建 FunctionInvocationContext
var context = new FunctionInvocationContext(
this, function, arguments, new FunctionResult(function, this.Culture));
// 执行 Filter 管道
await this.OnFunctionInvocationAsync(
function, arguments, context.Result,
isStreaming: false,
async ctx => {
// 核心执行逻辑
ctx.Result = await function.InvokeAsync(
this, ctx.Arguments, cancellationToken);
},
cancellationToken);
return context.Result;
}
public Task<FunctionResult> InvokePromptAsync(
string promptTemplate,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default)
{
Verify.NotNull(promptTemplate);
// 从 Prompt 模板创建 KernelFunction
var function = KernelFunctionFactory.CreateFromPrompt(
promptTemplate,
promptTemplateFactory: this.PromptTemplateFactory);
// 调用函数
return this.InvokeAsync(function, arguments, cancellationToken);
}
// 使用示例
var result = await kernel.InvokePromptAsync(
"Translate this to {{$language}}: {{$text}}",
new() { ["language"] = "French", ["text"] = "Hello" });
Console.WriteLine(result); // "Bonjour"
public abstract class KernelFunction : FullyQualifiedAIFunction
{
// 核心属性
public virtual string Name => this.Metadata.Name;
public virtual string? PluginName => this.Metadata.PluginName;
public override string Description => this.Metadata.Description;
public KernelFunctionMetadata Metadata { get; }
public IReadOnlyDictionary<string, PromptExecutionSettings>? ExecutionSettings { get; }
// 核心方法
public Task<FunctionResult> InvokeAsync(
Kernel kernel,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default);
public IAsyncEnumerable<StreamingKernelContent> InvokeStreamingAsync(
Kernel kernel,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default);
// 抽象方法
protected abstract ValueTask<FunctionResult> InvokeCoreAsync(
Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken);
public abstract KernelFunction Clone(string? pluginName = null);
}
protected KernelFunction(
string name,
string? pluginName,
string description,
IReadOnlyList<KernelParameterMetadata> parameters,
KernelReturnParameterMetadata? returnParameter = null,
Dictionary<string, PromptExecutionSettings>? executionSettings = null)
: base(new KernelFunctionMetadata(name)
{
PluginName = pluginName,
Description = description,
Parameters = KernelVerify.ParametersUniqueness(parameters),
ReturnParameter = returnParameter ?? KernelReturnParameterMetadata.Empty,
})
{
// 构建 JSON Schema(用于 Function Calling)
this.BuildFunctionSchema();
// 冻结 ExecutionSettings
if (executionSettings is not null)
{
this.ExecutionSettings = executionSettings.ToDictionary(
entry => entry.Key,
entry => { var clone = entry.Value.Clone(); clone.Freeze(); return clone; });
}
}
public async Task<FunctionResult> InvokeAsync(
Kernel kernel,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default)
{
kernel ??= this.Kernel;
Verify.NotNull(kernel);
arguments ??= [];
using var activity = this.StartFunctionActivity(...);
var logger = kernel.LoggerFactory.CreateLogger<KernelFunction>();
// 调用 Kernel 的 Filter 管道
var invocationContext = await kernel.OnFunctionInvocationAsync(
this, arguments, new FunctionResult(this, kernel.Culture),
isStreaming: false,
async context => {
// 核心:调用子类实现
context.Result = await this.InvokeCoreAsync(
kernel, context.Arguments, cancellationToken);
},
cancellationToken);
return invocationContext.Result;
}
public async IAsyncEnumerable<TResult> InvokeStreamingAsync<TResult>(
Kernel kernel,
KernelArguments? arguments = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
kernel ??= this.Kernel;
Verify.NotNull(kernel);
arguments ??= [];
var invocationContext = await kernel.OnFunctionInvocationAsync(
this, arguments, new FunctionResult(this, kernel.Culture),
isStreaming: true,
context => {
// 获取流式枚举器
var enumerable = this.InvokeStreamingCoreAsync<TResult>(
kernel, context.Arguments, cancellationToken);
context.Result = new FunctionResult(this, enumerable, kernel.Culture);
return Task.CompletedTask;
},
cancellationToken);
// 流式返回结果
var enumerator = invocationContext.Result
.GetValue<IAsyncEnumerable<TResult>>()!
.GetAsyncEnumerator(cancellationToken);
await using (enumerator.ConfigureAwait(false))
{
while (await enumerator.MoveNextAsync().ConfigureAwait(false))
{
yield return enumerator.Current;
}
}
}
public sealed class KernelFunctionMetadata : AIFunctionMetadata
{
public string Name { get; init; }
public string? PluginName { get; init; }
public string Description { get; init; }
public IReadOnlyList<KernelParameterMetadata> Parameters { get; init; }
public KernelReturnParameterMetadata ReturnParameter { get; init; }
public ReadOnlyDictionary<string, object?> AdditionalProperties { get; init; }
// 用于 Function Calling 的完整名称
public string FullyQualifiedName =>
string.IsNullOrWhiteSpace(this.PluginName)
? this.Name
: $"{this.PluginName}.{this.Name}";
// 创建 JSON Schema
public override JsonElement JsonSchema => this._jsonSchema;
}
[DebuggerDisplay("Name = {Name}, Functions = {FunctionCount}")]
public abstract class KernelPlugin : IEnumerable<KernelFunction>
{
public string Name { get; }
public string Description { get; }
public abstract int FunctionCount { get; }
protected KernelPlugin(string name, string? description = null)
{
KernelVerify.ValidPluginName(name);
this.Name = name;
this.Description = !string.IsNullOrWhiteSpace(description)
? description! : "";
}
// 索引器:通过名称获取函数
public KernelFunction this[string functionName] =>
this.TryGetFunction(functionName, out var function)
? function
: throw new KeyNotFoundException($"Function not found: {functionName}");
// 抽象方法
public abstract bool TryGetFunction(
string name, [NotNullWhen(true)] out KernelFunction? function);
public abstract IEnumerator<KernelFunction> GetEnumerator();
}
public sealed class KernelPluginCollection : ICollection<KernelPlugin>
{
private readonly Kernel _kernel;
private readonly Dictionary<string, KernelPlugin> _plugins = new();
public int Count => this._plugins.Count;
public bool IsReadOnly { get; private set; }
public void Add(KernelPlugin plugin)
{
Verify.NotNull(plugin);
if (this._plugins.ContainsKey(plugin.Name))
throw new ArgumentException($"Plugin already exists: {plugin.Name}");
// 克隆插件,绑定到当前 Kernel
var cloned = plugin.CloneForKernel(this._kernel);
this._plugins[cloned.Name] = cloned;
}
public void Add(string pluginName, IEnumerable<KernelFunction> functions)
{
var plugin = KernelPluginFactory.CreateFromFunctions(pluginName, functions);
this.Add(plugin);
}
public bool Contains(string pluginName) => this._plugins.ContainsKey(pluginName);
}
internal sealed class DefaultKernelPlugin : KernelPlugin
{
private readonly Dictionary<string, KernelFunction> _functions;
public override int FunctionCount => this._functions.Count;
internal DefaultKernelPlugin(
string name,
string? description,
IEnumerable<KernelFunction> functions)
: base(name, description)
{
this._functions = new Dictionary<string, KernelFunction>(
StringComparer.OrdinalIgnoreCase);
foreach (var function in functions)
{
var cloned = function.Clone(this.Name);
this._functions[cloned.Name] = cloned;
}
}
public override bool TryGetFunction(
string name, [NotNullWhen(true)] out KernelFunction? function)
=> this._functions.TryGetValue(name, out function);
public override IEnumerator<KernelFunction> GetEnumerator()
=> this._functions.Values.GetEnumerator();
}
public sealed class KernelArguments : AIFunctionArguments
{
private IReadOnlyDictionary<string, PromptExecutionSettings>? _executionSettings;
// 继承自 Dictionary<string, object?>
public ICollection<string> Names => this.Keys;
public IReadOnlyDictionary<string, PromptExecutionSettings>? ExecutionSettings
{
get => this._executionSettings;
set
{
// 验证 ServiceId 与 Key 匹配
if (value is { Count: > 0 })
{
foreach (var kv in value!)
{
if (!string.IsNullOrWhiteSpace(kv.Value.ServiceId)
&& kv.Key != kv.Value.ServiceId)
{
throw new ArgumentException(
$"Service id '{kv.Value.ServiceId}' must match key '{kv.Key}'");
}
}
}
this._executionSettings = value;
}
}
public bool ContainsName(string name)
{
Verify.NotNull(name);
return base.ContainsKey(name);
}
}
// 创建参数容器
var arguments = new KernelArguments
{
["topic"] = "AI",
["language"] = "Chinese"
};
// 添加 ExecutionSettings
arguments.ExecutionSettings = new Dictionary<string, PromptExecutionSettings>
{
["default"] = new OpenAIPromptExecutionSettings
{
MaxTokens = 1000,
Temperature = 0.7
}
};
// 在函数中使用
var result = await kernel.InvokeAsync(function, arguments);
// 获取结果
var text = result.GetValue<string>();
// 获取特定类型的设置
var settings = arguments.ExecutionSettings?
.GetSettings<OpenAIPromptExecutionSettings>();
public sealed class FunctionResult
{
public KernelFunction Function { get; }
public object? Value { get; internal set; }
public CultureInfo Culture { get; }
internal FunctionResult(
KernelFunction function,
object? value = null,
CultureInfo? culture = null)
{
this.Function = function;
this.Value = value;
this.Culture = culture ?? CultureInfo.InvariantCulture;
}
// 获取类型化值
public T? GetValue<T>()
{
if (this.Value is T typedValue) return typedValue;
if (this.Value is null) return default;
// 尝试转换
var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter.CanConvertFrom(this.Value.GetType()))
return (T?)converter.ConvertFrom(this.Value);
throw new InvalidCastException(
$"Cannot cast {this.Value.GetType()} to {typeof(T)}");
}
public override string ToString() => this.Value?.ToString() ?? string.Empty;
}
namespace Microsoft.SemanticKernel;
public interface IPromptTemplate
{
/// <summary>
/// 渲染 Prompt 模板
/// </summary>
Task<string> RenderAsync(
Kernel kernel,
KernelArguments? arguments = null,
CancellationToken cancellationToken = default);
}
// PromptTemplateConfig 配置
public sealed class PromptTemplateConfig
{
public string Template { get; set; } = string.Empty;
public string TemplateFormat { get; set; } = "semantic-kernel";
public string? Name { get; set; }
public string? Description { get; set; }
public List<InputVariable> InputVariables { get; set; } = new();
public List<PromptExecutionSettings> ExecutionSettings { get; set; } = new();
}
// 使用 JSON 配置
var config = new PromptTemplateConfig
{
Name = "Summarize",
Description = "Summarize the input text",
Template = """
Summarize the following text in {{$language}}:
{{$input}}
Summary:
""",
InputVariables = new()
{
new() { Name = "input", Description = "Text to summarize", IsRequired = true },
new() { Name = "language", Description = "Output language", Default = "English" }
},
ExecutionSettings = new()
{
new OpenAIPromptExecutionSettings
{
MaxTokens = 500,
Temperature = 0.3
}
}
};
// 从配置创建函数
var function = KernelFunctionFactory.CreateFromPrompt(config);
public static class KernelFunctionFactory
{
public static KernelFunction CreateFromMethod(
Delegate method,
string? functionName = null,
string? description = null,
IEnumerable<KernelParameterMetadata>? parameters = null,
KernelReturnParameterMetadata? returnParameter = null)
{
return new KernelFunctionFromMethod(
method, functionName, description, parameters, returnParameter);
}
}
// 使用示例
[KernelFunction("add")]
[Description("Add two numbers")]
public int Add(
[Description("First number")] int a,
[Description("Second number")] int b)
{
return a + b;
}
var function = KernelFunctionFactory.CreateFromMethod(
(int a, int b) => a + b,
functionName: "add",
description: "Add two numbers");
internal sealed class KernelFunctionFromPrompt : KernelFunction
{
private readonly IPromptTemplate _promptTemplate;
private readonly ITextGenerationService? _textGenerationService;
protected override async ValueTask<FunctionResult> InvokeCoreAsync(
Kernel kernel,
KernelArguments arguments,
CancellationToken cancellationToken)
{
// 1. 渲染 Prompt
var renderedPrompt = await this._promptTemplate
.RenderAsync(kernel, arguments, cancellationToken);
// 2. 获取 AI 服务
var service = this._textGenerationService
?? kernel.GetRequiredService<ITextGenerationService>();
// 3. 获取执行设置
var settings = arguments.ExecutionSettings?
.GetSettings<PromptExecutionSettings>()
?? new PromptExecutionSettings();
// 4. 调用 AI
var response = await service.GetTextContentsAsync(
renderedPrompt, settings, cancellationToken);
// 5. 返回结果
return new FunctionResult(this, response.FirstOrDefault()?.Text, kernel.Culture);
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class KernelFunctionAttribute : Attribute
{
public string? Name { get; }
public string? Description { get; set; }
public KernelFunctionAttribute(string? name = null)
{
this.Name = name;
}
}
// 使用示例
public class WeatherPlugin
{
[KernelFunction("get_weather")]
[Description("Get weather information for a city")]
public async Task<string> GetWeatherAsync(
[Description("City name")] string city,
[Description("Temperature unit (celsius/fahrenheit)")] string unit = "celsius")
{
// Implementation
return $"Weather in {city}: 25°{unit[0].ToString().ToUpper()}";
}
}
// 导入插件
var plugin = kernel.ImportPluginFromType<WeatherPlugin>("Weather");
public sealed class KernelParameterMetadata
{
public string Name { get; init; }
public string? Description { get; init; }
public Type? ParameterType { get; init; }
public bool IsRequired { get; init; }
public object? DefaultValue { get; init; }
public KernelJsonSchema? Schema { get; init; }
// 从 ParameterInfo 创建
public static KernelParameterMetadata FromParameterInfo(
ParameterInfo parameter,
JsonSerializerOptions? jsonSerializerOptions = null)
{
var descriptionAttr = parameter.GetCustomAttribute<DescriptionAttribute>();
return new KernelParameterMetadata(parameter.Name!)
{
Description = descriptionAttr?.Description,
ParameterType = parameter.ParameterType,
IsRequired = !parameter.HasDefaultValue,
DefaultValue = parameter.DefaultValue,
Schema = KernelJsonSchema.Create(parameter.ParameterType, jsonSerializerOptions)
};
}
}
public sealed class KernelReturnParameterMetadata
{
public string? Description { get; init; }
public Type? ParameterType { get; init; }
public KernelJsonSchema? Schema { get; init; }
public static KernelReturnParameterMetadata Empty { get; } = new();
// 从 MethodInfo 创建
public static KernelReturnParameterMetadata FromMethodInfo(
MethodInfo method,
JsonSerializerOptions? jsonSerializerOptions = null)
{
var returnAttr = method.ReturnParameter
.GetCustomAttribute<DescriptionAttribute>();
return new KernelReturnParameterMetadata
{
Description = returnAttr?.Description,
ParameterType = method.ReturnType,
Schema = KernelJsonSchema.Create(method.ReturnType, jsonSerializerOptions)
};
}
}
// 使用示例
[KernelFunction]
[return: Description("The sum of the two numbers")]
public int Add(int a, int b) => a + b;
public class PromptExecutionSettings
{
public const string DefaultServiceId = "default";
public string? ServiceId { get; set; }
public int? MaxTokens { get; set; }
public double? Temperature { get; set; }
public double? TopP { get; set; }
public double? FrequencyPenalty { get; set; }
public double? PresencePenalty { get; set; }
public IList<string>? StopSequences { get; set; }
public bool IsFrozen { get; private set; }
public void Freeze() => this.IsFrozen = true;
public virtual PromptExecutionSettings Clone()
{
return new PromptExecutionSettings
{
ServiceId = this.ServiceId,
MaxTokens = this.MaxTokens,
Temperature = this.Temperature,
TopP = this.TopP,
// ...
};
}
}
// OpenAI 特定设置
public class OpenAIPromptExecutionSettings : PromptExecutionSettings
{
public string? ChatSystemPrompt { get; set; }
public bool? Logprobs { get; set; }
public ToolCallBehavior? ToolCallBehavior { get; set; }
}
public abstract class KernelFunction : FullyQualifiedAIFunction
{
// 继承自 AIFunction
public override JsonElement JsonSchema => this._jsonSchema;
public override MethodInfo? UnderlyingMethod => this._underlyingMethod;
// 转换为 AIFunction
[Experimental("SKEXP0001")]
[Obsolete("Use Clone(Kernel) instead")]
public AIFunction AsAIFunction(Kernel? kernel = null)
{
return new KernelAIFunction(this, kernel);
}
// 内部包装类
private sealed class KernelAIFunction : AIFunction
{
private readonly KernelFunction _kernelFunction;
private readonly Kernel? _kernel;
protected override async ValueTask<object?> InvokeCoreAsync(
AIFunctionArguments? arguments, CancellationToken cancellationToken)
{
var kernelArgs = new KernelArguments(arguments ?? new());
var result = await this._kernelFunction
.InvokeAsync(this._kernel ?? new(), kernelArgs, cancellationToken);
return result.Value;
}
}
}
public sealed class FunctionInvocationContext
{
public Kernel Kernel { get; }
public KernelFunction Function { get; }
public KernelArguments Arguments { get; set; }
public FunctionResult Result { get; set; }
public bool IsStreaming { get; }
public CancellationToken CancellationToken { get; }
internal FunctionInvocationContext(
Kernel kernel,
KernelFunction function,
KernelArguments arguments,
FunctionResult result,
bool isStreaming = false,
CancellationToken cancellationToken = default)
{
this.Kernel = kernel;
this.Function = function;
this.Arguments = arguments;
this.Result = result;
this.IsStreaming = isStreaming;
this.CancellationToken = cancellationToken;
}
}
public interface IFunctionInvocationFilter
{
Task OnFunctionInvocationAsync(
FunctionInvocationContext context,
Func<FunctionInvocationContext, Task> next);
}
// 实现示例:日志 Filter
public class LoggingFilter : IFunctionInvocationFilter
{
private readonly ILogger _logger;
public LoggingFilter(ILogger<LoggingFilter> logger)
{
this._logger = logger;
}
public async Task OnFunctionInvocationAsync(
FunctionInvocationContext context,
Func<FunctionInvocationContext, Task> next)
{
this._logger.LogInformation(
"Invoking {Plugin}.{Function}",
context.Function.PluginName, context.Function.Name);
await next(context);
this._logger.LogInformation(
"Result: {Result}", context.Result.ToString());
}
}
internal async Task<FunctionInvocationContext> OnFunctionInvocationAsync(
KernelFunction function,
KernelArguments arguments,
FunctionResult result,
bool isStreaming,
Func<FunctionInvocationContext, Task> invokeCore,
CancellationToken cancellationToken)
{
var context = new FunctionInvocationContext(
this, function, arguments, result, isStreaming, cancellationToken);
// 构建 Filter 委托链
Func<FunctionInvocationContext, Task> pipeline = invokeCore;
foreach (var filter in this._functionFilters.AsEnumerable().Reverse())
{
var next = pipeline;
pipeline = ctx => filter.OnFunctionInvocationAsync(ctx, next);
}
// 执行管道
await pipeline(context);
return context;
}
// 安装 NuGet: Microsoft.SemanticKernel.PromptTemplate.Handlebars
var builder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4", "api-key");
builder.Services.AddSingleton<IPromptTemplateFactory, HandlebarsPromptTemplateFactory>();
var kernel = builder.Build();
// Handlebars 模板
var template = """
{{#each messages}}
{{role}}: {{content}}
{{/each}}
Assistant:
""";
var function = KernelFunctionFactory.CreateFromPrompt(
template,
templateFormat: "handlebars");
var result = await kernel.InvokeAsync(function, new()
{
["messages"] = new[]
{
new { role = "User", content = "Hello" },
new { role = "Assistant", content = "Hi there!" }
}
});
// 安装 NuGet: Microsoft.SemanticKernel.PromptTemplate.Liquid
var builder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4", "api-key");
builder.Services.AddSingleton<IPromptTemplateFactory, LiquidPromptTemplateFactory>();
var kernel = builder.Build();
// Liquid 模板
var template = """
{% for item in items %}
- {{ item.name }}: {{ item.value }}
{% endfor %}
Total: {{ items | size }} items
""";
var function = KernelFunctionFactory.CreateFromPrompt(
template,
templateFormat: "liquid");
var result = await kernel.InvokeAsync(function, new()
{
["items"] = new[]
{
new { name = "Apple", value = 10 },
new { name = "Banana", value = 20 }
}
});
Memory 是 Semantic Kernel 的向量存储抽象层
public interface IVectorStore
{
IVectorStoreRecordCollection<TKey, TRecord> GetCollection<
TKey, TRecord>(string name, VectorStoreRecordDefinition? definition = null)
where TKey : notnull;
Task<bool> CollectionExistsAsync(string name, CancellationToken cancellationToken = default);
Task CreateCollectionAsync(string name, CancellationToken cancellationToken = default);
Task DeleteCollectionAsync(string name, CancellationToken cancellationToken = default);
}
// 支持的存储后端
// - Azure AI Search
// - Qdrant
// - Pinecone
// - Chroma
// - Redis
// - In-Memory (开发用)
public interface ITextEmbeddingGenerationService : IAIService
{
Task<IReadOnlyList<ReadOnlyMemory<float>>> GenerateEmbeddingsAsync(
IEnumerable<string> data,
Kernel? kernel = null,
CancellationToken cancellationToken = default);
}
// 使用示例
var embeddingService = kernel.GetRequiredService<ITextEmbeddingGenerationService>();
var embeddings = await embeddingService.GenerateEmbeddingsAsync(
new[] { "Hello world", "Semantic Kernel is great" });
Console.WriteLine($"Embedding dimension: {embeddings[0].Length}");
// 输出: Embedding dimension: 1536 (for text-embedding-ada-002)
// 保存到向量存储
var collection = vectorStore.GetCollection<string, DataModel>("documents");
await collection.UpsertAsync(new DataModel
{
Id = "doc1",
Text = "Hello world",
Vector = embeddings[0]
});
public interface IVectorStoreRecordCollection<TKey, TRecord>
where TKey : notnull
{
string CollectionName { get; }
Task<TRecord?> GetAsync(TKey key, GetRecordOptions? options = null, CancellationToken cancellationToken = default);
Task<IReadOnlyList<TRecord?>> GetBatchAsync(IEnumerable<TKey> keys, GetRecordOptions? options = null, CancellationToken cancellationToken = default);
Task UpsertAsync(TRecord record, CancellationToken cancellationToken = default);
Task UpsertBatchAsync(IEnumerable<TRecord> records, CancellationToken cancellationToken = default);
Task DeleteAsync(TKey key, CancellationToken cancellationToken = default);
Task<VectorSearchResults<TRecord>> VectorizedSearchAsync(
ReadOnlyMemory<float> vector,
VectorSearchOptions? options = null,
CancellationToken cancellationToken = default);
}
// 使用示例
var searchResults = await collection.VectorizedSearchAsync(
queryEmbedding,
new VectorSearchOptions { Top = 5 });
await foreach (var result in searchResults.Results)
{
Console.WriteLine($"Score: {result.Score}, Text: {result.Record.Text}");
}
// 注册多个 AI 服务
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4", "openai-key", serviceId: "openai")
.AddAzureOpenAIChatCompletion("gpt-4", "endpoint", "azure-key", serviceId: "azure")
.Build();
// 获取特定服务
var openAIService = kernel.GetRequiredService<IChatCompletionService>("openai");
var azureService = kernel.GetRequiredService<IChatCompletionService>("azure");
// 通过 ExecutionSettings 选择服务
var arguments = new KernelArguments
{
ExecutionSettings = new Dictionary<string, PromptExecutionSettings>
{
["azure"] = new OpenAIPromptExecutionSettings { MaxTokens = 1000 }
}
};
// 执行时使用指定服务
var result = await kernel.InvokeAsync(function, arguments);
public interface IChatCompletionService : IAIService
{
IReadOnlyDictionary<string, object?> Attributes { get; }
Task<IReadOnlyList<ChatMessageContent>> GetChatMessageContentsAsync(
ChatHistory chatHistory,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default);
IAsyncEnumerable<StreamingChatMessageContent> GetStreamingChatMessageContentsAsync(
ChatHistory chatHistory,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default);
}
// 使用示例
var chatService = kernel.GetRequiredService<IChatCompletionService>();
var history = new ChatHistory();
history.AddUserMessage("Hello!");
var response = await chatService.GetChatMessageContentsAsync(history);
Console.WriteLine(response[0].Content);
public interface ITextGenerationService : IAIService
{
IReadOnlyDictionary<string, object?> Attributes { get; }
Task<IReadOnlyList<TextContent>> GetTextContentsAsync(
string prompt,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default);
IAsyncEnumerable<StreamingTextContent> GetStreamingTextContentsAsync(
string prompt,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default);
}
// 使用示例
var textService = kernel.GetRequiredService<ITextGenerationService>();
var results = await textService.GetTextContentsAsync(
"Translate to French: Hello",
new OpenAIPromptExecutionSettings { MaxTokens = 50 });
Console.WriteLine(results[0].Text); // "Bonjour"
// 流式调用 Chat
var chatService = kernel.GetRequiredService<IChatCompletionService>();
var history = new ChatHistory();
history.AddUserMessage("Tell me a story");
await foreach (var content in chatService.GetStreamingChatMessageContentsAsync(history))
{
Console.Write(content.Content);
}
// 流式调用 KernelFunction
await foreach (var chunk in kernel.InvokeStreamingAsync<StreamingKernelContent>(function))
{
Console.Write(chunk);
}
// 带更新的流式调用
var fullContent = new StringBuilder();
await foreach (var update in function.InvokeStreamingAsync<StreamingKernelContent>(kernel))
{
fullContent.Append(update);
Console.WriteLine($"Progress: {fullContent.Length} chars");
}
// 注册插件
kernel.ImportPluginFromType<WeatherPlugin>("Weather");
kernel.ImportPluginFromType<CalendarPlugin>("Calendar");
// 启用 Auto Function Calling
var settings = new OpenAIPromptExecutionSettings
{
MaxTokens = 1000,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};
// 自动调用插件函数
var result = await kernel.InvokePromptAsync(
"What's the weather in Beijing and my next meeting?",
new KernelArguments(settings));
// 内部流程:
// 1. LLM 返回 tool_calls: ["Weather.get_weather", "Calendar.get_next_meeting"]
// 2. SK 自动调用对应插件
// 3. 将结果发回 LLM
// 4. LLM 生成最终回答
// 方式1: 从类型导入
kernel.ImportPluginFromType<MyPlugin>("MyPlugin");
// 方式2: 从对象导入
kernel.ImportPluginFromObject(new MyPlugin(), "MyPlugin");
// 方式3: 从方法创建
kernel.ImportPluginFromFunctions("Math", new[]
{
KernelFunctionFactory.CreateFromMethod((int a, int b) => a + b, "Add"),
KernelFunctionFactory.CreateFromMethod((int a, int b) => a * b, "Multiply")
});
// 方式4: 从 Prompt 文件导入(YAML)
kernel.ImportPluginFromPromptDirectory("./Plugins/MyPlugin");
// 方式5: 从 OpenAPI 导入
kernel.ImportPluginFromOpenApiAsync("PetStore", "https://petstore.swagger.io/v2/swagger.json");
// 使用导入的插件
var result = await kernel.InvokeAsync(
kernel.Plugins["MyPlugin"]["MyFunction"],
new() { ["input"] = "test" });
var kernel = Kernel.CreateBuilder()
.AddAzureOpenAITextEmbeddingGeneration("text-embedding-ada-002", endpoint, key)
.AddAzureOpenAIChatCompletion("gpt-4", endpoint, key)
.Build();
// 导入文档插件
var vectorStore = new InMemoryVectorStore();
var collection = vectorStore.GetCollection<string, Document>("docs");
await collection.CreateCollectionIfNotExistsAsync();
// 创建 RAG 函数
var ragFunction = kernel.CreateFunctionFromPrompt("""
Use the following context to answer the question.
Context:
{{#each documents}}
- {{this}}
{{/each}}
Question: {{$question}}
Answer:
""", templateFormat: "handlebars");
// 执行 RAG
var question = "What is Semantic Kernel?";
var embedding = await kernel.InvokeAsync<ReadOnlyMemory<float>>(
embeddingFunction, new() { ["input"] = question });
var searchResults = await collection.VectorizedSearchAsync(embedding, new() { Top = 5 });
var answer = await kernel.InvokeAsync(ragFunction, new()
{
["question"] = question,
["documents"] = searchResults.Results.Select(r => r.Record.Content).ToList()
});
// 1. 复用 Kernel 实例
// ❌ 每次请求创建新 Kernel
// ✅ 使用单例 Kernel
// 2. 批量处理
var tasks = inputs.Select(input =>
kernel.InvokeAsync(function, new() { ["input"] = input }));
var results = await Task.WhenAll(tasks);
// 3. 使用流式输出减少延迟
await foreach (var chunk in kernel.InvokeStreamingAsync(function))
{
// 立即返回部分结果
yield return chunk;
}
// 4. 缓存 Embedding
var embeddingCache = new Dictionary<string, ReadOnlyMemory<float>>();
// 5. 禁用不需要的 Filter
var kernel = Kernel.CreateBuilder()
.ConfigureServices(s => s.RemoveAll<IFunctionInvocationFilter>())
.Build();
| 框架 | 语言 | 特点 | 适用场景 |
|---|---|---|---|
| Semantic Kernel | C#/Python/Java | 插件化、企业级 | .NET 企业应用 |
| LangChain | Python/JS | 生态丰富、社区大 | 快速原型 |
| AutoGen | Python/.NET | 多 Agent 协作 | 复杂 Agent 系统 |
| CrewAI | Python | 角色扮演、团队协作 | 多角色任务 |
| LlamaIndex | Python | RAG 专用 | 知识库应用 |
Microsoft.Extensions.AI 统一抽象 + 多语言支持
感谢阅读!
访问 https://atcfu.com/ai-articles/semantic-kernel/ 回顾本文