Skip to content

feat: migrate Anthropic provider to native structured outputs API#263

Merged
cpsievert merged 16 commits into
mainfrom
feat/stream-structured-data
May 12, 2026
Merged

feat: migrate Anthropic provider to native structured outputs API#263
cpsievert merged 16 commits into
mainfrom
feat/stream-structured-data

Conversation

@cpsievert
Copy link
Copy Markdown
Collaborator

@cpsievert cpsievert commented Jan 6, 2026

Summary

Structured data extraction with ChatAnthropic() now uses Anthropic's native structured outputs API for Claude 4.5+ models. This means:

  • Streaming works with data_model — previously disabled with a warning, now fully supported
  • More reliable output — Anthropic's constrained decoding guarantees valid JSON matching your schema
  • Cleaner responses — JSON comes back as text content instead of synthetic tool calls

Older models automatically fall back to the existing tool-based approach, so this is a non-breaking change. A new structured_output_mode parameter on ChatAnthropic() and ChatBedrockAnthropic() lets you override the auto-detection — set "native" to force the output_config API or "tool" to force the legacy approach.

Also includes

  • Tests: sync and async streaming with data_model for Anthropic
  • Re-recorded VCR cassettes for data extraction tests

Test plan

  • test_data_extraction — verifies structured extraction via GA API
  • test_anthropic_nested_data_model_extraction — nested Pydantic models (regression test for Structured Data Not Working for ChatAnthropic() #100)
  • test_stream_with_data_model — sync streaming with data_model
  • test_stream_async_with_data_model — async streaming with data_model
  • Type checking passes
  • Full test suite passes

@cpsievert cpsievert changed the base branch from feat/stream-data-model to main January 6, 2026 15:58
@cpsievert cpsievert force-pushed the feat/stream-structured-data branch 5 times, most recently from 1f65317 to 677a184 Compare January 6, 2026 16:31
@cpsievert cpsievert mentioned this pull request Jan 6, 2026
Use the new output_format parameter and beta client for models that support
structured outputs (claude-sonnet-4-5, claude-opus-4-1, claude-opus-4-5,
claude-haiku-4-5). This enables streaming with data_model for these models.

Older models fall back to the previous tool-based approach.

Documentation: https://platform.claude.com/docs/en/build-with-claude/structured-outputs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@cpsievert cpsievert force-pushed the feat/stream-structured-data branch from 677a184 to b268fe4 Compare January 6, 2026 16:35
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
cpsievert and others added 3 commits January 6, 2026 11:11
- Rename use_beta_structured_output to _supports_structured_outputs
- Inline STRUCTURED_OUTPUT_MODELS into the function
- Remove streaming fallback/warning for older models (let it fail)
- Make create_data_model_tool a staticmethod
- Revert unnecessary kwargs->api_kwargs rename in _token_count_args
- Remove redundant comments about Beta API type signatures

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move STRUCTURED_OUTPUTS_BETA and supports_structured_outputs after TYPE_CHECKING
- Make supports_structured_outputs public (remove leading underscore)
- Consolidate data_model handling into single block
- Add TODO for removing legacy tool-based approach

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
@cpsievert cpsievert requested a review from Copilot January 6, 2026 17:26

This comment was marked as resolved.

@cpsievert cpsievert marked this pull request as draft April 24, 2026 18:52
cpsievert added 4 commits May 12, 2026 09:23
…d-data

# Conflicts:
#	CHANGELOG.md
#	chatlas/_provider_anthropic.py
- Replace explicit model allowlist with regex pattern matching (claude-*-4-[5-9])
  to automatically support future Claude 4.5+ models
- Switch from beta endpoint (client.beta.messages.create) to regular
  messages.create since structured outputs are now GA
- Rename output_format to output_config.format per the GA API surface
- Remove STRUCTURED_OUTPUTS_BETA constant
- Remove type: ignore comments — output_config is in SubmitInputArgs
- Remove cast(list, ...) by appending to tool_schemas before dict construction
- Add OutputConfigParam import for proper type annotation
cpsievert added 2 commits May 12, 2026 09:43
Add sync and async streaming tests with data_model for ChatAnthropic,
mirroring the existing OpenAI tests. Re-record existing data extraction
cassettes to use the GA output_config parameter.
@cpsievert cpsievert requested a review from Copilot May 12, 2026 14:54
@cpsievert cpsievert marked this pull request as ready for review May 12, 2026 14:54

This comment was marked as resolved.

cpsievert added 5 commits May 12, 2026 10:03
…traction

Models that don't support native structured outputs (pre-4.5) were
silently attempting to stream with the tool-based approach after the
guard was removed during the output_config refactor.
Widen supports_structured_outputs() regex to match all Claude 4 models
(including 4.0, 4.1), not just 4.5+. Add "cookie" to VCR filter_headers
and remove leaked _cfuvid cookies from cassette.
…ckAnthropic

Lets users override auto-detection of native structured outputs support
with "native" (force output_config API) or "tool" (force legacy approach).
Defaults to "auto" which uses the model regex heuristic.
@cpsievert cpsievert merged commit 61f496b into main May 12, 2026
9 checks passed
@cpsievert cpsievert requested a review from Copilot May 12, 2026 15:42

This comment was marked as low quality.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants