두 에이전트와 하나의 지갑: 중복 지출을 방지하는 메모리 그래프
요약
본 글은 두 AI 에이전트가 동일한 지출 권한을 가질 때 발생할 수 있는 중복 지출 문제를 해결하는 'Permit 메모리 그래프'를 소개합니다. 이 시스템은 공유 상태(FalkorDB)에 노드와 엣지를 사용하여 모든 지출과 클레임을 기록하고, 에이전트 간의 협업 및 권한 관리를 가능하게 합니다.
핵심 포인트
- 공유 메모리 그래프는 에이전트 간 중복 지출을 방지합니다.
- 노드/엣지는 에이전트, 권한, 영수증 등 핵심 정보를 구조화합니다.
- 그래프 쿼리는 단순 로그가 아닌 출처(provenance) 기반의 명확한 거절 사유를 제공합니다.
문제점
두 AI 에이전트에게 동일한 지출 권한을 부여하면, 언젠가 같은 것을 두 번 결제하게 됩니다. 부주의해서가 아니라, 어느 쪽도 상대방이 방금 무엇을 했는지 볼 수 없기 때문입니다. 각 에이전트의 메모리는 자체 컨텍스트 창에서 끝납니다.
Permit은 에이전트를 위한 나의 지불 권한 계층(payment-authority layer)입니다: 모든 결과에 영수증(receipted)과 함께 범위가 지정되고 취소 가능한 지출 권한을 제공합니다. Graph Hacks를 위해 저는 더 좁은 질문을 했습니다: 만약 에이전트 간의 _협업(coordination)_이 둘 다 행동하기 전에 질의하는 그래프 안에 존재한다면 어떨까?
내가 구축한 것
Permit 메모리 그래프. FalkorDB가 공유 상태를 보유합니다:
- 노드(Nodes): 에이전트, 권한(permits), 클레임(claims), 상점(merchants), 영수증(receipts)
- 엣지(Edges): 누가 어떤 권한을 가지고 있는지, 누가 어떤 범위를 주장했는지, 무엇이 결정되었고 그 이유가 무엇인지
어떤 지출이 발생하기 전에, 에이전트는 그래프에 세 가지 질문을 합니다: 이 범위는 이미 클레임된 적이 있습니까? 이 권한은 아직 유효합니까? 지난 에이전트가 이 상점에 대해 배운 것은 무엇입니까?
세 단계로 보는 데모
- 에이전트 A가 공유된 500달러의 권한 풀(permit pool)을 대상으로 클라우드-GPU에 120달러를 지출합니다. 그래프는 이 클레임을 기록합니다.
- 에이전트 B가 같은 지출을 시도하며 — 먼저 그래프에 질문합니다. 그래프는 A의 클레임을 발견하고 거부합니다: 중복 범위(duplicate scope), 이미 클레임됨, 클레임 ID를 출처(provenance)로 인용하여 명시합니다.
- 권한 노드를 취소하면, 두 에이전트 모두 안전하게 실패(fail closed)합니다. 유효 권한 없음, 지출 없음, 예외 없음.
실제 FalkorDB 백엔드에서 데모 그래프는 9개의 노드 / 11개의 엣지에서 끝납니다; 최종 감사된 스위트(audited suite)는 17/17 슬라이스 테스트와 5/5 Falkor 기반 테스트를 통과합니다. 운영상의 교훈은 하나, 정직한 방식으로 배운 것입니다: 매번 실행 전에 그래프를 정리해야 합니다. 오염된 그래프에서 두 번째 실행도 여전히 통과하지만 카운트가 표류합니다 (13 노드 / 19 엣지) — 오래된 상태(stale state)는 조용히 거짓말을 하므로, 실행 매뉴얼은 항상 먼저 지우도록 합니다.
그래프가 제공하는 가치
그래프가 제공하는 것은 무엇일까요?
영수증이 있는 거절은 어깨를 으쓱하는 거절보다 낫다. Agent B가 '아니요'라고 말할 때, 어떤 주장 노드(claim node) 때문에 그렇게 말했는지 정확히 지적할 수 있다. 바로 그 출처(provenance)—결정, 증거, 엣지—가 나의 Permit 작업의 핵심 논제이며, 그래프는 이를 로그 파일이 아닌 쿼리로 만든다.
벤치마크: 내가 이미 수정했던 버그를 기준으로 측정하기
데모는 데모가 작동한다는 것을 증명한다. 그래서 나는 더 까다로운 테스트를 실행하기 전에 고정했다: Permit의 자체 역사에서 가져온 일곱 건의 사고—실제 문제와 수정 사항, 각각 병합된 PR(Pull Request) 기록이 있다—을 그래프 내 시나리오로 재구성했다. 내가 미리 작성한 각 사례에 대해, 두 번째 에이전트가 그래프에게 물어볼 질문과 Permit의 수정 사항이 보장하는 답변을 적었다. 그리고 그것들을 실제 FalkorDB 백엔드에서 실행하여 그래프가 답하게 했다.
첫 번째 실행: 7개 중 4개. 그런 다음 놓쳤던 세 가지를 수정하고 동일한 고정 세트를 다시 실행했다: 7개 중 7개. 두 번의 실행은 로그에 기록되어 있으며, 각각이 무엇을 보여줬는지 여기에 제시한다.
네 가지 통과 사례는 조정(coordination)의 핵심이다: 허가(permit)가 진행 도중에 취소된 후 시도된 지출은 안전하게 실패하고; 그래프는 어떤 에이전트가 먼저 지출을 주장했는지 이름을 밝히고, 두 번째 에이전트의 거절은 그 정확한 주장 ID를 인용하며; 거절 자체는 이유를 포함하여 기록에 남고; 허가를 취소하는 것은 이를 '활성'으로 남겨두지 않고 진행 중인 주장을 무효화한다.
첫 번째 실행에서 놓쳤던 세 가지 사례 역시 마찬가지로 구체적이며, 나는 그것들을 완곡하게 표현하지 않을 것이다:
- 누적 한도(Cumulative caps). 두 에이전트가 각각 하나의 500달러 한도에 대해 300달러씩 청구했는데, 서로 다른 상점에서 발생했습니다. 총 청구액은 600달러였고, 그래프는 이 모든 것을 허용했습니다. 이는 단일 청구만 한도와 비교했을 뿐, 이미 청구된 금액을 합산하지 않았습니다. Permit 자체는 이를 거부합니다 (원자적 동시성 한도, PR #20); 그래프 슬라이스는 그러한 보장을 갖지 못했습니다.
- 만료(Expiry). 만료 시간이 이미 지난 허가증이 여전히 성공적으로 사용되었습니다. 슬라이스는 만료 타임스탬프를 읽지 않았습니다. Permit은 출시 시점에 만료 시간을 강화했습니다 (PR #29); 그래프는 이를 강제하지 못했습니다.
- 충돌 생존(Crash survival). 서버를 종료했다가 다시 시작했습니다. 그래프는 비어 있게 되었습니다. 모든 청구의 출처 기록이 사라진 것입니다. 데모용으로 구성했기 때문에, 스토어는 휘발성이었습니다. Permit의 충돌 복원 내구성(PR #26)은 유지되지 않았습니다.
그래서 저는 정확히 이 세 가지를 수정했습니다. 이제 입장은 활성 청구액을 한도와 합산하고, 허가증은 입장이 실제로 읽는 만료 시간을 가지고 있으며, 서버는 영구적인 추가 전용 스토어(durable append-only storage)로 실행됩니다. 각 수정 사항에 대해 테스트 케이스를 하나씩 추가하여 (이제 9/9), 동일한 일곱 가지 사례를 이전과 같은 예상 답변으로 다시 실행했습니다. 두 번째 실행: 7개 중 7개 — 누적 한도와 관련하여 두 번째 300달러 청구는 거부되었고, 만료된 허가증은 거부되었으며, 종료 후 재시작했음에도 그래프는 누가 무엇을 청구했는지 여전히 알고 있었습니다.
이것이 이 시스템의 정직한 모습입니다. 즉, 그래프는 자신이 답변하도록 설계된 모든 질문에 답했습니다. 누가 무엇을 청구했고, 무엇이 결정되었으며, 무엇이 취소되었는지 말입니다. 그리고 벤치마크는 슬라이스가 아직 갖추지 못했던 세 가지 Permit 보장을 찾아냈습니다. 그것들을 수정하고 변경되지 않은 세트를 기준으로 재측정하는 것이 이 시스템을 가진 전체 목적입니다. 이미 통과하는 것만 포함된 벤치마크는 벤치마크가 아닙니다. (고정된 세트와 전체 측정 로그는 프로젝트에 함께 제공됩니다.)
다음에 할 일
세션 전반에 걸쳐 상점 평판을 유지하여 '이전 에이전트가 이 상점에 대해 무엇을 배웠는가?'라는 질문이 단일 데모 실행보다 더 긴 메모리를 갖도록 하고, 중복 청구 거부 시 실제 영수증 체인을 포함하는 Permit의 라이브 게이트에 그래프 검사를 연결합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기