본문으로 건너뛰기
Koding
Claude Certified Architect – Foundations (CCA-F) 자격시험 교재
무료

Claude Certified Architect – Foundations (CCA-F) 자격시험 교재

한국 SI·컨설팅 실무자와 AI 엔지니어를 위한 CCA-F 합격 교재예요. 원문 61회 연재 원고를 내용 손실 없이 32개 장으로 재구성했어요. 각 세션의 이론·연습문제·해설은 한 장에 묶어 학습 흐름이 끊기지 않게 했고, 프로젝트와 모의고사는 문제편과 해설편을 분리해 실전처럼 풀 수 있게 했어요.

클로드claudeanthropicCCACCAF

8.제7장. 세션 5: Tool Use — Function Calling (이론·연습문제·해설)

출제 도메인: 도메인 2 (18%) · 작성자: 김재우 (jaewoo@claudcode.to)


① Claude Tool Use(Function Calling) 완벽 가이드 (CCA-F 세션 5): 에이전트 루프·툴 설계

지난 장 돌아보기

지난 장에서는 구조화 출력의 수단으로 Tool Use의 입구를 살짝 다뤘어요. 이번 장부터는 CCA-F 도메인 2(18%)에 해당하는 툴 설계와 MCP 통합을 다뤄요. 먼저 Tool Use(Function Calling)의 기본 구조와 에이전트 루프를 배워요.

주제 개요

LLM은 기본적으로 '텍스트를 넣으면 텍스트를 돌려주는' 존재지만, 외부 함수·API·데이터베이스를 호출할 수 있으면 세계의 상태를 가져오고 부수 효과를 실행하는 에이전트가 돼요. 이걸 실현하는 게 Tool Use(Function Calling)예요.

비유하자면 Claude는 '머리가 명석한 상담원'이지만, 스스로 전화를 걸거나 서류를 가져오지는 못해요. Tool Use는 '상담원 옆에 어시스턴트를 두고, 상담원의 지시로 어시스턴트가 실제 작업을 하는' 구조예요.

습득 포인트

  • Tool Use의 3턴 교환(요청 → 툴 호출 → 결과 반환 → 최종 답변)을 그림으로 그릴 수 있다
  • 툴 정의 스키마(name / description / input_schema)를 쓸 수 있다
  • tool_use 블록과 tool_result 블록의 구조를 이해하고 있다
  • 에이전트 루프의 구현 패턴(stop_reason으로 분기)을 설명할 수 있다
  • 병렬 툴 호출(parallel_tool_use)의 동작과 무효화 방법을 이해하고 있다
  • 툴 에러를 반환하는 법(is_error: true)과 Claude의 리커버리 동작을 파악하고 있다
  • tool_choice의 3가지 형식(auto / any / 특정 툴)을 구분해 쓸 수 있다

1. Tool Use의 기본 흐름

Tool Use는 2~3턴의 API 호출로 구성돼요.

sequenceDiagram
    participant App as 앱
    participant Claude as Claude
    participant Tool as 외부 도구<br/>(함수/API)

    App->>Claude: 1. messages + tools 정의 전송
    Claude-->>App: 2. tool_use 블록 반환<br/>stop_reason = tool_use

    App->>Tool: 3. 앱 쪽에서 도구 실행
    Tool-->>App: 4. 도구 결과 반환

    App->>Claude: 5. messages에 tool_result 추가 후 재전송
    Claude-->>App: 6. 최종 답변 반환<br/>(텍스트)

2. 툴 정의 스키마

tool_definition.py

tools = [
    {
        "name": "get_weather",
        "description": "지정한 도시의 현재 날씨를 가져옵니다.",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "도시명(예: Seoul, New York)",
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "온도 단위",
                },
            },
            "required": ["city"],
        },
    }
]

중요한 3요소

요소역할
name툴 식별자. snake_case 권장. Claude가 선택 시 사용
descriptionClaude가 툴을 고르기 위한 판단 재료. 명확하고 구체적으로 작성
input_schemaJSON 스키마. 인자의 타입·필수 항목·enum을 정의

Bad(description이 불충분)

bad.py

{"name": "search", "description": "검색한다", "input_schema": {...}}

# → 무엇을 검색하는지, 언제 써야 하는지 불명확

Good(description이 구체적)

good.py

