Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Gränssnittet IChatClient definierar en klientabstraktion som ansvarar för att interagera med AI-tjänster som tillhandahåller chattfunktioner. Den innehåller metoder för att skicka och ta emot meddelanden med multimodalt innehåll (till exempel text, bilder och ljud), antingen som en fullständig uppsättning eller strömmas stegvis. Dessutom möjliggör det hämtning av starkt typade tjänster som tillhandahålls av klienten eller dess underliggande tjänster.
.NET-bibliotek som tillhandahåller klienter för språkmodeller och tjänster kan tillhandahålla en implementering av IChatClient gränssnittet. Alla användare av gränssnittet kan sedan samverka sömlöst med dessa modeller och tjänster via abstraktionerna. Du hittar exempel i avsnittet Implementeringsexempel .
Begära ett chattsvar
Med en instans av IChatClientkan du anropa IChatClient.GetResponseAsync metoden för att skicka en begäran och få ett svar. Begäran består av ett eller flera meddelanden som var och en består av ett eller flera innehåll. Acceleratormetoder finns för att förenkla vanliga fall, till exempel att skapa en begäran om ett enda textinnehåll.
using Microsoft.Extensions.AI;
using OllamaSharp;
IChatClient client = new OllamaApiClient(
new Uri("http://localhost:11434/"), "phi3:mini");
Console.WriteLine(await client.GetResponseAsync("What is AI?"));
Kärnmetoden IChatClient.GetResponseAsync accepterar en lista med meddelanden. Den här listan representerar historiken för alla meddelanden som ingår i konversationen.
Console.WriteLine(await client.GetResponseAsync(
[
new(ChatRole.System, "You are a helpful AI assistant"),
new(ChatRole.User, "What is AI?"),
]));
Den ChatResponse som returneras från GetResponseAsync visar en lista över ChatMessage instanser som representerar ett eller flera meddelanden som genereras som en del av åtgärden. I vanliga fall finns det bara ett svarsmeddelande, men i vissa situationer kan det finnas flera meddelanden. Meddelandelistan sorteras så att det sista meddelandet i listan representerar det slutliga meddelandet till begäran. Om du vill skicka tillbaka alla dessa svarsmeddelanden till tjänsten i en efterföljande begäran kan du lägga till meddelandena från svaret i meddelandelistan igen.
List<ChatMessage> history = [];
while (true)
{
Console.Write("Q: ");
history.Add(new(ChatRole.User, Console.ReadLine()));
ChatResponse response = await client.GetResponseAsync(history);
Console.WriteLine(response);
history.AddMessages(response);
}
Begär ett svar i direktchatt
Indata till IChatClient.GetStreamingResponseAsync är identiska med indata för GetResponseAsync. Men i stället för att returnera det fullständiga svaret som en del av ett ChatResponse objekt returnerar metoden en IAsyncEnumerable<T> där T är ChatResponseUpdate, vilket ger en ström med uppdateringar som tillsammans utgör det enskilda svaret.
await foreach (ChatResponseUpdate update in client.GetStreamingResponseAsync("What is AI?"))
{
Console.Write(update);
}
Tips/Råd
API:er för direktuppspelning är nästan synonyma med AI-användarupplevelser. C# möjliggör övertygande scenarier med stöd för IAsyncEnumerable<T>, vilket möjliggör ett naturligt och effektivt sätt att strömma data.
Precis som med GetResponseAsynckan du lägga till uppdateringarna från IChatClient.GetStreamingResponseAsync tillbaka till meddelandelistan. Eftersom uppdateringarna är enskilda delar av ett svar kan du använda hjälpverktyg som ToChatResponse(IEnumerable<ChatResponseUpdate>) att skapa en eller flera uppdateringar i en enda ChatResponse instans.
Hjälpare som AddMessages skriver en ChatResponse och extraherar sedan de sammansatta meddelandena från svaret och lägger till dem i en lista.
List<ChatMessage> chatHistory = [];
while (true)
{
Console.Write("Q: ");
chatHistory.Add(new(ChatRole.User, Console.ReadLine()));
List<ChatResponseUpdate> updates = [];
await foreach (ChatResponseUpdate update in
client.GetStreamingResponseAsync(chatHistory))
{
Console.Write(update);
updates.Add(update);
}
Console.WriteLine();
chatHistory.AddMessages(updates);
}
Verktygsanrop
Vissa modeller och tjänster stöder verktygssamtal. Om du vill samla in ytterligare information kan du konfigurera ChatOptions med information om verktyg (vanligtvis .NET-metoder) som modellen kan begära att klienten anropar. I stället för att skicka ett slutligt svar begär modellen ett funktionsanrop med specifika argument. Klienten anropar sedan funktionen och skickar resultatet tillbaka till modellen med konversationshistoriken.
Microsoft.Extensions.AI.Abstractions-biblioteket innehåller abstraktioner för olika typer av meddelandeinnehåll, inklusive begäranden om funktionsanrop och resultat. Konsumenterna IChatClient kan interagera direkt med det här innehållet, och Microsoft.Extensions.AI tillhandahåller hjälpverktyg som kan möjliggöra automatisk aktivering av verktygen som svarar på motsvarande förfrågningar. Biblioteken Microsoft.Extensions.AI.Abstractions och Microsoft.Extensions.AI innehåller följande typer:
- AIFunction: Representerar en funktion som kan beskrivas för en AI-modell och anropas.
-
AIFunctionFactory: Tillhandahåller fabriksmetoder för att skapa
AIFunctioninstanser som representerar .NET-metoder. -
FunctionInvokingChatClient: Omsluter en
IChatClientsom en annanIChatClientsom lägger till möjligheter för automatisk funktionsanrop.
I följande exempel visas ett slumpmässigt funktionsanrop (det här exemplet beror på 📦 NuGet-paketet OllamaSharp ):
using Microsoft.Extensions.AI;
using OllamaSharp;
string GetCurrentWeather() => Random.Shared.NextDouble() > 0.5 ? "It's sunny" : "It's raining";
IChatClient client = new OllamaApiClient(new Uri("http://localhost:11434"), "llama3.1");
client = ChatClientBuilderChatClientExtensions
.AsBuilder(client)
.UseFunctionInvocation()
.Build();
ChatOptions options = new() { Tools = [AIFunctionFactory.Create(GetCurrentWeather)] };
var response = client.GetStreamingResponseAsync("Should I wear a rain coat?", options);
await foreach (var update in response)
{
Console.Write(update);
}
Föregående kod:
- Definierar en funktion med namnet
GetCurrentWeathersom returnerar en slumpmässig väderprognos. - Instansierar en ChatClientBuilder med en
OllamaSharp.OllamaApiClientoch konfigurerar den att använda funktionsanrop. - Anropar
GetStreamingResponseAsyncpå klienten, skickar en prompt och en lista över verktyg som innehåller en funktion som skapats med Create. - Itererar över svaret och skriver ut varje uppdatering till konsolen.
Mer information om hur du skapar AI-funktioner finns i Åtkomst till data i AI-funktioner.
Du kan också använda MCP-verktyg (Model Context Protocol) med din IChatClient. Mer information finns i Skapa en minimal MCP-klient.
Verktygsreduktion (experimentell)
Viktigt!
Den här funktionen är experimentell och kan komma att ändras.
Verktygsminskning hjälper till att hantera stora verktygskataloger genom att trimma dem baserat på relevansen för den aktuella konversationskontexten. Gränssnittet IToolReductionStrategy definierar strategier för att minska antalet verktyg som skickas till modellen. Biblioteket tillhandahåller implementeringar som EmbeddingToolReductionStrategy det rangordnar verktyg genom att bädda in likheter med konversationen. Använd utökningsmetoden UseToolReduction för att lägga till verktygsreduktion i chattklientpipelinen.
Cache-svar
Om du är bekant med cachelagring i .NET är det bra att veta att Microsoft.Extensions.AI tillhandahåller delegeringsimplementeringar för IChatClient cachelagring.
DistributedCachingChatClient är en IChatClient som lager cache runt en godtycklig annan IChatClient instans. När en ny chatthistorik skickas till DistributedCachingChatClientvidarebefordras den till den underliggande klienten och cachelagrar sedan svaret innan det skickas tillbaka till konsumenten. Nästa gång samma historik skickas, så att ett cachelagrat svar kan hittas i cacheminnet, DistributedCachingChatClient returnerar det cachelagrade svaret i stället för att vidarebefordra begäran längs pipelinen.
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using OllamaSharp;
var sampleChatClient = new OllamaApiClient(new Uri("http://localhost:11434"), "llama3.1");
IChatClient client = new ChatClientBuilder(sampleChatClient)
.UseDistributedCache(new MemoryDistributedCache(
Options.Create(new MemoryDistributedCacheOptions())))
.Build();
string[] prompts = ["What is AI?", "What is .NET?", "What is AI?"];
foreach (var prompt in prompts)
{
await foreach (var update in client.GetStreamingResponseAsync(prompt))
{
Console.Write(update);
}
Console.WriteLine();
}
Det här exemplet beror på 📦 NuGet-paketet Microsoft.Extensions.Caching.Memory . För mer information, se Cachelagring i .NET.
Använda telemetri
Ett annat exempel på en delegerande chattklient är OpenTelemetryChatClient. Den här implementeringen följer OpenTelemetry semantiska konventioner för generativa AI-system. Precis som andra IChatClient delegeringsmän lagrar den mått och sträcker sig över andra godtyckliga IChatClient implementeringar.
using Microsoft.Extensions.AI;
using OllamaSharp;
using OpenTelemetry.Trace;
// Configure OpenTelemetry exporter.
string sourceName = Guid.NewGuid().ToString();
TracerProvider tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
.AddSource(sourceName)
.AddConsoleExporter()
.Build();
IChatClient ollamaClient = new OllamaApiClient(
new Uri("http://localhost:11434/"), "phi3:mini");
IChatClient client = new ChatClientBuilder(ollamaClient)
.UseOpenTelemetry(
sourceName: sourceName,
configure: c => c.EnableSensitiveData = true)
.Build();
Console.WriteLine((await client.GetResponseAsync("What is AI?")).Text);
(Föregående exempel beror på 📦 NuGet-paketet OpenTelemetry.Exporter.Console .)
Alternativt ger LoggingChatClient och motsvarande UseLogging(ChatClientBuilder, ILoggerFactory, Action<LoggingChatClient>) metod ett enkelt sätt att skriva loggposter till en ILogger för varje begäran och svar.
Ange alternativ
Varje anrop till GetResponseAsync eller GetStreamingResponseAsync kan också ange en ChatOptions instans som innehåller ytterligare parametrar för åtgärden. De vanligaste parametrarna bland AI-modeller och -tjänster visas som starkt skrivna egenskaper för typen, till exempel ChatOptions.Temperature. Andra parametrar kan anges med namn på ett löst typat sätt, via ChatOptions.AdditionalProperties ordlistan eller via en alternativ instans som den underliggande leverantören förstår med hjälp av ChatOptions.RawRepresentationFactory egenskapen.
Du kan också ange alternativ när du skapar ett IChatClient med api:et fluent ChatClientBuilder genom att länka ett anrop till ConfigureOptions(ChatClientBuilder, Action<ChatOptions>) tilläggsmetoden. Den här delegerande klienten omsluter en annan klient och anropar det angivna ombudet för att fylla i en ChatOptions instans för varje anrop. Om du till exempel vill se till att egenskapen ChatOptions.ModelId är standard för ett visst modellnamn kan du använda kod som följande:
using Microsoft.Extensions.AI;
using OllamaSharp;
IChatClient client = new OllamaApiClient(new Uri("http://localhost:11434"));
client = ChatClientBuilderChatClientExtensions.AsBuilder(client)
.ConfigureOptions(options => options.ModelId ??= "phi3")
.Build();
// Will request "phi3".
Console.WriteLine(await client.GetResponseAsync("What is AI?"));
// Will request "llama3.1".
Console.WriteLine(await client.GetResponseAsync("What is AI?", new() { ModelId = "llama3.1" }));
Funktionspipelines
IChatClient instanser kan kombineras för att skapa en pipeline med komponenter som var och en lägger till ytterligare funktioner. Dessa komponenter kan komma från Microsoft.Extensions.AI, andra NuGet-paket eller anpassade implementeringar. Med den här metoden kan du utöka beteendet för IChatClient på olika sätt för att uppfylla dina specifika behov. Överväg följande kodfragment som lagrar en distribuerad cache, funktionsanrop och OpenTelemetry-spårning runt en chattklientexempel:
// Explore changing the order of the intermediate "Use" calls.
IChatClient client = new ChatClientBuilder(new OllamaApiClient(new Uri("http://localhost:11434"), "llama3.1"))
.UseDistributedCache(new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions())))
.UseFunctionInvocation()
.UseOpenTelemetry(sourceName: sourceName, configure: c => c.EnableSensitiveData = true)
.Build();
Anpassad IChatClient mellanvara
Om du vill lägga till ytterligare funktioner kan du implementera IChatClient direkt eller använda klassen DelegatingChatClient. Den här klassen fungerar som bas för att skapa chattklienter som delegerar åtgärder till en annan IChatClient instans. Det förenklar sammanlänkning av flera klienter, vilket gör att anrop kan skickas till en underliggande klient.
Klassen DelegatingChatClient tillhandahåller standardimplementeringar för metoder som GetResponseAsync, GetStreamingResponseAsyncoch Dispose, som vidarebefordrar anrop till den inre klienten. En härledd klass kan sedan bara åsidosätta de metoder som behövs för att utöka beteendet, samtidigt som andra anrop delegeras till basimplementeringen. Den här metoden är användbar för att skapa flexibla och modulära chattklienter som är enkla att utöka och skriva.
Följande är en exempelklass som härleds från DelegatingChatClient som använder biblioteket System.Threading.RateLimiting för att tillhandahålla hastighetsbegränsningsfunktioner.
using Microsoft.Extensions.AI;
using System.Runtime.CompilerServices;
using System.Threading.RateLimiting;
public sealed class RateLimitingChatClient(
IChatClient innerClient, RateLimiter rateLimiter)
: DelegatingChatClient(innerClient)
{
public override async Task<ChatResponse> GetResponseAsync(
IEnumerable<ChatMessage> messages,
ChatOptions? 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.GetResponseAsync(messages, options, cancellationToken)
.ConfigureAwait(false);
}
public override async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
IEnumerable<ChatMessage> messages,
ChatOptions? options = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
using var lease = await rateLimiter.AcquireAsync(permitCount: 1, cancellationToken)
.ConfigureAwait(false);
if (!lease.IsAcquired)
throw new InvalidOperationException("Unable to acquire lease.");
await foreach (var update in base.GetStreamingResponseAsync(messages, options, cancellationToken)
.ConfigureAwait(false))
{
yield return update;
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
rateLimiter.Dispose();
base.Dispose(disposing);
}
}
Precis som med andra IChatClient implementeringar kan de RateLimitingChatClient bestå:
using Microsoft.Extensions.AI;
using OllamaSharp;
using System.Threading.RateLimiting;
var client = new RateLimitingChatClient(
new OllamaApiClient(new Uri("http://localhost:11434"), "llama3.1"),
new ConcurrencyLimiter(new() { PermitLimit = 1, QueueLimit = int.MaxValue }));
Console.WriteLine(await client.GetResponseAsync("What color is the sky?"));
För att förenkla sammansättningen av sådana komponenter med andra bör komponentförfattare skapa en Use* tilläggsmetod för att registrera komponenten i en pipeline. Tänk till exempel på följande UseRateLimiting tilläggsmetod:
using Microsoft.Extensions.AI;
using System.Threading.RateLimiting;
public static class RateLimitingChatClientExtensions
{
public static ChatClientBuilder UseRateLimiting(
this ChatClientBuilder builder,
RateLimiter rateLimiter) =>
builder.Use(innerClient =>
new RateLimitingChatClient(innerClient, rateLimiter)
);
}
Sådana tillägg kan också fråga efter relevanta tjänster från DI-containern. den IServiceProvider som används av pipelinen skickas som en valfri parameter:
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.RateLimiting;
public static class RateLimitingChatClientExtensions
{
public static ChatClientBuilder UseRateLimiting(
this ChatClientBuilder builder,
RateLimiter? rateLimiter = null) =>
builder.Use((innerClient, services) =>
new RateLimitingChatClient(
innerClient,
services.GetRequiredService<RateLimiter>())
);
}
Nu är det enkelt för konsumenten att använda detta i sin pipeline, till exempel:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
IChatClient client = new OllamaApiClient(
new Uri("http://localhost:11434/"),
"phi3:mini");
builder.Services.AddChatClient(services =>
client
.AsBuilder()
.UseDistributedCache()
.UseRateLimiting()
.UseOpenTelemetry()
.Build(services));
De tidigare tilläggsmetoderna visar hur du använder en Use metod på ChatClientBuilder.
ChatClientBuilder ger Use också överlagringar som gör det enklare att skriva sådana delegeringshanterare. I det tidigare exemplet RateLimitingChatClient behöver överlagringarna av GetResponseAsync och GetStreamingResponseAsync bara utföra arbete före och efter delegering till nästa klient i pipelinen. Om du vill uppnå samma sak utan att skriva en anpassad klass kan du använda en överlagring av Use som accepterar en delegat som används för både GetResponseAsync och GetStreamingResponseAsync, vilket minskar den mall som krävs.
using Microsoft.Extensions.AI;
using OllamaSharp;
using System.Threading.RateLimiting;
RateLimiter rateLimiter = new ConcurrencyLimiter(new()
{
PermitLimit = 1,
QueueLimit = int.MaxValue
});
IChatClient client = new OllamaApiClient(new Uri("http://localhost:11434"), "llama3.1");
client = ChatClientBuilderChatClientExtensions
.AsBuilder(client)
.UseDistributedCache()
.Use(async (messages, options, nextAsync, cancellationToken) =>
{
using var lease = await rateLimiter.AcquireAsync(permitCount: 1, cancellationToken).ConfigureAwait(false);
if (!lease.IsAcquired)
throw new InvalidOperationException("Unable to acquire lease.");
await nextAsync(messages, options, cancellationToken);
})
.UseOpenTelemetry()
.Build();
För scenarier där du behöver en annan implementering för GetResponseAsync och GetStreamingResponseAsync för att hantera deras respektive unika returtyper, kan du använda Use(Func<IEnumerable<ChatMessage>,ChatOptions,IChatClient,CancellationToken,
Task<ChatResponse>>, Func<IEnumerable<ChatMessage>,ChatOptions,
IChatClient,CancellationToken,IAsyncEnumerable<ChatResponseUpdate>>)-överlastningen som accepterar en delegerad för var och en.
Beroendeinsprutning
IChatClient implementeringar tillhandahålls ofta till ett program via beroendeinmatning (DI). I följande exempel läggs en IDistributedCache till i DI-containern, liksom en IChatClient. Registreringen för IChatClient använder en konfiguration som skapar en pipeline innehållande en cacheklient (som sedan använder en IDistributedCache hämtad från DI) och en exempelklient. Det injekterade IChatClient kan hämtas och användas någon annanstans i appen.
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OllamaSharp;
// App setup.
var builder = Host.CreateApplicationBuilder();
builder.Services.AddDistributedMemoryCache();
builder.Services.AddChatClient(new OllamaApiClient(new Uri("http://localhost:11434"), "llama3.1"))
.UseDistributedCache();
var host = builder.Build();
// Elsewhere in the app.
var chatClient = host.Services.GetRequiredService<IChatClient>();
Console.WriteLine(await chatClient.GetResponseAsync("What is AI?"));
Vilken instans och konfiguration som matas in kan skilja sig beroende på programmets aktuella behov, och flera pipelines kan matas in med olika nycklar.
Tillståndsfria kontra tillståndsfulla klienter
Tillståndslösa tjänster kräver att all relevant konversationshistorik skickas tillbaka på varje begäran. Tillståndskänsliga tjänster håller däremot reda på historiken och kräver att endast ytterligare meddelanden skickas med en begäran. Gränssnittet IChatClient är utformat för att hantera både tillståndslösa och tillståndskänsliga AI-tjänster.
När du arbetar med en tillståndslös tjänst behåller anroparna en lista över alla meddelanden. De lägger till alla mottagna svarsmeddelanden och anger listan igen vid efterföljande interaktioner.
List<ChatMessage> history = [];
while (true)
{
Console.Write("Q: ");
history.Add(new(ChatRole.User, Console.ReadLine()));
var response = await client.GetResponseAsync(history);
Console.WriteLine(response);
history.AddMessages(response);
}
För tillståndskänsliga tjänster kanske du redan känner till identifieraren som används för den relevanta konversationen. Du kan placera identifieraren i ChatOptions.ConversationId. Användningen följer sedan samma mönster, förutom att det inte finns något behov av att underhålla en historik manuellt.
ChatOptions statefulOptions = new() { ConversationId = "my-conversation-id" };
while (true)
{
Console.Write("Q: ");
ChatMessage message = new(ChatRole.User, Console.ReadLine());
Console.WriteLine(await client.GetResponseAsync(message, statefulOptions));
}
Vissa tjänster kan ha stöd för att automatiskt skapa ett konversations-ID för en begäran som inte har något, eller skapa ett nytt konversations-ID som representerar konversationens aktuella tillstånd när den sista meddelanderundan har införlivats. I sådana fall kan du överföra ChatResponse.ConversationId över till ChatOptions.ConversationId för efterföljande begäranden. Till exempel:
ChatOptions options = new();
while (true)
{
Console.Write("Q: ");
ChatMessage message = new(ChatRole.User, Console.ReadLine());
ChatResponse response = await client.GetResponseAsync(message, options);
Console.WriteLine(response);
options.ConversationId = response.ConversationId;
}
Om du inte vet i förväg om tjänsten är tillståndslös eller tillståndsberoende kan du kontrollera svaret ConversationId och vidta åtgärder baserat på dess värde. Om det anges sprids det värdet till alternativen och historiken rensas för att inte skicka samma historik igen. Om svaret ConversationId inte har angetts läggs svarsmeddelandet till i historiken så att det skickas tillbaka till tjänsten vid nästa tur.
List<ChatMessage> chatHistory = [];
ChatOptions chatOptions = new();
while (true)
{
Console.Write("Q: ");
chatHistory.Add(new(ChatRole.User, Console.ReadLine()));
ChatResponse response = await client.GetResponseAsync(chatHistory);
Console.WriteLine(response);
chatOptions.ConversationId = response.ConversationId;
if (response.ConversationId is not null)
{
chatHistory.Clear();
}
else
{
chatHistory.AddMessages(response);
}
}
Implementeringsexempel
Följande exempel implementerar IChatClient för att visa den allmänna strukturen.
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() { }
}
Mer realistiska, konkreta implementeringar av IChatClientfinns i:
Chattreduktion (experimentell)
Viktigt!
Den här funktionen är experimentell och kan komma att ändras.
Genom att minska chatten kan du hantera konversationshistoriken genom att begränsa antalet meddelanden eller sammanfatta äldre meddelanden när konversationen överskrider en angiven längd. Biblioteket Microsoft.Extensions.AI innehåller reducers som MessageCountingChatReducer det begränsar antalet icke-systemmeddelanden och SummarizingChatReducer som automatiskt sammanfattar äldre meddelanden samtidigt som kontexten bevaras.