Lộ trình học›Claude API›Building with the Claude API Mở bản đồ

6.31 · Tool schemas — JSON mô tả tool cho Claude

Bài viếtTrung cấp20 phút đọc

Khi bạn viết function Python, bạn thêm docstring cho dev khác đọc:

Sau bài này, bạn sẽ
  1. Viết tool schema đầy đủ với name, description, input_schema
  2. Hiểu JSON Schema spec — types, required, defaults
  3. Viết description chất lượng giúp Claude biết khi nào call tool
  4. Generate schema bằng Claude (self-generate) để tiết kiệm thời gian
  5. Dùng ToolParam type cho type safety

Mở đầu: Schema là "docstring" cho Claude

def get_weather(location: str, unit: str = "F"):
    """Get current weather for a location.
    
    Args:
        location: City name or airport code (e.g., "SF", "NYC")
        unit: "F" for Fahrenheit or "C" for Celsius
    
    Returns:
        String describing current weather
    """
    ...

Tool schema y hệt, nhưng là JSON cho Claude đọc thay vì Python developer. Schema càng rõ → Claude dùng tool càng chính xác.

3 thành phần của schema

{
  "name": "get_weather",
  "description": "Get current weather conditions for a specified location. Use this when user asks about current weather, temperature, or atmospheric conditions. Returns text with temperature, conditions, and wind.",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "City name or airport code, e.g., 'San Francisco' or 'SFO'"
      },
      "unit": {
        "type": "string",
        "enum": ["F", "C"],
        "description": "Temperature unit: F for Fahrenheit, C for Celsius",
        "default": "F"
      }
    },
    "required": ["location"]
  }
}

1. name

  • Snake_case
  • Descriptive verb
  • Match Python function name (convention)

Examples: get_weather, search_emails, create_calendar_event.

2. description

Quan trọng nhất. Claude dựa vào đây quyết định khi nào call tool.

Best practices:

  • 3-4 sentences
  • Describe what tool does
  • When Claude nên dùng
  • What tool returns

Bad: "Gets data"

Good: "Get current weather conditions for a specified location. Use this when user asks about weather, temperature, or wind. Returns a formatted string with temperature, conditions, and wind speed."

3. input_schema

Follows JSON Schema spec — standard cho validate JSON data.

JSON Schema basics

Types

  • string — text
  • integer — số nguyên
  • number — float / int
  • boolean — true/false
  • array — list
  • object — dict (nested)
  • null — null value

Example object schema

{
  "type": "object",
  "properties": {
    "name": {"type": "string"},
    "age": {"type": "integer"},
    "is_admin": {"type": "boolean"},
    "tags": {
      "type": "array",
      "items": {"type": "string"}
    },
    "address": {
      "type": "object",
      "properties": {
        "street": {"type": "string"},
        "city": {"type": "string"}
      }
    }
  },
  "required": ["name", "age"]
}

Additional constraints

  • enum: restrict to list of values
  • default: default value if not provided
  • minimum / maximum: numeric range
  • minLength / maxLength: string length
  • pattern: regex for string
  • description: per-field docs

Viết schema đầy đủ — Ví dụ get_current_datetime

from datetime import datetime

def get_current_datetime(date_format="%Y-%m-%d %H:%M:%S"):
    if not date_format:
        raise ValueError("date_format cannot be empty")
    return datetime.now().strftime(date_format)


get_current_datetime_schema = {
    "name": "get_current_datetime",
    "description": "Returns the current date and time formatted according to the specified format. Use when user asks for current time, today's date, or to timestamp an event.",
    "input_schema": {
        "type": "object",
        "properties": {
            "date_format": {
                "type": "string",
                "description": "Python strftime format string. Examples: '%Y-%m-%d' for date only, '%H:%M' for hour:minute, '%Y-%m-%d %H:%M:%S' for full datetime.",
                "default": "%Y-%m-%d %H:%M:%S"
            }
        },
        "required": []
    }
}

Naming convention: function_name + function_name_schema. Dễ pair.

Ví dụ phức tạp hơn — search_emails

search_emails_schema = {
    "name": "search_emails",
    "description": "Search user's email inbox by keywords, sender, or date range. Use when user asks to find emails, check inbox, or recall past conversations. Returns list of emails matching criteria.",
    "input_schema": {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "Search keywords to match in email subject or body"
            },
            "from_sender": {
                "type": "string",
                "description": "Filter by sender email address (optional)"
            },
            "date_from": {
                "type": "string",
                "description": "Start date in YYYY-MM-DD format (optional)",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "date_to": {
                "type": "string",
                "description": "End date in YYYY-MM-DD format (optional)",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "max_results": {
                "type": "integer",
                "description": "Max number of emails to return",
                "minimum": 1,
                "maximum": 50,
                "default": 10
            }
        },
        "required": ["query"]
    }
}

