OpenAI API 部署检查清单

2026-11-09 16:23 更新

本清单整理部署中常被忽略、但能改善质量、成本、延迟与可靠性的设计。按实际负载逐项评测,不把全部功能机械地加入每个请求。

内容 预期影响
使用Responses API 质量, 成本, 延迟, 可靠性
为工作负载选择模型 质量, 成本, 延迟
设置推理力度reasoning.effort 质量, 成本, 延迟
在会话中调整推理力度 质量, 成本, 延迟
设置text.verbosity 质量, 成本, 延迟
设置助手消息phase参数 质量, 成本
使用tool_search 成本, 延迟
使用程序化工具调用 质量, 成本, 延迟
用多智能体并行工作 质量, 成本, 延迟
使用异步工具调用 延迟
使用内置工具 质量
使用上下文压缩 成本
优化提示缓存 延迟, 成本
使用reasoning.encrypted_content 质量, 延迟
有意识地设置图像细节 质量, 成本, 延迟
发送安全标识符 安全, 可靠性
处理偏离意图监控 安全, 可靠性
处理流量骤增与模型过载 可靠性
使用background=True 任务持续性
使用WebSocket模式 延迟
使用轮次中引导 质量

使用Responses API

优先从Responses开始。它提供最新模型行为、内置工具、状态工作流和智能体能力,是平台主要API。

为工作负载选择模型

对代表性任务评估GPT-6系列:Astra面向最高能力,GPT-6.1 Sol适合低于Astra成本的复杂编码与专业工作,Luna适合高效、可重复任务;不必所有请求都用最强模型。

迁移时尽量保留既有负载角色及有效推理力度。带工具的推理使用Responses;Astra和GPT-6.1 Sol的工具调用要求Responses;Sol和Luna在Chat Completions中仅reasoning_effort:"none"时支持函数调用。

推理力度不是none时,移除temperature、top_p、top_logprobs;Chat Completions还移除logprobs,Responses的include移除message.output_text.logprobs。先检查驻留资格及迁移兼容性。改提示词或功能前运行评测,比较成功率、延迟、输入/输出/推理/缓存写入词元和每次成功任务成本。

设置推理力度reasoning.effort

Astra、GPT-6.1 Sol、Sol、Luna支持low、medium、high、xhigh、max;Sol和Luna另支持none,Astra及GPT-6.1 Sol不支持none。力度低通常更快、推理词元更少;高力度增加规划、调试、综合与多步权衡时间。

提取、分类、路由、常规改写可从low开始;诊断、比较、规划和代码可用medium/high;只有代表性评测证明收益时才用xhigh/max。从minimal或none迁移到Astra/6.1 Sol时先试low;其他情况先保留既有力度,再按目标测试调整。

极难且质量优先的负载,可在相同力度下对比reasoning.mode:"pro"。模式与力度独立;Pro增加计算、延迟和词元,换取可能更高可靠性。

来源示例 1(javascript):

// [中文] 根据任务调整reasoning.effort;低力度减少推理开销,高力度需用评测证明收益。
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);

来源示例 2(python):

## [中文] 根据任务调整reasoning.effort;低力度减少推理开销,高力度需用评测证明收益。
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)

来源示例 3(go):

// [中文] 根据任务调整reasoning.effort;低力度减少推理开销,高力度需用评测证明收益。
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())
}

来源示例 4(java):

// [中文] 根据任务调整reasoning.effort;低力度减少推理开销,高力度需用评测证明收益。
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()));

来源示例 5(ruby):

## [中文] 根据任务调整reasoning.effort;低力度减少推理开销,高力度需用评测证明收益。
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)

在会话中调整推理力度

GPT-6标准单智能体模式可在下一用户消息前插入configuration_update,保持请求级reasoning.effort不变以保留前缀缓存。更新作用于下一响应并持续,直到后续更新覆盖。

不能与自动压缩或截断组合;/responses/compact拒绝含该项的历史。如需压缩,使用compaction_trigger,之后再添加新的更新。

设置text.verbosity

用输出详略在简洁与完整间平衡。低详略适合紧凑答案,可减少输出词元和生成时间;medium/high在代码任务中通常生成更完整、结构更清楚的内容。迁移时重新评估“保持简洁”等全局指令;默认详略优先用参数,提示词再规定必需内容、结构和长度。

结合提示最佳实践评估质量、费用、延迟,以及编码智能体的测试/验证。

来源示例 6(javascript):

// [中文] 用text.verbosity控制默认输出详略,保留提示词必需内容。
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);

