2025년 04월 17일
24

프롬프트 엔지니어링의 실전 원리: LLM은 왜 같은 질문에도 다른 답을 내놓을까?

AI
KKingmo

Changmo Oh

@KKingmo

전체 카테고리 보기

이번 글은 공개된 Google Prompt Engineering 백서를 읽고, 핵심 내용을 내 방식대로 다시 정리한 기록이다. 실제로 프롬프트를 설계하고 운영할 때 무엇을 이해해야 하는지에 초점을 맞췄다.

LLM을 실제 서비스나 제품 개발에 적용하다 보면 빠르게 깨닫게 되는 사실이 있다.
모델 성능만으로 결과 품질이 결정되지는 않는다는 점이다. 같은 모델이라도 어떤 입력을 주는지, 어떤 형식을 요구하는지, 어떤 샘플링 설정을 사용하는지에 따라 출력의 정확도와 일관성은 크게 달라진다.
이 차이를 만드는 핵심이 바로 프롬프트 엔지니어링 이다.

프롬프트 엔지니어링은 단순히 질문을 잘 쓰는 방법이 아니다. 더 정확히 말하면, LLM이 수행해야 할 작업을 명확하게 정의하고, 원하는 출력 공간으로 모델의 행동을 유도하는 입력 설계 작업이다.
특히 실무에서는 이 과정을 단순한 문장 작성이 아니라, 모델 제어 인터페이스를 설계하는 일로 보는 편이 더 정확하다.


프롬프트 엔지니어링을 이해하려면 먼저 LLM의 동작 방식을 봐야 한다

LLM은 사람처럼 의미를 이해한 뒤 답변을 생성하는 존재라기보다, 주어진 문맥을 바탕으로 다음 토큰의 확률 분포를 계산하고, 그중 하나를 순차적으로 선택하는 예측 시스템에 가깝다.

즉, 모델은 입력을 보고 다음과 같은 작업을 반복한다.

  1. 현재 문맥에서 다음에 올 수 있는 토큰 후보를 계산한다.
  2. 각 후보의 확률을 산출한다.
  3. 샘플링 규칙에 따라 하나를 선택한다.
  4. 선택된 토큰을 문맥에 추가하고 다시 반복한다.

이 구조 때문에 LLM의 출력은 본질적으로 다음 두 요소의 영향을 강하게 받는다.

  • 입력 문맥의 구성 방식
  • 토큰 선택 규칙의 설정 방식

결국 프롬프트 엔지니어링이란, 모델의 "이해력"을 올리는 작업이 아니라 확률 분포와 출력 경로를 더 유리하게 형성하는 작업이라고 볼 수 있다.


프롬프트만큼 중요한 것: 출력 제어 파라미터

실무에서 프롬프트 품질만 신경 쓰고 샘플링 설정을 가볍게 보면 결과가 쉽게 흔들린다.
모델의 출력은 프롬프트와 설정값이 함께 만든다.

출력 길이(Max Output Tokens)

출력 길이는 응답 생성에 허용되는 최대 토큰 수를 의미한다.
이 값은 응답의 상세도, 비용, 지연 시간에 직접적인 영향을 준다.
다만 중요한 점은, 토큰 제한은 스타일 제어 도구가 아니라 길이 제한 장치라는 것이다.
최대 토큰 수를 줄인다고 해서 자동으로 답변이 더 간결하고 잘 정리되지는 않는다. 모델은 단지 주어진 한도 안에서 생성을 멈출 뿐이다.
따라서 실무에서는 다음처럼 구분해야 한다.

  • 길이 제한: max tokens
  • 표현 방식 제어: 프롬프트 지시문

예를 들어 응답을 짧게 만들고 싶다면 토큰 수만 줄일 것이 아니라, 프롬프트에 직접
"세 문단 이내로 설명하라", "핵심만 bullet 없이 요약하라", "한 문장으로 결론을 먼저 제시하라" 같은 요구를 명시해야 한다.

Temperature

Temperature는 샘플링 분포의 평탄도를 조정하는 값이다.
낮은 온도에서는 확률이 높은 후보가 더욱 강하게 선택되고, 높은 온도에서는 낮은 확률 후보에도 선택 기회가 더 많이 부여된다.

실무적으로 해석하면 다음과 같다.

  • 낮은 Temperature: 예측 가능성, 일관성, 재현성 강화
  • 높은 Temperature: 다양성, 창의성, 탐색성 강화

따라서 다음 같은 용도 구분이 가능하다.

  • 분류, 추출, 구조화된 응답, 규칙 기반 응답: 낮은 온도
  • 브레인스토밍, 카피라이팅, 창작, 대안 제시: 높은 온도

