Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

build-a-tool-using-agent changedagents-and-tools/tool-use/build-a-tool-using-agent

Nearest release: v2.1.307, published an hour after this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+13added
Lines−13removed
From line 770 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits12to this page, all time

The whole hunk

from line 770, old and new numbered
/
lines
from line 770
770770 # Send the user's request along with the tool definition. Claude decides
771771 # whether to call the tool based on the request and the tool description.
772772 response = client.messages.create(
773 model: "claude-opus-5-5",
773 model: Anthropic::Model::CLAUDE_OPUS_5_5,
774774 max_tokens: 1024,
775775 tools: tools,
776776 tool_choice: tool_choice,
from line 795
795795 # its tool_use_id must match the id from the tool_use block above. The
796796 # assistant's previous response is included so Claude has the full history.
797797 followup = client.messages.create(
798 model: "claude-opus-5-5",
798 model: Anthropic::Model::CLAUDE_OPUS_5_5,
799799 max_tokens: 1024,
800800 tools: tools,
801801 tool_choice: tool_choice,
from line 840
840840 
841841Ring 1 assumed Claude would call the tool exactly once. Real tasks often need several calls: Claude might create an event, read the confirmation, then create another. The fix is a `while` loop that keeps running tools and feeding results back until `stop_reason` is no longer `"tool_use"`.
842842 
843The other change is conversation history. Instead of rebuilding the `messages` array from scratch on each request, keep a running list and append to it. Every turn sees the complete prior context.
843The other change is conversation history. Instead of rebuilding the `messages` array on each request, keep a running list and append to it. Each request then includes the complete prior context.
844844 
845845<CodeGroup exclude="shell:cURL, shell:CLI">
846846 <CodeGroupItem language="cURL">
from line 1551
15511551 ]
15521552 
15531553 response = client.messages.create(
1554 model: "claude-opus-5-5",
1554 model: Anthropic::Model::CLAUDE_OPUS_5_5,
15551555 max_tokens: 1024,
15561556 tools: tools,
15571557 tool_choice: tool_choice,
from line 1577
15771577 }
15781578 
15791579 response = client.messages.create(
1580 model: "claude-opus-5-5",
1580 model: Anthropic::Model::CLAUDE_OPUS_5_5,
15811581 max_tokens: 1024,
15821582 tools: tools,
15831583 tool_choice: tool_choice,
from line 2369
23692369 ]
23702370 
23712371 response = client.messages.create(
2372 model: "claude-opus-5-5",
2372 model: Anthropic::Model::CLAUDE_OPUS_5_5,
23732373 max_tokens: 1024,
23742374 tools: tools,
23752375 messages: messages
from line 2390
23902390 messages << {role: "user", content: tool_results}
23912391 
23922392 response = client.messages.create(
2393 model: "claude-opus-5-5",
2393 model: Anthropic::Model::CLAUDE_OPUS_5_5,
23942394 max_tokens: 1024,
23952395 tools: tools,
23962396 messages: messages
from line 3261
32613261 ]
32623262 
32633263 response = client.messages.create(
3264 model: "claude-opus-5-5",
3264 model: Anthropic::Model::CLAUDE_OPUS_5_5,
32653265 max_tokens: 1024,
32663266 tools: tools,
32673267 messages: messages
from line 3290
32903290 messages << {role: "user", content: tool_results}
32913291 
32923292 response = client.messages.create(
3293 model: "claude-opus-5-5",
3293 model: Anthropic::Model::CLAUDE_OPUS_5_5,
32943294 max_tokens: 1024,
32953295 tools: tools,
32963296 messages: messages
from line 3309
33093309I tried to schedule the all-hands but the calendar only allows 10 attendees per event. I can split this into two sessions, or you can let me know which 10 people to prioritize.
33103310```
33113311 
3312The `is_error` flag is the only difference from a successful result. Claude sees the flag and the error text, and responds accordingly. See [Handle tool calls](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls) for the full error-handling reference.
3312The `is_error` flag is the only difference from a successful result. Claude receives the flag and the error text, and responds accordingly. See [Handle tool calls](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls) for the full error-handling reference.
33133313 
33143314## Ring 5: The Tool Runner SDK abstraction
33153315 
33163316Rings 2 through 4 wrote the same loop by hand: call the API, check `stop_reason`, run tools, append results, repeat. The Tool Runner does this for you. Define each tool as a function, pass the list to `client.beta.messages.tool_runner()` (typescript: `client.beta.messages.toolRunner()`; java: `client.beta().messages().toolRunner()`; php: `$client->beta->messages->toolRunner()`; csharp: `client.Beta.Messages.ToolRunner()`; go: `client.Beta.Messages.NewToolRunner()`), and retrieve the final message once the loop completes. Error wrapping, result formatting, and conversation management are handled internally.
33173317 
3318Each SDK provides a helper that turns an ordinary function into a runnable tool and derives the input schema from its signature; the following tabs show the idiomatic form for each language.
3318The SDK provides a helper that turns an ordinary function into a runnable tool and derives the input schema from its signature; the following example shows the idiomatic form.
33193319 
33203320<CodeGroup exclude="shell:cURL, shell:CLI">
33213321 <CodeGroupItem language="cURL">
from line 3905
39053905 # The runner calls the API, runs requested tools, and feeds results back
39063906 # until Claude produces a final answer.
39073907 runner = client.beta.messages.tool_runner(
3908 model: "claude-opus-5-5",
3908 model: Anthropic::Model::CLAUDE_OPUS_5_5,
39093909 max_tokens: 1024,
39103910 tools: [CreateCalendarEvent.new, ListCalendarEvents.new],
39113911 messages: [
from line 3931
39313931I checked your calendar for Monday, March 30 and found an existing meeting from 2pm to 3pm. I've scheduled the planning session for 10am to 11am to avoid the conflict.
39323932```
39333933 
3934The output is identical to Ring 3. The difference is in the code: roughly half the lines, no manual loop, and the schema lives next to the implementation.
3934The output is identical to Ring 3. The difference is in the code: roughly half the lines, no manual loop, and a schema that lives next to the implementation.
39353935 
39363936## What you built
39373937 
Feedback