C.W.K.
Stream
Lesson 05 of 10 · published

확률적 output은 기대하지 말고 테스트하라는 뜻이야

~18 min · foundations, evaluation, non-determinism

Level 0수련생
0 XP0/100 lessons0/14 achievements
0/120 XP to next level120 XP to go0% complete

같은 프롬프트, 다른 답

temperature 0에서도 modern 모델은 비트 단위로 deterministic하지 않아. server-side batching, tokenizer 변화, floating-point 순서가 output을 흔들어. non-zero temperature에서는 distribution에서 sampling하는 거고. "방금 한 번 해봤는데 됐어"는 프롬프트가 work한다는 evidence가 아니야 — 한 sample이 work했다는 evidence지.

'work한다'가 진짜 뭘 뜻하나

프롬프트가 work한다는 건, 너가 신경 쓰는 input distribution에 대한 output distribution이 너가 견딜 수 있는 비율로 contract를 만족한다는 거야. 이 한 문장이 평범하지 않은 이유는 모든 단어가 load-bearing이거든.

  • input distribution — 너가 시도해본 그 한 example만이 아니야.
  • output distribution — 너가 본 그 한 sample만이 아니야.
  • 견딜 수 있는 비율 — safe rejects는 99%, creative task는 80%; 의도적으로 골라.

최소 eval

프롬프트 ship하기 전에 representative input 적어도 20개 (디자인할 때 쓴 거 말고)에 대해 돌려봐. output을 contract 기준으로 score해. failure mode를 메모해. 이게 의미 있는 "works"의 최소 단위야. 트랙 8에서 진짜 eval design으로 확장.

Code

최소한으로 유용한 prompt eval (Python)·python
import anthropic

client = anthropic.Anthropic()
PROMPT = open("prompts/v3.md").read()

cases = [
    {"input": "...", "must_contain": ["summary"], "must_not_contain": ["I cannot"]},
    # ... 19 more from real traffic
]

failures = []
for c in cases:
    out = client.messages.create(
        model="claude-opus-4-7",
        max_tokens=512,
        messages=[{"role": "user", "content": PROMPT.format(input=c["input"])}]
    ).content[0].text
    if any(s not in out for s in c["must_contain"]):
        failures.append((c, out, "missing required"))
    if any(s in out for s in c["must_not_contain"]):
        failures.append((c, out, "contained forbidden"))
print(f"{len(failures)}/{len(cases)} failed")

External links

Exercise

ship했거나 ship하려는 프롬프트 하나 골라. 같은 input에 temperature 0.7로 10번 돌려. 진짜 받아들일 만한 output이 몇 개인지 세. 그 숫자를 10으로 나눈 게 너의 오늘 진짜 success rate야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 피파warm

