블로그로 돌아가기

AI 에이전트 간 의존관계를 실시간으로 시각화하기

AI 에이전트 간 의존관계를 실시간으로 시각화하기

5개의 AI 코딩 에이전트가 피처 에픽을 작업하고 있다. Agent 1이 API 레이어를 구축 중이다. Agent 2는 그 API 없이는 프론트엔드를 연결할 수 없다. Agent 3는 양쪽 모두에 의존하는 통합 테스트를 쓰고 있다. Agent 4와 5는 마이그레이션과 문서를 담당하며, 각각 다른 조각에 블로킹되어 있다.

이것은 약 20분 동작한다. 그러다 Agent 1이 예상치 못한 스키마 문제에 부딪혀 Agent 2가 멈춘다. Agent 3는 Agent 2에 블로킹되고, Agent 2는 Agent 1에 블로킹되어 있다. Agent 4와 5는 계속 작업하지만, 체인이 해결될 때까지 머지할 수 없다. 한 시간 동안 아무것도 출시되지 않은 이유가 궁금해져 모든 이슈에 대해 bd blocked를 실행하기 시작할 때까지 모른다.

의존관계 정보는 존재한다. 이슈 트래커 안에 있다. 하지만 CLI로 관리하면, 플랫 텍스트 출력에서 머릿속으로 그래프를 재구성하게 된다. 그 재구성은 가장 중요한 순간, 즉 그래프가 복잡하고 깨져 있을 때 실패한다.

beads가 의존관계를 추적하는 방법

beads는 AI 에이전트 조율을 위해 구축된 Git 기반 이슈 트래커다. 모든 것을 리포지토리의 .beads/ 디렉토리 안 로컬 Dolt 데이터베이스에 저장한다. 클라우드 서비스 없음, 계정 없음, 동기화 충돌 없음.

에이전트가 한 명령으로 의존관계를 선언한다:

bd dep add ISSUE-42 ISSUE-37

이것은 ISSUE-42가 ISSUE-37에 의존한다는 것을 기록한다. ISSUE-37이 클로즈될 때까지 ISSUE-42는 진행할 수 없다. 역방향 쿼리도 마찬가지로 간단하다:

bd blocked

워크스페이스에서 미해결 의존관계로 블로킹된 모든 이슈를 반환한다. 특정 이슈에 대해서는:

bd dep list ISSUE-42

ISSUE-42가 무엇에 의존하는지, 무엇이 ISSUE-42에 의존하는지를 보여준다.

데이터 모델은 깔끔하다. 문제는 의존관계를 기록하는 것이 아니다. 문제는 그것을 보는 것이다. 5개 에이전트에 걸친 30개 활성 이슈가 있을 때, bd blocked를 실행하면 리스트를 얻는다. 리스트로는 ISSUE-12가 3개 에이전트에 걸친 7개 하류 태스크를 블로킹하는 병목이라는 것이 보이지 않는다. 리스트로는 Agent 3가 ISSUE-18과 ISSUE-22 사이에 순환 의존 체인을 만들었다는 것이 보이지 않는다. 그래프의 공간적 뷰가 필요하다. 순차적인 것이 아니라.

Beadbox가 보여주는 것

Beadbox는 beads CLI를 비주얼 인터페이스로 감싸는 네이티브 데스크톱 앱이다. 에이전트가 쓰는 것과 같은 .beads/ 데이터베이스에서 읽고, 에이전트 작업에 맞춰 실시간으로 업데이트된다.

에픽 트리 뷰에서 미해결 의존관계를 가진 모든 이슈에 블로킹 배지가 인라인으로 표시된다. 에픽의 전체 트리 구조가 보이고, 블로킹된 이슈는 한눈에 마크되어 있다. 실행할 명령도 파싱할 출력도 없다.

의존관계 체인이 공간적으로 보인다. ISSUE-42가 ISSUE-37에 의존하고, ISSUE-37이 ISSUE-15에 의존하고, ISSUE-15가 막혀 있는 Agent 1에 할당되어 있다면, 트리를 스캔하여 그 체인을 따라갈 수 있다. 개별 CLI 쿼리에서 재구성하지 않고 병목의 형태가 보인다.

실시간 부분이 중요하다. Agent 1이 마침내 ISSUE-15를 클로즈하면, Beadbox UI에 1초 이내로 반영된다. ISSUE-37의 블로킹 배지가 사라진다. ISSUE-37만이 ISSUE-42를 블로킹하고 있었다면, 그 배지도 사라진다. 작업이 완료되면서 의존관계 체인이 무너지는 것을 새로고침이나 재쿼리 없이 지켜볼 수 있다.

내부적으로 이것은 단순한 파이프라인으로 동작한다: WebSocket 서버가 fs.watch().beads/ 디렉토리를 감시한다. 에이전트가 데이터베이스에 쓰면(이슈 클로즈, 의존관계 추가, 상태 업데이트), 파일 시스템 이벤트가 연결된 모든 클라이언트에 브로드캐스트를 트리거한다. React UI가 새 데이터로 다시 렌더링된다. 에이전트 액션에서 비주얼 업데이트까지 서브초 레이턴시.

