06. 흐름 제어¶
일직선으로 흐르는 자동화만으로 부족할 때 씁니다.
| 하고 싶은 것 | 쓸 노드 |
|---|---|
| 값에 따라 다른 길로 가기 | CONDITIONAL |
| 갈라진 길을 다시 합치기 | JOINT |
| 배열을 하나씩 처리하기 | LOOP_START / LOOP_END |
조건 분기 — CONDITIONAL¶
값을 보고 갈 길을 고릅니다.
- id: route
name: 금액별 분기
type: CONDITIONAL
execution-info:
conditions:
- label: vip
expression: "amount >= 100000"
- label: normal
expression: "amount >= 10000"
- label: small
otherwise: true # 위 조건에 다 안 맞으면 여기로
edges:
- from: route
to: vip-handler
label: vip # ← label로 어느 가지인지 지정
- from: route
to: normal-handler
label: normal
- from: route
to: small-handler
label: small
핵심 규칙 세 가지입니다.
- 조건은 위에서부터 검사합니다. 먼저 맞는 것 하나만 실행됩니다.
label마다 나가는 엣지가 하나씩 있어야 합니다. 없으면 저장이 거부됩니다.otherwise: true는 "위에 아무것도 안 맞을 때" 가는 기본 가지입니다. 넣는 걸 권합니다.
조건이 볼 값은 엣지로 넘겨야 합니다¶
⚠️ 조건식은 ${input.*} 범위에서 평가됩니다. 들어오는 엣지에 request.data가 없으면 조건은 아무 값도 못 봅니다.
edges:
- from: fetch-order
to: route
request:
data:
amount: "${nodes.fetch-order.response.body.totalAmount}" # ← 이게 있어야
status: "${nodes.fetch-order.response.body.status}"
이렇게 넘긴 뒤 조건식에서는 이름만 씁니다.
쓸 수 있는 연산자¶
| 연산자 | 뜻 | 예 |
|---|---|---|
== |
같다 | status == 'paid' |
!= |
다르다 | status != 'cancelled' |
> >= < <= |
크기 비교 | amount >= 50000 |
contains |
포함한다 | message contains '환불' |
startsWith |
로 시작한다 | orderId startsWith 'ORD-' |
endsWith |
로 끝난다 | email endsWith '@company.com' |
- 문자열은 작은따옴표로 감쌉니다:
'paid' - 양쪽 다 숫자로 바뀌면 숫자 비교, 아니면 사전순 문자열 비교입니다.
AI 답변으로 분기하기¶
contains는 AI 응답을 보고 갈라질 때 특히 유용합니다.
- id: classify
name: 문의 분류
type: CALL
integration: llm_chat
input:
apiContract: OPENAI_CHAT
model: gpt-4o-mini
apiKey: "${secrets.OPENAI_API_KEY}"
systemPrompt: "고객 문의를 딱 한 단어로 분류해라: 환불 / 배송 / 상품문의 / 기타. 다른 말은 하지 마라."
userPrompt: "${nodes.trigger.response.body.message}"
- id: route
name: 분류별 분기
type: CONDITIONAL
execution-info:
conditions:
- label: refund
expression: "category contains '환불'"
- label: delivery
expression: "category contains '배송'"
- label: other
otherwise: true
edges:
- from: classify
to: route
request:
data:
category: "${nodes.classify.response.body.content}"
- from: route
to: refund-flow
label: refund
- from: route
to: delivery-flow
label: delivery
- from: route
to: default-flow
label: other
AI가 딱 한 단어만 답하도록
systemPrompt에서 못 박아두는 게 요령입니다. 그래도 완벽하진 않으니otherwise가지는 꼭 두세요.
합류 — JOINT¶
갈라진 길이 다시 만나는 자리입니다. 여러 선이 들어올 수 있는 유일한 노드입니다.
설정할 게 아무것도 없습니다. type만 적으면 끝입니다.
하는 일¶
들어오는 모든 가지가 끝날 때까지 기다립니다. 전부 끝나면 다음 노드로 넘어갑니다. 두 API를 동시에 부르고 둘 다 온 다음에 처리하고 싶을 때 씁니다.
edges:
- from: trigger
to: fetch-orders
- from: trigger
to: fetch-stock
- from: fetch-orders
to: join
- from: fetch-stock
to: join
- from: join
to: summarize
⚠️ JOINT는 자기 출력이 없습니다¶
JOINT는 기다리기만 합니다. 값을 만들지 않습니다. 그 뒤 노드에서는 JOINT 앞의 노드를 직접 참조하세요.
# ❌
userPrompt: "${nodes.join.response.body.data}"
# ✅
userPrompt: |
주문: ${nodes.fetch-orders.response.body.data}
재고: ${nodes.fetch-stock.response.body.data}
반복 — LOOP_START / LOOP_END¶
배열을 받아 원소마다 같은 처리를 반복합니다.
- id: each-order
name: 주문별 반복 시작
type: LOOP_START
execution-info:
items: "${nodes.fetch-orders.response.body.data | raw}" # ← 반복할 배열
# ─── 여기부터 반복 본문 ───
- id: notify-each
name: 주문별 알림
type: CALL
integration: http_request
input:
uri: "https://api.example.com/notify"
method: POST
body:
orderId: "${item.orderId}" # ← 현재 원소
순번: "${index}" # ← 0부터 시작하는 회차
# ─── 반복 본문 끝 ───
- id: collect
name: 반복 집계
type: LOOP_END
execution-info:
loop-start: each-order # ← 짝이 되는 LOOP_START의 id
규칙¶
LOOP_START와LOOP_END는 반드시 짝입니다. 하나만 있으면 저장이 거부됩니다.items에는| raw를 꼭 붙이세요. 없으면 배열이 문자열이 되어 반복이 안 됩니다.- 반복 본문의 모든 길은
LOOP_END로 모여야 합니다. - 반복 안에는
CONDITIONAL을 넣을 수 없습니다. (아래 참고)
루프 안에서 쓰는 값¶
| 표현식 | 뜻 |
|---|---|
${item} |
현재 원소 전체 |
${item.필드} |
현재 원소의 특정 필드 |
${index} |
몇 번째인지 (0부터) |
이 값들은 LOOP_START와 LOOP_END 사이에서만 유효합니다.
반복 안에서 분기하고 싶다면¶
CONDITIONAL은 루프 안에 못 넣습니다. 가지가 하나 잘리면 LOOP_END로 모일 길이 없어지기 때문입니다.
대안 두 가지입니다.
대안 1 — 반복 전에 미리 걸러내기 (대부분 이걸로 충분합니다)
- id: filter
name: 처리 대상만 추리기
type: CALL
integration: transform_jmespath
input:
expression: "{targets: orders[?status == `paid`]}"
data: "${nodes.fetch-orders.response.body | raw}"
- id: each
type: LOOP_START
execution-info:
items: "${nodes.filter.response.body.targets | raw}"
대안 2 — 반복 밖에서 분기하기
집계 결과를 LOOP_END 다음에 CONDITIONAL로 판단합니다.
그래프 규칙 정리¶
저장할 때 검사되는 규칙입니다. 어기면 저장이 거부되고 무엇이 문제인지 알려줍니다.
| 규칙 | 내용 |
|---|---|
| 시작점 | ENTRYPOINT는 정확히 하나, 들어오는 선 0개 |
| 다중 입력 | 선이 2개 이상 들어올 수 있는 건 JOINT뿐 |
| 순환 금지 | 화살표를 따라가다 제자리로 돌아오면 안 됨 |
| 노드 id | 워크플로우 안에서 고유해야 함 |
| 엣지 참조 | from / to가 실제 존재하는 노드를 가리켜야 함 |
| 조건 분기 | 모든 label에 나가는 엣지가 있어야 함 |
| 루프 | LOOP_START와 LOOP_END가 짝을 이루고, 본문이 LOOP_END로 수렴해야 함 |
| 루프 안 분기 | 루프 본문에 CONDITIONAL 금지 |
| 크기 | 노드 최대 200개, YAML 최대 256,000자 |
다음 → 07. 연결 관리