그래프를 이용한 자금 추적: FalkorDB 기반 LedgerLens 구축기
요약
본 글은 그래프 데이터베이스인 FalkorDB를 활용하여 복잡하게 얽힌 재정 흐름과 위험 신호를 추적하는 에이전트 'LedgerLens' 구축 과정을 다룹니다. 이 시스템은 단순한 스프레드시트를 넘어, 관계(Relationship) 속에 숨겨진 비정상적인 자금 이동 경로와 패턴을 Cypher 쿼리를 통해 찾아냅니다.
핵심 포인트
- 그래프 DB는 복잡한 재정 관계 추적에 최적화되어 있습니다.
- Cypher 쿼리 기반의 다단계 탐색으로 위험 신호를 포착합니다.
- LLM은 요약만 담당하며, 데이터 검증은 반드시 원본 쿼리 결과가 필요합니다.
- 미끼(decoys)를 심어 시스템의 정확도와 견고성을 테스트했습니다.
합성 데이터. 비난이 아닌 위험 신호.
당신이 방금 주거 공동체의 회장이 되었다고 상상해 보세요. 그리고 아주 간단한 질문을 던집니다. "우리 예비 기금은 어디로 갔나요?" 스프레드시트에서는 그 답이 수많은 행의 벽으로 나타납니다. 하지만 진짜 이야기는 어느 한 줄에 있는 것이 아닙니다. 그것은 행들 사이의 관계 속에 있습니다. 돈을 절대 내지 않는 친척, 매년 재개되는 공사비 명목으로 계속 비용을 받는 보수 업체, 두 회사를 거쳐 외부 신탁 계좌로 흘러 들어가는 이체 기록 등입니다. 바로 이런 종류의 문제에 그래프가 적합하며, 저는 FalkorDB에서 이러한 숨겨진 연결 고리들을 추적하여 공동체의 재정을 조사하는 에이전트인 LedgerLens를 만들었습니다.
제가 이야기를 구성한 배경
저는 완전히 합성된 데이터셋(실제 사람이나 실제 돈은 없음)을 작성하고 여기에 하나의 시나리오를 심어 놓았습니다.
- 전임 회장의 친척들은 15개월에서 24개월 동안 미납되었거나 면제된 관리비가 있으며, 다른 모든 사람은 추가 부담금을 납부합니다.
- SH-Group이라는 업체는 계속해서 비용을 받지만, 같은 불만 사항들이 재발합니다: 누수 9건, 엘리베이터 고장 8건, 복도 조명 문제 6건.
- 총액 4억 원에 달하는 여덟 건의 이체 기록이 오직 비밀 장부에서만 기록되었고, 예비 기금에서 SH-Group으로, 그리고 페이퍼 컴퍼니를 거쳐 외부 신탁 계좌로 이동했습니다.
- 두 세트의 사람과 회사가 조용히 주소를 공유하고 있습니다.
- 정족수 없이 열린 회의에서 하나의 계약이 승인되었고, 또 다른 면제는 아예 회의가 없었습니다.
저는 또한 에이전트가 플래그를 지정해서는 안 되는 **미끼(decoys)**도 심어 놓았습니다: 적절하게 승인된 의료 면제 기록, 제때 돈을 내는 친척, 연결 고리가 없는 평범한 연체자, 그리고 정직한 업체입니다. 모든 것을 플래그하는 도구는 쓸모가 없기 때문에, 이 미끼들이 저의 정확도 테스트였습니다.
FalkorDB가 실제로 작동하는 방식
이 그래프에는 약 1,200개의 노드와 1,350개의 관계(사람, 세대, 청구서, 업체, 이체 기록, 회의, 결정 등)가 있습니다. 모든 위험 신호는 Python 로직이 아닌 Cypher 쿼리입니다:
- 전임 대통령으로부터
RELATIVE_OF|FRIEND_OF를 거쳐 일반 토지 소유주에게로 이동하는 다단계 탐색(Multi-hop traversal)과 청구서 건수 결합. - 예비 기금(Reserve Fund)에서 신탁(Trust)으로의
SENT및RECEIVED_BY이체에 따른 최단 경로(shortestPath). - 승인 결정이 없는 비밀 장부(secret ledger)에 기록된 이체에 대한 패턴 매칭(Pattern matching).
- 거래처별 반복되는 불만 사항을 찾기 위한
REOPENS체인에 대한 집계(Aggregation overREOPENSchains). - 사람과 회사 간의 공유 주소 매칭(Shared-address matching).
- 회의 기록이 없거나 정족수(quorum)가 없는 결정을 찾는 OPTIONAL MATCH.
LLM (Groq)은 요약문을 작성하지만, 쿼리가 반환하는 행만 볼 수 있습니다. 이 앱은 모든 Cypher 쿼리와 그 결과를 "어떻게 도달했는지(How it got there)" 섹션에 보여주므로 사람이 각 주장을 검증할 수 있습니다. 만약 FalkorDB가 제거된다면, 말할 것이 아무것도 남지 않을 것입니다.
무엇이 잘못되었고 (그리고 제가 배운 것)
1. 첫 번째 쿼리가 미끼를 포착했습니다. "숨겨진 수혜자(hidden beneficiaries)" 쿼리는 제때 납부하는 대통령의 사촌을 36건의 "미납" 청구서와 함께 나열했습니다. 저는 청구서 status 필드를 필터링했는데, 이는 제 데이터와 일치하지 않았습니다. 이를 납부 금액으로 변경하자 문제가 해결되었습니다. 교훈: 미끼는 행복한 경로 테스트(happy-path test)로는 절대 발견할 수 없었던 버그를 포착했습니다.
2. shortestPath에는 규칙이 있습니다. 저는 많은 Cypher 예제에서처럼 MATCH p = shortestPath(...)를 작성했지만, FalkorDB는 이것이 WITH 또는 RETURN 내부에서만 지원된다고 알려주었습니다. 이를 WITH shortestPath(...) AS p로 옮기자 문제가 해결되었습니다. 문서에 한 줄의 메모가 초보자들에게 도움이 될 것입니다.
3. 모델에게 무엇을 볼지 결정하게 두지 마십시오. 제가 사용한 첫 번째 에이전트는 LLM이 어떤 도구를 호출할지 선택하도록 했고, 제가 사용한 모델은 종종 하나의 쿼리 후에 멈추는 경향이 있었습니다. 저는 설계를 변경하여 모든 쿼리가 항상 실행되도록 하고, 모델은 요약만 하도록 했습니다. '에이전트적(agentic)' 유연성은 줄었지만, 증거의 신뢰도는 훨씬 높아졌습니다.
4. 단어 선택이 중요하다. 모델에게 "검토할 가치가 있는 위험 신호(risk signals worth review)"만 보고하고 누구도 비난하지 않도록 지시했습니다. 이 지시가 없었기 때문에 모델은 "kick-backs"와 같은 단어를 사용하기 시작했습니다. 실제 세계의 신뢰에 관한 도구에서, 어조(tone)는 제품의 일부입니다.
핵심 요점 (Takeaways)
- 질문이 행(rows)에 관한 것이 아니라 연결(connections)에 관한 것일 때 그래프가 빛을 발합니다.
- 미끼(decoys)를 심는 것은 조사 도구가 정직한지 테스트하는 가장 저렴한 방법입니다.
- 답변 옆에 쿼리(query)를 보여주는 것이 자신감 있는 요약보다 더 많은 신뢰를 구축합니다.
- FalkorDB는 시작하기가 쉬웠습니다. 단 하나의 Docker 명령어로 브라우저에서 Cypher를 실행할 수 있었습니다.
저는 이 프로젝트를 Graph Hacks 해커톤을 위해 약 이틀에 걸쳐 만들었으며, Claude의 도움으로 코드의 상당 부분을 작성했습니다. 디자인 결정은 제가 했고, 모든 것을 실행하고 결과를 저의 자체 정답지와 비교하여 확인했습니다.
코드: https://github.com/shrutisharma-sh/LedgerLense
데모 영상:
Graph Hacks를 위해 제작됨: AI 에이전트를 위한 맥락(Context for AI Agents) (FalkorDB), 트랙 01.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기