Skip to content

Locale ko · en

선이 부족할 때 지도를 그린다 — 그래프 엔지니어링

By Harin Kim · Published 4 Aug 2026 · Updated 3 Aug 2026

Summary

「코딩은 대화다」 6편. DAG·조건부 엣지·핸드오프 vs 도구, 에스컬레이션 노드. 루프 다음의 토폴로지.

5편에서 루프에 정지 조건을 넣었다면, 다음 질문은 이것입니다. 누가 다음에 말할지, 무엇을 병렬로 돌릴지, 실패 시 어느 노드로 보낼지 — 한 줄짜리 plan→act→observe로는 더 이상 안 그려질 때입니다.

핵심 한 줄: 그래프 엔지니어링은 모델을 더 똑똑하게 만드는 일이 아니라, 노드(역할·단계)·엣지(의존·라우팅)·상태(공유 계약) 로 “누가 언제 무엇을”을 명시하는 일입니다.

이 글은 「코딩은 대화다」 6편입니다. 루프 다음에 지도로 올라갑니다. 멀티에이전트·하네스가 전제입니다.

루프가 부족한 순간

증상루프만으로그래프가 필요할 때
역할이 바뀜한 에이전트가 전부Research → Implement → Review처럼 소유권이 이동
일이 갈라짐직렬로 우겨 넣음조사 A/B를 병렬 후 병합
정책이 갈라짐프롬프트에 if 나열조건부 엣지로 라우팅
실패 처리같은 턴 재시도에스컬레이션 노드(사람·시니어 역할)

루프(5편)는 한 노드 안의 리듬입니다. 그래프는 노드들 사이의 교통망입니다. WIP=1은 여전합니다 — 그래프 전체를 한 번에 삼키지 말고, 지금 활성인 노드(들) 만 돌리세요.

Rendering diagram…

위 그림에서 Implement→Gate→Review는 파이프라인(대체로 DAG), Review↔FactFix는 품질 루프(사이클) 입니다. 둘을 같은 단어로 뭉개지 마세요.

DAG와 사이클 — 이름을 정확히

  • DAG (Directed Acyclic Graph): 화살표가 순환하지 않는 방향 그래프. 에디토리얼 “단계 파이프라인”, 빌드 의존성, “Research가 끝나야 Outline”에 적합합니다.
  • 사이클이 있는 그래프: 에이전트 피드백·재시도·리뷰 루프. LangGraph는 노드·엣지·공유 State로 이런 워크플로를 모델링하고, 실행은 super-step 단위로 진행합니다 (Graph API, as of 2026-08-03).
  • 실무 규칙: 바깥은 DAG(단계·게이트), 안쪽 노드는 루프(5편의 max_turns) . 바깥까지 사이클로 풀면 디버깅이 지옥이 됩니다.

PapaCoder의 Workflow Engine 카드도 파이프라인을 의존성을 지키는 agent DAG 로 실행한다고 적습니다 (agents/platform-intelligence/workflow-engine.md). 오케스트레이션 코드는 결정적(deterministic)이고, LLM은 노드 안에서만 확률적으로 움직입니다.

노드 · 엣지 · 상태

요소의미실무 예
Node한 책임의 단계/역할Research, KR Writer, Fact Checker, Human Approve
Edge다음에 갈 곳Outline → KR Writer, accuracyFail → revise
Conditional edge관측 결과에 따른 분기테스트 fail → Implement, pass → Review
State노드가 읽고 쓰는 공유 계약brief JSON, draft markdown, quality scores

상태 스키마가 느슨하면 그래프는 “채팅 여러 개”와 다를 바 없습니다. 3편의 typed handoff 가 여기로 올라옵니다.

핸드오프 vs 도구로 부르는 에이전트

OpenAI 오케스트레이션 가이드는 두 패턴을 구분합니다 (Orchestration, as of 2026-08-03):

패턴언제무슨 일이 일어나나
Handoffs전문가가 그 분기 대화를 소유해야 할 때제어권이 전문가 에이전트로 이동
Agents as tools매니저가 최종 답을 유지해야 할 때매니저가 전문가를 유계 도구처럼 호출

SDK에서 handoff는 에이전트가 다른 에이전트에게 위임하는 장치입니다 (Handoffs). 그래프 용어로 말하면 엣지 위의 소유권 이전입니다. “전부 handoff”로 시작하면 라우팅 표면이 지저분해지니, 계약(도구·정책·프롬프트)이 실제로 달라질 때만 노드를 쪼개세요 — 가이드도 같은 조언을 합니다.

처음엔 모든 걸 한 Agent 모드에 몰아넣고 “알아서 리뷰까지”를 기대했습니다. 결과가 번갈아 좋아졌다 나빠지길래, Research / Implement / Review를 노드로 고정하고 엣지만 조건부로 바꿨더니 실패가 어디서 났는지 보이기 시작했습니다.

