# This loads ALL 500 tool definitions into context
tools <- lapply(1:500, create_tool)
chat <- claude_new(tools = tools)
# Context exhausted before first message!Overview
This vignette covers advanced tool use patterns:
- Tool Search: Dynamic tool discovery from large collections
- Programmatic Tool Calling: Orchestrate tools via code
- Token-Efficient Tools: Reduce tool response tokens by up to 70%
Tool Search
The Problem
Loading hundreds of tools upfront consumes massive context:
The Solution: Deferred Loading
Mark tools for deferred loading - Claude searches for needed tools on demand:
library(artclaude)
# Create 100 tools with deferred loading
tools <- lapply(1:100, function(i) {
claude_tool_defer(claude_tool(
fn = function() paste("Result from tool", i),
name = paste0("tool_", i),
desc = paste("Tool number", i)
))
})
chat <- claude_new(
tools = tools,
beta = beta_headers$BETA_TOOL_SEARCH
)
chat$chat("Use tool_42")
# Only tool_42 definition loaded into contextHow It Works
- You mark tools with
claude_tool_defer() - Tool metadata goes to API, full definitions stay deferred
- Claude searches tool names/descriptions
- Only needed tools get loaded into context
- Massive context savings
Best Practices
Tool search works best when:
-
Clear names:
calculate_tax, notcalc_t - Descriptive: Good descriptions help Claude find the right tool
- Organized: Group related tools with consistent naming
# Good: Clear names and descriptions
tax_tool <- claude_tool_defer(claude_tool(
fn = calculate_tax,
name = "calculate_sales_tax",
desc = "Calculate sales tax for a purchase amount and state"
))
# Not ideal: Vague names
tool_1 <- claude_tool_defer(claude_tool(
fn = calc,
name = "calc",
desc = "Does calculations"
))Programmatic Tool Calling
The Problem
Calling tools individually wastes tokens:
# 3 separate API round-trips, all results in context
chat$chat("Search for 'impressionism'")
chat$chat("Search for 'baroque'")
chat$chat("Search for 'renaissance'")The Solution
Claude writes code that orchestrates multiple tool calls:
search_tool <- claude_tool_programmatic(claude_tool(
fn = function(query) search_database(query),
name = "search",
desc = "Search the art database",
query = ellmer::type_string("Search query")
))
chat <- claude_new(
tools = list(search_tool, claude_code_exec(type = "python")),
beta = c(beta_headers$BETA_ADVANCED_TOOLS, beta_headers$BETA_CODE_EXEC_PYTHON)
)
chat$chat("Search for 'impressionism', 'baroque', and 'renaissance' and combine results")
# Claude writes Python that:
# 1. Calls search("impressionism")
# 2. Calls search("baroque")
# 3. Calls search("renaissance")
# 4. Combines and filters results
# 5. Returns only summary to contextBenefits
Programmatic tool calling provides:
- 37%+ token reduction vs individual calls
- Batch processing: Multiple calls in one execution
- Filtered results: Only relevant data enters context
- Aggregation: Combine/summarize before returning
Requirements
Programmatic tool calling requires:
-
Beta header:
beta_headers$BETA_ADVANCED_TOOLS -
Code execution:
claude_code_exec(type = "python") -
Marked tools: Wrap with
claude_tool_programmatic()
Example: Batch Processing
# Create programmatic tools
fetch_tool <- claude_tool_programmatic(claude_tool(
fn = function(url) fetch_url(url),
name = "fetch",
desc = "Fetch content from URL",
url = ellmer::type_string("URL to fetch")
))
analyze_tool <- claude_tool_programmatic(claude_tool(
fn = function(text) analyze_sentiment(text),
name = "analyze",
desc = "Analyze sentiment",
text = ellmer::type_string("Text to analyze")
))
chat <- claude_new(
tools = list(fetch_tool, analyze_tool, claude_code_exec(type = "python")),
beta = c(beta_headers$BETA_ADVANCED_TOOLS, beta_headers$BETA_CODE_EXEC_PYTHON)
)
chat$chat("Fetch these 10 URLs and analyze sentiment of each:
url1, url2, url3, url4, url5, url6, url7, url8, url9, url10")
# Claude writes Python to:
# - Loop through URLs
# - Fetch each
# - Analyze sentiment
# - Return summary statistics onlyToken-Efficient Tools
Enable Globally
Reduce all tool response tokens:
chat <- claude_new(
tools = list(claude_web_search()),
token_efficient = TRUE
)
chat$chat("Search for R package best practices")
# Uses more compact tool response formatImpact
Token-efficient tools:
- Average reduction: 14%
- Maximum reduction: 70% (some cases)
- No quality loss: Same information, more compact format
Combine with Other Features
# Maximum efficiency: token-efficient + context editing
chat <- claude_new(
tools = list(claude_web_search()),
token_efficient = TRUE,
context_edit = claude_context_edit(),
beta = beta_headers$BETA_CONTEXT_MGMT
)
# Can run extremely long sessions
for (i in 1:200) {
chat$chat(paste("Search topic", i))
}Complete Example: Research Assistant
Combining all advanced features:
library(artclaude)
# Setup
memory_dir <- "~/agents/research_assistant"
fs::dir_create(memory_dir)
# Create comprehensive research agent
agent <- claude_new(
tools = list(
claude_memory(memory_dir),
claude_web_search(),
claude_web_fetch(),
claude_code_exec(type = "python")
),
context_edit = claude_context_edit(
trigger_tokens = 50000L,
keep_tool_uses = 10L,
exclude_tools = c("memory")
),
token_efficient = TRUE,
beta = c(
beta_headers$BETA_CONTEXT_MGMT,
beta_headers$BETA_CODE_EXEC_PYTHON
)
)
# Day 1: Initial research
agent$chat("Research the history of Impressionism and save key facts to memory")
# Day 2: Expand research
agent$chat("Research Post-Impressionism and compare with Impressionism from memory")
# Day 3: Deep dive (many tool calls)
agent$chat("For each Impressionist artist in memory, search for their biography")
# Context editing prevents exhaustion
# Token-efficient keeps responses compact
# Day 4: Generate report
agent$chat("Create a comprehensive report from all research in memory")Performance Comparison
| Configuration | 100-turn Session | Notes |
|---|---|---|
| No optimizations | Fails at ~30 turns | Context exhaustion |
| Context editing | 84% less tokens | Completes successfully |
| + Token-efficient | 90%+ less tokens | Maximum efficiency |
| + Programmatic tools | 95%+ less tokens | With batch operations |
API References
Related Functions
-
claude_tool_defer(): Mark tool for deferred loading -
claude_tool_programmatic(): Enable programmatic calling -
claude_context_edit(): Configure context management -
claude_new(): Create chat with advanced features