来源示例 7(python):

## [中文] 用text.verbosity控制默认输出详略,保留提示词必需内容。
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)

来源示例 8(go):

// [中文] 用text.verbosity控制默认输出详略,保留提示词必需内容。
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())
}

来源示例 9(java):

// [中文] 用text.verbosity控制默认输出详略,保留提示词必需内容。
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()));

来源示例 10(ruby):

## [中文] 用text.verbosity控制默认输出详略,保留提示词必需内容。
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;完成回答使用final_answer。先看进度消息:

来源示例 11(json):

中间说明:我正在检查日志,并与上次成功部署对照。phase为commentary,不能当成最终回答。

{
  "role": "assistant",
  "phase": "commentary",
  "content": "I'm checking the logs and comparing them to the last successful deploy."
}

它不是最终答案,之后才有:

来源示例 12(json):

最终回答:部署失败,因为迁移引用了生产环境不存在的列。phase为final_answer。

{
  "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,帮助区分进度与最终结果、减少提前停止。

使用tool_search

工具搜索延迟加载完整工具定义:添加{"type":"tool_search"},并为需要延迟加载的工具设置defer_loading:true。初始只提供搜索工具的名称和描述,模型确定需要工具后才搜索并加载定义,再调用,可节省上下文词元并保护缓存。

已知潜在工具集合时,优先托管搜索;需要按租户、项目、权限或内部注册表决定工具可见性时,使用客户端执行的搜索。按用户意图分组,可用命名空间或MCP;每个命名空间建议约10个函数以内。组描述简短、易区分,详细指令放在延迟加载定义中,避免单个巨大命名空间。

来源示例 13(javascript):

// [中文] 注册tool_search并将工具defer_loading设为true,按需加载定义;示例工具由应用执行。
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);

来源示例 14(python):

## [中文] 注册tool_search并将工具defer_loading设为true,按需加载定义;示例工具由应用执行。
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)

来源示例 15(go):

// [中文] 注册tool_search并将工具defer_loading设为true,按需加载定义;示例工具由应用执行。
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}},
    )
}

来源示例 16(java):

// [中文] 注册tool_search并将工具defer_loading设为true,按需加载定义;示例工具由应用执行。
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();
}

来源示例 17(ruby):

## [中文] 注册tool_search并将工具defer_loading设为true,按需加载定义;示例工具由应用执行。
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)

使用程序化工具调用

Programmatic Tool Calling允许受支持模型在托管环境编写JavaScript,调用允许的工具,并先筛选、连接、排序、去重、汇总或检查大结果,再向模型返回小型结构化结果。

添加programmatic_tool_calling,逐工具配置allowed_callers:["programmatic"],或允许直接调用的["direct","programmatic"]。如果每个结果会改变下一步判断、动作需审批、最终答复需保留引用或原生附件,应保持直接调用。清楚说明工具返回字段和错误,以便模型无需先试一次才会编写程序。

工具循环需处理program、program_output和程序发出的function_call/function_call_output;保留call_id,并把调用的caller复制到输出,才能恢复正确程序。同时评测程序结果和最终助手答复,因为程序正确不保证最终回答完整;与直接调用对比成功率、证据、词元、时间和费用。

用多智能体并行工作

多智能体让支持的GPT-6等模型将独立、边界明确的研究、分析或实现交给子智能体,再综合结果。请求设multi_agent.enabled:true;HTTP使用Beta SDK的client.beta.responses及betas中的responses_multi_agent=v1;原始HTTP/WebSocket用OpenAI-Beta: responses_multi_agent=v1。Beta响应项结构可能变化。

短任务、顺序依赖链、频繁写共享状态更适合单智能体。子智能体会增加词元,先用默认并发3并评测。工具密集、长运行可考虑WebSocket。当前不支持/responses/compact、reasoning.summary和max_tool_calls,服务端会分别自动压缩根和每个子智能体。

使用异步工具调用

GPT-6函数或自定义工具设async:true时,应用执行慢工具期间模型可继续独立工作。应用仍负责执行、跟踪,在后续Responses请求用原call_id回传。它不用于内置工具或程序化工具调用;多智能体模式不能将异步工具与并行工具调用组合。完整流程见异步工具调用。

使用内置工具

原生能力符合任务时优先使用内置工具,未覆盖时再建自定义工具。可选项包括网页搜索、文件搜索、运行Python的代码解释器、托管或本地Shell、截图/点击/输入/滚动的计算机使用、图像生成、MCP/连接器、Skills指令与文件包、apply_patch结构化代码编辑。