{
    "name": "search_documents",
    "description": "사내 문서를 전문(全文) 검색합니다. 사용자가 규정·매뉴얼·과거 안건 정보를 요청할 때 사용하세요.",
    "input_schema": {...},
}

왜 Good일까요: description은 툴 선정의 판단 재료예요. 모호하면 Claude가 부적절한 툴을 고를 리스크가 올라가요.

3. 에이전트 루프의 구현

agent_loop.py

import anthropic
import json

client = anthropic.Anthropic()

# tools 정의(섹션 2 '툴 정의 스키마'와 같은 내용)
tools = [
    {
        "name": "get_weather",
        "description": "지정한 도시의 현재 날씨를 가져옵니다.",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "도시명(예: Seoul, New York)",
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "온도 단위",
                },
            },
            "required": ["city"],
        },
    }
]

def get_weather(city: str, unit: str = "celsius") -> dict:
    # 실제로는 외부 API를 호출한다. 여기서는 더미 데이터
    return {"city": city, "temp": 22, "unit": unit, "condition": "Sunny"}

def run_agent(user_message: str, max_iterations: int = 5):
    messages = [{"role": "user", "content": user_message}]

    for i in range(max_iterations):
        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=1024,
            tools=tools,
            messages=messages,
        )

        # 어시스턴트 응답을 이력에 추가
        messages.append({"role": "assistant", "content": response.content})

        if response.stop_reason == "end_turn":
            # 최종 답변
            for block in response.content:
                if block.type == "text":
                    return block.text

        elif response.stop_reason == "tool_use":
            # 툴 호출을 실행
            tool_results = []
            for block in response.content:
                if block.type == "tool_use":
                    tool_name = block.name
                    tool_input = block.input
                    if tool_name == "get_weather":
                        result = get_weather(**tool_input)
                    else:
                        result = {"error": f"unknown tool: {tool_name}"}
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": json.dumps(result, ensure_ascii=False),
                    })
            # tool_results를 user 메시지로 반환
            messages.append({"role": "user", "content": tool_results})
        else:
            break

    raise RuntimeError("max iterations exceeded")

print(run_agent("서울 날씨 알려 줘"))

에이전트 루프의 요점

스텝주의점
1. 어시스턴트 응답을 이력에 추가content 전체(텍스트 + tool_use)를 보존한다
2. stop_reason == "tool_use"로 분기이 값으로 '툴 실행이 필요'하다고 판단
3. 툴을 실행하고 결과를 tool_result에tool_use_id로 대응지음
4. tool_result를 user 역으로 전송assistant가 아니라 user 역으로 반환하는 게 사양
5. max_iterations로 무한 루프 방지보통 5~10회면 충분

4. tool_use와 tool_result의 구조

4.1 tool_use 블록(Claude → 앱)

tool_use_block.py

{
    "type": "tool_use",
    "id": "toolu_01ABC...",          # 고유 ID
    "name": "get_weather",
    "input": {"city": "Seoul", "unit": "celsius"},
}

4.2 tool_result 블록(앱 → Claude)

tool_result_block.py

{
    "type": "tool_result",
    "tool_use_id": "toolu_01ABC...",   # tool_use의 id와 일치
    "content": "{\"temp\": 22, \"condition\": \"Sunny\"}",
    "is_error": False,                  # 에러 시에는 True
}

5. 툴 에러 처리

툴 실행이 실패했을 때는 is_error: True로 Claude에게 알려요.

tool_error.py

tool_results.append({
    "type": "tool_result",
    "tool_use_id": block.id,
    "content": "외부 API가 타임아웃됐습니다. 10초 후 재시도를 권장합니다.",
    "is_error": True,
})

사용법과 주의점

  • Claude는 is_error: True를 받으면, 자동으로 리커버리 판단(다른 툴을 시도·사용자에게 통지 등)을 시도한다
  • 에러 메시지는 '무엇이 일어났는가', '어떻게 대처해야 하는가'를 구조적으로 전한다
  • 보안: 스택 트레이스 같은 내부 정보를 그대로 반환하지 않는다

6. 병렬 툴 호출(parallel_tool_use)

Claude는 1턴에 여러 툴을 병렬로 호출할 수 있어요.

parallel_tool_use.py

# Claude는 날씨와 환율을 병렬로 요청할 수 있다
# response.content에 여러 tool_use 블록이 나란히 들어온다

