LLM 에이전트를 코드베이스 탐색이나 취약점 연구에 써 본 사람이라면 비슷한 벽에 부딪힌다. 처음 몇 십 분은 놀라울 만큼 잘 하지만, 조사가 몇 시간 단위로 길어지면 모델이 지금까지 무엇을 확인했는지를 서서히 놓친다. 이미 배제한 접근을 다시 제안하거나, 거짓으로 판명된 가정 위에서 태연히 추론을 이어가는 식이다. Lemmalog를 만든 개발자는 이 문제를 두고 흥미로운 진단을 내린다. LLM에게 '틀렸다'고 알려 준다고 해서, 그 틀린 사실에 의존했던 다른 결론까지 자동으로 철회되지는 않는다는 것이다.
흔한 해법은 대화와 관찰 기록을 저장하고 임베딩한 뒤 필요할 때 유사한 조각을 검색해 다시 프롬프트에 넣는 방식이다. 이 방식은 그럭저럭 동작하지만 근본적인 한계가 있다. 취약점 연구 중에 개발자가 원한 것은 '우리가 무슨 말을 했는지'를 기억하는 것이 아니라 '지금 우리가 무엇을 알고 있는지'를 유지하는 것이었다. 예를 들어 객체 A가 객체 B를 가리킨다는 관찰에서 공격자가 커널 객체를 제어할 수 있다는 결론을 끌어냈는데, 두 시간 뒤 디버거에서 그 전제가 틀렸다는 사실이 드러났다고 하자. 검색 기반 메모리는 낡은 관찰과 새 관찰을 모두 저장한 채, 어떤 결론이 아직 유효한지를 매번 LLM이 다시 판단하기를 기대할 뿐이다.
메모리 대신 정적 분석의 관점으로
저자가 평소 하던 프로그램 분석에서는 이 문제를 다르게 다룬다. 프로그램에 대한 사실들과, 그로부터 새 사실을 유도하는 규칙들이 있고, 더 이상 새로운 사실이 나오지 않는 고정점까지 계산한다. 중요한 것은 입력 사실 하나가 바뀌었을 때 전체를 처음부터 다시 돌리지 않고 영향받은 결과만 갱신하는 증분 평가 기법이 이미 존재한다는 점이다. 관찰이 바뀌면 그에 딸린 결론이 자동으로 무효가 되는 것, 이것이 바로 조사 과정에서 필요했던 성질이다. 이렇게 문제를 바라보자 저자는 결국 LLM을 위한 Datalog 엔진을 짜게 되었다고 말한다.
Datalog는 '어떻게 계산할지'가 아니라 사실과 규칙을 선언적으로 기술하는 논리 프로그래밍 언어다. Lemmalog의 설계 핵심은 지식 유지의 책임을 둘로 나눈 데 있다. 자연어, 소스 코드, 디버거 출력 같은 지저분한 정보를 구조화된 사실로 변환하는 일은 여전히 LLM이 맡는다. 그러나 일단 사실로 바뀐 뒤에 그로부터 모든 귀결을 도출하는 결정론적 작업은 데이터베이스가 대신한다. 저자는 이 구조를 '조금 이상한 컴파일러'에 비유한다. 파서는 확률적이지만, 그 뒤의 중간 표현과 분석 엔진은 결정론적으로 동작할 수 있다는 것이다.
철회, 근거 추적, 시간 구간
구현에서 가장 까다로웠던 부분은 사실을 '제거'하는 일이었다. 결론 C가 A와 B라는 두 개의 독립된 근거로 성립할 때, A만 지운다고 C를 지울 수는 없다. 둘 다 사라져야 C도 사라진다. 취약점 연구에서 하나의 결론이 여러 관찰로 뒷받침되는 상황은 흔하므로, 엔진은 각 유도 사실이 무엇에 의해 지지되는지를 계속 추적한다. 이 근거 추적은 뜻밖의 부수 효과를 낳는다. 에이전트가 어떤 결론을 내렸을 때 '왜 그렇게 믿는가'를 되물을 수 있고, 특정 관찰이 틀린 것으로 밝혀지면 영향받은 결론들이 자동으로 제거된다. 반대로 어떤 주장을 뒷받침하는 근거가 아예 없다면 그것은 유지 상태의 일부가 아니다. 추출 단계의 환각을 막지는 못하지만, 근거 없는 결론이 조사에 조용히 스며드는 일은 훨씬 어려워진다.
또 하나의 구분은 낡은 사실을 지우는 것과 대체하는 것이 다르다는 점이다. 현재 질의에는 최신 사실만 필요하지만, 과거에 왜 특정 익스플로잇 전략을 탐색했는지를 이해하려면 예전 상태도 쓸모가 있다. 그래서 Lemmalog는 사실에 유효 구간을 부여한다. 서로 모순돼 보이는 두 사실을 그냥 나란히 두고 LLM에게 어느 쪽인지 고르라고 떠넘기지 않는 것이다. 저자는 여기서 '메모리'라는 한 단어 안에 사실은 두 개의 다른 문제가 숨어 있다고 정리한다. 관련 정보를 찾아오는 검색과, 무엇이 참인지를 유지하는 것은 다르며 코사인 유사도와 진실은 같지 않다. 검색은 전자에 강하고 Lemmalog는 후자를 겨냥한 실험이며, 실제로는 둘을 결합해 쓴다.
벤치마크가 말해 주는 것과 한계
엔진 자체는 증분 평가, 철회, 근거 추적, 시간적 사실, 집계, 엔티티 정합, 하이브리드 검색, 요구 기반 질의 등을 지원하고 에이전트가 직접 쓸 수 있는 MCP 서버도 있다. 그러나 실제로 효과가 있는지가 관건이다. 저자는 MemEval을 통해 LongMemEval과 LoCoMo에서 표준 리더 모델과 평가 설정으로 시험했다. 추출은 Claude Sonnet 4.6로 청크 단위·파일 캐싱을 써서 대화당 한 번만 비용이 들고, 그 이후는 벤치마크 자체의 표준 리더와 판정자를 쓴다. LongMemEval은 102개 문항을 여섯 범주에 고르게 나눈 구성이며, 범주당 17개라는 작은 표본을 감안해 세 번 반복 실행했다.
결과를 보면 Lemmalog는 아직 PropMem을 넘어서지 못했고 SimpleMem에도 약간 뒤졌지만, GPT-4.1에 대화 전체를 넣은 전체 문맥 방식의 0.197 F1보다 두 배 이상 높은 점수를 냈고 답변 모델에 전달되는 문맥은 약 38배 작았다. 특히 저자가 원래 관심 있던 '지식 갱신' 범주에서 Lemmalog는 0.579로 PropMem의 0.528과 전체 문맥의 0.202를 앞질렀다. 유지되는 프로그램 상태와 가장 닮은 범주에서 공개 기록을 앞선 셈이다. 단일 세션 사실 기억도 사용자 사실 0.790, 어시스턴트 사실 0.672로 잘 나왔고 시간 추론은 0.416으로 PropMem과 거의 비슷했다. 약점은 다중 세션 추론인데, 실패를 뜯어 보니 정보가 잘못 연결된 게 아니라 애초에 추출되지 않은 경우가 많았다. 추출기가 사실을 내보내지 않으면 아무리 좋은 유도 엔진도 답할 수 없다. 실제로 환각을 줄이려고 '검색된 사실이 답을 뒷받침하는지 확인하라'는 지시를 넣었더니 모델이 이를 '어떤 단일 사실이 최종 답을 글자 그대로 담고 있지 않으면 거부하라'로 해석해 102문항 중 32개를 거부하며 점수가 0.371까지 떨어진 일도 있었다. 답은 존재했지만 여러 사실에 흩어져 있었을 뿐이다. 실무자 입장에서 이 실험이 주는 교훈은 분명하다. LLM 조사의 신뢰성은 모델을 더 크게 만드는 데서만 오지 않으며, 무엇이 아직 참인지를 결정론적으로 유지하고 그 근거를 되물을 수 있게 만드는 상태 관리 계층이 별도로 필요하다는 것이다.
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공