Overview
This example demonstrates using Monty to generate and execute web scraping code. An LLM generates Python code to navigate websites with Playwright and parse HTML with BeautifulSoup, extracting structured pricing data from model provider documentation.This example uses Pydantic AI to generate code, but avoids the built-in
CodeExecutionToolset to showcase Monty features not yet available in Pydantic AI, such as iterative execution and type checking.Key Features
- Type-safe external functions: BeautifulSoup and Playwright APIs exposed as typed dataclasses
- Iterative agent loop: LLM generates code, Monty executes it, results feed back to LLM
- Type checking: Generated code is validated against stubs before execution
- Browser automation: Headless Playwright integration for dynamic web pages
Architecture
1
Generate Type Stubs
Use
stubgen to create type stubs for external functions, giving the LLM precise type information.2
LLM Generates Code
The agent receives instructions about available functions and generates Python code to scrape the target site.
3
Type Check & Execute
Monty validates the code against stubs, then executes it with access to
open_page(), beautiful_soup(), and record_model_info().4
Process Results
If execution succeeds, results are recorded. If it fails, error messages feed back to the LLM for correction.
Example Code Structure
Main Loop
Generated Code Example
Here’s the kind of code Claude Sonnet 4.5 generates for this task:External Functions API
Page Navigation
Page object provides methods like:
go_to(url)- Navigate to a new URLclick(selector)- Click an elementfill(selector, value)- Fill a form fieldget_text(selector)- Extract text contentscreenshot()- Take a screenshot
HTML Parsing
Tag object mirrors BeautifulSoup’s API:
find(name, attrs)- Find first matching tagfind_all(name, attrs, limit)- Find all matching tagsselect(selector)- CSS selector queryget_text(separator, strip)- Extract text contentchildren()- Get direct children
Running the Example
- OpenAI’s pricing page
- Anthropic’s pricing page
- Groq’s pricing page
Key Takeaways
- Code > Tool Calls: Writing a loop to process tables is more natural than sequential tool calls
- Type Safety: Type stubs catch errors before execution
- Iterative Refinement: Failed executions feed errors back to the LLM for correction
- Resource Efficiency: HTML parsing happens in the sandbox, keeping tokens out of context
Next Steps
- Explore the full source in
examples/web_scraper/ - Try Data Analysis for async patterns
- See SQL Playground for file mounting
