대부분의 Claude Code 사용자는 여전히 워크플로를 손으로 작성합니다. 이 글은 Dynamic Workflows가 해결하는 문제, Anthropic 엔지니어들이 실제로 쓰는 6가지 패턴, 그리고 비용·보안·저장까지 실전 운영법을 정리합니다.
대부분의 Claude Code 사용자는 여전히 워크플로를 손으로 작성합니다. 프롬프트를 연결하고, 출력을 복사해 다음 프롬프트에 붙여넣고, 잘못된 것을 고치고, 반복합니다.
빌더 10명 중 9명은 Dynamic Workflows를 단 한 번도 써보지 않았습니다. 출시된 지 벌써 2주가 지났는데도 말이죠.
이들은 하나의 워크플로로 끝낼 수 있는 일을 50개의 프롬프트로 처리합니다. 아래는 마이그레이션, 리서치, 정렬, 근본 원인 분석, 트리아지, 평가를 위해 Anthropic 엔지니어들이 실제로 사용하는 14단계 로드맵과 6가지 패턴입니다.
제 Substack을 팔로우해서 최신 AI 알파를 받아보세요:
Dynamic Workflows는 2026년 5월 28일 Claude Code에 출시되었습니다. 기본 Claude Code 하네스는 코딩을 위해 만들어졌고, 대부분의 코딩 작업에서는 잘 작동합니다. 하지만 하나의 컨텍스트 윈도우로는 무너지기 시작하는 작업 유형들이 있습니다. 오래 걸리고, 대규모 병렬이며, 매우 구조적이거나, 적대적인 작업들입니다.
이런 경우 Anthropic은 예전에는 직접 커스텀 하네스를 만들었습니다. (Research, Code Review, agent teams). Dynamic Workflows에서는 Claude가 그 하네스를 즉석에서, 작업에 맞춰 커스텀 빌드된 JavaScript로 직접 작성해 줍니다.
14단계. 6가지 패턴. 50개의 프롬프트 대신 하나의 워크플로.
Part 1 · 멘털 모델
기본 Claude Code 하네스에서는 Claude가 같은 컨텍스트 윈도우 안에서 계획하고 실행합니다. 대부분의 코딩 작업에는 이것이 훌륭합니다. 하지만 오래 걸리거나, 병렬적이거나, 적대적인 작업에서는 무너지기 시작합니다.
Dynamic Workflow는 Claude가 작업을 위해 자체 커스텀 하네스를 작성하는 것입니다. 몇 개의 특수 함수로 서브에이전트를 생성하고 조율하는 JavaScript 파일이며, 그 사이를 흐르는 데이터를 처리하기 위해 표준 JavaScript (Math, JSON, Array)도 사용합니다.
cat
@_catwu
Claude Code의 가장 강력한 새 기능인 dynamic workflows를 공유하게 되어 매우 기쁩니다! 프롬프트에 "workflow"라고 언급하면 Claude가 엄격히 따르는 오케스트레이션 계획을 동적으로 생성하여, 모든 단계가 올바른 순서로 진행된다는 것을 자신 있게 신뢰할 수 있게 해줍니다 even
이것이 기본 하네스가 줄 수 없는 세 가지를 제공합니다:
에이전트별 격리. 각 서브에이전트는 하나의 집중된 목표를 가진 자체 컨텍스트 윈도우를 받습니다. 교차 오염이 없습니다.
에이전트별 모델 선택. 워크플로는 각 서브에이전트가 어떤 모델을 쓸지 고릅니다. 어려운 추론에는 Opus, 저렴한 탐색에는 Haiku, 그 중간에는 Sonnet입니다.
에이전트별 격리 수준. Worktree (격리된 git checkout) 또는 remote (checkout 없음). 워크플로가 각 에이전트에 무엇이 필요한지 결정합니다.
Claude에게 직접 요청하거나 (“make a workflow that…”) 트리거 단어 ultracode로 시작하면 됩니다. 워크플로가 중단되더라도 - 사용자 동작, 터미널 종료 - 세션을 재개하면 중단된 지점부터 이어집니다.
워크플로가 올바른 도구인 시점을 알려면, 그것이 무엇을 고치는지 알아야 합니다. 복잡한 작업을 하나의 컨텍스트 윈도우에서 Claude가 오래 수행할수록, Anthropic 출시 글에서 직접 이름 붙인 세 가지 특정 실패 모드에 더 취약해집니다:
Agentic laziness - Claude가 복잡하고 다중 파트인 작업을 끝내기 전에 멈추고, 부분적인 진전만으로 완료되었다고 선언합니다. 보안 리뷰의 50개 항목 중 20개만 처리하고 나머지는 “handled”라고 부릅니다.
Self-preferential bias - Claude가 자신의 결과를 검증하거나 루브릭에 따라 판단하라는 요청을 받으면 자신의 결과를 선호합니다. 이해관계가 있는 검증자는 공정한 검증자가 될 수 없습니다.
Goal drift - 특히 compaction 이후 여러 턴에 걸쳐 원래 목표에 대한 충실도가 점진적으로 사라지는 현상입니다. 각 요약 단계는 손실을 동반합니다. “X를 하지 마라” 같은 제약은 47번째 턴쯤 되면 조용히 사라집니다.
워크플로는 이 세 가지를 구조적으로 모두 해결합니다. 각자 자신의 컨텍스트, 집중된 목표, 격리된 상태를 가진 분리된 Claude들로 해결하는 것입니다. 당신의 작업이 이 패턴들 중 하나라도 겪고 있다면, 그것이 워크플로를 꺼내야 한다는 신호입니다.
당신은 이미 Claude Agent SDK나 claude -p를 사용해 정적 워크플로를 만들어 여러 Claude Code 인스턴스를 함께 조율해봤을 수도 있습니다.
정적 워크플로는 범용적입니다. 모든 엣지 케이스를 처리하도록 한 번 작성됩니다. 작동은 하지만 보수적일 수밖에 없습니다.
Dynamic Workflows는 다릅니다. Claude가 이 작업을 위해 이 워크플로를 작성합니다. 하네스가 맞춤형으로 만들어집니다. 아래는 같은 질문을 두 방식으로 처리한 예입니다:
동적 버전이 이기는 이유는 검색 단계 때문이 아닙니다. 둘 다 검색은 할 수 있습니다.
차이는 워크플로가 당신의 컨텍스트를 중심으로 스스로 형태를 잡을 수 있다는 점입니다. 청구 코드를 읽고, 각 기능을 실제 새 프로바이더 문서와 대조하고, 당신의 거래량에서 가격을 계산하고, 스스로 형성 중인 답변에 대해 적대적인 “왜 마이그레이션하면 안 되는가” 검토를 실행할 수 있습니다.
정적 하네스는 당신의 코드가 존재한다는 사실을 모르기 때문에 이런 일을 할 수 없습니다.
세 가지 함수가 워크플로의 대부분의 일을 담당합니다. 이것만 알면 Claude가 당신을 위해 작성한 어떤 워크플로든 읽을 수 있고, 원하는 형태가 있을 때 Claude를 유도할 수도 있습니다.
parallel()은 배리어입니다. 작업을 분산시킨 다음, 반환하기 전에 모든 작업이 끝날 때까지 기다립니다. pipeline()은 스트리밍입니다. 각 항목이 모든 단계를 독립적으로 통과합니다.
질문으로 선택하세요: 다음 일을 하기 전에 모든 결과가 필요할까? 필요하다 → parallel. 아니다 → pipeline (더 저렴하고, 전체적으로 더 빠름).
분류기 에이전트가 작업 유형을 결정하고, 그 답에 따라 워크플로가 다른 에이전트나 동작으로 라우팅합니다. 또는 분류기가 마지막에 실행되어 원시 출력을 다음 단계에 필요한 버킷으로 분류할 수도 있습니다.
이 패턴이 진가를 발휘하는 때:
작업이 이질적일 때 - 서로 다른 하위 유형이 서로 다른 처리를 필요로 합니다.
복잡성이 요구할 때만 비싼 모델을 쓰고 싶을 때 (저렴한 모델에서 분류한 뒤, 필요할 때만 Opus로 라우팅).
작업 분해 자체가 만만치 않고, 모델이 형태를 결정하는 편이 유리할 때.
예시: “auth 모듈이 어떻게 작동하는지 설명해줘.” 분류기 서브에이전트가 먼저 코드베이스를 읽고 복잡도를 추정한 뒤, 실제 설명 작업을 10개 파일짜리 모듈이면 Sonnet으로, 100개 파일짜리 모듈이면 Opus로 라우팅합니다. 작업을 이해한 뒤에 결정되는, 작업에 맞는 올바른 모델입니다.
작업을 더 작은 여러 단계로 나누세요. 각 단계에 대해 에이전트를 병렬로 실행하세요. 그리고 그 결과를 하나의 답으로 종합하세요.
synthesize 단계는 배리어입니다. 모든 fan-out 에이전트를 기다린 다음, 그들의 구조화된 출력을 하나로 병합합니다.
이 패턴이 실전에서 지배적인 이유: 단일 컨텍스트 작업의 “한 번에 너무 많은 것” 실패를 해결하기 때문입니다. 각 서브에이전트는 자기 조각만 봅니다. 오케스트레이터는 50개의 관련 없는 세부 사항에 정신이 분산되지 않습니다.
각 단계는 자신의 깨끗한 윈도우를 갖기 때문에 서로 교차 오염되지 않습니다.
이럴 때 사용하세요:
작업 항목 목록이 명확히 열거 가능할 때 (파일 50개, 엔드포인트 200개, 리뷰 100개).
각 항목이 독립적일 때 - 어떤 항목도 시작하기 위해 다른 항목의 출력이 필요하지 않습니다.
마지막에 부분 보고서 더미가 아니라 하나의 통합된 답을 원할 때.
python
// Fan out: one agent per file. Barrier: wait for all.
const reviews = await parallel(
files.map(file => () => agent(
`Review ${file} for security issues`,
{ model: "haiku", schema: IssueList }
))
)
// Synthesize: one Opus agent merges everything.
const report = await agent(
`Merge these reviews into one prioritized report:\n${JSON.stringify(reviews)}`,
{ model: "opus" }
)
이것은 self-preferential bias에 대한 구조적 해결책입니다. 생성된 각 에이전트에 대해, 그 출력물을 루브릭에 따라 적대적으로 검증하는 별도의 생성 에이전트를 실행합니다. 검증자는 원래 작업을 본 적이 없으므로 그것을 편들 수 없습니다.
이 패턴이 가장 중요한 경우:
주장 검증 - 보고서의 모든 사실 진술마다 별도의 검증 서브에이전트를 두고, 원본 소스와 대조해 확인합니다.
코드 리뷰 - 작성 에이전트가 수정 사항을 만들고, 리뷰어 에이전트가 (분리된 컨텍스트에서) 그것을 검토합니다. 같은 Claude가 자기 자신을 판단하게 해서는 안 됩니다.
품질 게이트 - 어떤 산출물이든 배포되기 전에, 적대자가 그것에 대한 가장 약한 고리를 찾아내려 시도합니다. 적대자가 찾지 못하면 배포합니다.
페어링 규칙: 검증자는 루브릭과 산출물만 알아야 하며, 누가 그것을 만들었는지는 알면 안 됩니다. 그렇지 않으면 프롬프트의 힌트를 통해 self-preference가 다시 스며듭니다.
어떤 주제에 대해 여러 아이디어를 생성한 뒤, 루브릭이나 검증으로 걸러내세요. 중복은 제거하고, 품질이 가장 높고 검증된 아이디어만 반환하세요.
이 패턴이 빛나는 곳:
브레인스토밍 - 제품 이름 30개를 만든 뒤, 검증자가 진부함, 상표 충돌, 약한 발음을 제거합니다. 당신은 3개만 보게 됩니다.
가설 생성 - 문제에 대한 5가지 다른 접근을 만든 뒤, 각각을 당신의 제약 조건에 따라 점수화합니다. 우승안은 그 자격을 얻은 것입니다.
솔루션 설계 - 문제에 대한 5가지 다른 접근을 만든 뒤, 각각을 당신의 제약 조건에 따라 점수화합니다. 우승안은 그 자격을 얻은 것입니다.
이는 Claude에게 “최고의 답”을 요구하는 것의 반대입니다. 최고의 답을 요구하면 Claude는 너무 일찍 커밋합니다. Generate-and-filter는 모든 선택지가 도전받은 뒤에, 늦게 커밋하게 만듭니다.
작업을 나누는 대신, 에이전트들이 그것을 두고 경쟁하게 하세요. 같은 작업을 서로 다른 접근으로 시도하는 N개의 에이전트를 생성한 다음, 결과를 쌍대 비교 방식으로 판단해 한 명이 이길 때까지 진행합니다.
비교 판단은 절대 점수화보다 더 신뢰할 수 있습니다 - 특히 취향 기반 작업에서 그렇습니다.
이것이 점수 기반 정렬보다 나은 이유: 하나의 프롬프트에서 1,000개 항목을 정렬하려 하면 두 가지 측면에서 실패합니다. 품질이 저하되고, 컨텍스트에도 들어가지 않습니다. 토너먼트는 브래킷을 신선한 에이전트들로 나누어, 각 에이전트가 단지 두 항목만 비교하게 합니다.
브래킷 자체는 컨텍스트가 아니라 결정적 루프 코드에 존재합니다. 각 비교는 빠르고, 공정하며, 격리되어 있습니다. 같은 아이디어는 취향 기반 순위에도 작동합니다: 디자인 선택, 후보 선택, 콘텐츠 우선순위 지정.
작업량이 미지수인 작업에는, 고정된 횟수로 패스를 돌리는 대신 중단 조건이 충족될 때까지 에이전트를 반복 생성하세요 - 새로운 발견이 없을 때, 로그에 더 이상 오류가 없을 때, 이론이 검증되었을 때까지.
이 패턴은 “실제로 끝날 때까지 계속해”에 대한 해답입니다:
플래키 테스트 디버깅 - 재현하고, 이론을 세우고, 검증하고, 하나의 이론이 성립할 때까지 반복합니다.
버그 헌팅 - 전체 패스에서 0이 나올 때까지 계속 버그를 찾습니다.
패턴 채굴 - 클러스터링하고, 규칙을 식별하고, 새로운 클러스터가 더 이상 나타나지 않을 때까지 반복합니다.
이 패턴은 /goal과 함께 사용해 강한 완료 요구사항을 설정하세요 (“하나의 이론이 맞을 때까지 멈추지 마라”). 전체 워크플로 자체를 주기적으로 실행하고 싶다면 /loop와도 함께 쓰세요.
브래킷과 중단 조건은 코드에 존재하고, 활성 반복만 컨텍스트에 남습니다.
6가지 패턴은 단독으로 등장하는 경우가 드뭅니다. 실제 워크플로는 보통 그중 2-4개를 조합합니다. 아래 매트릭스는 Anthropic 출시 글에 나온 각 사용 사례를, 주로 사용하는 패턴과 짝지어 보여줍니다:
마이그레이션과 리팩터링. Fan-out (worktree에서 호출 지점/실패 테스트당 하나의 에이전트) → adversarial verification (각 수정 사항을 별도 에이전트가 리뷰) → 완료될 때까지 반복. 이것이 Anthropic이 Bun을 Zig에서 Rust로 다시 쓸 때 사용한 패턴입니다.
딥 리서치 (/deep-research 스킬). Fan-out (병렬 웹 검색) → adversarial verification (각 주장 독립 검증) → synthesize (인용이 포함된 하나의 보고서).
초안의 심층 검증. 모든 사실 주장을 식별 (에이전트 하나) → fan-out (주장마다 검증자 하나, 각 에이전트가 소스와 대조) → meta-verifier (검증자가 사용한 소스의 품질까지 점검).
1,000개 이상 항목 정렬. Tournament (5-9단계) - 쌍대 비교, 버킷 랭크, 또는 브래킷. 절대 점수화가 아니라 비교 판단.
메모리와 규칙 준수. 규칙당 검증자 하나 (fan-out) → false positive를 피하기 위해 회의적인 페르소나가 규칙 자체를 다시 검토.
근본 원인 조사. 분리된 증거로부터 이론 생성 (서로 다른 에이전트가 로그, 파일, 데이터를 읽음) → 각 이론에 대한 검증자와 반박자 패널 → 하나만 살아남을 때까지 반복.
대규모 트리아지. classify-and-act → 기존 티켓과 중복 제거 → 수정 시도 또는 에스컬레이션. 지속적 트리아지를 위해 /loop와 함께 사용.
탐색과 취향 (디자인, 네이밍, UI 선택). Generate-and-filter (옵션 5-20개) → 루브릭 기반 토너먼트 → 순위화 또는 선택.
경량 평가. worktree에서 후보 실행 → 비교 에이전트가 루브릭에 따라 평가 → 개선 후 재평가. 형태는 토너먼트와 같지만, 순위화가 아니라 채점용입니다.
이것을 올바르게 내재화하는 방법: 현재 작업이 어떤 실패 모드 아래에서 실패하는지 식별한 다음, 그것을 구조적으로 막는 패턴을 고르세요.
드리프트 → fan-out. Self-preference → adversarial verification. 개방형 작업 → 완료될 때까지 반복. 점수화하기 어려움 → tournament.
워크플로는 비용이 많이 들 수 있습니다. 세 가지 제어 장치가 이것을 “멋지지만 비싼 것”에서 “내가 무인으로 돌리는 도구”로 바꿉니다.
/goal은 강한 완료 요구사항을 설정합니다. 루프 패턴과 함께 사용하세요: “하나의 이론이 맞을 때까지 멈추지 마라.” /goal이 없으면 워크플로는 느슨한 완료 지점에서 멈춥니다. /goal이 있으면 실제 종료 조건이 충족될 때까지 반복합니다.
/loop는 전체 워크플로를 주기적인 일정으로 실행합니다. 지속적으로 돌리고 싶은 워크플로에 사용하세요 - 트리아지, 주간 리서치 업데이트, 반복 검증.
명시적 토큰 예산. 프롬프트에서 Claude에게 “use 10k tokens”라고 말하세요. 이것이 워크플로 실행에 상한을 설정합니다. 상한이 없으면 야심찬 워크플로가 예상보다 5–10배까지 토큰을 부풀릴 수 있습니다.
python
> ultracode quick adversarial review of this assumption:
"moving to Postgres eliminates our shard rebalancing."
Use 5k tokens. /goal don’t stop until you have either
a counterexample or three independent confirmations.
Claude Code 팀의 말을 직접 인용하면: “Best practices are still developing. Dynamic workflows often use more tokens, so think carefully about when and how to use them.” 대부분의 전통적인 코딩 작업에는 리뷰어 5명의 패널이 필요하지 않습니다.
스스로에게 물어보세요: 이 작업에 정말 더 많은 계산량이 필요한가? 일반적인 Claude Code 세션이 5분 안에 끝낼 수 있다면, 워크플로는 필요하지 않습니다.
신뢰할 수 없는 공개 콘텐츠를 읽는 모든 워크플로 - 지원 티켓, 버그 리포트, 사용자 피드백, 스크랩된 데이터 - 는 그 콘텐츠에 프롬프트 인젝션이 포함될 수 있다고 가정해야 합니다.
해결책은 격리입니다. 신뢰할 수 없는 콘텐츠를 읽는 에이전트가 높은 권한이 필요한 작업을 수행하지 못하게 막으세요. 원시 콘텐츠에 노출되지 않은 별도의 에이전트들이 실제 행동을 수행해야 합니다.
사용자 제출 콘텐츠를 처리하거나 (지원 티켓, 버그 리포트, 고객 피드백, 소셜 미디어), 공개 웹 페이지를 스크랩하거나, 제3자 API의 출력물을 대상으로 실행되는 모든 워크플로에 해당합니다.
입력이 당신이나 신뢰하는 팀원이 작성한 것이 아니라면, 격리하세요. 30줄짜리 읽기 전용 리더 에이전트는 거의 비용이 들지 않으면서 프롬프트 인젝션 위험의 한 부류 전체를 제거합니다.
워크플로가 잘 작동하면 저장하세요: 워크플로 메뉴에서 s를 누르세요. 저장된 워크플로는 ~/.claude/workflows로 갑니다. 여기서 두 가지 경로가 있습니다:
로컬에 유지 - 자신의 프로젝트 전반에서 재사용합니다.
Skill로 배포 - JavaScript 파일을 Skill 폴더 안에 넣고, SKILL.md에서 참조하면, Skill을 설치한 누구나 같은 워크플로를 실행합니다.
알아둘 만한 실용적인 뉘앙스 하나: 워크플로를 Skill로 패키징할 때는, Claude에게 그 워크플로를 그대로 실행할 스크립트가 아니라 템플릿으로 다루라고 프롬프트하세요.
그렇게 하면 전체 구조는 유지하면서도, Claude가 현재의 구체적 작업에 맞게 워크플로 형태를 조정할 여지가 생깁니다. 특히 “deep verification”이나 “triage”처럼 사용 사례마다 유연하게 변해야 하는 워크플로에 유용합니다.
일반적인 Claude Code 세션이면 충분한데도 워크플로를 꺼내는 것. 대부분의 전통적인 코딩 작업에는 리뷰어 5명의 패널이 필요하지 않습니다.
토큰 예산이 없는 것. 야심찬 워크플로는 명시적 상한이 없으면 예상의 5–10배까지 부풀어 오릅니다.
하나의 에이전트가 작업과 검증을 둘 다 하는 것. Self-preferential bias 때문에 검증자가 작업자를 편들게 됩니다. 둘은 반드시 분리되어야 합니다.
parallel()과 pipeline()을 서로 바꿔 써도 된다고 생각하는 것. 배리어가 중요합니다 - parallel은 모두를 기다리고, pipeline은 스트리밍합니다.
루프 패턴에서 /goal을 건너뛰는 것. 워크플로가 첫 번째 느슨한 완료 지점에서 너무 일찍 멈춥니다. /goal이 강한 완료를 강제합니다.
신뢰할 수 없는 콘텐츠가 액터에게 도달하게 두는 것. 사용자 제출 입력을 처리하는 순간부터 격리는 선택이 아닙니다.
절대 점수로 정렬하는 것. 비교 판단이 더 신뢰할 수 있습니다. 토너먼트를 사용하세요.
작동하는 워크플로를 한 번도 저장하지 않는 것. 매주 같은 형태를 다시 프롬프트하는 것. s로 저장하고, Skill로 배포하세요.