Skip to content

Commit d682369

Browse files
Merge pull request #46918 from dotnet/main
Merge main into live
2 parents 4f6705e + b12bc08 commit d682369

File tree

25 files changed

+121
-41
lines changed

25 files changed

+121
-41
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
title: "Sample implementations of IChatClient and IEmbeddingGenerator"
3+
description: Learn more about the IChatClient and IEmbeddingGenerator interfaces, see simple implementations, and find links to concrete implementations.
4+
ms.topic: article
5+
ms.date: 05/28/2025
6+
---
7+
8+
# Sample implementations of IChatClient and IEmbeddingGenerator
9+
10+
.NET libraries that provide clients for language models and services can provide implementations of the <xref:Microsoft.Extensions.AI.IChatClient> and <xref:Microsoft.Extensions.AI.IEmbeddingGenerator`2> interfaces. Any consumers of the interfaces are then able to interoperate seamlessly with these models and services via the abstractions.
11+
12+
## The `IChatClient` interface
13+
14+
The <xref:Microsoft.Extensions.AI.IChatClient> interface defines a client abstraction responsible for interacting with AI services that provide chat capabilities. It includes methods for sending and receiving messages with multi-modal content (such as text, images, and audio), either as a complete set or streamed incrementally. Additionally, it allows for retrieving strongly typed services provided by the client or its underlying services.
15+
16+
The following sample implements `IChatClient` to show the general structure.
17+
18+
:::code language="csharp" source="./snippets/sample-implementations/SampleChatClient.cs":::
19+
20+
For more realistic, concrete implementations of `IChatClient`, see:
21+
22+
- [AzureAIInferenceChatClient.cs](https://github.com/dotnet/extensions/blob/main/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs)
23+
- [OpenAIChatClient.cs](https://github.com/dotnet/extensions/blob/main/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs)
24+
- [Microsoft.Extensions.AI chat clients](https://github.com/dotnet/extensions/tree/main/src/Libraries/Microsoft.Extensions.AI/ChatCompletion)
25+
26+
## The `IEmbeddingGenerator<TInput,TEmbedding>` interface
27+
28+
The <xref:Microsoft.Extensions.AI.IEmbeddingGenerator`2> interface represents a generic generator of embeddings. Here, `TInput` is the type of input values being embedded, and `TEmbedding` is the type of generated embedding, which inherits from the <xref:Microsoft.Extensions.AI.Embedding> class.
29+
30+
The `Embedding` class serves as a base class for embeddings generated by an `IEmbeddingGenerator<TInput,TEmbedding>`. It's designed to store and manage the metadata and data associated with embeddings. Derived types, like `Embedding<T>`, provide the concrete embedding vector data. For example, an `Embedding<float>` exposes a `ReadOnlyMemory<float> Vector { get; }` property for access to its embedding data.
31+
32+
The `IEmbeddingGenerator<TInput,TEmbedding>` interface defines a method to asynchronously generate embeddings for a collection of input values, with optional configuration and cancellation support. It also provides metadata describing the generator and allows for the retrieval of strongly typed services that can be provided by the generator or its underlying services.
33+
34+
The following code shows how the `SampleEmbeddingGenerator` class implements the `IEmbeddingGenerator<TInput,TEmbedding>` interface. It has a primary constructor that accepts an endpoint and model ID, which are used to identify the generator. It also implements the <xref:Microsoft.Extensions.AI.IEmbeddingGenerator`2.GenerateAsync(System.Collections.Generic.IEnumerable{`0},Microsoft.Extensions.AI.EmbeddingGenerationOptions,System.Threading.CancellationToken)> method to generate embeddings for a collection of input values.
35+
36+
:::code language="csharp" source="./snippets/sample-implementations/SampleEmbeddingGenerator.cs":::
37+
38+
This sample implementation just generates random embedding vectors. For a more realistic, concrete implementation, see [OpenTelemetryEmbeddingGenerator.cs](https://github.com/dotnet/extensions/blob/main/src/Libraries/Microsoft.Extensions.AI/Embeddings/OpenTelemetryEmbeddingGenerator.cs).
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="9.5.0" />
11+
</ItemGroup>
12+
13+
</Project>

docs/ai/snippets/microsoft-extensions-ai/AI.Shared/SampleChatClient.cs renamed to docs/ai/advanced/snippets/sample-implementations/SampleChatClient.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System.Runtime.CompilerServices;
22
using Microsoft.Extensions.AI;
33

4-
public sealed class SampleChatClient(Uri endpoint, string modelId) : IChatClient
4+
public sealed class SampleChatClient(Uri endpoint, string modelId)
5+
: IChatClient
56
{
6-
public ChatClientMetadata Metadata { get; } = new(nameof(SampleChatClient), endpoint, modelId);
7+
public ChatClientMetadata Metadata { get; } =
8+
new(nameof(SampleChatClient), endpoint, modelId);
79

810
public async Task<ChatResponse> GetResponseAsync(
911
IEnumerable<ChatMessage> chatMessages,

docs/ai/snippets/microsoft-extensions-ai/AI.Shared/SampleEmbeddingGenerator.cs renamed to docs/ai/advanced/snippets/sample-implementations/SampleEmbeddingGenerator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ public async Task<GeneratedEmbeddings<Embedding<float>>> GenerateAsync(
1616
await Task.Delay(100, cancellationToken);
1717

1818
// Create random embeddings.
19-
return new GeneratedEmbeddings<Embedding<float>>(
20-
from value in values
19+
return [.. from value in values
2120
select new Embedding<float>(
22-
Enumerable.Range(0, 384).Select(_ => Random.Shared.NextSingle()).ToArray()));
21+
Enumerable.Range(0, 384)
22+
.Select(_ => Random.Shared.NextSingle()).ToArray())];
2323
}
2424

2525
public object? GetService(Type serviceType, object? serviceKey) =>

docs/ai/microsoft-extensions-ai.md

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,14 @@ The following subsections show specific [IChatClient](#the-ichatclient-interface
4343

4444
The following sections show specific [IEmbeddingGenerator](#the-iembeddinggenerator-interface) usage examples:
4545

46-
- [Sample implementation](#sample-implementation)
4746
- [Create embeddings](#create-embeddings)
4847
- [Pipelines of functionality](#pipelines-of-functionality)
4948

5049
### The `IChatClient` interface
5150

5251
The <xref:Microsoft.Extensions.AI.IChatClient> interface defines a client abstraction responsible for interacting with AI services that provide chat capabilities. It includes methods for sending and receiving messages with multi-modal content (such as text, images, and audio), either as a complete set or streamed incrementally. Additionally, it allows for retrieving strongly typed services provided by the client or its underlying services.
5352

54-
.NET libraries that provide clients for language models and services can provide an implementation of the `IChatClient` interface. Any consumers of the interface are then able to interoperate seamlessly with these models and services via the abstractions.
53+
.NET libraries that provide clients for language models and services can provide an implementation of the `IChatClient` interface. Any consumers of the interface are then able to interoperate seamlessly with these models and services via the abstractions. You can see a simple implementation at [Sample implementations of IChatClient and IEmbeddingGenerator](advanced/sample-implementations.md).
5554

5655
#### Request a chat response
5756

@@ -195,25 +194,13 @@ If you don't know ahead of time whether the service is stateless or stateful, yo
195194

196195
### The `IEmbeddingGenerator` interface
197196

198-
The <xref:Microsoft.Extensions.AI.IEmbeddingGenerator`2> interface represents a generic generator of embeddings. Here, `TInput` is the type of input values being embedded, and `TEmbedding` is the type of generated embedding, which inherits from the <xref:Microsoft.Extensions.AI.Embedding> class.
197+
The <xref:Microsoft.Extensions.AI.IEmbeddingGenerator`2> interface represents a generic generator of embeddings. For the generic type parameters, `TInput` is the type of input values being embedded, and `TEmbedding` is the type of generated embedding, which inherits from the <xref:Microsoft.Extensions.AI.Embedding> class.
199198

200-
The `Embedding` class serves as a base class for embeddings generated by an `IEmbeddingGenerator`. It's designed to store and manage the metadata and data associated with embeddings. Derived types, like `Embedding<T>`, provide the concrete embedding vector data. For example, an `Embedding<float>` exposes a `ReadOnlyMemory<float> Vector { get; }` property for access to its embedding data.
199+
The `Embedding` class serves as a base class for embeddings generated by an `IEmbeddingGenerator`. It's designed to store and manage the metadata and data associated with embeddings. Derived types, like <xref:Microsoft.Extensions.AI.Embedding`1>, provide the concrete embedding vector data. For example, an `Embedding<float>` exposes a `ReadOnlyMemory<float> Vector { get; }` property for access to its embedding data.
201200

202201
The `IEmbeddingGenerator` interface defines a method to asynchronously generate embeddings for a collection of input values, with optional configuration and cancellation support. It also provides metadata describing the generator and allows for the retrieval of strongly typed services that can be provided by the generator or its underlying services.
203202

204-
#### Sample implementation
205-
206-
The following sample implementation of `IEmbeddingGenerator` shows the general structure.
207-
208-
:::code language="csharp" source="snippets/microsoft-extensions-ai/AI.Shared/SampleEmbeddingGenerator.cs":::
209-
210-
The preceding code:
211-
212-
- Defines a class named `SampleEmbeddingGenerator` that implements the `IEmbeddingGenerator<string, Embedding<float>>` interface.
213-
- Has a primary constructor that accepts an endpoint and model ID, which are used to identify the generator.
214-
- Implements the `GenerateAsync` method to generate embeddings for a collection of input values.
215-
216-
The sample implementation just generates random embedding vectors. You can find a concrete implementation in the [📦 Microsoft.Extensions.AI.OpenAI](https://www.nuget.org/packages/Microsoft.Extensions.AI.OpenAI) package.
203+
Most users don't need to implement the `IEmbeddingGenerator` interface. However, if you're a library author, you can see a simple implementation at [Sample implementations of IChatClient and IEmbeddingGenerator](advanced/sample-implementations.md).
217204

218205
#### Create embeddings
219206

@@ -247,7 +234,7 @@ In this way, the `RateLimitingEmbeddingGenerator` can be composed with other `IE
247234

248235
You can start building with `Microsoft.Extensions.AI` in the following ways:
249236

250-
- **Library developers**: If you own libraries that provide clients for AI services, consider implementing the interfaces in your libraries. This allows users to easily integrate your NuGet package via the abstractions.
237+
- **Library developers**: If you own libraries that provide clients for AI services, consider implementing the interfaces in your libraries. This allows users to easily integrate your NuGet package via the abstractions. For example implementations, see [Sample implementations of IChatClient and IEmbeddingGenerator](advanced/sample-implementations.md).
251238
- **Service consumers**: If you're developing libraries that consume AI services, use the abstractions instead of hardcoding to a specific AI service. This approach gives your consumers the flexibility to choose their preferred provider.
252239
- **Application developers**: Use the abstractions to simplify integration into your apps. This enables portability across models and services, facilitates testing and mocking, leverages middleware provided by the ecosystem, and maintains a consistent API throughout your app, even if you use different services in different parts of your application.
253240
- **Ecosystem contributors**: If you're interested in contributing to the ecosystem, consider writing custom middleware components.

docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.AddMessages/ConsoleAI.AddMessages.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
<Nullable>enable</Nullable>
88
</PropertyGroup>
99

10+
<ItemGroup>
11+
<PackageReference Include="OllamaSharp" Version="5.1.19" />
12+
</ItemGroup>
13+
1014
<ItemGroup>
1115
<ProjectReference Include="..\AI.Shared\AI.Shared.csproj" />
1216
</ItemGroup>

docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.AddMessages/Program.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
using Microsoft.Extensions.AI;
2+
using OllamaSharp;
23

3-
IChatClient client = new SampleChatClient(
4-
new Uri("http://coolsite.ai"), "target-ai-model");
4+
IChatClient client = new OllamaApiClient(
5+
new Uri("http://localhost:11434/"), "phi3:mini");
56

67
// <Snippet1>
78
List<ChatMessage> history = [];

docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.ConsumeClientMiddleware/ConsoleAI.ConsumeClientMiddleware.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
<ItemGroup>
1111
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0-preview.5.25277.114" />
12+
<PackageReference Include="OllamaSharp" Version="5.1.19" />
1213
<ProjectReference Include="..\AI.Shared\AI.Shared.csproj" />
1314
</ItemGroup>
1415

docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.ConsumeClientMiddleware/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
using Microsoft.Extensions.AI;
44
using Microsoft.Extensions.DependencyInjection;
55
using Microsoft.Extensions.Hosting;
6+
using OllamaSharp;
67

78
// <SnippetUse>
89
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
910

11+
IChatClient client = new OllamaApiClient(
12+
new Uri("http://localhost:11434/"),
13+
"phi3:mini");
14+
1015
builder.Services.AddChatClient(services =>
11-
new SampleChatClient(new Uri("http://localhost"), "test")
16+
client
1217
.AsBuilder()
1318
.UseDistributedCache()
1419
.UseRateLimiting()

docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.ConsumeRateLimitingEmbedding/ConsoleAI.ConsumeRateLimitingEmbedding.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
<Nullable>enable</Nullable>
88
</PropertyGroup>
99

10+
<ItemGroup>
11+
<PackageReference Include="OllamaSharp" Version="5.1.19" />
12+
</ItemGroup>
13+
1014
<ItemGroup>
1115
<ProjectReference Include="..\AI.Shared\AI.Shared.csproj" />
1216
</ItemGroup>

0 commit comments

Comments
 (0)