본문 바로가기

C#

Part 2: 고급 상호작용 처리 및 C# ChatGPT 통합 개선

반응형

소개

첫 번째 파트에서는 기본 C# 콘솔 애플리케이션을 설정하고 OpenAI ChatGPT API에 간단한 요청을 보냈습니다. 두 번째 파트에서는 애플리케이션을 개선하여 더 고급 상호작용을 처리하고, 오류 처리를 추가하며, API 호출을 개선하여 더 나은 응답을 얻는 방법을 다룹니다.

1단계: 사용자 인터페이스 개선

ChatGPT와의 지속적인 상호작용을 허용하기 위해 사용자 인터페이스를 개선해 보겠습니다. Main 메서드를 수정하여 사용자가 "exit"를 입력할 때까지 입력을 받을 수 있는 루프를 만듭니다.

using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace ChatGPTDemo
{
    class Program
    {
        private static readonly HttpClient client = new HttpClient();
        private static string apiKey = "your_api_key_here";  // OpenAI API 키로 교체하세요

        static async Task Main(string[] args)
        {
            while (true)
            {
                Console.Write("You: ");
                string userInput = Console.ReadLine();

                if (userInput.ToLower() == "exit")
                {
                    break;
                }

                string response = await GetChatGPTResponse(userInput);
                Console.WriteLine("ChatGPT: " + response);
            }
        }

        private static async Task<string> GetChatGPTResponse(string prompt)
        {
            var requestContent = new
            {
                model = "gpt-3.5-turbo",
                messages = new[]
                {
                    new { role = "system", content = "당신은 도움을 주는 어시스턴트입니다." },
                    new { role = "user", content = prompt }
                }
            };

            var content = new StringContent(JsonConvert.SerializeObject(requestContent), Encoding.UTF8, "application/json");

            client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

            var response = await client.PostAsync("https://api.openai.com/v1/chat/completions", content);

            if (response.IsSuccessStatusCode)
            {
                var responseString = await response.Content.ReadAsStringAsync();
                dynamic responseObject = JsonConvert.DeserializeObject(responseString);
                return responseObject.choices[0].message.content.ToString();
            }
            else
            {
                return "Error: " + response.StatusCode;
            }
        }
    }
}

2단계: 오류 처리 추가

다양한 오류 조건을 확인하고 사용자에게 적절한 피드백을 제공하여 오류 처리를 개선하겠습니다.

private static async Task<string> GetChatGPTResponse(string prompt)
{
    var requestContent = new
    {
        model = "gpt-3.5-turbo",
        messages = new[]
        {
            new { role = "system", content = "당신은 도움을 주는 어시스턴트입니다." },
            new { role = "user", content = prompt }
        }
    };

    var content = new StringContent(JsonConvert.SerializeObject(requestContent), Encoding.UTF8, "application/json");

    client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

    try
    {
        var response = await client.PostAsync("https://api.openai.com/v1/chat/completions", content);

        if (response.IsSuccessStatusCode)
        {
            var responseString = await response.Content.ReadAsStringAsync();
            dynamic responseObject = JsonConvert.DeserializeObject(responseString);
            return responseObject.choices[0].message.content.ToString();
        }
        else
        {
            return "Error: " + response.StatusCode + " - " + await response.Content.ReadAsStringAsync();
        }
    }
    catch (HttpRequestException e)
    {
        return "Request error: " + e.Message;
    }
    catch (Exception e)
    {
        return "Unexpected error: " + e.Message;
    }
}

3단계: API 요금 한도 관리

API 요금 한도를 처리하기 위해 지수적 백오프(retry with exponential backoff)를 구현하겠습니다. 즉, 요청이 요금 한도로 인해 실패하면 대기 후 재시도하고, 재시도마다 대기 시간을 늘리는 것입니다.

