할루시네이션 - LLM이 거짓말하는 이유와 줄이는 법
LLM에게 존재하지 않는 API 함수를 자신 있게 알려주거나, 없는 논문을 그럴듯한 제목과 저자까지 붙여 인용하는 경험, 다들 한 번쯤 있으실 겁니다. 이렇게 모델이 사실이 아닌 내용을 사실처럼 생성하는 현상을 할루시네이션(hallucination, 환각)이라고 부릅니다.
이 글에서는 할루시네이션이 왜 발생하는지 그 원리부터, 실무에서 줄이는 방법, 그리고 "완전히 없앨 수는 없다"는 현실까지 정리합니다.
1. 할루시네이션은 버그가 아니라 부작용
먼저 오해를 풀어야 합니다. 할루시네이션은 모델이 고장 나서 생기는 게 아닙니다. LLM이 작동하는 방식 그 자체의 부작용입니다.
LLM은 본질적으로 "다음에 올 가장 그럴듯한 토큰"을 확률적으로 고르는 기계입니다. 사실인지 여부를 판단하는 별도 장치가 있는 게 아니라, 학습 데이터에서 통계적으로 자연스러운 단어의 흐름을 이어붙입니다.
비유하자면, 시험에서 모르는 문제를 만난 학생이 빈칸으로 두지 않고 가장 그럴듯한 답을 적어내는 것과 같습니다. 모델에게는 "모른다"보다 "문장을 매끄럽게 잇는다"가 더 자연스러운 기본 동작입니다.
2. 왜 "모른다"고 안 하고 지어내는가
핵심은 모델에게 자신이 무엇을 모르는지 아는 능력(메타인지)이 약하다는 점입니다.
- 모델은 확신의 정도를 잘 표현하지 못합니다. 정확히 아는 것과 어렴풋이 짜맞춘 것을 똑같이 유창한 문장으로 내놓습니다.
- 학습 데이터가 "정답을 자신 있게 말하는" 텍스트로 가득합니다. 그래서 모르는 영역에서도 그 말투를 흉내 냅니다.
- 좁은 지식이나 최신 정보는 학습에 거의 없거나 잘려 있어, 빈 곳을 그럴듯하게 보간(interpolate) 해버립니다.
즉 유창함과 정확함은 별개인데, 모델의 출력은 둘 다 똑같이 유창하기 때문에 우리가 구분하기 어려운 것입니다.
3. 할루시네이션의 유형
원인을 나눠 보면 대응책도 달라집니다.
| 유형 | 설명 | 예시 |
|---|---|---|
| 사실 조작 | 없는 사실을 지어냄 | 존재하지 않는 함수·논문·수치 |
| 출처 조작 | 근거를 그럴듯하게 위조 | 가짜 URL, 가짜 인용 |
| 맥락 무시 | 준 자료를 벗어나 답함 | 문서에 없는 내용을 덧붙임 |
| 지시 왜곡 | 질문을 잘못 해석해 엉뚱하게 답 | 조건을 무시하거나 뒤바꿈 |
| 논리 비약 | 계산·추론 중간이 틀림 | 그럴듯하지만 틀린 산수 |
특히 실무에서 위험한 것은 출처 조작입니다. 링크와 인용까지 붙어 있어 신뢰를 유도하지만, 눌러보면 존재하지 않는 경우가 많습니다.
4. 완화책 - 발생 확률을 낮추는 장치들
원리상 완전히 막을 순 없지만, 확률을 크게 낮추는 방법들은 명확합니다.
4-1. 근거를 주입한다 (RAG)
가장 효과적인 방법입니다. 모델이 기억에서 짜내게 하지 말고, 관련 문서를 찾아 프롬프트에 넣고 "이 안에서만 답하라" 고 지시합니다.
아래 [문서]의 내용만 근거로 답하세요. 문서에 근거가 없으면 반드시 "제공된 자료에서 찾을 수 없습니다"라고 답하세요. 추측하지 마세요. [문서] {검색된 청크들} [질문] {사용자 질문}
이때 "없으면 모른다고 하라"는 명시적 탈출구를 주는 것이 핵심입니다. 이 한 문장이 지어내기를 크게 줄입니다.
4-2. 근거·인용을 요구한다
답변에 어떤 문서의 어느 부분을 근거로 했는지 함께 출력하게 합니다. 근거를 대야 하면 모델은 아무 말이나 만들기 어려워지고, 사람이 검증하기도 쉬워집니다.
4-3. temperature를 낮춘다
temperature는 출력의 무작위성을 조절하는 값입니다. 사실 기반 응답에는 0에 가깝게 두어, 덜 그럴듯한(=더 창의적인) 토큰이 선택될 여지를 줄입니다.
const res = await llm.chat({ messages, temperature: 0, // 사실성이 중요한 작업은 낮게 });
창작·브레인스토밍이라면 높은 temperature가 오히려 좋습니다. 작업 성격에 맞춰 조절하세요.
4-4. 검증 단계를 붙인다
생성 결과를 곧바로 신뢰하지 말고 한 번 더 확인합니다.
- 링크·수치·코드처럼 검증 가능한 것은 프로그램으로 확인합니다 (URL이 200인지, 코드가 컴파일되는지).
- 중요한 답은 "이 답이 주어진 근거로 뒷받침되는가"를 모델에게 다시 물어(self-check) 교차 검증합니다.
- 함수 호출/도구를 붙여, 모델이 실제 데이터베이스나 API에서 값을 가져오게 합니다.
4-5. 프롬프트로 겸손을 유도한다
"확실하지 않으면 불확실하다고 말하라", "모르면 모른다고 하라"는 지시를 시스템 프롬프트에 넣습니다. 만능은 아니지만, 다른 방법과 겹쳐 쓰면 효과가 있습니다.
5. 완전 제거는 불가능하다 - 현실 받아들이기
여러 방법을 겹겹이 쌓아도 할루시네이션을 0으로 만들 수는 없습니다. 확률적 생성이라는 근본 구조가 그대로이기 때문입니다.
그래서 실무의 목표는 "제거"가 아니라 "위험 관리" 여야 합니다.
- 실패를 전제로 설계한다. 틀릴 수 있다고 가정하고, 틀렸을 때의 피해를 줄이는 구조를 짭니다.
- 위험도에 따라 사람을 개입시킨다. 의료·법률·금융처럼 대가가 큰 도메인은 사람의 최종 확인(human-in-the-loop) 을 반드시 둡니다.
- 사용자에게 한계를 알린다. "AI가 생성한 답변이며 부정확할 수 있습니다"라는 안내와 출처 링크를 함께 제공해 스스로 검증하게 합니다.
마무리
할루시네이션은 LLM의 결함이 아니라 특성입니다. "다음 토큰을 그럴듯하게 잇는다"는 작동 원리에서 필연적으로 따라 나옵니다.
그래서 대응의 핵심은 이렇게 정리됩니다.
- 근거를 주입한다 (RAG) — 기억이 아니라 문서에서 답하게.
- 모른다고 말할 여지를 준다 — 지어내기의 탈출구.
- temperature를 낮추고 검증을 붙인다 — 확률과 사후 확인으로 조인다.
- 완전 제거는 포기하고, 위험을 관리한다 — 사람 개입과 출처 제공.
"AI가 틀리지 않게 만들기"는 불가능합니다. 하지만 "틀려도 안전한 시스템 만들기" 는 충분히 가능합니다.