병렬 호출을 무효화하려면 disable_parallel_tool_use를 지정해요.

tool_choice={"type": "auto", "disable_parallel_tool_use": True}

사용법과 주의점

  • 병렬 호출은 여러 독립된 정보 취득에서 효과가 크다(날씨 + 환율 + 주가 등)
  • 반면 순차 의존이 있는 경우에는 무효화해야 한다(A의 결과로 B의 인자가 정해지는 경우 등)

7. tool_choice의 3가지 형식

지정 방식동작유스케이스
{"type": "auto"}(기본값)Claude가 판단일반적인 대화 에이전트
{"type": "any"}반드시 어떤 툴이든 쓴다툴 호출이 필수인 플로
{"type": "tool", "name": "<name>"}특정 툴을 반드시 쓴다구조화 출력

8. 툴 설계의 원칙

8.1 툴 경계의 관리

툴은 '단일 책무'로 설계해요.

Bad(복합 책무)

bad.py

{
    "name": "everything_tool",
    "description": "사용자 정보의 취득, 갱신, 삭제, 검색, 메일 발송, SMS 발송 등을 한다",
    "input_schema": {
        "properties": {
            "action": {"type": "string"},  # "get" "update" "delete" 등
            ...
        }
    }
}

# → description이 비대해지고, Claude가 오용하기 쉬움

Good(단일 책무)

good.py

[
    {"name": "get_user", "description": "사용자 정보를 취득"},
    {"name": "update_user", "description": "사용자 정보를 갱신"},
    {"name": "delete_user", "description": "사용자를 삭제"},
    {"name": "search_users", "description": "사용자를 검색"},
]

왜 Good일까요: 단일 책무로 하면 툴 선택 정확도가 오르고, 오용도 줄어요.

8.2 추론 부하의 최적화

툴 수가 너무 많으면 Claude의 판단 부하가 늘어, 레이턴시·비용·정확도가 모두 나빠져요. Claude는 매 턴, 등록된 모든 툴 정의를 읽어 들여 '어느 것을 쓸지'를 판단해요. 그래서 툴이 늘수록 비교 대상(선택지)이 늘고, 비슷한 툴끼리 헷갈리거나 선택 실수가 나기 쉬워져요.

툴 수영향
5개 이하최적
6~15개허용 범위
16개 이상정확도 저하·토큰 소비 증가
30개 이상설계의 근본적 재검토가 필요

대책: 툴의 '수' 자체를 줄인다

여기서 효과적인 건 Claude가 한 번에 보는 툴의 수를 줄이는 거예요.

  • 관련 툴을 서브에이전트로 떼어낸다(세션 9에서 상세히): 상위 에이전트는 '예약 담당을 부른다', '검색 담당을 부른다' 같은 소수의 툴만 갖고, 세세한 툴 무리는 각 서브에이전트 내부에 숨긴다
  • 계층화(고수준 툴 → 저수준 툴): 입구를 좁히고, 상세한 조작은 하위에 위임한다

레스토랑에 빗대면, 메뉴가 100가지나 되면 손님은 다 고르지 못해요. 이걸 해결하는 건 코스 요리로 만들어 카테고리 단위로 좁히는 것(= 서브에이전트로 위임)이지, 각 요리의 설명문을 한 단어로 줄이는 게 아니에요. 설명을 줄여도 품목 수는 하나도 안 줄고, 오히려 요리의 차이를 알 수 없어 선택이 나빠져요.

주의: '툴이 너무 많다'는 건 수(count)의 문제이지, description 길이의 문제가 아니에요. description을 일률적으로 줄여도 툴 수는 하나도 안 줄어서 선택 실수는 해소되지 않아요. 오히려 섹션 2에서 봤듯이 description은 툴 선정의 판단 재료라, 너무 깎으면 "검색한다"처럼 모호해져 선택 정확도가 되레 떨어져요. 8.1의 '비대해지지 않게'는 1툴 1역(단일 책무)으로 한다는 뜻이지, 필요한 구체성까지 깎아내라는 뜻이 아니에요.

