Skip to content

Conversation

@Mohd-Mursaleen
Copy link

Add Structured Output Support for Gemini API

Closes #139

What This Does

Implements structured output support for Google Gemini API to get reliable JSON responses without parsing headaches. Works automatically with Gemini while keeping Ollama working exactly as before.

This uses the latest google-genai client library which has native support for structured outputs, replacing the older approach of parsing JSON from text responses.

Why This Matters

The old approach had Gemini sometimes returning malformed JSON that we'd have to parse out of markdown code blocks. Now we get clean, validated JSON directly from the API.

Before:

  • Gemini returns: ```json\n{"name": "John"}\n```
  • We clean up the markdown formatting
  • Parse the JSON
  • Hope it's valid

After:

  • Gemini returns: {"name": "John"}
  • Done

Changes

Core Files

models.py

  • Added google-genai client integration for structured output
  • Passes response_schema to Gemini API calls
  • Simplified Pydantic models (removed constraints that broke Gemini's validation)

llm_utils.py

  • New parse_llm_response() - detects if response is already structured
  • New supports_structured_output() - checks provider capabilities
  • Traditional JSON parsing still works for Ollama

pdf.py & evaluator.py

  • Updated to use structured output when available
  • No changes needed for github.py (doesn't have schemas yet)

Schema Fixes

Had to remove some Pydantic field constraints that Gemini's API didn't like:

  • ge=0, gt=0 (caused exclusiveMinimum errors)
  • min_length=1, max_items=5 (validation conflicts)
  • le=20 (maximum value issues)

These were nice-to-haves for validation but not critical. The important validation still happens in our code.

Testing

Ran through the smoke tests from CONTRIBUTING.md:

  • PDF → Markdown extraction ✓
  • All JSON Resume sections (basics, work, education, skills, projects, awards) ✓
  • GitHub enrichment ✓
  • Full evaluation pipeline ✓

Tested with:

  • gemini-2.5-flash - structured output working perfectly
  • gemma3:4b via Ollama - traditional parsing still works
  • Real resumes - end-to-end processing successful

Usage

Nothing changes for users. The code detects your provider and does the right thing:

# Gemini automatically gets structured output
provider = initialize_llm_provider("gemini-2.5-flash")
response = provider.chat(model="gemini-2.5-flash", messages=msgs, format=schema)

# Ollama keeps using traditional parsing
provider = initialize_llm_provider("gemma3:4b")
response = provider.chat(model="gemma3:4b", messages=msgs)

@Mohd-Mursaleen
Copy link
Author

@sp2hari @anxkhn-hacker
Review please ! if you agree i can move on to implement structured output for ollama as well.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Add Structured Output Support for Gemini API

1 participant