Temperature를 높인다고 무조건 더 "좋은" 답이 나오는 것은 아니다.

대개는 정확성보다 분산이 커지는 것에 가깝다.

Top-K, Top-P

Temperature가 전체 분포의 성향을 바꾼다면, Top-K와 Top-P는 후보 집합 자체를 제한한다.

  • Top-K: 확률 상위 K개 후보만 남긴다
  • Top-P: 누적 확률이 P에 도달할 때까지 후보를 남긴다

Top-K는 고정된 수의 후보를 유지하므로 단순하고 직관적이다.
반면 Top-P는 확률 분포의 모양에 따라 후보 수가 유동적으로 달라지기 때문에, 실제로는 더 적응적인 제어가 가능하다.
일반적으로는 후보군을 Top-K 또는 Top-P로 먼저 줄이고, 그 안에서 Temperature를 적용해 최종 토큰을 샘플링하는 식으로 동작한다.

극단값의 문제: 반복과 붕괴

샘플링 설정이 과도하게 보수적이거나 과도하게 느슨하면 응답 품질이 오히려 악화된다.

  • 너무 낮은 온도/Top-K/Top-P: 반복, 경직된 출력, 표현 다양성 부족
  • 너무 높은 온도: 주제 이탈, 불필요한 확장, 일관성 저하

실제 서비스에서는 종종 동일 문장을 반복하거나, 앞서 말한 내용을 재조합해 계속 늘어놓는 현상이 발생한다.
이 문제는 모델 자체의 한계이기도 하지만, 상당수는 샘플링 설정의 불균형에서 비롯된다.


프롬프팅 기법은 "입력 문장"이 아니라 "작업 구조"의 문제다

프롬프트 엔지니어링을 단순한 문장 작성 요령으로 이해하면 금방 한계에 부딪힌다.
실제 중요한 것은 문장을 예쁘게 쓰는 것이 아니라, 작업을 어떤 구조로 제시할 것인가다.

Zero-shot, One-shot, Few-shot

가장 기본적인 구분은 예시 제공 여부다.

Zero-shot

예시 없이 작업 설명만 제공하는 방식이다.
간단한 질문이나 모델이 이미 충분히 학습했을 가능성이 높은 일반 작업에 적합하다.
장점은 간결하고 빠르다는 점이다.
단점은 출력 형식이나 판단 기준이 모델 내부 추정에 크게 의존한다는 점이다.

One-shot / Few-shot

하나 또는 여러 개의 예시를 함께 제공하는 방식이다.
이 방식은 특히 다음 상황에서 강력하다.

  • 응답 형식이 중요할 때
  • 분류 기준이 애매할 때
  • 모델이 따라야 하는 스타일이 구체적일 때
  • 경계 사례(edge case)를 함께 학습시켜야 할 때

실무적으로는 설명보다 예시가 더 강하다.
모델은 규칙 설명만 읽는 것보다, 실제 입력과 출력의 짝을 보는 편이 훨씬 안정적으로 동작한다.
즉, Few-shot은 단순한 힌트가 아니라 실행 가능한 암묵적 규격(spec) 에 가깝다.


시스템 프롬프트, 역할 프롬프트, 문맥 프롬프트는 서로 다른 계층이다

이 세 가지는 비슷해 보이지만 실제로는 담당하는 역할이 다르다.

시스템 프롬프트(System Prompting)

시스템 프롬프트는 모델이 수행해야 할 최상위 작업 규칙을 정의한다.

예를 들어 다음이 여기에 해당한다.

  • 작업 목표
  • 응답 형식
  • 안전성 제약
  • 우선순위 규칙
  • 금지/허용 범위

즉, 시스템 프롬프트는 모델의 "기본 운영 정책"을 정의하는 계층이다.

역할 프롬프트(Role Prompting)

역할 프롬프트는 모델이 어떤 시점에서 어떤 관점과 톤으로 말해야 하는지를 정한다.
예를 들어 "친절한 고객 지원 상담사", "엄격한 기술 리뷰어", "냉정한 데이터 분석가" 같은 지시가 여기에 해당한다.
이 방식은 단순히 말투를 바꾸는 수준을 넘어, 응답의 초점과 우선순위에도 영향을 준다.
같은 정보라도 어떤 역할을 부여하느냐에 따라 설명 방식과 판단 기준이 달라진다.

문맥 프롬프트(Contextual Prompting)

문맥 프롬프트는 현재 대화나 작업에 필요한 배경 정보를 공급하는 역할을 한다.

예를 들면 다음과 같다.

  • 이전 대화 이력
  • 사용자 프로필
  • 현재 세션 상태
  • 참조 문서 요약
  • 외부 검색 결과

