LLM에게 코드를 짜게 해서 10M 토큰을 읽게 한다 - RLM의 작동 원리
컨텍스트 윈도우가 커진다고 AI가 똑똑해지지 않습니다. RLM은 LLM이 직접 코드를 작성해 방대한 문서에서 필요한 부분만 선택적으로 읽는 완전히 새로운 접근법입니다.
“컨텍스트 윈도우가 커지면 AI가 더 똑똑해질까요?”
정답은 “아니오”입니다. 오히려 입력이 길어질수록 모델 성능은 떨어집니다.
컨텍스트 로트(Context Rot) - 왜 RLM이 필요한가
LLM은 입력 토큰에 대한 확률 분포를 계산해서 다음 토큰을 예측합니다. 문제는 입력이 길어질수록 관련 있는 정보와 노이즈가 뒤섞여 정확한 계산이 점점 어려워진다는 점입니다.
128K, 1M 컨텍스트를 지원한다고 광고하는 모델도 실제로는 10K 토큰 근처에서 가장 정확하고, 100K를 넘어가면 성능이 급격히 떨어집니다. 이 현상을 **컨텍스트 로트(Context Rot)**라고 부릅니다.
비유하자면 500페이지짜리 매뉴얼에서 질문 하나에 답하려는 상황과 같습니다. 실제로 필요한 건 딱 맞는 3개 문단인데, 거대한 컨텍스트 윈도우를 가진 LLM은 책 전체를 한꺼번에 소화하려 들고, 정작 중요한 신호가 노이즈에 묻혀버립니다.
RLM의 핵심 아이디어 - “다 읽지 말고, 필요한 것만 꺼내 쓰자”
RLM(Recursive Language Model)은 근본적으로 다른 접근법을 취합니다. 10M 토큰을 LLM에 한꺼번에 넣는 대신, 파이썬 변수에 저장해두고 LLM이 직접 코드를 작성해서 필요한 부분만 읽게 합니다.
쉽게 말해 LLM을 CPU로, 방대한 텍스트를 하드디스크로 취급하는 방식입니다. 매번 50K 정도의 관련 토큰만 처리하면서도 10M 이상 규모의 문서에서 정확한 답변을 뽑아낼 수 있습니다.
“모델에게 더 많은 컨텍스트를 주자”에서 “모델이 스스로 어떤 컨텍스트가 필요한지 결정하게 하자”로의 패러다임 전환입니다.
세 가지 핵심 컴포넌트
RLM Orchestrator
메시지 히스토리 관리, 반복 루프 제어, 최종 답변 판단을 담당하는 컨트롤러입니다. 모델이 데이터를 한 번 더 훑어야 하는지, 아니면 충분한 정보를 모았으니 응답해도 되는지를 결정합니다.
LMHandler
소켓 서버로 LLM API 요청을 중계하는 핸들러입니다. 핵심은 코드 실행 도중에도 이 핸들러를 통해 LLM을 호출할 수 있다는 점입니다. 즉, 모델이 데이터를 처리하는 중간에 스스로에게 질문을 던질 수 있습니다.
Environment / REPL
context 변수에 방대한 텍스트가 저장된 파이썬 샌드박스입니다. 핵심 함수는 llm_query()인데, 이 함수를 통해 실행 도중 LLM을 재귀적으로 다시 호출할 수 있습니다. RLM에서 “Recursive”가 의미하는 게 바로 이것입니다.
작동 흐름 - 탐색, 분해, 집계 루프
RLM은 방대한 문서를 처리하기 위해 구조화된 루프를 따릅니다.
탐색(Explore): 모델이 먼저 데이터 구조를 파악합니다. print(context[:500])처럼 앞부분을 출력해서 어떤 데이터를 다루고 있는지 살펴보는 단계입니다.
분해(Decompose): 텍스트를 청크로 나눈 뒤 각 청크에 llm_query()로 서브 질문을 던집니다. 수백만 토큰에 대한 하나의 거대한 쿼리 대신, 감당할 수 있는 크기의 조각들에 대해 집중된 쿼리 수십 개를 실행하는 겁니다.
집계(Aggregate): 서브 답변들을 결합합니다. 파이썬 로직(카운팅, 필터링, 정렬)으로 처리하거나, LLM에게 여러 청크의 결과를 종합해달라고 요청합니다.
종료(Terminate): 충분한 정보가 모이면 FINAL(answer)을 호출해서 최종 답변을 반환합니다.
이 루프는 필요한 만큼 반복할 수 있고, 각 반복은 이전 반복에서 발견한 내용 위에 쌓여갑니다.
Ralph Wiggum과의 연결점 - “실패해도 괜찮아, 계속 돌려”
최근 화제가 된 Claude Code의 공식 플러그인 Ralph Wiggum은 RLM과 철학을 공유하면서도 다른 문제를 해결합니다.
Ralph Wiggum의 작동 방식
Claude가 작업을 끝내고 종료하려 할 때, Stop Hook이 이를 가로채고 원래 프롬프트를 다시 주입합니다. 각 반복에서 Claude는 이전 실행에서 수정된 파일과 Git 히스토리를 볼 수 있어, 점진적으로 문제를 해결해 나갑니다.
공통점
둘 다 “한 번의 LLM 호출로 못 푸는 문제”를 반복 루프로 접근합니다. 실패를 데이터로 취급합니다. 각 반복이 이전 결과를 참조해서 개선해 나간다는 구조가 동일합니다.
차이점
RLM은 초대규모 텍스트 처리에 특화되어 있으며, 코드 실행 중 재귀적 LLM 호출이 핵심 메커니즘입니다. Ralph Wiggum은 개발 작업의 자율 실행에 초점을 맞추고 있으며, 세션 종료를 가로채 지속적 개선을 유도하는 방식으로 동작합니다.
실무 적용 팁
배치 처리: 1,000줄을 1,000번 호출하지 말고, 50줄씩 묶어서 20번 호출하세요. LLM 호출 횟수를 줄이는 것만으로도 비용과 지연 시간을 대폭 절감할 수 있습니다.
사전 필터링: llm_query()를 호출하기 전에 정규표현식으로 후보를 먼저 줄이세요. 결정론적 코드로 처리할 수 있는 부분은 미리 거르고, LLM 추론에 토큰을 쓰는 게 훨씬 효율적입니다.
재귀 깊이 제한: 깊이 1이면 대부분 충분합니다. 더 깊어지면 정확도가 올라가는 게 아니라 오류가 누적됩니다.
히스토리 관리: 롤링 윈도우나 요약 방식을 활용해서 반복이 거듭될 때 컨텍스트 로트가 누적되는 것을 방지하세요.
이것이 의미하는 것
RLM은 더 큰 컨텍스트 윈도우를 억지로 밀어넣는 방식에서, 모델이 데이터를 더 똑똑하게 읽는 방식으로의 전환을 보여줍니다. 모든 것을 하나의 프롬프트에 욱여넣는 대신, 모델이 코드를 작성하고, 실행하고, 선택적으로 읽고, 필요할 때 스스로를 재귀 호출합니다.
LLM이 코드를 작성하고 실행하면서 필요한 정보를 자율적으로 찾아가는 에이전트 스타일 추론은 AI 시스템 구축의 핵심 패턴으로 자리잡고 있습니다. 미래는 더 큰 컨텍스트 윈도우가 아니라 더 똑똑한 접근 패턴에 있습니다.
뉴스레터 구독하기
최신 프로젝트, 아티클, AI와 웹 개발 실험에 대한 소식을 받아보세요.