diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/ChatConversationEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/ChatConversationEvaluator.cs index 63e17ebe1ac..0aafa3726b1 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/ChatConversationEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/ChatConversationEvaluator.cs @@ -55,100 +55,8 @@ public virtual async ValueTask EvaluateAsync( return result; } - (ChatMessage? userRequest, List history) = GetUserRequestAndHistory(messages); - - int inputTokenLimit = 0; - int ignoredMessagesCount = 0; - - if (chatConfiguration.TokenCounter is not null) - { - IEvaluationTokenCounter tokenCounter = chatConfiguration.TokenCounter; - inputTokenLimit = tokenCounter.InputTokenLimit; - int tokenBudget = inputTokenLimit; - - void OnTokenBudgetExceeded() - { - EvaluationDiagnostic tokenBudgetExceeded = - EvaluationDiagnostic.Error( - $"Evaluation failed because the specified limit of {inputTokenLimit} input tokens was exceeded."); - - result.AddDiagnosticsToAllMetrics(tokenBudgetExceeded); - } - - if (!string.IsNullOrWhiteSpace(SystemPrompt)) - { - tokenBudget -= tokenCounter.CountTokens(SystemPrompt!); - if (tokenBudget < 0) - { - OnTokenBudgetExceeded(); - return result; - } - } - - string baseEvaluationPrompt = - await RenderEvaluationPromptAsync( - userRequest, - modelResponse, - includedHistory: [], - additionalContext, - cancellationToken).ConfigureAwait(false); - - tokenBudget -= tokenCounter.CountTokens(baseEvaluationPrompt); - if (tokenBudget < 0) - { - OnTokenBudgetExceeded(); - return result; - } - - if (history.Count > 0 && !IgnoresHistory) - { - if (history.Count == 1) - { - (bool canRender, tokenBudget) = - await CanRenderAsync( - history[0], - tokenBudget, - chatConfiguration, - cancellationToken).ConfigureAwait(false); - - if (!canRender) - { - ignoredMessagesCount = 1; - history = []; - } - } - else - { - int totalMessagesCount = history.Count; - int includedMessagesCount = 0; - - history.Reverse(); - - foreach (ChatMessage message in history) - { - cancellationToken.ThrowIfCancellationRequested(); - - (bool canRender, tokenBudget) = - await CanRenderAsync( - message, - tokenBudget, - chatConfiguration, - cancellationToken).ConfigureAwait(false); - - if (!canRender) - { - ignoredMessagesCount = totalMessagesCount - includedMessagesCount; - history.RemoveRange(index: includedMessagesCount, count: ignoredMessagesCount); - break; - } - - includedMessagesCount++; - } - - history.Reverse(); - } - } - } + (ChatMessage? userRequest, List conversationHistory) = + GetUserRequestAndConversationHistory(messages); var evaluationMessages = new List(); if (!string.IsNullOrWhiteSpace(SystemPrompt)) @@ -160,7 +68,7 @@ await CanRenderAsync( await RenderEvaluationPromptAsync( userRequest, modelResponse, - includedHistory: history, + conversationHistory, additionalContext, cancellationToken).ConfigureAwait(false); @@ -172,84 +80,9 @@ await PerformEvaluationAsync( result, cancellationToken).ConfigureAwait(false); - if (inputTokenLimit > 0 && ignoredMessagesCount > 0) - { -#pragma warning disable S103 // Lines should not be too long - result.AddDiagnosticsToAllMetrics( - EvaluationDiagnostic.Warning( - $"The evaluation may be inconclusive because the oldest {ignoredMessagesCount} messages in the supplied conversation history were ignored in order to stay under the specified limit of {inputTokenLimit} input tokens.")); -#pragma warning restore S103 - } - return result; } - /// - /// Determines if there is sufficient remaining to render the - /// supplied as part of the evaluation prompt that this uses. - /// - /// - /// A message that is part of the conversation history for the response being evaluated and that is to be rendered - /// as part of the evaluation prompt. - /// - /// - /// The number of tokens available for the rendering additional content as part of the evaluation prompt. - /// - /// - /// A that specifies the and the - /// that this uses to perform the evaluation. - /// - /// A that can cancel the operation. - /// - /// A tuple containing a indicating whether there is sufficient - /// remaining to render the supplied as part of the - /// evaluation prompt, and an containing the remaining token budget that would be available - /// once this is rendered. - /// - protected virtual ValueTask<(bool canRender, int remainingTokenBudget)> CanRenderAsync( - ChatMessage message, - int tokenBudget, - ChatConfiguration chatConfiguration, - CancellationToken cancellationToken) - { - _ = Throw.IfNull(message); - _ = Throw.IfNull(chatConfiguration); - - IEvaluationTokenCounter? tokenCounter = chatConfiguration.TokenCounter; - if (tokenCounter is null) - { - return new ValueTask<(bool, int)>((true, tokenBudget)); - } - - string? author = message.AuthorName; - string role = message.Role.Value; - string content = message.Text ?? string.Empty; - - int tokenCount = - string.IsNullOrWhiteSpace(author) - ? tokenCounter.CountTokens("[") + - tokenCounter.CountTokens(role) + - tokenCounter.CountTokens("] ") + - tokenCounter.CountTokens(content) + - tokenCounter.CountTokens("\n") - : tokenCounter.CountTokens("[") + - tokenCounter.CountTokens(author!) + - tokenCounter.CountTokens(" (") + - tokenCounter.CountTokens(role) + - tokenCounter.CountTokens(")] ") + - tokenCounter.CountTokens(content) + - tokenCounter.CountTokens("\n"); - - if (tokenCount > tokenBudget) - { - return new ValueTask<(bool, int)>((false, tokenBudget)); - } - else - { - return new ValueTask<(bool, int)>((true, tokenBudget - tokenCount)); - } - } - /// /// Renders the supplied to a string that can be included as part of the evaluation /// prompt that this uses. @@ -313,13 +146,13 @@ protected virtual ValueTask RenderAsync(ChatMessage message, Cancellatio /// The request that produced the that is to be evaluated. /// /// The response that is to be evaluated. - /// + /// /// The conversation history (excluding the and ) /// that is to be included as part of the evaluation prompt. /// /// /// Additional contextual information (beyond that which is available in the and - /// ) that this may need to accurately evaluate the + /// ) that this may need to accurately evaluate the /// supplied . /// /// A that can cancel the operation. @@ -327,7 +160,7 @@ protected virtual ValueTask RenderAsync(ChatMessage message, Cancellatio protected abstract ValueTask RenderEvaluationPromptAsync( ChatMessage? userRequest, ChatResponse modelResponse, - IEnumerable? includedHistory, + IEnumerable? conversationHistory, IEnumerable? additionalContext, CancellationToken cancellationToken); @@ -351,8 +184,8 @@ protected abstract ValueTask RenderEvaluationPromptAsync( /// s in the supplied . /// /// - /// A that specifies the and the - /// that this uses to perform the evaluation. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// The set of messages that are to be sent to the supplied to perform @@ -370,11 +203,11 @@ protected abstract ValueTask PerformEvaluationAsync( EvaluationResult result, CancellationToken cancellationToken); - private (ChatMessage? userRequest, List history) GetUserRequestAndHistory( + private (ChatMessage? userRequest, List conversationHistory) GetUserRequestAndConversationHistory( IEnumerable messages) { ChatMessage? userRequest = null; - List history; + List conversationHistory; if (IgnoresHistory) { @@ -383,22 +216,22 @@ protected abstract ValueTask PerformEvaluationAsync( ? lastMessage : null; - history = []; + conversationHistory = []; } else { - history = [.. messages]; - int lastMessageIndex = history.Count - 1; + conversationHistory = [.. messages]; + int lastMessageIndex = conversationHistory.Count - 1; if (lastMessageIndex >= 0 && - history[lastMessageIndex] is ChatMessage lastMessage && + conversationHistory[lastMessageIndex] is ChatMessage lastMessage && lastMessage.Role == ChatRole.User) { userRequest = lastMessage; - history.RemoveAt(lastMessageIndex); + conversationHistory.RemoveAt(lastMessageIndex); } } - return (userRequest, history); + return (userRequest, conversationHistory); } } diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/CoherenceEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/CoherenceEvaluator.cs index fb918e50aa4..ffdf0232932 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/CoherenceEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/CoherenceEvaluator.cs @@ -50,7 +50,7 @@ public sealed class CoherenceEvaluator : SingleNumericMetricEvaluator protected override async ValueTask RenderEvaluationPromptAsync( ChatMessage? userRequest, ChatResponse modelResponse, - IEnumerable? includedHistory, + IEnumerable? conversationHistory, IEnumerable? additionalContext, CancellationToken cancellationToken) { diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/EquivalenceEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/EquivalenceEvaluator.cs index 4a15f3640ee..9b7df80210f 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/EquivalenceEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/EquivalenceEvaluator.cs @@ -75,7 +75,7 @@ await base.EvaluateAsync( protected override async ValueTask RenderEvaluationPromptAsync( ChatMessage? userRequest, ChatResponse modelResponse, - IEnumerable? includedHistory, + IEnumerable? conversationHistory, IEnumerable? additionalContext, CancellationToken cancellationToken) { diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/FluencyEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/FluencyEvaluator.cs index c2463be2c5c..389de435a3a 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/FluencyEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/FluencyEvaluator.cs @@ -49,7 +49,7 @@ public sealed class FluencyEvaluator : SingleNumericMetricEvaluator protected override async ValueTask RenderEvaluationPromptAsync( ChatMessage? userRequest, ChatResponse modelResponse, - IEnumerable? includedHistory, + IEnumerable? conversationHistory, IEnumerable? additionalContext, CancellationToken cancellationToken) { diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/GroundednessEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/GroundednessEvaluator.cs index c8881864d40..c95284dd108 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/GroundednessEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/GroundednessEvaluator.cs @@ -77,7 +77,7 @@ await base.EvaluateAsync( protected override async ValueTask RenderEvaluationPromptAsync( ChatMessage? userRequest, ChatResponse modelResponse, - IEnumerable? includedHistory, + IEnumerable? conversationHistory, IEnumerable? additionalContext, CancellationToken cancellationToken) { @@ -99,9 +99,9 @@ userRequest is not null _ = builder.AppendLine(); } - if (includedHistory is not null) + if (conversationHistory is not null) { - foreach (ChatMessage message in includedHistory) + foreach (ChatMessage message in conversationHistory) { _ = builder.Append(await RenderAsync(message, cancellationToken).ConfigureAwait(false)); } diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/RelevanceTruthAndCompletenessEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/RelevanceTruthAndCompletenessEvaluator.cs index ee586b9b242..f781a689564 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/RelevanceTruthAndCompletenessEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/RelevanceTruthAndCompletenessEvaluator.cs @@ -93,7 +93,7 @@ protected override EvaluationResult InitializeResult() protected override async ValueTask RenderEvaluationPromptAsync( ChatMessage? userRequest, ChatResponse modelResponse, - IEnumerable? includedHistory, + IEnumerable? conversationHistory, IEnumerable? additionalContext, CancellationToken cancellationToken) { @@ -107,9 +107,9 @@ userRequest is not null : string.Empty; var builder = new StringBuilder(); - if (includedHistory is not null) + if (conversationHistory is not null) { - foreach (ChatMessage message in includedHistory) + foreach (ChatMessage message in conversationHistory) { _ = builder.Append(await RenderAsync(message, cancellationToken).ConfigureAwait(false)); } diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/Utilities/JsonOutputFixer.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/Utilities/JsonOutputFixer.cs index b50d69bcebd..8c07b93106c 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/Utilities/JsonOutputFixer.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Quality/Utilities/JsonOutputFixer.cs @@ -24,7 +24,7 @@ internal static ReadOnlySpan TrimMarkdownDelimiters(string json) // Trim 'json' marker from markdown if it exists. const string JsonMarker = "json"; int markerLength = JsonMarker.Length; - if (trimmed.Length > markerLength && trimmed[0..markerLength].SequenceEqual(JsonMarker.AsSpan())) + if (trimmed.Length > markerLength && trimmed.Slice(0, markerLength).SequenceEqual(JsonMarker.AsSpan())) { trimmed = trimmed.Slice(markerLength); } diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/Storage/AzureStorageReportingConfiguration.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/Storage/AzureStorageReportingConfiguration.cs index 0901e6e7063..9302107b926 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/Storage/AzureStorageReportingConfiguration.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/Storage/AzureStorageReportingConfiguration.cs @@ -29,10 +29,9 @@ public static class AzureStorageReportingConfiguration /// survive in the cache before they are considered expired and evicted. /// /// - /// A that specifies the and the - /// that are used by AI-based included in the - /// returned . Can be omitted if none of the included - /// are AI-based. + /// A that specifies the that is used by AI-based + /// included in the returned . Can be omitted if + /// none of the included are AI-based. /// /// /// to enable caching of AI responses; otherwise. diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ReportingConfiguration.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ReportingConfiguration.cs index c8a5c1b2411..e80f4b76f11 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ReportingConfiguration.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ReportingConfiguration.cs @@ -30,9 +30,8 @@ public sealed class ReportingConfiguration public IResultStore ResultStore { get; } /// - /// Gets a that specifies the and the - /// that are used by AI-based included in this - /// . + /// Gets a that specifies the that is used by + /// AI-based included in this . /// public ChatConfiguration? ChatConfiguration { get; } @@ -103,10 +102,9 @@ public sealed class ReportingConfiguration /// The that should be used to persist the s. /// /// - /// A that specifies the and the - /// that are used by AI-based included in this - /// . Can be omitted if none of the included are - /// AI-based. + /// A that specifies the that is used by + /// AI-based included in this . Can be omitted if + /// none of the included are AI-based. /// /// /// The that should be used to cache AI responses. If omitted, AI responses @@ -246,7 +244,7 @@ await ResponseCacheProvider.GetCacheAsync( } #pragma warning restore CA2000 - chatConfiguration = new ChatConfiguration(chatClient, chatConfiguration.TokenCounter); + chatConfiguration = new ChatConfiguration(chatClient); } return new ScenarioRun( diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRun.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRun.cs index 89a81288b3a..e82c3ebba6e 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRun.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRun.cs @@ -80,9 +80,9 @@ public sealed class ScenarioRun : IAsyncDisposable public string ExecutionName { get; } /// - /// Gets a that specifies the and the - /// that are used by AI-based s that are invoked as - /// part of the evaluation of this . + /// Gets a that specifies the that is used by + /// AI-based s that are invoked as part of the evaluation of this + /// . /// public ChatConfiguration? ChatConfiguration { get; } diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Storage/DiskBasedReportingConfiguration.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Storage/DiskBasedReportingConfiguration.cs index c1f1eccac67..94ab92e177b 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Storage/DiskBasedReportingConfiguration.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Storage/DiskBasedReportingConfiguration.cs @@ -25,10 +25,9 @@ public static class DiskBasedReportingConfiguration /// The set of s that should be invoked to evaluate AI responses. /// /// - /// A that specifies the and the - /// that are used by AI-based included in the - /// returned . Can be omitted if none of the included - /// are AI-based. + /// A that specifies the that is used by AI-based + /// included in the returned . Can be omitted if + /// none of the included are AI-based. /// /// /// to enable caching of AI responses; otherwise. diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/ContentSafetyServiceConfigurationExtensions.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/ContentSafetyServiceConfigurationExtensions.cs index 2021809c5e5..9bf6ade6068 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/ContentSafetyServiceConfigurationExtensions.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/ContentSafetyServiceConfigurationExtensions.cs @@ -46,7 +46,7 @@ public static ChatConfiguration ToChatConfiguration( originalChatClient: originalChatConfiguration?.ChatClient); #pragma warning restore CA2000 - return new ChatConfiguration(newChatClient, originalChatConfiguration?.TokenCounter); + return new ChatConfiguration(newChatClient); } /// diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/Microsoft.Extensions.AI.Evaluation.Safety.csproj b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/Microsoft.Extensions.AI.Evaluation.Safety.csproj index 48af7f9126c..75ffb46f84b 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/Microsoft.Extensions.AI.Evaluation.Safety.csproj +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Safety/Microsoft.Extensions.AI.Evaluation.Safety.csproj @@ -15,6 +15,10 @@ 0 0 + + + + diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation/ChatConfiguration.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation/ChatConfiguration.cs index becf1e9a9ff..881816b198b 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation/ChatConfiguration.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation/ChatConfiguration.cs @@ -9,27 +9,13 @@ namespace Microsoft.Extensions.AI.Evaluation; /// -/// Specifies the and the that should be used when -/// evaluation is performed using an AI model. +/// Specifies the that should be used when evaluation is performed using an AI model. /// /// An that can be used to communicate with an AI model. -/// -/// An that can be used to counts tokens present in evaluation prompts, or -/// if the AI model / deployment being used does not impose an input token limit. -/// -public sealed class ChatConfiguration(IChatClient chatClient, IEvaluationTokenCounter? tokenCounter = null) +public sealed class ChatConfiguration(IChatClient chatClient) { /// /// Gets an that can be used to communicate with an AI model. /// public IChatClient ChatClient { get; } = chatClient; - - /// - /// Gets an that can be used to counts tokens present in evaluation prompts. - /// - /// - /// can be set to if the AI model / deployment being used does - /// not impose an input token limit. - /// - public IEvaluationTokenCounter? TokenCounter { get; } = tokenCounter; } diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation/CompositeEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation/CompositeEvaluator.cs index 6feba92d6c3..17274fec666 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation/CompositeEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation/CompositeEvaluator.cs @@ -88,9 +88,8 @@ public CompositeEvaluator(IEnumerable evaluators) /// /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if one or more composed s use - /// an AI model to perform evaluation. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information (beyond that which is available in ) that composed diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation/EvaluatorExtensions.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation/EvaluatorExtensions.cs index cfef4121af4..3ffda8fb8f9 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation/EvaluatorExtensions.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation/EvaluatorExtensions.cs @@ -30,8 +30,8 @@ public static class EvaluatorExtensions /// The that should perform the evaluation. /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if the evaluation is performed using an AI model. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information that the may need to accurately evaluate the @@ -73,8 +73,8 @@ public static ValueTask EvaluateAsync( /// /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if the evaluation is performed using an AI model. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information (beyond that which is available in ) that the @@ -115,8 +115,8 @@ public static ValueTask EvaluateAsync( /// The that should perform the evaluation. /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if the evaluation is performed using an AI model. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information that the may need to accurately evaluate the @@ -160,8 +160,8 @@ public static ValueTask EvaluateAsync( /// The that should perform the evaluation. /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if the evaluation is performed using an AI model. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information that the may need to accurately evaluate the @@ -208,8 +208,8 @@ public static ValueTask EvaluateAsync( /// /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if the evaluation is performed using an AI model. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information (beyond that which is available in ) that the @@ -257,8 +257,8 @@ public static ValueTask EvaluateAsync( /// /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if the evaluation is performed using an AI model. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information (beyond that which is available in ) that the diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation/IEvaluationTokenCounter.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation/IEvaluationTokenCounter.cs deleted file mode 100644 index 6328a3e68b6..00000000000 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation/IEvaluationTokenCounter.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Extensions.AI.Evaluation; - -/// -/// Counts the number of tokens present in evaluation prompts that are to be sent to an AI model. -/// -/// -/// -/// s that rely on an AI model to perform evaluations can use -/// to ensure that the evaluation prompts they use do not exceed the specified -/// . -/// -/// -/// The token counting implementation can vary depending on the AI model that is used. Use the -/// extension method to get a -/// from the for a given AI model. -/// -/// -public interface IEvaluationTokenCounter -{ - /// - /// Gets the input token limit for the AI model / deployment in use. - /// - int InputTokenLimit { get; } - - /// - /// Counts the number of tokens present in the supplied . - /// - /// The string content that is to be counted. - /// The number of tokens present in the supplied . - int CountTokens(string content); -} diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation/IEvaluator.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation/IEvaluator.cs index eef8b2f3ada..255d577e4e4 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation/IEvaluator.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation/IEvaluator.cs @@ -38,8 +38,8 @@ public interface IEvaluator /// /// The response that is to be evaluated. /// - /// A that specifies the and the - /// that should be used if the evaluation is performed using an AI model. + /// A that specifies the that should be used if one or + /// more composed s use an AI model to perform evaluation. /// /// /// Additional contextual information (beyond that which is available in ) that the diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation/Microsoft.Extensions.AI.Evaluation.csproj b/src/Libraries/Microsoft.Extensions.AI.Evaluation/Microsoft.Extensions.AI.Evaluation.csproj index 0123cae0f0f..703c83cb390 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation/Microsoft.Extensions.AI.Evaluation.csproj +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation/Microsoft.Extensions.AI.Evaluation.csproj @@ -15,10 +15,6 @@ 0 - - - - diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation/TokenizerExtensions.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation/TokenizerExtensions.cs deleted file mode 100644 index 681d69ed1e1..00000000000 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation/TokenizerExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#pragma warning disable S3604 -// S3604: Member initializer values should not be redundant. -// We disable this warning because it is a false positive arising from the analyzer's lack of support for C#'s primary -// constructor syntax. - -using Microsoft.ML.Tokenizers; -using Microsoft.Shared.Diagnostics; - -namespace Microsoft.Extensions.AI.Evaluation; - -/// -/// Extension methods for . -/// -public static class TokenizerExtensions -{ - private sealed class TokenCounter(Tokenizer tokenizer, int inputTokenLimit) : IEvaluationTokenCounter - { - public int InputTokenLimit { get; } = inputTokenLimit; - - public int CountTokens(string content) - => tokenizer.CountTokens(content); - } - - /// - /// Returns an given the and the - /// for a particular AI model / deployment. - /// - /// The for a particular AI model. - /// - /// The threshold of maximum allowed input tokens for a particular AI model / deployment. - /// - /// - /// An for a particular AI model / deployment. - /// - public static IEvaluationTokenCounter ToTokenCounter(this Tokenizer tokenizer, int inputTokenLimit) - { - _ = Throw.IfNull(tokenizer); - - return new TokenCounter(tokenizer, inputTokenLimit); - } -} diff --git a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Microsoft.Extensions.AI.Evaluation.Integration.Tests.csproj b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Microsoft.Extensions.AI.Evaluation.Integration.Tests.csproj index 4679b04a338..b81985a4990 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Microsoft.Extensions.AI.Evaluation.Integration.Tests.csproj +++ b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Microsoft.Extensions.AI.Evaluation.Integration.Tests.csproj @@ -7,11 +7,12 @@ - + + @@ -19,8 +20,6 @@ - - diff --git a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/QualityEvaluatorTests.cs b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/QualityEvaluatorTests.cs index ab181160e26..1a53360799c 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/QualityEvaluatorTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/QualityEvaluatorTests.cs @@ -12,6 +12,7 @@ using Microsoft.Extensions.AI.Evaluation.Quality; using Microsoft.Extensions.AI.Evaluation.Reporting; using Microsoft.Extensions.AI.Evaluation.Reporting.Storage; +using Microsoft.Extensions.AI.Evaluation.Tests; using Microsoft.TestUtilities; using Xunit; diff --git a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/ResultsTests.cs b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/ResultsTests.cs index 1b52ee9d6d5..c2c02103714 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/ResultsTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/ResultsTests.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.AI.Evaluation; using Microsoft.Extensions.AI.Evaluation.Reporting; using Microsoft.Extensions.AI.Evaluation.Reporting.Storage; +using Microsoft.Extensions.AI.Evaluation.Tests; using Xunit; namespace Microsoft.Extensions.AI.Evaluation.Integration.Tests; diff --git a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/SafetyEvaluatorTests.cs b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/SafetyEvaluatorTests.cs index 3e4a7867ad5..36b0a9f68c5 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/SafetyEvaluatorTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/SafetyEvaluatorTests.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.AI.Evaluation.Reporting; using Microsoft.Extensions.AI.Evaluation.Reporting.Storage; using Microsoft.Extensions.AI.Evaluation.Safety; +using Microsoft.Extensions.AI.Evaluation.Tests; using Microsoft.TestUtilities; using Xunit; diff --git a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Setup.cs b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Setup.cs index 75c5f629e10..30cb541e700 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Setup.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/Setup.cs @@ -5,7 +5,6 @@ using System.ClientModel; using Azure.AI.OpenAI; using Azure.Identity; -using Microsoft.ML.Tokenizers; namespace Microsoft.Extensions.AI.Evaluation.Integration.Tests; @@ -25,8 +24,6 @@ internal static ChatConfiguration CreateChatConfiguration() : new AzureOpenAIClient(endpoint, credential, options); IChatClient chatClient = azureClient.GetChatClient(Settings.Current.DeploymentName).AsIChatClient(); - Tokenizer tokenizer = TiktokenTokenizer.CreateForModel(Settings.Current.ModelName); - IEvaluationTokenCounter tokenCounter = tokenizer.ToTokenCounter(inputTokenLimit: 6000); - return new ChatConfiguration(chatClient, tokenCounter); + return new ChatConfiguration(chatClient); } } diff --git a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/ChatMessageUtilities.cs b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Tests/ChatMessageUtilities.cs similarity index 89% rename from test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/ChatMessageUtilities.cs rename to test/Libraries/Microsoft.Extensions.AI.Evaluation.Tests/ChatMessageUtilities.cs index 374652e7199..e42d5fd7107 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Integration.Tests/ChatMessageUtilities.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Tests/ChatMessageUtilities.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.Extensions.AI.Evaluation.Integration.Tests; +namespace Microsoft.Extensions.AI.Evaluation.Tests; internal static class ChatMessageUtilities {