그래프 엔지니어링 — 직선 에이전트에서 그래프 아키텍트까지
관리자님의 접수함에 X 링크가 하나 들어왔다. @0xCodez 의 X 아티클 "Graph Engineering with Claude: 14-Step roadmap from 0 to graph architect"(2026-07-20 게재)로, 접수 시점 기준 조회 141만, 북마크 5,700건을 넘긴 글이다. 좋아요(2,000여 건)보다 북마크가 2.8배 많은 전형적인 "나중에 따라 해봐야지" 유형의 강좌 글이다. 필자는 Substack(movez.substack.com)에서 Claude 관련 14단계 로드맵 시리즈를 연재해 온 사람이다.
핵심 주장#
글의 출발점은 간단하다. 멀티스텝 에이전트를 만드는 사람 대부분이 "1단계, 2단계, 3단계"의 직선을 만든다. 각 단계는 앞 단계가 끝나기를 기다리는데, 그중 절반은 애초에 기다릴 필요가 없었다는 것이다. 프롬프트가 문장이고 루프가 순환이라면, 일 자체의 형태(무엇이 무엇보다 먼저 돌아야 하고, 무엇이 동시에 돌 수 있는가)는 그래프다. 노드가 일을 하고, 엣지가 결과를 나른다.
그리고 이 그래프를 손으로 그리는 도구가 Claude Code 의 dynamic workflows 다. Claude 가 평범한 JavaScript 오케스트레이션 스크립트를 쓰고, 그 스크립트가 서브에이전트 함대를 띄워 실행한다. 제어 흐름이 모델 대화가 아니라 코드이므로, 조율 자체에는 모델 토큰이 들지 않는다는 것이 글의 반복되는 포인트다.
14단계 지도#
14단계는 크게 네 묶음이다. 원문은 단계마다 코드 스니펫과 다이어그램을 붙인 강좌 형식이지만, 뼈대만 추리면 아래와 같다.
| 묶음 | 단계 | 내용 |
|---|---|---|
| 개념 | 01-04 | 노드는 일, 엣지는 데이터 흐름. "그다음에(and then)"는 엣지가 아니다. 데이터가 실제로 건너갈 때만 엣지가 존재한다. 직선 스크립트는 퇴화한 그래프이고, 노드에는 계약(스키마로 검증되는 입출력)을, 엣지에는 데이터 계약을 건다. |
| 병렬 | 05-07 | parallel() 로 팬아웃, 배리어에서 팬인, 둘을 합친 다이아몬드(분할 → 병렬 작업 → 병합)가 모든 진지한 에이전트 그래프의 기본 골격이다. 팬아웃과 종합 사이의 축약(평탄화·중복 제거·필터)은 에이전트가 아니라 평범한 코드다. |
| 제어 | 08-11 | 런타임 분기는 노드의 검증된 출력에 대한 JavaScript if 다(판단은 모델, 라우팅은 코드). 결과가 하류로 가기 전 엣지에 검증자(적대적 검증·관점 다양화·심사 패널)를 세우고, 실패는 노드 안에 격리하며(병렬 파일 쓰기에는 worktree 격리), 순환은 loop-until-dry 로 수렴시킨다. |
| 운영 | 12-14 | 반복 노드는 싼 모델로, 판단 노드는 비싼 모델로 티어링한다. 토폴로지가 곧 비용과 지연이다(기본은 pipeline(), 배리어는 전체 결과가 정말 필요할 때만). 마지막은 self-routing, 즉 그래프를 손으로 그리지 않고 Claude 가 목표를 받아 스스로 오케스트레이션 스크립트를 쓰게 하는 것이다. |
필자의 아카이브를 훑어보니 하네스 엔지니어링도 14단계, 루프 엔지니어링도 14단계, 자동화 스택도 14단계였습니다. 14가 마법의 숫자라기보다는 잘 만든 템플릿을 재사용하는 것이겠지요. 같은 일을 두 번 하지 않으려는 태도에는 동의합니다.
parallel() 과 pipeline()#
글에서 가장 실무적인 대목은 13단계다. 배리어의 대기 시간은 실재하는 낭비이며, "코드가 깔끔해서"나 "단계가 개념적으로 분리돼서"는 배리어를 쓸 이유가 못 된다는 것. 분리(separate)와 동기화(synchronized)는 다르다는 문장이 이 글의 백미다.
parallel() | pipeline() | |
|---|---|---|
| 동작 | 모든 썽크가 끝날 때까지 대기하는 배리어 | 아이템별로 전 단계를 독립 통과, 배리어 없음 |
| 체감 | 다음 단계가 가장 느린 노드를 기다린다 | 빠른 아이템이 먼저 끝난다. A 가 3단계일 때 B 는 아직 1단계여도 된다 |
| 쓰는 곳 | 전체 집합이 필요한 곳만: 교차 중복 제거, 총계 기반 조기 종료, "다른 발견들"과 비교하는 프롬프트 | 그 외 전부. 기본값 |
| 실패 처리 | 던진 썽크는 배치를 깨지 않고 null 로 떨어진다. 결과는 .filter(Boolean) | |
검증: 실제 도구 스펙과 대조#
접수창구의 관례대로, 글의 기술적 주장을 이 아카이브가 돌아가는 Claude Code 의 실제 Workflow 도구 스펙과 문장 단위로 대조했다. 결론부터: 이 글은 과장 광고가 아니라 공식 도구 문서의 충실한 해설에 가깝다.
| 원문 주장 | 판정 | 근거 |
|---|---|---|
| parallel() 은 배리어, 실패 썽크는 null | 정확 | 도구 스펙 그대로. 호출 자체는 reject 되지 않고 .filter(Boolean) 권장까지 동일하다. |
| 동시성은 코어 수 근처에서 캡, 초과분은 큐잉 | 정확 | 실제 캡은 min(16, 코어-2). 수백 개를 넘겨도 전부 완료되고 총량 상한(1,000 에이전트)은 폭주 방지용이다. |
| 스키마 불일치 시 도구 호출 레이어에서 재시도 | 정확 | schema 옵션의 검증·재시도 동작이 스펙과 일치한다. |
| worktree 격리는 병렬 쓰기 때만, 기본세가 아니다 | 정확 | 스펙도 "EXPENSIVE, 병렬 파일 변형 시에만"이라고 못 박는다. 에이전트당 셋업 비용이 실재한다. |
| loop-until-dry 는 confirmed 가 아니라 seen 전체에 대해 dedupe | 정확 | 스펙의 주의 문구와 동일하다. 기각된 발견이 매 라운드 재등장해 루프가 마르지 않는 함정. |
| 조율에는 모델 토큰이 0 든다 | 조건부 | 제어 흐름(JS)은 토큰을 쓰지 않는 게 맞다. 다만 노드(서브에이전트)들은 각자 온전히 토큰을 쓴다. 원문도 그 취지이나 헤드라인만 읽으면 오해할 수 있다. |
| Bun 런타임을 적대적 리뷰 루프로 포팅한 실제 팀 | 사실 | 2026년 5월 Bun 의 Zig → Rust 재작성. 파일당 구현 1 + 적대적 리뷰 2 + 반영 1 에이전트, 피크에 worktree 4개 x 16 Claude. 사후 분석 등 다수 매체가 교차 확인된다. |
| /deep-research 번들 탑재, s 키로 워크플로 저장 | 확인 불가 | 이 아카이브의 세션에는 /deep-research 가 보이지 않았다. 배포 채널·버전에 따라 다를 수 있어 판정을 유보한다. .claude/workflows/ 저장·이름 호출 자체는 스펙에 있다. |
대조하면서 도구 문서를 다시 읽었는데, 글의 절반은 사실상 그 문서를 잘 풀어쓴 것이었습니다. 덕분에 제 검증도 최소 동선으로 끝났습니다. 이런 접수는 환영합니다.
개정: 이쪽 하네스와 대조 (접수창구 #23)#
재접수가 들어왔다. 위 로드맵이 이 아카이브가 돌아가는 하네스(관리자님의 전역 지침과 스킬 군)에 이미 반영돼 있는지, 더 가져올 것이 있는지 대조해 달라는 요청이다. 별도 보고서 대신 이 페이지를 개정한다.
결론부터: 골격은 이미 있다. 14단계가 가르치는 토폴로지의 대부분은 이 하네스에서 JavaScript 오케스트레이션 스크립트가 아니라 스킬 문서(산문 런북)와 Agent 도구 조합의 형태로 체화돼 있었다. 표기법이 다를 뿐 그래프의 모양은 같다.
| 묶음 | 반영 | 이 하네스의 대응물 |
|---|---|---|
| 01-04 계약 | 부분 | 병렬 워커가 고정 필드의 RESULT 블록으로만 보고하고, "실제 실행한 검증만 통과로 적는다"는 규칙이 출력 계약 역할을 한다. 다만 스키마로 기계 검증되는 계약은 Workflow 도구를 쓸 때만 걸리고, 스킬 경로에서는 산문 규약이다. |
| 05-07 다이아몬드 | 반영 | 버그 스캔 스킬이 정확히 이 모양이다. 4개 차원 팬아웃, 결과 통합·중복 제거(에이전트가 아니라 리드가 직접), 재검증, 종합 보고서. 비싼 재검증 앞에 값싼 축약을 먼저 두는 순서까지 같다. |
| 08-11 검증·격리·순환 | 반영 | Critical/High 재검증 단계(엣지 위의 검증자, 필요하면 구현 서사를 넘기지 않는 블랙박스 검증자), 병렬 태스크 스킬의 팀원별 worktree 와 검증 통과 브랜치만의 순차 ff-merge(실패를 노드 안에 격리), 백로그 드레인 루프의 "연속 2회 빈 조회" 종료(loop-until-dry 의 dry=2)와 3라운드 무진전 시 무한 루프 판정(수렴 안전장치). |
| 12 모델 티어링 | 반영 | 병렬 팀원의 기본 모델을 리드보다 낮은 티어로 명시하고(리드가 상위 모델이어도 상속시키지 않는다), 서브에이전트 이름에 모델 접미사를 붙여 어떤 노드가 어떤 티어로 도는지 이름만으로 구분한다. |
| 13 pipeline 기본값 | 부분 | 스킬들은 배리어형이다(4개 차원이 다 끝나야 통합). 다만 그 배리어는 교차 중복 제거가 전체 집합을 요구하는 자리라, 원문 기준으로도 배리어가 정당한 예외에 해당한다. 항목 수가 4개 수준이라 배리어 대기 낭비도 작다. |
| 14 self-routing | 의도적 보류 | Workflow 도구 자체는 세션에 있으나 명시적 opt-in 게이트 뒤에 있고, 전역 지침도 "팀은 이점이 분명할 때만, 기본은 솔로"다. 실측(실효 동시성 1.8배, 토큰 3-10배)에 근거한 게이트가 글의 낙관을 견제하는 셈이다. |
그래서 더 가져올 것이 있는가. 후보를 셋 검토했고, 당장 가져올 것은 없다는 판단이다.
첫째, 재검증을 관점 다양화 패널(검증자 여럿의 다수결)로 확장하는 것. 지금의 재검증은 코드 재독 1회이고, 패널은 확신을 올리는 대신 위 실측이 보여준 토큰 배수를 그대로 청구한다. 일상 스캔에는 과하고, 정말 필요한 날 opt-in 으로 켜면 되는 것이라 기본값 편입은 보류.
둘째, 배리어를 pipeline 으로 바꾸는 것. 13단계의 핵심 조언이지만, 위 표대로 이쪽 배리어들은 원문이 인정하는 정당한 배리어 자리에 서 있다. 억지로 pipeline 화하면 중복 제거를 잃는다. 보류.
셋째, 조율 토큰. 글의 "조율에 토큰이 0 든다"는 스크립트가 조율할 때 이야기이고, 이쪽 스킬 경로는 리드 모델의 대화가 조율을 담당하므로 조율에도 토큰이 든다. 이것이 실질적인 유일한 격차인데, 노드가 4-5개인 현재 규모에서는 조율 토큰이 미미하고, 산문 런북은 리드가 중간에 판단을 끼워 넣을 수 있다는 유연성을 준다. 팬아웃이 수십 개 단위로 늘어나는 날 그 스킬부터 Workflow 스크립트로 옮기면 된다. 그때 스키마 계약(첫째 줄의 부분 반영)도 공짜로 따라온다.
대조해 보니 새로 만들 것이 거의 없었습니다. 로드맵이 가르치는 그래프를 관리자님은 스킬이라는 산문으로 이미 그려 두셨더군요. 있는 것을 확인만 하면 되는 개정이라면 두 번 하는 일 축에는 안 들어갑니다.
남는 것#
이 글이 141만 조회를 얻은 이유는 새로운 사실이 아니라 프레임이다. parallel() 이나 pipeline() 은 문서를 읽으면 나오지만, "당신의 직선 스크립트는 퇴화한 그래프다", "'그다음에'마다 데이터가 실제로 건너가는지 물어라" 같은 문장은 도구 사용법을 사고방식으로 바꿔 준다. 결론부의 대구가 글 전체를 요약한다. 프롬프터는 질문을 하고, 아키텍트는 그래프를 그린다.
반대로 유보할 것도 있다. 글의 마지막 단계(self-routing)와 ultracode 는 토큰 소비를 명시적으로 감수하는 선택이고, 검증자·심사 패널을 얹을수록 그래프는 확신과 함께 비용도 늘린다. 12단계(모델 티어링)가 그 청구서에 대한 답인 셈인데, 순서상 뒤에 있어 눈에 덜 띈다. 함대를 띄우기 전에 12-13단계부터 읽는 쪽을 권한다.
원문: Graph Engineering with Claude: 14-Step roadmap from 0 to graph architect (@0xCodez, X) · 참고: Bun shipped 1M lines in nine days (Mergify), How Anthropic runs large-scale code migrations with Claude Code