허풍을 떨지 않는 RAG 에이전트 — 근거가 있을 때는 인라인 [n] 인용을, 없을 때는 낮은 신뢰도 플래그를, 내용이 비어있을 때는
요약
RAG 에이전트의 환각 문제를 해결하기 위해 검색 유사도 점수와 모델의 근거 제시 여부를 결합한 신뢰도 판단 시스템을 소개합니다. 근거가 확실할 때는 인라인 인용을 제공하고, 근거가 부족할 때는 답변을 지어내는 대신 낮은 신뢰도 플래그를 표시하여 정직한 답변을 유도합니다.
핵심 포인트
- 검색 유사도와 모델의 grounding 보고를 결합한 3단계 신뢰도 로직 구현
- 인라인 인용을 통해 답변의 근거를 명확히 제시하여 환각 방지
- 유사도 임계값 미만 시 답변 생성을 중단하고 정보 부족 플래그 표시
- 가상 데이터를 활용해 모델의 파라미터 메모리 의존성을 배제한 검증
단순한 RAG 파이프라인의 실패 모드는 자신감 넘치는 환각(hallucination)입니다. 즉, 몇몇 구절을 검색한 뒤 그것이 얼마나 빈약한지는 무시하고 어쨌든 답변을 내놓는 것입니다. 저의 'Agentic AI from Zero' 빌드의 프로젝트 2는 결코 그런 일을 하지 않도록 설계된 RAG 에이전트입니다. 모든 답변은 프레임워크 없이 직접 구현되었으며, 정직한 신뢰도와 함께 검색된 소스에 의해 뒷받침됩니다. 저는 이를 NVIDIA NIM (meta/llama-3.1-8b-instruct, temperature 0)을 대상으로 실제로 실행해 보았으며, 기록된 실행 결과는 실제 모델 출력에서 세 가지 동작을 모두 보여줍니다.
로컬에서 검색하고, 결정론적으로 근거를 제시하기
검색(Retrieval)은 25개의 구절에 대해 로컬 TF-IDF + 코사인 유사도(cosine similarity) 단계를 거칩니다. 이 구절들은 가상의 제품인 "Nimbus Cloud"에 관한 6개의 짧은 마크다운 문서(가격, SLA, 지역, 보안, 보존, 제한 사항)입니다. 의도적으로 가상의 제품을 사용한 이유는 모델이 파라미터 메모리(parametric memory)를 통해 답변할 수 없게 하여, 정답이 반드시 검색을 통해 나와야만 하도록 만들기 위함입니다. 이것이 바로 인용(citation)이 핵심적인 역할을 하게 만드는 요소입니다. 검색은 오프라인이며 결정론적(deterministic)이기 때문에, 기록된 실행은 바이트 단위로 동일하게 재현되며 오직 생성(generation) 단계에서만 네트워크를 사용합니다. 즉, 세 번의 라이브 LLM 호출이 발생하며 각각 HTTP 200을 반환합니다.
두 가지 신호로부터 얻는 신뢰도
결정 과정은 최상위 1위(top-1) 코사인 유사도와 모델이 스스로 보고한 근거 제시(grounding) 여부를 결합합니다:
top_score < 0.15 -> FALLBACK (검색 결과가 너무 약함)
0.15 <= top_score < 0.30 -> LOW_CONFIDENCE (근거가 빈약함)
top_score >= 0.30 AND model says grounded -> GROUNDED (답변 + 인용)
...
사례 1 — 근거가 있으며, 인라인 인용 포함
"Nimbus Enterprise 플랜은 어떤 업타임 SLA를 보장하며, 좌석당 월간 가격은 얼마입니까?" 최상위 구절의 점수는 0.6180이었고 모델은 supported=true라고 보고했습니다. 따라서 에이전트는 근거를 제시하고 인라인으로 인용했습니다:
Nimbus Enterprise 플랜은 99.95%의 업타임을 보장하며 [1], 매달 좌석당 99달러의 비용이 발생합니다 [2].
각 마커는 해당 출처로 다시 연결됩니다: [1]은 sla.md (점수 0.618)로, [2]는 pricing.md (0.386)로 연결됩니다. 인용된 두 사실 모두 인용된 구절과 정확히 일치합니다. 즉, 인용은 장식이 아니라 증거입니다.
사례 2 — 근거가 약함, 조작 대신 플래그(flag) 표시
"비트코인(Bitcoin)이나 이더리움(Ethereum) 같은 암호화폐로 Nimbus 구독료를 결제할 수 있나요?" 가장 높은 검색 결과의 점수는 단 0.2185였습니다. 말뭉치(corpus) 내에 결제 수단에 관한 언급이 전혀 없었기 때문에 어휘적으로 거의 일치하지 않는 결과였으며, 모델은 supported=false라고 정확하게 보고했습니다. 임계값 미만의 유사도(similarity)와 모델 자체의 정직함이 결합되어, 에이전트는 정책을 지어내는 대신 다음과 같이 플래그를 표시합니다:
이 질문에 답변하기 위한 정보가 충분하지 않습니다.
이것이 핵심입니다. 그럴듯하지만 근거가 없는 질문에 대해, 지어낸 암호화폐 결제 규칙으로 답변하는 대신 플래그를 표시하는 것입니다.
사례 3 — 말뭉치 외부의 내용, 검색으로 폴백(fallback)
"성인의 비타민 D 결핍 시 나타나는 일반적인 증상은 무엇인가요?" 검색된 모든 구절의 점수가 0.0000으로, 하한선인 0.15 미만이었습니다. 따라서 에이전트는 근거 기반 호출(grounded call)을 수행하기 전에 회로를 차단하고, 명확하게 표시된 웹 검색 폴백(fallback)으로 경로를 전환합니다:
FALLBACK: top retrieval similarity 0.0000 < 0.15 -> corpus has no relevant passage
답변에는 필수 면책 조항 배너가 포함됩니다 — [FALLBACK - 일반적인 웹 지식임, Nimbus 지식 베이스(knowledge base)에서 가져온 것이 아님; 독립적으로 확인하십시오.] — 그리고 결정적으로, 신뢰할 수 있는 말뭉치에 이를 뒷받침하는 내용이 없기 때문에 출처 목록은 비어 있습니다. 일반 지식 답변에 가짜 인용을 덧붙이지 않습니다.
두 부분이 정직하고 교체 가능하도록 유지해 주는 세부 사항이 하나 있습니다. 검색(retrieval)은 결정론적(deterministic)인 오프라인 TF-IDF + 코사인 유사도(cosine similarity) 단계이므로, 기록된 실행은 바이트 단위로 동일하게 재현되며 검색 단계에는 네트워크가 필요하지 않습니다. 하지만 retriever.embed()는 에이전트를 수정하지 않고도 NIM의 embeddings.create 호출을 바로 삽입할 수 있도록 작성되었습니다. 임계값(0.15 폴백, 0.30 확신)은 이 특정 말뭉치에 맞춰 조정되었으며, 측정된 점수들은 모두 기록된 실행 내에 포함되어 있습니다.
이것이 하나의 에이전트에 담긴 네 가지 아이디어입니다. 즉, 컨텍스트를 검색(retrieve)하고, 출처와 함께 생성(generate)하며, 낮은 신뢰도를 표시(flag)하고, 검색으로 폴백(fall back)하는 것입니다. 이는 단순한 RAG 데모와 신뢰할 수 있는 RAG 에이전트 사이의 차이점입니다. 정직한 방법은 답변을 하기 — — 질문이 세 가지 경로 중 어디에 있는지 — — 미리 파악하고, 유창한 문장으로 빈 코퍼스(corpus)를 가리는 대신 검색 점수(retrieval score)와 모델 자체의 인정에 따라 결정하도록 하는 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기