Appearance
文本生成
文本生成是 OpenAI API 最核心的能力。无论是回答问题、撰写文章、翻译文本还是生成代码,本质上都是在调用文本生成接口。本模块将带你系统掌握 Responses API 的使用方法、核心参数的含义与调优技巧,以及多轮对话的实现方式。
Responses API 简介
Responses API 是 OpenAI 最新推出的文本生成接口,也是官方推荐的主力接口。相比旧版 Chat Completions API,Responses API 提供了更简洁的调用方式——你可以直接传入一个字符串作为输入,而不需要手动构造消息数组。同时,它还内置了对网页搜索、文件搜索、代码解释器等工具的原生支持,让模型能够在生成文本的过程中调用外部能力。
Responses API 的另一个重要特性是 有状态对话:通过 previous_response_id 参数,你可以让 API 自动维护对话历史,无需在每次请求中手动传入完整的对话上下文。这在构建多轮对话系统时尤为方便。
POST/v1/responses
消息角色
ℹ️三种消息角色
在与模型交互时,有三种角色的消息,它们各自承担不同的职责:
system(系统):设定模型的行为准则和角色定义。系统消息相当于给模型下达"元指令"——它告诉模型"你是谁"以及"你应该怎么做"。在 Responses API 中,系统消息通过 instructions 参数传入,而非放在消息数组里。系统消息对模型输出有全局性的影响,是控制模型行为最重要的手段。
user(用户):代表终端用户的输入,即你希望模型回应的问题或指令。用户消息是每次交互的起点,模型会基于用户消息(结合系统指令和对话历史)生成回复。
assistant(助手):模型的回复。在多轮对话中,历史的 assistant 消息帮助模型理解之前的对话上下文,保持回复的连贯性。你也可以手动构造 assistant 消息来引导模型的后续输出方向(这是一种高级的 prompt 技巧,称为 few-shot prompting)。
理解这三种角色是使用 API 的基础。一个典型的对话流程是:先用 instructions 设定模型的行为规范,然后用户发送问题,模型返回回复。在多轮对话中,这个过程不断重复,模型会参考所有历史消息来生成每一次回复。
基础调用示例
以下是使用 Responses API 进行最简单调用的完整示例。只需指定模型和输入文本,即可获得模型的回复:
python
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4.1",
input="用一句话解释量子计算"
)
print(response.output_text)javascript
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-4.1",
input: "用一句话解释量子计算",
});
console.log(response.output_text);bash
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-4.1",
"input": "用一句话解释量子计算"
}'在这个示例中,input 参数接受一个简单的字符串。模型会将其视为一条用户消息,结合默认的系统行为生成回复。response.output_text 是一个便捷属性,直接返回模型输出的纯文本内容。
核心参数详解
Responses API 提供了丰富的参数来控制模型的行为。理解这些参数的含义和取值范围,是调优模型输出的关键:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| model | string | 必填 | 使用的模型 ID,如 gpt-4.1 |
| input | string | array | 必填 | 用户输入,支持字符串或消息数组 |
| instructions | string | null | 系统指令,替代 system message |
| temperature | number | 1 | 随机性控制,0-2,越低越确定 |
| max_output_tokens | integer | 模型默认 | 限制输出 token 数量 |
| top_p | number | 1 | 核采样,与 temperature 二选一 |
| store | boolean | true | 是否存储到 Dashboard 日志 |
temperature 与 top_p
temperature 是最常用的调优参数。它控制模型输出的随机性:值越低,输出越确定、越保守;值越高,输出越多样、越有创意。
- temperature=0:几乎确定性的输出,适合需要精确答案的场景(如数据提取、代码生成)
- temperature=0.5-0.7:平衡模式,适合大多数日常任务
- temperature=1.0:默认值,较好的多样性
- temperature=1.5-2.0:高度随机,适合头脑风暴、创意写作
top_p 是另一种控制随机性的方式(核采样)。它限定模型只从概率最高的前 p% token 中采样。例如 top_p=0.1 意味着模型只考虑累计概率达到 10% 的 token。OpenAI 官方建议:temperature 和 top_p 只调一个,不要同时修改两者。
max_output_tokens
这个参数限制模型单次回复的最大 token 数量。设置合理的上限可以有效控制成本,并防止模型产生过长的输出。需要注意的是,如果模型的回复在达到上限时被截断,finish_reason 会返回 length 而不是 stop,你可以据此判断输出是否完整。
instructions(系统指令)
instructions 参数用于设定模型的行为准则,等效于传统的 system message,但使用起来更简洁。我们在后面的"系统指令"章节中详细讲解。
多轮对话
在实际应用中,大多数对话都不是一问一答就结束的。用户往往需要与模型进行多轮交互,逐步深入或纠正方向。Responses API 提供了两种实现多轮对话的方式。
方式一:使用 previous_response_id(推荐)
这是 Responses API 最便捷的多轮对话方式。你只需在后续请求中传入上一轮回复的 ID,API 会自动拼接完整的对话历史:
python
from openai import OpenAI
client = OpenAI()
# 第一轮对话
response1 = client.responses.create(
model="gpt-4.1",
instructions="你是一位耐心的物理学教授,用通俗易懂的方式解释概念。",
input="什么是相对论?"
)
print(f"助手: {response1.output_text}")
# 第二轮对话 — 自动携带上下文
response2 = client.responses.create(
model="gpt-4.1",
previous_response_id=response1.id,
input="能举个日常生活中的例子吗?"
)
print(f"助手: {response2.output_text}")
# 第三轮对话 — 继续深入
response3 = client.responses.create(
model="gpt-4.1",
previous_response_id=response2.id,
input="GPS 卫星和相对论有什么关系?"
)
print(f"助手: {response3.output_text}")javascript
import OpenAI from "openai";
const client = new OpenAI();
// 第一轮对话
const response1 = await client.responses.create({
model: "gpt-4.1",
instructions: "你是一位耐心的物理学教授,用通俗易懂的方式解释概念。",
input: "什么是相对论?",
});
console.log(`助手: ${response1.output_text}`);
// 第二轮对话 — 自动携带上下文
const response2 = await client.responses.create({
model: "gpt-4.1",
previous_response_id: response1.id,
input: "能举个日常生活中的例子吗?",
});
console.log(`助手: ${response2.output_text}`);
// 第三轮对话 — 继续深入
const response3 = await client.responses.create({
model: "gpt-4.1",
previous_response_id: response2.id,
input: "GPS 卫星和相对论有什么关系?",
});
console.log(`助手: ${response3.output_text}`);这种方式的优势在于:你不需要在客户端维护完整的对话历史,API 会在服务端自动管理。每次请求只需传入新的用户输入和上一轮的 response.id,非常简洁。
方式二:手动构造消息数组
如果你需要更精细地控制对话上下文(例如编辑历史消息、注入中间信息),可以使用消息数组方式:
python
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4.1",
instructions="你是一位耐心的物理学教授。",
input=[
{ "role": "user", "content": "什么是相对论?" },
{ "role": "assistant", "content": "相对论是爱因斯坦提出的物理学理论..." },
{ "role": "user", "content": "能举个日常生活中的例子吗?" },
]
)
print(response.output_text)javascript
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-4.1",
instructions: "你是一位耐心的物理学教授。",
input: [
{ role: "user", content: "什么是相对论?" },
{ role: "assistant", content: "相对论是爱因斯坦提出的物理学理论..." },
{ role: "user", content: "能举个日常生活中的例子吗?" },
],
});
console.log(response.output_text);这种方式给了你完全的控制权,但需要自行管理消息列表的增长。随着对话轮数增多,消息数组会越来越大,需要注意 token 消耗和上下文窗口的限制。
Token 计费与成本管理
⚠️注意 Token 消耗与成本
Token 是 API 计费的基本单位,也是理解 API 成本的关键。每次 API 调用都会消耗两部分 token:
- 输入 token:你发送给模型的所有内容,包括系统指令、对话历史和当前用户输入
- 输出 token:模型生成的回复内容
重要提醒:
多轮对话中 token 会累积。每一轮对话都会把之前的完整历史作为输入发送给模型,因此第 N 轮对话的输入 token 数约等于前 N-1 轮所有消息的 token 总和。一个 10 轮对话的最后一次请求,输入 token 可能是第一轮的 10 倍以上。
输出 token 通常比输入 token 贵 3-4 倍。因此,使用
max_output_tokens限制输出长度是控制成本的有效手段。系统指令也占用 token。一段 200 字的系统指令在每次请求中都会被计入输入 token,10 轮对话就是 10 次。保持系统指令精简非常重要。
利用
usage字段监控消耗。每次 API 响应都包含usage对象,记录了本次请求的输入和输出 token 数量,利用这个字段可以精确追踪成本。
成本优化策略:
- 选择合适的模型(GPT-4.1 mini 比 GPT-4.1 便宜数倍)
- 设置
max_output_tokens防止过长输出 - 在长对话中定期总结并截断历史
- 对重复查询实施缓存
系统指令
系统指令(instructions 参数)是控制模型行为最重要的工具。一条好的系统指令能够显著提升模型输出的质量和一致性。
基本用法
instructions 参数接受一个字符串,在每次请求中告诉模型应该扮演什么角色、遵循什么规则:
python
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4.1",
instructions="""你是一位资深的 Python 技术专家。请遵循以下规则:
1. 所有代码示例使用 Python 3.12+ 语法
2. 必须包含类型注解
3. 附带简洁的中文注释
4. 如果问题涉及多种实现方式,推荐最 Pythonic 的那种""",
input="如何合并两个字典?"
)
print(response.output_text)javascript
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-4.1",
instructions: `你是一位资深的 Python 技术专家。请遵循以下规则:
1. 所有代码示例使用 Python 3.12+ 语法
2. 必须包含类型注解
3. 附带简洁的中文注释
4. 如果问题涉及多种实现方式,推荐最 Pythonic 的那种`,
input: "如何合并两个字典?",
});
console.log(response.output_text);编写有效系统指令的原则
一条好的系统指令应该包含以下要素:
- 角色定义:告诉模型它是谁(如"你是一位资深前端工程师"),这会显著影响模型的回答风格和专业深度
- 行为约束:明确模型应该做什么、不应该做什么(如"只回答技术问题,拒绝无关话题")
- 输出格式:指定期望的回复格式(如"用 Markdown 格式回复""每个步骤用编号列出")
- 语气与风格:设定回复的语气(如"用通俗易懂的方式""保持专业严谨")
instructions 与消息数组中 system role 的区别
在 Responses API 中,instructions 参数是设置系统指令的推荐方式。如果你同时在 input 消息数组中使用了 developer 角色的消息,instructions 的内容会被追加到开发者消息之后。大多数情况下,直接使用 instructions 参数即可,更简洁也更直观。
TIP
系统指令的质量直接决定了模型输出的质量。花时间打磨你的系统指令,往往比调其他参数更有效。我们将在 Prompt Engineering 模块中深入讲解编写高质量指令的进阶技巧。
本模块小结
通过本模块的学习,你已经掌握了:
- Responses API 的基本调用方式
- 三种消息角色(system/user/assistant)的职责
- 核心参数(temperature、max_output_tokens、top_p)的含义与调优
- 多轮对话的两种实现方式
- Token 计费逻辑与成本管理策略
- 系统指令的编写原则
下一模块,我们将学习 Function Calling——让模型调用你定义的函数,实现与外部系统的交互。