언제 사람에게 에스컬레이션 노드를 두나

그래프에 사람 노드를 넣는 기준(4·5편과 연결):

  1. Harness가 막을 수 없는 판단 — 제품 우선순위, 법적/브랜드, “이 초안을 올릴까”
  2. 루프 예산 소진max_turns / 동일 실패 N회 / 시간 박스
  3. 게이트 실패가 정책 — accuracyFail, 시크릿 경계, 프로덕션 배포
  4. 병렬 병합 충돌 — 두 Research가 모순일 때 자동 합의가 위험

에스컬레이션은 실패가 아니라 설계된 엣지입니다. “나중에 사람이 보겠지”를 암묵지로 두지 말고, 노드 이름과 진입 조건을 적으세요.

실습: 주말용 미니 그래프 스케치

코드 프레임워크 없이 먼저 텍스트 DAG 로 고정하세요.

# draft-pipeline.graph
nodes:
  eic:      { wip: 1, artifacts: [EditorialBrief] }
  research: { depends: [eic], artifacts: [ResearchBrief] }
  outline:  { depends: [research], artifacts: [Outline] }
  write_ko: { depends: [outline], artifacts: [draft.ko] }
  write_en: { depends: [outline], artifacts: [draft.en] }  # parallel OK after outline
  review:   { depends: [write_ko, write_en], gate: score>=85 }
  facts:    { depends: [review], gate: accuracyPass }
  publish:  { depends: [facts], owner: human }  # never auto

edges_conditional:
  review.on_fail -> write_ko   # revise with new Observe
  facts.on_fail  -> review
  any.max_turns  -> human

LangGraph를 쓸 때는 StateGraph에 노드를 올리고 add_conditional_edges로 분기를 붙인 뒤 compile() 합니다. 사이클이 있으면 5편의 recursion_limit 을 바깥 예산으로 두세요.

OpenAI SDK 쪽이라면 triage → specialist를 handoff 엣지로, 요약 전용 헬퍼는 as tool 로 두는 식이 읽기 쉽습니다.

Cursor에서 그래프를 흉내 내는 법

  • Task/서브에이전트로 Research 두 갈래를 병렬로 돌리고, 부모 채팅에서만 Merge하세요. 부모가 WIP=1 오케스트레이터입니다.
  • 한 채팅에 “조사하고 구현하고 리뷰해”를 넣지 말고, 노드별 스레드 또는 명시적 단계 프롬프트로 나누세요.
  • 머지 전에 각 노드 산출물을 파일(research-brief.md 등)로 고정 — 이게 공유 State입니다.
  • Stop 조건·훅·CI(4편) 없는 그래프는 예쁜 그림일 뿐입니다.

PapaCoder 에디토리얼 DAG

agents/editorial/workflow.md 파이프라인은 이미 그래프입니다.

EiC → Research → Outline → KR Writer → EN Writer
  → Humanizer → Reviewer → Fact Checker → SEO → Publisher(draft)
                         ↘ accuracy/score fail → revise (새 입력)
Publisher → Admin(human publish)

시리즈 오케스트레이터(series-draft-run.md)는 이 DAG를 slug 하나(WIP=1) 로 실행합니다. 7편 현장 노트는 같은 지도를 제품 레포에 어떻게 붙였는지 이야기합니다.

FAQ

Q. 멀티에이전트(3편)랑 그래프는 뭐가 다르죠?
A. 3편은 역할과 계약, 6편은 역할이 시간에 따라 어떻게 연결되는지(토폴로지) 입니다. 역할 없이 그래프만 그리면 빈 상자가 됩니다.

Q. 모든 워크플로를 LangGraph로 짜야 하나요?
A. 아니요. 단계가 Straight line이면 루프+체크리스트로 충분합니다. 분기·병렬·게이트가 늘 때 그래프 비용이 이깁니다.

Q. DAG인데 리뷰 루프가 있으면 모순 아닌가요?
A. 바깥 단계 의존성은 DAG로 두고, 품질 재시도는 서브그래프/노드 내부 루프로 격리하면 됩니다.

Q. 에스컬레이션을 자동 재시도로 대체할 수 있나요?
A. 예산 안에서만. 예산을 넘기면 사람 노드가 정답입니다(5편).

소스

시리즈에서 다음

#주제
01–05도구 → 바이브 → 멀티에이전트 → 하네스 → 루프
06그래프 (지금)
07PapaCoder 현장 노트 — 같은 패턴을 제품/레포에 붙인 이야기

다음에 읽을 글: 현장 노트 — 이론을 책상 밖으로.

지금까지의 한 줄: 선으로 안 되면 지도를 그리고, 바깥은 DAG·안은 루프, 막히면 사람 노드로.

Related posts

More in Tutorials

Comments

Checking sign-in…

No comments yet.