Skip to content
Go back

Why Pydantic-AI Failed with Gemini 2.5 Pro (But Direct OpenRouter Integration Succeeded)

The Problem We Faced

While building a construction specification extraction system, I encountered a critical issue: Pydantic AI + OpenRouter + Gemini 2.5 Pro consistently failed to generate valid JSON outputs, despite the promise of seamless structured output generation.

The code would run without errors, but the extracted data was unreliable often incomplete, malformed, or missing critical fields. For production systems requiring consistent structured data extraction, this was a dealbreaker.

The Solution That Worked

By switching to the OpenAI Python client directly with OpenRouter + Gemini 2.5 Pro, structured outputs became 100% reliable. Same model, same API gateway, but dramatically different results.

The Technical Deep Dive

Why Pydantic-AI Failed:

1. Intermediary Abstraction Misalignment

2. JSON Schema Feature Support Gap

3. Response Formatting Issues

Why Direct OpenRouter Integration Succeeded:

1. Native JSON Schema Support

response_format={
    "type": "json_schema",
    "json_schema": {
        "name": "extraction_result",
        "schema": ExtractionResult.model_json_schema(),
        "strict": True
    }
}

2. Direct Model-Level Enforcement

3. Zero Intermediary Abstraction

4. Enhanced Error Handling

The Key Architectural Difference

❌ FAILED APPROACH:
Our Code → Pydantic-AI (schema abstraction) → OpenRouter (gateway) 
→ Gemini 2.5 Pro → Response → Pydantic-AI (validation) → Potential Failure

✅ WORKING APPROACH:
Our Code → OpenAI Client (standard interface) → OpenRouter (gateway) 
→ Gemini 2.5 Pro (native JSON schema enforcement) → Valid JSON Response

Real-World Impact

For our construction specification extraction system:

Key Takeaways

  1. Abstraction layers aren’t always beneficial - Sometimes going direct to the API yields better results
  2. Model-native features > post-processing validation - Structured output at inference time is more reliable
  3. API gateway ≠ abstraction framework - OpenRouter succeeds because it translates, not transforms
  4. Match your tools to model capabilities - Use frameworks that align with your model’s native features

The Technical Stack That Works

from openai import OpenAI
from pydantic import BaseModel

client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="your-openrouter-key"
)

completion = client.chat.completions.create(
    model="google/gemini-2.5-pro",
    messages=[...],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "your_schema",
            "schema": YourModel.model_json_schema(),
            "strict": True
        }
    }
)

Why This Matters

As we build more complex AI systems, understanding the actual integration mechanics not just the happy-path documentation—becomes critical. The difference between a 40% failure rate and 100% reliability isn’t just about code quality; it’s about architectural decisions that align with how models actually work.


Based on production experience extracting structured data from construction specifications using Gemini 2.5 Pro via OpenRouter.



Next Blog
🔗 EXTERNAL BLOG | Automated patient engagement with Voice AI in Healthcare