共用方式為


IChatClient 和 IEmbeddingGenerator 的範例實作

提供語言模型和服務的用戶端之 .NET 程式庫可以提供 IChatClientIEmbeddingGenerator<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> 介面的。 它有一個主要建構函式,可接受用來識別產生器的端點和模型標識符。 它也會實作 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