Skip to content

feat: schema complexity pre-flight analysis and automatic mode selection #2393

Description

@mimran-khan

Problem

Users frequently struggle to pick the right extraction mode for their schema. Complex models with deep nesting, recursion, or many fields often fail silently with generic validation errors, wasting tokens on retries. There is no guidance at call time about whether a schema is well-suited for the chosen mode.

Related issues: various discussions around mode selection confusion and retry-heavy workflows.

Proposal

Two lightweight, zero-dependency utilities:

1. Schema Complexity Analyzer (analyze_schema)

Inspects a Pydantic model's JSON schema before any API call and detects:

  • Deeply nested object hierarchies (warns at depth 4, errors at 7)
  • Recursive/self-referencing models
  • Large enum value sets (warns at 15, errors at 50)
  • Wide objects with too many properties
  • Excessive required fields

Returns a SchemaAnalysis with a 0-100 complexity score, actionable findings, and a recommended mode.

2. Automatic Mode Selection (select_mode)

Picks the best extraction mode for a given provider and response model:

  • Simple schemas -> TOOLS (native function calling)
  • Deep/complex schemas -> JSON_SCHEMA (explicit structural guidance)
  • Recursive schemas -> MD_JSON or JSON (avoids tool-call schema limitations)
  • Respects each provider's supported mode set (e.g., Perplexity only has MD_JSON)

Usage

import instructor
from pydantic import BaseModel

class MyModel(BaseModel):
    ...

# Analyze before calling
analysis = instructor.analyze_schema(MyModel)
if analysis.has_warnings:
    print(analysis.findings)

# Let instructor pick the best mode
best_mode = instructor.select_mode(MyModel, instructor.Provider.OPENAI)
client = instructor.from_openai(openai.OpenAI(), mode=best_mode)

Design

  • Pure functions, no side effects, no network calls
  • Works with any Pydantic BaseModel
  • Lazy-loaded (does not increase import cost)
  • Fully tested with 59 unit tests covering edge cases

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions