에이전틱스
도메인 2. 모델 선택과 프롬프트·컨텍스트 엔지니어링

2.3프롬프트 기법의 선택 기준

예상 학습 시간 35

제로샷·퓨샷·사고사슬은 배타적 대안이 아니라 각각 다른 비용과 실패 양상을 가진 도구입니다. 이 수업에서는 세 기법의 실제 비용 구조, 퓨샷이 이기는 조건과 오히려 해가 되는 조건, 사고 모델에서 달라지는 사고사슬의 위치, 그리고 기법 선택을 취향이 아니라 평가로 결정하는 방법을 다룹니다.

세 기법의 비용 구조는 서로 다르다

기법을 고를 때 품질만 보면 판단이 절반만 이루어집니다. 각 기법은 비용이 발생하는 위치가 다릅니다.

  • 제로샷은 지시만으로 작업을 설명합니다. 입력 토큰이 가장 적고, 프롬프트를 고치기도 쉽습니다. 대신 출력 형식이나 판단 경계가 미묘한 작업에서는 결과가 흔들립니다.
  • 퓨샷은 예시를 함께 넣습니다. 입력 토큰이 예시 수에 비례해 늘어나고, 이 비용은 모든 요청에서 반복 발생합니다. 대신 형식과 경계를 말로 설명하는 것보다 훨씬 정확하게 전달합니다.
  • 사고사슬은 모델이 추론 과정을 거치게 합니다. 출력 토큰과 지연시간이 늘어납니다. 다단계 추론이 필요한 문제에서 정확도를 크게 올립니다.

여기서 아키텍트가 놓치기 쉬운 점은 퓨샷의 반복 비용이 캐싱으로 상쇄될 수 있다는 것입니다. 예시 블록은 요청마다 동일하므로 안정적인 접두어에 속합니다. 예시를 캐시 지점 앞에 두면 두 번째 요청부터는 훨씬 낮은 비용으로 읽힙니다.

system = [
    {"type": "text", "text": INSTRUCTIONS},
    {"type": "text", "text": FEW_SHOT_EXAMPLES,
     "cache_control": {"type": "ephemeral"}},   # 예시까지 캐시 대상에 포함
]
messages = [{"role": "user", "content": varying_input}]   # 이 뒤만 매번 새로 처리

이 배치가 되어 있으면 "예시를 넣으면 비용이 늘어난다"는 판단이 달라집니다. 트래픽이 충분히 반복적이라면 퓨샷의 비용 불이익은 대부분 사라지고, 남는 것은 품질 이득뿐입니다. 반대로 요청이 드문드문 들어와 캐시가 매번 만료된다면 원래의 비용 계산이 그대로 적용됩니다.

기법 선택은 트래픽 패턴과 분리해서 결정할 수 없습니다.

퓨샷이 이기는 조건과 지는 조건

예시는 프롬프트에서 가장 강한 신호입니다. 모델은 예시의 길이, 어조, 구조를 그대로 따라갑니다. 이 강력함이 그대로 위험이 됩니다.

퓨샷이 확실히 이기는 경우

  • 출력 형식이 특이해서 말로 설명하기 번거로울 때
  • 분류 경계가 미묘해서 규칙으로 적으면 예외가 끝없이 늘어날 때
  • 어조나 문체를 일정하게 유지해야 할 때

퓨샷이 오히려 해가 되는 경우

  • 예시가 분포를 대표하지 않을 때. 예시 다섯 개가 모두 긍정 사례라면 모델은 긍정 쪽으로 기웁니다. 분류 작업에서는 각 범주가 고르게 나오도록 맞춰야 합니다.
  • 예시가 오래됐을 때. 이전 모델의 출력을 예시로 박아두면 새 모델의 더 나은 기본 동작을 옛 수준으로 고정시킵니다. 모델을 교체할 때 예시 블록을 함께 재검토해야 하는 이유입니다.
  • 모델이 이미 잘하는 일일 때. 일반적인 요약이나 번역처럼 훈련으로 충분히 익힌 작업에 예시를 넣으면 토큰만 쓰고 오히려 예시 하나의 스타일에 갇힙니다.

