day6_practice/specialist_agents.py

서브 Agent 3종: 누가 뭘 호출했나

Supervisor로 조립하기 전에 전문가 Agent 3개(데이터 조회, 규정 검색, 일반 응대)를 만들고, solo_test()로 하나씩 따로 불러 보는 실습입니다. 아래 콜 맵과 플레이어의 호출 순서, 인자, 결과, 토큰은 모두 실제로 돌려서 기록한 값입니다.

콜 맵: 실행 한 번에 일어난 호출 전부

__main__이 solo_test()를 4번 부르고, 각 Agent는 자기 worker_llm(Bedrock Claude Sonnet 4.5)을 부르고, LLM이 고른 도구만 실행됩니다. 아직 Supervisor는 없습니다. 세 Agent는 서로 모르고, __main__이 직접 하나씩 부릅니다.

__main__ 124~128줄 ① solo_test(data_agent,"…임직원 명단 알려줘") ② solo_test(data_agent,"연차 규정 알려줘") ③ solo_test(research_agent,"출장 숙박비 한도 얼마야?") ④ solo_test(general_agent,"안녕! 뭘 할 수 있어?") data_agent 임직원·자산·프로젝트 조회 LLM 3번 · 도구 1번 research_agent 사내 규정 검색 LLM 2번 · 도구 1번 general_agent 인사·잡담 (도구 없음) LLM 1번 · 도구 0번 🧠 worker_llm Bedrock Sonnet 4.5 ×3 ×2 ×1 search_employee(name) · 미호출 list_team_members(team) ✔ ①에서 1번 team='클라우드운영팀' get_asset(owner) · 미호출 list_projects(team) · 미호출 retrieve_docs(query) ✔ ③에서 1번 query='출장 숙박비 한도' tools=[] → tools 노드 자체가 없음 도구는 전부 더미 (4번째 세션에서 RAG·MCP로 교체)
이번 실행에서 실제로 호출됨 연결은 됐지만(쓸 수 있는 도구) 이번엔 안 부름 LLM 호출 (×횟수)

4개 테스트 한눈에: 호출 순서

solo_test 호출 model (LLM 호출) tools (도구 실행) 결과 반환·출력
tool_calls 있음 ToolMessage 들고 tool_calls 없음 result 반환 🧠 worker_llm Bedrock Sonnet 4.5 · temp 0 LLM 호출! solo_test() agent.invoke(...) START model data_agent tools ToolNode END

🎒 State["messages"]

🖥️ 터미널 출력

specialist_agents.py

호출 횟수 (실제 실행)

테스트AgentLLM 호출도구 호출 (인자)토큰 (LLM 호출별)결과

합계: LLM 번, 도구 번. 토큰은 각 LLM 응답의 usage_metadata.total_tokens입니다. 시스템 프롬프트와 도구 설명이 매번 같이 들어가서, 도구 4개를 가진 data_agent는 질문이 짧아도 한 번에 1,400토큰대가 나옵니다.

누가 무엇을 정하나

🧑‍💻 코드 (우리가 정함)

어떤 Agent를 부를지는 __main__이 정합니다(124~128줄에 직접 적음). 아직 라우터나 Supervisor가 없으니 질문이 Agent 담당 밖이어도(②) 그 Agent로 갑니다. 각 Agent가 쓸 수 있는 도구 목록도 create_agent(llm, [도구들])로 우리가 정합니다.

🧠 LLM (실행 중에 정함)

도구를 쓸지, 어떤 도구를, 어떤 인자로 부를지는 LLM이 정합니다. 근거는 시스템 프롬프트와 도구의 docstring입니다. ①에서 list_team_members를 고른 건 81줄 "팀 명단과 인원수는 list_team_members"와 30줄 docstring 덕분이고, ②에서 도구 없이 거절한 건 83줄 규칙 때문입니다.

🔁 create_agent (틀을 만들어 줌)

도구가 있으면 START → model ⇄ tools → END 루프를, 도구가 없으면 START → model → END만 만듭니다(실제 그래프 확인: general_agent엔 tools 노드가 없음). model 노드는 LLM을 부르고, 응답에 tool_calls가 있으면 tools로, 없으면 END로 갑니다.

🔧 ToolNode (실행만 함)

tools 노드는 LLM이 낸 tool_calls를 보고 해당 파이썬 함수를 그 인자로 실행한 뒤, 결과를 ToolMessage(tool_call_id=…)로 State에 넣습니다. 판단은 하지 않습니다. 그 결과를 들고 model로 돌아가 LLM이 최종 답을 씁니다.

알아둘 점