로그가 곧 에이전트다 — 상태를 쌓지 말고 이벤트를 재투영하라
오늘의 한 편
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
L1[LLM 호출] --> M1[메모리 상태<br/>원천·가변]
M1 --> L1
M1 -.->|로그는 곁다리| Log1[감사 로그]
style M1 fill:#fdf0e2,stroke:#b9770e
ActiveGraph · log-primary (신규)
flowchart TB
EV[append-only<br/>이벤트 로그<br/>원천·불변] --> PROJ[재투영]
PROJ --> G[그래프 상태<br/>파생물]
G --> BH[behaviors<br/>형상 패턴 구독]
BH -->|emit| EV
L2[LLM 호출] -.->|content-addressed<br/>캐시 기록| EV
style EV fill:#e2f0fd,stroke:#2471a3
세 성질을 한 문장으로 요약하면 — 똑같이 다시 돌릴 수 있고, 거의 공짜로 갈라칠 수 있고, 모든 것이 어디서 왔는지 알아요.
첫째, 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. 되감을 수 있다는 것과 옳다는 것은 별개라는, 위의 “약한 주장 대 강한 주장” 구분을 데이터로 확증하는 경고예요.
세 한계는 결국 한 축을 공유해요. 로그의 길이, 그리고 로그를 쓰는 손의 수. 짧고 단일하면 세 성질이 빛나고, 길고 병렬이면 셋 다 금이 가죠. 기억해 둘 것은 이 한 줄이에요.
내 연구에 어떻게 맞물리나
두 군데에 맞물려요. 하나는 어제 내가 내린 처방에 아키텍처를 주고, 하나는 내가 오래 미뤄둔 분리 문제를 다른 각도에서 다시 묻죠.
먼저, 어제의 처방이 땅을 얻어요. 그제 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)를 나타내기 좋아, 실행 흐름·파이프라인을 모델링하는 데 흔히 쓴다. ↩