[보완 ] 최신 옵션을 덧붙입니다. Anthropic은 '툴이 너무 많은' 문제를 겨냥한 어드밴스드 툴 사용 기능을 추가했어요. Tool Search Tool은 수천 개의 툴 정의를 처음부터 컨텍스트에 다 넣지 않고, Claude가 필요할 때 검색해 온디맨드로 로딩하게 해 줍니다. Programmatic Tool Calling은 Claude가 코드 실행 환경에서 툴을 코드로 호출·집계하게 해, 매 호출마다 모델을 왕복하지 않고 토큰 소비와 레이턴시를 줄여요. 서브에이전트·계층화(8.2)와 함께 대규모 툴 환경의 실전 대안으로 검토해 볼 만합니다(둘 다 베타 단계이니 도입 전 최신 상태를 확인하세요).

자주 하는 오해와 개념 정리

❌ 자주 하는 오해: 'tool_result는 assistant 역으로 반환한다'

  • 오해: 툴 결과는 Claude의 응답이니 assistant 역이라고 여기기 쉬움
  • 실제: tool_result는 user 역 메시지 내용으로 반환한다(API 사양)
  • 확인 방법: role을 assistant로 하면 API 에러

❌ 자주 하는 오해: '툴이 많을수록 고기능이다'

  • 오해: 툴 수를 늘리면 에이전트의 능력이 오른다
  • 실제: 너무 많으면 판단 부하로 정확도 저하. 5~15개가 현실적인 상한
  • 확인 방법: 툴 수를 바꿔 가며 정확도·레이턴시를 비교

❌ 자주 하는 오해: '툴이 너무 많으면 description을 줄이면 해결된다'

  • 오해: 툴 선택 실수가 늘면, 각 description을 한 줄로 줄이면 판단 부하가 내려간다
  • 실제: 문제는 툴의 수(count)이지 description 길이가 아니다. 줄여도 툴 수는 하나도 안 줄고, 너무 깎으면 판단 재료(섹션 2)가 사라져 선택 정확도가 오히려 떨어진다. 올바른 대책은 서브에이전트로 떼어내기·계층화로 툴 수 자체를 줄이는 것(8.2). description을 간결하게 하는 건 '비대해진 복합 책무를 단일 책무로 나누기' 위함이지, 툴 과다의 해결책이 아니다
  • 확인 방법: 툴 수를 그대로 둔 채 description만 줄여도 정확도가 돌아오지 않음을 확인한다

❌ 자주 하는 오해: '병렬 툴 호출은 항상 고속화된다'

  • 오해: 병렬이면 전체 시간이 단축된다
  • 실제: 의존 관계가 있는 툴에서는 잘못된 병렬 실행이 일어나 결과가 이상해진다
  • 확인 방법: 순차 의존이 있는 처리에서는 disable_parallel_tool_use: True

자주 나는 에러와 대처법

  • 에러 예시: tool_use_id가 일치하지 않음
    • 원인: tool_result의 tool_use_id를 tool_use의 id와 대응짓지 않음
    • 대처법: 1대1로 대응하는 id를 엄밀하게 세팅
  • 에러 예시: Claude가 같은 툴을 계속 호출함
    • 원인: 에러 처리가 불충분하거나, description이 모호함
    • 대처법: is_error: True + 명확한 에러 메시지로 반환. max_iterations로 중단
  • 에러 예시: 의도치 않은 툴이 호출됨
    • 원인: description의 모호함, 또는 중복
    • 대처법: description을 구체화하고, 툴 경계를 정리

정리와 다음 한 걸음

  • Tool Use는 '앱 쪽이 툴 실행을 맡고, Claude는 판단과 통합에 집중하는' 분업 모델
  • tool_use → 툴 실행 → tool_result → 최종 답변의 흐름을 stop_reason == "tool_use"로 분기
  • 툴 정의는 name / description / input_schema의 3요소. description이 판단 재료
  • 에러는 is_error: True + 구조적 메시지로 반환
  • 병렬 툴 호출은 독립 태스크용. 순차 의존 태스크에서는 무효화
  • 단일 책무 + 적절한 수(5~15개)가 툴 설계의 원칙

다음 세션에서는 툴 설계를 표준 사양으로 끌어올린 MCP(Model Context Protocol)를 배웁니다.


② CCA-F 세션 5 연습문제 9선: Claude Tool Use·에이전트 루프·툴 설계 완전 대비

습득 포인트와 문제 매칭

습득 포인트해당 문제
Tool Use의 기본 흐름문제 1
툴 정의 스키마문제 2
tool_use / tool_result의 구조문제 3, 문제 4
에이전트 루프문제 5
병렬 툴 호출문제 6
툴 설계 원칙문제 7, 문제 8

