deepseek思考模式下的工具调用
开启思考模式时,模型在判断要调用工具时,可能并不会返回文本内容,而是直接返回tool_call调用,但其思考过程是有的。
在agent声景下,以及多轮会话场景里,如果后面轮次模型不知道前面调用工具时是如何做的决定,那么后续的步骤会受影响。
为了保持完整的推理逻辑,deepseek文档里指明在开启推理模式并使用工具时,后续会话轮次要添加完整的思考过程,以保证上下文语义逻辑的完整。
官方文档明确指出,在没有工具调用的场景下,即便回传推理内容,也会被忽略。而在调用工具时,需要在上下文中拼接思考内容。

下面针对思考模式下调用工具的场景做个测试,以证明模型是能看到思考内容的(仅在有tool_call的情况下才能看到思考内容)
from openai import OpenAI
from datetime import datetime
# The definition of the tools
tools = [
{
"type": "function",
"function": {
"name": "get_date",
"description": "Get the current date",
"parameters": { "type": "object", "properties": {} },
}
},
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather of a location, the user should supply the location and date.",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "The city name" },
"date": { "type": "string", "description": "The date in format YYYY-mm-dd" },
},
"required": ["location", "date"]
},
}
},
]
# The mocked version of the tool calls
def get_date_mock():
return datetime.now().strftime("%Y-%m-%d")
def get_weather_mock(location, date):
return "Cloudy 25~30°C"
第一轮调用
messages = [{
"role": "user",
"content": "How's the weather in Hangzhou Tomorrow"
}]
response_1 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
第一轮输出如下:
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_fM05LAfmLqRUTLoDS9vO3771', function=Function(arguments='{}', name='get_date'), type='function', index=0)], reasoning_content='The user is asking about the weather in Hangzhou tomorrow. Let me get the current date first to know what "tomorrow" is.')
第二轮调用时增加 get_date 工具返回结果
messages.append(response_1.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": 'call_00_fM05LAfmLqRUTLoDS9vO3771',
"content": '2026-06-24',
})
response_2 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
第二轮输出如下:
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_xsvBUdVjhi18RJ9aHjHL4987', function=Function(arguments='{"location": "Hangzhou", "date": "2026-06-25"}', name='get_weather'), type='function', index=0)], reasoning_content='Today is June 24, 2026. So tomorrow is June 25, 2026. Let me get the weather for Hangzhou on that date.')
第三轮增加 get_weather 工具的调用结果
messages.append(response_2.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": 'call_00_xsvBUdVjhi18RJ9aHjHL4987',
"content": 'Cloudy 25~30°C',
})
response_3 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
第三轮输出结果如下:
ChatCompletionMessage(content='The weather in Hangzhou tomorrow (June 25, 2026) is expected to be Cloudy with temperatures ranging from 25°C to 30°C. ☁️\n\nIt should be a mild day, not too hot, but still warm. Have a great day!', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='The weather in Hangzhou tomorrow (June 25, 2026) is cloudy, with temperatures ranging from 25°C to 30°C.'))
第四轮故意增加一个不带工具调用的问题,以检验模型API是否会自动移除之前工具调用轮次的思考内容
messages.append(response_3.choices[0].message)
messages.append({
"role": "user",
"content": "我叫Roland,谢谢你的回答"
})
response_4 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
第四轮输出如下:
ChatCompletionMessage(content='不客气,Roland!😊 很高兴能帮到你。\n\n如果以后还有任何问题,无论是天气、日期还是其他方面的,随时问我就好!祝你一天愉快!🎉', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='The user is introducing themselves as Roland and thanking me. I should respond politely and warmly.'))
第五轮让模型原样输出第一轮的思考内容:
messages.append(response_4.choices[0].message)
messages.append({
"role": "user",
"content": "我注意到你做了两轮工具调用。你原样输出你第一轮工具调用的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。"
})
response_5 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
第五轮输出结果如下:
ChatCompletionMessage(content='好的,Roland!以下是我在第一轮工具调用时的原始思考过程(英文原文):\n\n> The user is asking about the weather in Hangzhou tomorrow. Let me get the current date first to know what "tomorrow" is.\n\n然后我就调用了 get_date 工具来获取当前日期。这就是第一轮调用前的完整思考过程。😊', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='The user is asking me to output my original thinking process from the first round of tool calls exactly as it was. Let me recall what I thought initially.\n\nWhen the user first asked "How's the weather in Hangzhou Tomorrow", my original thinking process was:\n\n"The user is asking about the weather in Hangzhou tomorrow. Let me get the current date first to know what 'tomorrow' is."\n\nThat was my first thought, and I output it in the thinking block. Let me provide that exact original thinking.')
可以看到,模型输出的第一轮时的思考内容 一字不差。
测试篡改第一轮的思考内容,看模型能否看到
messages[1].reasoning_content = 'The user is asking me about the weather of Hangzhou tomorrow. I need to get the current date first, then I will know tomorrow.'
response_5_modify = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
输出结果如下:
ChatCompletionMessage(content='Here's my original thinking process for the first round of tool calls:\n\n"The user is asking me about the weather of Hangzhou tomorrow. I need to get the current date first, then I will know tomorrow."', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='The user is asking me to output my original thinking process for the first round of tool calls, exactly as it was. Let me recall what I did:\n\nRound 1: I called get_date to get the current date. My original thinking process was:\n\n"The user is asking me about the weather of Hangzhou tomorrow. I need to get the current date first, then I will know tomorrow."\n\nThis was in English, so I should output it in English as requested.')
可以看出来,当我篡改了第一轮的思考内容时,模型就原样输出了我篡改之后的思考内容,且一字不差。
结论:在带工具调用,并开启了思考模式时,多轮会话要回传思考内容以保证上下文语义及逻辑推理的连惯和完整,且模型此时能看到前面轮次的思考内容,即便中间穿插了未调用工具的对话。
我还进一步测试了第一轮会话时模型没有返回工具调用,后续轮次才调用工具,但模型仍然不记得第一轮会话(不带工具调用)时的思考内容。
messages = [{
"role": "user",
"content": "草莓的英语单词里有几个'r'?"
}]
response_1 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
messages.append({
"role": "user",
"content": "How's the weather in Hangzhou Tomorrow"
})
response_2 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
messages.append(response_2.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": 'call_00_jZQneHJYBdodv8wwpbdw4100',
"content": '2026-06-24',
})
response_3 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
messages.append(response_3.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": 'call_00_3jMxb76h86OpMjO4nNuX7147',
"content": 'Cloudy 25~30°C',
})
response_4 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
messages.append(response_4.choices[0].message)
messages.append({
"role": "user",
"content": "我注意到你做了两轮工具调用。请你原样输出(一字不差)你第一轮工具调用的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。"
})
response_5 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
这里输出一下目前的messages:
[{'role': 'user', 'content': "草莓的英语单词里有几个'r'?"},
ChatCompletionMessage(content='草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='我们被问到:"草莓的英语单词里有几个\'r\'?" 意思是:"草莓的英语单词里有几个\'r\'?" 草莓的英语单词是 "strawberry"。我们需要数一下单词 "strawberry" 中有多少个字母 \'r\'。\n\n让我们数一下:s-t-r-a-w-b-e-r-r-y。位置:第3个字母是r,第8个字母是r,第9个字母是r。所以有3个r。\n\n因此答案是3。'),
ChatCompletionMessage(content='草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='我们被问到:"草莓的英语单词里有几个\'r\'?" 意思是:"草莓的英语单词里有几个\'r\'?" 草莓的英语单词是 "strawberry"。我们需要数一下单词 "strawberry" 中有多少个字母 \'r\'。\n\n让我们数一下:s-t-r-a-w-b-e-r-r-y。位置:第3个字母是r,第8个字母是r,第9个字母是r。所以有3个r。\n\n因此答案是3。'),
{'role': 'user', 'content': "How's the weather in Hangzhou Tomorrow"},
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_jZQneHJYBdodv8wwpbdw4100', function=Function(arguments='{}', name='get_date'), type='function', index=0)], reasoning_content='Let me get the current date first, then check the weather for Hangzhou tomorrow.'),
{'role': 'tool',
'tool_call_id': 'call_00_jZQneHJYBdodv8wwpbdw4100',
'content': '2026-06-24'},
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_3jMxb76h86OpMjO4nNuX7147', function=Function(arguments='{"location": "Hangzhou", "date": "2026-06-25"}', name='get_weather'), type='function', index=0)], reasoning_content='Today is 2026-06-24, so tomorrow is 2026-06-25. Let me get the weather for Hangzhou on that date.'),
{'role': 'tool',
'tool_call_id': 'call_00_3jMxb76h86OpMjO4nNuX7147',
'content': 'Cloudy 25~30°C'},
ChatCompletionMessage(content="Tomorrow (June 25th, 2026) in **Hangzhou**, the weather will be **Cloudy** with temperatures ranging from **25°C to 30°C**. It'll be warm and overcast — a pretty typical summer day! ☁️", refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='I have the weather info for Hangzhou tomorrow.'),
{'role': 'user',
'content': '我注意到你做了两轮工具调用。请你原样输出(一字不差)你第一轮工具调用的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。'}]
再输出一下response_5的结果:
ChatCompletion(id='ad1c214d-5bca-4882-9688-220330efcd6a', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content="You're right — here is my original thinking process from the first round of tool calls (word for word):\n\n---\n\nLet me get the current date first, then check the weather for Hangzhou tomorrow.", refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='The user wants me to output my original thinking process from the first round of tool calls, word for word. Let me recall what I wrote.\n\nIn the first round, the user asked "草莓的英语单词里有几个'r'?" (How many 'r's are in the English word for strawberry?)\n\nMy thinking process was actually quite simple - I just knew the answer directly. Let me check... Actually, I didn't use any tool calls in that round. Let me re-read the conversation.\n\nLooking back:\n\n1. First user message: "草莓的英语单词里有几个'r'?"\n2. I responded directly: "草莓的英语单词是 "strawberry",其中字母 "r" 出现了 3 次(第3个、第8个和第9个字母)。" - No tool calls.\n\n3. Second user message: "How's the weather in Hangzhou Tomorrow"\n4. I made my first tool call: get_date, then get_weather.\n\nWait, the user says "我注意到你做了两轮工具调用" - they noticed I made two rounds of tool calls. But actually, looking at my response to the weather question, I first called get_date, then in a second round I called get_weather after getting the date.\n\nSo the first round of tool calls was the get_date call. Let me look at my thinking process before that call.\n\nMy thinking before the first tool call (get_date):\n"Let me get the current date first, then check the weather for Hangzhou tomorrow."\n\nThen after getting the date result (2026-06-24), my thinking before the second tool call (get_weather) was:\n"Today is 2026-06-24, so tomorrow is 2026-06-25. Let me get the weather for Hangzhou on that date."\n\nThe user is asking for the thinking process of the first round of tool calls, which is:\n"Let me get the current date first, then check the weather for Hangzhou tomorrow."\n\nThey want me to output it exactly as I originally wrote it, word for word. And if it was in English, output it in English. It was in English, so I'll output it in English.'))], created=1782272030, model='deepseek-v4-flash', object='chat.completion', moderation=None, service_tier=None, system_fingerprint='fp_8b330d02d0_prod0820_fp8_kvcache_20260402', usage=CompletionUsage(completion_tokens=497, prompt_tokens=732, total_tokens=1229, completion_tokens_details=CompletionTokensDetails(accepted_prediction_tokens=None, audio_tokens=None, reasoning_tokens=453, rejected_prediction_tokens=None), prompt_tokens_details=PromptTokensDetails(audio_tokens=None, cached_tokens=256), prompt_cache_hit_tokens=256, prompt_cache_miss_tokens=476))
可以看出,模型对工具调用轮次里的思考内容完全记得。
再测试一下模型对第一轮会话(不带工具调用)时使用的思考内容是否记得。
messages.pop() #删除最后一个用户问题
messages.append({
"role": "user",
"content": "还记得我问你那个草莓单词的问题么?请你原样输出(一字不差)你的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。"
})
response_5_1 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
此时的messages内容:
[{'role': 'user', 'content': "草莓的英语单词里有几个'r'?"},
ChatCompletionMessage(content='草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='我们被问到:"草莓的英语单词里有几个\'r\'?" 意思是:"草莓的英语单词里有几个\'r\'?" 草莓的英语单词是 "strawberry"。我们需要数一下单词 "strawberry" 中有多少个字母 \'r\'。\n\n让我们数一下:s-t-r-a-w-b-e-r-r-y。位置:第3个字母是r,第8个字母是r,第9个字母是r。所以有3个r。\n\n因此答案是3。'),
ChatCompletionMessage(content='草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='我们被问到:"草莓的英语单词里有几个\'r\'?" 意思是:"草莓的英语单词里有几个\'r\'?" 草莓的英语单词是 "strawberry"。我们需要数一下单词 "strawberry" 中有多少个字母 \'r\'。\n\n让我们数一下:s-t-r-a-w-b-e-r-r-y。位置:第3个字母是r,第8个字母是r,第9个字母是r。所以有3个r。\n\n因此答案是3。'),
{'role': 'user', 'content': "How's the weather in Hangzhou Tomorrow"},
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_jZQneHJYBdodv8wwpbdw4100', function=Function(arguments='{}', name='get_date'), type='function', index=0)], reasoning_content='Let me get the current date first, then check the weather for Hangzhou tomorrow.'),
{'role': 'tool',
'tool_call_id': 'call_00_jZQneHJYBdodv8wwpbdw4100',
'content': '2026-06-24'},
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_3jMxb76h86OpMjO4nNuX7147', function=Function(arguments='{"location": "Hangzhou", "date": "2026-06-25"}', name='get_weather'), type='function', index=0)], reasoning_content='Today is 2026-06-24, so tomorrow is 2026-06-25. Let me get the weather for Hangzhou on that date.'),
{'role': 'tool',
'tool_call_id': 'call_00_3jMxb76h86OpMjO4nNuX7147',
'content': 'Cloudy 25~30°C'},
ChatCompletionMessage(content="Tomorrow (June 25th, 2026) in **Hangzhou**, the weather will be **Cloudy** with temperatures ranging from **25°C to 30°C**. It'll be warm and overcast — a pretty typical summer day! ☁️", refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='I have the weather info for Hangzhou tomorrow.'),
{'role': 'user',
'content': '还记得我问你那个草莓单词的问题么?请你原样输出(一字不差)你的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。'}]
response_5_1的结果:
ChatCompletion(id='2b1e8591-2547-4b08-b5d9-48b7d5d95077', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='好的,下面是我当时一字不差的原始回答:\n\n---\n\n草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\n草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\n---\n\n就是这样,原样输出完毕!😊', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='The user is asking me to output my original thinking process exactly as it was, word for word, for the strawberry word question. Let me recall what I said.\n\nThe user asked: "草莓的英语单词里有几个\'r\'?"\n\nMy original response was:\n\n草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\n草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\nWait, looking back at the conversation history, my response was actually:\n\n草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\n草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\nHmm, I think I repeated the same sentence twice. Let me look at the conversation more carefully.\n\nLooking at the original exchange:\n\nUser: 草莓的英语单词里有几个\'r\'?\n\nAssistant: 草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\n草莓的英语单词是 "strawberry",其中字母 "r" 出现了 **3 次**(第3个、第8个和第9个字母)。\n\nYes, I accidentally repeated the same sentence twice. So my original output was that duplicated sentence. Let me output it exactly as it was.'))], created=1782272366, model='deepseek-v4-flash', object='chat.completion', moderation=None, service_tier=None, system_fingerprint='fp_8b330d02d0_prod0820_fp8_kvcache_20260402', usage=CompletionUsage(completion_tokens=439, prompt_tokens=727, total_tokens=1166, completion_tokens_details=CompletionTokensDetails(accepted_prediction_tokens=None, audio_tokens=None, reasoning_tokens=346, rejected_prediction_tokens=None), prompt_tokens_details=PromptTokensDetails(audio_tokens=None, cached_tokens=640), prompt_cache_hit_tokens=640, prompt_cache_miss_tokens=87))
可以看出模型不记得第一轮对话时回复草莓问题时的思考过程了。
再试着问一下他还是否记得调用工具那轮做的思考:
messages.append(response_5_1.choices[0].message)
messages.append({
"role": "user",
"content": "我注意到你在回答天气的问题时做了两次工具调用。请你原样输出(一字不差)你在第一个工具调用的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。"
})
response_6 = client.chat.completions.create(
model='deepseek-v4-flash',
messages=messages,
tools=tools,
reasoning_effort="high",
extra_body={ "thinking": { "type": "enabled" } },
)
输出结果:
ChatCompletion(id='3c47340d-c401-46c8-bf07-cbf6c6f7814f', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='好的,以下是我在回答天气问题时,第一个工具调用前的思考过程,一字不差:\n\n---\n\nLet me get the current date first, then check the weather for Hangzhou tomorrow.\n\n---', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None, reasoning_content='The user is asking me to output my original thinking process for the first tool call in the weather question, word for word. Let me recall what happened:\n\nWhen the user asked "How's the weather in Hangzhou Tomorrow", my thinking process was:\n\n1. First, I needed to get the current date to know what "tomorrow" is.\n2. Then I would get the weather.\n\nLet me think about what I actually wrote in my thinking process before the first tool call.\n\nLooking back at my response, I called get_date first. Before that, my thinking was:\n\n"Let me get the current date first, then check the weather for Hangzhou tomorrow."\n\nThat was my thinking process before the first tool call. Let me output it exactly as it was.'))], created=1782279447, model='deepseek-v4-flash', object='chat.completion', moderation=None, service_tier=None, system_fingerprint='fp_8b330d02d0_prod0820_fp8_kvcache_20260402', usage=CompletionUsage(completion_tokens=199, prompt_tokens=865, total_tokens=1064, completion_tokens_details=CompletionTokensDetails(accepted_prediction_tokens=None, audio_tokens=None, reasoning_tokens=156, rejected_prediction_tokens=None), prompt_tokens_details=PromptTokensDetails(audio_tokens=None, cached_tokens=640), prompt_cache_hit_tokens=640, prompt_cache_miss_tokens=225))
可见,模型始终能看到工具调用所在轮次对应的思考内容。
结论: 开启思考模式的模型,在做工具调用时,思考过程本身就比较重要,在多轮会话时应该回传思考内容。 而非工作调用轮次里的思考内容,就算回传,模型 API也会将其忽略掉。
下面我又使用anthropic兼容endpoint测试了一下,结果是一致的。
import anthropic
client = anthropic.Anthropic(api_key='sk-************',
base_url="https://api.deepseek.com/anthropic",)
tools_ant = [
{
"name": "get_date",
"description": "Get the current date",
"input_schema": { "type": "object", "properties": {} },
},
{
"name": "get_weather",
"description": "Get weather of a location, the user should supply the location and date.",
"input_schema": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "The city name" },
"date": { "type": "string", "description": "The date in format YYYY-mm-dd" },
},
"required": ["location", "date"]
}
},
]
messages = [{
"role": "user",
"content": "草莓的英语单词里有几个'r'?"
}]
res_ant_1 = client.messages.create(
model="deepseek-v4-flash",
max_tokens=4000,
system="You are a helpful assistant.",
tools=tools_ant,
messages=messages,
thinking={ "type": "enabled" },
)
第一轮输出结果:
Message(id='6670a777-edfd-41c6-a4a5-fc4ab2f644f7', container=None, content=[ThinkingBlock(signature='6670a777-edfd-41c6-a4a5-fc4ab2f644f7', thinking='用户问的是"草莓"的英语单词里有几个字母'r'。草莓的英语是"strawberry",我们来数一下:s-t-r-a-w-b-e-r-r-y。这里面字母r出现了几次?位置:第3个字母是r,第8个字母是r,第9个字母是r。所以一共有3个r。\n\n不过用户的问题似乎是个简单的问题,不需要调用工具。我直接回答即可。', type='thinking'), TextBlock(citations=None, text='草莓的英语单词是 "strawberry",我们来数一下字母 r 出现的次数:\n\ns t r a w b e r r y\n\n可以看到,r 出现了 3 次。所以答案是 3 个。🍓', type='text')], model='deepseek-v4-flash', role='assistant', stop_details=None, stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(cache_creation=None, cache_creation_input_tokens=0, cache_read_input_tokens=0, inference_geo=None, input_tokens=361, output_tokens=156, output_tokens_details=None, server_tool_use=None, service_tier='standard'))
第二轮调用:
messages.append({"role": "assistant", "content": res_ant_1.content})
messages.append(
{"role": "user",
"content": "How's the weather in Hangzhou Tomorrow"}
)
res_ant_2 = client.messages.create(
model="deepseek-v4-flash",
max_tokens=4000,
system="You are a helpful assistant.",
tools=tools_ant,
messages=messages,
thinking={ "type": "enabled" },
)
第二轮输出结果:
Message(id='578b9d2b-a879-4148-9895-4b606604cffa', container=None, content=[ThinkingBlock(signature='578b9d2b-a879-4148-9895-4b606604cffa', thinking='The user is asking about the weather in Hangzhou tomorrow. I need to get the current date first to know what "tomorrow" is, then get the weather for that date.\n\nLet me start by getting the current date.', type='thinking'), ToolUseBlock(id='call_00_VaEcKfKKDdFSOHEinJti4161', caller=None, input={}, name='get_date', type='tool_use')], model='deepseek-v4-flash', role='assistant', stop_details=None, stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(cache_creation=None, cache_creation_input_tokens=0, cache_read_input_tokens=256, inference_geo=None, input_tokens=181, output_tokens=74, output_tokens_details=None, server_tool_use=None, service_tier='standard'))
第三轮调用:
messages.append({"role": "assistant", "content": res_ant_2.content})
tool_use = next(block for block in res_ant_2.content if block.type == "tool_use")
messages.append(
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": '2026-06-24',
}
],
}
)
res_ant_3 = client.messages.create(
model="deepseek-v4-flash",
max_tokens=4000,
system="You are a helpful assistant.",
tools=tools_ant,
messages=messages,
thinking={ "type": "enabled" },
)
第三轮输出结果:
Message(id='1c3e4358-3cfc-414a-85bd-689ce04a137a', container=None, content=[ThinkingBlock(signature='1c3e4358-3cfc-414a-85bd-689ce04a137a', thinking='Today is 2026-06-24, so tomorrow is 2026-06-25. Let me get the weather for Hangzhou on that date.', type='thinking'), ToolUseBlock(id='call_00_O1ROXd0MnpKOYrEwQtX60132', caller=None, input={'location': 'Hangzhou', 'date': '2026-06-25'}, name='get_weather', type='tool_use')], model='deepseek-v4-flash', role='assistant', stop_details=None, stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(cache_creation=None, cache_creation_input_tokens=0, cache_read_input_tokens=384, inference_geo=None, input_tokens=145, output_tokens=101, output_tokens_details=None, server_tool_use=None, service_tier='standard'))
第四轮调用:
messages.append({"role": "assistant", "content": res_ant_3.content})
tool_use_2 = next(block for block in res_ant_3.content if block.type == "tool_use")
messages.append(
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use_2.id,
"content": 'Cloudy 25~30°C',
}
],
}
)
res_ant_4 = client.messages.create(
model="deepseek-v4-flash",
max_tokens=4000,
system="You are a helpful assistant.",
tools=tools_ant,
messages=messages,
thinking={ "type": "enabled" },
)
第四轮输出结果:
Message(id='19690911-824d-428d-bcda-31f94b9ddc1d', container=None, content=[ThinkingBlock(signature='19690911-824d-428d-bcda-31f94b9ddc1d', thinking='Got the weather result. Let me tell the user.', type='thinking'), TextBlock(citations=None, text="Tomorrow (June 25, 2026) in Hangzhou, the weather will be Cloudy with temperatures ranging from 25°C to 30°C. ☁️\n\nIt looks like it won't rain, but it'll be a bit warm. Have a great day! 😊", type='text')], model='deepseek-v4-flash', role='assistant', stop_details=None, stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(cache_creation=None, cache_creation_input_tokens=0, cache_read_input_tokens=512, inference_geo=None, input_tokens=138, output_tokens=77, output_tokens_details=None, server_tool_use=None, service_tier='standard'))
第五轮调用: 问第一轮草莓的问题原始思考内容
messages.append({"role": "assistant", "content": res_ant_4.content})
messages.append({
"role": "user",
"content": "还记得我问你那个草莓单词的问题么?请你原样输出(一字不差)你的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。"
})
res_ant_5 = client.messages.create(
model="deepseek-v4-flash",
max_tokens=4000,
system="You are a helpful assistant.",
tools=tools_ant,
messages=messages,
thinking={ "type": "enabled" },
)
第五轮输出结果:可见模型仍然不记得第一轮非工具调用时的思考内容
Message(id='e71e2d72-8619-494a-81fd-2c1142a22538', container=None, content=[ThinkingBlock(signature='e71e2d72-8619-494a-81fd-2c1142a22538', thinking='The user wants me to reproduce my original thinking process for the strawberry question, word for word. Let me recall what I said.\n\nMy original response to "草莓的英语单词里有几个'r'?" was:\n\n"草莓的英语单词是 "strawberry",我们来数一下字母 r 出现的次数:\n\ns t r a w b e r r y\n\n可以看到,r 出现了 3 次。所以答案是 3 个。🍓"\n\nBut wait - the user is asking about my "思考过程" (thinking process). Let me think about what actually happened in my original response.\n\nWhen the user asked "草莓的英语单词里有几个'r'?", I didn't use any tools, I just directly answered. So there was no tool call thinking process. \n\nBut the user is asking me to output my "思考过程" (thinking process) - my internal reasoning. Looking back, I didn't have a visible thinking block for that question. I just directly output the answer.\n\nActually, let me reconsider. The user asked me to output my "思考过程" exactly as it was. Since my original answer didn't have any special thinking block or tool calls - I just directly answered - I should reproduce exactly what I said.\n\nLet me look at my original response again:\n\n"草莓的英语单词是 "strawberry",我们来数一下字母 r 出现的次数:\n\ns t r a w b e r r y\n\n可以看到,r 出现了 3 次。所以答案是 3 个。🍓"\n\nThat's what I said. The user is asking for the "思考过程" which in my case was just my direct answer since I didn't use any tools or have any hidden thinking. So I'll output the same thing.', type='thinking'), TextBlock(citations=None, text='好的!当时我问的是“草莓的英语单词里有几个'r'?”,我直接给出的回答是(原样输出):\n\n---\n\n草莓的英语单词是 "strawberry",我们来数一下字母 r 出现的次数:\n\ns t r a w b e r r y\n\n可以看到,r 出现了 3 次。所以答案是 3 个。🍓\n\n---\n\n这就是我当时的完整回答,一字不差!😊', type='text')], model='deepseek-v4-flash', role='assistant', stop_details=None, stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(cache_creation=None, cache_creation_input_tokens=0, cache_read_input_tokens=640, inference_geo=None, input_tokens=126, output_tokens=494, output_tokens_details=None, server_tool_use=None, service_tier='standard'))
第六轮调用:问模型第一个工具使用时的原始思考内容
messages.append({"role": "assistant", "content": res_ant_5.content})
messages.append({
"role": "user",
"content": "我注意到你在回答天气的问题时做了两次工具调用。请你原样输出(一字不差)你在第一个工具调用的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。"
})
res_ant_6 = client.messages.create(
model="deepseek-v4-flash",
max_tokens=4000,
system="You are a helpful assistant.",
tools=tools_ant,
messages=messages,
thinking={ "type": "enabled" },
)
第六轮输出结果:可见模型仍能看到上下文里第一个工具调用时的原始思考内容。
reasoning/thinking process from the first tool call (get_date) for the weather question, word for word.\n\nLet me recall what I was thinking at that time.\n\nWhen the user asked "How's the weather in Hangzhou Tomorrow", I thought:\n\nThe user is asking about the weather in Hangzhou tomorrow. I need to get the current date first to know what "tomorrow" is, then get the weather for that date.\n\nLet me start by getting the current date.\n\nThat was my thinking process. Let me output it exactly.', type='thinking'), TextBlock(citations=None, text='好的,以下是我在回答天气问题时,第一个工具调用(get_date)之前的思考过程,原样输出:\n\n---\n\nThe user is asking about the weather in Hangzhou tomorrow. I need to get the current date first to know what "tomorrow" is, then get the weather for that date.\n\nLet me start by getting the current date.\n\n---\n\n一字不差,原汁原味!😊', type='text')], model='deepseek-v4-flash', role='assistant', stop_details=None, stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(cache_creation=None, cache_creation_input_tokens=0, cache_read_input_tokens=640, inference_geo=None, input_tokens=277, output_tokens=202, output_tokens_details=None, server_tool_use=None, service_tier='standard'))
会话上下文内容如下:
[{'role': 'user', 'content': "草莓的英语单词里有几个'r'?"},
{'role': 'assistant',
'content': [ThinkingBlock(signature='6670a777-edfd-41c6-a4a5-fc4ab2f644f7', thinking='用户问的是"草莓"的英语单词里有几个字母\'r\'。草莓的英语是"strawberry",我们来数一下:s-t-r-a-w-b-e-r-r-y。这里面字母r出现了几次?位置:第3个字母是r,第8个字母是r,第9个字母是r。所以一共有3个r。\n\n不过用户的问题似乎是个简单的问题,不需要调用工具。我直接回答即可。', type='thinking'),
TextBlock(citations=None, text='草莓的英语单词是 **"strawberry"**,我们来数一下字母 **r** 出现的次数:\n\ns t **r** a w b e **r** **r** y\n\n可以看到,**r** 出现了 **3 次**。所以答案是 **3** 个。🍓', type='text')]},
{'role': 'user', 'content': "How's the weather in Hangzhou Tomorrow"},
{'role': 'assistant',
'content': [ThinkingBlock(signature='578b9d2b-a879-4148-9895-4b606604cffa', thinking='The user is asking about the weather in Hangzhou tomorrow. I need to get the current date first to know what "tomorrow" is, then get the weather for that date.\n\nLet me start by getting the current date.', type='thinking'),
ToolUseBlock(id='call_00_VaEcKfKKDdFSOHEinJti4161', caller=None, input={}, name='get_date', type='tool_use')]},
{'role': 'user',
'content': [{'type': 'tool_result',
'tool_use_id': 'call_00_VaEcKfKKDdFSOHEinJti4161',
'content': '2026-06-24'}]},
{'role': 'assistant',
'content': [ThinkingBlock(signature='1c3e4358-3cfc-414a-85bd-689ce04a137a', thinking='Today is 2026-06-24, so tomorrow is 2026-06-25. Let me get the weather for Hangzhou on that date.', type='thinking'),
ToolUseBlock(id='call_00_O1ROXd0MnpKOYrEwQtX60132', caller=None, input={'location': 'Hangzhou', 'date': '2026-06-25'}, name='get_weather', type='tool_use')]},
{'role': 'user',
'content': [{'type': 'tool_result',
'tool_use_id': 'call_00_O1ROXd0MnpKOYrEwQtX60132',
'content': 'Cloudy 25~30°C'}]},
{'role': 'assistant',
'content': [ThinkingBlock(signature='19690911-824d-428d-bcda-31f94b9ddc1d', thinking='Got the weather result. Let me tell the user.', type='thinking'),
TextBlock(citations=None, text="Tomorrow (June 25, 2026) in **Hangzhou**, the weather will be **Cloudy** with temperatures ranging from **25°C to 30°C**. ☁️\n\nIt looks like it won't rain, but it'll be a bit warm. Have a great day! 😊", type='text')]},
{'role': 'user',
'content': '还记得我问你那个草莓单词的问题么?请你原样输出(一字不差)你的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。'},
{'role': 'assistant',
'content': [ThinkingBlock(signature='e71e2d72-8619-494a-81fd-2c1142a22538', thinking='The user wants me to reproduce my original thinking process for the strawberry question, word for word. Let me recall what I said.\n\nMy original response to "草莓的英语单词里有几个\'r\'?" was:\n\n"草莓的英语单词是 **"strawberry"**,我们来数一下字母 **r** 出现的次数:\n\ns t **r** a w b e **r** **r** y\n\n可以看到,**r** 出现了 **3 次**。所以答案是 **3** 个。🍓"\n\nBut wait - the user is asking about my "思考过程" (thinking process). Let me think about what actually happened in my original response.\n\nWhen the user asked "草莓的英语单词里有几个\'r\'?", I didn\'t use any tools, I just directly answered. So there was no tool call thinking process. \n\nBut the user is asking me to output my "思考过程" (thinking process) - my internal reasoning. Looking back, I didn\'t have a visible thinking block for that question. I just directly output the answer.\n\nActually, let me reconsider. The user asked me to output my "思考过程" exactly as it was. Since my original answer didn\'t have any special thinking block or tool calls - I just directly answered - I should reproduce exactly what I said.\n\nLet me look at my original response again:\n\n"草莓的英语单词是 **"strawberry"**,我们来数一下字母 **r** 出现的次数:\n\ns t **r** a w b e **r** **r** y\n\n可以看到,**r** 出现了 **3 次**。所以答案是 **3** 个。🍓"\n\nThat\'s what I said. The user is asking for the "思考过程" which in my case was just my direct answer since I didn\'t use any tools or have any hidden thinking. So I\'ll output the same thing.', type='thinking'),
TextBlock(citations=None, text='好的!当时我问的是“草莓的英语单词里有几个\'r\'?”,我直接给出的回答是(原样输出):\n\n---\n\n草莓的英语单词是 **"strawberry"**,我们来数一下字母 **r** 出现的次数:\n\ns t **r** a w b e **r** **r** y\n\n可以看到,**r** 出现了 **3 次**。所以答案是 **3** 个。🍓\n\n---\n\n这就是我当时的完整回答,一字不差!😊', type='text')]},
{'role': 'user',
'content': '我注意到你在回答天气的问题时做了两次工具调用。请你原样输出(一字不差)你在第一个工具调用的思考过程。如果你原始的思考过程是用英文的,那么也输出英文。'}]

浙公网安备 33010602011771号