문맥 정보가 빈약하면 모델은 일반론으로 흐르기 쉽고, 문맥 정보가 과다하면 오히려 핵심을 놓치거나 비용이 커질 수 있다.
따라서 문맥 프롬프팅의 핵심은 많이 주는 것이 아니라 관련 있는 정보만 정확히 주는 것이다.

세 계층의 결합

실무에서는 이 세 가지를 분리해서 보기보다 계층 구조로 함께 설계하는 것이 좋다.

  • 시스템 프롬프트: 무엇을 해야 하는가
  • 역할 프롬프트: 어떤 태도로 해야 하는가
  • 문맥 프롬프트: 지금 어떤 상황에서 해야 하는가

이 구조가 잡히면 응답의 일관성과 재현성이 눈에 띄게 올라간다.


복잡한 문제에서는 단순 질문보다 추론 구조가 중요하다

LLM이 항상 단답형 질문에 강한 것은 아니다.
특히 계산, 다단계 판단, 계획 수립, 외부 도구 사용이 포함된 문제에서는 질문보다 추론 절차 설계가 중요해진다.

Step-back Prompting

Step-back은 구체적인 질문에 바로 답하게 하지 않고, 먼저 그 문제의 상위 개념이나 일반 원리를 떠올리게 하는 방식이다.
예를 들어 특정 기능 설계를 묻기 전에
"이 문제와 관련된 일반적인 설계 원칙은 무엇인가?"
를 먼저 생각하게 만드는 식이다.
이 방식은 모델이 세부 구현에 바로 매몰되는 것을 줄이고, 더 넓은 관점에서 답을 구성하게 만든다.
특히 정답보다 접근 방식이 중요한 문제에서 효과적이다.

Chain of Thought(CoT)

Chain of Thought는 문제 해결 과정을 단계별로 드러내도록 유도하는 방식이다.
복잡한 추론 문제에서 정확도를 높이는 대표적인 기법이다.
실무적으로 CoT가 유용한 경우는 다음과 같다.

  • 계산 과정이 필요한 문제
  • 여러 조건을 순차적으로 검토해야 하는 문제
  • 판단 이유를 추적해야 하는 문제
  • 디버깅 가능한 출력을 원할 때

다만 CoT는 비용이 늘고 응답이 길어질 수 있다.
그래서 모든 요청에 일괄 적용하기보다, 실제로 추론이 필요한 구간에만 선택적으로 적용하는 편이 합리적이다.

Self-consistency

Self-consistency는 동일한 문제를 여러 번 다른 추론 경로로 풀게 한 뒤, 가장 일관되게 도출된 결론을 채택하는 방식이다.
이 방식은 CoT의 정확도를 보완할 수 있지만, 실행 비용이 크게 늘어난다.

따라서 실무에서는 다음과 같은 경우에만 제한적으로 쓰는 편이 좋다.

  • 실패 비용이 큰 핵심 로직
  • 간헐적 오답이 치명적인 기능
  • 다수결 기반 안정성이 필요한 판단 문제

즉, Self-consistency는 기본 전략이 아니라 정확도 보강용 비용 집약적 기법에 가깝다.

Tree of Thoughts(ToT)

ToT는 하나의 추론 경로만 따라가는 것이 아니라, 여러 가능한 사고 경로를 트리 구조로 확장하고 평가하는 접근이다.
개념적으로는 강력하지만, 실제 적용은 쉽지 않다.

  • 구현 복잡도 높음
  • 탐색 비용 큼
  • 가지치기 기준 설계 필요
  • 응답 지연 증가

따라서 ToT는 일반적인 서비스 응답보다는, 계획 생성, 전략 탐색, 조합 최적화 같은 고난도 문제에서만 신중하게 검토할 만하다.

ReAct

ReAct는 추론과 행동을 결합하는 방식이다.
즉, 모델이 내부 지식만으로 답하는 것이 아니라, 필요할 때 외부 도구를 사용하고 그 결과를 다시 반영해 다음 행동을 결정한다.

예를 들어 다음과 같은 흐름이다.

  1. 현재 문제를 해석한다
  2. 필요한 외부 정보나 계산을 식별한다
  3. 검색, 계산기, 코드 실행기, API 등을 호출한다
  4. 결과를 관찰한다
  5. 다음 추론과 행동을 이어간다

ReAct는 단순한 프롬프트 기법을 넘어, 에이전트 구조의 핵심 패턴으로 볼 수 있다.
최신 정보, 외부 시스템 연동, 정밀 계산이 필요한 작업에서는 일반적인 단답형 모델 호출보다 훨씬 실용적이다.


좋은 프롬프트의 기준은 "멋진 문장"이 아니라 "운영 가능성"이다

