Automated Tool Runner
Relevant source files
The following files were used as context for generating this wiki page:
The Automated Tool Runner is a specialized module within the Anthropic Go SDK designed to simplify and automate the conversation loop between Claude and client-side tools. It eliminates the manual effort of parsing tool_use blocks from Claude's responses, executing the corresponding local functions, and sending the results back to the model.
This system supports both standard and streaming message interfaces. It handles parallel tool execution, automatic JSON schema generation from Go structs, and provides robust error handling where tool execution failures are communicated back to the model to allow for recovery or retry attempts.
Sources: tools.md:1-12, betatoolrunner.go:198-206
Architecture and Components
The Automated Tool Runner is built on a set of interfaces and runner classes that manage state, message history, and tool execution logic.
BetaTool Interface
The BetaTool interface is the core abstraction for any tool that can be executed. It encapsulates the tool's metadata (name, description, and input schema) and an Execute method that processes raw JSON input from the model.
Sources: betatoolrunner.go:11-21
Runner Implementations
The SDK provides two primary runner implementations:
- BetaToolRunner: Handles standard non-streaming conversation loops using
NextMessageorRunToCompletion. - BetaToolRunnerStreaming: Handles streaming conversation loops, yielding events as they arrive via
NextStreamingorAllStreaming.
Both runners inherit shared state from betaToolRunnerBase, which maintains the message history, tool map, and iteration counters.
Sources: betatoolrunner.go:29-50, betatoolrunner.go:198-209, betatoolrunner.go:275-285
Class Relationship Diagram
The following diagram illustrates the relationship between the runners, the tool interface, and the underlying message service.
Tool Definition and Schema Generation
Tools are defined by combining a Go function (handler) with a name, description, and JSON schema. The SDK provides helpers in the toolrunner package to automate this.
Tool Creation Methods
| Method | Description | Source |
|---|---|---|
NewBetaToolFromJSONSchema | Recommended. Inferred schema from a struct using jsonschema tags. | toolrunner/tool.go:102-132 |
NewBetaToolFromBytes | Creates a tool using a pre-defined JSON schema provided as bytes. | toolrunner/tool.go:88-98 |
NewBetaTool | Creates a tool using an explicit BetaToolInputSchemaParam object. | toolrunner/tool.go:135-146 |
Schema Transformation
The SDK uses schemautil.go to transform standard JSON schemas into a format compatible with Anthropic's API requirements. This includes:
- Setting
additionalProperties: falsefor objects. - Filtering for supported string formats (e.g.,
date-time,uuid). - Converting
oneOftoanyOffor broader compatibility.
Sources: schemautil.go:37-75, schemautil.go:121-137
Execution Flow and Logic
The Automated Tool Runner follows a cyclical "turn-based" logic to advance the conversation.
The Conversation Loop
- Request: The runner sends the current message history and tool definitions to Claude.
- Response Analysis: If Claude returns text content, it is captured. If Claude returns
tool_useblocks, the runner initiates execution. - Parallel Execution: Multiple tool calls within a single response are executed concurrently using
golang.org/x/sync/errgroup. - Result Integration: Tool results (or error messages) are formatted into a
userrole message and appended to the history. - Iteration: The process repeats until Claude stops calling tools or
MaxIterationsis reached.
Sequence Diagram: Tool Execution Loop
The following diagram shows the sequence of events when Claude triggers a tool call.
Configuration and State Management
Runners are configured via BetaToolRunnerParams, which extends the standard message parameters.
Configuration Options
| Parameter | Type | Description | Default |
|---|---|---|---|
BetaMessageNewParams | Struct | Standard message parameters (Model, Messages, MaxTokens, etc.) | N/A |
MaxIterations | int | Limits the number of API calls. 0 means no limit. | 0 |
Sources: betatoolrunner.go:23-27, tools.md:144-152
State Inspection
Developers can monitor the runner's progress through several methods:
- IterationCount(): Returns the total number of API calls made.
- IsCompleted(): Indicates if the loop has terminated.
- Messages(): Provides a copy of the conversation history.
- Err(): Returns the last error encountered during the loop.
Sources: betatoolrunner.go:81-105
Error Handling
The Tool Runner implements a "graceful failure" model. If a tool handler returns a Go error, the runner does not immediately crash. Instead:
- The error is intercepted in
executeToolUse. - An error message is formatted as a
tool_resultwithis_error: true. - This result is sent back to Claude.
This allows Claude to understand what went wrong (e.g., "invalid city name") and potentially correct its input in a subsequent turn.
Sources: betatoolrunner.go:171-196, toolrunner/runner_test.go:195-245
Conclusion
The Automated Tool Runner provides a robust framework for building agentic workflows with Claude in Go. By leveraging parallel execution and automated schema generation, it allows developers to focus on tool logic rather than the mechanics of the LLM conversation loop. Its support for both standard and streaming modes ensures it can be integrated into a wide variety of application architectures.
Sources: tools.md:1-12, betatoolrunner.go:198-206