TL;DR — 도구 사용(Tool Use)은 LLM에게 손과 발을 달아주는 패턴입니다. 입력 → LLM → 출력(끝) 대신, LLM이 외부 도구(API·DB·코드 실행기)를 호출해 실시간 데이터·정확한 계산·실제 행동을 수행합니다. 핵심은 6단계 루프(정의 → 결정 → 호출 생성 → 실행 → 관찰 → 처리). Function Calling은 "어떻게"(JSON 호출 생성), Tool Use는 "무엇을"(API·DB·다른 에이전트)입니다. 좋은 도구의 8할은 명확한 이름·docstring·Pydantic 스키마·구조화 반환·에러 처리에서 갈립니다. LangChain(@tool)·LangGraph(ReAct)·Google ADK(FunctionTool)로 구현하고, 단순 호출엔 Tool Calling Agent(빠름)·다단계 추론엔 ReAct Agent(투명)를 씁니다.
1. 왜 도구 사용인가 — 똑똑하지만 갇혀 있는 두뇌
지금까지의 네 편은 모두 LLM 안에서 텍스트를 다뤘습니다. 1편 프롬프트 체이닝은 작업을 순서대로 쪼갰고, 2편 라우팅은 입력에 따라 길을 나눴으며, 3편 병렬화는 독립 작업을 동시에 던졌고, 4편 리플렉션은 쓴 결과를 다시 읽고 고쳤습니다. 그런데 이 모든 건 모델이 이미 학습한 지식 위에서만 돌아갑니다. LLM에게 이렇게 물어보면 곧장 벽에 부딪힙니다.
“지금 서울 날씨 어때?” “우리 창고에 P001 재고 몇 개야?” “100만원을 연 5%로 10년 복리로 굴리면?” “고객한테 배송 지연 메일 보내줘.” — 모델은 오늘 날씨를 모르고, 우리 회사 DB에 접근할 수 없고, 큰 수의 계산을 종종 틀리며, 메일을 보낼 손이 없습니다. 아무리 똑똑해도 도서관에 갇혀 전화도 인터넷도 없는 천재인 셈이죠.
도구 사용은 이 천재에게 전화기와 계산기, 그리고 외부 세계로 통하는 문을 쥐어 줍니다. 에이전트가 "생각"을 넘어 처음으로 "행동"하게 되는 순간이고, 그래서 진짜 에이전트(Agent)가 시작되는 지점이기도 합니다.
2. Tool Use vs Function Calling — "무엇을" 과 "어떻게"
두 용어가 자주 섞여 쓰이지만, 정확히는 범위가 다릅니다. 한 문장으로 정리하면 — Function Calling은 "어떻게" 부르는지(기술), Tool Use는 "무엇을" 부를 수 있는지(개념)입니다.
| 용어 | 범위 | 설명 |
|---|---|---|
| Tool Use | 넓은 개념 | API·DB·코드 실행기·다른 에이전트까지 포함하는 포괄적 개념 |
| Function Calling | 구체적 메커니즘 | LLM이 JSON 형태로 함수 호출을 생성하는 기술적 방법 |
결정적 오해를 하나 풀고 갑시다. LLM은 함수를 직접 실행하지 않습니다. 모델이 하는 일은 오직 “get_weather라는 도구를 location="서울"로 불러 줘”라는 JSON 의도를 내놓는 것까지입니다. 그 JSON을 받아 진짜 파이썬 함수를 실행하는 건 프레임워크(런타임)의 몫이죠. 이 분업을 이해하면 뒤의 6단계가 한눈에 들어옵니다.
3. 6단계 실행 흐름 — 정의부터 최종 응답까지
도구 호출은 언제나 같은 6단계를 돕니다. 어느 프레임워크를 쓰든 본질은 동일하니, 이 흐름만 머릿속에 박아 두면 됩니다.
6단계의 마지막이 핵심입니다. 도구 결과를 받은 LLM은 곧장 답할 수도 있지만, “아직 정보가 부족하다”고 판단하면 2단계로 되돌아가 또 다른 도구를 부릅니다. 이 반복이 바로 다단계 작업의 엔진이고, 바로 뒤 6장에서 다룰 ReAct 패턴의 뼈대입니다. 아래는 한 번에 끝나는 경우와, 여러 번 도는 경우의 차이입니다.
4. 진짜 승부처 — 좋은 도구를 설계하는 법
초보가 가장 오해하는 부분이 여기입니다. 도구 사용의 성패는 화려한 프레임워크가 아니라 도구를 얼마나 잘 정의했느냐에서 갈립니다. LLM은 이름과 docstring(설명)만 보고 어떤 도구를 부를지 결정하기 때문에, 도구 설명서가 곧 프롬프트입니다. 같은 기능도 이렇게 달라집니다.
현업에서 검증된 다섯 가지 원칙이 있습니다. 이 다섯을 지키면 도구 선택 실패(엉뚱한 도구 호출)와 파싱 오류가 눈에 띄게 줄어듭니다.
- ① 명확한 이름 —
동사+명사(get_customer·create_order).process_data같은 모호한 이름 금지 - ② 상세한 docstring — 목적·파라미터·반환값을 LLM이 이해하도록 기술(예시 포함)
- ③ Pydantic 스키마 — 타입 안전성 +
Field(description=...)로 파라미터 설명 + 값 범위(ge·le) 제한 - ④ 구조화된 반환값 — 항상 같은 형식
{"status": "...", "data": {...}, "error": "..."} - ⑤ 에러 처리 — 모든 예외를
try/except로 잡아 구조화된 오류 반환(recoverable명시)
[search_products, get_faq]만, 인증 후엔 place_order·update_profile까지 — 도구가 많아질수록 LLM이 헷갈리므로, 지금 필요한 도구만 노출하는 게 정확도와 보안 양쪽에 이롭습니다.5. 구현 ① LangChain — @tool 데코레이터 + AgentExecutor
가장 직관적입니다. 평범한 파이썬 함수에 @tool 한 줄만 붙이면 LLM이 호출할 수 있는 도구가 됩니다. create_tool_calling_agent로 LLM·도구·프롬프트를 엮고, AgentExecutor가 도구 호출 루프를 자동으로 굴립니다.
핵심 부품은 셋입니다. @tool(함수를 도구로 변환), agent_scratchpad(도구 호출 기록을 담는 MessagesPlaceholder), 그리고 AgentExecutor(실행 런타임). temperature=0.1처럼 온도를 낮춰 도구 선택의 일관성을 높이는 게 실전 팁입니다. 빠른 프로토타이핑과 다양한 LLM 지원이 강점이지만, 복잡한 분기·상태가 필요하면 다음의 LangGraph로 넘어갑니다.
6. 구현 ② LangGraph — ReAct 패턴과 ToolNode
LangGraph는 도구 사용을 상태 그래프로 표현합니다. 그 위에서 ReAct(Reasoning + Acting) 패턴이 돕니다 — 생각(Thought) → 행동(Action) → 관찰(Observation)을 반복하며, 중간 결과를 보고 다음 행동을 정하는 방식이죠.
search_products 호출"
query="노트북")
1,500,000원]
구현은 두 갈래입니다. 한 줄짜리 Prebuilt create_react_agent, 또는 노드·엣지를 직접 짜는 Custom StateGraph. 핵심 부품은 ToolNode(도구 실행 전담)와 should_continue(추론 노드 뒤에서 “도구로 갈지, 끝낼지”를 가르는 조건부 엣지)입니다. 직접 만든 should_continue 대신 LangGraph가 기본 제공하는 tools_condition 라우터를 그대로 써도 됩니다.
상태가 TypedDict로 명시되고 흐름이 그래프로 보여 디버깅·시각화가 쉽고, Human-in-the-loop과 체크포인트(MemorySaver)를 얹기 좋습니다. 프로덕션 수준의 세밀한 제어가 LangGraph의 진짜 가치입니다.
7. 구현 ③ Google ADK — FunctionTool과 내장 도구
ADK는 Gemini와 네이티브로 통합됩니다. 데코레이터 없이 평범한 함수를 FunctionTool로 감싸면 타입 힌트와 docstring에서 스키마를 자동 추출하고, google_search·BuiltInCodeExecutor 같은 내장 도구를 바로 끼울 수 있습니다.
ADK가 권하는 정석은 도메인별 Agent 분리입니다. crm_agent·logistics_agent·code_agent처럼 도구 범위를 좁혀 두면 프롬프트가 짧아지고 도구 혼동(오선택)이 줄어듭니다. 대화 맥락은 InMemorySessionService가 session_id 재사용으로 유지합니다 — Google Cloud 연동과 내장 도구가 필요할 때 가장 빛납니다.
8. 세 프레임워크 — 같은 도구, 다른 추상화
셋 다 “LLM이 JSON으로 도구를 부르고, 런타임이 실행한다”는 원리는 동일합니다. 다른 건 도구를 어떻게 정의하고 상태를 어떻게 관리하느냐뿐입니다.
| 특성 | LangChain | LangGraph | Google ADK |
|---|---|---|---|
| 도구 정의 | @tool 데코레이터 | @tool + ToolNode | FunctionTool |
| 상태 관리 | chat_history | StateGraph + 상태 | SessionService |
| 복잡도 / 유연성 | 낮음 / 중간 | 높음 / 매우 높음 | 중간 / 높음 |
| Gemini 최적화 | 어댑터 필요 | 어댑터 필요 | 네이티브 |
| 추천 환경 | 빠른 프로토타이핑 | 프로덕션 | Google Cloud 연동 |
9. Tool Calling Agent vs ReAct Agent — 무엇을 고를까
도구를 부르는 방식에는 큰 두 갈래가 있습니다. 한 번에 빠르게 부르는 Tool Calling Agent와, 생각을 펼치며 반복하는 ReAct Agent입니다. 둘은 우열이 아니라 용도가 다릅니다.
단일 결정, 사고 과정 없이 곧장
중간 결과로 다음 행동 결정
규칙은 단순합니다. “재고 확인”처럼 도구 하나로 끝나면 Tool Calling, “검색 → 재고 확인 → 주문”처럼 앞 결과가 다음 행동을 정하면 ReAct. 그리고 도구가 외부 세계를 바꾸기 시작하면(주문·결제·발송) 보안이 따라붙습니다.
BuiltInCodeExecutor) · ④ 감사 로깅(모든 호출의 사용자·시각·입력·결과 기록). 도구는 강력한 만큼 오남용·할루시네이션의 통로도 되니, 처음부터 보안을 설계에 넣어야 합니다.10. 엔터프라이즈 적용 — CRM · ERP · Groupware
기업에서 도구 사용은 곧 레거시 API를 도구로 감싸는 일입니다. Salesforce REST, SAP RFC/BAPI, MS Graph API를 FunctionTool로 래핑하면, 사용자는 메뉴를 헤매는 대신 “김철수 고객의 미결 주문 알려줘”라고 말만 하면 됩니다. 효과는 숫자로 분명합니다.
도입은 한 번에 하지 않습니다. 조회 전용(Low Risk) → 생성·수정(Medium) → 복합 트랜잭션(Controlled)의 3단계로 위험을 통제하며 넓혀 가고, 부서 단위 파일럿(1~2개월) → 확장(2~3개월) → 전사(3~6개월) → 최적화(지속)의 로드맵을 탑니다. 핵심 안전장치는 모든 도구 앞단에 두는 Tool API Gateway(인증·권한·라우팅·로깅)입니다.
11. 케이스 스터디 — 통합 고객 서비스 Agent
하나의 요청이 여러 시스템에 걸치는 실제 시나리오를 봅시다. Orchestrator Agent가 의도를 쪼개 도메인별 Agent에 넘기고, 각 Agent가 자기 도구를 호출한 결과를 통합해 한 번에 답합니다(7편 멀티 에이전트의 토대).
도구를 3단계로 계층화하라
엔터프라이즈 도구는 복잡도에 따라 세 층으로 나눠 설계합니다. 아래로 갈수록 비즈니스 로직과 트랜잭션 관리가 무거워집니다.
get_customer·check_inventory · 빠른 응답·단순 입출력get_customer_360(고객+주문+케이스) · 비즈니스 로직 포함process_order(주문→재고→결제→배송) · 트랜잭션·롤백 관리여기에 역할별 도구 접근 권한 매트릭스를 겹칩니다. 일반 직원은 get_customer만, 팀장은 approve_request·cancel_order까지, 재무 조회는 부서장 이상 — 역할에 따라 Agent에 주입하는 도구 집합을 바꿔 권한을 코드로 강제합니다.
12. 베스트 프랙티스 & 트레이드오프
도구 사용을 쓸지 말지 — 의사결정
- 실시간 데이터 조회(날씨·주가·재고)
- 외부 시스템 연동(CRM·ERP·GW)
- 정확한 계산(금융·통계)
- 비즈니스 프로세스 자동화(주문·결재)
- 복잡한 다단계 작업(ReAct)
- 단순 지식 기반 질의응답
- 실시간 응답이 매우 중요한 경우
- 비용에 민감한 대용량 처리
- API가 불안정하거나 정의가 어려운 경우
트레이드오프 — 능력엔 대가가 따른다
도구는 LLM의 한계를 풀어 주는 대신 호출 오버헤드(지연), API 비용·Rate Limit, 도구 유지보수 비용, 보안 위험, 도구 오선택(할루시네이션)을 떠안깁니다. 그래서 “도구를 쓸 수 있다”가 아니라 “이 작업에 도구가 정말 필요한가”를 먼저 묻는 게 핵심입니다.
다른 패턴과의 조합
| 조합 | 활용 |
|---|---|
| Tool Use + 라우팅(2편) | 요청 유형에 따라 적절한 도구·Agent 선택 |
| Tool Use + 병렬화(3편) | 여러 도구를 동시에 호출해 응답 속도 향상 |
| Tool Use + 리플렉션(4편) | 도구 결과를 검증하고 필요시 재호출(grounding) |
| Tool Use + 플래닝(6편) | 복잡한 작업을 계획한 뒤 순차적 도구 호출 |
체크리스트
- ✅ 이름은 동사+명사 · docstring은 LLM이 읽는 설명서처럼 상세히
- ✅ Pydantic 스키마로 입력 검증 + 구조화된 반환값(status/data/error) 통일
- ✅ 모든 예외를 잡아 표준 오류로 반환 +
max_iterations로 무한 루프 차단 - ✅ 보안 4종 — 입력 검증·RBAC 권한·샌드박스 격리·감사 로깅
- ✅ 도구가 많으면 Dynamic Tool Calling으로 지금 필요한 것만 노출
- ✅ 도메인별 Agent 분리로 도구 범위를 좁혀 오선택 줄이기
체이닝(1편)이 “순서대로 쪼개기”, 라우팅(2편)이 “입력에 따라 길 나누기”, 병렬화(3편)가 “독립 작업 동시에”, 리플렉션(4편)이 “쓴 다음 읽고 고치기”였다면, 도구 사용은 “모르면 직접 알아보고, 못 하면 도구를 써라”입니다. 여기서 비로소 LLM은 생각을 넘어 행동하고, 머릿속 지식을 넘어 바깥 세계와 연결됩니다. 핵심은 단 둘 — 도구를 LLM이 읽을 수 있게 잘 정의하고, 손과 발을 단 만큼 보안을 처음부터 설계하는 것. 다섯 패턴은 경쟁이 아니라 조합됩니다. 라우터가 도구가 필요한 요청만 골라 보내고, 여러 도구를 병렬로 부르고, 도구 결과를 리플렉션으로 검증하죠. 다음 편에서는 에이전트가 복잡한 작업을 스스로 쪼개 단계적으로 실행하는 플래닝(Planning)을 다룹니다 — 도구를 언제·어떤 순서로 쓸지 계획하는 이야기입니다.
'Agentic AI Design Patterns' 카테고리의 다른 글
| CH07-혼자보다 팀 — 멀티 에이전트 협업(Multi-Agent Collaboration) 완벽 정리 (0) | 2026.06.04 |
|---|---|
| CH06-스스로 길을 그리는 AI — 플래닝(Planning) 패턴 완벽 정리 (0) | 2026.06.03 |
| CH04-스스로 고쳐 쓰는 AI — 리플렉션(Reflection) 패턴 완벽 정리 (0) | 2026.06.02 |
| CH03-AI 에이전트 병렬화 입문 | RunnableParallel·LangGraph·ParallelAgent·asyncio로 동시 실행 구현하기 (0) | 2026.06.01 |
| CH02-입력에 따라 길을 나눠라 — 라우팅(Routing) 패턴 완벽 정리 (0) | 2026.05.31 |