LabHub
배우기 러닝패스 코스

AI 에이전트 — 모델이 아니라 그래프 · 병렬 분기와 합치기 · 실습

갈래 하나가 죽자 답이 통째로 사라졌다

LabHub 에서 이어서 보기

목표

한 질문을 여러 자료원으로 동시에 흩뿌렸다가 다시 모은다. 같은 칸에 동시에 쓰면 무슨 예외가 나는지, 합쳐지는 순서가 무엇으로 정해지는지 직접 확인하고, 갯수가 실행 시점에 정해지는 갈래와 폭 상한, 부분 성공까지 만든다.

왜 중요한가

LangGraph 의 실행은 수퍼스텝 단위라, 한 수퍼스텝에서 갈 수 있는 노드가 여럿이면 그 노드들이 함께 돈다. 그래서 갈래를 늘리는 것은 엣지 몇 줄이면 된다. 어려운 것은 합치기다 — 같은 열쇠에 여러 값이 한꺼번에 들어올 때 리듀서가 없으면 InvalidUpdateError 로 그래프가 멈춘다. 순서대로 도는 그래프에서 조용히 덮어써지던 버그가 병렬로 바꾸는 순간 드러나는 것이라, 이 예외는 사실 친절한 편이다.
합쳐지는 순서도 오해하기 쉽다. "먼저 끝난 쪽이 앞" 이 아니다. 이 실습에서 이름을 바꿔 가며 직접 확인합니다.
자료원이 고정이 아니면 엣지를 미리 그릴 수 없다. Send 는 "이 노드를 이 입력으로 돌려라" 는 지시이고, 목록의 길이만큼 그 노드가 돈다. 그리고 그 노드는 전체 상태가 아니라 Send 가 넘긴 조각만 본다.
마지막으로 갈래 하나가 예외를 던지면 그 수퍼스텝 전체가 죽고 이미 성공한 갈래의 결과도 함께 사라진다. 실패를 값으로 돌려주면 부분 성공을 만들 수 있고, 실패한 자료원의 이름을 남기면 부분 결과가 전체 결과인 척하지 않게 된다.
채점기는 여러분이 적어 둔 설명을 믿지 않는다. 여러분의 모듈을 실제로 불러 임의의 주제와 임의의 노드 이름으로 돌려 보고, 채점기가 따로 계산한 값과 대조한다.

단계

1. /root/work/agpara/fanout.pySOURCES·hits·State·자료원마다의 노드·build_graph() 를 만드세요. START 에서 자료원 수만큼 갈라졌다가 END 로 갑니다. findings 는 이어 붙이는 리듀서를 씁니다.
2. conflict_demo(topic) 을 더해 리듀서가 없는 열쇠에 두 노드가 같은 수퍼스텝에 쓰면 무슨 예외가 나는지 잡아 {"error": ..., "message": ..., "note": ...} 로 돌려주게 하세요.
3. merge_order(names) 를 더해 노드 이름을 바꿔 가며 합쳐지는 순서를 직접 확인하게 하세요.
4. combine 노드를 더하고 갈래들을 END 대신 combine 으로 보내세요. combineranked(건수 내림차순, 동점이면 이름 오름차순)와 total 을 만듭니다.
5. plan·fan_out·probe·build_dynamic()·search_dynamic(topic, picked) 을 더해 Send 로 갯수가 실행 시점에 정해지는 갈래를 만드세요.
6. MAX_FANOUT = 2pick_sources(topic, limit=None) 을 더해 폭에 상한을 두세요. 건수가 많은 자료원부터, 동점이면 이름 순으로 고릅니다.
7. failures 열쇠와 run_partial(topic) 을 더해 갈래 하나가 못 찾아도 나머지 답이 살아남게 하세요.
8. /root/work/agpara/fanout_report.json/root/work/agpara/fanout_report.md 에 확인한 것을 기록하세요.

참고

단계 8개

  1. 한 번에 세 곳을 뒤진다
  2. 같은 칸에 동시에 쓰면 멈춘다
  3. 합쳐지는 순서는 우연이 아니다
  4. 갈래가 다 끝난 뒤 한 번 모은다
  5. 갯수가 실행 시점에 정해진다
  6. 폭에 상한을 둔다
  7. 하나가 실패해도 나머지는 살린다
  8. 확인한 것을 기록한다