始终优先选择
Responses API 。它是 OpenAI 的旗舰 API,
也是体验最新模型行为、使用内置工具、
有状态工作流和智能体功能的最佳选择。
根据工作负载选择合适的 GPT-5.6 模型 ,
而不是将每个请求都路由到能力最强的档位。需要旗舰级能力时,使用 gpt-5.6 或
gpt-5.6-sol;希望以更低价格获得强劲性能时,使用 gpt-5.6-terra;
需要高效处理大量任务时,使用 gpt-5.6-luna。
迁移时,首次对比应保持当前模型在工作负载中承担的角色和实际推理强度不变。
在修改提示或添加新能力之前,先运行有代表性的评测。
对比任务成功情况、延迟、输入 Token 数、输出 Token 数、推理 Token 数、缓存写入 Token 数,
以及每项成功任务的成本。
使用 reasoning.effort 决定模型在回答前
应进行多少思考。
GPT-5.6 模型支持的值为 none、low、medium、high、
xhigh 和 max。默认值为 medium。较低的推理强度可提高速度,
减少推理 Token 用量。较高的推理强度则让模型有更多时间进行规划、
调试、综合分析以及多步骤权衡。
当任务主要涉及提取、路由、分类或
常规改写时,使用 low。当模型需要诊断问题、
比较方案、制定计划或分析代码逻辑时,使用 medium 或 high。只有当有代表性的评测表明,质量提升足以抵偿
额外的延迟和成本时,才使用 xhigh 或 max。
从 GPT-5.5 或 GPT-5.4 迁移时,先沿用
当前的推理强度,再将其与低一级的设置进行比较。GPT-5.6 通常能
以更少的推理 Token 保持或提高质量,因此较低的
设置也可能降低延迟和成本。
对于最复杂且以质量为先的工作负载,还应比较
reasoning.mode: "pro" 与
相同推理强度下的标准模式。推理模式和推理强度彼此独立。
Pro 模式可以让模型在返回一个最终答案前执行更多处理,
从而提高可靠性,但也会增加延迟和 Token 用量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import OpenAI from "openai";
const openai = new OpenAI();
const prompt = [
"Our CI job started failing after a dependency bump.",
"",
"Error:",
"TypeError: Timeout.__init__() got an unexpected keyword argument 'connect'",
"",
"Identify the likeliest root cause and the smallest safe fix.",
].join("\n");
const response = await openai.responses.create({
model: "gpt-6-astra",
reasoning: { effort: "xhigh", mode: "pro" },
input: prompt,
});
console.log(response.output_text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 from openai import OpenAI
client = OpenAI()
prompt = """
Our CI job started failing after a dependency bump.
Error:
TypeError: Timeout.__init__() got an unexpected keyword argument 'connect'
Identify the likeliest root cause and the smallest safe fix.
"""
response = client.responses.create(
model = "gpt-6-astra" ,
reasoning = { "effort" : "xhigh" , "mode" : "pro" },
input = prompt,
)
print (response.output_text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package main
import (
"context"
"fmt"
"strings"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
"github.com/openai/openai-go/v3/shared"
)
func main() {
client := openai.NewClient()
prompt := strings.Join([]string{
"Our CI job started failing after a dependency bump.",
"",
"Error:",
"TypeError: Timeout.__init__() got an unexpected keyword argument 'connect'",
"",
"Identify the likeliest root cause and the smallest safe fix.",
}, "\n")
reasoning := shared.ReasoningParam{Effort: shared.ReasoningEffortXhigh}
reasoning.SetExtraFields(map[string]any{"mode": "pro"})
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Reasoning: reasoning,
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String(prompt)},
})
if err != nil {
panic(err)
}
fmt.Println(response.OutputText())
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.Reasoning;
import com.openai.models.ReasoningEffort;
import com.openai.models.responses.ResponseCreateParams;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input(
"Our CI job started failing after a dependency bump. Error: TypeError: Timeout.__init__() got an unexpected keyword argument 'connect'. Identify the likeliest root cause and the smallest safe fix.")
.reasoning(
Reasoning.builder()
.effort(ReasoningEffort.XHIGH)
.putAdditionalProperty("mode", JsonValue.from("pro"))
.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())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 require "openai"
client = OpenAI::Client.new
prompt = <<~PROMPT
Our CI job started failing after a dependency bump.
Error:
TypeError: Timeout.__init__() got an unexpected keyword argument 'connect'
Identify the likeliest root cause and the smallest safe fix.
PROMPT
response = client.responses.create(
model: "gpt-6-astra",
reasoning: {
effort: :xhigh,
mode: :pro
},
input: prompt
)
puts(response.output_text)
设置 text.verbosity
text.verbosity 是平衡简洁性与完整性的主要调节项。
如果产品需要快速、简短的回答,请使用较低的详细程度;
如果回答需要更丰富的解释、更清晰的结构或
完整的上下文,请使用较高的详细程度。较低的详细程度意味着更少的输出 Token,
因此模型生成的内容更少,返回输出也更快。
对于编程任务,medium 和 high 通常会生成更长、更有条理、
结构更清晰的输出。low 则让回答更紧凑、更精简。
默认情况下,GPT-5.6 的回答往往比 GPT-5.5 更简洁。迁移时,请检查
“保持简洁”之类的宽泛指令是否仍然有帮助。在某些情况下,这些指令可能
让回答过于简短。仅在它们仍然有帮助时保留,并优先使用
text.verbosity 控制默认的详细程度;然后通过提示
指定必需的内容、结构,并在适用时给出更具体的长度要求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import OpenAI from "openai";
const openai = new OpenAI();
const incident = [
"Summarize this incident for the next on-call engineer.",
"- checkout latency spiked from 220 ms to 4.8 s",
"- only us-east-1 was affected",
"- rollback is complete",
"- likely trigger: cache stampede after deploy",
].join("\n");
const response = await openai.responses.create({
model: "gpt-6-astra",
text: { verbosity: "low" },
input: incident,
});
console.log(response.output_text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model = "gpt-6-astra" ,
text = { "verbosity" : "low" },
input = """
Summarize this incident for the next on-call engineer.
- checkout latency spiked from 220 ms to 4.8 s
- only us-east-1 was affected
- rollback is complete
- likely trigger: cache stampede after deploy
""" ,
)
print (response.output_text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package main
import (
"context"
"fmt"
"strings"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
incident := strings.Join([]string{
"Summarize this incident for the next on-call engineer.",
"- checkout latency spiked from 220 ms to 4.8 s",
"- only us-east-1 was affected",
"- rollback is complete",
"- likely trigger: cache stampede after deploy",
}, "\n")
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Text: responses.ResponseTextConfigParam{Verbosity: "low"},
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String(incident)},
})
if err != nil {
panic(err)
}
fmt.Println(response.OutputText())
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseTextConfig;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input(
"Summarize this incident for the next on-call engineer: checkout latency spiked from 220 ms to 4.8 s, only us-east-1 was affected, rollback is complete, and the likely trigger was a cache stampede.")
.text(ResponseTextConfig.builder().verbosity(ResponseTextConfig.Verbosity.LOW).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())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 require "openai"
client = OpenAI::Client.new
incident = <<~INCIDENT
Summarize this incident for the next on-call engineer.
- checkout latency spiked from 220 ms to 4.8 s
- only us-east-1 was affected
- rollback is complete
- likely trigger: cache stampede after deploy
INCIDENT
response = client.responses.create(
model: "gpt-6-astra",
text: { verbosity: :low },
input: incident
)
puts(response.output_text)
phase 是对话历史中助手消息的标签。
它向模型表明,先前的助手消息是工作过程中的
中间说明,还是最终答案。对于进度更新、
工具调用前的说明及其他中间消息,请使用 phase: "commentary"。
对于已完成的回答,请使用 phase: "final_answer"。
助手可能会这样说:
1
2
3
4
5 {
"role" : "assistant" ,
"phase" : "commentary" ,
"content" : "I'm checking the logs and comparing them to the last successful deploy."
}
这不是答案,而是一条进度说明。稍后,助手可能会说:
1
2
3
4
5 {
"role" : "assistant" ,
"phase" : "final_answer" ,
"content" : "The deploy failed because the migration referenced a column that does not exist in production."
}
在长时间运行或大量使用工具的工作流中,助手可能会在完成前
显示进度更新,此时这个参数很有用。在向 gpt-5.3-codex 及后续模型发送后续请求、
回传这段历史记录时,请在助手消息中
保留并重新发送 phase ,以便模型区分
进度更新和最终结果。这有助于减少提前停止的情况,
让智能体更有可能持续执行,直到得出最终回答。
无需在每个请求中加载完整的工具目录,您可以使用
工具搜索 :添加
{"type": "tool_search"},并用
defer_loading: true 标记加载成本较高的工具定义。这样,模型就可以在运行时仅加载所需的工具子集。
请求开始时,模型只能看到搜索工具的名称和描述。
如果模型判断需要某个延迟加载的工具,就会运行工具搜索,
此时才会将相应的工具定义加载到上下文中。只有完成加载后,
模型才会调用这些工具。这可以节省 Token,并保持缓存性能。
工具搜索有两种模式:
托管式工具搜索 是更简单的选择。如果您已经知道
当前请求可能使用哪些工具,就可以选择这种模式。
客户端执行的工具搜索 适用于应用需要自行决定
哪些工具可用的情况,例如根据用户的租户、项目、权限或
内部注册表来决定。
优先使用托管式工具搜索 ,除非您的应用确实需要
自行控制工具发现过程。
按用户意图对工具分组。尽可能使用命名空间或 MCP 服务器。
与冗长的扁平函数列表相比,几个划分清晰的分组更便于模型选择。
我们建议将每个命名空间的函数数量控制在约 10 个以下,
以实现最佳 Token 使用效率和模型性能。
命名空间的描述应简短,并能清楚区分各组工具。
将详细指令放在延迟加载的工具定义中。
避免将所有工具都放进一个庞大的命名空间。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 import OpenAI from "openai";
const openai = new OpenAI();
const billingNamespace = {
type: "namespace",
name: "billing",
description: "Billing tools for invoices, payments, taxes, and credits.",
tools: [
{
type: "function",
name: "lookup_invoice",
description:
"Look up invoice state, taxes, credits, and payment attempts.",
parameters: {
type: "object",
properties: {
invoice_id: { type: "string" },
},
required: ["invoice_id"],
additionalProperties: false,
},
strict: true,
defer_loading: true,
},
],
};
const crmNamespace = {
type: "namespace",
name: "crm",
description:
"CRM tools for account ownership, plans, health, and payment history.",
tools: [
{
type: "function",
name: "get_account",
description: "Fetch account owner, plan, health, and payment history.",
parameters: {
type: "object",
properties: {
account_id: { type: "string" },
},
required: ["account_id"],
additionalProperties: false,
},
strict: true,
defer_loading: true,
},
],
};
const response = await openai.responses.create({
model: "gpt-6-astra",
input:
"Find the right billing tool and explain why invoice INV-1043 still " +
"shows overdue after a payment yesterday.",
tools: [billingNamespace, crmNamespace, { type: "tool_search" }],
});
console.log(response.output); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 from openai import OpenAI
client = OpenAI()
billing_namespace = {
"type" : "namespace" ,
"name" : "billing" ,
"description" : "Billing tools for invoices, payments, taxes, and credits." ,
"tools" : [
{
"type" : "function" ,
"name" : "lookup_invoice" ,
"description" : "Look up invoice state, taxes, credits, and payment attempts." ,
"parameters" : {
"type" : "object" ,
"properties" : {
"invoice_id" : { "type" : "string" },
},
"required" : [ "invoice_id" ],
"additionalProperties" : False ,
},
"strict" : True ,
"defer_loading" : True ,
}
],
}
crm_namespace = {
"type" : "namespace" ,
"name" : "crm" ,
"description" : "CRM tools for account ownership, plans, health, and payment history." ,
"tools" : [
{
"type" : "function" ,
"name" : "get_account" ,
"description" : "Fetch account owner, plan, health, and payment history." ,
"parameters" : {
"type" : "object" ,
"properties" : {
"account_id" : { "type" : "string" },
},
"required" : [ "account_id" ],
"additionalProperties" : False ,
},
"strict" : True ,
"defer_loading" : True ,
}
],
}
response = client.responses.create(
model = "gpt-6-astra" ,
input = (
"Find the right billing tool and explain why invoice INV-1043 still "
"shows overdue after a payment yesterday."
),
tools = [billing_namespace, crm_namespace, { "type" : "tool_search" }],
)
print (response.output) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
billing := namespaceTool(
"billing",
"Billing tools for invoices, payments, taxes, and credits.",
"lookup_invoice",
"Look up invoice state, taxes, credits, and payment attempts.",
"invoice_id",
)
crm := namespaceTool(
"crm",
"CRM tools for account ownership, plans, health, and payment history.",
"get_account",
"Fetch account owner, plan, health, and payment history.",
"account_id",
)
toolSearch := responses.ToolUnionParam{OfToolSearch: &responses.ToolSearchToolParam{}}
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String(
"Find the right billing tool and explain why invoice INV-1043 still shows overdue after a payment yesterday.",
)},
Tools: []responses.ToolUnionParam{billing, crm, toolSearch},
})
if err != nil {
panic(err)
}
fmt.Println(response.Output)
}
func namespaceTool(namespace, namespaceDescription, name, description, argument string) responses.ToolUnionParam {
parameters := map[string]any{
"type": "object",
"properties": map[string]any{
argument: map[string]any{"type": "string"},
},
"required": []string{argument},
"additionalProperties": false,
}
function := responses.NamespaceToolToolFunctionParam{
Name: name, Description: openai.String(description), Parameters: parameters, Strict: openai.Bool(true), DeferLoading: openai.Bool(true),
}
return responses.ToolParamOfNamespace(
namespaceDescription,
namespace,
[]responses.NamespaceToolToolUnionParam{{OfFunction: &function}},
)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.responses.NamespaceTool;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ToolSearchTool;
import java.util.List;
import java.util.Map;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input(
"Find the right billing tool and explain why invoice INV-1043 still shows overdue after a payment yesterday.")
.addTool(
namespace(
"billing",
"Billing tools for invoices, payments, taxes, and credits.",
"lookup_invoice",
"Look up invoice state, taxes, credits, and payment attempts.",
"invoice_id"))
.addTool(
namespace(
"crm",
"CRM tools for account ownership, plans, health, and payment history.",
"get_account",
"Fetch account owner, plan, health, and payment history.",
"account_id"))
.addTool(ToolSearchTool.builder().execution(ToolSearchTool.Execution.SERVER).build())
.build();
client.responses().create(params).output().forEach(System.out::println);
private static NamespaceTool namespace(
String name,
String description,
String function,
String functionDescription,
String argument) {
return NamespaceTool.builder()
.name(name)
.description(description)
.addTool(
NamespaceTool.Tool.Function.builder()
.name(function)
.description(functionDescription)
.deferLoading(true)
.strict(true)
.parameters(
JsonValue.from(
Map.of(
"type",
"object",
"properties",
Map.of(argument, Map.of("type", "string")),
"required",
List.of(argument),
"additionalProperties",
false)))
.build())
.build();
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 require "openai"
def namespace_tool(name, description, function_name, function_description, argument)
{
type: :namespace,
name: name,
description: description,
tools: [
{
type: :function,
name: function_name,
description: function_description,
defer_loading: true,
strict: true,
parameters: {
type: "object",
properties: { argument => { type: "string" } },
required: [argument],
additionalProperties: false
}
}
]
}
end
client = OpenAI::Client.new
billing = namespace_tool(
"billing",
"Billing tools for invoices, payments, taxes, and credits.",
"lookup_invoice",
"Look up invoice state, taxes, credits, and payment attempts.",
"invoice_id"
)
crm = namespace_tool(
"crm",
"CRM tools for account ownership, plans, health, and payment history.",
"get_account",
"Fetch account owner, plan, health, and payment history.",
"account_id"
)
response = client.responses.create(
model: "gpt-6-astra",
input: "Find the right billing tool and explain why invoice INV-1043 still shows overdue after a payment yesterday.",
tools: [billing, crm, { type: :tool_search }]
)
puts(response.output)
程序化工具调用
让 GPT-5.6 能够编写 JavaScript,在托管运行时中调用符合条件的工具,
并精简其中间结果。它适用于范围明确的处理阶段:
代码可以对大量工具结果进行筛选、关联、排序、去重、合并或检查,
然后向模型返回更小的结构化结果。
添加 programmatic_tool_calling 工具,并为每个符合条件的工具启用此功能。
对于仅由程序调用的工具,使用 allowed_callers: ["programmatic"];
如果模型也可以直接调用该工具,则使用 allowed_callers: ["direct", "programmatic"]。
如果每次返回的结果都可能改变模型的下一步决策,
或某项操作需要审批,或最终回答必须保留
引用或原生产物,请继续使用直接调用。请在文档中说明工具的返回字段和出错时的行为,
以便模型无需先查看结果,就能编写正确的程序。
您的工具循环必须处理 program 和 program_output 项,以及
程序发出的 function_call 项及其对应的 function_call_output 项。
保留每个 call_id,并将函数调用的 caller 复制到其输出中,
以便服务恢复正确的程序。
同时测试 program_output 和助手的最终消息。即使程序结果正确,
最终回答仍可能不完整。请将其与采用直接工具调用的同一工作流进行比较,
评估任务完成情况、所需证据、Token 总量、延迟
和成本。
多智能体 是 GPT-5.6 的一项功能,
让根智能体能够将独立的工作分派给子智能体,
并综合它们的结果。如果您可以将研究、分析或实现工作
拆分成具体、范围明确、使用独立上下文且可并行运行的任务,就可以使用这项功能。
在请求中将 multi_agent.enabled 设为 true。对于 HTTP,请使用测试版
Responses SDK 中的 client.beta.responses,并将 responses_multi_agent=v1
传入 betas。对于原始 HTTP 或 WebSocket 连接,请发送
OpenAI-Beta: responses_multi_agent=v1。
多智能体处于测试阶段期间,各项的数据模式可能会发生变化。
对于简短任务、每一步都依赖前一步的有序任务链,
或需要写入同一可变资源的工作,优先使用单个智能体。
子智能体可能增加 Token 用量,因此建议先使用 max_concurrent_subagents 的默认值 3,
并衡量端到端的质量、延迟和成本。对于大量使用工具或长时间运行的
多智能体工作流,WebSocket 模式可以减少继续执行时的开销。
启用多智能体前,请考虑其当前限制:
不支持 /responses/compact、reasoning.summary 和 max_tool_calls。
服务器会自动压缩根智能体的上下文,
以及每个子智能体的上下文。
内置工具 是 API 的原生能力。
您无需自行构建每一个工具,可以让模型使用
已集成到 Responses API 中的工具。模型随后可以自行决定
何时使用这些工具。
OpenAI 不断增加新的原生工具,因此,只要内置工具适合您的工作流,就应优先使用。
原生工具无法满足任务需求时,再构建自定义工具。
当前的内置工具及相关工具选项包括:
网页搜索 :搜索网页以获取最新信息
文件搜索 :搜索已上传的文件或向量存储
代码解释器 :运行 Python,执行分析、数学计算、图表绘制
和文件处理
Shell :在托管容器或您自己的运行时中运行 Shell 命令
计算机使用 :通过截图、点击、输入
和滚动操作用户界面
图像生成 :生成或编辑图像
MCP/连接器 :将模型连接到外部服务和工具
技能 :附加可复用的指令包和工作流文件
应用补丁 :以结构化方式编辑代码
模型表现也是优先使用内置工具的另一个理由。内置工具符合我们后训练的数据分布,
也就是说,模型的训练和评测都围绕这些工具的形式、行为和输出展开。
与使用新工具相比,使用内置工具时,
OpenAI 模型能够更准确地选择工具、更顺畅地执行操作,
并减少失败。
压缩 是一种上下文工程工具:
它决定模型在多轮交互中继续保留哪些信息。
对于长时间运行的智能体,问题不只是是否会达到上下文上限。
旧消息、工具日志、重试记录和过时细节还会挤占
模型所需状态信息的空间。
压缩让您能够以可控的方式减小上下文,同时保留后续轮次所需的状态。
在达成重要里程碑后,例如完成一个调试阶段
或缩小根因范围,您可以压缩此前的上下文窗口,
再从压缩后的输出继续。这有助于模型保持良好表现,
因为下一轮将围绕重要状态展开,而不必带上每一段中间推理、
失败的命令和已过时的推理分支。
您可以通过两种方式使用压缩:
交由服务器处理 :如果您使用 previous_response_id,请启用
context_management 并设置 compact_threshold。
当对话变得过大时,服务器会自动进行压缩。
您仍然只需发送最新的用户消息。
自行处理 :如果您自行管理完整的输入数组,请调用
client.responses.compact()。它会返回一个更小的上下文窗口。
在下一次 responses.create() 调用中直接使用返回的输出。
不要编辑压缩后的输出。 它不是供人阅读的摘要,
而是帮助模型继续执行的机器状态。请将其原样传入后续请求,
再添加下一条用户消息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 import OpenAI from "openai";
import { toResponseInputItems } from "openai/lib/responses/ResponseInputItems";
const openai = new OpenAI();
// Full window collected from a long debugging session:
// user messages, assistant outputs, tool calls, and tool outputs.
const longWindow = sessionItems;
const compacted = await openai.responses.compact({
model: "gpt-6-astra",
input: longWindow,
});
const nextResponse = await openai.responses.create({
model: "gpt-6-astra",
store: false,
input: [
// Preserve replayable compacted items.
...toResponseInputItems(compacted.output),
{
type: "message",
role: "user",
content:
"We found the bad cache invalidation path. Write the fix plan " +
"and the verification checklist.",
},
],
});
console.log(nextResponse.output_text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 from openai import OpenAI
client = OpenAI()
# Full window collected from a long debugging session:
# user messages, assistant outputs, tool calls, and tool outputs.
long_window = session_items
compacted = client.responses.compact(
model = "gpt-6-astra" ,
input = long_window,
)
next_response = client.responses.create(
model = "gpt-6-astra" ,
store = False ,
input = [
* compacted.output, # Use compact output as-is.
{
"type" : "message" ,
"role" : "user" ,
"content" : (
"We found the bad cache invalidation path. Write the fix plan "
"and the verification checklist."
),
},
],
)
print (next_response.output_text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 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()
longWindow := []responses.ResponseInputItemUnionParam{
responses.ResponseInputItemParamOfMessage("Find the cache invalidation bug in this debugging session.", responses.EasyInputMessageRoleUser),
}
compacted, err := client.Responses.Compact(context.Background(), responses.ResponseCompactParams{
Model: "gpt-6-astra",
Input: responses.ResponseCompactParamsInputUnion{OfResponseInputItemArray: longWindow},
})
if err != nil {
panic(err)
}
input := append(outputAsInput(compacted.Output),
responses.ResponseInputItemParamOfMessage(
"We found the bad cache invalidation path. Write the fix plan and the verification checklist.",
responses.EasyInputMessageRoleUser,
),
)
nextResponse, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Store: openai.Bool(false),
Input: responses.ResponseNewParamsInputUnion{OfInputItemList: input},
})
if err != nil {
panic(err)
}
fmt.Println(nextResponse.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
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCompactParams;
import com.openai.models.responses.ResponseCompactionItemParam;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.ArrayList;
var compacted =
client
.responses()
.compact(
ResponseCompactParams.builder()
.model("gpt-6-astra")
.input("Find the cache invalidation bug in this debugging session.")
.build());
var input = new ArrayList<ResponseInputItem>();
for (var item : compacted.output()) {
item.message().map(ResponseInputItem::ofResponseOutputMessage).ifPresent(input::add);
item.reasoning().map(ResponseInputItem::ofReasoning).ifPresent(input::add);
item.compaction()
.map(
value ->
ResponseInputItem.ofCompaction(
ResponseCompactionItemParam.builder()
.id(value.id())
.encryptedContent(value.encryptedContent())
.build()))
.ifPresent(input::add);
}
input.add(
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content(
"We found the bad cache invalidation path. Write the fix plan and the verification checklist.")
.build()));
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.inputOfResponse(input)
.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())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 require "openai"
client = OpenAI::Client.new
long_window = [
{
role: :user,
content: "Find the cache invalidation bug in this debugging session."
}
]
compacted = client.responses.compact(
model: "gpt-6-astra",
input: long_window
)
input = compacted.output.dup
input << {
role: :user,
content: "We found the bad cache invalidation path. Write the fix plan and the verification checklist."
}
response = client.responses.create(
model: "gpt-6-astra",
store: false,
input: input
)
puts(response.output_text)
当请求复用相同的长前缀时,提示缓存 会自动降低延迟
和成本。将稳定不变的指令、
示例和参考资料放在前面,再放入随用户变化的动态
内容。保持工具定义及其顺序稳定,并在末尾追加新的对话
轮次,不要改写之前的上下文。
GPT-5.6 引入了显式提示缓存。隐式缓存仍是
默认方式,但 GPT-5.6 模型及后续模型系列还支持显式
缓存断点和请求级缓存策略。如果稳定前缀后面
跟着会变化的后缀,请在可复用内容的边界处添加显式 prompt_cache_breakpoint。
只有当请求应仅使用您提供的断点、
不使用任何隐式断点时,才将 prompt_cache_options.mode 设为 explicit。较早的模型
仍然仅使用自动提示缓存。
对于 GPT-5.6 模型及后续模型系列,缓存写入按
未缓存输入 Token 单价的 1.25 倍收费。记录 cached_tokens 和 cache_write_tokens,然后
比较写入量与后续缓存读取量,以衡量净成本并调整
断点位置。
对于 GPT-5.6 之前的模型,为共享可复用前缀的请求使用固定的 prompt_cache_key,
有助于将相关请求路由到同一缓存,
优化缓存命中率。对于流量较大的请求组,请遵循将流量分散到
更多键的指南 。
在 GPT-5.6 及后续模型中,prompt_cache_key 是可选的:即使不使用它,也能达到最佳
缓存命中率。您可以用它为客户、用户或工作空间
单独核算缓存。这样更便于向各方说明缓存 Token 用量
及相应费用。为每个客户分配一个不同的键,
并在该客户的相关请求中保持不变。使用不同的键还有助于
防止跨客户探测缓存命中情况。请参阅使用键
单独核算缓存 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import OpenAI from "openai";
const openai = new OpenAI();
const instructions = [
"You are the support agent for Acme.",
"Follow the Acme support policy and escalation rubric.",
"Use the same tone, safety rules, and tool plan for each ticket.",
].join("\n");
const response = await openai.responses.create({
model: "gpt-6-astra",
prompt_cache_key: "tenant-acme-support-agent",
instructions,
input: "Summarize the current escalation for the on-call lead.",
});
console.log(response.output_text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 from openai import OpenAI
client = OpenAI()
instructions = """
You are the support agent for Acme.
Follow the Acme support policy and escalation rubric.
Use the same tone, safety rules, and tool plan for each ticket.
"""
response = client.responses.create(
model = "gpt-6-astra" ,
prompt_cache_key = "tenant-acme-support-agent" ,
instructions = instructions,
input = "Summarize the current escalation for the on-call lead." ,
)
print (response.output_text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package main
import (
"context"
"fmt"
"strings"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
instructions := strings.Join([]string{
"You are the support agent for Acme.",
"Follow the Acme support policy and escalation rubric.",
"Use the same tone, safety rules, and tool plan for each ticket.",
}, "\n")
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
PromptCacheKey: openai.String("tenant-acme-support-agent"),
Instructions: openai.String(instructions),
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Summarize the current escalation for the on-call lead.")},
})
if err != nil {
panic(err)
}
fmt.Println(response.OutputText())
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.instructions(
"You are the support agent for Acme.\n"
+ "Follow the Acme support policy and escalation rubric.\n"
+ "Use the same tone, safety rules, and tool plan for each ticket.")
.input("Summarize the current escalation for the on-call lead.")
.promptCacheKey("tenant-acme-support-agent")
.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())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
CreateResponseOptions options = new()
{
Model = "gpt-6-astra",
PromptCacheKey = "tenant-acme-support-agent",
Instructions = "Follow the Acme support policy and escalation rubric.",
};
options.InputItems.Add(
ResponseItem.CreateUserMessageItem("Summarize the current escalation for the on-call lead.")
);
ResponseResult response = await client.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText()); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 require "openai"
client = OpenAI::Client.new
instructions = <<~INSTRUCTIONS
You are the support agent for Acme.
Follow the Acme support policy and escalation rubric.
Use the same tone, safety rules, and tool plan for each ticket.
INSTRUCTIONS
response = client.responses.create(
model: "gpt-6-astra",
prompt_cache_key: "tenant-acme-support-agent",
instructions: instructions,
input: "Summarize the current escalation for the on-call lead."
)
puts(response.output_text)
使用 reasoning.encrypted_content
GPT-5.6 可以在多次调用之间
保留推理 。
当任务的目标、假设和优先级
保持稳定时,使用 reasoning.context: "all_turns"。当之前的推理已不再相关,
且可能让模型固守过时的方法时,使用 current_turn。如果您省略
reasoning.context 或将其设为 auto,请检查响应中的
reasoning.context 字段,以确认实际生效的模式。
持久化推理
只有在之前的推理项可用时才会生效。对于已存储的响应,使用 previous_response_id。
如果您的零数据保留
(ZDR) 要求不允许
存储响应数据,加密的推理内容可以实现
无状态交接。
响应输出中的推理项默认包含加密的推理内容。
您可以通过每个推理项的
encrypted_content 属性访问这些加密的推理内容。您的应用无需理解
该值,只需原样保留返回的每个推理项,并在下一轮
将其回传,让模型可以利用它继续工作流。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 import OpenAI from "openai";
import { toResponseInputItems } from "openai/lib/responses/ResponseInputItems";
const openai = new OpenAI();
const history = [
{
role: "user",
content: "Investigate why invoice INV-1043 has mismatched tax totals.",
},
];
const first = await openai.responses.create({
model: "gpt-6-astra",
store: false,
reasoning: { effort: "medium", context: "current_turn" },
input: history,
});
history.push(...toResponseInputItems(first.output));
history.push({
role: "user",
content: "Now write the customer-facing explanation in plain English.",
});
const second = await openai.responses.create({
model: "gpt-6-astra",
store: false,
reasoning: { effort: "medium", context: "all_turns" },
input: history,
});
console.log(second.output_text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 from openai import OpenAI
client = OpenAI()
history = [
{
"role" : "user" ,
"content" : "Investigate why invoice INV-1043 has mismatched tax totals." ,
}
]
first = client.responses.create(
model = "gpt-6-astra" ,
store = False ,
reasoning = { "effort" : "medium" , "context" : "current_turn" },
input = history,
)
history.extend(item.model_dump( exclude = { "status" }) for item in first.output)
history.append(
{
"role" : "user" ,
"content" : "Now write the customer-facing explanation in plain English." ,
}
)
second = client.responses.create(
model = "gpt-6-astra" ,
store = False ,
reasoning = { "effort" : "medium" , "context" : "all_turns" },
input = history,
)
print (second.output_text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 package main
import (
"context"
"encoding/json"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
"github.com/openai/openai-go/v3/shared"
)
func main() {
client := openai.NewClient()
history := []responses.ResponseInputItemUnionParam{
responses.ResponseInputItemParamOfMessage("Investigate why invoice INV-1043 has mismatched tax totals.", responses.EasyInputMessageRoleUser),
}
first, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Store: openai.Bool(false),
Reasoning: shared.ReasoningParam{Effort: shared.ReasoningEffortMedium, Context: shared.ReasoningContextCurrentTurn},
Include: []responses.ResponseIncludable{responses.ResponseIncludableReasoningEncryptedContent},
Input: responses.ResponseNewParamsInputUnion{OfInputItemList: history},
})
if err != nil {
panic(err)
}
history = append(history, outputAsInput(first.Output)...)
history = append(history, responses.ResponseInputItemParamOfMessage(
"Now write the customer-facing explanation in plain English.",
responses.EasyInputMessageRoleUser,
))
second, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Store: openai.Bool(false),
Reasoning: shared.ReasoningParam{Effort: shared.ReasoningEffortMedium, Context: shared.ReasoningContextAllTurns},
Input: responses.ResponseNewParamsInputUnion{OfInputItemList: history},
})
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
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.Reasoning;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseIncludable;
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("Investigate why invoice INV-1043 has mismatched tax totals.")
.build()));
var first =
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.inputOfResponse(history)
.store(false)
.reasoning(
Reasoning.builder()
.effort(com.openai.models.ReasoningEffort.MEDIUM)
.putAdditionalProperty("context", JsonValue.from("current_turn"))
.build())
.addInclude(ResponseIncludable.of("reasoning.encrypted_content"))
.build());
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("Now write the customer-facing explanation in plain English.")
.build()));
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.inputOfResponse(history)
.store(false)
.reasoning(
Reasoning.builder()
.effort(com.openai.models.ReasoningEffort.MEDIUM)
.putAdditionalProperty("context", JsonValue.from("all_turns"))
.build())
.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())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 require "openai"
client = OpenAI::Client.new
history = [
{
role: :user,
content: "Investigate why invoice INV-1043 has mismatched tax totals."
}
]
first = client.responses.create(
model: "gpt-6-astra",
store: false,
reasoning: {
effort: :medium,
context: :current_turn
},
include: ["reasoning.encrypted_content"],
input: history
)
history.concat(first.output)
history << {
role: :user,
content: "Now write the customer-facing explanation in plain English."
}
second = client.responses.create(
model: "gpt-6-astra",
store: false,
reasoning: {
effort: :medium,
context: :all_turns
},
input: history
)
puts(second.output_text)
在 GPT-5.6 模型中,省略图像 detail 或使用 detail: "auto" 时,
尺寸处理方式与 original 相同。服务会保留输入图像的尺寸,
但如果任意一边超过 65,535 像素,则会缩小图像,
使其符合该限制。对于缩小后仍超过
30,000 个图像块上限 的图像,API 会拒绝处理,
而不会再次调整尺寸以满足该限制。因此,大图像可能消耗更多输入 Token,
并增加延迟。
根据任务选择合适的 detail 。
您可以调整图像尺寸,在精细视觉细节不重要时使用 low,
或使用 high 进行标准的高保真图像理解。
对于大尺寸、信息密集、对坐标敏感的图像处理任务,以及 OCR、定位或
视觉检查任务,如果更多细节有助于提高质量,请保留 original。部署前,请测量
最坏情况下的图像 Token 用量和延迟。
如果您的应用面向终端用户,请在每次请求中发送一个稳定的、
保护隐私的
safety_identifier 。
这有助于 OpenAI 检测滥用行为,也为您的团队提供一种稳定的方式,
用于追踪违反政策的行为。它还能降低个别用户的滥用行为
影响组织内其他用户访问的可能性。
请对用户的用户名或电子邮件地址进行哈希处理,不要直接发送可识别身份的信息。
对于未登录场景,请使用稳定的会话 ID。
对于可能耗时较长的请求,请使用 background=True 。
API 会启动一项作业并返回 ID,无需保持客户端连接。
您的应用可以轮询该作业,直到它完成、失败或
被取消。此模式适用于大型分析、长时间运行的工具调用,或需要状态查询
和重试机制的工作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 // Replace the illustrative IDs and URLs below with your own resource values.
import OpenAI from "openai";
const openai = new OpenAI();
const logBundleFileId = "file_123";
let job = await openai.responses.create({
model: "gpt-6-astra",
background: true,
store: false,
input: "Analyze this large log bundle and cluster the primary failure modes.",
tools: [
{
type: "code_interpreter",
container: {
type: "auto",
file_ids: [logBundleFileId],
},
},
],
});
while (["queued", "in_progress"].includes(job.status)) {
await new Promise((resolve) => setTimeout(resolve, 2000));
job = await openai.responses.retrieve(job.id);
}
console.log(job.output_text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 # Replace the illustrative IDs and URLs below with your own resource values.
from openai import OpenAI
import time
client = OpenAI()
log_bundle_file_id = "file_123"
job = client.responses.create(
model = "gpt-6-astra" ,
background = True ,
store = False ,
input = "Analyze this large log bundle and cluster the primary failure modes." ,
tools = [
{
"type" : "code_interpreter" ,
"container" : {
"type" : "auto" ,
"file_ids" : [log_bundle_file_id],
},
}
],
)
while job.status in { "queued" , "in_progress" }:
time.sleep( 2 )
job = client.responses.retrieve(job.id)
print (job.output_text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package main
import (
"context"
"fmt"
"time"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
tool := responses.ToolParamOfCodeInterpreter(responses.ToolCodeInterpreterContainerCodeInterpreterContainerAutoParam{
FileIDs: []string{"file_abc123"},
})
job, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Background: openai.Bool(true),
Store: openai.Bool(false),
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Analyze this large log bundle and cluster the primary failure modes.")},
Tools: []responses.ToolUnionParam{tool},
})
if err != nil {
panic(err)
}
for job.Status == responses.ResponseStatusQueued || job.Status == responses.ResponseStatusInProgress {
time.Sleep(2 * time.Second)
job, err = client.Responses.Get(context.Background(), job.ID, responses.ResponseGetParams{})
if err != nil {
panic(err)
}
}
fmt.Println(job.OutputText())
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseStatus;
import com.openai.models.responses.Tool;
String fileId = "file_abc123";
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input("Analyze this large log bundle and cluster the primary failure modes.")
.background(true)
.store(false)
.addCodeInterpreterTool(
Tool.CodeInterpreter.Container.CodeInterpreterToolAuto.builder()
.addFileId(fileId)
.build())
.build();
var response = client.responses().create(params);
while (response.status().filter(ResponseStatus.QUEUED::equals).isPresent()
|| response.status().filter(ResponseStatus.IN_PROGRESS::equals).isPresent()) {
Thread.sleep(1000);
response = client.responses().retrieve(response.id());
}
if (response.status().filter(ResponseStatus.COMPLETED::equals).isEmpty()) {
throw new IllegalStateException(
"Research ended with status: " + response.status().orElseThrow());
}
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())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 require "openai"
client = OpenAI::Client.new
job = client.responses.create(
model: "gpt-6-astra",
background: true,
store: false,
input: "Analyze this large log bundle and cluster the primary failure modes.",
tools: [
{
type: :code_interpreter,
container: {
type: :auto,
file_ids: ["file_abc123"]
}
}
]
)
while [:queued, :in_progress].include?(job.status)
sleep(2)
job = client.responses.retrieve(job.id)
end
puts(job.output_text)
您可以结合 stream=True 获取进度事件,但与普通请求相比,
首个事件可能需要更长时间才会到达。
从用户界面的角度看,后台模式传达的是:“任务正在运行;这是当前状态;
结果就绪后会显示在这里。”
WebSocket 模式 专为长时间运行、
需要大量工具调用的工作流而设计。在这种模式下,您保持持久连接打开,
每次只需发送新的输入项和 previous_response_id 即可继续。对于
包含 20 次或更多工具调用的运行,这种方式可将端到端
速度提高约 40%。
工作原理 :第一条消息与普通的 Responses 请求类似,包含
模型、指令、工具和用户输入。服务器以流式方式返回事件。
如果模型请求调用工具,您的应用就执行该工具。接下来,您无需发送新的
HTTP 请求,而是在同一个套接字上再发送一个 response.create 事件,其中包含
此前的 previous_response_id 和新的输入项。这就是延迟
降低的原因。使用普通 HTTP 时,每次后续交互都是一个全新的请求。在 WebSocket 模式下,
连接保持打开,最近一次响应的状态保留在
该连接的内存中,可随时复用。当下一轮从该响应继续时,
后端需要完成的准备工作就更少。
如果您的工作流是一次请求对应一个回答,请 继续使用 HTTP 。
如果您的工作流像智能体一样长时间运行,请尝试 WebSocket 模式。
单个 WebSocket 连接同一时间只能处理一个进行中的响应,
因此并行工作需要多个连接。目前,每个连接最长可持续 60 分钟。
继续交互时,previous_response_id 的语义与 HTTP 模式
相同,同时会使用连接本地缓存来保存最近一次响应。
注意:WebSocket 模式兼容 ZDR,因为您的数据不会写入磁盘,
只会存储在内存中。
Python 示例使用 pip install "openai[realtime]>=3.8.0"。
JavaScript 示例使用 npm install openai@^7.10.0 ws。
Ruby 示例使用 gem install openai async-websocket。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 import OpenAI from "openai";
import { ResponsesWS } from "openai/resources/responses/ws";
const openai = new OpenAI();
const ws = new ResponsesWS(openai);
ws.on("event", (event) => {
console.log(event.type);
if (
event.type === "response.completed" ||
event.type === "response.failed" ||
event.type === "response.incomplete"
) {
ws.close();
}
});
ws.on("error", (error) => {
console.error(error);
ws.close();
});
ws.send({
type: "response.create",
model: "gpt-6-astra",
store: false,
input: [
{
type: "message",
role: "user",
content: [
{
type: "input_text",
text:
"Find the flaky test in this run, call the tools you need, " +
"and keep going until you can explain the root cause.",
},
],
},
],
tools: [testLogTool, codeSearchTool],
}); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 from openai import OpenAI
client = OpenAI()
with client.responses.connect() as connection:
# Use the same typed parameters as client.responses.create(...).
connection.response.create(
model = "gpt-6-astra" ,
store = False ,
input = [
{
"type" : "message" ,
"role" : "user" ,
"content" : [
{
"type" : "input_text" ,
"text" : (
"Find the flaky test in this run, call the tools "
"you need, and keep going until you can explain "
"the root cause."
),
}
],
}
],
tools = [test_log_tool, code_search_tool],
)
first_event = connection.recv()
print (first_event.type) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 require "async"
require "openai"
require "json"
def wait_for_response(connection)
while (event = connection.receive)
case event.type.to_s
when "response.completed" then return event.response
when "response.failed", "response.incomplete", "error"
raise "Response failed: #{event.to_json}"
end
end
raise "Connection closed before the response finished"
end
test_log_tool = {
type: "function",
name: "search_test_logs",
description: "Search test logs.",
parameters: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
additionalProperties: false
},
strict: true
}
code_search_tool = {
type: "function",
name: "search_code",
description: "Search source code.",
parameters: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
additionalProperties: false
},
strict: true
}
client = OpenAI::Client.new
Sync do |task|
task.with_timeout(120) do
client.responses.connect(request_options: { timeout: 10 }) do |connection|
connection.response.create(
stream_id: "main", model: "gpt-6-astra", store: false,
input: [
{
role: "user",
content: "Find the flaky test in this run, call the tools you need, and keep going until you can explain the root cause."
}
],
tools: [test_log_tool, code_search_tool]
)
puts(JSON.pretty_generate(wait_for_response(connection).output.map(&:to_h)))
end
end
end
Responses API 是构建更智能、能力更强的 OpenAI 应用的基础。
它的真正优势在于,让开发者能够从一次性提示转向可持续运行、
使用工具并感知上下文的工作流,灵活应对任务的复杂性。
遵循本指南,可提升实际部署中的表现。