Compartir a través de


Implementaciones de ejemplo de IChatClient e IEmbeddingGenerator

Las bibliotecas de .NET que proporcionan clientes para los modelos de lenguaje y los servicios pueden proporcionar implementaciones de las interfaces IChatClient y IEmbeddingGenerator<TInput,TEmbedding>. Los consumidores de las interfaces pueden interoperar sin problemas con estos modelos y servicios a través de las abstracciones.

Interfaz IChatClient

La interfaz IChatClient define una abstracción de cliente responsable de interactuar con los servicios de INTELIGENCIA ARTIFICIAL que proporcionan funcionalidades de chat. Incluye métodos para enviar y recibir mensajes con contenido multi modal (como texto, imágenes y audio), ya sea como un conjunto completo o transmitido incrementalmente. Además, permite recuperar servicios fuertemente tipados proporcionados por el cliente o sus servicios subyacentes.

En el ejemplo siguiente se implementa IChatClient para mostrar la estructura general.

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

Para obtener implementaciones más realistas y concretas de IChatClient, consulte:

Interfaz IEmbeddingGenerator<TInput,TEmbedding>

La interfaz IEmbeddingGenerator<TInput,TEmbedding> representa un generador genérico de incrustaciones. Aquí, TInput es el tipo de valores de entrada que se insertan y TEmbedding es el tipo de inserción generado, que hereda de la clase Embedding.

La clase Embedding actúa como una clase base para incrustaciones generadas por un IEmbeddingGenerator<TInput,TEmbedding>. Está diseñado para almacenar y administrar los metadatos y los datos asociados a las incrustaciones. Los tipos derivados, como Embedding<T>, proporcionan los datos vectoriales de inserción concretos. Por ejemplo, Embedding<float> expone una propiedad ReadOnlyMemory<float> Vector { get; } para el acceso a sus datos incrustados.

La interfaz IEmbeddingGenerator<TInput,TEmbedding> define un método para generar de forma asincrónica inserciones para una colección de valores de entrada, con compatibilidad opcional de configuración y cancelación. También proporciona metadatos que describen el generador y permite la recuperación de servicios fuertemente tipados que el generador o sus servicios subyacentes pueden proporcionar.

En el código siguiente se muestra cómo implementa la SampleEmbeddingGenerator clase la IEmbeddingGenerator<TInput,TEmbedding> interfaz . Tiene un constructor principal que acepta un punto de conexión y un identificador de modelo, que se usan para identificar el generador. También implementa el GenerateAsync(IEnumerable<TInput>, EmbeddingGenerationOptions, CancellationToken) método para generar inserciones para una colección de valores de entrada.

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

Esta implementación de ejemplo solo genera vectores de inserción aleatorios. Para obtener una implementación más realista y concreta, consulte OpenTelemetryEmbeddingGenerator.cs.