fix: use json.RawMessage for JSONOutputFormatParam.Schema to preserve key ordering#271
Conversation
… key ordering The SDK's internal JSON encoder sorts map keys alphabetically for deterministic output (internal/apijson/encoder.go L359-362). When Schema is typed as map[string]any, this sorting reorders the JSON schema keys sent in the response_format parameter. This key reordering can affect model output, as models may be sensitive to the structural presentation of the schema even when the schemas are semantically equivalent. By changing Schema from map[string]any to json.RawMessage, the user-provided JSON schema is sent verbatim to the API without any key reordering, preserving the intended field ordering and ensuring consistent model behavior. Reference: envoyproxy/ai-gateway#1299
dtmeadows
left a comment
There was a problem hiding this comment.
Thanks so much for this @xiaolin593! This fix looks correct to me. We've changed the type of many of these schema-type fields to this type, like here: https://github.com/anthropics/anthropic-sdk-go/blob/main/message.go#L1457-L1458
|
Or hrmmm.... maybe not. This is a breaking type change. |
…mat-schema-key-ordering
|
It's indeed a breaking type change which I believe it's needed. I merged latest into branch, @dtmeadows can you help kick off CI? |
|
https://platform.claude.com/docs/en/build-with-claude/structured-outputs#property-ordering I think |
|
Hey @xiaolin593, I definitely agree that this is a positive change! I'd also buy the argument that this is arguably a bug fix where a change like this is merited. I do want to triple check though that a breaking change (albeit small) is acceptable here. |
|
I'm supportive of a breaking change but lets make sure we audit and do it across all fields that need it in one so we don't end up having to make multiple breaking changes or create inconsistency (tool use block's |
The change is to preserve user's input key order in honor of model's chain of thoughts.
The SDK's internal JSON encoder sorts map keys alphabetically for
deterministic output (internal/apijson/encoder.go L359-362). When
Schema is typed as map[string]any, this sorting reorders the JSON
schema keys sent in the response_format parameter. This key reordering
can affect model output, as models may be sensitive to the structural
presentation of the schema even when the schemas are semantically
equivalent.
By changing Schema from map[string]any to json.RawMessage, the
user-provided JSON schema is sent verbatim to the API without any key
reordering, preserving the intended field ordering and ensuring
consistent model behavior.
Reference: