Can Pydantic Models Be Used Directly as Extraction Schemas in Needle?
Yes, Needle treats Pydantic models as first-class extraction schemas, automatically converting them to OpenAI-compatible JSON schemas for LLM tool extraction.
The cactus-compute/needle library eliminates manual schema writing by detecting pydantic.BaseModel subclasses and generating proper extraction schemas at runtime. This native integration means you can define structured data requirements using Pydantic's familiar syntax, then pass models directly as function type hints for automatic schema generation.
How Needle Detects Pydantic Models
Needle's schema building pipeline includes explicit Pydantic detection in needle/agent/tools.py. The _is_pydantic_model function (lines 45-48) identifies when a parameter annotation inherits from pydantic.BaseModel:
# From needle/agent/tools.py (lines 45-48)
def _is_pydantic_model(annotation) -> bool:
"""Check if an annotation is a Pydantic model."""
return isinstance(annotation, type) and issubclass(annotation, pydantic.BaseModel)
Once detected, the model conversion flows through pydantic_schema (lines 51-61), which extracts field definitions, types, defaults, and descriptions into standard JSON Schema format.
Complete Working Example
Here's how to use a Pydantic model directly as an extraction schema in a Needle tool:
# example.py
import pydantic
from needle import tool
# Step 1: Define your data model
class Weather(pydantic.BaseModel):
"""Current weather conditions."""
location: str # Required field
temperature_c: float # Required numeric field
description: str = "clear" # Optional with default
# Step 2: Use the model as a direct type hint
@tool
def get_weather(info: Weather) -> str:
"""Retrieve a weather report based on the provided info."""
return f"The weather in {info.location} is {info.temperature_c}°C and {info.description}."
# Step 3: Needle generates the extraction schema automatically
The resulting schema from build_schema(get_weather) produces:
{
"name": "get_weather",
"description": "Retrieve a weather report based on the provided info.",
"parameters": {
"type": "object",
"properties": {
"info": {
"type": "object",
"properties": {
"location": {"type": "string"},
"temperature_c": {"type": "number"},
"description": {"type": "string", "default": "clear"}
},
"required": ["location", "temperature_c"]
}
},
"required": ["info"]
}
}
Schema Generation Pipeline
The conversion happens in three stages inside needle/agent/tools.py:
build_schema(lines 11-42) — Entry point that processes function signatures and docstrings_json_type(lines 68-70) — Dispatches topydantic_schemawhen_is_pydantic_modelreturnsTruepydantic_schema(lines 51-61) — Converts Pydantic fields to JSON Schema properties, handling:- Type mappings (str→string, float→number, etc.)
- Required vs. optional fields
- Default values
- Field descriptions from docstrings
Nested Models and Complex Structures
Pydantic models with nested structures work automatically. Needle recursively processes compound types:
from typing import List
from needle import tool
import pydantic
class Address(pydantic.BaseModel):
street: str
city: str
class Person(pydantic.BaseModel):
name: str
addresses: List[Address] # Nested model in a list
@tool
def register_person(data: Person) -> str:
"""Register a person with their addresses."""
return f"Registered {data.name} with {len(data.addresses)} addresses"
The generated schema includes the full nested Address definition under data.properties.addresses.items.
Validation and Testing
The Needle repository includes comprehensive tests confirming Pydantic schema functionality:
tests/test_tools.py— Unit tests forbuild_schemawith various Pydantic model configurationstests/test_inference.py— End-to-end tests demonstrating LLM extraction into Pydantic instances
Summary
- Direct type hint usage — Annotate function parameters with
pydantic.BaseModelsubclasses - Automatic detection — Needle's
_is_pydantic_modelidentifies Pydantic classes at runtime - Full schema generation —
pydantic_schemaconverts models to OpenAI-compatible JSON Schema - Nested support — Complex models with nested structures and collections work without additional configuration
Frequently Asked Questions
Does Needle support Pydantic v2 models?
Yes, Needle's pydantic_schema function (lines 51-61 in needle/agent/tools.py) uses Pydantic's core schema generation APIs that work with both Pydantic v1 and v2. The validation logic in tests/test_tools.py confirms compatibility across versions.
What happens if a Pydantic model has validation rules?
Needle extracts the type structure and field metadata, but does not embed Pydantic validation rules (like Field(gt=0)) into the JSON Schema sent to the LLM. The returned data is validated when Pydantic instantiates the model, so invalid values raise pydantic.ValidationError at runtime.
Can I use standard Python types instead of Pydantic?
Yes. Needle's _json_type handles both standard types (str, int, float, bool, list, dict) and Pydantic models. Standard types map directly to JSON Schema primitives, while Pydantic models trigger the full conversion pipeline for structured data extraction.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →