Guia prático de decisões de projeto pouco exploradas que podem melhorar a qualidade, a velocidade e a confiabilidade da implantação e reduzir os custos.
Comece sempre pela API Responses. É a principal API da OpenAI e a melhor opção para acessar os comportamentos mais recentes dos modelos, ferramentas integradas, fluxos de trabalho que mantêm estado e recursos de agentes.
Escolha um modelo para a carga de trabalho
Avalie a família de modelos GPT-6 para a sua carga de trabalho. Use o gpt-6-astra quando precisar da maior capacidade, o gpt-6.1-sol para tarefas complexas de programação e atividades profissionais a um custo menor que o do Astra, e o gpt-6-luna para executar tarefas repetíveis com eficiência. Escolha o modelo que apresenta bons resultados em tarefas representativas, em vez de encaminhar todas as solicitações ao modelo mais capaz.
Ao migrar para o GPT-6, mantenha a função que o modelo atual desempenha na carga de trabalho e o esforço de raciocínio efetivamente usado, quando houver suporte. Use a API Responses para raciocínio com ferramentas. O GPT-6 Astra e o GPT-6.1 Sol exigem a API Responses para chamadas de ferramentas. O GPT-6 Sol e o GPT-6 Luna só aceitam chamadas de função em Chat Completions com reasoning_effort: "none". Quando o esforço de raciocínio for diferente de none, remova temperature, top_p e top_logprobs. Remova também logprobs das solicitações de Chat Completions e message.output_text.logprobs do array include da API Responses. Confira os critérios de elegibilidade para residência de dados antes de escolher um modelo ou nível de processamento. Consulte as orientações para migração de modelos para outras verificações de compatibilidade. Execute avaliações representativas antes de alterar prompts ou adicionar recursos. Compare a taxa de sucesso das tarefas, a latência, as quantidades de tokens de entrada, saída, raciocínio e gravação em cache, além do custo por tarefa concluída com sucesso.
Configure reasoning.effort
Use reasoning.effort para definir quanto o modelo deve raciocinar antes de responder.
O GPT-6 Astra, o GPT-6.1 Sol, o GPT-6 Sol e o GPT-6 Luna aceitam low, medium, high, xhigh e max. O GPT-6 Sol e o GPT-6 Luna também aceitam none, opção indisponível no GPT-6 Astra e no GPT-6.1 Sol. Um esforço menor acelera a resposta e consome menos tokens de raciocínio. Um esforço maior dá ao modelo mais tempo para planejar, depurar, sintetizar informações e ponderar alternativas em tarefas de várias etapas.
Use low quando a tarefa envolver principalmente extração, roteamento, classificação ou reescrita simples. Use medium ou high quando o modelo precisar diagnosticar um problema, comparar opções, elaborar um plano ou analisar a lógica de um código. Use xhigh ou max somente quando avaliações representativas mostrarem que o ganho de qualidade justifica a latência e o custo adicionais. Se estiver migrando de minimal, ou de none para o GPT-6 Astra ou o GPT-6.1 Sol, comece com low e compare os resultados. Nos demais casos, mantenha o esforço efetivamente usado hoje e teste as alterações em relação às suas metas de qualidade, latência e custo.
Para as cargas de trabalho mais difíceis em que a qualidade é a prioridade, compare também reasoning.mode: "pro" com o modo padrão, usando o mesmo esforço. O modo e o esforço de raciocínio são independentes. No modo Pro, o modelo trabalha mais antes de retornar uma única resposta final. Isso pode melhorar a confiabilidade, mas aumenta a latência e o consumo de tokens.
Ajuste o esforço de raciocínio à tarefa
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import 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
20from openai import OpenAIclient = 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
24import 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
22require "openai"client = OpenAI::Client.newprompt = <<~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.PROMPTresponse = client.responses.create( model: "gpt-6-astra", reasoning: { effort: :xhigh, mode: :pro }, input: prompt)puts(response.output_text)
Altere o esforço de raciocínio durante a conversa
Nos modelos GPT-6 em modo padrão com um único agente, adicione um item de entrada configuration_update antes da próxima mensagem do usuário para alterar o esforço entre respostas. Mantenha o valor de reasoning.effort da solicitação para que o prefixo original do prompt continue elegível para cache. A atualização passa a valer na próxima resposta e permanece em vigor até que outra a substitua. As atualizações de configuração são incompatíveis com a compactação ou o truncamento automáticos, e /responses/compact rejeita históricos que as contenham. Para compactar o histórico, inclua um item compaction_trigger e adicione uma nova atualização em seguida.
Configure text.verbosity
text.verbosity é o principal controle para equilibrar concisão e abrangência. Use um nível de detalhamento menor quando o produto precisar de uma resposta rápida e curta, e um nível maior quando a resposta exigir explicações mais detalhadas, uma estrutura mais clara ou contexto completo. Com menos detalhes, o modelo gera menos tokens de saída e retorna a resposta mais rápido.
Em tarefas de programação, medium e high tendem a produzir respostas mais longas, organizadas e com estrutura mais clara. Com low, a resposta fica mais enxuta.
Ao migrar, verifique se instruções genéricas como “Seja conciso” ainda ajudam. Prefira text.verbosity para controlar o nível de detalhe padrão e use o prompt para especificar o conteúdo, a estrutura e o tamanho necessários.
Reduza o nível de detalhamento para obter uma resposta mais curta
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import 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
17from openai import OpenAIclient = 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
30package mainimport ( "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
18import 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
18require "openai"client = OpenAI::Client.newincident = <<~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 deployINCIDENTresponse = client.responses.create( model: "gpt-6-astra", text: { verbosity: :low }, input: incident)puts(response.output_text)
Configure o parâmetro phase do assistente
phase é um rótulo nas mensagens do assistente no histórico da conversa. Ele indica ao modelo se uma mensagem anterior do assistente era um comentário sobre o trabalho em andamento ou a resposta final. Use phase: "commentary" para atualizações de progresso, observações antes de chamar ferramentas e outras mensagens intermediárias. Use phase: "final_answer" para a resposta concluída.
O assistente pode dizer algo assim:
Mensagem de comentário do assistente
1
2
3
4
5{"role": "assistant","phase": "commentary","content": "I'm checking the logs and comparing them to the last successful deploy."}
Essa mensagem informa o progresso. A resposta vem depois, quando o assistente pode dizer:
Mensagem de resposta final do assistente
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."}
Essa distinção é útil em fluxos de trabalho demorados ou com uso intenso de ferramentas, nos quais o assistente pode mostrar atualizações de progresso antes de terminar. Ao reenviar esse histórico em solicitações subsequentes para o gpt-5.3-codex e modelos posteriores, preserve e reenvie phase nas mensagens do assistente para que o modelo diferencie as atualizações de progresso do resultado final. Isso ajuda a reduzir as interrupções prematuras e aumenta a chance de o agente continuar até chegar à resposta final.
Use tool_search
Em vez de carregar todo o catálogo de ferramentas em cada solicitação, use a busca de ferramentas. Adicione {"type": "tool_search"} e marque com defer_loading: true as definições de ferramentas cujo carregamento tem custo elevado. Assim, o modelo pode carregar em tempo de execução apenas o subconjunto necessário. No início da solicitação, o modelo vê apenas o nome e a descrição da ferramenta de busca. Se decidir que precisa de uma ferramenta com carregamento adiado, o modelo executa a busca. Só então as definições adiadas são carregadas no contexto, e o modelo pode chamar essas ferramentas. Isso economiza tokens e preserva o desempenho do cache.
A busca de ferramentas tem dois modos:
Busca de ferramentas hospedada é a opção mais simples. Use-a quando já souber quais ferramentas podem estar disponíveis para a solicitação.
Busca de ferramentas executada pelo cliente é indicada quando o aplicativo precisa decidir quais ferramentas disponibilizar, por exemplo, com base no tenant, no projeto ou nas permissões do usuário, ou em um registro interno.
Comece pela busca de ferramentas hospedada, a menos que o próprio aplicativo precise controlar a descoberta.
Agrupe as ferramentas de acordo com a intenção do usuário. Sempre que possível, use um namespace ou um servidor MCP. Para o modelo, é mais fácil escolher entre alguns grupos bem definidos do que percorrer uma longa lista de funções sem agrupamento. Para otimizar o uso de tokens e o desempenho do modelo, recomendamos manter cada namespace abaixo de aproximadamente 10 funções.
Escreva descrições curtas que diferenciem os namespaces. Coloque as instruções detalhadas nas definições das ferramentas com carregamento adiado. Evite reunir tudo em um único namespace muito grande.
Use a busca hospedada com ferramentas de carregamento adiado
As chamadas programáticas de ferramentas permitem que os modelos compatíveis escrevam código JavaScript que chama ferramentas elegíveis e reduz o volume dos resultados intermediários em um ambiente de execução hospedado. Use esse recurso em etapas com escopo delimitado nas quais o código possa filtrar, cruzar, classificar, deduplicar, combinar ou verificar resultados volumosos das ferramentas antes de retornar ao modelo um resultado estruturado menor.
Adicione a ferramenta programmatic_tool_calling e habilite o recurso em cada ferramenta elegível. Use allowed_callers: ["programmatic"] para ferramentas que só podem ser chamadas por programas, ou allowed_callers: ["direct", "programmatic"] quando o modelo também puder chamar a ferramenta diretamente. Mantenha as chamadas diretas quando cada resultado puder mudar a próxima decisão do modelo, uma ação exigir aprovação ou a resposta final precisar preservar citações ou artefatos nativos. Documente os campos retornados pelas ferramentas e seu comportamento em caso de erro para que o modelo possa escrever um programa correto sem precisar examinar um resultado antes.
O loop de execução das ferramentas deve tratar os itens program e program_output, além dos itens function_call emitidos pelo programa e dos respectivos itens function_call_output. Preserve cada call_id e copie o campo caller da chamada de função para a saída correspondente para que o serviço retome o programa correto.
Teste tanto o program_output quanto a mensagem final do assistente. Mesmo com um resultado correto do programa, a resposta final pode ficar incompleta. Compare o sucesso das tarefas, as evidências necessárias, o total de tokens, a latência e o custo com os do mesmo fluxo usando chamadas diretas de ferramentas.
Use vários agentes para trabalhar em paralelo
O modo multiagente permite que os modelos compatíveis, incluindo os modelos GPT-6, deleguem frentes de trabalho independentes a subagentes e sintetizem os resultados. Use esse modo quando puder dividir uma pesquisa, análise ou implementação em tarefas concretas de escopo delimitado, cada uma com seu próprio contexto, que possam ser executadas em paralelo.
Defina multi_agent.enabled como true na solicitação. Para HTTP, use o SDK beta da API Responses com client.beta.responses e passe responses_multi_agent=v1 em betas. Para conexões HTTP diretas ou WebSocket, envie OpenAI-Beta: responses_multi_agent=v1. Os schemas dos itens podem mudar enquanto o modo multiagente estiver em beta.
Prefira um único agente para tarefas curtas, sequências em que cada etapa depende da anterior ou tarefas que gravam no mesmo recurso mutável. Os subagentes podem aumentar o consumo de tokens. Comece com o valor padrão de max_concurrent_subagents, que é 3, e meça a qualidade, a latência e o custo de ponta a ponta. Em fluxos multiagente demorados ou com uso intenso de ferramentas, o modo WebSocket pode reduzir o processamento adicional necessário para continuar a execução.
Antes de habilitar o modo multiagente, considere as limitações atuais. Não há suporte a /responses/compact, reasoning.summary nem max_tool_calls. O servidor compacta automaticamente o contexto do agente principal e o de cada subagente.
Use chamadas assíncronas de ferramentas
Nos modelos GPT-6, defina async: true em uma função ou ferramenta personalizada quando o modelo puder continuar trabalhando enquanto o aplicativo a executa. Inicie logo as chamadas de ferramentas mais demoradas e deixe o modelo cuidar das tarefas independentes. O aplicativo continua responsável por executar e acompanhar a chamada. Depois, ele retorna o resultado em uma nova solicitação à API Responses com o call_id original. A execução assíncrona não se aplica a ferramentas integradas nem a chamadas programáticas de ferramentas. No modo multiagente, não combine ferramentas assíncronas com chamadas paralelas de ferramentas. Consulte o fluxo completo em chamadas assíncronas de ferramentas.
Use ferramentas integradas
As ferramentas integradas são recursos nativos da API. Em vez de criar cada ferramenta por conta própria, você pode dar ao modelo acesso a ferramentas que já funcionam na API Responses. O modelo pode então decidir quando usá-las.
A OpenAI continua adicionando ferramentas nativas. Comece pelas integradas quando elas atenderem às necessidades do fluxo de trabalho. Crie ferramentas personalizadas quando as opções nativas não cobrirem a tarefa. Entre as ferramentas integradas e as opções relacionadas disponíveis hoje estão:
Pesquisa na Web: pesquise informações atualizadas na Web
Busca em arquivos: pesquise em arquivos enviados ou repositórios de vetores
Code Interpreter: execute Python para fazer análises e cálculos, gerar gráficos e processar arquivos
Shell: execute comandos de shell em um contêiner hospedado ou no seu próprio ambiente de execução
Uso do computador: interaja com uma interface por meio de capturas de tela, cliques, digitação e rolagem
Geração de imagens: gere ou edite imagens
MCP/conectores: conecte o modelo a serviços e ferramentas externos
Habilidades: anexe conjuntos reutilizáveis de instruções e arquivos de fluxo de trabalho
Aplicação de patches: faça alterações estruturadas no código
A qualidade do modelo é outro motivo para preferir essas ferramentas. As ferramentas integradas fazem parte da distribuição usada no pós-treinamento. Isso significa que treinamos e avaliamos os modelos com os formatos, comportamentos e saídas dessas ferramentas. Com elas, os modelos da OpenAI escolhem melhor as ferramentas, executam as chamadas de forma mais precisa e apresentam menos falhas do que com ferramentas novas.
Use a compactação
A compactação é uma ferramenta de engenharia de contexto que determina quais informações o modelo leva adiante ao longo de vários turnos. Em agentes que trabalham por longos períodos, a questão vai além de saber se o modelo vai atingir o limite de contexto. Mensagens antigas, logs de ferramentas, novas tentativas e detalhes desatualizados acabam ocupando o espaço das informações de estado de que o modelo precisa.
Com a compactação, você pode reduzir o tamanho do contexto de forma controlada e preservar o estado necessário para os próximos turnos. Ao atingir um marco importante, como concluir uma etapa de depuração ou restringir as possíveis causas de uma falha, você pode compactar a janela anterior e continuar a partir da saída compactada. Assim, o modelo mantém o foco porque o próximo turno parte do estado relevante, sem precisar retomar cada raciocínio intermediário, comando que falhou ou linha de raciocínio já descartada.
Você pode usar a compactação de duas maneiras:
Delegue ao servidor: se usar previous_response_id, habilite context_management com um compact_threshold. O servidor compactará automaticamente a conversa quando ela ficar grande demais. Continue enviando apenas a mensagem mais recente do usuário.
Gerencie a compactação no aplicativo: se você gerenciar todo o array de entrada, chame client.responses.compact(). A chamada retorna uma janela de contexto menor. Use a saída retornada diretamente na próxima chamada a responses.create().
Não edite a saída compactada. Ela contém o estado de máquina que permite ao modelo continuar, e não um resumo para leitura humana. Encaminhe-a exatamente como foi recebida e acrescente a próxima mensagem do usuário.
Continue a partir do estado compactado da resposta
Python
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
31import 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
30from openai import OpenAIclient = OpenAI()# Full window collected from a long debugging session:# user messages, assistant outputs, tool calls, and tool outputs.long_window = session_itemscompacted = 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
27require "openai"client = OpenAI::Client.newlong_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.dupinput << { 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)
Otimize o cache de prompts
O cache de prompts reduz automaticamente a latência e o custo quando as solicitações reutilizam o mesmo prefixo longo. Coloque primeiro as instruções, os exemplos e os materiais de referência que permanecem estáveis. Depois, acrescente o conteúdo dinâmico específico de cada usuário. Mantenha estáveis as definições e a ordem das ferramentas e acrescente novos turnos da conversa sem reescrever o contexto anterior.
O GPT-5.6 introduziu o cache de prompts explícito. O cache implícito continua sendo o padrão, mas os modelos GPT-5.6 e as famílias posteriores também aceitam pontos de corte explícitos e uma política de cache para toda a solicitação. Se um sufixo variável vier depois de um prefixo estável, adicione um prompt_cache_breakpoint explícito no fim da parte reutilizável. Defina prompt_cache_options.mode como explicit somente quando a solicitação precisar usar exclusivamente os pontos de corte que você fornecer, sem nenhum ponto de corte implícito. Os modelos anteriores continuam usando apenas o cache de prompts automático.
Ao migrar do GPT-5.5 ou de versões anteriores, substitua prompt_cache_retention por prompt_cache_options.ttl: "30m". Consulte as diferenças no cache de prompts entre modelos antes de alterar as configurações de cache.
Nos modelos GPT-5.6 e nas famílias posteriores, o preço por token gravado no cache equivale a 1,25 vez o preço por token de entrada sem cache. Registre cached_tokens e cache_write_tokens e compare o volume gravado com as leituras posteriores do cache para medir o custo líquido e ajustar a posição dos pontos de corte.
Use uma prompt_cache_key estável para solicitações que compartilham um prefixo reutilizável. Isso ajuda a encaminhar solicitações relacionadas ao mesmo cache e a otimizar a taxa de acertos do cache nos modelos anteriores ao GPT-5.6. Para grupos com muito tráfego, siga as orientações para distribuir o tráfego entre mais chaves.
No GPT-5.6 e nos modelos posteriores, prompt_cache_key é opcional. É possível atingir uma taxa ideal de acertos do cache sem essa chave. Você pode usá-la para contabilizar o uso do cache separadamente por cliente, usuário ou workspace. Isso facilita a explicação do consumo de tokens em cache e da cobrança para cada grupo. Atribua uma chave distinta a cada cliente e use a mesma chave nas solicitações relacionadas desse cliente. Chaves separadas também ajudam a impedir que um cliente teste se o conteúdo de outro está em cache. Consulte Contabilização separada do cache com chaves.
Contabilize o uso do cache separadamente por cliente
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import 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
18from openai import OpenAIclient = 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
29package mainimport ( "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
20import 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
18using OpenAI.Responses;#pragma warning disable OPENAI001string 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
17require "openai"client = OpenAI::Client.newinstructions = <<~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.INSTRUCTIONSresponse = 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)
Use reasoning.encrypted_content
Os modelos compatíveis, incluindo os modelos GPT-6, podem preservar o raciocínio entre chamadas. Use reasoning.context: "all_turns" quando os objetivos, as premissas e as prioridades da tarefa permanecerem estáveis. Use current_turn quando o raciocínio anterior perder a relevância e puder prender o modelo a uma abordagem ultrapassada. Se você omitir reasoning.context ou definir seu valor como auto, confira o campo reasoning.context da resposta para confirmar o modo efetivamente usado.
A persistência do raciocínio só funciona quando os itens de raciocínio anteriores estão disponíveis. Use previous_response_id para respostas armazenadas. Se seus requisitos de zero retenção de dados (ZDR) impedirem o armazenamento de dados das respostas, o conteúdo de raciocínio criptografado permite dar continuidade ao trabalho sem manter estado no servidor.
Por padrão, os itens de raciocínio na saída da resposta incluem o conteúdo de raciocínio criptografado. Você pode acessá-lo pela propriedade encrypted_content de cada item de raciocínio. O aplicativo não precisa interpretar esse valor. Basta manter cada item de raciocínio exatamente como foi retornado e reenviá-lo no turno seguinte para que o modelo possa continuar o fluxo de trabalho.
Transmita o raciocínio criptografado entre turnos sem estado
O valor padrão de detail para imagens é auto, e o dimensionamento depende do modelo. Imagens grandes podem consumir mais tokens de entrada e aumentar a latência. Consulte a tabela de dimensionamento dos modelos listados e, antes da implantação, meça o consumo de tokens das imagens e verifique os limites do modelo escolhido.
Escolha o valor de detail de acordo com a tarefa. Redimensione a imagem, use low quando os detalhes visuais mais finos forem dispensáveis ou use high para a análise padrão de imagens em alta fidelidade. Quando houver suporte, use original para imagens grandes ou densas, tarefas que exigem precisão nas coordenadas, OCR, localização ou inspeção visual, se os detalhes adicionais melhorarem a qualidade. Antes da implantação, meça o consumo de tokens das imagens e a latência no pior cenário.
Envie um identificador de segurança
Se o aplicativo atender usuários finais individuais, envie em cada solicitação um safety_identifier estável que preserve a privacidade. Ele ajuda a OpenAI a detectar uso indevido e oferece à sua equipe uma forma consistente de rastrear violações de políticas. Também reduz a chance de que o uso indevido por uma pessoa prejudique o acesso do restante da organização.
Em vez de enviar informações de identificação, calcule e envie o hash do nome de usuário ou do endereço de e-mail. Quando o usuário não estiver conectado à conta, use um ID de sessão estável.
Trate os eventos de monitoramento de desalinhamento
Nos fluxos de trabalho com agentes GPT-6 Astra, prepare o aplicativo para o monitoramento de desalinhamento. Se uma solicitação retornar 403 com misalignment_policy_violation, pare de enviar ações para essa conversa e não tente executar novamente o fluxo bloqueado de forma automática. Trate também os erros durante o streaming e revise todas as ações que possam já ter sido executadas. Assine o evento safety.alert.created se a equipe precisar de alertas do projeto. O webhook não substitui o tratamento de erros nas solicitações. Consulte o guia para saber quais solicitações da API Responses podem ser interrompidas automaticamente.
Trate picos de tráfego e sobrecarga do modelo
Confira o status HTTP e o error.code antes de escolher uma ação de recuperação. Um 429 com slow_down indica que a taxa de solicitações aumentou rápido demais. Respeite Retry-After quando presente, reduza o tráfego e volte a aumentá-lo gradualmente. Um 503 com server_is_overloaded indica que o modelo solicitado está temporariamente sobrecarregado. Respeite Retry-After quando presente e tente novamente. Na ausência do cabeçalho, aumente exponencialmente o intervalo entre tentativas, com uma variação aleatória, e limite o número de tentativas. Erros de cobrança, gastos ou cota exigem providências antes de uma nova tentativa. Não trate todo 429 como um limite de taxa temporário. Consulte os limites de taxa e os códigos de erro.
Use background=True
Use background=True para solicitações que podem demorar. Em vez de manter a conexão do cliente aberta, a API inicia uma tarefa e retorna um ID. O aplicativo pode consultar periodicamente a tarefa até que ela termine, falhe ou seja cancelada. Use esse modo para análises extensas, execuções demoradas de ferramentas ou trabalhos em que seja preciso acompanhar o status e fazer novas tentativas.
Execute uma resposta em segundo plano e consulte seu status
Python
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 OpenAIimport timeclient = 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)
Você pode combiná-lo com stream=True para receber eventos de progresso, mas o primeiro evento pode demorar mais do que em uma solicitação normal.
Na interface, o modo em segundo plano comunica ao usuário: “A tarefa está em andamento. Acompanhe o status aqui. O resultado aparecerá aqui quando estiver pronto.”
Use o modo WebSocket
O modo WebSocket foi desenvolvido para fluxos de trabalho demorados com muitas chamadas de ferramentas. Você mantém uma conexão persistente aberta e dá continuidade ao fluxo enviando apenas os novos itens de entrada e previous_response_id. Em fluxos com 20 ou mais chamadas de ferramentas, observamos execuções de ponta a ponta até cerca de 40% mais rápidas.
Como funciona: a primeira mensagem se parece com uma solicitação normal à API Responses e inclui modelo, instruções, ferramentas e entrada do usuário. O servidor retorna eventos por streaming. Se o modelo solicitar uma ferramenta, o aplicativo a executa. Em seguida, em vez de fazer outra solicitação HTTP, você envia um novo evento response.create pelo mesmo socket com o previous_response_id da resposta anterior e o novo item. É isso que reduz a latência. Com HTTP convencional, cada continuação exige uma nova solicitação. No modo WebSocket, a conexão permanece aberta e o estado da resposta mais recente fica disponível na memória dessa conexão. Quando o próximo turno dá continuidade à resposta, o serviço precisa de menos processamento para retomá-la.
Se o fluxo consiste em uma solicitação e uma resposta, continue usando HTTP. Se o fluxo funciona como um agente de longa duração, experimente o modo WebSocket.
Use valores distintos de stream_id para conversas paralelas na mesma conexão e encaminhe os eventos intercalados de acordo com o stream_id. Uma conexão aceita até 16 respostas ativas, e as solicitações no mesmo fluxo são executadas em ordem. As conexões duram até 60 minutos. Para continuar uma resposta, previous_response_id funciona da mesma forma que no modo HTTP, com um cache local à conexão para a resposta mais recente de cada fluxo.
Observação: o modo WebSocket funciona com ZDR porque os dados ficam apenas na memória, sem gravação em disco.
O exemplo em Python usa pip install "openai[realtime]>=3.8.0".
O exemplo em JavaScript usa npm install openai@^7.10.0 ws.
O exemplo em Ruby usa gem install openai async-websocket.
Para Go, execute go get github.com/openai/openai-go/v3@v3.98.0.
Para Java, adicione a dependência Maven com.openai:openai-java:4.101.0.
Essas versões dos SDKs de Go e Java oferecem suporte nativo a WebSocket na API Responses.
Inicie uma sessão WebSocket na API Responses
Python
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76import 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();}
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
61from openai import OpenAIfrom openai.types.responses import FunctionToolParamtest_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)breakif event.type in {"response.failed", "response.incomplete", "error"}:raiseRuntimeError(event.to_json())else:raiseRuntimeError("Connection closed before the response finished.")
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
40import 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());}
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
58require "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"endtest_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.newSync 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 endend
Envie novas instruções durante o turno
Se os usuários puderem acrescentar requisitos enquanto um modelo GPT-6 trabalha, use uma conexão WebSocket com a API Responses. Envie response.steer com o ID da resposta ativa em previous_response_id e a nova entrada do usuário. Continue lendo os eventos para acompanhar a continuação. O evento response.steer.accepted indica que a atualização entrou na fila. As novas instruções não alteram a saída já enviada ao aplicativo nem desfazem execuções de ferramentas já iniciadas. Consulte orientação durante o turno para entender o fluxo de eventos e o tratamento dos resultados das ferramentas.
Conclusão
A API Responses é a base para criar aplicativos mais inteligentes e capazes com a OpenAI. Com ela, os desenvolvedores podem passar de prompts isolados para fluxos de trabalho duradouros que usam ferramentas, levam o contexto em conta e se adaptam à complexidade da tarefa. Siga as orientações deste guia para melhorar o desempenho em produção.