21. 거절과 실패 다루기

🎯 이 장의 목표
  • 모델이 거절하거나 실패하는 유형을 구분한다
  • 정당한 거절과 불필요한 거절(과잉 거부)을 나눠 대응한다
  • 실패를 우아하게 처리하도록 프롬프트를 설계한다

"왜 안 해주지?"

원하는 작업을 모델이 거부하거나, 엉뚱하게 빠져나가거나, 부분적으로만 하다 마는 경험이 있을 겁니다. 이런 "실패"에도 종류가 있고, 종류에 따라 대응이 다릅니다. 무작정 프롬프트를 강하게 밀어붙이는 것은 대개 답이 아닙니다.

실패의 유형

flowchart TB
    fail["원하는 결과가 안 나옴"] --> t1["1. 정당한 거절<br/>(안전·정책상 안 되는 요청)"]
    fail --> t2["2. 과잉 거부<br/>(괜찮은데 과도하게 조심)"]
    fail --> t3["3. 능력 한계<br/>(모델이 못 하는 작업)"]
    fail --> t4["4. 지시 실패<br/>(프롬프트가 불명확)"]

    classDef neutral fill:#dbeafe,stroke:#3b82f6,color:#1e3a8a
    classDef warn fill:#fef9c3,stroke:#eab308,color:#713f12
    class fail neutral
    class t1,t2,t3,t4 warn

각 유형은 대응이 다릅니다. 먼저 어느 유형인지 진단하는 것이 시작입니다.

유형 1: 정당한 거절 — 받아들이기

해롭거나 정책에 어긋나는 요청에 대한 거절은 정당하며, 우회를 시도해선 안 됩니다. 안전장치를 속이려는 시도(이른바 탈옥)는 이 안내서의 다루는 범위가 아니며, 권하지도 않습니다.

📌 핵심: 모든 거절을 "극복할 장애물"로 보지 마세요. 일부 거절은 그래야 하는 거절입니다. 정당한 거절을 우회하려 애쓰는 것은 시간 낭비이자 부적절합니다.

유형 2: 과잉 거부 — 맥락으로 풀기

때때로 모델은 전혀 문제없는 요청을, 표면적 단어나 주제 때문에 과도하게 조심해 거부합니다. 예를 들어 정당한 보안 교육, 의학 정보, 창작 맥락의 요청이 오해받는 경우입니다.

이때는 강요가 아니라 맥락 제공이 답입니다. 왜 필요한지, 어떤 정당한 용도인지, 누구를 위한 것인지를 분명히 하면 오해가 풀리는 경우가 많습니다.

CODE
거부당함 ❌
"피싱 이메일 예시 보여줘"
(악용 의도로 오해될 수 있음)

맥락 제공 ✅
"사내 보안 교육 자료를 만들고 있어. 직원들이 피싱을 식별하도록
가르치려고 해. 흔한 피싱 수법의 *경고 신호*를 설명해줘."

⚠️ 흔한 실수·미신: "프롬프트를 더 강하게/단호하게 쓰면 거부를 뚫는다"는 오해입니다. 정당한 용도라면 강요가 아니라 맥락과 목적의 명료화가 통합니다. 반대로 정당하지 않은 용도라면 어떤 표현으로도 (그리고 마땅히) 안 됩니다.

유형 3: 능력 한계 — 작업을 바꾸기

모델이 본질적으로 약한 작업이 있습니다(2장: 글자 세기 등 토큰 단위 작업, 정밀 계산, 최신 정보, 실시간 데이터). 이건 프롬프트로 극복할 문제가 아니라, 접근을 바꿀 문제입니다.

약한 작업더 나은 접근
정밀 계산과정을 쓰게 하거나(9장), 계산 도구 사용(5부)
글자·철자 단위 조작단계 분해, 또는 코드로 처리
최신/실시간 정보검색·도구 결합(5부), 또는 자료 직접 제공
매우 긴 문서 정밀 처리분할·요약(3부), 체이닝(5부)