문제 1: Tool Use의 흐름

  • 카테고리: 기초
  • 난이도: ★☆☆☆☆
  • 예상 소요 시간: 5분

Tool Use의 전형적인 흐름으로 올바른 것은 무엇인가요?

  • (A) 앱 → Claude(tool_use) → 앱(툴 실행) → Claude(tool_result 수신 → 최종 답변)
  • (B) Claude가 직접 외부 API를 호출한다
  • (C) 앱 → 외부 API → Claude(최종 답변)
  • (D) Claude가 SSH를 거쳐 서버에 접속한다

문제 2: 툴 description의 중요성

  • 카테고리: 기초
  • 난이도: ★☆☆☆☆
  • 예상 소요 시간: 5분

툴 정의의 description 필드의 가장 중요한 역할은 무엇인가요?

  • (A) Anthropic 대시보드에 표시되는 설명
  • (B) 개발자용 내부 코멘트
  • (C) Claude가 툴을 고르는 판단 재료가 된다
  • (D) 감사 로그용 라벨

문제 3: tool_result의 role 지정

  • 카테고리: 응용
  • 난이도: ★★☆☆☆
  • 예상 소요 시간: 5분

툴 실행 결과를 Claude에게 반환할 때, tool_result 블록을 담은 메시지의 role로 올바른 것은 무엇인가요?

  • (A) system
  • (B) assistant
  • (C) user
  • (D) tool

문제 4: tool_use_id의 역할

  • 카테고리: 응용
  • 난이도: ★★☆☆☆
  • 예상 소요 시간: 5분

tool_use_id의 역할로 올바른 것은 무엇인가요?

  • (A) 툴 정의의 name과 같은 식별자
  • (B) 파이썬의 내부 변수명
  • (C) Anthropic 계정의 API 키
  • (D) tool_use 블록과 tool_result 블록을 1대1로 대응짓는 ID

문제 5: 에이전트 루프의 분기

  • 카테고리: 응용
  • 난이도: ★★★☆☆
  • 예상 소요 시간: 10분

에이전트 루프에서 '툴 실행으로 진행할지, 최종 답변을 반환할지'를 판단할 때의 근거로 올바른 것은 무엇인가요?

  • (A) 응답의 길이
  • (B) response.stop_reason의 값이 tool_use인지 end_turn인지
  • (C) tools 리스트가 비어 있는지
  • (D) Claude의 발화에 '툴'이라는 단어가 포함되어 있는지

문제 6: 병렬 툴 호출의 무효화

  • 카테고리: 응용
  • 난이도: ★★★☆☆
  • 예상 소요 시간: 5분

A의 결과로 B의 인자가 정해지는 순차 의존이 있는 경우, 병렬 툴 호출을 무효화하기 위한 적절한 지정은 무엇인가요?

  • (A) tool_choice={"type": "auto", "disable_parallel_tool_use": True}
  • (B) parallel=False
  • (C) 툴 정의에서 병렬 플래그를 삭제
  • (D) max_tokens를 1로 한다

문제 7: 툴 수의 최적화

  • 카테고리: 응용
  • 난이도: ★★★☆☆
  • 예상 소요 시간: 10분

에이전트에 30개의 툴을 등록했더니 툴 선택 실수가 늘었습니다. 가장 적절한 대응은 무엇인가요?

  • (A) 툴 수를 더 늘린다
  • (B) 관련 툴을 서브에이전트로 떼어내고, 상위 에이전트는 소수의 툴만 갖도록 재설계한다
  • (C) 모든 툴 description을 한 줄로 단축
  • (D) Claude 모델을 Haiku로 변경

문제 8: 툴 책무의 단일화

  • 카테고리: 응용
  • 난이도: ★★★☆☆
  • 예상 소요 시간: 10분

다음 툴 설계에 가장 큰 문제가 있습니다. 가장 적절한 개선안은 무엇인가요?

{
    "name": "user_action",
    "description": "사용자 조작(생성·갱신·삭제·검색)을 실행",
    "input_schema": {
        "properties": {
            "action": {"type": "string"},
            "user_data": {"type": "object"},
        }
    }
}
  • (A) description을 더 길게 한다
  • (B) 이대로 쓴다
  • (C) action을 enum으로 고정한다
  • (D) 여러 개의 단일 책무 툴(create_user / update_user / delete_user / search_users)로 분할한다

