構造化出力
response_format は受理され、転送されません(openai-ignorable-keys)。形の決まった出力が要るときは、ネイティブなツール呼び出しを「形」として使うのが確実です: function の parameters に JSON Schema を書き、tool_choice でその function を強制すると、arguments が schema 通りの JSON で返ります。
{"model": "qwen3.8-flash-next-whitehacker", "max_tokens": 2048,
"tools": [{"type": "function", "function": {"name": "report_finding",
"parameters": {"type": "object", "required": ["severity", "title", "evidence"],
"properties": {"severity": {"enum": ["low", "medium", "high", "critical"]},
"title": {"type": "string"}, "evidence": {"type": "string"}}}}}],
"tool_choice": {"type": "function", "function": {"name": "report_finding"}},
"messages": [{"role": "user", "content": "Review this handler: ..."}]}
→ choices[0].message.tool_calls[0].function.arguments
"{\"severity\":\"high\",\"title\":\"Auth bypass via ...\",\"evidence\":\"...\"}"
プロンプトで頼む場合
messages: [{"role":"user","content":"Return ONLY a JSON object {\"finding\": string, \"severity\": \"low|medium|high\"}. No prose."}]
# then parse; validate on your side; retry on a parse failure
arguments は文字列(JSON 文字列)で届きます。呼び出し側で parse と検証をしてください。モデルが schema を外すことはあり得るので、検証失敗時は再送を。