Skip to content

C4 · lesson 1 · 10 min read

Tool definitions and descriptions

Define tools with a name, a description and an input_schema, and write descriptions that make Claude pick the right tool with the right arguments.

Ընտրեք տեքստը՝ հայերեն թարգմանությունը տեսնելու համար։Highlight text to see Armenian. Machine-assisted translation; English is the source of truth.

A tool is a function that your code runs and Claude decides to call. You describe it in the request’s tools array. Claude reads the description, decides whether the request needs the tool, and answers with a structured call. Your application runs it and sends the result back. These are called client tools. Server tools such as web search run on Anthropic’s side instead, and you never execute them yourself.

your applicationruns the toolClaudepicks a tool1. tools + messages(later: + tool_result, is_error?)2. stop_reason: "tool_use"+ tool_use blocks (id, name, input)repeat until stop_reason is "end_turn" (or your turn limit)
The client-tool loop. Claude never runs your code; it asks your application to.

Anatomy of a definition

Field Required What it does
name yes Must match ^[a-zA-Z0-9_-]{1,128}$
description in practice Plain text: what the tool does, when to use it, what it returns
input_schema yes A JSON Schema object for the arguments
input_examples no Example inputs; each one must validate against input_schema
strict no true guarantees Claude’s inputs match the schema exactly

Other optional properties include cache_control and defer_loading (lesson 3).

# define_tool.py - needs ANTHROPIC_API_KEY in the environment
import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY itself

pod_logs_tool = {
    "name": "k8s_get_pod_logs",
    "description": (
        "Returns the last lines of logs from one container in one Kubernetes pod. "
        "Use it when the user asks why a pod is failing, restarting or erroring, after "
        "you know the exact pod name. Do not use it to list pods or to read events; "
        "it only returns container stdout/stderr. Read-only: it never changes the cluster. "
        "Output is plain text, newest line last, capped at tail_lines."
    ),
    "input_schema": {
        "type": "object",
        "properties": {
            "namespace": {
                "type": "string",
                "description": "Kubernetes namespace, e.g. payments. Never guess; ask if unknown.",
            },
            "pod": {"type": "string", "description": "Exact pod name, e.g. checkout-7d9f8-abcde."},
            "container": {
                "type": "string",
                "description": "Container name. Omit for single-container pods.",
            },
            "tail_lines": {"type": "integer", "minimum": 1, "maximum": 500, "default": 100},
            "previous": {
                "type": "boolean",
                "description": "true = logs of the previous (crashed) container instance.",
            },
        },
        "required": ["namespace", "pod"],
    },
}

response = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    tools=[pod_logs_tool],
    messages=[{"role": "user", "content": "Pod checkout-7d9f8-abcde in payments keeps restarting. Why?"}],
)
print(response.stop_reason)
for block in response.content:
    if block.type == "tool_use":
        print(block.name, block.input)

Descriptions do most of the work

Anthropic’s guidance is blunt: a detailed description is by far the biggest factor in how well tools work. Claude has nothing else to go on. Aim for at least three or four sentences that cover:

  • What the tool does and what it returns.
  • When to use it, and just as important, when not to.
  • What each parameter means, with formats and examples.
  • Limits and caveats: what it doesn’t return, side effects, size caps.

Compare "Gets pod logs." with the example above. With the short version Claude has to guess whether it can list pods, whether previous exists, and whether calling it is safe. With the long version, “list my pods” clearly doesn’t fit, and a crash loop clearly calls for previous: true.

Designing the tool set

  • Consolidate. Many near-identical tools make selection ambiguous. One github_pr tool with an action enum (create, review, merge) is often better than three tools.
  • Namespace. Prefix tool names with the service, for example k8s_, pagerduty_ or github_. It removes ambiguity once you have tools from several systems, and it helps tool search (lesson 3).
  • Return high-signal output. Return stable, meaningful identifiers such as slugs or UUIDs, not internal row IDs, and only the fields Claude needs for its next step. A 5,000-line kubectl get -o json dump wastes context.
  • Use input_examples for tricky formats. They help with nested objects or format-sensitive strings. Each example costs prompt tokens, and an invalid one makes the request fail with a 400.
  • Ask for evidence, not reasoning. If you add a parameter such as reason, ask for a short explanation. A field that asks for step-by-step thinking can trigger a refusal.

Recap

  • A tool is name, description and input_schema. Your code runs it; Claude only asks for it with a tool_use block and stop_reason: "tool_use".
  • The description matters most: say what it does, when to use it and when not to, what the parameters mean, and its limits.
  • Prefer fewer, namespaced, well-described tools that return concise output.
  • Use input_examples for complex formats and strict: true to guarantee schema-valid input.

$ ./try-it.sh

Try it: a read-only pod-logs tool

  1. Install the SDK with pip install anthropic and export ANTHROPIC_API_KEY in your shell. Never put the key in the script.
  2. Save the script from this lesson as define_tool.py and run it. Confirm that the response has stop_reason tool_use and a tool_use block for k8s_get_pod_logs.
  3. Replace the description with the one-line version (Gets pod logs.) and run again with the prompt why is checkout crashing?. Compare which arguments Claude invents.
  4. Add a second tool, k8s_describe_pod, and write descriptions that say when to use each one instead of the other.

Check yourself

4 questions. Original practice questions, not taken from the real exam.

  1. Your on-call assistant has two tools, k8s_get_pod_logs and k8s_get_events, both described in one short sentence. When engineers ask why a pod was evicted, Claude usually reads logs instead of events.

    1. What is the most effective first fix?

  2. A tool scale_check takes an environment argument that must be dev, staging or prod, and a window argument in minutes between 1 and 60. Claude sometimes sends "production" or a window of 120.

    2. Which two changes to the definition address this most directly? (Choose two.)

    Choose 2.

  3. An internal agent has separate tools create_pr, review_pr, merge_pr, close_pr and comment_pr for GitHub, plus a similar set for GitLab. Claude often calls the GitLab tool for a GitHub repository.

    3. Which design change best follows Anthropic's tool-definition guidance?

  4. You add input_examples to a deployment_lookup tool. One example leaves out the service field, which input_schema lists in required. You expect Claude to learn that service is sometimes optional.

    4. What actually happens?

Answer every question to check.