Google Vertex AI in Practice

Tool Use with Claude on Vertex AI

Tool use is how Claude goes from answering questions to doing work — querying your database, filing the ticket, fetching the record. On Vertex AI, your code runs the tools; Claude decides when to call them.

Claude 3P 101 · Updated July 2026 · Unofficial guide

Tool use (also called function calling) lets you hand Claude a menu of operations your application can perform. Instead of replying with prose, Claude can respond with a structured request — "call get_order_status with order_id: 4711" — which your code executes, returning the result so Claude can finish the job. Tool use is generally available for Claude on Google Vertex AI, with one boundary to internalize up front: Google's documentation states it plainly — Claude models on the platform support client tools, but server tools are not supported. Anything the tool actually does happens in your code, on your infrastructure, under your IAM. (The exceptions are the basic web search variant and tool search, which Vertex does run server-side; Anthropic-hosted tools like code execution and web fetch are unavailable here.)

Defining a tool schema

A tool is a name, a description, and a JSON Schema describing its parameters. The description does the heavy lifting — Claude decides when to use the tool based on it, so write it like documentation for a new colleague:

tools = [{
    "name": "get_order_status",
    "description": "Look up the current status and ETA of a customer "
                   "order by its numeric order ID.",
    "input_schema": {
        "type": "object",
        "properties": {"order_id": {"type": "string",
                        "description": "The order number, digits only"}},
        "required": ["order_id"],
    },
}]

Parsing tool_use blocks and closing the loop

When Claude decides to call a tool, the response arrives with stop_reason: "tool_use" and the content includes a tool_use block carrying an id, the tool name, and the parsed input. Your job is to execute the call and send back a tool_result block that echoes the same ID, then let Claude continue:

from anthropic import AnthropicVertex

client = AnthropicVertex(project_id="my-project", region="global")
messages = [{"role": "user", "content": "Where is order 4711?"}]

while True:
    resp = client.messages.create(model="claude-sonnet-5",
        max_tokens=1024, tools=tools, messages=messages)
    if resp.stop_reason != "tool_use":
        break
    messages.append({"role": "assistant", "content": resp.content})
    results = [{"type": "tool_result", "tool_use_id": b.id,
                "content": run_tool(b.name, b.input)}          # your code
               for b in resp.content if b.type == "tool_use"]
    messages.append({"role": "user", "content": results})

Three details keep this loop honest in production. First, append the assistant's entire content back into the history, not just the tool blocks — if the model produced thinking blocks alongside a tool request, they must be returned unmodified. Second, a single response can contain several tool_use blocks; answer all of them in one user turn, as the loop above does. Third, when a tool fails, don't swallow the error — return a tool_result describing the failure so Claude can recover or tell the user, and put a hard cap on loop iterations so a confused exchange can't spin forever.

Enterprise notes for the Vertex surface

Because tools execute in your application, the security story is refreshingly conventional: the service account calling Vertex needs only roles/aiplatform.user, while each tool's side effects are governed by whatever permissions your code already has. Treat tool inputs as untrusted user input — validate them before acting, exactly as you would form data. Structured outputs and strict tool use are generally available on Vertex if you need schema-guaranteed arguments, and fine-grained tool streaming works if you stream responses. Tool definitions count as input tokens on every request, which makes a long tool catalogue a natural candidate for prompt caching.

Rule of thumb: start with one or two well-described tools and an evaluation set of real tasks. Most tool-use failures trace back to vague descriptions, not model limitations.

Testing the loop before it meets users

Tool-use quality is measurable in a way free-form generation is not, so take advantage. Build a small suite of real tasks and assert on concrete outcomes: did Claude pick the right tool, were the arguments valid against your schema, did the loop terminate within its iteration cap, and did the final answer actually incorporate the tool result rather than ignoring it. Run the suite whenever you change a tool description, add a tool, or move to a new model version — description wording and model generation are the two variables that most often shift tool-selection behavior. Because the tool executor is ordinary code you wrote, it can be unit-tested separately with mocked model output, which keeps the expensive live-model tests focused on the decision-making layer.

Where to go next

For designing the surrounding agent, see the agentic loop pattern and Agent vs Workflow. For what server-side tooling Vertex lacks and the workarounds, see The Feature Gaps.

Sources