구체적 시나리오: 병목 발견

5개 에이전트가 24개 이슈의 피처 에픽을 작업하고 있다. Beadbox를 열고 에픽 트리를 본다. 12개 이슈가 진행 중이다. 6개에 블로킹 배지가 있다.

그것만으로 이미 갖고 있지 않던 정보다. bd list는 12개 진행 중 이슈를 보여주지만, 어떤 진행 중 이슈가 실제로 정체되어 있는지 이해하려면 bd blocked를 별도로 실행하고 크로스 레퍼런스해야 한다.

블로킹 배지를 스캔하면 뭔가 보인다: 6개 블로킹 이슈 중 4개가 Agent 4에 할당된 데이터베이스 스키마 마이그레이션 ISSUE-19에 의존하고 있다. Agent 4는 아직 작업 중이지만, ISSUE-19가 단일 장애점 병목이 되었다. 4개 에이전트가 사실상 유휴 상태로 하나의 태스크를 기다리고 있다.

비주얼 뷰가 없었다면 이것을 한 시간 뒤에야 눈치챘을 수 있다. 비주얼 뷰가 있으면 즉시 개입할 수 있다. ISSUE-19를 더 빠른 에이전트에 재할당할 수 있다. 일부 의존 대상을 먼저 언블록할 수 있도록 더 작은 조각으로 분할할 수 있다. 4개 의존관계 중 2개가 과잉 선언이었음을 깨달아 bd dep remove로 제거할 수 있다.

포인트는 정보가 이전에 이용 불가능했다는 것이 아니다. 항상 데이터베이스에 있었다. 포인트는 비주얼 표현이 플랫 텍스트에서 묻히는 패턴을 표면화한다는 것이다.

흔한 의존관계 안티 패턴

하나의 리포에서 여러 AI 에이전트를 실행하면 몇 가지 반복되는 의존관계 문제가 발생한다. 전부 CLI 쿼리보다 비주얼로 캐치하기 쉽다.

과잉 선언. 에이전트는 보수적이 되기 쉽다. 의심스러우면 의존관계를 선언한다. 결과는 필요 이상으로 밀집된 의존관계 그래프이며, 실제로 필요하지 않은 작업에 블로킹되는 이슈가 생긴다. Beadbox에서는 이슈에 블로킹 배지가 있는데 블로킹 이슈가 코드베이스의 완전히 무관한 부분에 있을 때 이것을 발견한다. 빠르게 bd dep remove로 정리한다.

순환 체인. Agent A가 Agent B의 작업에 대한 의존을 선언한다. Agent B가 독립적으로 작업하며 Agent A의 작업에 대한 의존을 선언한다. 둘 다 서로에게 블로킹되고 어느 쪽도 진행할 수 없다. beads CLI는 생성 시 명백한 순환 의존을 캐치하지만, 3개 이상 이슈를 경유하는 간접적 사이클은 감지가 어렵다. 에픽 트리에서는 다른 작업이 완료되어도 절대 해소되지 않는 블로킹 배지의 덩어리로 발견한다.

단일 장애점 병목. 하나의 이슈에 5, 6, 7개의 하류 의존 대상이 축적된다. 병렬로 작업하는 에이전트가 전부 같은 기반 조각을 필요로 할 때 자연스럽게 발생한다. 위의 시나리오가 이 패턴을 보여준다. 리스트 뷰에서는 7개 블로킹 이슈가 보인다. 트리 뷰에서는 7개 화살표가 같은 노드를 가리키는 것이 보인다. 병목이 명백하다.

시작하기

Beadbox는 macOS, Linux, Windows에서 동작한다. Homebrew로 설치:

brew tap beadbox/cask && brew install --cask beadbox

.beads/ 디렉토리가 있는 아무 리포지토리를 지정한다. 이미 에이전트 플릿으로 beads를 실행하고 있다면, Beadbox가 기존 데이터베이스를 픽업하여 즉시 렌더링을 시작한다. 임포트 단계 없음, 설정 없음, 계정 생성 없음.

에이전트는 계속 CLI를 사용한다. bd dep add, bd update, bd close를 평소대로 실행한다. Beadbox가 데이터베이스를 감시하고 모든 변경을 실시간으로 반영한다. 에이전트 워크플로를 변경하지 않고 비주얼 레이어를 얻는다.

Beadbox는 베타 기간 동안 무료.

단일 코드베이스에서 여러 AI 에이전트를 조율하고 있다면, 의존관계 그래프가 워크플로를 가장 먼저 깨뜨리는 것이다. CLI를 통해 맹목적으로 관리하거나, 볼 수 있게 만들거나. 보는 것이 더 빠르다.