OpenAI模型API调用参数完全解析(下)

发布时间:2026/7/17 5:32:12
OpenAI模型API调用参数完全解析(下) OpenAI模型API调用参数完全解析下三、多轮交互实战演示从查天气到理解完整调用链前面讲了很多参数是什么但只看单个请求很难理解这些参数怎么配合工作。下面用一个完整的查天气多轮对话把tools、tool_choice、messages和stream串起来让你看清每一次 API 调用的参数怎么变、messages 怎么累积。3.1 整体流程一览用户提问 → 模型决定调函数第1轮请求你的代码执行真实函数把结果塞回 messages模型基于真实数据回答第2轮请求3.2 逐轮代码实现第1轮用户提问模型决定调函数from openai import OpenAI client OpenAI() # 准备函数定义 tools [{ type: function, function: { name: get_weather, description: 获取指定城市的实时天气, parameters: { type: object, properties: { city: { type: string, description: 城市名称 } }, required: [city] } } }] # 初始化 messages只有用户问题 messages [ {role: user, content: 北京今天天气怎么样} ] # 第1轮请求 response client.chat.completions.create( modelgpt-4o, messagesmessages, # 只有1条user消息 toolstools, # 告诉模型你能调这个函数 tool_choiceauto, # 模型自己决定调不调 temperature0 # 工具调用场景建议用0 ) # 关键查看 finish_reason print(response.choices[0].finish_reason) # → tool_calls ← 不是stop模型要调函数没直接回答 msg response.choices[0].message print(msg.tool_calls[0].function.name) # → get_weather print(msg.tool_calls[0].function.arguments) # → {city: 北京}中间步骤你的代码执行真实函数import json # 将 assistant 回复加入 messages messages.append(msg.model_dump()) # 执行函数这里模拟实际可能调天气API def get_weather(city): # 实际项目这里调真实API return json.dumps({ city: city, temp: 28, condition: 晴, humidity: 45%, wind: 东北风3级 }, ensure_asciiFalse) result get_weather(北京) # 将函数执行结果也加入 messages messages.append({ role: tool, tool_call_id: msg.tool_calls[0].id, # 必须对应 content: result }) # 此时 messages 变成了3条 # [user] → [assistant(tool_calls)] → [tool(result)]第2轮模型基于真实数据回答# 第2轮请求参数和第一轮基本一致但 messages 多了2条 response2 client.chat.completions.create( modelgpt-4o, messagesmessages, # 现在是3条消息了 toolstools, # 依然要带tools tool_choiceauto, temperature0.7 # 回答阶段可以适当提高 ) print(response2.choices[0].finish_reason) # → stop ← 这次模型直接回答问题 print(response2.choices[0].message.content) # → 北京今天天气不错晴天气温28°C湿度45% # 东北风3级。适合出门活动注意防晒哦。 # 最终对话也加入 messages可以继续多轮 messages.append(response2.choices[0].message.model_dump())3.3 messages 的演化过程多轮对话的核心就是messages 数组逐步累积。每一轮你都要把完整历史发回给模型messages 数组演化4轮请求 4次API调用 第1轮请求时的messages1条 [0] role: user content: 北京今天天气怎么样 第1轮响应assistant返回tool_calls加入messages 第2轮请求时的messages3条 [0] role: user content: 北京今天天气怎么样 [1] role: assistant ← 新增 tool_calls: [{get_weather...}] [2] role: tool ← 新增 content: {temp:28,...} 第2轮响应assistant返回自然语言content 继续提问那上海呢时的messages5条 [0] user: 北京今天天气怎么样 [1] assistant: tool_calls[...] [2] tool: {temp:28,...} [3] assistant: 北京今天晴天... ← 新增 [4] user: 那上海呢 ← 新增 每次API调用都带上全部历史——模型不记得上一轮说了什么关键洞察messages 数组就是你的对话内存。每次 API 调用都要把所有历史拼接好发过去——模型本身是无状态的不会记住上一轮对话。这也是为什么长对话 token 消耗越来越大的根本原因。三点很容易踩的坑tool 消息的tool_call_id必须和 assistant 消息里的id对上否则 API 直接报错第2轮请求仍然要带tools参数否则模型不知道还能继续调函数messages里 assistant 有了tool_calls就必须跟一条tool消息否则 API 会拒绝——它认为对话不完整3.4 流式模式的多轮调用如果开启streamTrue处理方式略有不同——需要手动拼接 tool_calls# 流式模式下tool_calls 是分片段返回的 stream client.chat.completions.create( modelgpt-4o, messagesmessages, toolstools, tool_choiceauto, streamTrue # 开启流式 ) # 需要手动收集碎片 collected_tool_calls {} for chunk in stream: delta chunk.choices[0].delta # 工具调用片段需要逐片拼接 if delta.tool_calls: for tc in delta.tool_calls: idx tc.index if idx not in collected_tool_calls: collected_tool_calls[idx] { id: tc.id or , function: {name: , arguments: } } if tc.id: collected_tool_calls[idx][id] tc.id if tc.function.name: collected_tool_calls[idx][function][name] tc.function.name if tc.function.arguments: collected_tool_calls[idx][function][arguments] tc.function.arguments # 拼接完成后后续多轮逻辑和非流式一样四、场景化参数预设 理论归理论实际使用时该设什么值比参数什么意思更重要。以下是5个高频场景的参数预设直接复制用代码生成 数学推理{ model: o4-mini, temperature: 0.1, top_p: 1.0, max_completion_tokens: 4096, seed: 42, frequency_penalty: 0, presence_penalty: 0, reasoning_effort: high }创意写作 头脑风暴{ model: gpt-4o, temperature: 0.9, top_p: 1.0, max_completion_tokens: 2048, presence_penalty: 0.3, frequency_penalty: 0.3 }结构化数据提取{ model: gpt-4o-mini, temperature: 0, top_p: 1.0, max_completion_tokens: 1024, response_format: { type: json_schema, json_schema: { name: extraction, strict: true, schema: {} } } }对话 客服{ model: gpt-4o-mini, temperature: 0.7, top_p: 0.9, max_completion_tokens: 512, presence_penalty: 0.1, frequency_penalty: 0.1 }Agent / 函数调用{ model: gpt-4o, temperature: 0, top_p: 1.0, tools: [], tool_choice: auto, parallel_tool_calls: true, stream: true }五、最常见配置误区 Top 5误区1temperature top_p 一起调错误做法 temperature0.7, top_p0.8 ← 两个采样策略互相干扰 正确做法 temperature0.7, top_p1.0 ← 只用temperature控制 或 temperature1.0, top_p0.8 ← 只用top_p控制 原因两者同时施加会过度限制候选词输出容易质量平庸。误区2temperature0 确定输出错误认知 temperature0 就能保证相同prompt永远得到相同结果 实际情况 浮点运算的微小差异可能导致不同请求间结果不完全一致。 如需高度可复现temperature0 seed固定值误区3presence_penalty 和 frequency_penalty 同时提高错误做法 presence_penalty1.5, frequency_penalty1.5 ← 双高 组合后果 模型几乎不敢使用任何已出现的词输出可能语法混乱甚至无意义 正确做法 两个参数建议不超过0.5通常从0.1~0.3开始尝试误区4只设max_tokens不管模型上限错误做法 max_tokens100000 ← 超出模型上限请求直接失败 正确做法 每个模型有硬上限设置前查一下 gpt-4o → 最大输出 16384 tokens gpt-4o-mini → 最大输出 16384 tokens o4-mini → 最大输出 100000 tokens误区5所有场景都用同一个参数错误做法 写代码、写文章、做分析全用一套参数比如全用temperature0.7 正确做法 不同任务的参数需求完全不同参考第四章的场景预设六、总结核心要点回顾temperature 和 top_p 二选一不要同时调presence_penalty 管话题多样性frequency_penalty 管用词多样性json_schema json_object生产环境务必用前者temperature0 不等于完全确定配合 seed 才是不同场景用不同参数预设不要一套参数走天下一张图记住所有参数参数一句话默认核心作用model选哪个模型必填决定能力上限temperature越大越疯1控制创造力top_p候选词门槛1过滤噪音词max_completion_tokens回答最长多长无限制到上限控制长度和成本stop说到这就停null控制结束位置presence_penalty说过的话题别再说0鼓励话题多样性frequency_penalty用过的词少重复0鼓励用词多样性seed让结果可复现null确定性输出stream边想边说false交互体验response_format输出长什么样text结构化输出tools可以调哪些函数null函数调用tool_choice怎么选函数auto控制调用行为掌握了这些参数你就从会用API升级到了精通API调优。别忘了收藏这篇文章下次调参数时打开看看。