





















reasoning parameter causes tool_call chain error in DeepAgents subagent| Package | Version |
|---|---|
| deepagents | 0.4.11 |
| langchain | 1.2.12 |
| langchain-openai | 1.1.11 |
| langgraph | 1.1.3 |
| Python | 3.12+ |
| LLM Provider | Alibaba DashScope (OpenAI-compatible) |
| Model | qwen3.5-122b-a10b |
When using ChatOpenAI with the reasoning parameter and create_deep_agent with subagents, the main agent works correctly (delegates task to subagent), but the subagent crashes during its internal tool call chain.
The reasoning parameter triggers the Responses API code path (_construct_lc_result_from_responses_api), which formats messages differently. When the subagent inherits this model and performs multi-step tool calling, the tool_call → tool_response message pairing breaks, and the LLM API rejects the request.
from langchain_openai import ChatOpenAI
from deepagents import create_deep_agent
# Tool functions (simplified)
async def query_kyc(company_name: str) -> str:
"""查询企业基本工商信息"""
return "企业名称:xxx有限公司\n法人:张三\n..."
async def query_field(company_name: str, query: str) -> str:
"""根据用户意图查询企业详细字段"""
return "纳税信用等级:A"
model = ChatOpenAI(
model="qwen3.5-122b-a10b",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="sk-xxx",
timeout=60,
reasoning={ # ← This causes the issue
"effort": "medium",
"summary": "auto"
}
)
subagent = {
"name": "Business_agent",
"description": "Query company information.",
"system_prompt": "You are a business info assistant. Use tools to query data.",
"tools": [query_kyc, query_field],
}
agent = create_deep_agent(
model=model,
system_prompt="You are an enterprise info expert.",
subagents=[subagent]
)
import asyncio
async def main():
async for chunk in agent.astream({"messages": [
{"role": "user", "content": "查询xxx有限公司的基本信息,纳税等级,开户行,画像和标签"}
]}):
print(chunk)
asyncio.run(main())
The main agent successfully delegates to the subagent via the task tool. Then the subagent crashes when it tries to call its own tools:
ValueError: ResponseError(code='server_error', message='<400> InternalError.Algo.InvalidParameter:
An assistant message with "tool_calls" must be followed by tool messages responding to each "tool_call_id".
The following tool_call_ids did not have response messages: message[4].role')
Traceback (most recent call last):
File "core/main_agent.py", line 63, in <module>
asyncio.run(t1.quick_start(messages))
File "core/main_agent.py", line 45, in quick_start
async for chunk in agent.astream({"messages": messages}):
File "langgraph/pregel/main.py", line 3111, in astream
async for _ in runner.atick(
File "langgraph/pregel/_runner.py", line 304, in atick
await arun_with_retry(
File "langgraph/pregel/_retry.py", line 211, in arun_with_retry
return await task.proc.ainvoke(task.input, config)
# --- Main agent's tools node spawns the subagent ---
File "langgraph/prebuilt/tool_node.py", line 846, in _afunc
outputs = await asyncio.gather(*coros)
File "langgraph/prebuilt/tool_node.py", line 1191, in _arun_one
return await self._awrap_tool_call(tool_request, execute)
File "deepagents/middleware/subagents.py", line 463, in atask
result = await subagent.ainvoke(subagent_state)
# --- Inside subagent: model node tries to call LLM ---
File "langgraph/pregel/main.py", line 3462, in ainvoke
async for chunk in self.astream(
File "langgraph/pregel/main.py", line 3111, in astream
async for _ in runner.atick(
File "langchain/agents/factory.py", line 1352, in amodel_node
result = await awrap_model_call_handler(request, _execute_model_async)
# --- Through middleware chain ---
File "langchain/agents/middleware/todo.py", line 253, in awrap_model_call
File "deepagents/middleware/filesystem.py", line 1126, in awrap_model_call
File "deepagents/middleware/summarization.py", line 1024, in awrap_model_call
# --- LLM call crashes here ---
File "langchain/agents/factory.py", line 1321, in _execute_model_async
output = await model_.ainvoke(messages)
File "langchain_openai/chat_models/base.py", line 1744, in _agenerate
return _construct_lc_result_from_responses_api(
File "langchain_openai/chat_models/base.py", line 4423, in _construct_lc_result_from_responses_api
raise ValueError(response.error)
ValueError: ResponseError(code='server_error', message='<400> InternalError.Algo.InvalidParameter:
An assistant message with "tool_calls" must be followed by tool messages responding to each "tool_call_id".
The following tool_call_ids did not have response messages: message[4].role')
During task with name 'model' and id '0f42eef9-ac9e-b585-321b-e9a3f65283f8'
During task with name 'tools' and id 'cb8ef8e4-8e89-0d95-ac39-68555be375f7'
The reasoning parameter should work with subagents that perform multi-step tool calling, or the subagent should be able to override the model to avoid inheriting the Responses API code path.
Use separate model instances — subagent config supports a model field to override the main agent’s model:
model_with_reasoning = ChatOpenAI(..., reasoning={"effort": "medium", "summary": "auto"})
model_basic = ChatOpenAI(...) # no reasoning
agent = create_deep_agent(
model=model_with_reasoning, # main agent: reasoning ON
subagents=[{
"name": "Business_agent",
"model": model_basic, # subagent: reasoning OFF ← fixes the issue
"tools": [query_kyc, query_field],
...
}]
)
The issue is primarily in DashScope’s Responses API compatibility layer, not in langchain-openai or DeepAgents.
The reasoning parameter causes langchain-openai to switch from the Chat Completions API path to the Responses API path (see _use_responses_api at base.py:1512: if self.reasoning is not None: return True).
langchain-openai constructs the request using Responses API format — messages become a flat input array with typed blocks (reasoning, function_call, function_call_output, etc.) via _construct_responses_api_input at base.py:4225.
DashScope’s OpenAI-compatible endpoint receives this Responses API format and internally converts it back to Chat Completions format for processing. Evidence: the error message uses Chat Completions terminology (“assistant message with tool_calls”) rather than Responses API terminology (“function_call” / “function_call_output”).
During this internal conversion, when multiple tool-calling rounds are flattened into the input array (with interleaved reasoning, function_call, and function_call_output blocks), DashScope’s conversion logic loses the tool_call → tool_response pairing, causing the validation to fail at message[4].
The main agent is unaffected because it only makes a single tool call (the task tool), so there’s no multi-round accumulation. The subagent crashes because it performs multi-step tool calling internally.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。