OpenAI Responses API 写作如何控制输出长度和推理预算
先理解三个控制点
Responses API 的 max_output_tokens 是一次响应可生成的 token 上限,而且这个上限包含可见输出 token 与推理 token。因此,文章正文能使用的空间并不等于参数值本身。推理模型还可以通过 reasoning 参数配置推理行为,但具体可用选项要以当前模型和接口支持为准,不能把某个固定档位硬编码到所有模型。
此外,输入上下文也会影响请求能否完成。truncation 使用 disabled 时,输入超过模型上下文窗口会请求失败;使用 auto 时,接口会从对话开头丢弃项目以适应上下文。写作生产环境通常应先记录输入规模,再决定是否允许自动截断。
准备
- 确认使用的模型支持 Responses API,以及你要使用的 reasoning 配置。
- 先定义交付规格,例如正文目标字数、必须包含的标题数量、是否允许省略和返回格式。
- 为每次请求保存 model、max_output_tokens、reasoning、input、instructions、response_id 和完成状态,方便定位文章生成超限问题。
- 准备一条失败处理规则:响应不完整时进入续写或重新生成,不直接发布。
如果还没有整理输入,可以先参考OpenAI Responses API 写作输入怎么组织:文章与提纲模板,把稳定规则和本次任务材料分开。
分步操作
1. 先把交付目标写成可检查的规则
不要只写“生成一篇详细文章”。应明确文章用途、目标长度、段落范围、必需字段和停止条件。例如要求输出 5 个小节,每节 2 到 4 段;若资料不足,输出“待补资料”,不要自行补充事实。
2. 用 max_output_tokens 设置硬上限
max_output_tokens 是防止响应无限变长的第一道边界。设置时要给正文、标题、格式符号和可能消耗的推理 token 留出空间。若上限过小,模型可能在结尾处被截断;若上限过大,又失去成本和长度控制。
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="your-supported-model",
instructions=(
"你是内容编辑。只根据输入资料写作。"
"输出 4 个 h2 小节,每节 2 到 3 段。"
"资料不足时明确标记,不补造事实。"
),
input="请围绕目标读者的问题生成一篇操作说明。",
max_output_tokens=3000,
reasoning={"effort": "low"},
truncation="disabled",
)
print(response.output_text)
print(response.status)上面的数值只是示例,不代表所有模型的固定推荐值。reasoning 的具体字段和可用值应以当前 SDK 类型检查、模型文档和实际返回结果为准。对简单改写任务,可以减少推理配置;对复杂提纲或多条件校验任务,再评估是否需要更高推理投入。
3. 让提示词主动收敛输出
参数只能设置上限,不能保证文章恰好达到目标长度。提示词中应同时写清“只输出需要的内容”“达到最后一个小节后停止”“不要重复总结”“每个示例只保留一份”。这样可以减少模型在上限附近反复扩写的情况。
写作要求:
1. 先给出准备事项,再给出分步操作。
2. 正文只保留 4 个 h2 小节。
3. 每个步骤说明动作、判断结果和下一步。
4. 完成最后一项检查后立即停止。
5. 不重复题目,不添加资料中没有确认的产品能力。4. 根据任务类型分配预算
- 短改写:重点限制输出格式和最大长度,避免为简单任务保留过大的预算。
- 文章初稿:为正文、标题和结构检查预留空间,并要求模型在固定小节后停止。
- 复杂提纲:先生成结构,再分请求生成各章节,避免一次请求承担整篇文章。
- 连续修改:保存 previous_response_id 或自行保存版本,避免每轮重复塞入完整历史。
5. 读取响应并判断是否完整
不要只判断 output_text 是否非空。应用侧至少应保存 response.status,并检查正文是否包含要求的最后一个小节、结尾标记或结构化字段。若使用流式输出,还要等完成事件后再把草稿转为可发布内容。
text = response.output_text or ""
required_sections = ["准备", "分步操作", "完成前检查"]
missing = [name for name in required_sections if name not in text]
if response.status != "completed" or missing:
print("进入返工流程", response.status, missing)
else:
print("通过基础完整性检查")可复制模板或示例
下面是一份适合文章生成的请求模板。你只需要替换模型、任务说明和预算,不要把示例中的预算值当成通用标准。
response = client.responses.create(
model="your-supported-model",
instructions="""
你负责生成可发布的中文操作文章。
输出要求:
- 从 h2 开始,不输出 h1。
- 必须包含:准备、分步操作、翻车怎么改、完成前检查。
- 每一步写清动作、预期结果和失败后的处理。
- 只使用输入资料确认过的事实。
- 文章达到最后一个检查项后停止。
""",
input="""
目标读者:需要控制 API 写作长度和成本的开发者。
核心问题:如何设置输出上限,并识别响应是否被截断。
期望交付:一篇带 Python 示例的操作说明。
""",
max_output_tokens=3500,
reasoning={"effort": "low"},
truncation="disabled",
)若文章仍然经常超限,优先拆成“提纲请求”和“分章节请求”。每次只让模型完成一个清晰任务,并在应用侧拼接和检查,比单纯不断提高 max_output_tokens 更容易控制成本和交付长度。
翻车怎么改
故障一:文章结尾突然消失
原因通常是响应触及 max_output_tokens 上限,或者推理 token 占用了预算,导致可见正文空间不足。修正动作是先检查 response.status 和输出末尾,再适度提高上限或降低不必要的推理投入,同时缩短提示词和拆分章节。
故障二:上下文过长导致请求失败
原因是 truncation 为 disabled 时,输入超过模型上下文窗口,接口会拒绝请求。修正动作是删除重复历史、压缩资料,或在确认允许丢弃早期对话的前提下使用 truncation="auto",并记录被截断的上下文策略。
故障三:文章很长但没有完成任务
原因是提示词只规定了“详细”,没有规定停止条件和验收字段。修正动作是列出固定小节、每节范围、最后一个检查项,并在应用侧检查这些字段是否全部出现。
故障四:推理预算无法按预期生效
原因可能是当前模型不支持所填写的 reasoning 配置,或 SDK 与接口版本不匹配。修正动作是先查看当前 SDK 的参数类型和模型支持范围,删除未经确认的字段,并用一条最小请求验证实际响应。
完成前检查
- 确认响应状态为 completed,或已按业务规则处理非完成状态。
- 确认输出包含准备、分步操作、翻车怎么改和完成前检查。
- 确认正文没有在句子中间、代码块中间或列表中间被截断。
- 确认实际请求中的 max_output_tokens、reasoning 和 truncation 与日志记录一致。
- 确认资料不足之处被标记,没有把推测写成确定事实。
- 确认文章长度、格式和字段通过发布前验收后,才从草稿状态进入发布流程。
下一步
把这篇的方法练一遍
提示词和步骤可以带到创作里直接试做一版。