OpenAI API 会话状态

2026-11-06 18:37 更新

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数组词元、生成输出词元及规划回答的推理词元都计入窗口。超出窗口的生成内容可能被截断。

输入、输出与推理词元共同占用上下文窗口

可用上述词元工具预估消息量。

上下文压缩

详细操作见上下文压缩:

后续阅读

更多用例见OpenAI Cookbook:

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号