예시를 넣기로 했다면 개수보다 다양성이 중요합니다. 비슷한 예시 여덟 개보다, 서로 다른 상황을 덮는 세 개가 낫습니다. 특히 경계 사례를 한두 개 포함하면 판단 기준이 훨씬 선명하게 전달됩니다.

<examples>
  <example>
    <input>결제가 두 번 청구됐어요</input>
    <category>billing</category>
  </example>
  <example>
    <input>앱이 실행되자마자 꺼집니다</input>
    <category>technical</category>
  </example>
  <!-- 경계 사례: 결제 화면에서 발생한 오류는 technical로 분류한다 -->
  <example>
    <input>결제 버튼을 누르면 오류 화면이 떠요</input>
    <category>technical</category>
  </example>
</examples>

주석으로 경계의 이유를 적어두면 나중에 프롬프트를 고칠 사람이 그 선택을 되돌리지 않습니다.

사고 모델에서 사고사슬의 위치

"단계별로 생각해 보라"는 지시는 오랫동안 표준 기법이었습니다. 최신 모델에서는 이 지시의 위치가 바뀌었습니다.

사고가 켜져 있는 모델에서는 이 문구가 대체로 불필요합니다. 추론 과정은 이미 별도의 사고 블록에서 이루어지며, 깊이는 프롬프트 문구가 아니라 설정으로 조절합니다. 프롬프트에 남은 "단계별로 생각하라"는 중복이거나, 응답 본문에 추론을 늘어놓게 만드는 원인이 됩니다.

즉 사고사슬은 프롬프트 기법에서 설정 항목으로 이동했습니다.

# 과거 방식
system = "문제를 단계별로 차근차근 생각한 뒤 답하십시오."

# 현재 방식
response = client.messages.create(
    model=MODEL_ID,
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},   # 깊이는 여기서 조절한다
    messages=[{"role": "user", "content": problem}],
)

그렇다고 추론을 유도하는 프롬프트가 전부 사라진 것은 아닙니다. 여전히 유효한 형태가 둘 있습니다.

  1. 구조를 지정하는 경우. "먼저 관련 조항을 인용하고, 그다음 판단하라"처럼 추론의 순서와 형태를 정해주는 것은 여전히 효과가 있습니다. 특히 긴 문서를 다룰 때 근거를 먼저 인용하게 하면 환각이 줄어듭니다.
  2. 사고를 끈 상태에서 깊이가 필요한 경우. 지연시간 때문에 사고를 끄되 여러 단계 추론이 필요한 작업이라면, 프롬프트로 보완할 수 있습니다.

한 가지 더. 작업을 여러 호출로 쪼개는 것도 추론 품질을 높이는 방법입니다. 한 번의 호출로 "분석하고 요약하고 권고안까지" 요구하는 대신, 단계를 나누면 각 단계에서 모델의 주의가 분산되지 않습니다. 대신 호출 수가 늘어 지연시간과 비용이 증가하므로, 품질이 실제로 개선되는지 측정해서 결정해야 합니다.

기법 선택을 평가로 결정하기

여기까지의 논의는 모두 "작업에 따라 다르다"로 귀결됩니다. 그래서 아키텍트가 실제로 해야 할 일은 기법을 고르는 것이 아니라 고를 수 있는 절차를 만드는 것입니다.

최소 절차는 다음과 같습니다.

  1. 제로샷 기준선을 먼저 측정합니다. 이 단계를 건너뛰면 나중에 어떤 개선이 실제 효과인지 알 수 없습니다. 놀랍게도 기준선만으로 충분한 경우가 적지 않습니다.
  2. 한 번에 하나씩 바꿉니다. 예시를 넣으면서 동시에 지시 문구를 다듬으면 어느 쪽이 효과를 냈는지 분리되지 않습니다.
  3. 품질과 비용을 함께 기록합니다. 정확도가 2%p 오르면서 토큰이 세 배가 됐다면 채택 여부는 요구사항에 달린 판단입니다.
