Udostępnij za pośrednictwem


Przykładowe implementacje elementów IChatClient i IEmbeddingGenerator

Biblioteki platformy .NET, które dostarczają klientom modele językowe i usługi, mogą zapewniać implementacje interfejsów IChatClient i IEmbeddingGenerator<TInput,TEmbedding>. Wszyscy użytkownicy interfejsów mogą bezproblemowo współpracować z tymi modelami i usługami za pośrednictwem abstrakcji.

Interfejs IChatClient

Interfejs IChatClient definiuje abstrakcję klienta odpowiedzialną za interakcję z usługami sztucznej inteligencji, które zapewniają możliwości czatu. Zawiera metody wysyłania i odbierania wiadomości z treściami multimodalnymi (takimi jak tekst, obrazy i dźwięk) jako kompletne zestawy lub strumieniowo w sposób przyrostowy. Ponadto umożliwia pobieranie silnie typowanych usług udostępnianych przez klienta lub jego bazowe usługi.

Poniższy przykład implementuje IChatClient, aby pokazać ogólną strukturę.

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() { }
}

Aby uzyskać bardziej realistyczne, konkretne implementacje programu IChatClient, zobacz:

Interfejs IEmbeddingGenerator<TInput,TEmbedding>

Interfejs IEmbeddingGenerator<TInput,TEmbedding> reprezentuje ogólny generator osadzonych elementów. W tym miejscu TInput jest typem osadzonych wartości wejściowych, a TEmbedding jest typem wygenerowanego osadzania, który dziedziczy z klasy Embedding.

Klasa Embedding służy jako klasa bazowa dla osadzeń generowanych przez IEmbeddingGenerator<TInput,TEmbedding>. Jest ona przeznaczona do przechowywania metadanych i danych skojarzonych z osadzaniem i zarządzania nimi. Typy pochodne, takie jak Embedding<T>, zapewniają konkretne dane wektorów osadzania. Na przykład Embedding<float> udostępnia właściwość ReadOnlyMemory<float> Vector { get; }, która umożliwia dostęp do danych osadzania.

Interfejs IEmbeddingGenerator<TInput,TEmbedding> definiuje metodę do asynchronicznego generowania osadzeń dla kolekcji wartości wejściowych, z opcjonalną konfiguracją i obsługą anulowania. Udostępnia również metadane opisujące generator i umożliwia pobieranie mocno typowanych usług, które mogą być udostępniane przez generator lub podstawowe jego usługi.

Poniższy kod pokazuje, jak SampleEmbeddingGenerator klasa implementuje IEmbeddingGenerator<TInput,TEmbedding> interfejs. Ma podstawowy konstruktor, który akceptuje punkt końcowy i identyfikator modelu, który jest używany do identyfikowania generatora. Implementuje również metodę GenerateAsync(IEnumerable<TInput>, EmbeddingGenerationOptions, CancellationToken) generowania osadzeń dla kolekcji wartości wejściowych.

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() { }
}

Ta przykładowa implementacja generuje tylko losowe wektory osadzania. Aby uzyskać bardziej realistyczne, konkretne wdrożenie, zobacz OpenTelemetryEmbeddingGenerator.cs.