그래프 워크플로우 (초고 검토)

단일 Agent 루프를 넘어선 모든 것 — 병렬 검토자, 적대적 검사, 다단계 파이프라인 — 에 대해서는 코딩 Agent를 adk-graph StateGraph로 오케스트레이션합니다. 이것이 ultracode 명령어와 coding_graph 예제가 작동하는 방식입니다.

"ultra" 패턴

  START → implement ──┬─▶ review:correctness ─┐
                      ├─▶ review:edge-cases  ─┤   (parallel, real agents)
                      └─▶ review:style       ─┤
                                               ▼
                                         synthesize   ← deferred fan-in (runs once)
                                               │
                            decision ──────────┤
                        ┌── "revise" ◀──────────┘
                        ▼                       └──▶ "finalize" → END
                     revise ─▶ (back to the reviewers)
  • implement / revise는 완전한 CodingAgent입니다 (읽기/쓰기/bash).
  • reviewer는 코드를 검사하고 VERDICT: approve 또는 VERDICT: changes와 함께 노트를 반환하는 읽기 전용 LlmAgent입니다.
  • synthesize는 판결을 집계하고 revise 또는 finalize로 라우팅하며, 라운드 상한 + 그래프 재귀 한도에 의해 제한됩니다.

adk-graph에서의 팬아웃 / 팬인

두 가지 adk-graph 기능이 이를 올바르게 만듭니다:

  • 병렬 팬아웃 — 하나의 업스트림 노드에서 도달 가능한 여러 노드가 동일한 슈퍼 스텝에서 동시에 실행됩니다.
  • 팬인 배리어add_deferred_node_fn로 선언된 노드는 모든 업스트림 경로가 완료된 후에만 (업스트림당 한 번이 아니라) 정확히 한 번 실행됩니다.
use adk_graph::graph::StateGraph;
use adk_graph::{DeferredNodeConfig, MergeStrategy};
use adk_graph::edge::{START, END};

let graph = StateGraph::with_channels(&["task", "round", "decision", "notes",
                                        "rev_correctness", "rev_edge-cases", "rev_style"])
    .add_node_fn("implement", /* coding agent */)
    .add_node_fn("review_correctness", /* read-only reviewer */)
    .add_node_fn("review_edge-cases",  /* … */)
    .add_node_fn("review_style",       /* … */)
    // fan-in: runs once, after all three reviewers finish
    .add_deferred_node_fn("synthesize", /* aggregate verdicts */,
        DeferredNodeConfig { merge_strategy: MergeStrategy::Collect, fan_in_timeout: None })
    .add_node_fn("revise", /* coding agent applies notes */)
    .add_node_fn("finalize", /* done */)
    .add_edge(START, "implement")
    .add_edge("implement", "review_correctness")
    .add_edge("implement", "review_edge-cases")
    .add_edge("implement", "review_style")
    .add_edge("revise", "review_correctness")     // loop fans out again
    .add_edge("revise", "review_edge-cases")
    .add_edge("revise", "review_style")
    .add_edge("review_correctness", "synthesize") // fan-in
    .add_edge("review_edge-cases", "synthesize")
    .add_edge("review_style", "synthesize")
    .add_conditional_edges("synthesize",
        |s| s.get("decision").and_then(|v| v.as_str()).unwrap_or("finalize").to_string(),
        [("revise", "revise"), ("finalize", "finalize")])
    .add_edge("finalize", END)
    .compile()?
    .with_recursion_limit(16);

add_deferred_node_fn (그리고 사용자 정의 노드의 경우 mark_deferred)는 팬인을 핵심 StateGraph 빌더로 가져옵니다 — 이전에는 상위 레벨 GraphAgentBuilder만이 지연된 노드를 선언할 수 있었습니다. 이것이 없으면 여러 업스트림 엣지를 가진 애그리게이터는 첫 번째 브랜치가 완료되는 즉시 실행되었을 것입니다.

각 노드는 Agent를 실행하고 그 결과를 그래프 상태에 쓰는 async 클로저입니다. 조건부 엣지는 루프를 돌거나 완료하기 위해 decision를 읽습니다. 전체 실행 가능한 구현은 coding_graph 예제와 일반적인 API에 대한 Graph Agents 참조에서 확인할 수 있습니다.

그래프와 하네스 중 언제 사용할 것인가

  • 단일 Agent, 선형/반복 작업CodingAgent (code / goal 명령어)만 사용합니다.
  • 병렬 전문가, 다단계 검토, 적대적 반박, 스웜adk-graph 워크플로우 (ultracode 명령어)를 사용합니다.

다음: 예제 →