IEmbeddingGenerator<TInput,TEmbedding> 인터페이스는 임베딩의 일반적인 생성기를 나타냅니다. 제네릭 타입 매개변수의 경우, TInput는 포함되는 입력 값의 타입이고, TEmbedding는 Embedding 클래스를 상속받는 생성된 포함의 타입입니다.
Embedding 클래스는 IEmbeddingGenerator에 의해 생성된 포함의 기본 클래스 역할을 합니다. 포함과 관련된 메타데이터 및 데이터를 저장하고 관리하도록 설계되었습니다. 파생 형식(예: Embedding<T>구체적인 포함 벡터 데이터)을 제공합니다. 예를 들어, Embedding<float>는 그것의 포함 데이터를 액세스하기 위한 ReadOnlyMemory<float> Vector { get; } 속성을 노출합니다.
IEmbeddingGenerator 인터페이스는 선택적 구성 및 취소 지원을 사용하여 입력 값 모음에 대해 임베딩을 비동기적으로 생성하는 메서드를 정의합니다. 또한 생성기를 설명하는 메타데이터를 제공하고 생성기 또는 해당 기본 서비스에서 제공할 수 있는 강력한 형식의 서비스를 검색할 수 있습니다.
임베딩 생성
IEmbeddingGenerator<TInput,TEmbedding>을 사용하여 수행되는 주요 작업은 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()));
}
또한 가속기 확장 메서드는 단일 입력에서 포함 벡터를 생성하는 것과 같은 일반적인 사례를 간소화하기 위해 존재합니다.
ReadOnlyMemory<float> vector = await generator.GenerateVectorAsync("What is AI?");
기능 파이프라인
IChatClient마찬가지로 IEmbeddingGenerator 구현을 계층화할 수 있습니다.
Microsoft.Extensions.AI 는 캐싱 및 원격 분석을 위한 IEmbeddingGenerator 위임 구현을 제공합니다.
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()));
}
IEmbeddingGenerator는 IEmbeddingGenerator의 기능을 확장할 수 있는 사용자 지정 미들웨어를 구축할 수 있도록 합니다.
DelegatingEmbeddingGenerator<TInput,TEmbedding> 클래스는 다른 IEmbeddingGenerator<TInput, TEmbedding> 인스턴스에 작업을 위임하는 포함 생성기를 만들기 위한 기본 클래스 역할을 하는 IEmbeddingGenerator<TInput, TEmbedding> 인터페이스의 구현입니다. 여러 생성기를 순서대로 연결하여 기본 생성기에 호출을 전달할 수 있습니다. 이 클래스는 호출을 내부 생성기 인스턴스로 전달하는 GenerateAsync 및 Dispose같은 메서드에 대한 기본 구현을 제공하여 유연하고 모듈식 포함 생성을 가능하게 합니다.
다음은 임베딩 생성 요청의 속도를 제한하는 위임 임베딩 생성기의 예제 구현입니다.
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);
}
}
그런 다음 임의 IEmbeddingGenerator<string, Embedding<float>> 로 계층화하여 모든 포함 생성 작업을 속도 제한할 수 있습니다.
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()));
}
이러한 방식으로 RateLimitingEmbeddingGenerator 다른 IEmbeddingGenerator<string, Embedding<float>> 인스턴스와 함께 구성하여 속도 제한 기능을 제공할 수 있습니다.
구현 예제
대부분의 사용자는 인터페이스를 구현 IEmbeddingGenerator 할 필요가 없습니다. 그러나 라이브러리 작성자인 경우 이러한 구현 예제를 살펴보는 것이 유용할 수 있습니다.
다음 코드는 SampleEmbeddingGenerator 클래스가 IEmbeddingGenerator<TInput,TEmbedding> 인터페이스를 구현하는 방법을 보여 줍니다. 생성기를 식별하는 데 사용되는 엔드포인트 및 모델 ID를 허용하는 기본 생성자가 있습니다. 또한 입력 값 컬렉션에 대한 임베딩을 생성하는 메서드를 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 참조하세요.
.NET