Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A interface do IEmbeddingGenerator<TInput,TEmbedding> representa um gerador genérico de inserções. Para os parâmetros de tipo genérico, TInput é o tipo de valores de entrada que estão sendo inseridos e TEmbedding é o tipo de inserção gerada, que herda da Embedding classe.
A classe Embedding serve como uma classe base para inserções geradas por um IEmbeddingGenerator. Ela foi criada para armazenar e gerenciar os metadados e os dados associados a inserções. Tipos derivados, como Embedding<T>, fornecem os dados concretos de vetor de inserção. Por exemplo, uma Embedding<float> expõe uma ReadOnlyMemory<float> Vector { get; } propriedade para acesso aos seus dados de inserção.
A interface do IEmbeddingGenerator define um método para gerar inserções de forma assíncrona para uma coleção de valores de entrada, com suporte opcional de configuração e cancelamento. Ela também fornece metadados que descrevem o gerador e permite a recuperação de serviços com tipo forte que podem ser fornecidos pelo gerador ou seus serviços subjacentes.
Criar inserções
A operação primária executada com um IEmbeddingGenerator<TInput,TEmbedding> é a geração de embeddings, realizada com seu 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()));
}
Também existem métodos de extensão de acelerador para simplificar casos comuns, como a geração de um vetor de incorporação a partir de uma única entrada.
ReadOnlyMemory<float> vector = await generator.GenerateVectorAsync("What is AI?");
Pipelines de funcionalidade
Assim como acontece com IChatClient, as implementações de IEmbeddingGenerator podem ser em camadas.
Microsoft.Extensions.AI fornece uma implementação de delegação para IEmbeddingGenerator para cache e telemetria.
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()));
}
O IEmbeddingGenerator permite a criação de middleware personalizado que estende a funcionalidade de um IEmbeddingGenerator. A classe DelegatingEmbeddingGenerator<TInput,TEmbedding> é uma implementação da interface do IEmbeddingGenerator<TInput, TEmbedding> que serve como uma classe base para a criação de geradores de inserção que delegam suas operações a outra instância do IEmbeddingGenerator<TInput, TEmbedding>. Ele permite encadear vários geradores em qualquer ordem, transmitindo chamadas para um gerador subjacente. A classe fornece implementações padrão para métodos como GenerateAsync e Dispose, que encaminham as chamadas para a instância do gerador interno, permitindo a geração de inserções flexíveis e modulares.
Veja a seguir um exemplo de implementação de um gerador de incorporação de delegação que limita a taxa de solicitações de geração de incorporação:
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);
}
}
Isso pode então ser colocado em camadas em torno de um IEmbeddingGenerator<string, Embedding<float>> arbitrário para limitar a taxa de todas as operações de geração de incorporação.
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()));
}
Dessa forma, o RateLimitingEmbeddingGenerator pode ser composto com outras instâncias IEmbeddingGenerator<string, Embedding<float>> para fornecer funcionalidade de limitação de taxa.
Exemplo de implementação
A maioria dos usuários não precisa implementar a IEmbeddingGenerator interface. No entanto, se você for um autor de biblioteca, talvez seja útil examinar esses exemplos de implementação.
O código a seguir mostra como a SampleEmbeddingGenerator classe implementa a IEmbeddingGenerator<TInput,TEmbedding> interface. Ele tem um construtor primário que aceita um ponto de extremidade e uma ID de modelo, que são usados para identificar o gerador. Ele também implementa o GenerateAsync(IEnumerable<TInput>, EmbeddingGenerationOptions, CancellationToken) método para gerar inserções para uma coleção 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() { }
}
Essa implementação de exemplo gera apenas vetores de inserção aleatórios. Para obter uma implementação mais realista e concreta, consulte OpenTelemetryEmbeddingGenerator.cs.