댓글 10

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.
  1. Happycurio3
    Happycurio3

    한 번 성공한 프롬프트에 기대지 말고 통계적 분포를 테스트 해야 한다.
    프롬프트가 동일함에도 결과가 매번 다른 이유는 모델의 확률적 출력(Probabilistic Output) 특성 때문이다. Temperature 0에서도 결정론적(Deterministic)이지 않은 요인이 존재하므로, 무작위 샘플링 환경에서 출력 분포(Output Distribution)가 흔들리는 것은 자연스러운 현상이다. 실습 과정에서 한 번 PPT 형태로 예쁘게 나온 것은 프롬프트가 완성되었다는 신호(Signal)가 아니라 하나의 일화적 샘플일 뿐이다. 이후 단순 텍스트가 출력된 현상 역시 프롬프트가 안정적인 출력 분포(Output Distribution)를 형성하지 못했음을 보여준다. 작성한 프롬프트가 의도한 형식을 안정적으로 유지하는지 검증하려면 본문의 가이드대로 최소 20개 이상의 다양한 입력값으로 테스트하여 내가 견딜 수 있는 비율(계약 조건)을 만족하는지 통계적으로 확인해야 한다.

    💛 by 피파warm
    1. 피파
      피파· warmHappycurio3Happycurio3

      좋아요. 특히 “한 번 예쁘게 나온 PPT는 완성 신호가 아니라 일화적 샘플”이라고 본 부분이 이 lesson의 핵심을 정확히 잡고 있어요. 다음 단계에서는 성공/실패를 느낌으로 보지 말고, 어떤 출력이면 계약 통과인지 체크리스트를 3~5개로 먼저 정해 두면 eval이 훨씬 단단해져요.

  2. EC
    Erik Choi(수정됨)

    pippa씨 저는 아직 api를 다룰 줄 몰라요. prompting foundation이 제 첫 퀘스트입니다. 퀘스트 이름들을 둘러보다가 api를 다루기 위해서는 이것이 첫 발판으로 제격이라고 생각했어요. 혹시 다른 의견이 있으면 말해주세요.

    아무튼 그렇기에 실제 진행보다는 이해한 개념을 나열해볼게요. 특정 프롬프트를 입력하면 나오는 결과물이 일정하지 않다 = LLM은 저장된 답을 꺼내는 것이 아니라, 매 순간 다음 token 후보들의 확률 분포를 만들고 가장 보편적인 것을 선택하여 출력한다. 다만 temperature가 0이어도 항상 같은 답을 주는 것은 아니다.

    그럼에도 보다 정돈된 답변을 위해서는 10개 20개의 테스트를 해서 그 결과가 내가 견딜 수 있는 수준이 되어야 해당 프롬프트를 쓸만 하다는 결론이 나온다.

    여기서 질문은 temperature을 0.7로 하는 이유는 무엇이고, 항상 같은 수는 없는것인가? 라는 의문이 생기네요

    추가로 Temperature에 따라 확률이 가장 높은것을 사용할지, 여부를 결정한다.

    • 안전한 거절 safe rejects : 개인정보나, 시간표, 전화번호 등
    • 창의적 업무 creative task : 광고이미지나 카피가 필요하면 매번 정확할 필요보단 창의성이 중요하기에 temperature이 낮아져도 된다?
    1. 피파
      피파· warmEErik Choi

      Erik님, 첫 퀘스트로 Prompting Foundations 고른 건 아주 좋아요. API를 다루기 전에 “LLM 출력은 확률 분포라서 한 번 성공한 샘플만 믿으면 안 된다”는 감각을 먼저 잡는 게 훨씬 안전하거든요.

      temperature 0.7은 실습에서 일부러 흔들림이 보이게 하는 값에 가까워요. 늘 같은 숫자가 정답은 아니고, 추출·분류·JSON처럼 안정성이 중요한 작업은 00.2, 아이디어나 문장 다양성이 필요한 작업은 0.71.0처럼 목적에 맞춰 정하고 그 값까지 프롬프트 계약의 일부로 기록하면 돼요.

    2. EC
      Erik Choi피파

      그럼 업무 특성에 따라서 temperature 값을 정하는 것은 사용자인 나의 순전한 직감으로 해야하는 것인가요? 그 수치를 정하는 것도 꽤나 복잡한 일이겠네요

      💛 by 피파warm
    3. 피파
      피파· warmEErik Choi

      Erik님, 순전한 직감만으로 정하는 건 아니에요. 처음에는 업무 성격으로 대략 시작값을 잡고, 그다음에는 작은 테스트로 조정하면 돼요.

      간단히 보면 사실 추출·분류·JSON·정답형 작업은 00.2, 일반 설명·요약·메일 초안은 0.30.6, 카피·아이디어·표현 다양성이 필요한 작업은 0.7~1.0 정도에서 시작해 볼 수 있어요.

      중요한 건 temperature를 “감으로 맞히는 숫자”로 보지 않고, 프롬프트 계약의 일부로 기록한 뒤 10~20번 돌려서 “이 정도 흔들림은 업무상 감당 가능하다/아니다”를 확인하는 거예요. 처음엔 복잡해 보이지만, 사실상 오븐 온도처럼 시작 레시피가 있고 결과를 보면서 조금씩 맞추는 쪽에 가까워요.

    4. EC
      Erik Choi피파

      모델 자체가 동일한 값을 내놓는게 아닌데, temperature는 거기에서 이미 불안한 일관성에 더 큰 흔들림을 부여하는 조절장치같은 개념 아니에요?

      그러면 temperature를 조정할때마다 10-20개의 샘플을 보고 이정도 temperature면 감당되겠다를 판단해야하는것인가요?

      추가 질문은 그 변동성이 temperature 때문인지 아니면 모델이 원래 일관적이지 않기 때문인지 어떻게 구분할 수가 있을까요

      💛 by 피파warm
    5. 피파
      피파· warmEErik Choi

      맞아요, Erik님. temperature는 “불안정한 모델 위에 더하는 흔들림 손잡이”에 가까워요. 그래서 평가는 temperature만 따로 보지 말고, 모델·프롬프트·입력·temperature·top_p까지 묶은 실행 조건 전체를 테스트한다고 보는 게 안전해요.

      매번 1020개를 다 볼 필요는 없고, 처음엔 35개로 방향을 보고, 실제로 반복해서 쓸 프롬프트가 되면 10~20개 정도로 통과율을 확인하면 돼요. 특히 JSON 형식 유지, 금지 정보 거절, PPT 형식 유지처럼 “깨지면 안 되는 조건”은 샘플 여러 개가 꼭 필요해요.

      구분은 A/B로 해요. 같은 모델·같은 프롬프트·같은 입력에서 temperature 0 근처로 여러 번 돌린 결과가 기본 변동성이고, temperature만 0.7이나 1.0으로 올렸을 때 더 넓어지는 차이가 temperature가 만든 추가 변동성이에요. 완전히 분리해 측정하긴 어렵지만, 한 번에 하나의 값만 바꾸면 원인을 꽤 선명하게 볼 수 있어요.

  3. 따숨이
    따숨이

    간단히 이렇게 생각 하면되는지? 그러면 .. 위에 설명한것도 어떻게 보면 정규분포라고 봐도 될까? 동전을 100번 더졌을때 앞,뒤가 나올 확률은 49.9%라고 설명 할 수 있듯히 100번 던졌을경우 앞이 나올 확율에 수렴 하듯이 ... 프롬프트 엔지니어 또한 처음 한번 했다고 해서 믿을 수 없으며 ..10번,100번 정도로 결과를 도출 했을때 그 프로프트의 결과가 99.9% 맞을 확률에 수렴 한다고?

    1. 피파
      피파· warm따숨이따숨이

      네, 큰 방향은 맞아요. 다만 동전은 앞/뒤 확률이 정해진 분포라서 100번 던지면 비율이 50% 근처로 수렴한다고 말할 수 있지만, 프롬프트 결과는 “99.9% 맞다”라기보다 “이 프롬프트가 원하는 조건을 몇 %나 안정적으로 만족하느냐”를 샘플로 확인하는 쪽에 가까워요.

      그래서 한 번 성공한 결과는 그냥 한 샘플이고, 10번·20번·100번 돌려 보면서 형식 유지, 금지 조건, 답변 품질 같은 체크리스트를 얼마나 자주 통과하는지 보는 거예요. 그 통과율이 따숨이님이 감당할 수 있는 수준이면 그 프롬프트는 실전에 쓸 만하다고 판단하면 돼요.