Tool Generation
Anvil’s core capability is generating working Python code from natural language descriptions. This page explains the generation process in detail.
The Generation Prompt
Section titled “The Generation Prompt”When you call use_tool(), Anvil constructs a prompt for the LLM that includes:
- System instructions - Guidelines for generating clean, safe Python code
- Your intent - The natural language description of what the tool should do
- Documentation - Fetched API docs (if
docs_urlprovided) - Input schema - Parameter definitions (if
inputsprovided)
Providing Good Intents
Section titled “Providing Good Intents”The quality of generated code depends heavily on your intent description.
Good Intent Examples
Section titled “Good Intent Examples”# Specific and actionableanvil.use_tool( name="search_notion", intent="Search a Notion workspace for pages matching a query using the official API")
# Includes key detailsanvil.use_tool( name="send_slack", intent="Send a message to a Slack channel using the Web API, handling rate limits")
# Specifies return formatanvil.use_tool( name="get_stock", intent="Get stock price for a ticker symbol, returning price and daily change as a dict")Poor Intent Examples
Section titled “Poor Intent Examples”# Too vagueanvil.use_tool(name="search", intent="Search stuff")
# Missing contextanvil.use_tool(name="send", intent="Send a message")Using Documentation URLs
Section titled “Using Documentation URLs”Providing a docs_url significantly improves code quality:
anvil.use_tool( name="create_github_issue", intent="Create a new issue in a GitHub repository", docs_url="https://docs.github.com/en/rest/issues/issues#create-an-issue")Anvil will:
- Fetch the documentation page using FireCrawl
- Extract relevant API details
- Include them in the generation prompt
This gives the LLM accurate endpoint URLs, authentication methods, and request/response formats.
Defining Input Parameters
Section titled “Defining Input Parameters”For complex tools, explicitly define inputs:
from anvil import Anvil, InputParam
anvil.use_tool( name="create_calendar_event", intent="Create a Google Calendar event", inputs=[ InputParam( name="title", param_type="str", required=True, description="Event title" ), InputParam( name="start_time", param_type="str", required=True, description="Start time in ISO 8601 format" ), InputParam( name="duration_minutes", param_type="int", required=False, default=60, description="Event duration in minutes" ), InputParam( name="attendees", param_type="list", required=False, default=[], description="List of attendee email addresses" ), ])Supported Parameter Types
Section titled “Supported Parameter Types”| Type | Python Type | Example |
|---|---|---|
str | str | "hello" |
int | int | 42 |
float | float | 3.14 |
bool | bool | True |
list | list | ["a", "b"] |
Regeneration Triggers
Section titled “Regeneration Triggers”Anvil regenerates tool code when:
- Intent changes - The hash of your intent differs from the cached version
- Force flag - You explicitly request regeneration
- Self-healing - A tool execution failed
# Force regeneration by changing intentanvil.use_tool( name="search", intent="Search the web with advanced filters" # Different from before)
# Or clear the cache# $ anvil cleanVersion Management
Section titled “Version Management”Each regeneration increments the version:
Version 1.0 → Initial generationVersion 1.1 → After self-healing fixVersion 1.2 → Another fixVersion 2.0 → Major intent changeVersion history is tracked in the tool registry.
Multi-Provider Support
Section titled “Multi-Provider Support”Anvil supports multiple LLM providers for generation:
# Use Claude (default)anvil = Anvil(provider="anthropic")
# Use GPT-4anvil = Anvil(provider="openai", model="gpt-4o")
# Use Grokanvil = Anvil(provider="grok")Each provider has default models:
- Anthropic:
claude-sonnet-4-20250514 - OpenAI:
gpt-4o - Grok:
grok-2-latest
Stub Mode for Testing
Section titled “Stub Mode for Testing”Generate placeholder tools without LLM calls:
anvil = Anvil(use_stub=True)
# Returns a stub function that returns mock datatool = anvil.use_tool(name="test", intent="Test tool")result = tool.run() # {'status': 'stub', 'intent': 'Test tool'}Useful for:
- Testing without API keys
- CI/CD pipelines
- Development without incurring LLM costs