Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La interfaz IEmbeddingGenerator<TInput,TEmbedding> representa un generador genérico de incrustaciones. Para los parámetros de tipo genérico, TInput es el tipo de valores de entrada que se insertan y TEmbedding es el tipo de inserción generada, que hereda de la Embedding clase .
La clase Embedding actúa como una clase base para incrustaciones generadas por un IEmbeddingGenerator. 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 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.
Creación de incrustaciones
La operación principal realizada con un IEmbeddingGenerator<TInput,TEmbedding> es la generación de inserciones, que se genera con su método GenerateAsync.
using Microsoft.Extensions.AI;
using OllamaSharp;
IEmbeddingGenerator<string, Embedding<float>> generator =
new OllamaApiClient(new Uri("http://localhost:11434/"), "phi3:mini");
foreach (Embedding<float> embedding in
await generator.GenerateAsync(["What is AI?", "What is .NET?"]))
{
Console.WriteLine(string.Join(", ", embedding.Vector.ToArray()));
}
Los métodos de extensión de acelerador también existen para simplificar los casos comunes, como generar un vector de inserción a partir de una sola entrada.
ReadOnlyMemory<float> vector = await generator.GenerateVectorAsync("What is AI?");
Flujos de funcionalidades
Al igual que con IChatClient, se pueden superponer las implementaciones de IEmbeddingGenerator.
Microsoft.Extensions.AI proporciona una implementación de delegación para el IEmbeddingGenerator almacenamiento en caché y la telemetría.
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using OllamaSharp;
using OpenTelemetry.Trace;
// Configure OpenTelemetry exporter
string sourceName = Guid.NewGuid().ToString();
TracerProvider tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
.AddSource(sourceName)
.AddConsoleExporter()
.Build();
// Explore changing the order of the intermediate "Use" calls to see
// what impact that has on what gets cached and traced.
IEmbeddingGenerator<string, Embedding<float>> generator = new EmbeddingGeneratorBuilder<string, Embedding<float>>(
new OllamaApiClient(new Uri("http://localhost:11434/"), "phi3:mini"))
.UseDistributedCache(
new MemoryDistributedCache(
Options.Create(new MemoryDistributedCacheOptions())))
.UseOpenTelemetry(sourceName: sourceName)
.Build();
GeneratedEmbeddings<Embedding<float>> embeddings = await generator.GenerateAsync(
[
"What is AI?",
"What is .NET?",
"What is AI?"
]);
foreach (Embedding<float> embedding in embeddings)
{
Console.WriteLine(string.Join(", ", embedding.Vector.ToArray()));
}
El IEmbeddingGenerator permite crear middleware personalizado que amplía la funcionalidad de un IEmbeddingGenerator. La clase DelegatingEmbeddingGenerator<TInput,TEmbedding> es una implementación de la interfaz IEmbeddingGenerator<TInput, TEmbedding> que actúa como clase base para crear generadores de inserción que deleguen sus operaciones a otra instancia de IEmbeddingGenerator<TInput, TEmbedding>. Permite encadenar varios generadores en cualquier orden, pasando llamadas a un generador subyacente. La clase proporciona implementaciones predeterminadas para métodos como GenerateAsync y Dispose, que reenvía las llamadas a la instancia del generador interno, lo que permite la generación de inserción flexible y modular.
A continuación se muestra un ejemplo de implementación de un generador de incrustaciones delegadas que limita la velocidad de las solicitudes de generación de incrustaciones.
using Microsoft.Extensions.AI;
using System.Threading.RateLimiting;
public class RateLimitingEmbeddingGenerator(
IEmbeddingGenerator<string, Embedding<float>> innerGenerator, RateLimiter rateLimiter)
: DelegatingEmbeddingGenerator<string, Embedding<float>>(innerGenerator)
{
public override async Task<GeneratedEmbeddings<Embedding<float>>> GenerateAsync(
IEnumerable<string> values,
EmbeddingGenerationOptions? options = null,
CancellationToken cancellationToken = default)
{
using var lease = await rateLimiter.AcquireAsync(permitCount: 1, cancellationToken)
.ConfigureAwait(false);
if (!lease.IsAcquired)
{
throw new InvalidOperationException("Unable to acquire lease.");
}
return await base.GenerateAsync(values, options, cancellationToken);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
rateLimiter.Dispose();
}
base.Dispose(disposing);
}
}
Después, se puede superponer a una IEmbeddingGenerator<string, Embedding<float>> arbitraria para limitar la velocidad de todas las operaciones de generación de inserción.
using Microsoft.Extensions.AI;
using OllamaSharp;
using System.Threading.RateLimiting;
IEmbeddingGenerator<string, Embedding<float>> generator =
new RateLimitingEmbeddingGenerator(
new OllamaApiClient(new Uri("http://localhost:11434/"), "phi3:mini"),
new ConcurrencyLimiter(new()
{
PermitLimit = 1,
QueueLimit = int.MaxValue
}));
foreach (Embedding<float> embedding in
await generator.GenerateAsync(["What is AI?", "What is .NET?"]))
{
Console.WriteLine(string.Join(", ", embedding.Vector.ToArray()));
}
De este modo, RateLimitingEmbeddingGenerator se puede componer con otras IEmbeddingGenerator<string, Embedding<float>> instancias para proporcionar funcionalidad de limitación de velocidad.
Ejemplos de implementación
La mayoría de los usuarios no necesitan implementar la IEmbeddingGenerator interfaz. Sin embargo, si es autor de la biblioteca, puede resultar útil examinar estos ejemplos de implementación.
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.