OpenAI API 会话状态
OpenAI提供多种会话状态管理方式,用于在多条消息和多个轮次间保留信息。
排查GPT-5.5将中间更新误当最终回答的问题时,应确认集成正确保留助手消息的phase字段,参见phase参数。
手动管理会话状态
每次文本生成请求本身独立、无状态,但可在请求中传入更多历史消息实现多轮对话。以下以敲门笑话展示:
来源示例 1(javascript):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
import OpenAI from "openai";
const openai = new OpenAI();
const response = await openai.responses.create({
model: "gpt-6-astra",
input: [
{ role: "user", content: "knock knock." },
{ role: "assistant", content: "Who's there?" },
{ role: "user", content: "Orange." },
],
});
console.log(response.output_text);
来源示例 2(python):
## [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-6-astra",
input=[
{"role": "user", "content": "knock knock."},
{"role": "assistant", "content": "Who's there?"},
{"role": "user", "content": "Orange."},
],
)
print(response.output_text)
来源示例 3(go):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Input: responses.ResponseNewParamsInputUnion{
OfInputItemList: responses.ResponseInputParam{
responses.ResponseInputItemParamOfMessage("Knock knock.", responses.EasyInputMessageRoleUser),
responses.ResponseInputItemParamOfMessage("Who's there?", responses.EasyInputMessageRoleAssistant),
responses.ResponseInputItemParamOfMessage("Orange.", responses.EasyInputMessageRoleUser),
},
},
})
if err != nil {
panic(err)
}
fmt.Println(response.OutputText())
}
来源示例 4(java):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.List;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.inputOfResponse(
List.of(
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content("Knock knock.")
.build()),
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.ASSISTANT)
.content("Who's there?")
.build()),
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content("Orange.")
.build())))
.build();
client.responses().create(params).output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
来源示例 5(csharp):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
ResponseResult response = await client.CreateResponseAsync(
"gpt-6-astra",
[
ResponseItem.CreateUserMessageItem("Knock knock."),
ResponseItem.CreateAssistantMessageItem("Who's there?"),
ResponseItem.CreateUserMessageItem("Orange."),
]
);
Console.WriteLine(response.GetOutputText());
来源示例 6(ruby):
## [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
require "openai"
client = OpenAI::Client.new
response = client.responses.create(
model: "gpt-6-astra",
input: [
{
role: :user,
content: "Knock knock."
},
{
role: :assistant,
content: "Who's there?"
},
{
role: :user,
content: "Orange."
}
]
)
puts(response.output_text)
同页HTML还提供Chat Completions版本:
来源示例 29(javascript):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
import OpenAI from "openai";
const openai = new OpenAI();
const response = await openai.chat.completions.create({
model: "gpt-6-astra",
messages: [
{
role: "user",
content: "knock knock.",
},
{
role: "assistant",
content: "Who's there?",
},
{
role: "user",
content: "Orange.",
},
],
});
console.log(response.choices[0].message.content);
来源示例 30(python):
## [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-6-astra",
messages=[
{"role": "user", "content": "knock knock."},
{"role": "assistant", "content": "Who's there?"},
{"role": "user", "content": "Orange."},
],
)
print(response.choices[0].message.content)
来源示例 31(go):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
func main() {
client := openai.NewClient()
completion, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: "gpt-6-astra",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Knock knock."),
openai.AssistantMessage("Who's there?"),
openai.UserMessage("Orange."),
},
})
if err != nil {
panic(err)
}
fmt.Println(completion.Choices[0].Message.Content)
}
来源示例 32(java):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
ChatCompletionCreateParams params =
ChatCompletionCreateParams.builder()
.model("gpt-6-astra")
.addUserMessage("Knock knock.")
.addAssistantMessage("Who's there?")
.addUserMessage("Orange.")
.build();
client.chat().completions().create(params).choices().stream()
.flatMap(choice -> choice.message().content().stream())
.forEach(System.out::println);
来源示例 33(csharp):
// [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
using OpenAI.Chat;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-6-astra";
ChatClient client = new(model, key);
ChatCompletion completion = await client.CompleteChatAsync(
[
new UserChatMessage("Knock knock."),
new AssistantChatMessage("Who's there?"),
new UserChatMessage("Orange."),
]
);
Console.WriteLine(completion.Content[0].Text);
来源示例 34(ruby):
## [中文] 交替提交用户与助手消息;敲门笑话为“咚咚—谁呀—橙子”。
require "openai"
client = OpenAI::Client.new
completion = client.chat.completions.create(
model: "gpt-6-astra",
messages: [
{
role: :user,
content: "Knock knock."
},
{
role: :assistant,
content: "Who's there?"
},
{
role: :user,
content: "Orange."
}
]
)
puts(completion.choices.fetch(0).message.content)
交替传入user与assistant消息,就能在一次请求中重现之前的会话状态。跨次生成共享上下文时,把上一响应输出追加到历史输入,再用于下一次请求。
对无状态推理模型请求,保留output数组中的每一个项目。Responses默认返回加密推理项,完整重放输出可保留推理项及助手phase。支持持久推理的模型可用reasoning.context:"all_turns"将可用的前轮推理纳入下一次采样,参见跨调用保留推理。
以下先要求讲笑话,再要求另一个;追加历史输出使后续对话保留上下文。
来源示例 7(javascript):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
import OpenAI from "openai";
import { toResponseInputItems } from "openai/lib/responses/ResponseInputItems";
const openai = new OpenAI();
let history = [
{
role: "user",
content: "tell me a joke",
},
];
const response = await openai.responses.create({
model: "gpt-6-astra",
input: history,
store: false,
});
console.log(response.output_text);
// Add replayable output items, including reasoning items, to the history
history.push(...toResponseInputItems(response.output));
history.push({
role: "user",
content: "tell me another",
});
const secondResponse = await openai.responses.create({
model: "gpt-6-astra",
input: history,
store: false,
});
console.log(secondResponse.output_text);
来源示例 8(python):
## [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
from openai import OpenAI
client = OpenAI()
history = [{"role": "user", "content": "tell me a joke"}]
response = client.responses.create(
model="gpt-6-astra",
input=history,
store=False,
)
print(response.output_text)
## Add all response output items, including encrypted reasoning items, to the conversation
history += response.output
history.append({"role": "user", "content": "tell me another"})
second_response = client.responses.create(
model="gpt-6-astra",
input=history,
store=False,
)
print(second_response.output_text)
来源示例 9(go):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
history := responses.ResponseInputParam{
responses.ResponseInputItemParamOfMessage("tell me a joke", responses.EasyInputMessageRoleUser),
}
first, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Input: responses.ResponseNewParamsInputUnion{OfInputItemList: history},
Store: openai.Bool(false),
})
if err != nil {
panic(err)
}
fmt.Println(first.OutputText())
history = append(history, outputAsInput(first.Output)...)
history = append(history, responses.ResponseInputItemParamOfMessage("tell me another", responses.EasyInputMessageRoleUser))
second, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Input: responses.ResponseNewParamsInputUnion{OfInputItemList: history},
Store: openai.Bool(false),
})
if err != nil {
panic(err)
}
fmt.Println(second.OutputText())
}
func outputAsInput(output []responses.ResponseOutputItemUnion) []responses.ResponseInputItemUnionParam {
input := make([]responses.ResponseInputItemUnionParam, 0, len(output))
for _, item := range output {
var converted responses.ResponseInputItemUnion
if err := json.Unmarshal([]byte(item.RawJSON()), &converted); err != nil {
panic(err)
}
input = append(input, converted.ToParam())
}
return input
}
来源示例 10(java):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.ArrayList;
var history = new ArrayList<ResponseInputItem>();
history.add(
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content("Tell me a joke.")
.build()));
var first =
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.inputOfResponse(history)
.store(false)
.build());
first.output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
first.output().stream()
.map(item -> JsonValue.from(item).convert(ResponseInputItem.class))
.forEach(history::add);
history.add(
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content("Tell me another.")
.build()));
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.inputOfResponse(history)
.store(false)
.build())
.output()
.stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
来源示例 11(csharp):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
List<ResponseItem> history =
[
ResponseItem.CreateUserMessageItem("Tell me a joke."),
];
CreateResponseOptions options = new("gpt-6-astra", history)
{
StoredOutputEnabled = false,
IncludedProperties =
{
IncludedResponseProperty.ReasoningEncryptedContent,
},
};
ResponseResult first = await client.CreateResponseAsync(options);
Console.WriteLine(first.GetOutputText());
history.AddRange(first.OutputItems);
history.Add(ResponseItem.CreateUserMessageItem("Tell me another."));
options = new("gpt-6-astra", history)
{
StoredOutputEnabled = false,
IncludedProperties =
{
IncludedResponseProperty.ReasoningEncryptedContent,
},
};
ResponseResult second = await client.CreateResponseAsync(options);
Console.WriteLine(second.GetOutputText());
来源示例 12(ruby):
## [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
require "openai"
client = OpenAI::Client.new
history = [
{
role: :user,
content: "Tell me a joke."
}
]
first = client.responses.create(
model: "gpt-6-astra",
input: history,
store: false
)
puts(first.output_text)
history.concat(first.output)
history << {
role: :user,
content: "Tell me another."
}
second = client.responses.create(
model: "gpt-6-astra",
input: history,
store: false
)
puts(second.output_text)
Chat Completions历史消息版本:
来源示例 35(javascript):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
import OpenAI from "openai";
const openai = new OpenAI();
let history = [
{
role: "user",
content: "tell me a joke",
},
];
const completion = await openai.chat.completions.create({
model: "gpt-6-astra",
messages: history,
});
console.log(completion.choices[0].message.content);
history.push(completion.choices[0].message);
history.push({
role: "user",
content: "tell me another",
});
const secondCompletion = await openai.chat.completions.create({
model: "gpt-6-astra",
messages: history,
});
console.log(secondCompletion.choices[0].message.content);
来源示例 36(python):
## [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
from openai import OpenAI
client = OpenAI()
history = [{"role": "user", "content": "tell me a joke"}]
response = client.chat.completions.create(
model="gpt-6-astra",
messages=history,
)
print(response.choices[0].message.content)
history.append(response.choices[0].message)
history.append({"role": "user", "content": "tell me another"})
second_response = client.chat.completions.create(
model="gpt-6-astra",
messages=history,
)
print(second_response.choices[0].message.content)
来源示例 37(go):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
func main() {
client := openai.NewClient()
history := []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Tell me a joke."),
}
first, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: "gpt-6-astra",
Messages: history,
})
if err != nil {
panic(err)
}
fmt.Println(first.Choices[0].Message.Content)
history = append(history,
openai.AssistantMessage(first.Choices[0].Message.Content),
openai.UserMessage("Tell me another."),
)
second, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: "gpt-6-astra",
Messages: history,
})
if err != nil {
panic(err)
}
fmt.Println(second.Choices[0].Message.Content)
}
来源示例 38(java):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
var params =
ChatCompletionCreateParams.builder()
.model("gpt-6-astra")
.addUserMessage("Tell me a joke.")
.build();
var first = client.chat().completions().create(params);
first.choices().stream()
.flatMap(choice -> choice.message().content().stream())
.forEach(System.out::println);
var second =
client
.chat()
.completions()
.create(
params.toBuilder()
.addAssistantMessage(first.choices().get(0).message().content().orElseThrow())
.addUserMessage("Tell me another.")
.build());
second.choices().stream()
.flatMap(choice -> choice.message().content().stream())
.forEach(System.out::println);
来源示例 39(csharp):
// [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
using OpenAI.Chat;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-6-astra";
ChatClient client = new(model, key);
List<ChatMessage> messages = [new UserChatMessage("Tell me a joke.")];
ChatCompletion first = await client.CompleteChatAsync(messages);
Console.WriteLine(first.Content[0].Text);
messages.Add(new AssistantChatMessage(first));
messages.Add(new UserChatMessage("Tell me another."));
ChatCompletion second = await client.CompleteChatAsync(messages);
Console.WriteLine(second.Content[0].Text);
来源示例 40(ruby):
## [中文] 将完整响应输出追加到历史,再要求“再讲一个笑话”;Responses保留加密推理项与phase,Chat版本使用自己的消息结构。
require "openai"
client = OpenAI::Client.new
history = [
{
role: :user,
content: "Tell me a joke."
}
]
first = client.chat.completions.create(
model: "gpt-6-astra",
messages: history
)
puts(first.choices.fetch(0).message.content)
history << {
role: :assistant,
content: first.choices.fetch(0).message.content
}
history << {
role: :user,
content: "Tell me another."
}
second = client.chat.completions.create(
model: "gpt-6-astra",
messages: history
)
puts(second.choices.fetch(0).message.content)
用于会话状态的OpenAI API
平台可自动管理状态,减少逐轮手动传递输入。
使用Conversations API
Conversations API结合Responses API,把会话持久化为具有稳定标识符的长期对象,可跨会话、设备或任务继续使用。
会话存储的项目可包括消息、工具调用、工具输出及其他数据。创建会话:
来源示例 13(javascript):
// [中文] 创建持久Conversation对象,保存稳定会话ID。
const conversation = await client.conversations.create();
来源示例 14(python):
## [中文] 创建持久Conversation对象,保存稳定会话ID。
conversation = openai.conversations.create()
来源示例 15(go):
// [中文] 创建持久Conversation对象,保存稳定会话ID。
conversation, err := client.Conversations.New(context.Background(), conversations.ConversationNewParams{})
if err != nil {
panic(err)
}
来源示例 16(java):
// [中文] 创建持久Conversation对象,保存稳定会话ID。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
var conversation = client.conversations().create();
System.out.println(conversation.id());
来源示例 17(ruby):
## [中文] 创建持久Conversation对象,保存稳定会话ID。
conversation = client.conversations.create
之后在Responses请求中传入conversation,即可持续保存并共享上下文,无需手动串接每个响应项。
来源示例 18(javascript):
// [中文] 将conversation.id传给Responses;示例问题是躲避球的五个D。
const response = await client.responses.create({
model: "gpt-6-astra",
input: [{ role: "user", content: "What are the five Ds of dodgeball?" }],
conversation: conversation.id,
});
console.log(response.output_text);
来源示例 19(python):
## [中文] 将conversation.id传给Responses;示例问题是躲避球的五个D。
response = openai.responses.create(
model="gpt-6-astra",
input=[{"role": "user", "content": "What are the 5 Ds of dodgeball?"}],
conversation=conversation.id,
)
来源示例 20(go):
// [中文] 将conversation.id传给Responses;示例问题是躲避球的五个D。
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Conversation: responses.ResponseNewParamsConversationUnion{
OfString: openai.String(conversation.ID),
},
Input: responses.ResponseNewParamsInputUnion{
OfString: openai.String("What are the five Ds of dodgeball?"),
},
})
if err != nil {
panic(err)
}
fmt.Println(response.OutputText())
来源示例 21(java):
// [中文] 将conversation.id传给Responses;示例问题是躲避球的五个D。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
var conversation = client.conversations().create();
var response =
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.conversation(conversation.id())
.input("What are the five Ds of dodgeball?")
.build());
response.output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
来源示例 22(ruby):
## [中文] 将conversation.id传给Responses;示例问题是躲避球的五个D。
response = client.responses.create(
model: "gpt-6-astra",
conversation: conversation.id,
input: "What are the five Ds of dodgeball?"
)
puts(response.output_text)
传递上一响应的上下文
也可用previous_response_id串接响应,建立连续的多轮会话。
来源示例 23(javascript):
// [中文] 用previous_response_id续接前一个笑话并要求解释笑点;历史输入仍计费。
import OpenAI from "openai";
const openai = new OpenAI();
const response = await openai.responses.create({
model: "gpt-6-astra",
input: "tell me a joke",
store: true,
});
console.log(response.output_text);
const secondResponse = await openai.responses.create({
model: "gpt-6-astra",
previous_response_id: response.id,
input: [{ role: "user", content: "explain why this is funny." }],
store: true,
});
console.log(secondResponse.output_text);
来源示例 24(python):
## [中文] 用previous_response_id续接前一个笑话并要求解释笑点;历史输入仍计费。
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-6-astra",
input="tell me a joke",
)
print(response.output_text)
second_response = client.responses.create(
model="gpt-6-astra",
previous_response_id=response.id,
input=[{"role": "user", "content": "explain why this is funny."}],
)
print(second_response.output_text)
来源示例 25(go):
// [中文] 用previous_response_id续接前一个笑话并要求解释笑点;历史输入仍计费。
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
first, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Input: responses.ResponseNewParamsInputUnion{
OfString: openai.String("Tell me a joke."),
},
})
if err != nil {
panic(err)
}
fmt.Println(first.OutputText())
second, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
PreviousResponseID: openai.String(first.ID),
Input: responses.ResponseNewParamsInputUnion{
OfString: openai.String("Explain why this is funny."),
},
})
if err != nil {
panic(err)
}
fmt.Println(second.OutputText())
}
来源示例 26(java):
// [中文] 用previous_response_id续接前一个笑话并要求解释笑点;历史输入仍计费。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
var first =
client
.responses()
.create(
ResponseCreateParams.builder().model("gpt-6-astra").input("Tell me a joke.").build());
first.output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
var second =
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input("Explain why this is funny.")
.previousResponseId(first.id())
.build());
second.output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
来源示例 27(csharp):
// [中文] 用previous_response_id续接前一个笑话并要求解释笑点;历史输入仍计费。
using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
ResponseResult first = await client.CreateResponseAsync(
"gpt-6-astra",
"Tell me a joke."
);
Console.WriteLine(first.GetOutputText());
ResponseResult second = await client.CreateResponseAsync(
"gpt-6-astra",
"Explain why this is funny.",
previousResponseId: first.Id
);
Console.WriteLine(second.GetOutputText());
来源示例 28(ruby):
## [中文] 用previous_response_id续接前一个笑话并要求解释笑点;历史输入仍计费。
require "openai"
client = OpenAI::Client.new
first = client.responses.create(
model: "gpt-6-astra",
input: "Tell me a joke."
)
puts(first.output_text)
second = client.responses.create(
model: "gpt-6-astra",
previous_response_id: first.id,
input: "Explain why this is funny."
)
puts(second.output_text)
WebSocket模式中的previous_response_id
Responses WebSocket模式沿用HTTP的previous_response_id语义,但通过持久连接多次发送response.create。
连接内存缓存保留最近响应,减少续接延迟。使用stream_id时,每条通道可保留最新响应;谱系仍由previous_response_id决定,因此可从另一通道仍可访问的响应分叉。如果未缓存的ID无法解析,将previous_response_id设为null,连同完整上下文发起新一轮。
模型响应的数据保留
响应对象默认保存30天,可在日志或读取接口查看。创建时设置store=false可关闭该默认响应存储行为。
Conversation对象及其中项目不适用30天TTL;附加到会话的响应,其项目也会持久保存而不受该TTL限制。未经明确同意,OpenAI不使用API数据训练模型,详见数据说明。
即使用previous_response_id,链中历史输入词元仍按API输入词元计费;不等于省去历史上下文费用。
管理上下文窗口
上下文窗口是单次请求可使用的最大词元量,包含输入、输出和推理词元。上限见模型详情。
管理文本生成上下文
输入更复杂或轮次更多时,要同时考虑输出上限和上下文总量。词元是模型分析输入及组织输出的计量单位。
- 输出词元:模型生成的内容。不同模型有不同上限;来源举例
gpt-4o-2024-08-06最多16,384个输出词元。 - 上下文窗口:输入、输出及部分模型的推理词元之和;上述来源快照总窗口128k。该数字仅为来源模型示例,不是所有模型的统一上限。
附加大量上下文、数据或示例可能超限,输出也可能截断。可用基于tiktoken的词元工具查看文本计数。
对启用推理的Responses请求,例如来源的o1示例,input数组词元、生成输出词元及规划回答的推理词元都计入窗口。超出窗口的生成内容可能被截断。

可用上述词元工具预估消息量。
上下文压缩
详细操作见上下文压缩:
/responses的context_management与compact_threshold见服务端压缩。- 显式控制见独立压缩端点及
/responses/compact参考。
后续阅读
更多用例见OpenAI Cookbook:

TRAE-AI编程


更多建议: