Skip to content

fix(dashscope): forward structured response format#1865

Open
guslegend0510 wants to merge 4 commits into
agentscope-ai:mainfrom
guslegend0510:fix/issue-1852-dashscope-structured-output
Open

fix(dashscope): forward structured response format#1865
guslegend0510 wants to merge 4 commits into
agentscope-ai:mainfrom
guslegend0510:fix/issue-1852-dashscope-structured-output

Conversation

@guslegend0510

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.0.0-SNAPSHOT

Description

This PR fixes DashScope native structured output by forwarding GenerateOptions.responseFormat into DashScopeParameters.responseFormat during request building.

Before this change, the DashScope request path dropped response_format, so structured-output calls could not be parsed correctly and Msg.hasStructuredData() stayed false.

Changes made:

  • forward responseFormat in DashScope option mapping
  • add regression coverage for explicit and default response format handling

How to test:

  • mvn -pl agentscope-core -Dtest=DashScopeToolsHelperComprehensiveTest test

Checklist

@guslegend0510 guslegend0510 requested a review from a team June 22, 2026 12:10
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@AgentScopeJavaBot AgentScopeJavaBot added bug Something isn't working area/core/model Model providers and formatters labels Jun 23, 2026

@AgentScopeJavaBot AgentScopeJavaBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 AI Review

Precise fix for DashScope request path dropping response_format. The forwarding logic in DashScopeToolsHelper.applyOptions() follows the established null-guard pattern and is symmetric across streaming/non-streaming paths. Tests cover the regression. Suggestion: add a json_object type test case alongside the existing json_schema coverage.

@guslegend0510

Copy link
Copy Markdown
Contributor Author

@chickenlj 麻烦你帮我审核一下,谢谢您

@zhangliyuangit

Copy link
Copy Markdown

I independently reproduced this on release/2.0.0-RC3 and can confirm the open question in the issue ("confirm whether the DashScope native endpoint supports strict json_schema") — it does not.

Root cause confirmed: DashScopeToolsHelper.applyOptions() never copies GenerateOptions.getResponseFormat() into DashScopeParameters, so the schema is dropped, qwen-max returns prose, wrapNativeStructuredResult fails to parse it, and getStructuredData() throws No structured output ... Key '_structured_output' not found.

But forwarding the format alone (the approach in #1865) does not fix qwen-max — it converts the silent failure into a hard 400. After wiring responseFormat through, the native endpoint (/api/v1/services/aigc/text-generation/generation) replies:

<400> InternalError.Algo.InvalidParameter: 'messages' must contain the word 'json'
in some form, to use 'response_format' of type 'json_object'.

i.e. the native DashScope endpoint only supports json_object, not json_schema. The OpenAI-compatible endpoint (/compatible-mode/v1) returns the same 400 for qwen-max — which lines up with the fact that the compatible-mode E2E providers in this repo use qwen-plus/qwen3-*, never qwen-max.

The only path that works for native DashScope (incl. qwen-max) is the fallback generate_response tool (Option 2 in this issue: supportsNativeStructuredOutput()false). Verified: with that flag flipped, all four examples in the official StructuredOutputExample pass and hasStructuredData() returns true.

Suggested direction, relating the open PRs:

Net: Option 2 for DashScope + #1743 as the cross-provider safety net looks like the complete fix.

Minimal reproduction
ReActAgent agent = ReActAgent.builder()
    .name("AnalysisAgent")
    .model(DashScopeChatModel.builder()
        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
        .modelName("qwen-max").stream(true).enableThinking(false)
        .formatter(new DashScopeChatFormatter())
        .build())
    .toolkit(new Toolkit())
    .build();

Msg msg = agent.call(new UserMessage("Extract product requirements: Apple laptop, 16GB RAM, $2000, lightweight"),
                     ProductRequirements.class).block();
System.out.println(msg.hasStructuredData()); // false on current main; true once Option 2 applied

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core/model Model providers and formatters bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:DashScope 结构化输出失效:native 路径从不下发 response_format,导致 hasStructuredData() 恒为 false

4 participants