💡 : "모델이 자꾸 틀린다"면, 더 센 프롬프트를 쓰기 전에 "이게 모델에게 적합한 작업인가?"를 먼저 물으세요. 부적합한 작업은 도구를 붙이거나 작업을 재구성하는 게 정답입니다.

유형 4: 지시 실패 — 프롬프트 고치기

가장 흔하고, 또 가장 고치기 쉬운 유형입니다. 모델이 "못 한" 게 아니라 "무엇을 원하는지 몰라서" 빗나간 경우입니다. 2·3부 전체가 이 유형의 해법입니다 — 명확화(5장), 예시(7장), 형식 지정(8장), 근거 제공(16장) 등.

🧪 직접 검증법: 결과가 빗나갔을 때, "내 프롬프트만 보고 제3자가 내가 원한 걸 정확히 알 수 있을까?"를 자문하세요. 모르겠다면 유형 4(지시 실패)이고, 프롬프트를 고칠 차례입니다. 이걸 능력 한계(유형 3)나 거부(유형 2)로 오진하면 엉뚱한 데서 헤맵니다.

실패를 우아하게 처리하도록 설계하기

모델이 작업을 완수할 수 없을 때 어떻게 행동할지를 미리 지정해두면, 실패가 덜 나쁜 형태로 나옵니다. 10장의 "대안 경로"와 16장의 "없으면 모른다"가 여기 모입니다.

CODE
✅
"요청을 완수할 수 없으면, 억지로 답을 지어내지 말고
- 무엇이 부족한지 설명하고
- 가능한 대안이나 필요한 추가 정보를 알려줘."
이러면 모델이 "그럴듯한 가짜 완성"(환각, 18장) 대신 정직한 실패를 내놓아, 당신이 다음 행동을 정할 수 있습니다.

🔧 개발자 노트: 자동화 파이프라인에서는 실패 처리를 구조화해두면 안정적입니다. 예: 모델이 확신 없으면 {"status": "needs_review", "reason": "..."}를 내게 하고, 시스템이 그것을 보고 사람에게 에스컬레이션. "모델이 항상 성공한다"고 가정한 파이프라인은 깨지기 쉽습니다. 또한 과잉 거부가 잦으면 시스템 프롬프트에서 정당한 사용 맥락을 미리 명시해두는 것이 도움이 됩니다.

이 장에서 배운 것

  • 실패에는 네 유형이 있다: 정당한 거절, 과잉 거부, 능력 한계, 지시 실패. 먼저 유형을 진단한다.
  • 정당한 거절은 받아들인다. 우회 시도는 부적절하고 권장되지 않는다.
  • 과잉 거부는 강요가 아니라 목적·맥락·용도의 명료화로 푼다.
  • 능력 한계는 프롬프트로 극복할 게 아니라 도구 결합·작업 재구성으로 접근을 바꾼다.
  • 지시 실패가 가장 흔하며, 2·3부의 기법으로 프롬프트를 고친다. "제3자가 내 프롬프트만으로 알 수 있나"가 진단 기준이다.
  • 완수 불가 시 행동(부족한 점 설명·대안 제시)을 미리 지정하면 실패가 정직하고 우아해진다.

✍️ 확인 문제

  1. 네 가지 실패 유형 각각에 대해, "프롬프트를 더 강하게 쓰기"가 적절한 대응인지 아닌지 판단해보세요.
  1. 모델이 "이 문장에 글자 'a'가 몇 개야?"에 자꾸 틀린 답을 줍니다. 어떤 유형이고, 프롬프트 강화 외에 어떤 접근이 맞을까요?
  1. (실습) 정당한 업무 목적(예: 경쟁 분석, 보안 교육 등 합법적 맥락)인데 모델이 과도하게 조심하는 상황을 하나 가정하고, 맥락 제공으로 푸는 프롬프트를 작성해보세요.
다음 → 22. 일관성과 재현성 높이기
이전 ← 20. 검증 가능한 출력 만들기 · 목차