Skip to main content
GitHub

Instructor

Auto-instrument Instructor for structured outputs.

Risicare automatically instruments Instructor for structured output generation.

Installation

pip install risicare[instructor]
# or
pip install risicare instructor

Version Compatibility

Requires instructor >= 1.0.0.

Auto-Instrumentation

import risicare
import instructor
from pydantic import BaseModel
 
risicare.init()
 
client = instructor.from_provider("openai/gpt-4o")
 
class User(BaseModel):
    name: str
    age: int
 
# Automatically traced
user = client.create(
    response_model=User,
    messages=[{"role": "user", "content": "Extract: John is 25 years old"}]
)

What's Captured

FeatureDescription
Extraction CallsFull instructor.create calls
Response ModelPydantic model schema
ValidationValidation attempts and retries
LLM CallsUnderlying provider calls
Retry LogicAutomatic retry on validation failure

Span Hierarchy

instructor.create/{response_model} (INTERNAL kind)

Provider Spans

Instructor instrumentation creates agent/framework-level spans. Underlying LLM calls (e.g., OpenAI, Anthropic) are traced separately by provider instrumentation, giving you both framework-level and LLM-level visibility.

Retries

Instructor's retry logic is fully traced:

from instructor import Mode
 
client = instructor.from_provider(
    "openai/gpt-4o",
    mode=Mode.JSON,
    max_retries=3
)
 
# Each retry attempt appears as a child span
user = client.create(
    response_model=User,
    messages=[{"role": "user", "content": "Extract user info"}]
)

Streaming

from typing import Iterable
 
class PartialUser(BaseModel):
    name: str | None = None
    age: int | None = None
 
for partial in client.chat.completions.create_partial(
    model="gpt-4o",
    response_model=PartialUser,
    messages=[{"role": "user", "content": "Extract: John is 25"}]
):
    print(partial)

Complex Models

Nested and complex models are fully captured:

from typing import List
 
class Address(BaseModel):
    street: str
    city: str
    country: str
 
class Company(BaseModel):
    name: str
    employees: int
    addresses: List[Address]
 
# Schema complexity is captured
company = client.create(
    response_model=Company,
    messages=[{"role": "user", "content": "Extract company info..."}]
)

Next Steps