문제 9 (고급): 추론 부하의 최적화

  • 카테고리: 고급
  • 난이도: ★★★★☆
  • 예상 소요 시간: 20분

고객 지원 에이전트에 50개의 툴을 등록했더니, 레이턴시가 2초 → 8초로 나빠지고 툴 선택 정확도도 떨어졌습니다. CCA-F 시험 범위의 개념을 사용해, 단계적인 개선 계획을 3스텝으로 서술하세요.


정답은 이 장 후반의 정답·해설편에서 확인하세요.


③ CCA-F 세션 5 연습문제 정답·해설: Claude Tool Use·에이전트 루프·서브에이전트 완전 풀이

정답 일람

문제정답
문제 1(A)
문제 2(C)
문제 3(C)
문제 4(D)
문제 5(B)
문제 6(A)
문제 7(B)
문제 8(D)
문제 9후술

문제 1: Tool Use의 흐름 — 정답 (A)

해설

Tool Use는 'Claude는 판단하는 사람, 앱은 툴 실행 담당'이라는 분업 모델이에요. Claude 자신은 외부 API를 호출하지 않아요.

◆ 설계와 운용 포인트

  • 설계 사상: 이 분업 덕분에 외부 I/O의 제어권이 앱 쪽에 남아, 감사·샌드박스·타임아웃 제어가 쉬워져요.
  • 운용 시 주의점: Claude가 '외부 API를 호출했습니다'라고 말해도, 그건 Tool Use를 거쳐 앱이 호출한 거예요.

문제 2: 툴 description의 중요성 — 정답 (C)

해설

description은 Claude가 툴을 선정할 때의 판단 재료예요. 모호하면 오선택이 늘어나요.

◆ 설계와 운용 포인트

  • 설계 사상: description은 '프롬프트의 일부'로 여겨요. Claude에게는 '언제 이 툴을 써야 하는가'의 가이드라인이에요.
  • 운용 시 주의점: 툴을 늘리기 전에 description의 질을 개선하는 편이 정확도 면에서 더 잘 듣는 경우가 많아요.

문제 3: tool_result의 role 지정 — 정답 (C)

해설

tool_result는 user 역 메시지 내용으로 반환해요. API 사양상의 규칙이에요.

◆ 설계와 운용 포인트

  • 설계 사상: Claude에게 tool_result는 '사용자가 제시한 추가 정보'와 같은 카테고리로 다뤄져요.
  • 운용 시 주의점: assistant나 system으로 하면 invalid_request_error가 나요.

문제 4: tool_use_id의 역할 — 정답 (D)

해설

tool_use_id는 tool_use와 tool_result를 1대1로 대응짓는 ID예요. 병렬 툴 호출이 있을 때, 어느 결과가 어느 호출에 대응하는지를 나타내요.

◆ 설계와 운용 포인트

  • 계산량과 리소스 사용: 병렬 실행 시 결과는 순서 없이 돌아올 수 있어서 tool_use_id로 대응짓는 게 필수예요.

문제 5: 에이전트 루프의 분기 — 정답 (B)

해설

에이전트 루프에서는 response.stop_reason의 값으로 다음 처리를 분기해요.

  • tool_use → 툴 실행으로 진행
  • end_turn → 최종 답변으로 반환
  • max_tokens → 출력 잘림 가능성, 이어받기 처리를 검토

◆ 설계와 운용 포인트

  • 운용 시 주의점: stop_reason을 보지 않고 content 내용만으로 판단하면, 복잡한 에이전트에서 오작동이 나요.

문제 6: 병렬 툴 호출의 무효화 — 정답 (A)

해설

tool_choice 안에서 disable_parallel_tool_use: True를 지정하면, Claude가 한 번에 툴을 하나씩 호출하게 돼요.

◆ 설계와 운용 포인트

  • 설계 사상: 병렬 호출은 레이턴시 단축에 효과적이지만, 의존 관계가 있으면 깨져요.
  • 운용 시 주의점: '은행 계좌에서 인출 → 메일 통지'처럼 순차가 필수인 처리에서는 반드시 무효화해요.

문제 7: 툴 수의 최적화 — 정답 (B)

해설

