进阶 api-docs.deepseek.com 2026-10-13 22:45:35 · 31 阅读

第17章 DeepSeek 思考模式详解

思考模式 DeepSeek 模型支持思考模式:在输出最终答案之前,模型会先执行思维链推理,以提升最终回复的准确性。 思考模式切换与思考强度控制​ 控制参数(OpenAI 格式)控制参数(Anthropic 格式)控制参数(Responses API 格式)思考模式切换(1){"thinking": {"type": "enabled/disabled"}}{"reasoning": {"effort": "none/low/high/max"}}
(none 会禁用思考模式)思考强度控制(2){"reasoning_effort": "low/high/max"}{"output_config": {"effort": "low/high/max"}} (1) 默认启用思考模式,默认强度为 high
(2) 用户设置的强度与实际推理强度的映射关系如下:请求强度实际映射强度minimallowlowlowmediumhighhighhighxhighhighmaxmaxultramax 当使用 OpenAI SDK 进行 Chat Completion 并设置 thinking 参数时,需通过 extra_body 传入: response = client.chat.completions.create(
model="deepseek-flash",
# ...
reasoning_effort="high",
extra_body={"thinking": {"type": "enabled"}}
)

输入与输出参数

思考模式不支持 temperature、presence_penalty 和 frequency_penalty 参数。请注意,为兼容现有软件,设置这些参数不会报错,但也不会生效。

top_p 仅在思考模式下生效,有效范围为 0.95–1.0:低于 0.95 的值会按 0.95 处理。在非思考模式下,top_p 固定为 1.0,你设置的值会被忽略。

在思考模式下,思维链内容通过 reasoning_content 参数返回,与 content 处于同一层级。在后续请求中,reasoning_content 是否需要传回、是否会被拼接到上下文中,取决于请求是否携带 tools 参数:

  • 如果请求携带 tools 参数:需要将之前所有轮次的 reasoning_content 传回 API,它会被拼接到上下文中。详见 Tool Calls。
  • 如果请求不携带 tools 参数:无需传回 reasoning_content;即使传给了 API,也会被忽略,不会拼接到上下文中。详见 Multi-turn Conversation。

多轮对话

在对话的每一轮中,模型会输出 CoT(reasoning_content)和最终答案(content)。如果请求不携带 tools 参数,则上一轮的 CoT 内容不会拼接到下一轮的上下文中,如下图所示:

示例代码

以下代码以 Python 为例,演示了如何获取 CoT 和最终答案,以及如何在多轮对话中拼接上下文。

NoStreamingStreamingfrom openai import OpenAI
client = OpenAI(api_key="", base_url="https://api.deepseek.com")

# Turn 1
messages = [{"role": "user", "content": "9.11 and 9.8, which is greater?"}]
response = client.chat.completions.create(
model="deepseek-flash",
messages=messages,
reasoning_effort="high"
extra_body={"thinking": {"type": "enabled"}},
)

reasoning_content = response.choices[0].message.reasoning_content
content = response.choices[0].message.content

# Turn 2
# The reasoning_content will be ignored by the API
messages.append(response.choices[0].message)
messages.append({'role': 'user', 'content': "How many Rs are there in the word 'strawberry'?"})

response = client.chat.completions.create(
model="deepseek-flash",
messages=messages,
reasoning_effort="high"
extra_body={"thinking": {"type": "enabled"}},
)
# ...
from openai import OpenAI
client = OpenAI(api_key="", base_url="https://api.deepseek.com")

# 第 1 轮
messages = [{"role": "user", "content": "9.11 和 9.8,哪个更大?"}]
response = client.chat.completions.create(
model="deepseek-flash",
messages=messages,
stream=True,
reasoning_effort="high"
extra_body={"thinking": {"type": "enabled"}},
)

reasoning_content = ""
content = ""

for chunk in response:
if chunk.choices[0].delta.reasoning_content:
reasoning_content += chunk.choices[0].delta.reasoning_content
else:
content += chunk.choices[0].delta.content

# 第 2 轮
# API 会忽略 reasoning_content 参数
messages.append({"role": "assistant", "reasoning_content": reasoning_content, "content": content})
messages.append({'role': 'user', 'content': "单词 'strawberry' 中有多少个字母 R?"})
response = client.chat.completions.create(
model="deepseek-flash",
messages=messages,
stream=True,
reasoning_effort="high"
extra_body={"thinking": {"type": "enabled"}},
)
# ...

工具调用

DeepSeek 模型的思考模式支持工具调用。在输出最终答案前,模型可以进行多轮推理和工具调用,以提升回复质量。调用模式如下所示:

请注意:如果请求中携带了 tools 参数,则后续所有请求都必须完整回传 reasoning_content——即使在该轮中模型并未执行工具调用。如果代码未正确回传 reasoning_content,API 将返回 400 错误。请参照下方的示例代码获取正确做法。

示例代码

以下是一个思考模式下工具调用的简单示例代码:

import os
import json
from openai import OpenAI
from datetime import datetime

