Port your scratch agent to a production-ready framework. Learn typed tools and structured outputs.
You've built an agent from scratchβnow you understand the fundamentals. But raw API calls don't scale. Tenzai uses frameworks that provide type safety, validation, and better developer experience.
Pydantic AI is a lightweight, type-first framework that's closer to the metal than LangChain but more structured than raw calls. Rebuild your agent using it.
| Aspect | Raw API | Pydantic AI |
|---|---|---|
| Tool definitions | Manual JSON schemas | Derived from Pydantic models |
| Type safety | None (dict/str) | Full type checking |
| Validation | Manual | Automatic via Pydantic |
| Boilerplate | Higher | Lower |
| Flexibility | Maximum | Framework conventions |
pip install pydantic-ai
from pydantic_ai import Agent
from pydantic import BaseModel
# Define the agent with a system prompt
agent = Agent(
'openai:gpt-4',
system_prompt='You are a helpful assistant that uses tools to solve problems.'
)
from pydantic import Field
class CalculatorInput(BaseModel):
expression: str = Field(description="Math expression to evaluate")
@agent.tool
def calculator(input: CalculatorInput) -> str:
"""Perform arithmetic calculations."""
# Safe evaluation (use a proper math parser in production!)
try:
result = eval(input.expression)
return f"Result: {result}"
except Exception as e:
return f"Error: {e}"
class ReadFileInput(BaseModel):
path: str = Field(description="Path to file to read")
@agent.tool
def read_file(input: ReadFileInput) -> str:
"""Read contents of a file."""
try:
with open(input.path, 'r') as f:
return f.read()
except FileNotFoundError:
return f"File not found: {input.path}"
async def main():
result = await agent.run("What is 25 * 17 + 89?")
print(result.data) # The final response
print(result.all_messages()) # Full conversation history
import asyncio
asyncio.run(main())
from pydantic import BaseModel
class MathResult(BaseModel):
expression: str
result: float
explanation: str
# Create agent that returns structured output
math_agent = Agent(
'openai:gpt-4',
result_type=MathResult,
system_prompt='Solve math problems and explain your work.'
)
# The agent will return a MathResult object, not a string
result = await math_agent.run("What is 25 * 17 + 89?")
print(result.data.result) # 514.0
print(result.data.explanation) # "First multiply 25 by 17..."
Official documentation with examples and API reference
Deep dive into tool definitions and patterns
How to get typed outputs from agents
Official examples from the Pydantic AI repo