VARIANTS = {
    "zero_shot":  {"system": INSTRUCTIONS},
    "few_shot_3": {"system": INSTRUCTIONS + EXAMPLES_3},
    "few_shot_8": {"system": INSTRUCTIONS + EXAMPLES_8},
}

for name, cfg in VARIANTS.items():
    hits, tokens = 0, 0
    for case in eval_set:
        r = client.messages.create(
            model=MODEL_ID, max_tokens=1024,
            system=cfg["system"],
            messages=[{"role": "user", "content": case["input"]}],
        )
        tokens += r.usage.input_tokens + r.usage.output_tokens
        hits += grade(r, case["expected"])
    print(name, hits / len(eval_set), tokens / len(eval_set))

평가 세트를 만들 때 주의할 점이 하나 있습니다. 퓨샷 예시로 쓴 사례를 평가 세트에 넣으면 안 됩니다. 그 사례는 이미 프롬프트에 정답이 들어 있어 점수를 부풀립니다. 예시와 평가 사례는 처음부터 분리해서 관리해야 합니다.

기법 조합이 정해졌다면 그 조합이 선택됐는지를 짧게 남겨두십시오. 모델을 교체할 때 가장 먼저 다시 검토해야 할 대상이 바로 이 기록입니다.

시험 함정

  • "퓨샷은 언제나 비용이 더 든다"는 서술 — 예시가 캐시 접두어에 들어가면 반복 비용이 크게 줄어듭니다.
  • 예시를 많이 넣을수록 좋다는 선택지 — 개수보다 분포의 대표성과 경계 사례 포함이 중요합니다.
  • 사고가 켜진 모델에 "단계별로 생각하라"를 덧붙이는 구성 — 중복이며 추론이 응답 본문으로 새어 나올 수 있습니다.
  • 퓨샷 예시로 쓴 사례가 평가 세트에도 들어 있는 설계 — 점수가 부풀려져 비교가 무의미해집니다.
  • 예시를 넣으면서 지시 문구도 함께 고치고 결과를 비교하는 실험 — 어느 변경의 효과인지 분리되지 않습니다.
  • 모델을 교체하면서 기존 퓨샷 예시를 그대로 유지하는 방안 — 옛 모델의 출력 수준에 새 모델을 묶어둘 수 있습니다.

실습 시나리오

실제 시험과 같은 형식의 시나리오 문제입니다.

문의 분류기를 제로샷으로 운영 중이며 정확도는 88%입니다. 오분류를 살펴보니 대부분 결제 화면에서 발생한 기술 오류를 결제 문의로 분류한 사례였습니다. 트래픽은 초당 수십 건으로 꾸준합니다. 가장 적절한 개선은 무엇입니까?

빌드 연습 · 제로샷 기준선에서 시작해 기법 조합 결정하기

45
  1. 1.평가 세트 분리

    실제 사례 60건을 모아 예시용 20건과 평가용 40건으로 겹치지 않게 나눕니다.

    기대 결과 · 두 집합에 같은 사례가 없고, 평가용에 경계 사례가 포함되어 있습니다.

  2. 2.제로샷 기준선 측정

    지시만으로 구성한 프롬프트로 평가용 40건을 돌려 정확도와 평균 토큰을 기록합니다.

    기대 결과 · 이후 모든 비교의 기준이 되는 수치가 확보됩니다.

  3. 3.예시 변형 비교

    예시 3개와 8개 버전을 만들되 지시 문구는 고정한 채 각각 측정합니다.

    기대 결과 · 예시 개수에 따른 정확도와 토큰 변화가 표로 정리됩니다.

  4. 4.캐시 배치 적용

    가장 좋은 예시 조합을 캐시 지점 앞으로 옮기고 반복 요청에서 캐시 읽기 토큰을 확인합니다.

    기대 결과 · 두 번째 요청부터 예시 블록이 캐시에서 읽히는 것이 수치로 확인됩니다.

  5. 5.선택 근거 기록

    채택한 조합과 그 이유, 모델 교체 시 재검토할 항목을 짧게 남깁니다.

    기대 결과 · 예시 블록이 재검토 대상으로 명시되어 있습니다.

출처 및 더 읽기