原生工具形态、行为和输出用于模型后训练与评测,官方认为能改善工具选择、执行和故障率。这是产品说明,具体效果仍需评测。

使用上下文压缩

压缩决定跨轮保留哪些状态,避免旧消息、日志、重试与过时分支挤占上下文。完成调试阶段、缩小根因等里程碑后可压缩再继续。

使用previous_response_id时设置context_management和compact_threshold,服务端自动处理,后续仅发送新用户消息;自行管理输入数组时可调用client.responses.compact(),把完整返回输出原样交给下次create并追加新用户消息。不要编辑独立压缩输出:它是机器状态,不是供人改写的摘要。

来源示例 18(javascript):

// [中文] 将独立压缩返回的完整输出原样传入下一轮,不删除压缩状态。
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);

来源示例 19(python):

## [中文] 将独立压缩返回的完整输出原样传入下一轮,不删除压缩状态。
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)

来源示例 20(go):

// [中文] 将独立压缩返回的完整输出原样传入下一轮,不删除压缩状态。
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
}

来源示例 21(java):

// [中文] 将独立压缩返回的完整输出原样传入下一轮,不删除压缩状态。
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()));

来源示例 22(ruby):

## [中文] 将独立压缩返回的完整输出原样传入下一轮,不删除压缩状态。
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及以后支持显式断点和请求缓存策略,隐式缓存仍为默认。稳定前缀后有动态后缀时,在边界放prompt_cache_breakpoint;只有希望完全按显式断点时才用prompt_cache_options.mode:"explicit"。早期模型只有自动缓存。迁移时将prompt_cache_retention改为prompt_cache_options.ttl:"30m",见模型差异。

本页以默认缓存寿命说明GPT-5.6及以后写入费率为未缓存输入的1.25倍;应记录cached_tokens及cache_write_tokens,对照后续读取量判断净节省,再调整断点。不同寿命价格仍以完整缓存指南为准。

5.6之前模型可用稳定prompt_cache_key帮助相同前缀路由,提高命中;高流量组参考多键分流。5.6及以后该键可选,不提供也可获得良好命中;可为客户、用户、工作区划分独立缓存核算,每组保持稳定,并减少跨客户探测缓存命中的机会。见按键隔离核算。

来源示例 23(javascript):

// [中文] 为共享前缀设置稳定prompt_cache_key以隔离核算;不把键当作缓存命中保证。
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);

来源示例 24(python):

## [中文] 为共享前缀设置稳定prompt_cache_key以隔离核算;不把键当作缓存命中保证。
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)

来源示例 25(go):

// [中文] 为共享前缀设置稳定prompt_cache_key以隔离核算;不把键当作缓存命中保证。
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())
}

来源示例 26(java):

// [中文] 为共享前缀设置稳定prompt_cache_key以隔离核算;不把键当作缓存命中保证。
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()));

来源示例 27(csharp):

// [中文] 为共享前缀设置稳定prompt_cache_key以隔离核算;不把键当作缓存命中保证。
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());

来源示例 28(ruby):

## [中文] 为共享前缀设置稳定prompt_cache_key以隔离核算;不把键当作缓存命中保证。
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

支持模型可跨调用保留推理。目标、假设、优先级稳定用reasoning.context:"all_turns";旧推理不相关、可能锚定错误时用current_turn。省略或auto时检查响应字段确认实际模式。

只有先前推理项可用时才能延续。已存储响应可用previous_response_id;ZDR不能存储时,使用加密推理无状态传递。输出推理项默认含encrypted_content,应用无需理解,按原样保留并在下轮回传。

来源示例 29(javascript):

// [中文] 无状态轮次保留全部相关输出项,包括加密推理;应用无需解密。
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);

来源示例 30(python):

## [中文] 无状态轮次保留全部相关输出项,包括加密推理;应用无需解密。
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.to_dict() 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)

来源示例 31(go):

// [中文] 无状态轮次保留全部相关输出项,包括加密推理;应用无需解密。
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
}

来源示例 32(java):

// [中文] 无状态轮次保留全部相关输出项,包括加密推理;应用无需解密。
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()));

来源示例 33(ruby):

## [中文] 无状态轮次保留全部相关输出项,包括加密推理;应用无需解密。
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)

有意识地设置图像细节

detail默认auto,尺寸处理依模型。大图增加输入词元及延迟,先查模型尺寸行为。不需细节可缩图或用low;标准高保真用high;受支持模型的original适合密集大图、坐标、OCR、定位、视觉检查。上线前测最坏词元量、延迟及限制,见细节等级。