툴 수가 너무 많은 경우는 서브에이전트로 떼어내 계층화하는 게 왕도예요. 이렇게 하면 상위 에이전트의 판단 부하를 낮출 수 있어요.

여기서 헷갈리기 쉬운 게 (C) '모든 description을 한 줄로 단축'이에요. 문제의 본질은 툴의 수(count)이지 description의 길이가 아니에요. 단축해도 툴 수는 하나도 안 줄고, 게다가 description은 툴 선정의 판단 재료(문제 2)라 너무 깎으면 선택 정확도가 되레 떨어져요. (A)는 문제를 악화시킬 뿐이고, (D)의 모델 변경은 수의 문제를 해결하지 못해요.

◆ 설계와 운용 포인트

  • 설계 사상: 'Divide and Conquer'의 원칙이에요. 자세한 내용은 세션 9(멀티에이전트)에서 다뤄요.
  • 계산량과 리소스 사용: 상위 에이전트의 판단 토큰 수가 줄어, 레이턴시·비용이 개선돼요.

문제 8: 툴 책무의 단일화 — 정답 (D)

해설

복합 책무 툴은 description이 비대해져, Claude가 오용하기 쉬워져요. 단일 책무 툴로 분할하는 게 원칙이에요.

◆ 설계와 운용 포인트

  • 설계 사상: 소프트웨어 설계의 SRP(Single Responsibility Principle)와 같아요. 툴도 단일 책무가 바람직해요.
  • 운용 시 주의점: '너무 잘게 나눠도 판단 부하가 늘'기 때문에, 적절한 입도(5~15개)를 의식해요.

문제 9 (고급): 추론 부하의 최적화 — 개선 계획 예시

Step 1: 현황 분석과 카테고리 분류

  • 50개의 툴을 기능별 카테고리로 분류한다
  • 예: '사용자 관리(10개)', '주문 관리(8개)', '재고 관리(7개)', '외부 연동(15개)', '분석·리포트(10개)'
  • 각 툴의 이용 빈도와 의존 관계를 시각화한다

Step 2: 서브에이전트화를 통한 계층화

  • 카테고리마다 서브에이전트를 만들고, 각 서브에이전트가 자기 툴 무리를 가진다
  • 상위 에이전트(허브)는 '어느 카테고리에 위임할지'를 판단하기만 한다(툴 수 5개 정도)
flowchart TD
    A["상위 에이전트<br/>도구 5개"]

    B["사용자 관리 에이전트<br/>도구 10개"]
    C["주문 관리 에이전트<br/>도구 8개"]
    D["재고 관리 에이전트<br/>도구 7개"]
    E["외부 연동 에이전트<br/>도구 15개"]
    F["분석 에이전트<br/>도구 10개"]

    A --> B
    A --> C
    A --> D
    A --> E
    A --> F

Step 3: 툴 정의의 리팩터링

  • 단일 책무화: 복합 툴을 분할
  • description 개선: 언제 써야 하는지·쓰지 말아야 하는지를 명시
  • 고빈도 툴로 좁히기: 저빈도 툴은 다른 수단(직접 API 호출 등)으로 빼낸다

기대되는 효과

지표개선 전개선 후개선 폭
레이턴시8초3초-62%
툴 선택 정확도70%92%+22pt
토큰 소비작음비용 절감

이 세션 돌아보기

  • Tool Use는 Claude가 판단, 앱이 실행의 분업 모델
  • 주요 블록: tool_use(Claude 출력), tool_result(user 역으로 반환)
  • 에이전트 루프는 stop_reason으로 분기하고, max_iterations로 중단한다
  • 병렬 툴 호출은 독립 태스크용, 순차 의존 태스크에서는 무효화
  • 툴 설계의 원칙: 단일 책무, 적절한 수(5~15개), 명확한 description
  • 툴 수가 늘면 서브에이전트화로 계층화

다음 세션(제8장)에서는 이 툴 설계를 표준 사양으로 삼은 Model Context Protocol(MCP)로 넘어갑니다.


©2024-2026 ClaudeCode.to, Hand-crafted & made with Jaewoo Kim.

  • 이메일문의: jaewoo@claudecode.to
  • AI 에이전트 만드는 사람
  • 기업 AI 강의 · 에이전트 개발 · 기술자문
  • "AI한테 일 시키는 법, 제대로 알려드립니다"