항상 프로덕트를 만들다보면.. 새로운게 나오고
새로운게 나오면 이걸 우리꺼에다 적용시켰을 때 뭐가 더 유리할지에 대해 고민하는 시간이 길어지는것같다.
예전에는 하나하나 검색하고 찾아보면서 판단했었는데..
지금은 일단 claude에게 물어보는중..
이미 예전에 했었던 고민이였지만 그당시에는 이렇게 점점 고도화가 되지 않았었기 때문에
deep-agent deploy가 나온 시점.. 함게 deep-agent도 다시 고민해보는 시간을 갖었다..
새로운게 계속 나오니까 나올때마다 이고민중이다 ㅠ 설계너무어려워..
create_react_agent vs Deep Agent — 실제 실행 메커니즘 차이User: "강남역 지하철 도착 시간 알려줘"
LLM (1회 호출)
├─ System Prompt: "너는 도우미야"
├─ Tool descriptions: [a,b,c ..... ] ← 20개 전부 프롬프트에
├─ User: "강남역 지하철 도착 시간"
└─ LLM 판단: tool_call → search(search="강남")
└─ 결과 받아서 → LLM 최종 응답
이게 전부입니다. ReAct 루프는:
Think → Act(tool call) → Observe(결과) → Think → ... → 최종 답변
LLM 한 놈이 모든 걸 결정합니다. 도구 20개의 description을 전부 읽고, 어떤 도구를 쓸지 스스로 고릅니다.
User: "강남역 지하철 도착 시간 알려줘"
Supervisor (LLM 1회 호출) — 가벼운 라우터
├─ System Prompt: "아래 skill 중 적절한 것을 골라라"
├─ Skill 목록 (도구가 아니라 에이전트 이름):
│ ├─ "a" - search
│ ├─ "b"
│ ├─ "c"
│ ├─ "d"—
│ └─ "e" — 그냥 대화
├─ LLM 판단: → "search"
│
└─ Agent (별도 LLM 호출)
├─ System Prompt: "너는 한국 서비스 전문가야"
├─ Tool descriptions: [a] ← 1개만!
├─ Context: 원래 질문 + Supervisor가 전달한 맥락
└─ LLM 판단: tool_call → search(search="강남")
└─ 결과 받아서 → 최종 응답
create_react_agent | Supervisor + Skill | |
|---|---|---|
| LLM 호출 수 | 1회 (도구 사용 시 +1) | 2회 (분류 1회 + 실행 1회) |
| 도구 선택 | LLM이 20개 중 직접 선택 | Supervisor가 분야 선택 → Skill Agent가 3개 중 선택 |
| 프롬프트 크기 | 20개 도구 description 전부 (~2K 토큰) | Supervisor: 5줄 목록 (~200 토큰), Skill: 3개 description (~300 토큰) |
| 오선택 확률 | 비슷한 도구 많으면 혼동 | 단계적 축소 → 혼동 적음 |
본질적 차이는 "2단계 분류"입니다. 그 이상도 이하도 아닙니다.
Deep Agents 블로그에서 말하는 harness는 거창한 게 아닙니다:
# 이게 하네스의 전부입니다
harness = {
"supervisor": supervisor_agent, # 라우팅 에이전트
"skills": {
"search": search_agent, # Skill Agent 1
"math": math_agent, # Skill Agent 2
},
"memory": memory_store, # 대화 기록/학습된 패턴
"config": agents_md # AGENTS.md 설정 파일
}
# 실행
async def run(user_input):
skill_name = await harness["supervisor"].invoke(user_input) # 분류
result = await harness["skills"][skill_name].invoke(user_input) # 실행
return result
하네스 = Supervisor + Skill Agents + Memory + Config를 묶어놓은 실행 컨테이너
LangChain 코드로 치면:
from langgraph.prebuilt import create_react_agent
# Skill Agent들 정의
search_agent = create_react_agent(
model=llm,
tools=[a, b, c]
)
math_agent = create_react_agent(
model=llm,
tools=[d, f]
)
# Supervisor = 그냥 또 다른 에이전트인데, "tools" 대신 "agents"를 호출
supervisor = create_react_agent(
model=llm,
tools=[
Tool(name="search", func=search_agent.ainvoke, description="웹 검색"),
Tool(name="math", func=math_agent.ainvoke, description="수학 계산"),
]
)
Supervisor의 "도구"가 다른 에이전트를 호출하는 함수인 겁니다.
현재 시스템에서 도구 20개 중 오선택이 자주 발생하나요?
도구가 50개, 100개로 늘어날 예정이라면 지금 구조화해두는 게 맞고, 현재 20개 선에서 잘 돌아가고 있다면 굳이 바꿀 필요 없습니다.
이렇게 보면.. 또 클로드 코드분석했을때의 tool사용하는 방법이랑 비슷한것같기도 한데..
아마 좀 더 기능을 붙이면 나중에는 deep-agent를 써야하지 않을 까 싶다..
제대로 알아보고 이해한게 맞는지 여러번 되묻고 찾아보기도했는데
혹시나 알게되는 다른내용이라던지.. 잘못이해한 내용있다면 언제든 피드백 환영입니다!