接入 DeepSeek 思考模式时,可能遇到请求成功、思考内容很长,最终答案却为空。先检查finish_reason、reasoning_content和content,再决定是调整输出额度,还是修复代码的读取方式。
1. 先判断:被截断,还是读错字段?
思考内容在message.reasoning_content,最终答案在message.content,两者是并列字段。拿到了思考内容,不代表已经拿到最终答案。
# response 是已有的非流式 Chat Completions 响应 choice = response.choices[0] msg = choice.message reasoning = getattr(msg, "reasoning_content", None) or "" answer = msg.content or "" print("结束原因:", choice.finish_reason) print("思考字符数:", len(reasoning)) print("答案字符数:", len(answer)) print("是否请求工具:", bool(msg.tool_calls)) print("输出 token:", response.usage.completion_tokens)| 返回现象 | 优先检查 | 处理方向 |
|---|---|---|
length,答案为空或不完整 | max_tokens、上下文总长度 | 调整输出额度或缩短输入,重新请求 |
stop,原始content有答案但界面空白 | SDK 字段读取与页面渲染 | 修复答案显示逻辑 |
tool_calls,content为空 | tool_calls是否有内容 | 执行工具并继续对话 |
| 流式返回只有思考被显示 | 是否读取delta.content、是否过早结束 | 分别接收两种内容,等待正常结束 |
如果是content_filter、超时或连接中断,按对应原因处理。不能把所有空答案都归咎于思考太久。
2. 为什么设了 8192,还可能没有最终答案?
max_tokens限制的是生成输出,并不保证给最终答案预留同样多的额度。思考本身也会消耗生成 token。上限设得太小,复杂问题可能在进入最终答案前就用完额度。
看到finish_reason="length"时,先检查输出是否接近请求上限,再检查输入与输出是否触及模型上下文限制。不要只因为“HTTP 200”就把这次结果当成完整答案。
处理时一次改一个条件:在模型允许范围内提高max_tokens,或将reasoning_effort调低;简单任务也可以关闭思考。输出额度越大,潜在费用和等待时间也越高,不必一律拉满。
# 以下是三个独立的调整选项,按任务需要选择 # 1. 在原请求中提高 max_tokens,须符合当前模型限制 # 2. reasoning_effort="low" # 3. OpenAI Python SDK 关闭思考: extra_body={"thinking": {"type": "disabled"}}3. 流式接收时,不要遇到思考就提前退出
流式返回中,思考从delta.reasoning_content读取,答案从delta.content读取。不要把“暂时没有 content”当成流已结束,也不要在第一段思考到达时就返回页面。
thought_parts, answer_parts = [], [] for chunk in stream: # stream 是已有的流式响应 if not chunk.choices: continue delta = chunk.choices[0].delta thought = getattr(delta, "reasoning_content", None) if thought: thought_parts.append(thought) if delta.content: answer_parts.append(delta.content) answer = "".join(answer_parts)使用工具调用时,还要收集工具参数、执行工具并继续请求。