RAG(2일차) + MCP(4일차) + Supervisor(6일차)를 한 파일에 합친 마지막 시나리오입니다. 이 페이지는 파일을 위에서 아래로 실행되는 순서대로 따라갑니다. 먼저 부품이 어떻게 조립되는지(1~8단계), 그다음 질문 하나가 들어와 Agent들이 일하는 과정(9~24단계)입니다. 호출 순서, 인자, 토큰, 터미널 출력은 모두 실제로 돌려서 기록한 값입니다(서브 Agent 안쪽까지 보려고 subgraphs=True로 따로 기록).
위에서 아래로 진입 → 조율 → 전문 Agent → 자원 4층입니다. 각 상자의 L49-58은 final_scenario.py의 줄 번호입니다. 점선 상자는 코드 밖에 있는 외부 시스템입니다.
python final_scenario.py를 치면 ① import 시점에 만들어지는 것, ② asyncio.run(main()) 안에서 만들어지는 것, ③ 질문을 처리하는 루프 순서로 진행됩니다. 소스에 보이는 순서와 실제 실행 순서가 다른 곳이 있습니다(build_app은 정의만 위에 있고 실제로는 맨 마지막 줄 asyncio.run이 불러야 실행됩니다).
세로줄이 주체, 가로 화살표가 호출입니다. 🧠는 LLM을 부른 지점이고 번호 옆 숫자는 그 호출의 토큰입니다. 파란 배경은 main()의 print가 못 보는 서브 Agent 안쪽이고, 붉은 줄은 에러로 끝난 호출입니다.
main()은 stream_mode="updates"로 바깥 그래프 노드가 끝날 때마다 그 노드가 돌려준 메시지를 찍습니다. 바깥 업데이트는 5번 왔고, 이번 실행에서 찍힌 줄은 줄입니다. 그중 줄은 앞에서 이미 찍은 줄의 반복(주황색)입니다.
supervisor 업데이트는 그때까지의 대화 전체를 담고 있습니다(3개 → 8개 → 12개로 늘어남). 그래서 앞에서 이미 찍은 줄이 매번 또 찍힙니다. State에는 중복이 없습니다. 같은 id의 메시지는 add_messages가 교체하므로 최종 State는 12개입니다.
라벨은 m.name or node입니다. 사용자 질문(HumanMessage)은 name이 없어서 [supervisor] 출장 규정에서…처럼 supervisor가 말한 것처럼 찍힙니다. 도구 호출 줄은 항상 node를 쓰므로(131줄) research_agent가 만든 transfer_back_to_supervisor가 나중엔 [supervisor] 도구: …로 찍힙니다.
get_text(m)[:200] 때문에 research_agent의 긴 보고서와 Supervisor의 최종 보고서는 앞 200자만 보입니다. 터미널로는 최종 답의 결론(맨 끝)을 볼 수 없습니다. 전체를 보려면 마지막 업데이트의 마지막 메시지를 따로 전부 출력해야 합니다.
retrieve_docs, list_team_members, list_projects, data_agent의 LLM 호출 3번, 그리고 에러가 났던 호출까지 바깥 그래프에서는 보이지 않습니다. 안쪽 이벤트는 app.astream(..., subgraphs=True)로 받아야 나옵니다. 이 페이지의 안쪽 기록이 그렇게 뽑은 것입니다.
| 누가 | 무엇을 | 횟수 | 토큰 (호출별) | main()에 보임? |
|---|
research_agent와 general_agent는 모듈 맨 위(import 시점)에서 만들어지고, data_agent와 Supervisor는 async def build_app() 안에서 만들어집니다. MCP 도구를 가져오는 await client.get_tools()가 비동기라서 그 뒤에 오는 data_agent도 함수 안에 들어가야 하기 때문입니다.
Supervisor LLM은 transfer_to_research_agent({})처럼 빈 인자로 담당을 고릅니다. "무엇을 해라"는 말이 없으니 서브 Agent는 원래 질문 전체와 지금까지의 대화를 그대로 받습니다. 서브 Agent는 돌려줄 때 마지막 메시지 하나만 내보냅니다(output_mode="last_message").
client.get_tools()를 세션 없이 부르면, 가져온 도구는 실행할 때마다 서버를 새로 띄웁니다. 이번 실행의 stderr에 Starting MCP server가 번 찍혔습니다. 도구 목록을 가져올 때 1번, list_team_members와 list_projects를 부를 때 2번입니다. 그래서 MCP 도구가 첫 호출에 1~2초 더 걸립니다.
Supervisor 프롬프트 107줄 "여러 요구가 섞인 질문은 각 Agent를 순서대로 호출" 때문인지, 이번엔 research → data 순으로 하나씩 넘겼습니다(2번 돌려 2번 다 그랬습니다). 앞서 verify_routing.py의 ④ 질문에서는 두 Agent를 한 응답에 같이 요청해 실패했습니다. 프롬프트로 유도할 뿐 보장은 아닙니다.