Tool-Use Design Patterns
Learn tool-use design patterns for AI function calling. Parallel calls, sequential dependencies, error recovery, and prompt templates for reliable tool use.
Tool-Use Design Patterns
Tool-use (function calling) lets AI models interact with external systems — databases, APIs, search engines, or code execution environments. The way you structure tool calls — parallel, sequential, or conditional — dramatically affects reliability and performance.
Parallel Tool Calls
Multiple independent tools execute simultaneously. Best for gathering data from unrelated sources in a single turn.
Available tools:
- get_weather(city: string, units: string) → temperature, conditions
- get_news(category: string, limit: integer) → headlines, sources
- get_stock_price(symbol: string) → price, change, volume
Query: "What's the weather in Tokyo, latest tech news, and Apple's stock price?"
Model calls all 3 tools in parallel (no dependencies between them):
→ get_weather("Tokyo", "celsius")
→ get_news("technology", 5)
→ get_stock_price("AAPL")
Real-world example — dashboard data aggregation:
A user asks for their daily briefing. The model identifies 4 independent data needs:
1. get_calendar_events(today) → today's meetings
2. get_weather(user_city) → weather forecast
3. get_unread_emails(count=5) → recent messages
4. get_stock_portfolio() → portfolio performance
All 4 fire in parallel. Results are assembled into a single response.
Handling partial results: When some parallel calls fail, still present the successful ones.
Reply with whatever data you received. For failed calls, say:
"I couldn't retrieve your calendar data, but here's your weather and email summary."
Best for: Independent data gathering, dashboard widgets, initial research scoping.
Sequential Tool Calls
Output of one tool feeds the next. Required when later steps depend on earlier results.
Available tools:
- search_restaurants(cuisine: string, location: string) → list with IDs
- get_reviews(restaurant_id: string) → reviews, ratings, price range
Query: "Find the best Italian restaurants in NYC and show me their reviews"
Model executes sequentially:
1. search_restaurants("Italian", "NYC") → [restaurant_1, restaurant_2, ...]
2. get_reviews(restaurant_1), get_reviews(restaurant_2) — parallel since they depend on step 1 but not on each other
Real-world example — e-commerce fulfillment flow:
Tools:
- check_inventory(product_id: string) → {in_stock: boolean, quantity: int}
- get_shipping_options(zip: string, weight: float) → [{carrier, cost, eta}]
- place_order(product_id: string, address: string, shipping_id: string) → order_confirmation
Flow:
1. check_inventory("PROD-123")
→ {in_stock: true, quantity: 5, weight: 2.5}
2. get_shipping_options("10001", 2.5)
→ [{carrier: "UPS", cost: 8.99, eta: "3 days"}, ...]
3. place_order("PROD-123", "10001", "ups-standard")
→ {order_id: "ORD-456", status: "confirmed", total: 8.99}
Intermediate validation: After step 1, validate before proceeding.
If the product is out of stock, do not proceed to step 2 or 3.
Instead, respond with: "This item is currently out of stock."
Best for: Multi-step research, data enrichment pipelines, transaction flows, dependency chains.
Conditional Tool Calls
The model decides which tool to call next based on previous results. This creates decision trees rather than fixed sequences.
Tools:
- check_inventory(product_id: string) → stock level
- find_alternatives(product_id: string) → similar products
- get_shipping_estimate(zip: string, weight: float) → cost, eta
User: "Can I get a coffee maker delivered to 10001?"
1. check_inventory("coffee-maker-123")
Result: {in_stock: true, quantity: 3, weight: 4.2}
→ Continue to shipping estimate
But if:
1. check_inventory("coffee-maker-123")
Result: {in_stock: false, quantity: 0}
→ Branch to: find_alternatives("coffee-maker-123")
→ Show user alternatives instead
You have access to these tools. Make decisions based on data:
1. Check prerequisites first
2. Based on the result, choose the correct next step:
- Success → proceed to dependent call
- Partial success → offer alternatives
- Failure → explain and stop
3. Never call a tool whose inputs depend on data you don't have
Real-world example — troubleshooting diagnostic tree:
Tools:
- check_service_status(service: string) → up/down/degraded
- check_recent_deployments(service: string) → {timestamp, status}
- get_error_logs(service: string, timeframe: string) → [errors]
Flow:
1. check_service_status("api-gateway")
→ degraded
2. check_recent_deployments("api-gateway")
→ deployed 30 min ago
3. get_error_logs("api-gateway", "1h")
→ 500 errors on /checkout endpoint
Conclusion: Recent deployment caused errors. Recommend rollback.
Best for: Decision trees, checkout flows, validation chains, diagnostic systems.
Error Recovery Patterns
Tools fail. Your prompt should plan for every failure mode.
Available tools with error handling:
1. get_weather(city, units)
- On failure: retry once
- If still failing: search_web("weather {city}")
2. get_stock_price(symbol)
- On failure: retry once
- If still failing: "Stock data is temporarily unavailable"
3. send_email(to, subject, body)
- On failure: retry once
- If still failing: save to drafts and alert user
Error handling protocol:
Network timeout:
→ Retry once after 1 second
→ If fail again: try an alternative tool that provides similar data
→ If no alternative: report the outage to the user
Invalid parameters (400 error):
→ Check parameter format and types
→ Fix and retry
→ Report if the issue persists
Empty results (200 with no data):
→ Report "no results found"
→ Suggest broadening the search
→ Do not retry — the request was valid but nothing matched
Service unavailable (503):
→ Inform the user
→ Offer to retry later
→ Do not retry immediately
Tool Description Best Practices
Tool descriptions are prompts for the model — they determine whether tools get called correctly.
Bad description:
"get_user_data(id) — gets user data"
Good description:
"get_user_data(user_id: string) → {name, email, plan, created_at}
Fetches a user's profile information by their MongoDB ObjectId.
Example: get_user_data('507f1f77bcf86cd799439011')
Returns all fields needed for account dashboard display."
Guidelines:
- Include return schema — the model needs to know what data comes back
- Provide example parameter values — helps the model format calls correctly
- Document error conditions — "Returns null if user not found"
- Specify units, formats, and constraints — "temperature in Celsius", "max 100 results"
Rate Limiting & Token Budget
When calling tools, respect these limits:
- Max 5 concurrent tool calls
- Wait for a response before making dependent calls
- If a tool returns an empty result, do not retry more than once
Budget management:
- Each tool call costs ~100-300 tokens
- Reserve 2000 tokens for the final response
- If you have limited budget, prioritize essential tool calls
Testing Tool Calls
Test your tool-use prompts before deploying:
- Mock all dependencies — Replace real APIs with mock functions that return controlled responses
- Test error paths — What happens when a tool returns null, an unexpected schema, or a network error?
- Log call sequences — Track which tools were called in what order during development
- Validate output schemas — Ensure the model passes correct parameter types
- Test with ambiguous inputs — What if the user says "get me that thing from yesterday"?
Selection Guide
| Pattern | Dependency Type | Latency | Reliability Risk |
|---|---|---|---|
| Parallel | No dependencies between calls | Lowest (concurrent) | Partial failure handling needed |
| Sequential | Each step depends on previous | Medium | Compounding delays |
| Conditional | Branches based on results | Variable | Decision quality depends on data |
| Error recovery | All patterns | Adds retry latency | Required for production safety |
Best Practices
- Clear tool descriptions - Describe what each tool does, its parameters, and return values
- Limit concurrent calls - Too many parallel calls can overwhelm rate limits
- Set timeouts - Define maximum wait time for each tool
- Provide fallbacks - What to do when a tool is unavailable
- Log tool calls - Track which tools were called and their results for debugging
- Test error paths - Mock failures to verify your error recovery logic works
Related Articles
Modern Digital Anime SREF Codes for Midjourney
Master modern digital anime SREF codes for Midjourney. Create contemporary animation styles with smooth digital rendering, modern color techniques, and current production aesthetics.
Prompt Optimization
Techniques for optimizing prompts to improve AI response quality, reduce token usage, and achieve consistent results across models.
1920s-1930s Art Deco & Early Photography SREF Codes
Glamorous Art Deco period SREF codes with early photographic techniques, geometric luxury, and Jazz Age aesthetics.