Retrieval-Augmented Self-Recall — 파트 3: RAG에게 "모른다"라고 말하는 법 가르치기
요약
RAG 시스템에서 검색 결과의 신뢰도를 평가하여 에이전트의 환각을 방지하는 'RE-call' 기법을 소개합니다. 검색 결과가 충분히 유사하지 않을 때 'gap_warning' 가드를 통해 에이전트가 모른다고 답변할 수 있도록 정직한 검색 환경을 구축하는 방법을 다룹니다.
핵심 포인트
- 단순 랭킹 개선보다 검색 결과의 신뢰도를 판단하는 '정직함'이 중요함
- gap_warning 가드를 통해 유사도 임계값 미달 시 경고 신호 제공
- 에이전트가 환각 없이 '모른다'고 판단할 수 있는 근거 마련
- 검색 결과에 대한 2차 신호를 제공하여 에이전트의 의사결정 고도화
Retrieval-Augmented Self-Recall의 파트 3입니다. 코드: RE-call. 파트 2: Postgres에서의 하이브리드 검색(hybrid retrieval).
정답이 _"전혀 없습니다"_인 상황에서 에이전트에게 _"이전에 이 시장에 이 필터를 적용해 본 적이 있나요?"_라고 물어보십시오. 랭킹 기반 검색기(ranking retriever)는 어쨌든 가장 유사한 세 개의 메모를 반환합니다. 비록 다른 시장에 대한 다른 필터에 관한 내용일지라도 말입니다. 그러면 에이전트는 확신에 찬 세 개의 결과를 보고 다음과 같이 결론을 내립니다: "네, 검토한 적이 있습니다."
이는 방금 환각 (hallucination)을 바탕으로 결정을 내린 것입니다. 스택(stack)의 그 무엇도 이를 알아차리지 못했습니다. 오류도 발생하지 않았습니다. 검색기(retriever)의 관점에서는 아무런 문제가 없었기 때문입니다. 당신은 가장 가까운 이웃(nearest neighbours)을 요청했고, 검색기는 가장 가까운 이웃을 제공했을 뿐입니다.
파트 2의 모든 내용은 검색을 좋게(good) 만드는 것이었습니다. 좋은 랭킹은 이 실패를 개선하는 것이 아니라 오히려 악화시킵니다. 확신에 찬 노이즈를 더 빠르게 반환하기 때문입니다. 이 포스트는 검색을 정직하게(honest) 만드는 것에 관한 것이며, 이는 에이전트 메모리(agent memory)에서 실제로 당신이 그것을 신뢰할 수 있는지 여부를 결정하는 부분입니다.
따라서 RE-call은 검색을 **정직 가드(honesty guards)**로 감쌉니다. 이 포스트에서는 랭킹 지표(ranking metrics)가 결코 묻지 않는 질문들에 답하는 원래의 세 가지 가드를 다룹니다. (현재 리포지토리(repo)는 해당 테이블을 6개로 확장했으며, 그 성장 과정은 별도의 포스트로 나와 있습니다. 새로운 가드 중 두 개는 파트 1의 독자들이 제가 설명하려는 바로 그 약점들을 지적했기 때문에 존재합니다. 진행하면서 해당 부분들을 표시하겠습니다.)
가드 1: gap_warning — "최선의 매칭이 신뢰할 만큼 충분히 좋은가?"
검색(retrieval) 후, 가장 높은 밀집 코사인 유사도(dense cosine similarity)를 확인합니다. 만약 이 값이 보정된 임계값(calibrated threshold) 미만으로 떨어진다면, 최상위 결과는 정답이 아니라 그나마 가장 나은 노이즈일 뿐입니다. 이때 시스템은 gap_warning = true로 설정합니다.
중요한 설계 아이디어는 이것입니다: 이것은 **2차 신호(second-order signal)**입니다. 검색(Retrieval)은 여전히 순위가 매겨진 목록을 반환하지만, 가드(guard)는 그 결과에 대해 얼마나 신뢰할 수 있는지 주석을 답니다. 이 주석이야말로 호출하는 에이전트(calling agent)가 맹목적으로 행동하는 것 외의 다른 일을 할 수 있게 하는 것입니다. 즉, 보류하거나(abstain), 사람에게 확인을 요청하거나, 검색 범위를 넓히거나, 또는 진행하기 전에 명시적으로 '사전에 기록된 메모리가 없다'고 표시할 수 있게 합니다.
이 단 하나의 플래그는 에이전트가 '우리는 이것을 이전에 살펴본 적이 있다'라고 말하는 것과 '나는 이것에 대해 관련 있는 것이 아무것도 없다 — 새로운 것으로 취급하라'라고 말하는 것 사이의 차이를 만듭니다. 의사결정을 내리는 시스템에서, 그 구별은 어떤 순위 개선보다도 더 큰 가치가 있습니다.
여기에는 하나 숨겨진 지뢰가 있습니다: 어떤 임계값(threshold)인가? 명백한 움직임은 0.50과 같은 값을 선택하고 넘어가는 것입니다. 이 명백한 움직임은 조용히, 위험하게 잘못된 것이며 — 이것이 이번 시리즈에서 가장 큰 발견이므로, 저는 여기에 별도의 게시물(Part 5)을 할 예정입니다. 현재로서는, 핵심 단어는 '보정된(calibrated)'입니다: 임계값은 데이터에 맞춰져야 하며, 절대 하드코딩되어서는 안 됩니다.
가드 2: 신선도(freshness) — '이 메모리가 여전히 최신인가?'
모든 메모에는 타임스탬프가 있습니다. 신선도 가드는 검색된 콘텐츠의 **나이(age)**를 보고하고, 재색인 주기와 비교하여 오래되었을 때 경고합니다 (제 코퍼스는 매일 재색인되므로 '오래되었다'는 것이 구체적인 의미를 갖습니다).
이것은 문서 QA가 거의 다루지 않는 방식의 _메모리_에 특화되어 있습니다. 문서 코퍼스는 대부분 정적입니다 — 작년 페이지도 여전히 대략적으로 사실입니다. 에이전트 메모리는 움직이는 목표물입니다: 4월에 기록된 결정은 6월에 번복되었을 수 있습니다. 신선도 신호가 없다면, 4월의 진실과 6월의 진실은 검색 시점에 구별할 수 없으며, 에이전트는 폐기된 결론에 만족스럽게 따라 행동할 것입니다. 신선도는 그것이 최신성을 가중치로 두거나, 적어도 위험을 표시할 수 있게 합니다.
솔직한 업데이트, 이 섹션의 내용이 시간이 지나며 변했기 때문입니다: 신선도(freshness)는 세 가지 가드(guard) 중 가장 취약한 것으로 드러났으며, 파트 1의 한 댓글 작성자가 그 이유를 정확히 짚어주었습니다. 즉, 대체(supersession)는 두 메모 사이의 관계인데, 문서별 타임스탬프(per-document timestamp)는 관계를 파악할 수 없다는 점입니다. 이후 저희가 이를 측정해 본 결과,
그것이 바로 **검색 인덱스 (search index)**와 **메모리 (memory)**의 근본적인 차이입니다. 검색 인덱스는 순위를 매기지만, 메모리는 자신의 한계를 알고 있습니다.
(이 초안이 작성된 이후, 가드 테이블 (guard table)이 확장되었습니다: 선언된 대체 (supersession)를 통한 신뢰 판결, 임계값(threshold)으로는 절대 잡아낼 수 없는 '유사도는 높지만 틀린' 사례를 위한 선택적 함의 판사 (opt-in entailment judge), 그리고 대체 그래프 (supersession graph)를 위한 쓰기 시점 린트 (write-time lint). 이 세 가지는 모두 독자들이 이 포스트의 이전 글들에 대해 논쟁을 제기했기 때문에 존재합니다. 측정 결과가 포함된 그 이야기는 후속 글에서 확인할 수 있습니다.)
하나의 규칙, 그렇지 않으면 가드는 연극에 불과합니다
가드는 그 신호가 의사결정 계층 (decision layer)에 도달할 때만 도움이 됩니다. 에이전트가 확인하기도 전에 계산된 후 버려지는 gap_warning은 무용지물보다 더 나쁩니다. 시스템이 주의를 기울이지 않으면서도 주의를 기울이고 있다는 잘못된 확신을 주기 때문입니다. 따라서 RE-call에서는 정직성 신호가 검색 결과 _내부_에 포함됩니다. 즉,
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기