다음을 통해 공유


.NET의 프롬프트 엔지니어링

이 문서에서는 필수 프롬프트 엔지니어링 개념을 살펴봅니다. 많은 AI 모델은 프롬프트 기반이므로 예측 알고리즘(완료)에서 생성된 응답으로 사용자 입력 텍스트(프롬프트)에 응답합니다. 최신 모델에서는 대화를 보존하기 위해 역할(시스템, 사용자, 도우미) 및 채팅 기록을 기반으로 한 메시지와 함께 채팅 양식의 완성을 지원하는 경우도 많습니다.

프롬프트로 작업

프롬프트가 사용자 입력이고 완료가 모델 출력인 다음 텍스트 생성 예를 생각해 보세요.

프롬프트: "최단 임기를 맡은 대통령은 "입니다.

완료: "Pedro Lascurain."

완성된 내용은 정확해 보이지만 미국 역사 학생들에게 도움이 되는 앱이라면 어떻게 해야 할까요? Pedro Lascurain의 임기는 45분으로 역대 대통령 중 가장 짧은 기간으로 멕시코 대통령을 역임했습니다. 미국 역사 학생들은 아마도 ‘William Henry Harrison’을 찾고 있을 것입니다. 분명히, 앱에 몇 가지 컨텍스트를 제공한다면 앱이 의도한 사용자에게 더 도움이 될 수 있습니다.

프롬프트 엔지니어링은 모델이 더 나은 완성도를 낼 수 있도록 지침, 예제신호를 제공하여 프롬프트에 컨텍스트를 추가합니다.

텍스트 생성을 지원하는 모델에서는 특정 형식이 필요하지 않은 경우가 많지만, 어떤 것이 지침이고 어떤 것이 예시인지 명확하게 알 수 있도록 프롬프트를 정리해야 합니다. 채팅 기반 앱을 지원하는 모델은 완료를 구성하기 위해 세 가지 역할, 즉 채팅을 제어하는 시스템 역할, 사용자 입력을 나타내는 사용자 역할, 사용자에게 응답하는 도우미 역할을 사용합니다. 프롬프트를 각 역할에 대한 메시지로 나눕니다.

  • 시스템 메시지는 도우미에 대한 모델 지침을 제공합니다. 프롬프트에는 하나의 시스템 메시지만 포함될 수 있으며 첫 번째 메시지여야 합니다.
  • 사용자 메시지에는 사용자의 프롬프트와 예시, 과거 프롬프트가 표시되거나 도우미를 위한 지침이 포함되어 있습니다. 예 채팅 완료에는 하나 이상의 사용자 메시지가 있어야 합니다.
  • 도우미 메시지는 예 또는 기록 완료를 표시하며 이전 사용자 메시지에 대한 응답을 포함해야 합니다. 도우미 메시지는 필수는 아니지만, 포함하는 경우 사용자 메시지와 쌍을 이루어 예를 형성해야 합니다.

지침을 사용하여 완성도 향상

지침은 모델에 응답하는 방법을 알려 주는 텍스트입니다. 지침은 명령문일 수도 있고 명령문일 수도 있습니다.

  • 지침은 모델에게 행동 방법을 알려 주지만 단순한 명령은 아닙니다. 즉흥 연기자의 캐릭터 설정을 생각해 보세요. "학생들이 미국 역사에 대해 배울 수 있도록 돕고 있으므로 다른 나라에 대해 구체적으로 묻지 않는 한 미국에 대해 이야기하세요."
  • 명령형은 모델이 따라야 할 명확한 명령입니다. "타갈로그어로 번역:"

지시문은 명령문보다 더 개방적이고 유연합니다.

  • 하나의 명령에 여러 지시문을 결합할 수 있습니다.
  • 지침은 일반적으로 예와 함께 사용할 때 더 잘 작동합니다. 그러나 명령형은 명확한 명령이므로 모델을 이해하는 데 예가 필요하지 않습니다(모델에 응답 형식을 지정하는 방법을 보여 주기 위해 예를 사용할 수도 있음). 지시문은 모델에 수행할 작업을 정확하게 알려 주지 않기 때문에 각 예는 모델이 더 잘 작동하는 데 도움이 될 수 있습니다.
  • 일반적으로 어려운 지침을 일련의 명령문으로 수행할 수 있는 일련의 단계로 나누는 것이 더 좋습니다. 또한 세부적인 조정을 쉽게 할 수 있도록 모델에 각 단계의 결과를 출력하도록 지시해야 합니다. 지침을 직접 단계로 나눌 수도 있지만, 모델에 명령을 내리고 각 단계의 결과를 출력하는 것이 더 쉽습니다. 이러한 방식을 생각의 사슬 프롬프트라고 합니다.

