/////
Search

ChatHistory with Reducer

ChatHistory 기능은 이전 대화 내용들을 기억했다가 다음 답변 시에 활용해 사용자가 필요한 정보에 더욱 알맞은 내용을 주지만, 장점만 있는 것은 아닙니다.
ChatHistory 기능을 사용하면, 그만큼 메모리를 잡아먹게 되기도 하고 보통 AI모델들은 토큰 제한이 있기 때문에 일정 수준을 넘어가면 오히려 응답 속도도 저하되고 대화 내용이 잘린 채 요청을 보냄으로써 이상한 답변을 만들어내기도 합니다.
이때, 대화 내용을 요약하거나 일정 개수의 최신 대화 내용만 반영되도록 reducer를 사용하면 성능을 높일 수 있습니다.

소스 코드

#pragma warning disable SKEXP0001 // Suppress Experimental Feature Warning using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.Extensions.Configuration; // 애플리케이션 설정 구성 인스턴스 생성 var config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) // JSON 파일에서 설정을 로드하도록 .AddUserSecrets<Program>() // 민감 정보를 관리하기 위해 추가 .Build(); // 구성 객체 생성 var endpoint = config["GitHub:Models:EndPoint"]!; var apikey = config["GitHub:Models:ApiKey"]!; var model = config["GitHub:Models:ModelId"]!; // Kernel 및 ChatCompletion 서비스 설정 var kernel = Kernel.CreateBuilder() // CreateBuilder()를 통해 커널 객체 생성 .AddAzureOpenAIChatCompletion(model, endpoint, apikey) // AddOpenAIChatCompletion 대신 AddAzureOpenAIChatCompletion 사용 : 모델 추가 .Build(); var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>(); // IChatCompletionService(: AI 채팅 기능 담당 서비스) 타입의 의존성 검색 & 반환 // Chat History 객체 생성 ChatHistory chatHistory = [ // 시스템 메시지 추가 (초기 설정) new ChatMessageContent(AuthorRole.System, "You are a helpful assistant."), ]; // chatHistory reducer var reducer = new ChatHistoryTruncationReducer(targetCount: 3); // 최대 3개의 메시지만 유지하도록 설정 // var reducer2 = new ChatHistorySummarizationReducer(chatCompletionService, targetCount: 3); // 기본 제공되는 요약 리듀서도 존재 while (true) { Console.Write("User: "); string userInput = Console.ReadLine() ?? string.Empty; if (string.IsNullOrWhiteSpace(userInput) || string.Equals(userInput, "exit", StringComparison.OrdinalIgnoreCase)) break; // 사용자 메시지 추가 chatHistory.Add(new ChatMessageContent(AuthorRole.User, userInput)); // AI 응답 생성 var response = await chatCompletionService.GetChatMessageContentAsync(chatHistory); // 응답을 Chat History에 추가 chatHistory.Add(response); // chatHistory를 줄이기 위해 reducer 호출 var reducedHistory = await reducer.ReduceAsync(chatHistory); chatHistory = reducedHistory is not null ? [.. reducedHistory] : chatHistory; // 응답 출력 Console.WriteLine($"Assistant: {response.Content}"); // chatHistory 개수 출력 Console.WriteLine($"Chat History: {chatHistory.Count}"); } Console.WriteLine("Chat ended.");
C#
복사
처음 ChatHistory 리스트를 생성할때 ChatMessageContent를 하나 넣어주고, 기본 제공되는 메소드를 이용해 reducer 변수를 만들어 최대 3개의 메세지만 유지되도록 만듭니다.
응답을 chatHistory에 추가한 후, reducer를 호출하여 null이 아닌 경우엔 reducedHistory를 사용합니다.

결과

계속해서 3개의 메세지만을 저장하는 모습을 확인 가능합니다.