환각(Hallucination)을 일으키지 않는 지구상 최초의 LLM
요약
본 글은 LLM이 코드를 생성할 때 발생하는 '환각' 문제를 아키텍처 차원에서 해결하는 방법을 제시합니다. 기존의 자유 형식 언어 대신, 실행 트리를 구성하고 모든 노드가 유한하게 정의된 슬롯(slot) 호출로 이루어진 Hyperlambda라는 폐쇄 어휘력 언어를 사용합니다. 이를 통해 모델이 지어낸 기능은 런타임에 정적으로 검증되어 거짓말임을 즉시 감지할 수 있습니다.
핵심 포인트
- 자유 형식 코드는 환각된 함수를 구별하기 어렵다.
- Hyperlambda는 실행 트리를 구성하며, 모든 노드가 유한한 슬롯 호출이다.
- verify-slots 기능을 통해 생성된 모든 명령어를 레지스트리와 정적으로 비교 검증한다.
네, 헤드라인은 미끼입니다. 아니요, 거짓말은 아닙니다.
전 세계 모든 AI 벤더들은 자신들의 모델이 '환각을 줄인다'고 주장합니다. 감소(Reduction)는 백분율 문제입니다. _불가능하다(Cannot)_는 아키텍처 문제입니다. 이 글은 그 아키텍처에 관한 것입니다.
모델이 코드를 작성할 때 환각이란 무엇인가
LLM이 Python이나 JavaScript를 작성할 때, 존재하지 않는 API 호출이라도 구문적으로 완벽합니다. pandas.read_excel_fast(), express.validateJWT()와 같이 한 번도 존재한 적 없는 패키지라 할지라도 — 모델은 이를 완전한 확신을 가지고 생성하며, 언어는 기꺼이 이를 받아들입니다. 코드는 컴파일됩니다. 훑어보기 수준의 검토를 통과합니다. 하지만 최악의 순간에 실패합니다: 실제 데이터가 적용되는 런타임(runtime), 프로덕션 환경에서 말이죠.
이는 자유 형식 코드 생성의 더러운 비밀입니다: 일반 목적 언어는 무한한 어휘력을 가지고 있기 때문입니다. 모델이 꾸며내는 이름은 문법적으로 유효한 코드이며, 실행되기 전까지는 실제 것과 구별할 수 없습니다.
업계의 답변은 무엇일까요? 모든 것을 검토하고, 아무것도 믿지 않는 것입니다. 생성된 모든 라인은 프로덕션에 들어가기 전에 인간의 승인을 거치게 되는데 — 이는 AI가 절약해 줄 것이라 기대했던 시간을 조용히 돌려주는 셈입니다.
1단계: 어휘력을 제한하다(Close the vocabulary)
저희 생성기는 자유 형식 소스 코드를 방출하지 않습니다. 대신 Hyperlambda라는 언어를 방출하는데, 이 언어에서는 코드 자체가 실행 트리(execution tree)이며, 모든 실행 가능한 노드는 슬롯(slot) 호출입니다. 슬롯은 런타임에 등록된 명명된 기능(named capability)을 의미합니다.
핵심 속성은 다음과 같습니다: 슬롯의 집합은 유한하다는 것입니다. 레지스트리가 존재합니다. 어떤 기능은 그 안에 있거나, 아니면 없는 것입니다. 모델은 기능을 지어낼 수 없습니다 — 단지 그것에 이름을 붙일 뿐입니다. 그리고 이름은 검증 가능합니다.
자유 형식 언어에서는 환각된 함수가 유효한 코드입니다. 하지만 폐쇄 어휘력(closed-vocabulary) 언어에서는 환각된 슬롯이 감지 가능한 거짓말이 됩니다.
2단계: 모든 명령어가 존재함을 정적으로 증명하다
2단계: 모든 명령어가 존재함을 정적으로 증명하다
[hyperlambda.verify-slots]라는 슬롯이 있습니다. 여기에 Hyperlambda 조각을 전달하면, 이 슬롯은 실행 가능한 모든 구문 위치의 노드—루트 레벨과 발견하는 모든 본문 보유 슬롯의 본문 내부(슬롯 _시그니처 메타데이터_에서 해결되며 하드코딩된 이름이 아님)에 관계없이, 어떤 중첩 깊이까지—를 따라 이동하며 각 호출을 레지스트리와 비교합니다.
hyperlambda.verify-slots:"strings.reverse:Hello world"
모델은 strings.reverse를 지어냈습니다. 판결은 다음과 같습니다:
hyperlambda.verify-slots:bool:false
:strings.reverse
이는 구조화된 데이터로, false와 존재하지 않는 모든 것의 _정확한 이름_입니다. 몇 주 후에 나오는 스택 트레이스도 아니고, 사고 보고서도 아닙니다. 밀리초 만에 전달되는, 이름이 지정되고 기계적이며 실행 전의 판결입니다.
3단계: 모델은 결코 투표권을 얻지 못한다
이제 이 둘을 연결합니다. 우리의 Hyperlambda 생성기는 루프 안에서 실행됩니다:
- 생성(Generate) — 모델이 자연어 프롬프트로부터 실행 트리를 만듭니다.
- 증명(Prove) —
verify-slots가 모든 실행 가능한 구문을 따라 이동하며 이를 레지스트리와 비교합니다. - 거부 및 재시도(Reject and retry) — 무언가가 존재하지 않으면, _정확히 누락된 이름_이 생성 컨텍스트로 바로 되돌아가고, 모델은 다시 시도합니다.
true일 때만 배포(Ship only ontrue) — 판결이 기계적이고 이진적인 '예'가 될 때만 코드가 루프를 빠져나옵니다.
이 과정 중 어느 것도 모델의 행동에 의존하지 않습니다. 모델은 루프 안에서 원하는 만큼 환각할 수 있지만—루프 _밖으로 나오는 것_은 존재함이 증명된 기능만을 호출합니다. 환각된 코드는 구조적으로 배포될 수 없습니다.
모델을 신뢰할 필요가 없습니다. 기계가 숙제를 확인해 줍니다.
읽는 것보다 보는 것을 선호한다면, 전체 과정을 여기서 보여드립니다:
세부 사항을 먼저 공개합니다
큰 주장은 정확한 경계를 요구하므로, 이 것이 정확히 어디서 시작하고 끝나는지 알려드리겠습니다.
보장됨(Guaranteed): 발명된 기능은 절대 실행되지 않습니다. 프로덕션 로직의 모든 명령어는 실제로 구동되는 런타임에 증명 가능하게 존재합니다. 이 전체 실패 유형—환각화된 API, 유령 패키지, 지어낸 함수—이 감소하는 것이 아니라 완전히 제거됩니다.
주장하지 않음(Not claimed): 증명 가능한 것이 현명하다는 것을 의미하지는 않습니다. 로직이 실행되어야 하는지는 별개의 질문이며, 이에 대한 별도의 답변을 얻습니다. 즉, 실행 경계 자체에서 역할별 화이트리스트가 적용되어, 완벽하게 유효한 코드조차도 귀하의 RBAC 정책이 명시적으로 지정하는 기능에만 접근할 수 있습니다. 그리고 그 로직이 비즈니스에 올바른지 여부는 테스트를 위한 것입니다—이는 인간이 작성한 코드와 같으며, 물론 인간 역시 때때로 존재하지 않는 함수를 호출합니다.
핵심은 생성된 코드가 마법처럼 완벽해진다는 것이 아닙니다. 핵심은 신뢰 경계가 프롬프트에서 런타임으로 이동한다는 것입니다—
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기