AI 어시스턴트가 망각하는 이유, 그리고 메모리를 처음부터 다시 구축하며 배운 것들
요약
AI 어시스턴트가 대화 맥락을 유지하지 못하고 반복적인 오류를 범하는 '메모리 격차' 문제를 분석합니다. 컨텍스트 윈도우의 한계와 비용 문제, 그리고 모델의 정보 회상 특성을 바탕으로 효과적인 메모리 시스템 구축의 필요성을 다룹니다.
핵심 포인트
- AI의 실패는 지식 격차와 메모리 격차라는 두 가지 별개 문제로 구분됨
- 단순히 컨텍스트 윈도우를 늘리는 것은 비용 효율성과 정보 회상 측면에서 한계가 있음
- 모델은 컨텍스트 중간 부분의 정보를 놓치는 경향이 있음
- 효과적인 메모리 설계를 위해 문제 중심의 재구성 접근 방식이 필요함
저는 똑같은 오답을 반복해서 내놓는 AI 어시스턴트 때문에 5일을 허비했습니다.
저는 MLOps 파이프라인을 구축 중이었고 Airflow DAG를 설정해야 했습니다. Microsoft가 막 Airflow를 Azure에서 Fabric으로 옮긴 상태였기에, 새로운 설정에 대한 문서가 거의 없었습니다. 제가 어시스턴트를 교정할 때마다, 그것은 사과하고 수정하겠다고 약속하며, 약간만 문구를 바꾼 동일한 오류가 있는 설정(config)을 다시 내놓았습니다. 저는 새로운 채팅창을 열고 문제 전체를 다시 설명했습니다. 매번 똑같은 루프가 반복되었습니다.
그냥 문서를 검색하는 것이 더 빨랐을 것입니다.
그 경험은 제 머릿속에 남았고, 하나의 프로젝트로 이어졌습니다. AI 어시스턴트가 왜 망각하는지, 그리고 시스템이 제대로 기억하기 위해 실제로 무엇이 필요한지를 밑바닥부터 재구성해 보는 것이었습니다. 제가 발견한 내용은 다음과 같습니다.
하나의 가면을 쓴 두 가지 실패
제가 처음에 잘못 생각했던 것은 환각 (hallucination)을 탓한 것이었습니다. 실제 이야기는 두 가지 별개의 문제였습니다.
하나는 지식 격차 (knowledge gap)였습니다. 문서가 실제로 존재하지 않았기 때문에, 어떤 메모리(memory)도 도움이 되지 않았을 것입니다. 답이 세상에 존재하지 않는다면, 어시스턴트는 그것을 찾을 수 없습니다.
다른 하나는 메모리 격차 (memory gap)였으며, 이것이 흥미로운 지점입니다. 어시스턴트는 대화 전반에 걸쳐 저의 문제를 유지할 수 없었습니다. 제가 이미 제외한 것이 무엇인지 기억하지 못했습니다. 또한 저의 교정 사항이 이전 답변을 덮어쓰도록 허용하지 못했습니다. 단일 채팅 안에서도 흐름을 놓쳤습니다. 채팅 간에는 아무것도 유지하지 못했습니다.
이것들은 서로 다른 실패이며, 이 둘을 구분하는 것이 첫 번째 정직한 단계입니다.
방법론: 해결책을 읽기 전에 먼저 망가뜨려 보기
메모리 시스템이 어떻게 구축되는지 읽으며 고개를 끄덕이는 대신, 저는 재구성 접근 방식 (reconstruction approach)을 사용했습니다. 문제에서 시작하여 가능한 가장 단순한 해결책을 상상한 다음, 그 해결책이 정확히 어떻게 망가지는지 파악하는 방식입니다. 각 실패는 다음 설계가 무엇을 해결해야 하는지를 가리킵니다.
실제 정답에 도달할 때쯤이면 그것이 당연하게 느껴질 것입니다. 왜냐하면 그 정답을 필요하게 만든 모든 벽에 당신이 직접 부딪혀 보았기 때문입니다.
그래서 여기 몇 가지 간단한 해결책들을 순서대로 나열하고, 왜 각각의 방법이 실패하는지 설명하겠습니다.
해결책 1: 매번 대화 전체를 전송하기
가장 뻔한 방법입니다. 모델이 잊어버린다면, 모든 것을 다시 보내는 것입니다.
이 방법은 세 가지 이유로 실패하며, 그중 단 하나만이 사람들이 예상하는 이유입니다.
첫째, 용량이 맞지 않습니다. 컨텍스트 윈도우 (Context window)는 유한합니다. 이전 모델들은 공간이 다 차기 전까지 불과 수십 개의 주고받은 메시지만을 유지할 수 있었습니다. 코딩 작업의 경우 상황은 더 나쁩니다. 붙여넣은 로그(logs)와 스택 트레이스 (stack traces)가 공간을 빠르게 차지하기 때문입니다.
둘째, 윈도우를 키우는 것은 비용이 많이 듭니다. 어텐션 메커니즘 (Attention mechanism)은 모든 토큰을 다른 모든 토큰과 비교하므로, 비용은 길이의 제곱에 비례하여 증가합니다. 컨텍스트를 두 배로 늘리면 비용은 대략 네 배로 늘어납니다.
셋째, 저를 놀라게 했던 부분입니다. 모든 내용이 들어갈 수 있는 상황에서도 모델은 종종 이를 사용하지 않습니다. 연구에 따르면 모델은 윈도우의 중간 부분보다 시작과 끝 부분의 정보를 훨씬 더 잘 회상합니다. 따라서 당신이 필요로 하는 사실이 바로 그 자리에 놓여 있음에도 불구하고 놓쳐질 수 있다는 뜻입니다.
더 큰 컨텍스트가 더 나은 메모리를 의미하는 것은 아닙니다.
해결책 2: 실행 중인 요약본 유지하기
모든 것을 유지할 수 없다면, 요약하십시오. 대화의 짧은 버전을 저장하고 이를 계속 가져가는 방식입니다. 당신을 "기억하는" 대부분의 어시스턴트가 대략 이런 방식으로 작동합니다.
문제는 요약 과정에서 나중에 던질 질문들이 의존하게 될 구체적인 세부 사항들이 버려진다는 점입니다.
MemGPT 논문에서 제가 이 사실을 깨닫게 해준 측정 지표가 있었습니다. 그들은 이전 세션의 요약본을 바탕으로 모델에게 자신의 과거 대화에 대한 질문을 던졌습니다. GPT-4는 32%의 확률로 정답을 맞혔습니다. 대략 세 번 중 한 번꼴입니다.
정말 충격적이었던 세부 사항은 다음과 같습니다: GPT-4가 동일한 테스트에서 GPT-3.5보다 낮은 점수를 기록했다는 점입니다. 더 유능한 모델이 더 못한 결과를 낸 것입니다.
이는 문제가 모델에 있는 것이 아님을 말해줍니다. 더 똑똑한 모델도 도움이 되지 않는다면, 다음 모델이 이를 해결해주기만을 기다릴 수는 없습니다. 격차는 지능이 아니라 메모리 설계 (memory design)에 있습니다.
해결책 3: 모든 것을 저장하고 관련 있는 것을 검색하기
이것이 성숙한 버전입니다. 과거의 모든 정보를 데이터베이스 (database)에 저장하고, 새로운 질문이 들어오면 그와 가장 유사한 조각들을 가져오는 것입니다. 이것이 검색 (retrieval)이며, 실제로 매우 유용합니다. 이는 오늘날 작동하는 많은 것들의 기반이 됩니다.
하지만 유사성 (similarity)만으로는 분명한 허점이 있습니다.
정작 필요한 정보가 상위 결과에 없는 경우가 많습니다. 때로는 당신에게 필요한 내용이 노이즈 (noise)보다 훨씬 낮은 순위에 위치하기도 하며, 상위 몇 개만 읽는 시스템은 이를 결코 발견할 수 없습니다.
여러 사실을 결합해야 하는 질문에는 단 한 번의 검색만으로는 부족합니다. 저의 Airflow 문제는 런타임 버전 (runtime version), 플랫폼 마이그레이션 (platform migration), 그리고 제가 이미 시도했던 접근 방식들을 한꺼번에 필요로 했습니다. 단 하나의 저장된 노트에는 그 답이 들어있지 않았습니다. 여러 노트를 가로질러 조립되어야 했으며, 단 한 번의 조회 (lookup)로는 그것을 수행할 수 없습니다.
그리고 이것이 제 사례에서 가장 중요한 문제입니다. 유사성에는 시간 개념이 없습니다. 제가 어시스턴트에게 Azure에서 Fabric으로 이동했다고 말했을 때, 예전의 Azure 설정은 이전과 마찬가지로 제 질문과 유사한 상태로 남아 있었습니다. 따라서 유사성만 사용하는 시스템은 그것이 더 이상 유효하다는 신호를 전혀 주지 못한 채, 구식 정보를 계속해서 노출합니다. 저의 수정 사항은 결코 승리하지 못하는데, 왜냐하면 "유사하다"는 것이 "최신이다"를 의미하지는 않기 때문입니다.
논문들이 다루지 않은 두 가지 문제
이를 위해 저는 네 편의 기초적인 논문들을 공부했습니다. 가장 어려운 두 가지 문제는 그 어떤 논문에서도 나타나지 않았으며, 제가 코딩 어시스턴트라는 실제 도메인을 선택하고 나서야 비로소 나타났습니다.
첫 번째는 사용자 간의 정보 유출 (leakage)입니다. 만약 시스템이 유사성에 따라 메모리를 찾는다면, 두 사람이 동일한 데이터베이스 오류를 디버깅하고 있을 때 한 사람의 개인적인 연결 문자열 (connection string)이 다른 사람의 세션에 나타나는 것을 무엇이 막을 수 있을까요? 유사성만을 유일한 기준으로 삼는다면 아무것도 막을 수 없습니다. 콘텐츠 자체가 정말로 유사하기 때문입니다. 그리고 시스템이 사용하는 유일한 척도에 따르면 그 메모리는 완벽하게 일치하므로, 이 실패는 소리 없이 발생합니다.
두 번째는 민감한 정보입니다. 디버깅을 할 때, 당신은 설정 파일(config files), API 키, 연결 문자열(connection strings)을 붙여넣습니다. "유용한 것을 기억하도록" 설계된 시스템은 당신이 결코 저장되기를 원치 않을 바로 그 정보들을 저장할 것입니다. 이런 종류의 작업에서, 유용한 정보와 민감한 정보는 종종 동일한 정보입니다.
이 두 가지 모두 검색 버그(retrieval bug)나 모델 버그(model bug)가 아닙니다. 이것들은 정보가 저장되는 시점에 누군가가 의도적으로 내려야 하는 결정들입니다.
실제 메모리 시스템에 진정으로 필요한 것들
모든 단순한 해결책이 무너지는 것을 지켜보고 나면, 요구 사항들은 더 이상 희망 사항처럼 느껴지지 않고 증거에 의해 강제되는 것처럼 느껴지기 시작합니다. 그중 몇 가지는 다음과 같습니다:
모든 것을 유지하거나 아무것도 유지하지 않는 대신, 무엇을 유지할지 결정하십시오. 유사성(similarity) 이상의 기준으로 메모리의 순위를 매겨, 최근의 중요한 정보가 우선순위를 가질 수 있게 하십시오. 수정 사항이 기존 사실 옆에 나란히 놓이는 대신, 기존 사실을 진정으로 대체할 수 있게 하십시오. 요청 시 완전히 삭제하십시오. 한 사용자의 메모리가 다른 사용자의 메모리와 섞이지 않게 하십시오. 그리고 답을 찾지 못했을 때는 루프(looping)에 빠지는 대신, 답을 찾지 못했다고 말할 수 있어야 합니다. 제 시스템이 정확히 실패했던 부분이 바로 이것입니다.
이 중 어느 것도 특정 솔루션을 지칭하지는 않습니다. 그것은 나중에 다루겠습니다. 이것들은 정직한 시도라면 반드시 충족해야 하는 속성들이며, 각각은 제가 지목할 수 있는 실패 사례에서 비롯되었습니다.
제가 실제로 얻은 교훈
재구축(reconstruction) 접근 방식이야말로 메모리에 관한 그 어떤 단일 사실보다 더 큰 진짜 교훈이었습니다.
완성된 설계를 읽는 것은 무엇(what)을 가르쳐 줍니다. 하지만 단순한 버전을 직접 망가뜨려 보는 것은 왜(why)를 가르쳐 줍니다. 그리고 그 '왜'는 누군가 반박할 때 당신이 방어할 수 있는 부분입니다. 왜냐하면 당신은 문제가 각 선택을 강제하는 과정을 직접 지켜보았기 때문입니다.
저는 아직 이 과정의 초기에 있습니다. 다음 단계로, 저는 순진한(naive) 버전을 실제로 구축하고, 그것이 정확히 어디에서 무너지는지 측정하며, 그 측정값들이 실제 설계를 형성하도록 할 것입니다. 진행하면서 계속 글을 쓰겠습니다.
만약 당신이 AI 메모리를 사용하여 무언가를 구축해 보았다면, 민감한 데이터(sensitive-data) 측면을 어떻게 처리했는지 진심으로 듣고 싶습니다. 그 부분이 제가 가장 확신하지 못하는 부분입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기