18차시. State 이해
4. 실습 ① — State 정의하고 흐름 보기
출처: 원본 PDF 18차시_State이해.pdf 9쪽 · 쪽 그림 9쪽
📝 src/state_demo.py
from typing import TypedDict, List
from langgraph.graph import StateGraph, START, END
class DemoState(TypedDict):
question: str
documents: List[str]
answer: str
def retrieve(state: DemoState):
print("[retrieve] 받은 State:", state)
return {"documents": ["조각A", "조각B"]}
def generate(state: DemoState):
print("[generate] 받은 State:", state)
n = len(state["documents"])
return {"answer": f"{n}건의 근거로 만든 답변"}
g = StateGraph(DemoState)
g.add_node("retrieve", retrieve)
g.add_node("generate", generate)
g.add_edge(START, "retrieve")
g.add_edge("retrieve", "generate")
g.add_edge("generate", END)
app = g.compile()
final = app.invoke({"question": "환불 규정은?"})
print("\n[최종] State:", final)
실행 결과
─────────────────────────────────────────────
─────────
[retrieve] 받은 State: {'question': '환불 규정은?'}
[generate] 받은 State: {'question': '환불 규정은?',
'documents': ['조각A', '조각B']}
[최종] State: {'question': '환불 규정은?',
'documents': ['조각A', '조각B'],
'answer': '2건의 근거로 만든 답변'}🔍 출력에서 읽어낼 것
① 처음엔 question만 있습니다
invoke에 넣은 값만 들어 있습니다
② generate 차례가 되니 documents가 생겼습니다
retrieve가 반환한 것이 State에 합쳐졌습니다
③ question은 계속 살아 있습니다
아무도 반환하지 않았는데도 유지됩니다
④ 최종 State에 모든 것이 쌓였습니다
노드를 지날 때마다 내용이 늘어났습니다
실습 코드 · 18/state_demo.py
실습 코드: 실습/src/18/state_demo.py · 위의 원본 PDF 18차시 9쪽 「4️⃣ 실습 ① — State 정의하고 흐름 보기」과 이어집니다.
# ============================================================
# 18차시 | State 이해
# 교안: 18차시_State이해.pptx
# 역할: 두 노드가 같은 State(공유 노트)를 이어 받는 모습을 출력으로 확인한다.
# 입력: question, documents, answer
# 출력: documents 와 answer 가 채워진 최종 State
#
# State = 그래프 전체의 공용 딕셔너리. 노드 사이 지역 변수가 아니다.
# 앞 노드가 쓴 키가 다음 노드의 인자로 그대로 들어온다.
# Node = retrieve, generate. 고친 키만 return 하면 그 칸만 덮어쓴다.
# Edge = START → retrieve → generate → END. 갈림길은 없다.
# START / END = 시작과 끝.
# compile = 연결 확정. invoke = 초기 State로 끝까지 실행한 최종 State.
#
# 흐름
# START
# |
# v
# retrieve 읽기 question / 쓰기 documents
# |
# v
# generate 읽기 question, documents / 쓰기 answer
# |
# v
# END
# ============================================================
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
class DemoState(TypedDict):
"""그래프 전체에서 공유할 데이터를 정의합니다."""
question: str # 사용자 질문
documents: list[str] # 검색된 문서
answer: str # 최종 답변
# 노드 retrieve
# 읽기: question (출력으로 노트 전체를 보여 준다)
# 쓰기: documents
def retrieve(state: DemoState):
"""질문을 받아 관련 문서를 검색하는 노드입니다."""
# 현재 State가 어떻게 전달되었는지 확인합니다.
print("[retrieve] 받은 State:", state)
# 실제 검색 대신 테스트용 문서를 반환합니다.
documents = ["조각A", "조각B"]
# documents만 State에 업데이트합니다.
return {"documents": documents}
# 노드 generate
# 읽기: question, documents
# 쓰기: answer
def generate(state: DemoState):
"""검색된 문서를 이용해 답변을 만드는 노드입니다."""
# retrieve에서 추가한 documents도 함께 전달됩니다.
print("[generate] 받은 State:", state)
# 검색된 문서 개수를 계산합니다.
document_count = len(state["documents"])
# 문서 개수를 이용해 간단한 답변을 만듭니다.
answer = f"{document_count}건의 근거로 만든 답변"
# answer만 State에 업데이트합니다.
return {"answer": answer}
# DemoState를 사용하는 그래프를 만듭니다.
graph = StateGraph(DemoState)
# 그래프에 노드를 등록합니다.
graph.add_node("retrieve", retrieve)
graph.add_node("generate", generate)
# START → retrieve → generate → END 순서로 연결합니다.
graph.add_edge(START, "retrieve")
graph.add_edge("retrieve", "generate")
graph.add_edge("generate", END)
# compile: 직선 연결을 실행 앱으로 확정한다.
app = graph.compile()
# 처음 사용할 State를 만듭니다.
initial_state = {
"question": "환불 규정은?",
"documents": [],
"answer": ""
}
# invoke: 초기 노트를 넣고 END까지의 최종 노트를 받는다.
final_state = app.invoke(initial_state)
# 모든 노드 실행이 끝난 최종 State를 출력합니다.
print("\n[최종] State:", final_state)실행 결과 샘플 (교안 기록. API 키가 필요한 코드는 키 없이 맞춘 예시이고, 모델의 답은 실행할 때마다 달라집니다)
===== 실행 결과 샘플 =====
실행: cd 실습/src/18
python state_demo.py
(실제 실행 출력)
[retrieve] 받은 State: {'question': '환불 규정은?', 'documents': [], 'answer': ''}
[generate] 받은 State: {'question': '환불 규정은?', 'documents': ['조각A', '조각B'], 'answer': ''}
[최종] State: {'question': '환불 규정은?', 'documents': ['조각A', '조각B'], 'answer': '2건의 근거로 만든 답변'}
경로: retrieve → generate → END코드 해설
두 노드가 같은 State(공유 노트)를 이어 받는 모습을 출력으로 확인한다. 입력은 question, documents, answer이고, 출력은 documents 와 answer 가 채워진 최종 State입니다.
주석에 적힌 흐름입니다.
흐름
START
|
v
retrieve 읽기 question / 쓰기 documents
|
v코드 앞에서 고정해 두는 말입니다.
- 18차시 | State 이해
- 교안: 18차시_State이해.pptx
- State = 그래프 전체의 공용 딕셔너리. 노드 사이 지역 변수가 아니다.
- 앞 노드가 쓴 키가 다음 노드의 인자로 그대로 들어온다.
- Node = retrieve, generate. 고친 키만 return 하면 그 칸만 덮어쓴다.
- Edge = START → retrieve → generate → END. 갈림길은 없다.
- START / END = 시작과 끝.
- compile = 연결 확정. invoke = 초기 State로 끝까지 실행한 최종 State.
함수와 클래스로 나누어 읽습니다.
DemoState: 그래프 전체에서 공유할 데이터를 정의합니다.retrieve: 노드 retrieve 읽기: question (출력으로 노트 전체를 보여 준다) 쓰기: documentsgenerate: 노드 generate 읽기: question, documents 쓰기: answer
파일 맨 아래 실행 결과 샘플 주석은 실행되지 않습니다. 화면 출력은 다음 절에 다시 적어 두었습니다.