The Tool-Use Loop

When Claude asks to use a tool, run it, return the result, and let Claude continue.

Tool use is a small loop between your code and Claude.

The steps

  1. You send messages plus your tools.
  2. If Claude wants a tool, it stops with stop_reason: "tool_use" and includes a tool_use block with the arguments.
  3. You run the tool with those arguments.
  4. You append the assistant's message, then send a tool_result back.
  5. Claude uses the result to write its final answer.
The tool-use loop between your app and ClaudeYour appClaude1. messages + tools2. "call search_products(...)"3. you run the tool4. tool_result - 5. final answer
Claude asks; you run the tool; you return the result; Claude answers. Repeat if more tools are needed.

Example

Example Β· javascript
let messages = [{ role: "user", content: "Weather in Paris?" }];

let res = await client.messages.create({ model: "claude-opus-4-8", max_tokens: 1024, tools, messages });

while (res.stop_reason === "tool_use") {
  messages.push({ role: "assistant", content: res.content });
  const results = [];
  for (const block of res.content) {
    if (block.type === "tool_use") {
      const output = await runTool(block.name, block.input); // your function
      results.push({ type: "tool_result", tool_use_id: block.id, content: output });
    }
  }
  messages.push({ role: "user", content: results });
  res = await client.messages.create({ model: "claude-opus-4-8", max_tokens: 1024, tools, messages });
}

When to use it

  • Run the full tool-use loop in a support bot so Claude can call lookupOrder, then craft its reply with the result.
  • Implement a multi-step agent where Claude calls getProductDetails and then calculateShipping before answering.
  • Build a React code assistant where Claude calls readFile, suggests changes, then calls writeFile with the new content.

More examples

Single-tool-use loop

Implements the three-step tool loop: send request, run the tool, return the result, get the final reply.

Example Β· javascript
let messages = [{ role: "user", content: "What is the stock price of AAPL?" }];

// Step 1: initial request
let res = await client.messages.create({ model: "claude-haiku-4-5", max_tokens: 256, tools, messages });

if (res.stop_reason === "tool_use") {
  const toolBlock = res.content.find(b => b.type === "tool_use");
  // Step 2: run the tool
  const result = await getStockPrice(toolBlock.input.ticker);
  // Step 3: return result to Claude
  messages = [
    ...messages,
    { role: "assistant", content: res.content },
    { role: "user", content: [{ type: "tool_result", tool_use_id: toolBlock.id, content: String(result) }] },
  ];
  res = await client.messages.create({ model: "claude-haiku-4-5", max_tokens: 256, tools, messages });
}
console.log(res.content[0].text);

Reusable runToolLoop helper

A reusable async function that drives the tool loop until Claude returns end_turn, handling multiple tools.

Example Β· javascript
async function runToolLoop(client, params, handlers) {
  let res = await client.messages.create(params);
  while (res.stop_reason === "tool_use") {
    const calls = res.content.filter(b => b.type === "tool_use");
    const results = await Promise.all(calls.map(async c => ({
      type: "tool_result",
      tool_use_id: c.id,
      content: String(await handlers[c.name](c.input)),
    })));
    params.messages = [
      ...params.messages,
      { role: "assistant", content: res.content },
      { role: "user",      content: results },
    ];
    res = await client.messages.create(params);
  }
  return res;
}

Return a structured tool result

Returns a JSON-serialised object as the tool result so Claude receives rich structured data to base its answer on.

Example Β· javascript
// After running your tool:
const toolResult = {
  type: "tool_result",
  tool_use_id: toolBlock.id,
  content: JSON.stringify({ price: 189.45, currency: "USD", timestamp: Date.now() }),
};

messages.push(
  { role: "assistant", content: res.content },
  { role: "user",      content: [toolResult] },
);

Discussion

  • Be the first to comment on this lesson.