提供用于语言模型和服务的客户端的 .NET 库可以提供IChatClient和IEmbeddingGenerator<TInput,TEmbedding>接口的实现。 然后,接口的任何使用者都可以通过抽象与这些模型和服务无缝互作。
IChatClient
接口
IChatClient 接口定义一个客户端抽象,负责与提供聊天功能的 AI 服务交互。 它包括发送和接收具有多模式内容(如文本、图像和音频)的消息的方法,无论是作为一个完整的集合还是增量流式传输。 此外,它还允许检索由客户端或其基础服务提供的强类型服务。
以下示例实现 IChatClient
以显示一般结构。
using System.Runtime.CompilerServices;
using Microsoft.Extensions.AI;
public sealed class SampleChatClient(Uri endpoint, string modelId)
: IChatClient
{
public ChatClientMetadata Metadata { get; } =
new(nameof(SampleChatClient), endpoint, modelId);
public async Task<ChatResponse> GetResponseAsync(
IEnumerable<ChatMessage> chatMessages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
{
// Simulate some operation.
await Task.Delay(300, cancellationToken);
// Return a sample chat completion response randomly.
string[] responses =
[
"This is the first sample response.",
"Here is another example of a response message.",
"This is yet another response message."
];
return new(new ChatMessage(
ChatRole.Assistant,
responses[Random.Shared.Next(responses.Length)]
));
}
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
IEnumerable<ChatMessage> chatMessages,
ChatOptions? options = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
// Simulate streaming by yielding messages one by one.
string[] words = ["This ", "is ", "the ", "response ", "for ", "the ", "request."];
foreach (string word in words)
{
// Simulate some operation.
await Task.Delay(100, cancellationToken);
// Yield the next message in the response.
yield return new ChatResponseUpdate(ChatRole.Assistant, word);
}
}
public object? GetService(Type serviceType, object? serviceKey) => this;
public TService? GetService<TService>(object? key = null)
where TService : class => this as TService;
void IDisposable.Dispose() { }
}
有关 IChatClient
的更实际的具体实现,请参阅:
IEmbeddingGenerator<TInput,TEmbedding>
接口
IEmbeddingGenerator<TInput,TEmbedding> 接口表示嵌入的泛型生成器。 此处,TInput
是嵌入的输入值的类型,TEmbedding
是生成的嵌入的类型,它继承自 Embedding 类。
Embedding
类充当由 IEmbeddingGenerator<TInput,TEmbedding>
生成的嵌入的基类。 它旨在存储和管理与嵌入相关的元数据和数据。 派生类型(例如 Embedding<T>
)提供具体的嵌入向量数据。 例如,Embedding<float>
公开一个 ReadOnlyMemory<float> Vector { get; }
属性以便访问其嵌入的数据。
IEmbeddingGenerator<TInput,TEmbedding>
接口定义一种方法,以异步方式为输入值的集合生成嵌入,并提供可选配置和取消支持。 它还提供描述生成器的元数据,并允许检索可由生成器或其基础服务提供的强类型服务。
以下代码演示如何类 SampleEmbeddingGenerator
实现 IEmbeddingGenerator<TInput,TEmbedding>
接口。 它有一个接受终结点和模型 ID 的主构造函数,用于标识生成器。 它还实现 GenerateAsync(IEnumerable<TInput>, EmbeddingGenerationOptions, CancellationToken) 为输入值集合生成嵌入的方法。
using Microsoft.Extensions.AI;
public sealed class SampleEmbeddingGenerator(
Uri endpoint, string modelId)
: IEmbeddingGenerator<string, Embedding<float>>
{
private readonly EmbeddingGeneratorMetadata _metadata =
new("SampleEmbeddingGenerator", endpoint, modelId);
public async Task<GeneratedEmbeddings<Embedding<float>>> GenerateAsync(
IEnumerable<string> values,
EmbeddingGenerationOptions? options = null,
CancellationToken cancellationToken = default)
{
// Simulate some async operation.
await Task.Delay(100, cancellationToken);
// Create random embeddings.
return [.. from value in values
select new Embedding<float>(
Enumerable.Range(0, 384)
.Select(_ => Random.Shared.NextSingle()).ToArray())];
}
public object? GetService(Type serviceType, object? serviceKey) =>
serviceKey is not null
? null
: serviceType == typeof(EmbeddingGeneratorMetadata)
? _metadata
: serviceType?.IsInstanceOfType(this) is true
? this
: null;
void IDisposable.Dispose() { }
}
此示例实现只生成随机嵌入向量。 有关更现实的具体实现,请参阅 OpenTelemetryEmbeddingGenerator.cs。