一律先使用
Responses API 。這是 OpenAI 的旗艦 API,
也是使用最新模型行為、內建工具、
具狀態工作流程與智慧體功能的最佳選擇。
依工作負載選擇合適的 GPT-5.6 模型 ,
不要將每個請求都送往能力最強的層級。需要旗艦級能力時,使用 gpt-5.6 或
gpt-5.6-sol;希望以較低價格獲得強大效能時,使用 gpt-5.6-terra;
需要高效處理大量工作的情境則使用 gpt-5.6-luna。
遷移時,首次比較應維持目前模型在工作負載中的角色,以及實際使用的推理強度。
在變更提示詞或新增能力之前,先執行具代表性的評估。
比較任務成功情況、延遲、輸入、輸出、推理與快取寫入的 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 時,請透過
Beta 版 Responses SDK 的 client.beta.responses,將 responses_multi_agent=v1
傳入 betas。若直接使用 HTTP 或 WebSocket 連線,請傳送
OpenAI-Beta: responses_multi_agent=v1。多智慧體處於 Beta 階段期間,
項目的結構描述可能會變更。
對於簡短任務、每一步都依賴前一步的循序流程,
或會寫入同一個可變動資源的工作,請優先使用單一智慧體。子代理程式可能增加
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,再
比較寫入量與後續的快取讀取量,以衡量淨成本並調整
斷點位置。
對於共用可重複使用前綴的請求,請使用穩定的 prompt_cache_key,
以協助將相關請求路由至同一個快取,並提升
GPT-5.6 之前模型的快取命中率。對於流量較大的群組,請遵循將流量分散至
更多索引鍵的指引 。
在 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 接收進度事件,但收到第一個事件的等待時間
可能比一般請求更長。
從 UI 的角度來看,背景模式傳達的是:「作業正在執行,這是目前的狀態;
結果準備好後會顯示在這裡。」
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 應用程式的基礎。
它真正的優勢在於,讓開發人員從一次性的提示詞,轉向能持續運作、使用工具並理解上下文的工作流程,
依任務的複雜程度調整運作方式。遵循本指南,讓實際部署的應用程式發揮更高效能。