发送安全标识符

服务终端用户时,每次发送稳定且保护隐私的safety_identifier,帮助检测滥用、追踪违规,并降低单用户影响整个组织的机会。对用户名/邮箱做哈希,避免直接发送身份信息;匿名场景可用稳定会话ID。

处理偏离意图监控

GPT-6 Astra智能体工作流应处理偏离监控。收到403 misalignment_policy_violation后,停止该会话动作派发,不自动重试被阻断工作流;也处理流式错误,并检查可能已执行的操作。按需订阅safety.alert.created项目告警,但Webhook不能替代请求错误处理,具体自动中止范围见指南。

处理流量骤增与模型过载

先检查HTTP状态和error.code。429 slow_down遵守Retry-After,降流量后逐步恢复;503 server_is_overloaded也遵守等待后重试。无头时采用带随机抖动的指数退避并限制次数。账单、支出、配额错误需先处理原因,不能把所有429都当临时限流。见速率限制和错误代码。

使用background=True

后台模式适合大型分析、长工具运行或需要状态和重试的任务。服务端启动任务返回ID,应用轮询至成功、失败或取消:

来源示例 34(javascript):

// [中文] 创建background任务后轮询状态,区分成功、失败及取消;未实际运行。
// 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);

来源示例 35(python):

## [中文] 创建background任务后轮询状态,区分成功、失败及取消;未实际运行。
## 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)

来源示例 36(go):

// [中文] 创建background任务后轮询状态,区分成功、失败及取消;未实际运行。
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())
}

来源示例 37(java):

// [中文] 创建background任务后轮询状态,区分成功、失败及取消;未实际运行。
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()));

来源示例 38(ruby):

## [中文] 创建background任务后轮询状态,区分成功、失败及取消;未实际运行。
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显示进度,但首事件可能更慢。界面应明确显示运行状态,以及完成后呈现结果的位置。

使用WebSocket模式

WebSocket适合长运行、密集工具调用,用持久连接传新增输入和previous_response_id。官方在20次以上工具调用的工作流观察到端到端最多约快40%,这是来源经验,非每次保证。

首事件包含模型、指令、工具和用户输入;工具执行后,同一连接发送新response.create及上次ID。连接保持热状态可减少每轮HTTP建立与设置开销;一次请求一次回答仍可保留HTTP。

并行会话用不同stream_id并按它分派事件;一条连接最多16个活跃响应,同一流顺序运行,连接最长60分钟。每流最近响应缓存在连接内存中,续接语义与HTTP相同。来源说明其内存状态而非落盘支持ZDR,实际仍需核对数据要求。

来源SDK版本:Python openai[realtime]>=3.8.0,JavaScript openai@^7.10.0 ws,Ruby openai async-websocket,Go openai-go/v3@v3.96.0,Java openai-java:4.101.0,后两者支持原生Responses WebSocket。此处保留示例版本,未安装或运行。

来源示例 39(javascript):

// [中文] 在同一WebSocket用previous_response_id继续,工具结果仍由应用提供;需要相应SDK及连接环境。
import OpenAI from "openai";
import { ResponsesWS } from "openai/resources/responses/ws";

const testLogTool = {
  type: "function",
  name: "search_test_logs",
  description: "Search test logs for a query.",
  parameters: {
    type: "object",
    properties: { query: { type: "string" } },
    required: ["query"],
    additionalProperties: false,
  },
  strict: true,
};

const codeSearchTool = {
  type: "function",
  name: "search_code",
  description: "Search the codebase for a query.",
  parameters: {
    type: "object",
    properties: { query: { type: "string" } },
    required: ["query"],
    additionalProperties: false,
  },
  strict: true,
};

const openai = new OpenAI();
const ws = new ResponsesWS(openai);

try {
  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],
  });
  let completed = false;
  for await (const event of ws) {
    if (event.type === "error") throw event.error;
    if (event.type !== "message") continue;
    const message = event.message;
    if (message.type === "response.completed") {
      console.log(JSON.stringify(message.response.output));
      completed = true;
      break;
    }
    if (
      message.type === "response.failed" ||
      message.type === "response.incomplete"
    ) {
      throw new Error(JSON.stringify(message));
    }
  }
  if (!completed) {
    throw new Error("Connection closed before the response finished.");
  }
} finally {
  ws.close();
}

来源示例 40(python):

## [中文] 在同一WebSocket用previous_response_id继续,工具结果仍由应用提供;需要相应SDK及连接环境。
from openai import OpenAI
from openai.types.responses import FunctionToolParam