private static async Task<string> GetChatGPTResponse(string prompt)
{
    var requestContent = new
    {
        model = "gpt-3.5-turbo",
        messages = new[]
        {
            new { role = "system", content = "당신은 도움을 주는 어시스턴트입니다." },
            new { role = "user", content = prompt }
        }
    };

    var content = new StringContent(JsonConvert.SerializeObject(requestContent), Encoding.UTF8, "application/json");

    client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

    int maxRetries = 5;
    int delay = 1000;

    for (int i = 0; i < maxRetries; i++)
    {
        try
        {
            var response = await client.PostAsync("https://api.openai.com/v1/chat/completions", content);

            if (response.IsSuccessStatusCode)
            {
                var responseString = await response.Content.ReadAsStringAsync();
                dynamic responseObject = JsonConvert.DeserializeObject(responseString);
                return responseObject.choices[0].message.content.ToString();
            }
            else if (response.StatusCode == (System.Net.HttpStatusCode)429) // Too Many Requests
            {
                await Task.Delay(delay);
                delay *= 2;
            }
            else
            {
                return "Error: " + response.StatusCode + " - " + await response.Content.ReadAsStringAsync();
            }
        }
        catch (HttpRequestException e)
        {
            return "Request error: " + e.Message;
        }
        catch (Exception e)
        {
            return "Unexpected error: " + e.Message;
        }
    }

    return "Failed to get a response after multiple attempts.";
}

4단계: 대화 컨텍스트 향상

대화의 컨텍스트를 유지하기 위해 대화 기록을 저장하고 각 새로운 사용자 입력과 함께 전송하겠습니다.

using System.Collections.Generic;

namespace ChatGPTDemo
{
    class Program
    {
        private static readonly HttpClient client = new HttpClient();
        private static string apiKey = "your_api_key_here";  // OpenAI API 키로 교체하세요
        private static List<dynamic> messages = new List<dynamic>
        {
            new { role = "system", content = "당신은 도움을 주는 어시스턴트입니다." }
        };

        static async Task Main(string[] args)
        {
            while (true)
            {
                Console.Write("You: ");
                string userInput = Console.ReadLine();

                if (userInput.ToLower() == "exit")
                {
                    break;
                }

                messages.Add(new { role = "user", content = userInput });
                string response = await GetChatGPTResponse(messages);
                Console.WriteLine("ChatGPT: " + response);

                messages.Add(new { role = "assistant", content = response });
            }
        }

        private static async Task<string> GetChatGPTResponse(List<dynamic> messages)
        {
            var requestContent = new
            {
                model = "gpt-3.5-turbo",
                messages = messages.ToArray()
            };

            var content = new StringContent(JsonConvert.SerializeObject(requestContent), Encoding.UTF8, "application/json");

            client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

            int maxRetries = 5;
            int delay = 1000;

            for (int i = 0; i < maxRetries; i++)
            {
                try
                {
                    var response = await client.PostAsync("https://api.openai.com/v1/chat/completions", content);

                    if (response.IsSuccessStatusCode)
                    {
                        var responseString = await response.Content.ReadAsStringAsync();
                        dynamic responseObject = JsonConvert.DeserializeObject(responseString);
                        return responseObject.choices[0].message.content.ToString();
                    }
                    else if (response.StatusCode == (System.Net.HttpStatusCode)429) // Too Many Requests
                    {
                        await Task.Delay(delay);
                        delay *= 2;
                    }
                    else
                    {
                        return "Error: " + response.StatusCode + " - " + await response.Content.ReadAsStringAsync();
                    }
                }
                catch (HttpRequestException e)
                {
                    return "Request error: " + e.Message;
                }
                catch (Exception e)
                {
                    return "Unexpected error: " + e.Message;
                }
            }

            return "Failed to get a response after multiple attempts.";
        }
    }
}

결론

이 파트에서는 사용자 상호작용을 개선하여 지속적인 대화를 가능하게 하고, 오류 처리를 추가하며, 요금 한도를 위한 재시도 메커니즘을 구현하고, 대화 컨텍스트를 유지하는 방법을 다루었습니다. 이로써 C# 애플리케이션이 OpenAI ChatGPT API와 더 효과적으로 상호작용할 수 있습니다.

반응형