LLM을 호출하지 않는 메모리 계층: 그로 인해 얻는 것과 치르는 대가
요약
LLM 호출 여부에 따른 메모리 계층 방식인 Mem0와 RE-call의 성능 및 비용 차이를 분석합니다. Mem0는 LLM을 통해 데이터를 정제하여 저장하는 반면, RE-call은 원본 데이터를 그대로 저장하여 비용을 절감하고 정확도와 트레이드오프를 가집니다.
핵심 포인트
- Mem0는 LLM을 사용하여 메모리 기록 시 데이터를 정제함
- RE-call은 LLM 호출 없이 원본 턴을 저장하여 비용 효율적임
- 정제된 메모리는 정확도가 높으나, 원본 저장 방식은 특정 추론에서 한계가 있음
- 리랭킹(Reranking) 기술이 검색 성능 향상에 핵심적인 역할을 함
The Answerability Problem의 4부이며, 절제(abstention)에 관한 내용이 아닌 부분입니다. 1~3부에서는 이 분야가 잘못된 절반을 측정하고 있으며, 저의 시스템이 올바른 절반에서 한계에 부딪힌다는 점을 논했습니다. 이번 파트는 장부(ledger)와 같습니다. RE-call이 무엇인지, 무엇을 놓치는지, 그리고 왜 여전히 그 결점을 가진 것을 원할 수도 있는지에 대해 다룹니다. 코드: RE-call (MIT).
"이것은 작동하지 않는다"라는 세 가지 부분이 있어야 "이것은 무엇을 위한 것이다"라는 한 가지 부분을 얻을 수 있습니다.
따라서 명확히 말씀드리자면: BEAM의 1M-토큰 버킷(1M-token bucket)에서, Mem0는 제가 중요하게 생각하는 카테고리들에 대해 RE-call보다 더 높은 점수를 기록했습니다. 저는 이 사실을 숨기거나 변명하지 않을 것입니다. 대신 왜 이런 일이 발생하는지, 그 정확도가 어떤 대가를 치르는지 정확히 말씀드리고, 여러분이 어떤 쪽의 거래를 원하는지 직접 결정하게 하겠습니다. 왜냐하면 많은 사람에게 그 답은 결코 자명하지 않기 때문입니다.
메커니즘을 한 문장으로 요약하자면
Mem0는 메모리를 쓸(write) 때 LLM을 호출하고, 정제된 결과를 저장합니다. RE-call은 LLM을 전혀 호출하지 않으며, 사용자의 원본 턴(raw turns)을 저장합니다.
이 단 하나의 결정이 이후의 모든 것, 즉 승리, 패배, 비용, 그리고 데이터가 어디로 가는지에 대한 모든 것을 설명합니다.
이를 가장 명확하게 확인할 수 있는 곳은 제가 BEAM에서 두 번째로 낮은 점수를 기록한 카테고리인 temporal_reasoning입니다: Mem0의 0.567 대비 0.408입니다.
이 수치가 어디에 쓰이기 전에 한 가지 밝혀둘 점이 있습니다. 이 수치는 의미를 변화시키기 때문입니다: 해당 셀은 리랭킹(reranking)을 끈 상태에서 측정되었습니다. BEAM 하네스(harness)는 --reranker 플래그를 사용하며 기본값은 none으로 설정되어 있고, 이번 실행에서는 해당 플래그를 전달하지 않았습니다. 리랭킹(Reranking)은 이 프로젝트에서 가장 큰 검색(retrieval) 이득을 가져다주는 요소입니다. 2부에서는 LOCOMO에서 hit@5가 0.671에서 0.777로 향상되는 것을 측정했으며, 이는 제가 건드리지 못할 것이라고 예측했던 멀티홉(multi-hop) 바닥을 포함하여 모든 카테고리를 개선했습니다. 따라서 0.408은 저의 **출시 기본값(shipped default)**이지 최적의 설정이 아니며, 리랭킹이 적용된 셀은 측정되지 않았습니다.
그것이 어느 방향으로 흐를지는 말씀드리지 않겠습니다. 리랭킹 (reranking)의 이득을 보지 못할 카테고리를 예측했다가 틀렸던 지난번의 실수를 반복하고 싶지 않으며, 여기서 추측하는 것은 더 큰 수치가 뒤따르는 동일한 오류가 될 것입니다.
제가 말할 수 있는 것은 리랭킹이 문제의 전부일 가능성은 낮다는 점입니다. 왜냐하면 진단 결과가 랭킹 실패가 아니기 때문입니다. 잘못 답변된 7개의 질문 중 단 하나만이 검색 (retrieval) 결과가 비어 있었고, 5개는 자신 있게 틀린 답을 내놓았습니다. 이 질문들은 모두 "A와 B 사이의 날짜가 며칠인가"라는 동일한 형태를 띠고 있었으며, 모든 경우에서 제 시스템은 날짜의 잘못된 _인스턴스 (instance)_를 사용했습니다.
| gold | our answer |
|---|---|
| 25 Mar → 1 Apr = 7 days | 14 days, 4월 15일로 업데이트된 마감일 사용 |
| ... |
Mem0는 저장된 메모리가 _"Sprint 1 마감일: 2024년 2월 15일"_이라는 하나의 정제된 라인으로 되어 있기 때문에 이를 정확히 맞춥니다. 반면 제 시스템은 동일한 날짜가 서로 다른 역할(role)을 가진 여러 개의 가공되지 않은 턴 (raw turns)에 흩어져 있습니다. 즉, 날짜가 설정되었을 때, 수정되었을 때, 그리고 누군가 지나가는 말로 언급했을 때 등 말입니다.
이것은 수집 (ingest) 단계에서의 LLM 증류 (distillation)가 진정으로 더 나은 아키텍처 (architecture)인 유일한 카테고리이며, 제가 감당할 수 있는 수준의 검색 측면의 변경으로는 이를 재현할 수 없습니다. 이는 리포지토리 (repo)에 해결해야 할 과제가 아닌 알려진 한계 (known limit)로 기록되어 있습니다. 가장 최신 인스턴스를 선호하는 명백한 해결책을 시도해 보았으나 결과는 틀렸습니다. 때로는 수정된 날짜가 아닌 원래의 마감일인 이전 날짜가 정답인 경우가 있기 때문입니다. 이는 모든 최신성 휴리스틱 (recency heuristic)을 무력화하며, 이 프로젝트에서 '최신 것 승리(newest-wins)' 방식에 반하는 세 번째 독립적인 증거가 됩니다.
결론적으로: 그들은 실제적인 이유로 이 부분에서 더 뛰어나며, 저는 이를 저렴하게 해결할 수 없습니다.
그 정확도가 치르는 대가
동일한 벤치마크 워크로드 (benchmark workload)로 측정한 동일한 결정의 다른 측면은 다음과 같습니다:
| RE-call | Mem0 | |
|---|---|---|
| 메모리 구축을 위한 LLM 호출 (LLM calls to build the memory) | 0 | 272 |
| ... |
그 7.29달러는 단 하나의 벤치마크 메모리에 대한 비용입니다. 구독료가 아닙니다. 당신이 작성하는 모든 것에 따라 확장되는 메모리당 한계 비용 (marginal cost)입니다. RE-call의 쓰기 경로 (write path)는 모델을 호출하지 않으므로, 그 한계 비용은 어떤 규모에서든, 어떤 모델을 사용하든, 영원히 $0입니다. 상위 단계의 가격 변동이 이 수치를 바꿀 수 없습니다.
인제스트 격차 (ingest gap)는 스톱워치를 들고 있는 동일한 사실입니다. 즉, 세션당 한 번의 추출 호출 (extraction call)은 세션당 한 번의 네트워크 왕복 (network round-trip)을 의미합니다.
(검색 지연 시간 (Retrieve latency)은 104ms 대비 77ms로,
ef{directional only}로 보고합니다. 반복 쿼리 부트스트랩 CI (repeated-query bootstrap CI)는 낙관적이며 두 백엔드가 서로 다르므로, 이 수치에 의존하지는 않겠습니다.)
숫자가 아닌 부분
당신의 데이터는 결코 당신의 인프라를 떠나지 않습니다. 로컬 임베딩 (Local embeddings), 이미 실행 중인 PostgreSQL을 사용하며, 이는 **오프라인 (offline)**에서도 작동합니다. 에어갭 (air-gapped) 환경, 프라이버시 제한 환경, 또는 추가적인 하위 프로세서 (subprocessor)를 허용하지 않는 데이터 처리 합의 (DPA) 하에서도 작동합니다.
쓰기 작업마다 LLM을 호출하는 메모리 계층는 구조적으로 이를 제공할 수 없습니다. 누군가 부주의해서가 아니라, 콘텐츠를 증류 (distil)하기 위해 외부로 전송해야 하는 아키텍처가 요구하기 때문입니다.
당신이 1인 개발자라면 이것은 비용의 문제이지만, 고객과의 대화를 보유한 기업이라면 이는 조달 (procurement)의 문제입니다. 그리고 이는 대개 정확도가 논의되기도 전에 결론이 나는 문제입니다.
클라우드 임베더 (cloud embedder)는 기본값이 아닌 **측정된 옵션 (measured option)**으로 제공되며, 해당 리포지토리(repo)는 이를 정직하게 가격 책정합니다. 이 옵션은 17개의 테스트 코퍼스 (held-out corpora) 중 16개에서 승리하며, 중앙값 hit@5 +0.059를 기록합니다. 하지만 이는 모든 문서와 모든 쿼리가 당신의 기기를 떠난다는 것을 의미하며, 로컬의 45ms 대비 246ms(p50)의 지연 시간이 발생합니다. 당신은 수치를 확인하고 선택하면 됩니다. 이것이 여기서 다루는 모든 것의 패턴입니다.
모든 것은 스위치이며, 두 설정 모두 측정 가능합니다
이 부분은 제가 다섯 편의 글 동안 과소평가했던 부분입니다.
- Embedder (임베더): 다운로드가 필요 없는 해싱 모델 (hashing model),
bge-small,bge-large, Voyage, 또는 OpenAI 호환 모델 중 선택 가능합니다. 17개의 코퍼스 (corpora)를 통해 측정되었으며, 비용을 지불할 가치가 있는 기준을 제시합니다. - Reranking (재순위화): 기본적으로 꺼져 있으며, 하나의 플래그로 켤 수 있습니다. 이 프로젝트에서 가장 큰 검색 성능 향상(hit@5 0.671 → 0.777)을 가져오지만, 쿼리당 약 1,050ms의 비용이 발생하며 이는 실제 시간 (wall clock) 기준으로 약 4배에 달합니다. 두 가지 측면이 모두 공개되어 있으므로 결정은 여러분의 몫입니다. 사람에게 답변하는 경우라면, 뒤따르는 LLM 호출에 비해 ~1초의 시간은 느껴지지 않을 것입니다. 하지만 대량의 자동화된 검색 (automated retrieval)을 서비스하는 경우에는 이 비용이 지배적입니다.
- Entailment abstention (함의 기권): 기본적으로 꺼져 있으며, Part 2에서는 이것이 왜 어려운 사례를 구제하지 못하는지에 대해 2,000단어에 걸쳐 다룹니다.
- The whole stack (전체 스택): Postgres 및 pgvector를 사용합니다. 별도의 벡터 데이터베이스 (vector database), 큐 (queue), 또는 일관성을 유지하기 위한 두 번째 저장소는 필요하지 않습니다.
저는 마케팅 문구가 담긴 기본 설정값을 제공하기보다, 측정된 두 가지 설정값을 플래그로 제공하는 쪽을 택하겠습니다.
그리고 정확도 열에는 나타나지 않는 위험 요소
BEAM에는 정답이 "여기에 없습니다"인 질문들을 분류하는 abstention (기권) 카테고리가 있습니다. 저는 Mem0가 직접 공개한 답변들을 **Mem0 자체 판사 (judge)**를 통해 이 카테고리로 채점했습니다. n=70:
| Mem0의 동작 | n | 평균 점수 |
|---|---|---|
| 기권함 (abstained) | 38 | 0.974 |
| 그냥 답변함 (answered anyway) | 32 | 0.016 |
이 카테고리는 거의 완벽하게 이진적(binary)이며, 정확히 한 가지만을 테스트합니다: 증거가 없을 때 시스템이 답변을 지어내는가? 시스템은 46%의 확률로 답변을 지어냅니다.
실제 사례 하나를 들면: 기록된 적 없는 사용자 피드백에 대해 질문했을 때, 시스템은 _"사용자 테스트 결과 긍정적인 반응을 보였습니다: 동적 언어 전환 기능은 90%의 만족도를 달성했습니다."_라고 답변했습니다. 코퍼스에는 _"90%의 만족도를 달성하는 것은 강력한 시작입니다"_라는 문구가 포함되어 있었는데, **어시스턴트 (assistant)**가 이를 추측한 것이 검색(retrieval)을 통해 표면화되었고, 답변 생성기(answerer)가 이를 사실로 읽어버린 것입니다.
제가 주장하는 바를 정확하게 전달하고 싶습니다. 왜냐하면 이 지점은 자칫 과하게 해석하기 쉬운 부분이기 때문입니다:
- 그들이 발표한 점수는 정직합니다. 저는 그들의 BEAM 셀을 0.0005 차이(0.6414 대 0.6409)로 재현했습니다. 무엇도 조작되지 않았습니다.
- 벤치마크는 그들에게 맞춰져 있지 않습니다 (not backfitted). 특정 벤더에게 유리하도록 조정된 벤치마크라면, 해당 벤더의 46% 조작률(fabrication rate)을 이토록 노출하지 않았을 것입니다.
- 그리고 여기서 제시하는 저의 수치는 승전보가 아닙니다. 동일한 카테고리에서, 제가 출시한 정책(shipped policy)은 대화 0~14에 걸친 30개의 답변 불가능한 질문과 270개의 답변 가능한 질문을 대상으로 측정했을 때, $0의 비용으로 **9.3%**의 오탐(false-abstain) 비용을 지불하며 **23.3%**의 확률로 올바르게 기권(abstain)합니다. 이 탐색(probe)에는 LLM이 필요하지 않기 때문입니다. 위와 동일한 설정 주의사항이 적용됩니다: 리랭커(reranker)는 꺼져 있습니다. 저는 네 가지 더 엄격한 정책을 테스트했으며, BEAM의 9:1 답변 가능/불가능 혼합 비율에서 그들 모두가 더 나쁜 결과를 냈습니다. 출시된 정책은 이미 다섯 가지 중 가장 우수하며, 이는 제가 예측했던 것과 정반대입니다.
따라서 우리 중 누구도 이 문제를 해결하지 못했습니다. 차이점은 실패의 형태에 있습니다. 그럴듯한 만족도를 조작해내는 시스템은 아무것도 반환하지 않는 시스템과는 다른 종류의 책임(liability) 문제입니다. 당신이 무엇을 만들고 있느냐에 따라, "약간 덜 정확한 것"과 "확신을 가지고 통계를 지어내는 것"은 하나의 척도 위에 있는 두 지점이 아닙니다.
벤치마크 자체의 두 가지 문제점
이 점들은 다른 누구보다도 제 주장과 상충되는 부분이기에 언급할 가치가 있습니다.
BEAM의 답변 불가능한 질문 점수가 답변 가능한 질문보다 더 높습니다: 중앙값 top-1 코사인 유사도(cosine similarity)가 0.641인 것에 비해 0.676입니다. 이 질문들은 적대적으로 구성되었으며, 코사인 유사도와 수학적 원리를 공유하지 않는 어휘적 커버리지(lexical-coverage) 신호는 동일한 방향으로 역전됩니다. 따라서 그들의 것이든 저의 것이든 모든 BEAM 수치는 난이도의 상한선(upper bound)이지, 실제 배포된 동작의 추정치가 아닙니다. 답변 불가능함이 진정으로 부재함을 의미하는 일반적인 코퍼스(corpus)에서는, 단순 코사인 유사도가 AUC 0.780에서 분리됩니다.
점수 산정 방식은 답변 유보(withholding)에 대해 9:1의 불리한 비율을 가집니다. BEAM에서 답변 유보(abstention)는 약 10%를 차지하므로, 더 많이 유보하는 정책은 30개의 질문에서 이득을 얻지만 270개의 질문에서 손해를 봅니다. 이는 벤치마크에 대한 불만 사항이 아닙니다. 이 벤치마크의 답변 유보 카테고리는 잘 구축되어 있습니다. 이는 정책이 아무리 좋아지더라도, BEAM의 집계(aggregate)를 통해서는 답변 유보에 대한 주장을 할 수 없음을 의미합니다. 이 분야에는 오답(false answer)과 답변 유보(withheld answer)의 가치를 비교할 수 있는 지표가 필요하며, 이것은 그 지표가 아닙니다.
ARM(Arm)이 생성한 두 가지 작은 수정 사항은 다음과 같습니다: BEAM의 하네스(harness)는 답변자와 판정자로 gpt-5를 지정합니다(gpt-4o가 아님). 또한, 발표된 64.1은 평균 루브릭-너겟(rubric-nugget) 점수이며, 통과율(pass rate)이 아닙니다: 동일한 실행에 대한 통과율은 70.14%입니다.
제가 보고하지 않는 것: 쌍을 이룬 BEAM 집계(paired BEAM aggregate). 저는 카테고리별 셀(cell)과 답변 유보 프로브(abstention probe)를 가지고 있지만, 동일 선상에서 비교 가능한 총계(like-for-like total)는 가지고 있지 않습니다. 따라서 리포지토리(repo)에도 없고 여기에도 없습니다. 이 프로젝트의 이전 초안에서는 서로 관련 없는 두 개의 BEAM 수치를 결합하여, 읽기에는 좋지만 실제로는 존재하지 않는 헤드라인을 만든 적이 있습니다. 한 번의 실수로 교훈을 얻었습니다.
그렇다면 어떤 것을 사용해야 할까요?
진정으로 상황에 따라 다르며, 제 이익에 반하는 말일지라도 말씀드리겠습니다:
**LLM 증류 아키텍처 (LLM-distilling architecture)**를 사용하십시오. 만약 질문이 밀집된 자료에 대한 시간적(temporal) 추론 및 멀티홉(multi-hop) 추론 비중이 높고, 강력한 독자가 답변을 수행하며, 메모리당 비용이 제약 사항이 아니며, 모델 제공업체에 콘텐츠를 보내는 것이 괜찮다면 이 방식이 적합합니다. 이 방식은 측정 가능한 측면에서 해당 작업에 더 뛰어나며, 저는 이미 그 방식이 저를 이기는 카테고리와 그 이유를 보여드렸습니다.
**이 방식 (this one)**을 사용하십시오. 만약 메모리의 한계 비용(marginal cost)이 0이어야 하거나, 데이터가 외부로 유출될 수 없거나, 오프라인에서 작동해야 하거나, 검색 경로(retrieval path)가 모델의 의견이 아닌 검사 및 교체 가능한 형태이기를 원하거나, 혹은 만족도를 자신 있게 지어내는 시스템이 아무 말도 하지 않는 시스템보다 더 나쁜 결과라면 이 방식을 사용해야 합니다.
그것이 트레이드오프(trade-off)입니다. 이것은 "우리가 더 낫다"는 뜻이 아닙니다. 쓰기 경로(write path)에 LLM을 사용하는 것은 더 나은 표현(representation)을 얻는 대신 돈, 지연 시간(latency), 그리고 데이터를 대가로 지불하는 것이며, 수많은 실제 배포 환경에서는 그것이 잘못된 선택이 될 수 있다는 뜻입니다.
시리즈를 마무리하며
Parts 1–3에서는 이 분야가 정답이 존재하는 질문에 대한 정확도(accuracy)를 측정한다는 점, 가장 많이 인용되는 벤치마크의 표준 하네스(harness)가 답변을 거부하는 것을 금지한다는 점, 제가 누락된 지표를 구축했을 때 제 시스템의 점수가 0점이었다는 점, 그리고 마지막으로 두 공개 벤치마크가 서로 일치하지 않는 이유는 각자가 숨겨진 축의 한 지점을 샘플링하여 예/아니오 질문을 좌표로 변환하기 때문이라는 점을 다루었습니다.
이번 파트에서는 나머지 내용을 다룹니다. 즉, temporal_reasoning을 놓치는 바로 그 설계가 비용이 0달러이고, 4.3배 더 빠르게 데이터를 흡수하며, 문서를 어디로도 전송하지 않는 설계라는 점, 그리고 기존 방식(incumbent)의 더 나은 총합 점수는 정직한 답변이 침묵이어야 하는 질문들에 대해 46%의 환각(fabrication) 비율을 동반한다는 점을 설명합니다.
이 두 가지 사실은 동시에 참입니다. 유리한 절반만을 발표하는 것이 바로 이 시리즈 전체가 반대하는 지점입니다.
완전성을 위하여: 쌍을 이룬 대결 (paired contest)
LOCOMO에서는 동일한 질문, 동일한 생성기(generator), 동일한 판사(judge)를 사용하며 오직 메모리(memory)만 다릅니다. 질문별 결과에 대한 쌍을 이룬 맥네마 검정(Paired McNemar), n=1,540:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기