Repository navigation
fix: keep non-ASCII in prompt schemas - #1131
Merged
andreatnvidia merged 2 commits intoNov 9, 2026
Merged
Conversation
StructuredResponseRecipe.schema and PydanticResponseRecipe.schema serialize the JSON schema with json.dumps' default ensure_ascii=True. The schema is embedded in the user prompt, so non-ASCII descriptions, enum values and LLM-judge rubrics (Thai, CJK, accented Latin, ...) reach the model as \uXXXX escapes instead of readable text. Serialize with ensure_ascii=False, as serialize_output in the same file already does. ASCII-only schemas are unchanged. generate_response_example gets the same change for consistency. Tests cover Thai descriptions and enum values and check that an ASCII-only schema serializes exactly as before. Fixes NVIDIA-NeMo#1130 Signed-off-by: spped2000 <spped2000@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
All contributors have signed the DCO ✍️ ✅ |
Contributor
[Medium impact] The PR appears safe to merge. SummaryThe PR keeps non-ASCII text readable in schemas sent to the model.
Reviews (2) · Last reviewed commit: "Merge branch 'main' into fix/non-ascii-p..." · Reviewed by Greptile |
Contributor
Author
|
I have read the DCO document and I hereby sign the DCO. |
3 tasks done
andreatnvidia
approved these changes
Nov 9, 2026
andreatnvidia
left a comment
Contributor
There was a problem hiding this comment.
Thanks for putting this together! This covers the changes and tests we discussed in #1130. Looks good to me.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📋 Summary
StructuredResponseRecipeandPydanticResponseRecipeserialize the response schema withjson.dumps, which defaults toensure_ascii=True. Any non-ASCII text in a structured-output or LLM-judge schema (descriptions, enum values, score rubrics) is therefore sent to the model as\uXXXXescapes inside<response_schema>. This PR serializes the schema withensure_ascii=False, asserialize_outputin the same file already does. ASCII-only schemas are unchanged.🔗 Related Issue
Fixes #1130
🔄 Changes
StructuredResponseRecipe.schemaandPydanticResponseRecipe.schema:json.dumps(..., ensure_ascii=False). These are the strings embedded in<response_schema>intask_instructions.StructuredResponseRecipe.generate_response_example: same change. It has no production callers today, so this is for consistency withserialize_output, not a behavior fix.test_response_recipes.py: one parametrized test (a Thai pydantic model and the same schema as a dict) checks thattask_instructionscontains the Thai text, has no\u0eescapes, and thatschemastill round-trips throughjson.loads. One more test covers the example round-trip. A third (AsciiFoo, pydantic and dict) checks that an ASCII-only schema serializes exactly asjson.dumpsdid before, as requested in Structured-output prompt schemas escape non-ASCII text as \uXXXX #1130.Before (main), LLM-judge rubric
Score(description="ประเมินความถูกต้อง", options={1: "ผิดทั้งหมด", 3: "ถูกต้องครบถ้วน"})rendered throughcreate_response_recipe():After:
For a three-option Thai rubric, a local vLLM server (Qwen3.6-35B-A3B tokenizer) counted 623 prompt tokens before and 315 after. In one request each way, both replies were valid fenced JSON and parsed with the recipe. That single sample makes no claim about judge quality; the change is to what the model reads.
🧪 Testing
CPU only (
CUDA_VISIBLE_DEVICES=), dev environment fromuv sync --all-packages --group dev(Python 3.14.6):make testpasses (ran the three package test suites above directly with pytest)Scope and limitations:
serialize_outputalready handle non-ASCII text.engine/mcp/io.py(L502, L531) also uses the defaultensure_ascii=Truefor MCP tool results. It is mentioned in the issue as a possible follow-up and left out of this PR.Why this is not a duplicate: I found no issue or PR about schema escaping. #800 is the only other
ensure_asciichange (JSONL scheduler events). #971/#972 changed bare-JSON parsing in the same recipes. #1125 is an open feature request for an opt-in native schema-enforcement mode, a separate feature with no PR yet. No open PR touchesresponse_recipes.py.I prepared this with help from Claude (Anthropic) and reviewed and tested it myself.
✅ Checklist
triaged🤖 Generated with Claude Code