react_agent.py 파이프라인

질문 하나가 graph.stream() 안에서 어떤 노드를 거치고, State의 messages가 어떻게 쌓이는지

1. 그래프와 데이터 흐름

AgentState.messages Annotated[list, add_messages] — 노드가 돌려준 메시지는 덮어쓰지 않고 뒤에 append Human AI (tool_calls) Tool Tool AI (최종) … 질문 HumanMessage(q) START agent 노드 ① [SystemMessage(전략)] + messages ② llm_with_tools.invoke() ③ {"messages": [AIMessage]} 반환 System은 State에 저장 안 됨 (매번 앞에 붙임) 읽기 AIMessage append tool_calls? should_continue 없음 END 마지막 AI = 답변 있음 tools 노드 ToolNode — 실행 결과를 ToolMessage로 포장 search_employee 더미 dict 조회 calculate eval (builtins 차단) classify_request 도구 안에서 LLM 호출 마지막 AI의 tool_calls 읽기 ToolMessage append 사이클 add_edge("tools","agent") Bedrock · Claude Sonnet 4.5 ChatBedrockConverse (us-east-1) bind_tools 버전 (도구 스키마 포함) plain llm · 부서명만
실선은 그래프 엣지와 State 읽기/쓰기, 점선은 LLM 호출. agent와 classify_request는 같은 Bedrock 모델을 부르지만, agent는 도구 스키마가 붙은 llm_with_tools, 도구 안쪽은 도구 없는 llm을 씁니다. 파란 엣지가 수동 루프의 while을 대신하는 사이클입니다.

2. 질문 1에서 messages가 쌓이는 순서

step 1 · agent step 2 · tools step 3 · agent LLM에 System + 1개 도구 2개 실행 LLM에 System + 4개 Human김하늘 팀 + 10% 인상 AI · tool_calls 2개 search_employee(김하늘) · calculate("3480000 * 1.1") → tool_calls 있음 → tools Human AI · tool_calls Tool · search_employee클라우드운영팀 / 이메일 Tool · calculate3828000.0… → 다시 agent (사이클) Human AI · tool_calls Tool Tool AI · 텍스트tool_calls 없음 → END
노란 칸이 그 step에서 노드가 돌려준 메시지(= stream_mode="updates"로 받는 값)이고, add_messages가 그것을 뒤에 붙입니다. 모델이 두 도구를 한 번에 부른다고 가정한 흐름이라, 하나씩 부르면 agent↔tools 왕복이 한 번 더 생깁니다. 질문 2는 classify_request 한 번 → agent → END로 같은 3 step 모양입니다.

수동 루프와 대응