Skip to content

add anthropic json schema support#339

Merged
TonsOfFun merged 3 commits into
activeagents:mainfrom
aoki-ryusei:feature/anthropic-json-schema-support
Jun 25, 2026
Merged

add anthropic json schema support#339
TonsOfFun merged 3 commits into
activeagents:mainfrom
aoki-ryusei:feature/anthropic-json-schema-support

Conversation

@aoki-ryusei

Copy link
Copy Markdown
Contributor

Summary

Adds native JSON Schema structured output support for the Anthropic provider by mapping the common response_format: :json_schema
API to Anthropic's output_config.format API. This allows agents using Anthropic to get schema-validated JSON responses using the same interface as OpenAI — no provider-specific code required.

The implementation adds normalize_response_format in Transforms, which converts the common format to Anthropic's native structure. json_object emulation (prompt prefill) is unchanged.

How it works

normalize_response_format translates the common response_format hash into Anthropic's output_config.format structure. name and strict from the common format are intentionally dropped — Anthropic's API does not use them. JSON Schema Hashes are passed through as-is and are not converted to Anthropic::BaseModel. No beta header is required; output_config is part of the stable Messages API.

Usage

class ColorsAgent < ApplicationAgent
  generate_with :anthropic, model: "claude-haiku-4-5"

  def primary_colors
    prompt(
      "Return the three primary colors.",
      response_format: :json_schema
    )
  end
end

Place a schema file at app/views/agents/colors_agent/primary_colors.json:

{
  "schema": {
    "type": "object",
    "properties": {
      "colors": { "type": "array", "items": { "type": "string" } }
    },
    "required": ["colors"],
    "additionalProperties": false
  }
}

ActiveAgent serializes the request as:

{
  output_config: {
    format: {
      type: "json_schema",
      schema: { ... }
    }
  }
}

Supported input forms

All four input forms produce the same output_config payload:

Form Example
Bare symbol response_format: :json_schema
Type-only hash response_format: { type: "json_schema" }
Inline schema response_format: { type: "json_schema", json_schema: { name:, schema:, strict: } }
Named schema response_format: { type: "json_schema", json_schema: "other" }

Files changed

Production code (2 files):

File Purpose
anthropic/transforms.rb Add normalize_response_format to convert json_schema to output_config.format; call it in normalize_params
anthropic/request.rb Read response_format without deleting so @response_format is preserved for json_object emulation; normalize_params handles deletion and conversion

Test code (1 file, 6 tests):

File Tests
response_format_test.rb Enable test_request_builder for all four input forms; enable live VCR test asserting response.format.type == "json_schema" and response.message.parsed_json[:colors] is an Array

Supporting files:

File Purpose
vcr_cassettes/…/test_agent_response_json_schema_*.yml VCR cassettes for the four json_schema variants
docs/actions/structured_output.md Update provider support table (Anthropic json_schema: ❌ → 🟩)
docs/providers/anthropic.md Add JSON Schema Support section; update Limitations

Design decisions

  • Pass-through Hash: JSON Schema Hashes are forwarded as-is to Anthropic. No conversion to Anthropic::BaseModel — keeps the
    implementation provider-agnostic and consistent with how OpenAI structured output works in ActiveAgent.
  • name / strict dropped: Anthropic's output_config.format does not support these OpenAI fields. They are accepted in the common API
    but not forwarded.
  • json_object unchanged: The existing prompt-prefill emulation for json_object is preserved. output_config.format and message
    prefill are incompatible, so they remain separate code paths.
  • No beta header: output_config is part of the stable Messages API. Beta is only triggered by MCP or explicit anthropic_beta.

Test plan

  • All four input forms produce the same output_config payload — verified by test_request_builder
  • Live VCR test confirms response.format.type == "json_schema" and response.message.parsed_json[:colors] is an Array
  • Existing json_object and text tests pass unchanged
  • Reviewer: verify CI passes on all matrix combinations

Add native structured output support for the Anthropic provider by
mapping the common response_format: :json_schema to Anthropic's
output_config.format API.

Changes:
- transforms.rb: add normalize_response_format to convert json_schema
  response_format to { format: { type: "json_schema", schema: ... } }
  for output_config. json_object and text remain unhandled (nil) to
  preserve existing behavior.
- transforms.rb: call normalize_response_format in normalize_params,
  deleting response_format and setting output_config when applicable.
- request.rb: read response_format without deleting so @response_format
  is preserved for json_object emulation; normalize_params handles
  deletion and conversion.

Design decisions:
- JSON Schema Hashes are passed through as-is; not converted to
  Anthropic::BaseModel.
- name and strict from the common format are not forwarded;
  Anthropic's output_config.format does not use them.
- Beta header is not required for output_config (stable API).
Activate previously commented-out json_schema tests now that the
Anthropic provider supports output_config.format.

Changes:
- Update REQUEST_JSON_SCHEMA to include output_config.format.schema
  as the expected serialized request shape.
- Enable test_request_builder for response_json_schema_inline,
  response_json_schema_implicit, response_json_schema_named, and
  response_json_schema_implicit_bare, verifying all four input forms
  produce the same output_config payload.
- Enable live VCR test asserting response.format.type == "json_schema"
  and response.message.parsed_json[:colors] is an Array.
- Add VCR cassettes for the four json_schema variants and update
  text cassettes to reflect current request format.
Document Anthropic's native json_schema structured output support.

Changes:
- structured_output.md: update provider support table, marking
  Anthropic json_schema as supported (🟩) with a note about
  output_config.format on supported Claude models.
- anthropic.md: add JSON Schema Support section with usage example,
  serialized request format, and notes on name/strict not forwarded
  and model availability.
- anthropic.md: update Response Format parameter reference to include
  JSON Schema Support link.
- anthropic.md: update Limitations section to reflect that Anthropic
  now natively supports json_schema via output_config.format.

@TonsOfFun TonsOfFun left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to merge this as the only failure is from a deprecation on rails main that is now resolved on activeagent main

@TonsOfFun TonsOfFun merged commit 3cbd61a into activeagents:main Jun 25, 2026
8 of 9 checks passed
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.

Support structured output for newer Anthropic models

2 participants