Regarding Qwen 3.6 35B-A3B reasoning/thinking mode

#66
by bardenthenry - opened

Subject:
I was reading the Qwen documentation and noticed that you can use the thinking_budget parameter to limit the number of thinking tokens. However, in practice, setting thinking_budget doesn't seem to make any difference at all.

Could any expert here point out how I can properly limit the token usage of Qwen 3.5 35B-A2B in thinking mode?

Below is the code I wrote:

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

def verify_thinking_budget(base_url, api_key, model, prompt, budget=1024):
    # ① 有 budget 限制
    llm_limited = ChatOpenAI(
        model=model,
        base_url=base_url,
        api_key=api_key,
        extra_body={
            "skip_special_tokens": False,
            "enable_thinking": True,
            "thinking_budget": budget
        }
    )

    # ② 無 budget 限制
    llm_full = ChatOpenAI(
        model=model,
        base_url=base_url,
        api_key=api_key,
        extra_body={
            "skip_special_tokens": False,
            "enable_thinking": True
        }
    )

    msg = [HumanMessage(content=prompt)]
    resp_limited = llm_limited.invoke(msg)
    resp_full = llm_full.invoke(msg)

    # ✅ 正確欄位是 "reasoning",不是 "reasoning_content"
    reasoning_limited = resp_limited.additional_kwargs.get("reasoning", "")
    reasoning_full    = resp_full.additional_kwargs.get("reasoning", "")

    usage_limited = resp_limited.response_metadata.get("token_usage", {})
    usage_full    = resp_full.response_metadata.get("token_usage", {})

    print("=== 驗證結果 ===")
    print(f"[有 budget={budget}]  reasoning 字元數:{len(reasoning_limited)}")
    print(f"[無 budget]           reasoning 字元數:{len(reasoning_full)}")
    print(f"[有 budget]  token_usage:{usage_limited}")
    print(f"[無 budget]  token_usage:{usage_full}")

    print("\n=== 判斷 ===")
    if reasoning_limited:
        print("✅ Thinking mode 已開啟(reasoning 欄位存在)")
    else:
        print("❌ Thinking mode 未開啟")

    if len(reasoning_limited) < len(reasoning_full):
        print(f"✅ thinking_budget 生效:{len(reasoning_full)}{len(reasoning_limited)} 字元(減少 {len(reasoning_full)-len(reasoning_limited)} 字元)")
    elif len(reasoning_limited) == len(reasoning_full):
        print("⚠️  兩者相同,budget 可能未被採用,或問題太簡單不需要完整推論")
    else:
        print("⚠️  有 budget 的反而更長,請檢查參數是否正確傳遞")

    print(f"\n[有 budget] reasoning 預覽:\n{reasoning_limited[:300]}...")

hard_reasoning_prompt = """
請詳細推導並證明「為什麼根號 2 (√2) 是無理數」。
要求:請一步步詳細列出所有邏輯反證法的步驟,包含假設、代數推導、矛盾點的產生,
請儘可能寫得極其詳細,思維步驟越多越好,預計思考字數要求在 1000 字以上。
"""

verify_thinking_budget(AGENT_LLM_URL, AGENT_LLM_API_KEY, AGENT_LLM_MODEL,  hard_reasoning_prompt, 1024)

And hers is reason

[有 budget=1024]  reasoning 字元數:0
[無 budget]           reasoning 字元數:0
[有 budget]  token_usage:{'completion_tokens': 4826, 'prompt_tokens': 87, 'total_tokens': 4913, 'completion_tokens_details': None, 'prompt_tokens_details': None}
[無 budget]  token_usage:{'completion_tokens': 4669, 'prompt_tokens': 87, 'total_tokens': 4756, 'completion_tokens_details': None, 'prompt_tokens_details': None}

The result is that the version with thinking_budget added actually used more tokens than the one without it. Why?

Because it sees that budget as a goal. It will do what it can to achieve that number. Same as max tokens.

Sign up or log in to comment