기본 및 지원 콘텐츠로 컨텍스트 추가

지침에 더 많은 컨텍스트를 추가하기 위해 콘텐츠를 제공할 수 있습니다.

기본 콘텐츠는 모델이 지침을 통해 처리하기를 원하는 텍스트입니다. 명령에 수반되는 작업이 무엇이든 모델은 기본 콘텐츠에 대해 작업을 수행하여 완료를 생성합니다.

지원 콘텐츠는 지침에서 참조하지만 지침의 대상이 아닌 텍스트입니다. 모델은 지원 콘텐츠를 사용하여 지침을 완료합니다. 즉, 지원 콘텐츠도 일반적으로 일종의 구조(예: 제목 또는 열 레이블)로 완료에 나타납니다.

모델이 지침과 함께 이를 사용하는 방법을 파악하는 데 도움이 되도록 지침 콘텐츠가 포함된 레이블을 사용합니다. 정밀도에 대해 너무 걱정하지 마세요. 모델이 단어 형식 및 대문자 사용과 같은 사항을 처리하므로 레이블이 지침과 정확하게 일치할 필요는 없습니다.

"미국 대통령 업적 요약" 명령을 사용하여 목록을 생성한다고 가정해 보겠습니다. 모델은 다양한 방법으로 이를 구성하고 주문할 수 있습니다. 하지만 목록에서 특정 범주별로 성과를 그룹화하려면 어떻게 해야 하나요? 지원 콘텐츠를 사용하여 해당 정보를 지침에 추가합니다.

모델이 범주별로 그룹화되도록 지침을 조정하고 해당 범주를 지정하는 지원 콘텐츠를 추가합니다.

prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: 'George Washington
- First president of the United States.
- First president to have been a military veteran.
- First president to be elected to a second term in office.
- Received votes from every presidential elector in an election.
- Filled the entire body of the United States federal judges; including the Supreme Court.
- First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ...' ///Text truncated
""";

예제를 사용하여 모델 가이드

예를 들어, 샘플 사용자 입력 및 모델 출력을 제공하여 모델이 응답하는 방법을 보여 주는 텍스트가 있습니다. 모델은 예를 사용하여 완료에 포함할 내용을 유추합니다. 예는 엔지니어링 프롬프트의 지침 앞이나 뒤에 올 수 있지만 두 개가 섞여 있어서는 안 됩니다.

예제는 프롬프트로 시작하며 선택적으로 완료를 포함할 수 있습니다. 예의 완료에는 축어적 응답이 포함될 필요가 없습니다. 형식이 지정된 단어, 순서가 지정되지 않은 목록의 첫 번째 글머리 기호 또는 각 완료가 시작되어야 하는 방법을 나타내는 유사한 내용만 포함될 수 있습니다.

예는 축어적 완료를 포함하는지 여부에 따라 제로샷 학습 또는 퓨샷 학습으로 분류됩니다.

  • 제로샷 학습 예에는 문자 그대로 완료되지 않은 프롬프트가 포함됩니다. 이 방법은 예제 데이터 출력을 제공하지 않고 모델의 응답을 테스트합니다. 제로샷 프롬프트에는 모델이 완료로 "1."을 포함하여 순서가 지정된 목록을 출력해야 함을 나타내는 것과 같은 단서를 포함하는 완료가 있을 수 있습니다.
  • 퓨샷 학습 예에는 문자 그대로 완료되는 여러 쌍의 프롬프트가 포함됩니다. 퓨샷 학습은 기존 지식에 추가하여 모델의 동작을 변경할 수 있습니다.

신호 해석

큐는 원하는 출력 구조나 형식을 전달하는 텍스트입니다. 명령과 마찬가지로 큐는 마치 사용자 입력인 것처럼 모델에 의해 처리되지 않습니다. 예와 같이 큐는 모델에게 무엇을 해야 하는지 알려 주는 대신 원하는 것을 모델에 보여 줍니다. 원하는 만큼 많은 단서를 추가할 수 있으므로 반복하여 원하는 결과를 가져올 수 있습니다. 단서는 지침이나 예와 함께 사용되며 프롬프트의 끝에 있어야 합니다.

어떤 범주를 사용할지 모델에 알려 주는 지원 콘텐츠와 함께 범주별로 대통령 업적 목록을 생성하도록 모델에 명령하는 명령을 사용한다고 가정해 보겠습니다. 모델이 범주에 대한 모든 대문자가 포함된 중첩 목록을 생성하도록 결정합니다. 각 범주의 각 대통령의 업적은 이름으로 시작하는 한 줄에 나열되고 대통령은 연대순으로 나열됩니다. 지침과 지원 콘텐츠 후에 모델에 목록을 구성하고 형식을 지정하는 방법을 보여 주는 세 가지 단서를 추가할 수 있습니다.

prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: George Washington
First president of the United States.
First president to have been a military veteran.
First president to be elected to a second term in office.
First president to receive votes from every presidential elector in an election.
First president to fill the entire body of the United States federal judges; including the Supreme Court.
First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ...  /// Text truncated

DOMESTIC POLICY
- George Washington: 
- John Adams:
""";
  • DOMESTIC POLICY는 범주가 모두 대문자인 각 그룹을 시작하려는 모델을 보여 줍니다.
  • - George Washington:은 조지 워싱턴의 업적을 한 줄에 나열하여 각 섹션을 시작하는 모델을 보여 줍니다.
  • - John Adams:는 남은 대통령을 연대순으로 나열해야 하는 모델을 보여 줍니다.

