[Bug] JSONAdapter structured outputs: pydantic Field constraints (ge, le, multiple_of, pattern) are silently dropped in the signature-to-model derivation — is this intentional?
What happens
Field-level constraint kwargs on OutputField never reach any
structured-output backend — the derived response-format model keeps the
type but drops the constraint metadata:
import dspy
from dspy.adapters.json_adapter import _get_structured_outputs_response_format
class Score(dspy.Signature):
text: str = dspy.InputField()
score: float = dspy.OutputField(ge=0.0, le=1.0, multiple_of=0.25)
print(_get_structured_outputs_response_format(Score, True).model_json_schema())
# {'properties': {'score': {'title': 'Score', 'type': 'number'}}, ...}
# ge / le / multipleOf: goneConstraints expressed in the annotation itself survive (Literal[...],
nested models, set[str] -> uniqueItems); constraints passed as Field
kwargs do not. Users writing OutputField(ge=0, le=1) reasonably believe
the bound is part of the contract; outputs violating it parse fine and
flow downstream. dspy 3.2.1, Python 3.12.
The question
Is the stripping intentional? A plausible reason would be provider
compatibility: OpenAI's strict structured outputs REJECT schemas
containing unsupported keywords like multipleOf, so passing constraints
through naively would break those calls. But today's behavior drops them
for every backend equally — including local/vLLM grammar backends that
could enforce some of them, and validation layers that could at least
check them (related territory: #7925 on partial output-field validation).
If intentional, a suggestion
Strip per-provider rather than globally — or pass constraints through and let each backend declare what it can't honor. #9686 shows the same schema-hygiene problem in the opposite direction (vendor extensions leaking TO strict providers), so a single provider-aware schema-sanitization point might solve both.
Happy to work on a PR for whichever direction maintainers prefer. We hit this while integrating a grammar backend and wrote up the full analysis with workarounds here: https://www.evolutionid.com/en/technical-insights/your-dspy-field-constraints-never-reach-the-model.
Source: stanfordnlp/dspy