RAG2026-5일21차시 · 첫 번째 LangGraph 실습9 / 19← 이전목차다음 →MetaContents

21차시. 첫 번째 LangGraph 실습

6. invoke vs stream

출처: 원본 PDF 21차시_첫번째LangGraph실습.pdf 11~12쪽 · 쪽 그림 11쪽 12쪽

그래프를 실행하는 방법은 두 가지입니다. 상황에 따라 골라 씁니다.

방식반환쓰는 상황
invoke최종 State 하나결과만 필요할 때 · 운영 환경
stream노드별 중간 결과를 순차 반환디버깅 · 진행 상황 표시
astream비동기 스트리밍웹 서비스 실시간 출력
get_graph()그래프 구조 객체구조 확인 · 시각화

6-1) invoke — 결과만

Python
result = app.invoke(init("환불 규정은?"),
                    {"recursion_limit": 15})

print("답변:", result["answer"])
print("재시도:", result["retries"])
print("로그:", result["log"])

실행 결과 예시 (코드를 읽고 만든 예상 화면입니다. 실제 실행 결과, 특히 모델의 답은 다를 수 있습니다)

출력
   → retrieve: 3건
   → generate: 부실한 답변
   → verify: 재시도
   → bump: 1회차
   → generate: 좋은 답변
   → verify: 통과
답변: 3건 근거로 만든 좋은 답변
재시도: 1
로그: ['검색 3건', '생성(부실한)', '검증 실패', '재시도 1', '생성(좋은)', '검증 통과']

6-2) stream — 과정까지

출력
for step in app.stream(init("환불 규정은?"),
                       {"recursion_limit": 15}):
    for node, update in step.items():
        print(f"[{node}] {update}")

stream 출력
──────────────────────────────────────────
   → retrieve: 3건
[retrieve] {'documents': [...], 'log': ['검색 3건']}
   → generate: 부실한 답변
[generate] {'answer': '...부실한 답변', 'log': [...]}
   → verify: 재시도
[verify]   {'grade': 'retry', 'log': ['검증 실패']}
   → bump: 1회차
[bump]     {'retries': 1, 'log': ['재시도 1']}
   → generate: 좋은 답변           ← 루프가 돌았다!
[generate] {'answer': '...좋은 답변', 'log': [...]}
   → verify: 통과
[verify]   {'grade': 'pass', 'log': ['검증 통과']}

🎯 stream이 보여주는 것
루프가 실제로 돌았다는 증거가 보입니다.
generate가 두 번 등장하고,
두 번째에는 "좋은 답변"이 나와서 통과했습니다.
invoke만 썼다면 최종 결과만 보이니
루프가 돌았는지조차 몰랐을 겁니다.
개발 중에는 무조건 stream을 쓰세요.

← 이전 절21차시 · 5. 실습 ③ — 그래프 조립다음 절 →21차시 · 7. 실습 ④ — 세 가지 경로 모두 확인하기