# 工具定义
tools = [
{
"type": "function",
"function": {
"name": "get_date",
"description": "获取当前日期",
"parameters": { "type": "object", "properties": {} },
}
},
{
"type": "function",

$
"function": {
"name": "get_weather",
"description": "获取指定地点的天气,用户需要提供地点和日期。",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "城市名称" },
"date": { "type": "string", "description": "日期,格式为 YYYY-mm-dd" },
},
"required": ["location", "date"]
},
}
},
]

# 模拟工具调用
def get_date_mock():
return datetime.now().strftime("%Y-%m-%d")

def get_weather_mock(location, date):
return "多云 7~13°C"

TOOL_CALL_MAP = {
"get_date": get_date_mock,
"get_weather": get_weather_mock
}

def run_turn(turn, messages):
sub_turn = 1
while True:
response = client.chat.completions.create(
model='deepseek-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
messages.append(response.choices[0].message)
reasoning_content = response.choices[0].message.reasoning_content
content = response.choices[0].message.content
tool_calls = response.choices[0].message.tool_calls
print(f"Turn {turn}.{sub_turn}\n{reasoning_content=}\n{content=}\n{tool_calls=}")
# 若无工具调用,则模型应得出最终答案,需终止循环
if tool_calls is None:
break
for tool in tool_calls:
tool_function = TOOL_CALL_MAP[tool.function.name]
tool_result = tool_function(json.loads(tool.function.arguments))
print(f"tool result for {tool.function.name}: {tool_result}\n")
messages.append({
"role": "tool",
"tool_call_id": tool.id,
"content": tool_result,
})
sub_turn += 1
print()

client = OpenAI(
api_key=os.environ.get('DEEPSEEK_API_KEY'),
base_url=os.environ.get('DEEPSEEK_BASE_URL'),
)

# 用户开始提问
turn = 1
messages = [{
"role": "user",
"content": "杭州明天天气怎么样"
}]$
run_turn(turn, messages)

# 用户开始一个新问题
turn = 2
messages.append({
"role": "user",
"content": "How's the weather in Guangzhou Tomorrow"
})
run_turn(turn, messages)
在 Turn 1 的每次子请求中,该轮生成的 reasoning_content 都会被发送给 API,使模型能够继续之前的推理。response.choices[0].message 包含了 assistant 消息所需的全部字段,包括 content、reasoning_content 和 tool_calls。为简化代码,你可以直接用下面这行代码把该消息追加到 messages 列表末尾: messages.append(response.choices[0].message)
这行代码等价于: messages.append({
'role': 'assistant',
'content': response.choices[0].message.content,
'reasoning_content': response.choices[0].message.reasoning_content,
'tool_calls': response.choices[0].message.tool_calls,
})
另外,在 Turn 2 的请求中,我们仍然把 Turn 1 生成的 reasoning_content 传给了 API。 这段代码的运行输出示例如下: Turn 1.1
reasoning_content="The user is asking about the weather in Hangzhou tomorrow. I need to get tomorrow's date first, then call the weather function."
content="Let me check tomorrow's weather in Hangzhou for you. First, let me get tomorrow's date."
tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_kw66qNnNto11bSfJVIdlV5Oo', function=Function(arguments='{}', name='get_date'), type='function', index=0)]
tool result for get_date: 2026-04-19

Turn 1.2
reasoning_content="Today is 2026-04-19, so tomorrow is 2026-04-20. Now I'll call the weather function for Hangzhou."
content=''
tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_H2SCW6136vWJGq9SQlBuhVt4', function=Function(arguments='{"location": "Hangzhou", "date": "2026-04-20"}', name='get_weather'), type='function', index=0)]
tool result for get_weather: Cloudy 7~13°C

Turn 1.3
reasoning_content='The weather result is in. Let me share this with the user.'
content="Here's the weather forecast for
Hangzhou tomorrow (April 20, 2026):\n\n- 🌤 Condition: Cloudy \n- 🌡 Temperature: 7°C ~ 13°C (45°F ~ 55°F)\n\nIt'll be on the cooler side, so you might want to bring a light jacket if you're heading out! Let me know if you need anything else."
tool_calls=None

Turn 2.1
reasoning_content='用户询问广州明天的天气。今天是 2026-04-19,所以明天是 2026-04-20。我可以直接调用天气函数。'
content=''
tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_8URkLt5NjmNkVKhDmMcNq9Mo', function=Function(arguments='{"location": "Guangzhou", "date": "2026-04-20"}', name='get_weather'), type='function', index=0)]
get_weather 工具返回结果:多云 7~13°C

第 2.2 轮
reasoning_content='广州的天气预报结果与杭州相同。我来把这个信息分享给用户。'
content="这是
广州明天(2026年4月20日)的天气预报:\n\n- 🌤 天气状况: 多云 \n- 🌡 气温: 7°C ~ 13°C (45°F ~ 55°F)\n\n天气较凉且多云,出门建议带件轻薄夹克。如果你想知道其他内容,随时告诉我!"
tool_calls=None

评论 (0)