Phân tích

  • query là required
  • from_sender, date_from, date_to optional — Claude sẽ pass nếu user mention
  • max_results có default + min/max để tránh abuse
  • pattern cho date validate format

Tự generate schema bằng Claude

Thay vì viết schema thủ công, dùng Claude:

Prompt

Generate a JSON schema for tool calling for this Python function.
Follow Anthropic best practices.

Function:
def create_calendar_event(title, start_time, duration_minutes=60, attendees=None):
    """Create calendar event. Returns event ID."""
    ...

Reference: https://docs.anthropic.com/en/docs/build-with-claude/tool-use

Output (Claude generate)

{
  "name": "create_calendar_event",
  "description": "Create a new calendar event and return the event ID. Use when user asks to schedule meetings, appointments, or reminders.",
  "input_schema": {
    "type": "object",
    "properties": {
      "title": {
        "type": "string",
        "description": "Event title/subject"
      },
      "start_time": {
        "type": "string",
        "description": "Event start time in ISO 8601 format (e.g., '2026-04-20T14:00:00')"
      },
      "duration_minutes": {
        "type": "integer",
        "description": "Event duration in minutes",
        "default": 60,
        "minimum": 15
      },
      "attendees": {
        "type": "array",
        "items": {"type": "string"},
        "description": "List of attendee email addresses (optional)"
      }
    },
    "required": ["title", "start_time"]
  }
}

Bạn chỉ cần review + adjust. Tiết kiệm 10 phút/schema.

Type safety với ToolParam

Thay vì raw dict, dùng ToolParam type từ SDK:

from anthropic.types import ToolParam

get_weather_schema: ToolParam = {
    "name": "get_weather",
    "description": "...",
    "input_schema": {
        ...
    }
}

Benefits

  • IDE autocomplete
  • Mypy type checking
  • Catch schema typo trước runtime

Pass schema trong API call

response = client.messages.create(
    model=model,
    max_tokens=1000,
    messages=messages,
    tools=[
        get_weather_schema,
        get_current_datetime_schema,
        search_emails_schema,
    ],  # ← List of schemas
)

Claude sẽ thấy tất cả schema và decide dùng cái nào (hoặc không dùng).

Organize schemas

Cho app nhiều tool, tách file:

def get_weather(location, unit="F"):
    ...

get_weather_schema = {...}


def search_emails(query, ...):
    ...

search_emails_schema = {...}


from .weather import get_weather, get_weather_schema
from .email import search_emails, search_emails_schema

ALL_TOOLS = [
    {"schema": get_weather_schema, "function": get_weather},
    {"schema": search_emails_schema, "function": search_emails},
]

ALL_SCHEMAS = [t["schema"] for t in ALL_TOOLS]
TOOL_FUNCTIONS = {t["schema"]["name"]: t["function"] for t in ALL_TOOLS}

Usage:

response = client.messages.create(
    tools=ALL_SCHEMAS,
    ...
)

if response.stop_reason == "tool_use":
    tool_call = response.content[-1]
    func = TOOL_FUNCTIONS[tool_call.name]
    result = func(**tool_call.input)

Anti-patterns

Description quá ngắn

"description": "Weather tool"

Claude không biết khi nào dùng. Fix: 3-4 sentences.

Param name không rõ

"properties": {"x": {"type": "string"}}

Fix: location, query, order_id — tên có ý nghĩa.

Quên required

"required": []  // mọi field optional

Claude có thể pass incomplete, tool crash.

Fix: List required properly.

Dùng any type

Không có any trong JSON Schema. Nếu cần flexible:

  • oneOf cho multi type
  • string rồi parse trong function

Schema quá dài

15 nested levels → Claude overwhelm.

Fix: Flatten. Nếu nested cần → bẻ thành nhiều tool.

Áp dụng ngay

Bài tập 1: Generate schema tool đầu tiên (15 phút)

Chọn 1 function cho app của bạn. Dùng Claude generate schema. Review + adjust.

Bài tập 2: Review schema quality (10 phút)

Cho schema bạn viết, check:

  • Name snake_case, descriptive?
  • Description 3-4 sentences?
  • Mỗi property có description?
  • required đúng?
  • Có default cho optional params?

Tóm tắt bài học

Những điều cốt lõi
  • Schema = docstring cho Claude. Rõ ràng → Claude dùng tool đúng.
  • 3 phần: name, description, input_schema. Description là quan trọng nhất.
  • Tự generate schema bằng Claude tiết kiệm 10 phút.
  • ToolParam type cho IDE autocomplete + type check.
  • Organize multi-tool qua ALL_SCHEMAS và TOOL_FUNCTIONS dict.
Kiểm tra nhanh3 câu hỏi · chọn đáp án để xem giải thích
    Bạn đã hoàn thành bài này chưa?Tiến độ lưu trên trình duyệt của bạn.