프롬프트 엔지니어링을 잘하는 팀은 보통 프롬프트를 감으로 다루지 않는다.
프롬프트를 실험 가능한 자산으로 관리한다.

예시를 적극적으로 사용한다

가장 강력한 방식 중 하나다.
모델은 요구사항 설명보다 실제 예시를 더 안정적으로 따른다.

지시문은 짧고 명확하게 작성한다

프롬프트가 길다고 정교한 것이 아니다.
불필요한 수식과 중복 설명은 오히려 모델의 주의 분산을 유발한다.

출력 형식을 명시한다

특히 백엔드나 자동화 파이프라인에서는 JSON 같은 구조화된 출력이 매우 유리하다.
이는 후처리 안정성, 파싱 용이성, UI 렌더링 일관성을 동시에 확보해준다.

부정 명령보다 긍정 명령을 우선한다

"이렇게 하지 마라"보다 "이렇게 해라"가 더 효과적인 경우가 많다.
모델은 금지 규칙만으로 행동 공간을 축소하는 것보다, 원하는 출력을 직접 제시받을 때 더 안정적으로 따른다.

변수화와 재사용성을 고려한다

실서비스에 들어가는 프롬프트는 고정 문장이 아니라 템플릿이어야 한다.
사용자 입력, 세션 상태, 검색 결과, 정책 조건 등을 끼워 넣을 수 있어야 한다.

모든 실험을 기록한다

프롬프트, 모델 버전, 온도, 토큰 제한, 출력 결과, 실패 패턴, 개선 히스토리를 기록하지 않으면 프롬프트 개선은 반복 가능성이 없는 감각 노동이 된다.
프롬프트는 코드만큼이나 버전 관리와 회귀 검증이 필요한 운영 대상이다.


AI 서비스 개발 단계에서 프롬프팅 기법은 어떻게 배치해야 하는가

프롬프트 기법은 한 번에 전부 적용하는 것이 아니라, 제품 개발 단계에 맞춰 선택적으로 사용하는 것이 효율적이다.

초기 설계 및 프로토타이핑

이 단계에서는 서비스의 역할, 사용자 경험의 톤, 핵심 기능 가능성을 빠르게 검증해야 한다.
따라서 Role Prompting, 기본적인 Context 설계, Zero-shot/Few-shot, 간단한 CoT 정도가 중심이 된다.

핵심 기능 구현

실제 기능이 동작해야 하는 단계다.
복잡한 판단이나 추론이 포함된다면 CoT가 중요해지고, 외부 데이터 연동이 필요하다면 ReAct 구조가 핵심이 된다.

UX/UI 정교화

이 단계에서는 정확도만큼 톤과 상호작용의 품질이 중요해진다.
Role Prompting과 Contextual Prompting을 미세 조정하며, 응답의 일관성과 개성을 다듬는 작업이 많아진다.

성능 최적화 및 안정성 강화

핵심 기능의 간헐적 오류를 줄이기 위해 Self-consistency 같은 기법을 선별 적용할 수 있다.
또한 ReAct의 도구 선택 로직, 오류 복구 전략, 문맥 주입 방식도 이 시점에서 고도화된다.

운영 및 지속 개선

배포 후에는 실제 사용자 로그를 기반으로 프롬프트를 계속 수정해야 한다.
모델 버전이 바뀌면 기존 프롬프트의 성능도 달라질 수 있으므로, 프롬프트는 한 번 완성해서 끝나는 산출물이 아니라 지속적으로 관리해야 하는 운영 자산이다.


결론

프롬프트 엔지니어링의 핵심은 화려한 문장을 쓰는 데 있지 않다.
본질은 모델이 수행해야 할 작업을 구조화하고, 출력 조건을 제어하며, 원하는 결과를 재현 가능하게 만드는 것에 있다.

정리하면 다음과 같다.

  • 프롬프트는 질문이 아니라 작업 명세다.
  • 샘플링 설정은 품질에 직접 영향을 주는 제어 장치다.
  • 예시 제공은 모델 행동을 가장 강하게 유도하는 수단 중 하나다.
  • 시스템, 역할, 문맥 프롬프트는 서로 다른 계층에서 함께 설계되어야 한다.
  • 복잡한 문제에서는 단순 질의보다 추론 구조 설계가 더 중요하다.
  • 프롬프트는 감각이 아니라 실험, 기록, 개선의 대상이다.

결국 프롬프트 엔지니어링은 LLM을 "더 똑똑하게 만드는 기술"이라기보다, 이미 존재하는 모델 능력을 더 안정적으로 끌어내는 인터페이스 설계 기술에 가깝다.
그리고 AI 서비스를 만드는 입장에서는, 이 차이가 곧 제품 품질의 차이로 이어진다.

참고한 문서

Google Prompt Engineering 백서