탐색은 search agent. 평가는 eval agent. 보고는 report agent.
오케스트레이터가 셋을 조율한다.
각자의 시스템 프롬프트는 작고 분명해진다.
각 에이전트는 자기 역할에 필요한 툴만 가진다.
컨텍스트가 좁아지므로 LLM이 헷갈릴 일이 줄어든다.
from tools_specs import make_tools all_tools = make_tools() search_tools = [t for t in all_tools if t["function"]["name"] in ["execute_sql", "retrieve_from_rag"]] eval_tools = [t for t in all_tools if t["function"]["name"] in ["execute_sql", "get_confluence_page_content"]] report_tools = [t for t in all_tools if t["function"]["name"] in ["save_excel", "send_email"]]
전체 카탈로그에서 역할에 맞는 부분만 잘라 전달.
각 에이전트는 자기 영역 바깥의 툴은 호출할 수 없다 — 부주의한 호출도 방지.
def run_agent(system_prompt, user_message, tools, max_steps=10): # Chapter 8의 handle_request와 동일한 피드백 루프 ... def search_agent(result): output = run_agent(search_system_prompt, f"목표: {result['goal']}", search_tools) result["resume_ids"] = output return result def eval_agent(result): output = run_agent(eval_system_prompt, f"이력서: {result['resume_ids']}\n목표: {result['goal']}", eval_tools) result["eval_result"] = output return result def report_agent(result): run_agent(report_system_prompt, f"평가 결과: {result['eval_result']}", report_tools) result["report_done"] = True return result
def orchestrator(result): status = f""" 목표: {result['goal']} search 완료: {'완료' if result.get('resume_ids') else '미완료'} eval 완료: {'완료' if result.get('eval_result') else '미완료'} report 완료: {'완료' if result.get('report_done') else '미완료'}""" message = generate_response([{"role": "system", "content": orchestrator_system_prompt}, {"role": "user", "content": status}]) decision = json.loads(message.content) return decision.get("next_agent", "end") AGENT_MAP = {"search": search_agent, "eval": eval_agent, "report": report_agent} def run_multi_agent(goal, max_steps=10): result = {"goal": goal, ...} for _ in range(max_steps): next_agent = orchestrator(result) if next_agent == "end": break result = AGENT_MAP[next_agent](result) return result
완료 상태 보고 → 다음 결정 → 실행 → 완료 상태 → 결정 → ...
완료 횟수만큼 LLM 호출.
처음 한 번 호출 → ["search", "eval", "report"] 계획 수립 → 순서대로 실행.
LLM 호출 1번으로 끝.
def planning_orchestrator(result): if not result.get("plan"): # 처음 한 번만 계획 수립 result["plan"] = make_plan_for_agents(result["goal"])["plan"] result["current_step"] = 0 i = result["current_step"] if i >= len(result["plan"]): return "end" result["current_step"] = i + 1 return result["plan"][i]
system prompt가 LLM의 기본 행동을 정의한다.
history list로 매번 통째로 다시 전달.
LLM이 못 하는 일을 대신하는 일반 파이썬 함수.
코드가 결정 → LLM이 결정. JSON → tool_calls API.
피드백 루프(ReAct) → Planning → Multi-Agent. 복잡도에 따라.
이 다음은 도메인.
채용 평가가 아니라 여러분의 업무에 같은 패턴을 적용해보세요.
더 깊이 — MCP · LangGraph · AutoGen · OpenAI Assistants API.
모두 이 열 장에서 본 패턴의 변주.