기존 방식이 제대로 작동하지 않아 LLM 에이전트를 위한 메모리 레이어를 구축하는 데 8개월을 보냈습니다. 제가 배운 점은 다음과 같습니다.
요약
LLM 에이전트의 메모리 문제를 단순 저장(Storage)이 아닌 관련성(Relevance)의 관점에서 접근하여 직접 구축한 사례를 다룹니다. HNSW 그래프 재배선, 양자화 오차 보정, 시간적 쇠퇴 모델 도입을 통해 에이전트의 기억력을 개선하는 기술적 방법론을 제시합니다.
핵심 포인트
- HNSW 그래프를 int8 거리에 맞춰 직접 재배선하여 재현율 향상
- 양자화 오차 해결을 위해 빔 서치 중 잔차 보상(residual compensation) 도입
- 에빙하우스 모델을 거리 메트릭에 통합하여 시간적 쇠퇴(decay) 구현
- 단순 벡터 저장 방식의 한계를 극복하는 메모리 레이어 설계
지난해 저는 친구의 사업을 위한 AI 어시스턴트를 구축하고 있었습니다.
에이전트는 똑똑했습니다. 질문에 답변도 잘했습니다. 하지만 매번 새로운 대화가 시작될 때마다, 에이전트는 제로(zero) 상태에서 시작했습니다. 이 고객이 동일한 문제로 두 번이나 불만을 제기했다는 사실을 알지 못했습니다. 다른 사용자가 항상 짧은 답변을 원한다는 사실도 몰랐습니다. 누구에 대해서도 아무것도 알지 못했습니다.
저는 모든 것을 시도해 보았습니다. Pinecone, Chroma, Weaviate, 순환 요약(Rolling summaries), 컨텍스트 윈도우(context window)가 폭발할 때까지 프롬프트에 전체 이력을 주입하는 방식까지 말이죠.
그 어떤 것도 제대로 된 느낌이 들지 않았습니다. 왜냐하면 그것들은 모두 메모리를 저장(storage)의 문제로 취급했기 때문입니다.
그것은 저장의 문제가 아닙니다. 관련성(relevance)의 문제입니다.
1월에 에이전트에게 "React를 사용합니다"라고 말하고, 3월에 "Vue로 전환했습니다"라고 말한 사용자가 있다면, 정적인 벡터 데이터베이스(vector database)는 두 정보 모두 동일한 가중치로 반환합니다. 당신의 에이전트는 혼란에 빠집니다. 사용자는 당신의 제품이 고장 났다고 생각할 것입니다.
그래서 저는 해결책을 찾는 것을 멈추고 직접 만들었습니다.
8개월 후, 제가 실제로 배운 점은 다음과 같습니다:
아무도 이야기하지 않는 그래프 토폴로지(graph topology) 문제
표준 HNSW는 float32 거리를 기반으로 그래프를 구축한 다음, 검색을 위해 int8로 양자화(quantize)합니다. 그래프 토폴로지는 실제 검색 시점에 발생하는 일이 아니라 float32 이웃에 최적화되어 있습니다. 저는 int8 거리에 따라 그래프를 직접 재배선(rewired)했습니다. 그 결과 재현율(Recall)이 향상되었습니다.
양자화 오차(Quantization error)의 누적
모든 int8 거리 계산에는 오차가 포함됩니다. 저는 잔차 보상(residual compensation)을 추가했습니다. 빔 서치(beam search) 중에 오차를 수정하는 노드당 8개의 float16 계수를 도입했습니다. float32 저장 공간은 필요하지 않았습니다.
시간적 문제(temporal problem)가 가장 어렵습니다
이것은 아무도 제대로 해결하지 못하는 문제입니다. 저는 에빙하우스(Ebbinghaus)에서 영감을 얻은 쇠퇴(decay) 모델을 HNSW 거리 메트릭(distance metric)에 직접 통합했습니다. 후처리 단계(post-processing step)나 재순위화(re-ranking) 방식이 아닙니다. 빔 서치 자체 내부에서, 흐릿해지는 기억들이 쿼리(query)로부터 기하학적으로 더 멀리 떨어져 나타나도록 했습니다.
3가지 시간적 시나리오(선호도 업데이트, 강화, 쇠퇴)에 걸쳐 100회의 테스트를 진행한 결과:
본문:
지난해 저는 친구의 사업을 위한 AI 어시스턴트를 구축하고 있었습니다.
에이전트는 똑똑했습니다. 질문에 답변도 잘했습니다.
하지만 모든 새로운 대화는 항상 제로(zero) 상태에서 시작되었습니다. 이 고객이 동일한 문제에 대해 두 번이나 불만을 제기했다는 사실을 알지 못했습니다. 또 다른 사용자가 항상 짧은 답변을 원한다는 사실도 몰랐습니다. 그 누구에 대해서도 아무것도 알지 못했습니다.
저는 모든 것을 시도해 보았습니다. Pinecone, Chroma, Weaviate, 그리고 요약본을 계속 생성하는 방식(Rolling summaries)까지 말이죠. 컨텍스트 윈도우(Context window)가 폭발할 때까지 전체 히스토리를 프롬프트(Prompt)에 주입하기도 했습니다.
그 무엇도 제대로 작동하는 느낌이 들지 않았습니다. 왜냐하면 이 방식들은 모두 메모리를 저장(Storage)의 문제로 취급했기 때문입니다.
그것은 저장의 문제가 아닙니다. 관련성(Relevance)의 문제입니다.
1월에 에이전트에게 "저는 React를 사용합니다"라고 말하고, 3월에 "Vue로 전환했습니다"라고 말한 사용자가 있다면, 정적인 벡터 데이터베이스(Vector database)는 두 정보 모두를 동일한 가중치로 반환합니다. 당신의 에이전트는 혼란에 빠지고, 사용자는 당신의 제품이 고장 났다고 생각할 것입니다.
그래서 저는 해결책을 찾는 것을 멈추고 직접 만들기로 했습니다.
8개월 후, 제가 실제로 배운 점은 다음과 같습니다:
아무도 말하지 않는 그래프 토폴로지(Graph topology) 문제
표준 HNSW는 float32 거리를 기반으로 그래프를 구축한 다음, 검색을 위해 int8로 양자화(Quantize)합니다. 그래프 토폴로지는 실제 검색 시점에 발생하는 상황이 아니라 float32 이웃(Neighbors)에 최적화되어 있습니다. 저는 int8 거리에 따라 그래프를 직접 재배선(Rewired)했습니다. 그 결과 재현율(Recall)이 상승했습니다.
양자화 오차(Quantization error)의 누적
모든 int8 거리 계산에는 오차가 포함됩니다. 저는 잔차 보정(Residual compensation)을 추가했습니다. 즉, 빔 서치(Beam search) 중에 오차를 수정하는 노드당 8개의 float16 계수를 도입했습니다. float32 저장 공간은 필요하지 않았습니다.
시간적(Temporal) 문제가 가장 어렵습니다
이것은 아무도 제대로 해결하지 못하는 문제입니다. 저는 에빙하우스(Ebbinghaus)의 망각 곡상에서 영감을 얻은 감쇠(Decay) 모델을 HNSW 거리 메트릭(Distance metric)에 직접 통합했습니다. 후처리(Post-processing) 단계로 넣은 것도, 재순위화(Re-ranking)로 처리한 것도 아닙니다. 빔 서치 자체 내부에서, 희미해지는 기억들이 쿼리(Query)로부터 기하학적으로 더 멀리 떨어져 있는 것처럼 나타나게 했습니다.
3가지 시간적 시나리오(선호도 업데이트, 강화, 감쇠)에 걸친 100회의 테스트 결과:
정적 인덱스(Static index): 74% Temporal Recall@1
제 구현 방식: 100% Temporal Recall@1
hnswlib 및 FAISS와 GloVe 100K 실제 텍스트 벡터를 비교했을 때:
hnswlib C++: 99.3% 재현율, 0.087ms
FAISS HNSWFlat: 99.0% 재현율, 0.134ms
제 방식: 90.25% 재현율, 4.8ms
네, Python은 C++보다 느립니다.
그것은 예상된 결과이며 핵심이 아닙니다. Rust 포팅 (Rust port)이 진행 중입니다.
핵심은 알고리즘입니다. 그리고 실제 난제인 시간적 관련성 (temporal relevance) 측면에서, 정적 인덱스 (static index)는 4번 중 1번은 실패합니다. 제 방식은 그렇지 않습니다.
만약 여러분이 에이전트 (agents)를 구축하면서 정적 벡터 저장소 (static vector store)로 메모리를 처리하고 있다면, 오래된 컨텍스트 (stale context) 문제를 어떻게 다루고 있는지 궁금합니다. 그냥 무시하고 사용자가 눈치채지 못하기를 바라고 계신가요?
submitted by /u/Scared_Animator9241
[link] [comments]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/LocalLLaMA의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기