OpenAI Responses API 怎样用 previous_response_id 延续多轮对话
我第一次把 Responses API 接进多轮助手时,最容易误判的一点是:只要把上一轮的 response.id 传给下一轮,就等于拥有了一个永久会话。实际上,previous_response_id 只是把响应串成一条上下文链;应用仍然要负责保存这条链的入口、处理失败恢复,并决定什么时候需要更持久的会话对象。
这篇文章只解决一个问题:怎样用 previous_response_id 延续多轮对话,以及它与手动维护历史、Conversations API 的边界。官方资料入口是 https://developers.openai.com/api/docs/guides/conversation-state,可直接复制打开。
先把三种状态管理方式分开
Responses API 的多轮状态大致有三种组织方式。用 previous_response_id 是“沿着上一条响应继续问”;使用 Conversations API 是“给一段长期会话一个独立的 conversation_id”;手动历史则是应用自己把过去的输入和输出整理成下一次请求的 input。
| 方式 | 适合的压力 | 应用需要保存什么 |
|---|---|---|
previous_response_id | 简单的串行追问、短链路任务 | 最后一次响应 ID 与用户会话的对应关系 |
| Conversations API | 跨请求、跨设备或长期保存的会话 | conversation_id,以及业务侧的权限和归属 |
手动 input 历史 | 需要自己裁剪、脱敏、重排或迁移上下文 | 可重放的消息和输出项,以及裁剪策略 |
这里的关键判断不是“哪个 API 更高级”,而是上下文的所有权在哪里。链式响应把上下文关联交给 API,手动历史把关联交给应用,而 Conversations API 则把长期会话变成一个可以单独管理的资源。

用 response.id 接上下一轮请求
最小链路只有三件事:首轮创建 Response,保存返回对象的 id,下一轮把它放到 previous_response_id。下面的 Node.js 示例故意把状态保存写成函数参数,方便看出业务会话和 API 响应链不是同一个对象。
import OpenAI from "openai";
const client = new OpenAI();
export async function continueConversation(lastResponseId, userText) {
// 首轮没有 ID 时从新的输入开始;有 ID 时让 API 接续上一轮响应。
const params = {
model: process.env.OPENAI_MODEL,
input: [{ role: "user", content: userText }],
store: true,
};
if (lastResponseId) {
// 只关联上一轮响应,不把业务用户 ID 直接当作 API 的响应 ID。
params.previous_response_id = lastResponseId;
}
const response = await client.responses.create(params);
// 调用方应把这个 ID 与自己的会话记录一起保存。
return { text: response.output_text, lastResponseId: response.id };
}
第一次调用时,返回值中的 lastResponseId 会成为第二次调用的输入。第二次调用完成后,要用新的 response.id 覆盖旧值;不要一直保存首轮 ID,否则每次都从相同节点分叉。
这个示例没有把 API key、用户标识或真实响应 ID写进文章,也没有把调用结果当成已经在本机运行过的证据。它只是展示请求字段之间的静态关系。
指令不会因为链式关联自动继承
这是最值得单独提醒的边界:previous_response_id 负责传递上下文关联,并不等于应用层配置会永远沿用。官方文档特别说明,使用 previous_response_id 时,上一轮的 instructions 不会自动带到下一轮。
因此,下面这种“第一轮设定了回答格式,第二轮什么都不补”的写法不适合作为稳定的生产约定:
const next = await client.responses.create({
model: process.env.OPENAI_MODEL,
previous_response_id: previous.id,
// 中文说明:如果本轮仍需遵守输出格式,应在这里再次明确要求。
input: "把刚才的结论改成三条检查清单。",
});
更稳妥的做法是把每一轮都需要的稳定规则放进本轮请求的 instructions,把只属于当前问题的内容放进 input。这样即使以后更换状态载体,也不必依赖“隐藏的上一轮配置”。
store、响应保留与输入成本要一起看
链式调用还有三个经常被混为一谈的概念。
store是响应对象是否由 API 保存的请求选项,不是业务数据库里的会话表。- 保存响应不等于无限期保存;响应对象有默认保留周期,长期会话应评估 Conversations API 或应用自己的持久化策略。
- 即使使用
previous_response_id,链中先前的输入 token 仍会作为输入计费,不能把“少传几段文本”理解为“完全没有上下文成本”。
在服务端,至少应记录用户会话 ID、最后一次响应 ID、状态更新时间和失败状态。用户会话 ID用于找回业务状态,响应 ID用于续接 API 链,两者不要混用。