test_log_tool: FunctionToolParam = {
    "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: FunctionToolParam = {
    "type": "function",
    "name": "search_code",
    "description": "Search source code.",
    "parameters": {
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"],
        "additionalProperties": False,
    },
    "strict": True,
}

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],
    )
    for event in connection:
        if event.type == "response.completed":
            print(event.response.output)
            break
        if event.type in {"response.failed", "response.incomplete", "error"}:
            raise RuntimeError(event.to_json())
    else:
        raise RuntimeError("Connection closed before the response finished.")

来源示例 41(go):

// [中文] 在同一WebSocket用previous_response_id继续,工具结果仍由应用提供;需要相应SDK及连接环境。
tools := []responses.ToolUnionParam{}
for _, name := range []string{
    "search_test_logs",
    "search_code",
} {
    tools = append(tools, responses.ToolUnionParam{
        OfFunction: &responses.FunctionToolParam{
            Name:        name,
            Description: openai.String("Search for a query."),
            Parameters: map[string]any{
                "type": "object",
                "properties": map[string]any{
                    "query": map[string]any{
                        "type": "string",
                    },
                },
                "required": []string{
                    "query",
                },
                "additionalProperties": false,
            },
            Strict: openai.Bool(true),
        },
    })
}
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
client := openai.NewClient()
conn, err := client.Responses.Connect(ctx, responses.ResponseConnectionOptions{})
if err != nil {
    log.Fatal(err)
}
defer conn.Close()
if err := conn.Create(ctx, responses.ResponsesClientEventResponseCreateParam{
    Model: "gpt-6-astra",
    Store: openai.Bool(false),
    Input: responses.ResponsesClientEventResponseCreateInputUnionParam{
        OfString: openai.String("Find the flaky test in this run, call the tools you need, and keep going until you can explain the root cause."),
    },
    Tools: tools,
}); err != nil {
    log.Fatal(err)
}
response, err := conn.FinalResponse(ctx)
if err != nil {
    log.Fatal(err)
}
if response.Status != responses.ResponseStatusCompleted {
    log.Fatalf("Response ended with status %s", response.Status)
}
output := make([]json.RawMessage, 0, len(response.Output))
for _, item := range response.Output {
    output = append(output, json.RawMessage(item.RawJSON()))
}
if err := json.NewEncoder(os.Stdout).Encode(output); err != nil {
    log.Fatal(err)
}

来源示例 42(java):

// [中文] 在同一WebSocket用previous_response_id继续,工具结果仍由应用提供;需要相应SDK及连接环境。
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.responses.*;
import java.util.*;

var tools = new ArrayList<Tool>();
for (var name : List.of("search_test_logs", "search_code"))
  tools.add(
      Tool.ofFunction(
          FunctionTool.builder()
              .name(name)
              .description("Search for a query.")
              .strict(true)
              .parameters(
                  FunctionTool.Parameters.builder()
                      .putAdditionalProperty("type", JsonValue.from("object"))
                      .putAdditionalProperty(
                          "properties",
                          JsonValue.from(Map.of("query", Map.of("type", "string"))))
                      .putAdditionalProperty("required", JsonValue.from(List.of("query")))
                      .putAdditionalProperty("additionalProperties", JsonValue.from(false))
                      .build())
              .build()));

try (var conn = client.responses().connect()) {
  conn.send(
      ResponsesClientEvent.ofResponseCreate(
          ResponsesClientEvent.ResponseCreate.builder()
              .model("gpt-6-astra")
              .store(false)
              .input(
                  "Find the flaky test in this run, call the tools you need, and keep going until you can explain the root cause.")
              .tools(tools)
              .build()));
  var response = conn.finalResponse();
  if (response.status().filter(ResponseStatus.COMPLETED::equals).isEmpty())
    throw new IllegalStateException(
        "Response ended with status " + response.status().orElse(null));
  System.out.println(response.output());
}

来源示例 43(ruby):

## [中文] 在同一WebSocket用previous_response_id继续,工具结果仍由应用提供;需要相应SDK及连接环境。
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

使用轮次中引导

用户在GPT-6处理时补要求,可通过同一WebSocket发送response.steer,把活跃响应ID放入previous_response_id,并提供新用户输入。accepted只表示排队,继续读取后续事件;不会改写已送出的内容或撤销已启动工具。见完整事件流程。

最后说明

Responses把单次提示扩展为持久、可用工具、理解上下文的工作流。根据任务复杂度逐项采用并评测这些能力,才能判断实际部署收益。

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

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号