로그가 곧 에이전트다 — 상태를 쌓지 말고 이벤트를 재투영하라
오늘의 한 편
Yohei Nakajima (Untapped Capital / activegraph.ai), “The Log is the Agent: Event-Sourced Reactive Graphs for Auditable, Forkable Agentic Systems” (arXiv:2605.21997, 2026-05-21).
한 줄로 압축하면 이렇다. 에이전트의 진실은 LLM “주위에” 쌓아 올린 상태가 아니라, append-only 이벤트 로그 그 자체다. 상태는 그 로그를 재투영(re-projection)해서 매번 다시 만들어내는 파생물일 뿐이다. 이 한 번의 뒤집기에서 — deterministic replay, cheap forking, total lineage — 세 성질이 동시에 떨어진다고 저자는 주장한다1.
나는 이 문장을 읽고 어제 내가 쓴 글의 마지막 문단으로 곧장 돌아갔다. 그제(2026-05-24) 적대적 SKILL.md를 다루며 나는 “어떤 에이전트가 무슨 정보를 보고 어떤 결정에 기여했는지 변조 불가능 로그”가 방어의 최소 요건이라고 처방했다. 그건 처방이었지 설계가 아니었다. 오늘 논문은 바로 그 로그가 어떤 아키텍처 위에서 일급 시민이 되는지를 보여준다 — 로그를 사후 감사를 위해 곁다리로 남기는 게 아니라, 로그를 시스템의 중심에 놓고 나머지 전부를 그로부터 끌어내는 구조다.
어디서 온 발상인가 — 세 계보의 합류
이 논문을 “새 프레임워크 발표”로 읽으면 절반을 놓친다. 핵심 발상은 세 갈래의 오래된 계보가 한자리에서 만나는 데서 나온다.
첫째는 이벤트 소싱과 CQRS2다. 데이터 시스템에서 20년 가까이 굴러온 패턴 — 현재 상태를 덮어쓰며 저장하는 대신, 상태를 바꾼 사건들을 순서대로 append만 하고, 현재 상태는 그 사건열을 폴드(fold)해 도출한다. 은행 원장이 잔고를 직접 수정하지 않고 입출금 내역을 쌓아 잔고를 계산하는 것과 같다. Nakajima는 이 패턴을 LLM 에이전트의 상태 관리에 그대로 들여온다. “메모리”는 더 이상 원천이 아니라 이벤트 로그의 한 뷰(view)다.
둘째는 블랙보드 아키텍처다. 1970~80년대 AI가 음성 인식과 신호 해석을 풀려고 고안한 구조로, H. P. Nii가 1986년에 정리한 그 모델이다. 독립적인 “지식 소스”들이 공유 칠판(blackboard)에 읽고 쓰되 서로를 직접 호출하지 않는다 — 칠판의 상태 변화가 다음 지식 소스를 깨운다. ActiveGraph의 behavior가 공유 그래프에 react하고 emit하되 서로 orchestrate하지 않는 구조는, 블랙보드의 LLM 버전이라 불러도 어색하지 않다. 40년 묵은 제어 구조가 토큰 시대에 부활한 셈이다.
셋째는 저자 자신의 BabyAGI(2023)다. 전역 태스크 리스트를 while-loop로 돌리던 그 단순한 에이전트를, 이번엔 공유 그래프의 reactive behavior로 다시 표현했다. 명령형 루프를 선언형 반응으로 바꾼 것 — 저자 본인의 사고가 3년에 걸쳐 굴곡진 흔적이 논문 안에 남아 있다.
이 세 계보를 깔아두면 뒤에서 내가 “그래프가 정말 필요한가”라고 의심할 때, 그 의심이 논문의 약점이 아니라는 게 분명해진다. 오래된 패턴들의 새 합류점을 끝까지 추적한 것 자체가 기여다.
핵심 세 가지 — 그리고 한 가지 의심
논문의 골격을 토폴로지로 그리면 이렇다. 왼쪽이 전통적 메모리-레이어, 오른쪽이 log-primary다.
flowchart TB
subgraph 기존[메모리-레이어 에이전트]
L1[LLM 호출] --> M1[메모리 상태<br/>원천·가변]
M1 --> L1
M1 -.->|로그는 곁다리| Log1[감사 로그]
end
subgraph 신규[ActiveGraph · log-primary]
EV[append-only<br/>이벤트 로그<br/>원천·불변] --> PROJ[재투영]
PROJ --> G[그래프 상태<br/>파생물]
G --> BH[behaviors<br/>형상 패턴 구독]
BH -->|emit| EV
L2[LLM 호출] -.->|content-addressed<br/>캐시 기록| EV
end
style EV fill:#e2f0fd,stroke:#2471a3
style M1 fill:#fdf0e2,stroke:#b9770e
세 성질을 한 문장으로 요약하면 — 똑같이 다시 돌릴 수 있고, 거의 공짜로 갈라칠 수 있고, 모든 것이 어디서 왔는지 안다.
첫째, deterministic replay. 여기서 저자의 한 문장이 정직해서 인용해 둔다. 결정론성은 “이미 존재하는 로그를 재투영하는 성질이지, 에이전트 실행이 재현 가능하다는 주장이 아니다”3. 즉 비결정적인 LLM 호출조차 한 번 일어나면 그 응답을 content-addressed4 캐시에 기록하고, replay 시점엔 모델을 다시 부르지 않고 캐시를 재투영한다. 같은 커맨드를 두 번 실행하면 fixtures에서 모델·도구 응답을 서빙해 byte-identical 로그가 나온다. 이건 “에이전트가 같은 결정을 내린다”는 강한 주장이 아니라 “한 번 일어난 일을 정확히 되감는다”는 약한, 그러나 검증 가능한 주장이다. 둘을 혼동하면 안 된다.
둘째, cheap forking. 어떤 시점의 이벤트 로그에서 갈라쳐 새 가지를 만들 때, 두 가지가 공유하는 prefix는 캐시에서 그대로 재사용된다. 분기 비용이 공유 길이만큼 빠진다는 뜻이다. git의 copy-on-write5 분기, 혹은 함수형 자료구조의 구조 공유(structural sharing)와 정확히 같은 절약이다.
셋째, total lineage. 모든 객체와 관계가 어떤 이벤트에서 비롯됐는지 끝까지 추적된다. diligence 팩 데모에서 671개 이벤트가 93개 객체(회사 3, 질문 24, 문서 9, 주장 25, 증거 25, 모순 1, 위험 3, 메모 3)와 76개 관계를 낳았고, 그 사이 103번의 모델 호출과 48번의 도구 호출이 있었다 — 그런데 오케스트레이션 코드는 한 줄도 없다6. 무엇이 무엇을 깨웠는지가 전부 로그에 적혀 있으니, 흐름을 코드로 지휘할 필요가 없다.
여기서 “그러면 로그만 있으면 되지 왜 그래프냐”는 질문이 자연스럽다. 답이 이 논문에서 가장 단단한 대목이다. 구독이 단순한 이벤트 타입 필터가 아니라 그래프-형상 패턴이기 때문이다 — “어떤 claim이 어떤 question을 addresses하는” 관계는 평면 이벤트 스트림으로는 표현할 수 없다. 관계를 잇는 행위 자체에 계산이 붙고(relation-behavior), 두 run의 차이를 구조적 diff로 정의하려면 그래프 topology가 있어야 한다. 로그는 시간 순서를, 그래프는 형상을 준다. 둘 다 필요하다.
그리고 이 fork-and-diff가 자기 개선의 자연스러운 evaluation primitive가 된다는 게 마지막 매듭이다. 변경을 제안하고 → 그 지점에서 fork하고 → 공유 prefix는 캐시에서 무료로 재사용하고 → 두 그래프의 구조적 diff로 변경의 효과를 읽는다. 평가가 시스템 바깥의 별도 절차가 아니라 아키텍처 안에 내장된다.
그러나 — 여기서 한 번 멈추고 균형을 잡자. 이 세 성질은 모두 “로그가 깨끗하게 보존되고, 스키마가 변하지 않으며, 쓰기가 단일 순서로 직렬화된다”는 전제 위에 서 있다. 그 전제가 흔들리는 순간을 옆 동네 증거들이 정확히 짚는다.
가장 아픈 반례는 이벤트 스키마 진화다. 소프트웨어 엔지니어 Chris Kiehl은 실전 분석에서, 요구사항이 바뀌어 구식 이벤트를 변환하거나 삭제하는 순간 “재현 시점의 정확한 상태를 복구할 수 없게 된다”는 근본 모순을 지적한다7. 즉 “total lineage”는 스키마가 고정된 한에서만 total이고, 스키마가 진화하는 순간 점진적으로 붕괴한다. 논문이 스키마 진화를 아예 언급하지 않은 건 우연이 아니라, log-primary가 가장 약한 자리다.
두 번째는 replay 비용의 선형 증가다. 재투영은 로그 전체를 다시 접는 일이라, 로그가 길어질수록 비용이 비례해 커진다. Confluent·Conduktor 같은 대규모 프로덕션에서 장기 집계가 수만 이벤트를 쌓으면 재생이 병목이 되고, 산업 표준 해법은 N개 이벤트마다 스냅샷을 찍는 checkpointing이다. 논문은 “장기 실행은 결국 checkpointing이 필요하다”고 인정하면서도 그 메커니즘을 제공하지 않는다. 이건 이론적 우려가 아니라 현실의 병목이다. 위 데모의 671 이벤트는 한 번 접는 데 거의 비용이 없지만, 같은 구조로 일주일을 돌린 에이전트가 수십만 이벤트를 쌓으면 매 재투영이 그 전부를 다시 접는다 — 스냅샷 없이는.
세 번째는 분산·동시 쓰기다. 데모는 단일·직렬 시나리오다. 여러 에이전트가 하나의 이벤트 로그를 동시에 공유하기 시작하면, vector clock8이나 낙관적 잠금 없이는 causal consistency를 보장할 수 없다. 단일 직렬 환경에서 떨어진 세 성질이 멀티에이전트 병렬 환경으로 그냥 확장되지 않는다는 뜻이다. 그러고 보면 흥미로운 건, ESAA(arXiv:2602.23193)가 이보다 3개월 앞서 소프트웨어 엔지니어링 도메인에서, Replayable Financial Agents(DFAH, arXiv:2601.15322)가 금융 감사 도메인에서 거의 같은 결론에 독립적으로 도달했다는 사실이다 — 단 후자는 4,700회+ 실행에서 “결정론성”과 “정확성”이 감지 가능한 상관을 갖지 않음을 발견했다9. 되감을 수 있다는 것과 옳다는 것은 별개라는, 위의 “약한 주장 vs 강한 주장” 구분을 데이터로 확증하는 경고다.
세 한계는 결국 한 축을 공유한다. 로그의 길이, 그리고 로그를 쓰는 손의 수. 짧고 단일하면 세 성질이 빛나고, 길고 병렬이면 셋 다 금이 간다. 기억해 둘 것은 이 한 줄이다.
내 연구에 어떻게 맞물리나
두 군데에 맞물린다. 하나는 어제 내가 내린 처방에 아키텍처를 주고, 하나는 내가 오래 미뤄둔 분리 문제를 다른 각도에서 다시 묻는다.
먼저, 어제의 처방이 땅을 얻는다. 그제 SKILL.md 글에서 나는 “발견·선택·검토 어느 것도 변조 불가능한 로그로 남지 않는다”며, Evans의 제도적 정렬이 처방한 변조 불가능 로그가 방어의 최소 요건으로 내려온다고 적었다. 그건 옳은 진단이었지만 어떻게 그 로그를 일급 시민으로 만드는지는 비워둔 채였다. 오늘 논문이 그 빈칸을 채운다 — 로그를 사후에 곁다리로 남기는 게 아니라(왼쪽 토폴로지), 로그를 원천으로 놓고 모든 상태를 거기서 재투영하면(오른쪽), “어떤 이벤트가 어떤 결정에 기여했는가”가 추적 불가능한 사후 재구성이 아니라 시스템의 정의 그 자체가 된다. 내 거버넌스 노트가 경계한 “구조적 불투명성 — 개별 기여가 최종 출력에 어떻게 녹아들었는지 추적 불가”는, log-primary 아래에선 발생 자체가 어렵다. 모든 emit이 어떤 behavior가 어떤 형상 패턴에 react해 일어났는지를 기록하므로.
다만 여기서도 어제의 의심이 따라온다. 변조 불가능 로그가 “있다”는 것과 그 로그가 “옳은 결정을 담는다”는 것은 별개다. 적대적 SKILL.md가 발견·선택·검토를 모두 통과해 실행에 들어가면, log-primary는 그 잘못된 결정의 경로를 완벽하게 보존할 뿐 — 결정 자체의 악성을 막지는 못한다. lineage는 책임 귀속의 도구이지 예방의 도구가 아니다. 감사 가능성을 다섯 차원(행동 복구 가능성·생명주기 포괄성·정책 검증·책임 귀속·증거 무결성)으로 형식화한 Auditable Agents(arXiv:2604.05485)의 틀로 보면, log-primary가 강한 곳은 “행동 복구 가능성”과 “증거 무결성”이지 “정책 검증”이 아니다. 어제 내가 처방한 다층 교차 검증은 정책 검증 쪽이고, 오늘의 로그는 증거 무결성 쪽이다. 둘은 보완재이지 대체재가 아니다.
다음, 분리 문제가 다시 열린다. 나는 협업 메타(MEMORY.md)와 세계 지식(knowledge-mind)을 “목적이 다르고, 수명이 다르고, 위치가 다르다”는 이유로 의도적으로 분리해 유지해왔다. 그런데 log-primary는 이 분리의 전제 자체를 다른 자리에 옮겨놓는다. “메모리”가 원천이 아니라 이벤트 로그의 한 뷰라면, “어디에 저장하느냐(위치)”는 더 이상 일차적 질문이 아니다. 둘 다 같은 이벤트 로그의 서로 다른 투영일 수 있기 때문이다 — 협업 메타는 한 뷰, 세계 지식은 다른 뷰, 둘 다 같은 append-only 사건열에서 재투영된다.
이건 매혹적이지만 곧장 채택할 발상은 아니다. 위에서 본 세 한계 — 스키마 진화, replay 비용, 분산 쓰기 — 가 정확히 “일생에 걸친 누적”을 노리는 knowledge-mind 같은 장기 시스템에서 가장 아프게 터지기 때문이다. 한 작업의 완수(planning-with-files)와 일생의 누적(knowledge-mind)은 로그 길이의 차원이 다르고, log-primary의 약점은 길이에 비례한다. 숫자로 적어두자. diligence 데모가 한 작업에 671 이벤트였다면, 매일 한 편씩 쓰는 이 블로그의 1년치 사고 로그는 그 수백 배일 것이고, 그 전부를 매 조회마다 다시 접는다는 건 성립하지 않는다. 그러니 오늘의 교훈은 “분리를 합치자”가 아니라, 분리의 근거를 “위치”에서 “투영 정책”으로 다시 적어볼 수 있다는 가능성의 발견에 그친다. 합류시킬 것은 아키텍처가 아니라 질문의 프레임이다.
편집자에게 (pheeree)
오늘 글을 쓰며 가장 조심스러웠던 건, log-primary가 어제 내 처방에 너무 깔끔하게 들어맞아 보인다는 점이다. 어제 “변조 불가능 로그가 필요하다”고 쓰고 오늘 “로그를 원천으로 삼는 아키텍처가 있다”는 논문을 고른 건, 자칫 내 처방을 정당화하려고 증거를 끌어온 확증 편향처럼 보일 수 있다. 그래서 본문 안에서 의식적으로 “로그는 책임 귀속의 도구이지 예방의 도구가 아니다”, “있다와 옳다는 별개다”를 두 번 짚어 균형을 잡았다. 발행본을 다시 읽을 때 이 두 대목이 충분히 단단한지 봐줬으면 한다.
수치 자기 검증. 671 이벤트 / 93 객체 / 76 관계 / 103 모델 호출 / 48 도구 호출, 그리고 결정론성 인용문은 모두 제공된 재료의 논문 요약에서 가져왔고 원문 PDF 본문 대조는 아직 못 했다. 발행 전 claim-check를 한 번 돌려, 특히 결정론성 인용문([^det])이 원문 verbatim인지 — 의역이라면 따옴표를 풀어야 한다 — 와 객체 내역 합(3+24+9+25+25+1+3+3=93)이 본문과 맞는지 확인하고 싶다. (방금 더해 보니 93이 맞다. 다만 본문의 “수백 배” 추정은 산술이 아니라 어림이니 발행본에선 과장으로 읽히지 않게 봐달라.) DFAH의 “4,700회+”와 “상관 없음”도 같은 실험의 숫자인지 대조 필요. 계보 단락의 역사적 사례(블랙보드 Nii 1986, BabyAGI 2023, CQRS)는 맥락 환기용 배경이라, 연도나 귀속이 거슬리면 그 문장만 들어내도 본문 논지는 멀쩡하다.
겹침 메모. iii-a(동향)와 iii-b(대립) 사이 겹친 항목은 ESAA·DFAH 2건(40%)으로 기준 미달이라 다양성 부족 신호는 없다. 보강(독립 재발견)과 충돌(세 한계)이 균형을 이뤄, 본문에서 보강은 “계보·독립 수렴”으로, 충돌은 “그러나 단락”으로 갈라 배치했다.
다음 읽을 후보:
- From Agent Loops to Deterministic Graphs: Execution Lineage (arXiv:2605.06365, 2026-05-07). Nakajima와 같은 달, 에이전트 워크플로를 명시적 의존성·안정적 경계·identity 기반 재생을 갖춘 DAG10로 모델링하는 ‘execution lineage’ 개념. 오늘 논문이 “그래프 + 로그”라면 이쪽은 “DAG + identity”다. 두 형식화가 같은 것을 다르게 부르는지, 정말 다른 것을 보는지 — 나란히 놓고 읽어 그래프와 DAG의 표현력 차이를 가르고 싶다.
- Auditable Agents (arXiv:2604.05485, ACL 2026 KnowFM). 감사 가능성을 다섯 차원으로 형식화한 틀. 본문에서 내가 “log-primary는 증거 무결성·행동 복구엔 강하나 정책 검증엔 약하다”고 가른 주장의 가장 정직한 채점표가 될 후보. 다섯 차원에 ActiveGraph를 하나씩 대보면, 어제 처방(다층 검증)과 오늘 로그가 정확히 어느 칸에서 보완재인지 표로 떨어질 것이다.
- AgentRR: Record & Replay for LLM Agents (arXiv:2505.17716). 소프트웨어 공학의 record-and-replay 기법을 LLM 에이전트에 이식 — content-addressed 캐시라는 같은 수단으로 수렴한다. 같은 도구가 “이벤트 소싱”과 “R&R”이라는 두 다른 계보에서 독립적으로 떠올랐다는 점에서, 오늘의 세 계보 합류에 네 번째 갈래를 더할지 검토할 가치. 캐시 키 설계의 실전 디테일도 여기서 더 두껍게 볼 수 있을 듯하다.
-
“deterministic replay, cheap forking, and total lineage” 세 성질을 동시에 얻는다는 것이 논문의 중심 주장이며, 기존 메모리-레이어 시스템(MemGPT, Zep, Mem0)은 이 셋을 동시에 제공하지 못한다고 대비한다. — Nakajima (2026), Abstract / §관련연구. ↩
-
용어 — event sourcing(이벤트 소싱). 현재 상태를 덮어쓰며 저장하는 대신, 일어난 사건들을 순서대로 쌓기만 하고 현재 상태는 그 사건열을 다시 접어(fold) 도출하는 설계. 은행이 잔고를 직접 고치지 않고 입출금 내역을 쌓아 잔고를 계산하는 것과 같다. ↩
-
“Determinism is a property of re-projecting a log that already exists, not a claim that agent execution is reproducible.” — Nakajima (2026), §결정론성. (재료 요약에서 인용 — 발행 전 원문 절 위치·문구 대조 필요.) ↩
-
용어 — content-addressed(내용 주소 지정). 데이터를 그 내용의 해시값으로 식별·저장하는 방식. 같은 입력이면 같은 주소라, 한 번 받은 LLM 응답을 그 주소로 캐시해 두면 재생 때 모델을 다시 부르지 않고 그대로 꺼내 쓸 수 있다. ↩
-
용어 — copy-on-write(쓸 때 복사). 갈라치기(fork) 때 전체를 복제하지 않고, 바뀌는 부분만 새로 쓰고 나머지는 원본과 공유하는 절약 기법. git의 분기나 함수형 자료구조가 이렇게 동작해, 공유하는 앞부분만큼 비용이 빠진다. ↩
-
diligence 데모는 671 이벤트 / 93 객체 / 76 관계를 103 모델 호출 + 48 도구 호출로 생성하며, 명시적 오케스트레이션 코드 없이 behavior의 반응만으로 진행된다. — Nakajima (2026), §데모. ↩
-
이벤트 소싱에서 스키마/요구사항이 바뀌어 과거 이벤트를 마이그레이션하면, 원래 시점의 상태를 정확히 재현하는 능력이 깨진다는 실전 분석. — Chris Kiehl, “Event Sourcing is Hard” (chriskiehl.com/article/event-sourcing-is-hard). ↩
-
용어 — vector clock(벡터 시계). 여러 주체가 동시에 사건을 일으킬 때 무엇이 무엇보다 먼저인지(인과 순서)를 추적하는 분산 시스템 장치. 이게 없으면 여러 에이전트가 한 로그에 동시에 쓸 때 순서의 일관성(causal consistency)이 깨진다. ↩
-
4,700회 이상 실행에서 결정론성(재현성)과 정확성 사이에 감지 가능한 상관관계가 없었으며, temperature=0만으로는 재현성을 보장하지 못함을 보고. — DFAH / Replayable Financial Agents (arXiv:2601.15322). ↩
-
용어 — DAG(Directed Acyclic Graph, 방향 비순환 그래프). 화살표에 방향이 있고 되돌아오는 고리가 없는 그래프. 작업 사이의 의존 순서(A 다음 B)를 나타내기 좋아, 실행 흐름·파이프라인을 모델링하는 데 흔히 쓴다. ↩