业务服务怎样保存最后一个响应 ID
可以把续接逻辑包在一个小的状态仓库后面。下面用 Python 写一个最小接口,重点不在数据库选型,而在“成功后才推进指针”:请求失败时不能先把新 ID 写入会话,否则下一次恢复会从一个不存在或未完成的节点继续。
from openai import OpenAI
client = OpenAI()
def ask(session, text):
# session 只保存业务会话和最后一次成功响应 ID,不保存密钥。
params = {
"model": "${OPENAI_MODEL}",
"input": [{"role": "user", "content": text}],
"store": True,
}
if session.get("last_response_id"):
# 中文说明:只从最后一次成功响应继续,避免重复使用旧分支。
params["previous_response_id"] = session["last_response_id"]
response = client.responses.create(**params)
# 中文说明:API 成功返回后再推进本地游标,失败时保留旧游标以便重试。
session["last_response_id"] = response.id
return response.output_text
生产代码还需要给 session 加上并发控制。例如同一个用户同时提交两条消息时,两个请求都读取到相同的旧 ID,就可能形成两个分支。可以采用数据库乐观锁、队列串行化,或明确允许分支并把每个分支单独命名。
什么时候应该改用 Conversations API
如果只是一个页面上的连续追问,previous_response_id 足够直观;如果要让会话跨设备、跨作业或长期存在,Conversations API 更容易表达真实的资源关系。官方文档描述的 conversation 可以保存消息、工具调用和工具输出等 item,后续 Responses 请求通过 conversation 继续使用它。
还有一种情况适合手动历史:你必须在发给模型前做敏感字段脱敏、按租户重排、按预算裁剪,或者要把历史迁移到另一套模型服务。此时应用掌握完整的可重放输入,会比依赖单条响应链更容易审计。
可以用下面的清单做选择:
- 只需把上一轮答案接到下一轮:使用
previous_response_id。 - 需要长期、跨设备管理一个会话资源:优先考虑 Conversations API。
- 需要脱敏、裁剪、重排或跨供应商迁移:自己保存并组装 input 历史。
- 无论选哪种方式,都单独保存业务会话身份、权限和失败恢复状态。
相关问题
previous_response_id 能代替业务数据库吗?
不能。它是 API 请求的上下文关联字段,不包含你的用户权限、租户归属、审计信息和业务状态。
下一轮是否必须再次传完整历史?
使用 previous_response_id 时不需要按手动历史方式重放全部输入,但链式上下文仍然会产生输入 token 成本;如果需要自定义裁剪,就改为手动管理历史。
为什么要保存最新 response.id 而不是首轮 ID?
因为每个响应都是链上的新节点。保存最新 ID 才能让下一轮从最近一次成功状态继续,而不是反复从旧节点分叉。
把 previous_response_id 看成“响应链指针”,而不是“万能会话开关”,多轮对话的设计就会清楚很多:短链路用它,长期资源用 Conversations API,需要控制上下文就自己维护历史。
VS Code launch 怎样给调试配置传递环境文件
- 上一篇
- VS Code launch 怎样给调试配置传递环境文件
- 下一篇
- Hugging Face PEFT 怎样用 LoRA 保存适配器而不保存底模
-
- 科技周边 · 人工智能 | 58分钟前 |
- vLLM 怎样设置连续批处理的并发上限
- 397浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face PEFT 怎样用 LoRA 保存适配器而不保存底模
- 357浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 | 模型评估 AI evaluation 事实性评分 格式评分
- AI evaluation 怎样区分事实性与格式性评分
- 119浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- RAG 怎样按文档版本过滤检索候选
- 346浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 | GenAI 可观测性 耗时 OpenTelemetry 模型调用 trace
- OpenTelemetry AI 怎样把模型调用耗时纳入 trace
- 101浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- ONNX Runtime 怎样选择 CPU 与 CUDA provider
- 246浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- Hugging Face Datasets 怎样用 cast_column 统一字段类型
- 118浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- Hugging Face tokenizer 怎样按 special tokens 判断截断边界
- 489浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- Hugging Face pipelines 怎样为批量推理设置 batch size
- 469浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 |
- OpenAI embeddings 怎样选择维度缩减参数
- 439浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 | 人工智能 · 结构化输出 · 结构化输出 JSON Schema OpenAI Responses API strict json_schema
- OpenAI Responses API 怎样用结构化输出约束 JSON 形状
- 168浏览 收藏
-
- 科技周边 · 人工智能 | 5小时前 | 人工智能 · 工具调用 · SSE 工具调用 OpenAI Responses API 流式事件 文本增量
- OpenAI Responses API 怎样区分文本增量与工具事件
- 239浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 671次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 690次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 735次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 701次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 539次使用
-
- Go语言restyhttp包调用jenkinsapi实例
- 2022-12-31 214浏览
-
- Go 1.25 testing.Attr 实战:别让 CI 测试报告只剩一堆失败日志
- 2026-06-02 478浏览
-
- Go 令牌桶限流实战:用 time.Ticker 保护高频接口
- 2026-06-13 484浏览
-
- Go 结构化日志库怎么选:标准库 slog、zap 与 zerolog 的取舍
- 2026-07-22 151浏览
-
- Go 1.26 的 go fix 怎么安全改造旧项目:从扫描到回归验证
- 2026-07-24 396浏览

