From 406618527c01cd1130f9bfda0149c99964eccea8 Mon Sep 17 00:00:00 2001 From: Marco Minerva Date: Mon, 24 Mar 2025 10:12:04 +0100 Subject: [PATCH] Refactor token usage and enhance logging capabilities - Updated `TokenUsage` class properties to `PromptTokens` and `CompletionTokens`. - Modified `Ask.razor` to display new token counts. - Added logger to `ChatService` constructor for improved logging. - Implemented logging for token usage in `ChatService` methods. - Changed logging level to `Debug` for paragraph storage in `VectorSearchService`. - Updated logging configuration in `appsettings.Development.json` for better visibility. --- SqlDatabaseVectorSearch/Components/Pages/Ask.razor | 6 +++--- SqlDatabaseVectorSearch/Models/TokenUsage.cs | 4 ++-- SqlDatabaseVectorSearch/Services/ChatService.cs | 5 ++++- SqlDatabaseVectorSearch/Services/VectorSearchService.cs | 4 +++- SqlDatabaseVectorSearch/appsettings.Development.json | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/SqlDatabaseVectorSearch/Components/Pages/Ask.razor b/SqlDatabaseVectorSearch/Components/Pages/Ask.razor index cb315f1..f67d29d 100644 --- a/SqlDatabaseVectorSearch/Components/Pages/Ask.razor +++ b/SqlDatabaseVectorSearch/Components/Pages/Ask.razor @@ -235,9 +235,9 @@ return string.Empty; } - return $"Input Token Count: {tokenUsage.InputTokenCount}
" + - $"Output Token Count: {tokenUsage.OutputTokenCount}
" + - $"Total Token Count: {tokenUsage.TotalTokenCount}"; + return $"Prompt tokens: {tokenUsage.PromptTokens}
" + + $"Completion tokens: {tokenUsage.CompletionTokens}
" + + $"Total tokens: {tokenUsage.TotalTokens}"; } } diff --git a/SqlDatabaseVectorSearch/Models/TokenUsage.cs b/SqlDatabaseVectorSearch/Models/TokenUsage.cs index 603ee1f..9a39649 100644 --- a/SqlDatabaseVectorSearch/Models/TokenUsage.cs +++ b/SqlDatabaseVectorSearch/Models/TokenUsage.cs @@ -1,6 +1,6 @@ namespace SqlDatabaseVectorSearch.Models; -public record class TokenUsage(int InputTokenCount, int OutputTokenCount) +public record class TokenUsage(int PromptTokens, int CompletionTokens) { - public int TotalTokenCount => InputTokenCount + OutputTokenCount; + public int TotalTokens => PromptTokens + CompletionTokens; } diff --git a/SqlDatabaseVectorSearch/Services/ChatService.cs b/SqlDatabaseVectorSearch/Services/ChatService.cs index 0dc6e3e..befa22e 100644 --- a/SqlDatabaseVectorSearch/Services/ChatService.cs +++ b/SqlDatabaseVectorSearch/Services/ChatService.cs @@ -10,7 +10,7 @@ using SqlDatabaseVectorSearch.Settings; namespace SqlDatabaseVectorSearch.Services; -public class ChatService(IChatCompletionService chatCompletionService, TokenizerService tokenizerService, HybridCache cache, IOptions appSettingsOptions) +public class ChatService(IChatCompletionService chatCompletionService, TokenizerService tokenizerService, HybridCache cache, IOptions appSettingsOptions, ILogger logger) { private readonly AppSettings appSettings = appSettingsOptions.Value; @@ -36,6 +36,7 @@ public class ChatService(IChatCompletionService chatCompletionService, Tokenizer await UpdateCacheAsync(conversationId, chat, cancellationToken); var tokenUsage = GetTokenUsage(reformulatedQuestion); + logger.LogDebug("Reformulation: {TokenUsage}", tokenUsage); return new(reformulatedQuestion.Content!, tokenUsage); } @@ -53,6 +54,7 @@ public class ChatService(IChatCompletionService chatCompletionService, Tokenizer await SetChatHistoryAsync(conversationId, question, answer.Content!, cancellationToken); var tokenUsage = GetTokenUsage(answer); + logger.LogDebug("Ask question: {TokenUsage}", tokenUsage); return new(answer.Content!, tokenUsage); } @@ -78,6 +80,7 @@ public class ChatService(IChatCompletionService chatCompletionService, Tokenizer var tokenUsage = GetTokenUsage(token); if (tokenUsage is not null) { + logger.LogDebug("Ask streaming: {TokenUsage}", tokenUsage); yield return new(null, tokenUsage); } } diff --git a/SqlDatabaseVectorSearch/Services/VectorSearchService.cs b/SqlDatabaseVectorSearch/Services/VectorSearchService.cs index 2c1a26d..581abc5 100644 --- a/SqlDatabaseVectorSearch/Services/VectorSearchService.cs +++ b/SqlDatabaseVectorSearch/Services/VectorSearchService.cs @@ -47,7 +47,7 @@ public class VectorSearchService(IServiceProvider serviceProvider, ApplicationDb // Save the document chunks and the corresponding embedding in the database. foreach (var (index, paragraph) in paragraphs.Index()) { - logger.LogInformation("Storing a paragraph of {TokenCount} tokens.", tokenizerService.CountChatCompletionTokens(paragraph)); + logger.LogDebug("Storing a paragraph of {TokenCount} tokens.", tokenizerService.CountChatCompletionTokens(paragraph)); var documentChunk = new Entities.DocumentChunk { Document = document, Index = index, Content = paragraph!, Embedding = embeddings[index].ToArray() }; dbContext.DocumentChunks.Add(documentChunk); @@ -103,7 +103,9 @@ public class VectorSearchService(IServiceProvider serviceProvider, ApplicationDb { // Reformulate the question taking into account the context of the chat to perform keyword search and embeddings. var reformulatedQuestion = reformulate ? await chatService.CreateQuestionAsync(question.ConversationId, question.Text, cancellationToken) : new(question.Text); + var embeddingTokenCount = tokenizerService.CountEmbeddingTokens(reformulatedQuestion.Text!); + logger.LogDebug("Embedding Token Count: {EmbeddingTokenCount}", embeddingTokenCount); // Perform Vector Search on SQL Database. var questionEmbedding = await textEmbeddingGenerationService.GenerateEmbeddingAsync(reformulatedQuestion.Text!, cancellationToken: cancellationToken); diff --git a/SqlDatabaseVectorSearch/appsettings.Development.json b/SqlDatabaseVectorSearch/appsettings.Development.json index 63fe121..19c6237 100644 --- a/SqlDatabaseVectorSearch/appsettings.Development.json +++ b/SqlDatabaseVectorSearch/appsettings.Development.json @@ -3,7 +3,7 @@ "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", - "Microsoft.KernelMemory": "Debug" + "SqlDatabaseVectorSearch": "Debug" } } }