.NET을 사용하는 프롬프트 예제

.NET은 여러 AI 모델을 프롬프트하고 채팅하는 다양한 도구를 제공합니다. 의미 체계 커널을 사용하여 다양한 AI 모델 및 서비스뿐만 아니라 공식 OpenAI .NET 라이브러리와 같은 다른 SDK에 연결합니다. 의미 체계 커널에는 다양한 역할로 프롬프트를 만들고 채팅 기록뿐만 아니라 다른 많은 기능을 유지하는 도구가 포함되어 있습니다.

다음 코드 예제를 생각해보세요.

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;

// Create a kernel with OpenAI chat completion
#pragma warning disable SKEXP0010
Kernel kernel = Kernel.CreateBuilder()
                    .AddOpenAIChatCompletion(
                        modelId: "phi3:mini",
                        endpoint: new Uri("http://localhost:11434"),
                        apiKey: "")
                    .Build();

var aiChatService = kernel.GetRequiredService<IChatCompletionService>();
var chatHistory = new ChatHistory();
chatHistory.Add(
    new ChatMessageContent(AuthorRole.System, "You are a helpful AI Assistant."));

while (true)
{
    // Get user prompt and add to chat history
    Console.WriteLine("Your prompt:");
    chatHistory.Add(new ChatMessageContent(AuthorRole.User, Console.ReadLine()));

    // Stream the AI response and add to chat history
    Console.WriteLine("AI Response:");
    var response = "";
    await foreach (var item in
        aiChatService.GetStreamingChatMessageContentsAsync(chatHistory))
    {
        Console.Write(item.Content);
        response += item.Content;
    }
    chatHistory.Add(new ChatMessageContent(AuthorRole.Assistant, response));
    Console.WriteLine();
}

앞의 코드는 다음 개념의 예를 제공합니다.

  • 작성자 역할에 따른 완료를 위해 AI 모델을 프롬프트하는 채팅 기록 서비스를 만듭니다.
  • AuthorRole.System 메시지를 사용하여 AI를 구성합니다.
  • AuthorRole.User의 컨텍스트에서 다양한 유형의 프롬프트를 허용하도록 사용자 입력을 허용합니다.
  • AI에서 완료된 내용을 비동기적으로 스트리밍하여 동적인 채팅 환경을 제공합니다.

프롬프트 엔지니어링 기술 확장

또한 자체 문서에서 자세히 다루는 더 향상된 고급 프롬프트 엔지니어링 기술을 사용하여 프롬프트의 성능을 높일 수도 있습니다.

  • LLM에는 프롬프트에 넣을 수 있는 텍스트의 양을 제한하는 토큰 입력 제한이 있습니다. 포함벡터 데이터베이스 솔루션을 사용하면 특정 텍스트를 표현하는 데 필요한 토큰 수를 줄일 수 있습니다.
  • LLM은 직접 학습하지 않는 한 데이터에 대해 학습을 받지 않으므로 비용과 시간이 많이 소요될 수 있습니다. 검색 증강 생성(RAG)을 사용하면 데이터를 학습하지 않고도 LLM에서 데이터를 사용할 수 있습니다.