The memory that proved itself
기억이라는 말은 보관을 연상시킨다. 서랍, 창고, 아카이브. 그런데 뇌는 그렇게 일하지 않는다. 회상은 재생이 아니라 재구성이고, 기억은 꺼내 쓸 때마다 다시 평가받는다. 도움이 된 기억은 굳고, 틀린 기억은 밀려난다. 기억의 본질은 저장이 아니라 검증이다.
에이전트 메모리를 만들면서, 우리는 이 당연한 사실을 코드에서 배신하고 있었다.
들통난 건 우리 제품을 우리 에이전트에 붙인 날이다. 자동 저장된 기억 1,833건을 해부했더니 93%가 쓰레기였다. 원시 JSON, 트랜스크립트 조각, API 키를 닮은 문자열 268건. 저장은 성실했고 쓸모는 없었다. 그날 밤 진단서에 적었다. 저장만 하는 메모리 제품은 무의미하다, 파일로 충분하다. 증거: 나부터가 에이전트 메모리 대신 마크다운 파일을 쓰고 있었다.
보관함을 팔면서 기억이라고 부르고 있었던 셈이다. 그리고 보관함의 문제는 용량이 아니다. 보관함은 자기 안의 무엇이 틀렸는지 모른다. 석 달 전의 결정과 어제의 번복이 나란히 꽂혀 있고, 검색은 그 둘을 공평하게 대접한다. 에이전트는 그중 아무거나 집어 들고, 확신에 차서 일한다.
그래서 루프를 닫았다. 에이전트가 기억을 꺼내 쓰고 나면 결과를 라벨하게 했다. 이 기억은 도움이 됐다, 이 기억이 나를 틀리게 만들었다. 그 라벨이 다음 검색의 랭킹으로 흘러 들어간다. 규칙 하나는 처음부터 박았다. 사람이 남긴 명시적 피드백은 에이전트의 라벨이 절대 덮어쓰지 못한다.
말이 되는지는 프로덕션에서 확인했다. 서로 모순되는 사실 두 개를 저장한다. 하나는 낡은 결제사, 하나는 지금 쓰는 결제사. 검색하면 낡은 쪽이 위에 온다. 더 오래, 더 여러 번 적힌 표현이라 질의와 더 닮았기 때문이다. 여기까지가 보관함의 세계다. 이제 에이전트가 컨텍스트를 조립해 일을 하고, 낡은 사실에 harmful 라벨 하나를 남긴다. 재검색: 현행 사실이 1위로 올라오고, 낡은 사실은 0.478에서 0.328로 내려앉는다. 재임베딩도 수동 큐레이션도 없다. 라벨 하나가 순위를 뒤집는다.
그 뒤로는 루프가 알아서 증거를 만들었다. 대화 기록이 전혀 없는 새 세션이 메모리만으로 상황을 브리핑했고 — 일곱 사실, 전부 정확 — 세션 세 개가 기억을 릴레이하며 우리가 못 본 버그 두 개를 찾아 고치고 배포했다. 사람이 한 일은 승인뿐이다. 밝혀 두자면 이 글의 증거는 전부 우리가 우리를 상대로 만든 것이다. 외부 사용자는 아직 거의 없다. 남에게 팔기 전에 우리가 먼저 겪어야 했다.
만들면서 배운 것은 기억의 절반이 망각이라는 사실이다. 무엇을 기억하느냐는 절반이고, 낡은 기억을 언제 어떻게 끌어내리느냐가 나머지 절반이다. 뇌는 이걸 공짜로 한다. 안 쓰는 기억은 흐려지고, 틀렸던 기억은 다음 회상에서 밀린다. 시스템은 이걸 공짜로 얻지 못한다. 누군가 틀렸다고 말해줘야 하고, 그 말이 실제로 다음 인출을 바꿔야 한다. 우리가 라벨을 랭킹에 꽂기 전까지, 우리 시스템의 기억은 늙지 않는 대신 낡아갔다.
Enacta는 Mem0 호환 API로 시작한다. add와 search는 이미 아는 그 모양 그대로다. 루프는 그 위에 있다. 컨텍스트를 조립하면 trace가 남고, 결과를 라벨하면 다음 검색이 바뀐다. 3분이면 순위가 뒤집히는 걸 직접 볼 수 있다. 기억은 쌓이는 게 아니라 증명되는 것이다.
The word memory suggests storage. Drawers, warehouses, archives. But the brain doesn't work that way. Recall is reconstruction, not playback, and a memory is re-evaluated every time it's used. What helped gets consolidated; what misled gets pushed down. The essence of memory is verification, not storage.
Building agent memory, we were betraying this obvious fact in our own code.
We found out the day we plugged our product into our own agent. Dissecting 1,833 auto-saved memories, 93% were junk — raw JSON, transcript fragments, 268 strings that looked like API keys. The saving was diligent; the usefulness was zero. That night I wrote in the diagnosis doc: a memory product that only stores is pointless, files are enough. Evidence: I myself was using markdown files instead of agent memory.
We had been selling a filing cabinet and calling it memory. And a filing cabinet's problem isn't capacity. A filing cabinet doesn't know which of its contents are wrong. A decision from three months ago sits next to yesterday's reversal, and search treats them with perfect fairness. The agent picks either one and works with full confidence.
So we closed the loop. After an agent uses its memories, it labels the outcome: this one helped, this one misled me. Those labels flow into the ranking of the next search. One rule went in from the start — explicit human feedback can never be overwritten by an agent's label.
We checked whether this holds in production. Store two contradicting facts: the old payment provider and the current one. Search, and the stale fact ranks first — it's been written longer and more often, so it resembles the query more. That's the filing cabinet's world. Now the agent assembles context, does its work, and leaves one harmful label on the stale fact. Search again: the current fact rises to first, and the stale one drops from 0.478 to 0.328. No re-embedding, no manual curation. One label flips the ranking.
After that, the loop generated its own evidence. A fresh session with zero conversation history briefed itself from memory alone — seven facts, all correct — and three sessions relayed memories to find, fix, and ship two bugs we had missed. The only human contribution was approval. To be clear: every piece of evidence in this post is something we produced against ourselves. We have almost no outside users yet. Before selling this to anyone, we had to live it first.
What building this taught us is that half of memory is forgetting. What to remember is one half; when and how to pull a stale memory down is the other. The brain does this for free — unused memories fade, and the ones that misled you lose the next recall. A system gets none of that for free. Something has to say "this was wrong," and that word has to actually change the next retrieval. Until we wired labels into ranking, our system's memories never aged. They just went stale.
Enacta starts as a Mem0-compatible API — add and search look exactly like what you already know. The loop sits on top. Assemble context and you get a trace; label the outcome and the next search changes. It takes about three minutes to watch a ranking flip with your own eyes. Memory isn't something you accumulate. It's something you prove.