Usare l'API delle risposte di Azure OpenAI per generare risposte con stato a più turni. Riunisce le funzionalità dai completamenti della chat e dall'API degli Assistenti in un'unica esperienza. Usare l'orchestrazione multi-agente per delegare il lavoro indipendente ai subagenti paralleli o usare la ricerca degli strumenti per caricare le definizioni degli strumenti solo quando il modello ne ha bisogno. L'API Risposte supporta anche il modello che supporta computer-use-preview del computer.
Per le descrizioni complete dei parametri di richiesta e risposta, vedere le informazioni di riferimento sui parametri dell'API Responses.
Prerequisiti
- Un modello Azure OpenAI distribuito.
- Metodo di autenticazione:
- Chiave API (ad esempio,
AZURE_OPENAI_API_KEY) o
- Microsoft Entra ID (scelta consigliata).
- Installa la libreria client per il tuo linguaggio:
-
Python:
pip install openai azure-identity
-
.NET:
dotnet add package OpenAI e dotnet add package Azure.Identity
-
JavaScript/TypeScript:
npm install openai @azure/identity
-
Java: aggiungere
com.openai:openai-java e com.azure:azure-identity al progetto.
- Per esempi REST, impostare
AZURE_OPENAI_API_KEY (flusso di chiave API) o AZURE_OPENAI_AUTH_TOKEN (flusso di Microsoft Entra ID).
Regioni supportate
Prima di eseguire gli esempi in questo articolo, verificare che l'area di risorse supporti l'API Risposte. L'API v1 è necessaria per accedere alle funzionalità più recenti. Per informazioni dettagliate, vedere il ciclo di vita della versione dell'API. Per il supporto a livello di area del servizio Foundry Agent, vedere la tabella di disponibilità a livello di area. L'API Risposte è attualmente disponibile nelle aree seguenti:
- australiaeast
- brasilesouth
- canadacentral
- Canada orientale
- centralus
- eastus
- eastus2
- francecentral
- germania ovest centrale
- italynorth
- japaneast
- japanwest
- koreacentral
- northcentralus
- norvegiaest
- polandcentral
- southafricanorth
- southcentralus
- Sud-est asiatico
- southindia
- spaincentral
- Swedencentral
- SvizzeraNorth
- switzerlandwest
- uaenorth
- uksouth
- ukwest
- westcentralus
- Europa occidentale
- westus
- westus2
- westus3
Modelli supportati
L'API Risposte supporta i modelli seguenti:
-
gpt-6.1-terra (Versione: 2026-10-26)
-
gpt-6.1-sol (Versione: 2026-09-29)
-
gpt-6-luna (Versione: 2026-09-22)
-
gpt-6-sol (Versione: 2026-09-22)
-
gpt-6-astra (Versione: 2026-09-03)
-
gpt-5.6-sol (Versione: 2026-07-09)
-
gpt-5.6-terra (Versione: 2026-07-09)
-
gpt-5.6-luna (Versione: 2026-07-09)
-
gpt-chat-latest (Versioni: 2026-10-07, 2026-08-06, 2026-06-24, 2026-05-28, 2026-05-05)
-
gpt-5.5 (Versione: 2026-04-24)
-
gpt-5.4-nano (Versione: 2026-03-17)
-
gpt-5.4-mini (Versione: 2026-03-17)
-
gpt-5.4-pro (Versione:2026-03-05)
-
gpt-5.4 (Versione:2026-03-05)
-
gpt-5.3-chat (Versione: 2026-03-03)
-
gpt-5.3-codex (Versione: 2026-02-24)
-
gpt-5.2-codex (Versione: 2026-01-14)
-
gpt-5.2 (Versione: 2025-12-11)
-
gpt-5.2-chat (Versione: 2025-12-11)
-
gpt-5.2-chat (Versione: 2026-02-10)
-
gpt-5.1-codex-max (Versione: 2025-12-04)
-
gpt-5.1 (Versione: 2025-11-13)
-
gpt-5.1-chat (Versione: 2025-11-13)
-
gpt-5.1-codex (Versione: 2025-11-13)
-
gpt-5.1-codex-mini (Versione: 2025-11-13)
-
gpt-5-pro (Versione: 2025-10-06)
-
gpt-5-codex (Versione: 2025-09-11)
-
gpt-5 (Versione: 2025-08-07)
-
gpt-5-mini (Versione: 2025-08-07)
-
gpt-5-nano (Versione: 2025-08-07)
-
gpt-5-chat (Versione: 2025-08-07)
-
gpt-5-chat (Versione: 2025-10-03)
-
gpt-5-codex (Versione: 2025-09-15)
-
gpt-4o (Versioni: 2024-11-20, 2024-08-06, 2024-05-13)
-
gpt-4o-mini (Versione: 2024-07-18)
computer-use-preview
-
gpt-4.1 (Versione: 2025-04-14)
-
gpt-4.1-nano (Versione: 2025-04-14)
-
gpt-4.1-mini (Versione: 2025-04-14)
-
gpt-image-1 (Versione: 2025-04-15)
-
gpt-image-1-mini (Versione: 2025-10-06)
-
gpt-image-1.5 (Versione: 2025-12-16)
-
gpt-image-2.5-flare (Versione: 2026-09-09)
-
gpt-image-2.5-sunburst (Versione: 2026-09-09)
-
o1 (Versione: 2024-12-17)
-
o3-mini (Versione: 2025-01-31)
-
o3 (Versione: 2025-04-16)
-
o4-mini (Versione: 2025-04-16)
Non tutti i modelli sono disponibili in ogni area supportata. Controllare la pagina dei modelli per la disponibilità dell'area del modello.
Nota
Attualmente non supportato:
- Generazione di immagini con modifica e streaming a più turni.
Si è verificato un problema noto con quanto segue:
- PDF come file di input è ora supportato, ma l'impostazione dello scopo di caricamento dei file su
user_data non è attualmente supportata.
- Problemi di prestazioni quando viene usata la modalità in background con lo streaming. Microsoft sta lavorando per risolvere questo problema.
Generare una risposta di testo
Generare una risposta di testo semplice usando l'API Risposte. Sostituire YOUR-RESOURCE-NAME e MODEL_NAME con i valori di distribuzione.
import os
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
# API key authentication
client = OpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
)
response = client.responses.create(
model="MODEL_NAME",
input="This is a test."
)
print(response.model_dump_json(indent=2))
# Microsoft Entra ID authentication (recommended)
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider(),
)
response = client.responses.create(
model="MODEL_NAME",
input="This is a test."
)
print(response.model_dump_json(indent=2))
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("This is a test.") }
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import { OpenAI } from "openai";
import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
const endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/";
// API key authentication
const openai = new OpenAI({
baseURL: endpoint,
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await openai.responses.create({
model: "MODEL_NAME",
input: "This is a test."
});
console.log(response.output_text);
// Microsoft Entra ID authentication (recommended)
const tokenProvider = getBearerTokenProvider(
new DefaultAzureCredential(),
"https://ai.azure.com/.default"
);
const openaiEntra = new OpenAI({
baseURL: endpoint,
apiKey: await tokenProvider(),
});
const responseEntra = await openaiEntra.responses.create({
model: "MODEL_NAME",
input: "This is a test."
});
console.log(responseEntra.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
// Microsoft Entra ID authentication (recommended)
OpenAIClient openAIClientEntra = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(BearerTokenCredential.create(
AuthenticationUtil.getBearerTokenSupplier(
new DefaultAzureCredentialBuilder().build(),
"https://ai.azure.com/.default")))
.build();
ResponseCreateParams params = ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("This is a test.")
.build();
Response response = openAIClient.responses().create(params);
System.out.println(response.outputText());
Microsoft Entra ID
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AZURE_OPENAI_AUTH_TOKEN" \
-d '{
"model": "MODEL_NAME",
"input": "This is a test."
}'
Chiave API
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "This is a test."
}'
Risposta di esempio
{
"id": "resp_67cb32528d6881909eb2859a55e18a85",
"created_at": 1741369938.0,
"output_text": "Great! How can I help you today?",
...
}
Recuperare una risposta
Recuperare una risposta in base al relativo ID da una chiamata API Risposte precedente.
import os
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
# API key authentication
client = OpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
)
response = client.responses.retrieve("<response_id>")
print(response.model_dump_json(indent=2))
# Microsoft Entra ID authentication
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
response = client.responses.retrieve("<response_id>")
print(response.model_dump_json(indent=2))
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
string responseId = "<response_id>";
ResponseResult response = await openAIClient.GetResponseAsync(responseId);
Console.WriteLine(response.GetOutputText());
import { OpenAI } from "openai";
import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
const endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/";
// API key authentication
const openai = new OpenAI({
baseURL: endpoint,
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await openai.responses.retrieve("<response_id>");
console.log(response.output_text);
// Microsoft Entra ID authentication
const tokenProvider = getBearerTokenProvider(
new DefaultAzureCredential(),
"https://ai.azure.com/.default"
);
const openaiEntra = new OpenAI({
baseURL: endpoint,
apiKey: await tokenProvider(),
});
const responseEntra = await openaiEntra.responses.retrieve("<response_id>");
console.log(responseEntra.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
// Microsoft Entra ID authentication
OpenAIClient openAIClientEntra = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(BearerTokenCredential.create(
AuthenticationUtil.getBearerTokenSupplier(
new DefaultAzureCredentialBuilder().build(),
"https://ai.azure.com/.default")))
.build();
Response response = openAIClient.responses().retrieve("<response_id>");
System.out.println(response.outputText());
Microsoft Entra ID
curl -X GET https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id> \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AZURE_OPENAI_AUTH_TOKEN"
Chiave API
curl -X GET https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id> \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
Risposta di esempio
{
"id": "resp_67cb61fa3a448190bcf2c42d96f0d1a8",
"output_text": "Hello! How can I assist you today?",
...
}
Eliminare una risposta
Per impostazione predefinita, i dati di risposta vengono conservati per 30 giorni. Eliminare una risposta archiviata in base all'ID.
import os
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
# API key authentication
client = OpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
)
response = client.responses.delete("<response_id>")
print(response)
# Microsoft Entra ID authentication
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
response = client.responses.delete("<response_id>")
print(response)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
string responseId = "<response_id>";
var result = await openAIClient.DeleteResponseAsync(responseId);
Console.WriteLine(result); // result.Deleted == true if successful
import { OpenAI } from "openai";
import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
const endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/";
// API key authentication
const openai = new OpenAI({
baseURL: endpoint,
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const result = await openai.responses.delete("<response_id>");
console.log(result);
// Microsoft Entra ID authentication
const tokenProvider = getBearerTokenProvider(
new DefaultAzureCredential(),
"https://ai.azure.com/.default"
);
const openaiEntra = new OpenAI({
baseURL: endpoint,
apiKey: await tokenProvider(),
});
const resultEntra = await openaiEntra.responses.delete("<response_id>");
console.log(resultEntra);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
// Microsoft Entra ID authentication
OpenAIClient openAIClientEntra = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(BearerTokenCredential.create(
AuthenticationUtil.getBearerTokenSupplier(
new DefaultAzureCredentialBuilder().build(),
"https://ai.azure.com/.default")))
.build();
Response result = openAIClient.responses().delete("<response_id>");
System.out.println(result);
Microsoft Entra ID
curl -X DELETE https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id> \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AZURE_OPENAI_AUTH_TOKEN"
Chiave API
curl -X DELETE https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id> \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
Crittografia dei dati di risposta archiviati
Quando l'API delle risposte memorizza in modo persistente la cronologia dei messaggi e il contenuto correlato, il servizio crittografa il contenuto archiviato. Per la spiegazione della crittografia dell'archiviazione, vedere Dati, privacy e sicurezza per i modelli forniti da Azure in Microsoft Foundry. Per la copertura e i prerequisiti di CMK, vedere Crittografia con chiave gestita dal cliente in Microsoft Foundry.
Questa crittografia è separata dagli elementi di ragionamento crittografati restituiti all'applicazione quando si gestisce lo stato della conversazione con store=false.
Concatenamento delle risposte
Concatena i turni passando l'ID della risposta precedente a previous_response_id.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
first_response = client.responses.create(
model="MODEL_NAME",
input="Define catastrophic forgetting."
)
second_response = client.responses.create(
model="MODEL_NAME",
previous_response_id=first_response.id,
input="Explain it for a college freshman."
)
print(second_response.output_text)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions firstOptions = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("Define and explain the concept of catastrophic forgetting?") }
};
ResponseResult firstResponse = await openAIClient.CreateResponseAsync(firstOptions);
Console.WriteLine(firstResponse.GetOutputText());
CreateResponseOptions secondOptions = new()
{
Model = "MODEL_NAME",
PreviousResponseId = firstResponse.Id,
InputItems = { ResponseItem.CreateUserMessageItem("Explain this at a level that could be understood by a college freshman") }
};
ResponseResult secondResponse = await openAIClient.CreateResponseAsync(secondOptions);
Console.WriteLine(secondResponse.GetOutputText());
import { OpenAI } from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const firstResponse = await client.responses.create({
model: "MODEL_NAME",
input: "Define catastrophic forgetting."
});
const secondResponse = await client.responses.create({
model: "MODEL_NAME",
previous_response_id: firstResponse.id,
input: "Explain it for a college freshman."
});
console.log(secondResponse.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Response first = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("Define and explain the concept of catastrophic forgetting?")
.build());
Response second = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.previousResponseId(first.id())
.input("Explain this at a level that could be understood by a college freshman.")
.build());
second.output().stream()
.flatMap(item -> item.message().stream())
.flatMap(m -> m.content().stream())
.flatMap(c -> c.outputText().stream())
.forEach(t -> System.out.println(t.text()));
# First turn
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "Define catastrophic forgetting."
}'
# Follow-up turn using previous_response_id from the first call
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"previous_response_id": "<response_id>",
"input": "Explain it for a college freshman."
}'
Concatenamento manuale delle risposte
In alternativa, è possibile trasferire manualmente gli elementi di output nella richiesta successiva.
import os
from openai import OpenAI
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
inputs = [{"type": "message", "role": "user", "content": "Define and explain the concept of catastrophic forgetting?"}]
response = client.responses.create(
model="gpt-4o", # replace with your model deployment name
input=inputs
)
inputs += response.output
inputs.append({"role": "user", "type": "message", "content": "Explain this at a level that could be understood by a college freshman"})
second_response = client.responses.create(
model="MODEL_NAME",
input=inputs
)
print(second_response.model_dump_json(indent=2))
Compattare una risposta
La compattazione riduce il contesto di input mantenendo lo stato essenziale per turni successivi.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
compacted = client.responses.compact(
model="MODEL_NAME",
input=[
{"role": "user", "content": "Create a simple landing page for a dog cafe."},
{
"id": "msg_001",
"type": "message",
"status": "completed",
"role": "assistant",
"content": [{"type": "output_text", "text": "..."}],
},
]
)
follow_up = client.responses.create(
model="MODEL_NAME",
input=[*compacted.output, {"role": "user", "content": "Add a booking form."}]
)
print(follow_up.output_text)
Nota
SDK di .NET non fornisce ancora una superficie fortemente tipizzata per la compattazione della risposta. Vedere la scheda REST per la forma della chiamata o richiamare il metodo del protocollo direttamente con BinaryContent JSON.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const compacted = await client.responses.compact({
model: "MODEL_NAME",
input: [
{ role: "user", content: "Create a simple landing page for a dog cafe." },
{
id: "msg_001",
type: "message",
status: "completed",
role: "assistant",
content: [{ type: "output_text", text: "..." }],
},
],
});
const followUp = await client.responses.create({
model: "MODEL_NAME",
input: [...compacted.output, { role: "user", content: "Add a booking form." }],
});
console.log(followUp.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.CompactedResponse;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCompactParams;
import com.openai.models.responses.ResponseCreateParams;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Response initial = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("Create a simple landing page for a dog cafe.")
.build());
CompactedResponse compacted = openAIClient.responses().compact(
ResponseCompactParams.builder()
.model("MODEL_NAME")
.previousResponseId(initial.id())
.build());
Response followUp = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.previousResponseId(compacted.id())
.input("Add a booking form.")
.build());
System.out.println(followUp.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/compact \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": [
{"role": "user", "content": "Create a simple landing page for a dog cafe."},
{
"id": "msg_001",
"type": "message",
"status": "completed",
"role": "assistant",
"content": [{"type": "output_text", "text": "..."}]
}
]
}'
Compattare utilizzando gli elementi restituiti
È possibile compattare tutti gli elementi restituiti dalle richieste precedenti, ad esempio ragionamento, messaggio, chiamata di funzione e così via.
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/compact \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AZURE_OPENAI_AUTH_TOKEN" \
-d '{
"model": "MODEL_NAME",
"input": [
{
"role" : "user",
"content": "Create a simple landing page for a dog petting café."
},
{
"id": "msg_001",
"type": "message",
"status": "completed",
"content": [
{
"type": "output_text",
"annotations": [],
"logprobs": [],
"text": "Below is a single file, ready-to-use landing page for a dog petting café:..."
}
],
"role": "assistant"
}
]
}'
# Use the compacted output as input for the next turn.
next_response = client.responses.create(
model="MODEL_NAME",
input=[*compacted.output, {"role": "user", "content": "Add opening hours."}],
)
print(next_response.output_text)
Compattare utilizzando l'ID risposta precedente
È anche possibile compattare usando un ID risposta precedente.
initial_response = client.responses.create(
model="MODEL_NAME",
input="What is the size of France?"
)
compacted_response = client.responses.compact(
model="MODEL_NAME",
previous_response_id=initial_response.id
)
follow_up_response = client.responses.create(
model="MODEL_NAME",
input=[
*compacted_response.output,
{"role": "user", "content": "What is the capital?"}
]
)
print(follow_up_response.output_text)
Compattazione lato server
È anche possibile usare la compattazione lato server direttamente in Risposte (POST /responses o client.responses.create) impostando context_management con .compact_threshold
- Quando il numero di token di output supera la soglia configurata, l'API Risposte esegue automaticamente la compattazione.
- In questa modalità non è necessario chiamare
/responses/compact separatamente.
- La risposta include un elemento di compattazione crittografato.
- La compattazione lato server funzionerà quando si imposta store=false sulle richieste di creazione delle risposte.
L'elemento di compattazione porta avanti lo stato precedente essenziale e il ragionamento nel turno successivo usando meno token. È opaco e non deve essere leggibile dall'uomo.
Se si usa il concatenamento di matrici di input senza stato, aggiungere gli elementi di output come di consueto. Se si usa previous_response_id, passare solo il nuovo messaggio utente ad ogni turno. In entrambi i modelli, l'elemento di compattazione contiene il contesto necessario per la finestra successiva.
Suggerimento
Dopo aver accodato gli elementi di output agli elementi di input precedenti, è possibile eliminare gli elementi che sono arrivati prima dell'elemento di compattazione più recente per mantenere le richieste più piccole e ridurre la latenza della coda lunga. L'elemento di compattazione più recente contiene il contesto necessario per continuare la conversazione. Se si usa il concatenamento previous_response_id, non eseguire manualmente l'eliminazione.
Flusso
- Chiama
responses come di consueto. Aggiungere context_management a compact_threshold per abilitare la compattazione lato server.
- Se l'output supera la soglia, il servizio attiva la compattazione, genera un elemento di compattazione nel flusso di output e elimina il contesto prima di continuare l'inferenza.
- Continuare la conversazione usando uno dei modelli seguenti:
- Concatenamento di matrici di input senza stato: aggiungere elementi di output, inclusi gli elementi di compattazione, alla matrice di input successiva.
- Concatenamento
previous_response_id: passare solo il nuovo messaggio utente a ogni turno e portare avanti l'ID risposta più recente.
Esempio
conversation = [
{
"type": "message",
"role": "user",
"content": "Let's begin a long coding task.",
}
]
while keep_going:
response = client.responses.create(
model="MODEL_NAME",
input=conversation,
store=False,
context_management=[{"type": "compaction", "compact_threshold": 200000}],
)
conversation.append(
{
"type": "message",
"role": "user",
"content": get_next_user_input(),
}
)
Streaming
Trasmetti la risposta in streaming man mano che viene generata impostando stream=true. Il servizio emette eventi incrementali che si possono consumare per visualizzare l'output token per token.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
stream = client.responses.create(
model="MODEL_NAME",
input="Summarize Azure OpenAI Responses API in one sentence.",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="")
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("Summarize Azure OpenAI Responses API in one sentence.") },
StreamingEnabled = true
};
await foreach (StreamingResponseUpdate update in openAIClient.CreateResponseStreamingAsync(options))
{
if (update is StreamingResponseOutputTextDeltaUpdate textDelta)
{
Console.Write(textDelta.Delta);
}
else if (update is StreamingResponseCompletedUpdate completed)
{
Console.WriteLine();
Console.WriteLine($"[done] response id: {completed.Response.Id}");
}
}
import { OpenAI } from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const stream = await client.responses.create({
model: "MODEL_NAME",
input: "Summarize Azure OpenAI Responses API in one sentence.",
stream: true,
});
for await (const event of stream) {
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
}
}
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseStreamEvent;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
ResponseCreateParams params = ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("This is a test")
.build();
try (StreamResponse<ResponseStreamEvent> stream = openAIClient.responses().createStreaming(params)) {
stream.stream()
.flatMap(event -> event.outputTextDelta().stream())
.forEach(delta -> System.out.print(delta.delta()));
}
curl -N -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "Summarize Azure OpenAI Responses API in one sentence.",
"stream": true
}'
Durante lo streaming, se si verifica un errore mid-stream, il sistema tenta di risolvere l'errore internamente. Se la richiesta ha ancora esito negativo, il servizio rileva un errore irreversibile. In questi casi, il codice di risposta HTTP è 200 (esito positivo), ma l'evento di errore nel flusso include dettagli sugli errori midstream.
Il server restituisce i tipi di errore seguenti:
| Tipo di errore |
Può essere tradotto come |
server_error |
Codice di ritorno 500 |
too_many_requests |
Codice di ritorno 429 |
forbidden |
Codice di ritorno 403 |
user_error |
Codice di ritorno 400 |
Evento di errore di esempio:
{
"type": "error",
"error": {
"type": "too_many_requests",
"code": "no_capacity",
"headers": {
"skip-error-remapping": "true"
},
"message": "The system is currently experiencing high demand and cannot process your request. Your request exceeds the maximum usage size allowed during peak load. For improved capacity reliability, consider switching to Provisioned Throughput.",
"param": null
}
}
Le applicazioni devono rilevare questi errori e arrestare o riavviare normalmente lo streaming. Non vengono addebitati i costi per i token generati durante le risposte di streaming fallite.
Risultati strutturati
Usare output strutturati per creare una risposta seguendo uno schema JSON. In una richiesta dell'API Responses, definire lo schema in text.format. Chat Completions utilizza invece response_format. Per esempi di SDK e REST, vincoli di schema supportati e limitazioni, vedere Output strutturati.
Chiamata di funzione
La Responses API supporta il function calling.
import os
import json
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
tools=[
{
"type": "function",
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"],
},
}
],
input="What is the weather in San Francisco?",
)
tool_outputs = []
for item in response.output:
if item.type == "function_call" and item.name == "get_weather":
args = json.loads(item.arguments)
weather = {"location": args["location"], "temperature": "70 F"}
tool_outputs.append(
{
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(weather),
}
)
final_response = client.responses.create(
model="MODEL_NAME",
previous_response_id=response.id,
input=tool_outputs,
)
print(final_response.output_text)
#pragma warning disable OPENAI001
using System.Text.Json;
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
FunctionTool getWeatherTool = ResponseTool.CreateFunctionTool(
functionName: "get_weather",
functionParameters: BinaryData.FromBytes("""
{
"type": "object",
"properties": {
"location": { "type": "string", "description": "The city, e.g. Boston, MA" }
},
"required": ["location"]
}
"""u8.ToArray()),
strictModeEnabled: false,
functionDescription: "Get the current weather for a location.");
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("What is the weather in San Francisco?") },
Tools = { getWeatherTool }
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
foreach (ResponseItem item in response.OutputItems)
{
if (item is FunctionCallResponseItem call && call.FunctionName == "get_weather")
{
using JsonDocument args = JsonDocument.Parse(call.FunctionArguments);
string location = args.RootElement.GetProperty("location").GetString();
string toolOutput = $"{{ \"location\": \"{location}\", \"temperature\": \"70 F\" }}";
CreateResponseOptions followUp = new()
{
Model = "MODEL_NAME",
PreviousResponseId = response.Id,
InputItems = { ResponseItem.CreateFunctionCallOutputItem(call.CallId, toolOutput) },
Tools = { getWeatherTool }
};
ResponseResult finalResponse = await openAIClient.CreateResponseAsync(followUp);
Console.WriteLine(finalResponse.GetOutputText());
}
}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
tools: [
{
type: "function",
name: "get_weather",
description: "Get weather for a location",
parameters: {
type: "object",
properties: { location: { type: "string" } },
required: ["location"],
},
},
],
input: "What is the weather in San Francisco?",
});
const toolOutputs = [];
for (const item of response.output ?? []) {
if (item.type === "function_call" && item.name === "get_weather") {
const args = JSON.parse(item.arguments);
toolOutputs.push({
type: "function_call_output",
call_id: item.call_id,
output: JSON.stringify({ location: args.location, temperature: "70 F" }),
});
}
}
const finalResponse = await client.responses.create({
model: "MODEL_NAME",
previous_response_id: response.id,
input: toolOutputs,
});
console.log(finalResponse.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseFunctionToolCall;
import com.openai.models.responses.ResponseInputItem;
import java.util.ArrayList;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
// Strongly-typed function parameter class.
class GetWeather {
@JsonPropertyDescription("City and country, for example, Paris, France")
public String location;
}
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("What is the weather like in Paris today?")
.addTool(GetWeather.class)
.build());
List<ResponseInputItem> followUp = new ArrayList<>();
response.output().forEach(item -> {
if (item.isFunctionCall()) {
ResponseFunctionToolCall call = item.asFunctionCall();
// Execute the tool with call.arguments() and capture the result.
String result = "{\"temperature\":\"22 C\",\"conditions\":\"Sunny\"}";
followUp.add(ResponseInputItem.ofFunctionCallOutput(
ResponseInputItem.FunctionCallOutput.builder()
.callId(call.callId())
.output(result)
.build()));
}
});
Response finalResponse = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.previousResponseId(response.id())
.inputOfResponse(followUp)
.addTool(GetWeather.class)
.build());
System.out.println(finalResponse.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"]
}
}
],
"input": "What is the weather in San Francisco?"
}'
Gestire misure di sicurezza e filtraggio dei contenuti
Applicare guardrail (filtri di contenuto) a livello di distribuzione. Ogni controllo configurato valuta il contenuto e i punti di intervento supportati: i filtri core-harm valutano l'input e l'output, il rilevamento degli attacchi al prompt dell'utente valuta l'input dell'utente e il rilevamento degli attacchi al documento valuta il contenuto del documento quando abilitato. Configura separatamente i guardrail. Per altre informazioni, vedere Configurare protezioni e controlli. Questa sezione illustra come rilevare e gestire i risultati dei guardrail quando si chiama l'API Responses.
L'API Responses espone i risultati dei guardrail in modo diverso rispetto a Chat Completions. Anziché i campi prompt_filter_results e content_filter_results restituiti dai completamenti di chat, l'oggetto di risposta include un array di primo livello content_filters. Ogni voce descrive un risultato del filtro.
| Campo |
Description |
blocked |
Indica se il contenuto è stato bloccato. |
source_type |
Indica se il risultato si applica a prompt (input) o a completion (output). |
content_filter_results |
I risultati della categoria, ad esempio hate, sexualviolence, e self_harm con livelli di gravità, oltre a categorie facoltative come jailbreak, indirect_attackprotected_material_text, e protected_material_code. |
content_filter_offsets |
Gli offset dei caratteri a cui si applica il risultato. |
Nota
La content_filters matrice è un'estensione Microsoft Foundry che non fa parte dello schema di risposta OpenAI di base, quindi gli SDK non espongono una proprietà tipizzata. Leggerlo come campo non elaborato o aggiuntivo, come illustrato negli esempi seguenti.
Quando le protezioni bloccano l'input, l'API restituisce un errore HTTP 400 con il codice content_filter. Intercettare questo errore per gestire correttamente i prompt bloccati.
import os
from openai import OpenAI, BadRequestError
client = OpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
)
# A blocked prompt raises BadRequestError with the code "content_filter"
try:
response = client.responses.create(
model="MODEL_NAME",
input="This is a test."
)
print(response.output_text)
except BadRequestError as error:
if error.code == "content_filter":
print("The prompt was blocked by a guardrail.")
else:
raise
#pragma warning disable OPENAI001
using OpenAI.Responses;
using System.ClientModel;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("This is a test.") }
};
// A blocked prompt throws ClientResultException with HTTP 400
try
{
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
}
catch (ClientResultException error) when (error.Status == 400)
{
Console.WriteLine("The prompt was blocked by a guardrail.");
}
import { OpenAI, APIError } from "openai";
const openai = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
// A blocked prompt throws APIError with the code "content_filter"
try {
const response = await openai.responses.create({
model: "MODEL_NAME",
input: "This is a test."
});
console.log(response.output_text);
} catch (error) {
if (error instanceof APIError && error.code === "content_filter") {
console.log("The prompt was blocked by a guardrail.");
} else {
throw error;
}
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.AzureApiKeyCredential;
import com.openai.errors.BadRequestException;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1")
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
ResponseCreateParams params = ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("This is a test.")
.build();
// A blocked prompt throws BadRequestException (HTTP 400)
try {
Response response = openAIClient.responses().create(params);
System.out.println(response.outputText());
} catch (BadRequestException error) {
System.out.println("The prompt was blocked by a guardrail.");
}
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "This is a test."
}'
Quando guardrail blocca l'input, l'API restituisce HTTP 400 con il codice content_filter:
{
"error": {
"code": "content_filter",
"message": "The response was filtered due to the prompt triggering content management policy."
}
}
Leggi le annotazioni delle protezioni
Quando una richiesta va a buon fine, leggere l'array content_filters dalla risposta per esaminare i risultati del guardrail per l'input e l'output.
In modalità annotazione, i controlli configurati possono segnalare i risultati di gravità o di rilevamento senza imporli. I corrispondenti valori filtered e blocked rimangono false. La modalità annotazione per le quattro categorie di danni principali richiede l'approvazione per i guardrail modificati.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
)
response = client.responses.create(
model="MODEL_NAME",
input="This is a test."
)
# content_filters is an Azure extension, so read it from model_extra
content_filters = response.model_extra.get("content_filters", [])
for result in content_filters:
print(f"Source: {result['source_type']}, Blocked: {result['blocked']}")
#pragma warning disable OPENAI001
using OpenAI.Responses;
using System.ClientModel;
using System.ClientModel.Primitives;
using System.Text.Json;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("This is a test.") }
};
// content_filters has no typed property, so parse it from the raw response
ClientResult<ResponseResult> result = await openAIClient.CreateResponseAsync(options);
using JsonDocument doc = JsonDocument.Parse(result.GetRawResponse().Content);
if (doc.RootElement.TryGetProperty("content_filters", out JsonElement filters))
{
foreach (JsonElement filter in filters.EnumerateArray())
{
string source = filter.GetProperty("source_type").GetString()!;
bool blocked = filter.GetProperty("blocked").GetBoolean();
Console.WriteLine($"Source: {source}, Blocked: {blocked}");
}
}
import { OpenAI } from "openai";
const openai = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await openai.responses.create({
model: "MODEL_NAME",
input: "This is a test."
});
// content_filters is an Azure extension not in the typed response
const contentFilters = response.content_filters ?? [];
for (const result of contentFilters) {
console.log(`Source: ${result.source_type}, Blocked: ${result.blocked}`);
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.AzureApiKeyCredential;
import com.openai.core.JsonValue;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1")
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
ResponseCreateParams params = ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("This is a test.")
.build();
Response response = openAIClient.responses().create(params);
// content_filters has no typed accessor, so read it from additional properties
JsonValue contentFilters = response._additionalProperties().get("content_filters");
System.out.println(contentFilters);
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "This is a test."
}'
La content_filters matrice viene visualizzata nell'oggetto risposta:
{
"id": "resp_<id>",
"content_filters": [
{
"source_type": "prompt",
"blocked": false,
"content_filter_results": {
"hate": { "filtered": false, "severity": "safe" },
"self_harm": { "filtered": false, "severity": "safe" },
"sexual": { "filtered": false, "severity": "safe" },
"violence": { "filtered": false, "severity": "safe" }
}
}
]
}
Per ulteriori informazioni sulle categorie dei guardrail e sui livelli di gravità, consulta Panoramica dei guardrail e Lavorare con le annotazioni.
Interprete di codice
Lo strumento Interprete codice consente ai modelli di scrivere ed eseguire codice Python in un ambiente protetto e in modalità sandbox. Supporta una gamma di attività avanzate, tra cui:
- Elaborazione di file con formati e strutture di dati diversi
- Generazione di file che includono dati e visualizzazioni (ad esempio, grafici)
- Scrivere ed eseguire codice in modo iterativo per risolvere i problemi: i modelli possono eseguire il debug e riprovare il codice fino a raggiungere il successo.
- Miglioramento del ragionamento visivo nei modelli supportati (ad esempio, o3, o4-mini) abilitando trasformazioni delle immagini, ad esempio ritaglio, zoom e rotazione
- Questo strumento è particolarmente utile per scenari che coinvolgono l'analisi dei dati, il calcolo matematico e la generazione di codice.
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"tools": [
{ "type": "code_interpreter", "container": {"type": "auto"} }
],
"instructions": "You are a personal math tutor. When asked a math question, write and run code using the python tool to answer the question.",
"input": "I need to solve the equation 3x + 11 = 14. Can you help me?"
}'
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}],
instructions="You are a math tutor. Write and run Python code to solve math problems.",
input="Solve 3x + 11 = 14."
)
print(response.output_text)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Containers;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CodeInterpreterToolContainer container = new(
CodeInterpreterToolContainerConfiguration.CreateAutomaticContainerConfiguration());
CodeInterpreterTool codeInterpreterTool = new(container);
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem("Solve 3x + 11 = 14.")
},
Tools = { codeInterpreterTool }
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
tools: [{ type: "code_interpreter", container: { type: "auto" } }],
instructions: "You are a math tutor. Write and run Python code to solve math problems.",
input: "Solve 3x + 11 = 14.",
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.Tool;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Tool codeInterpreter = Tool.ofCodeInterpreter(
Tool.CodeInterpreter.builder()
.container(Tool.CodeInterpreter.Container.ofCodeInterpreterToolAuto(
Tool.CodeInterpreter.Container.CodeInterpreterToolAuto.builder().build()))
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("Solve 3x + 11 = 14.")
.addTool(codeInterpreter)
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"tools": [{"type": "code_interpreter", "container": {"type": "auto"}}],
"instructions": "You are a math tutor. Write and run Python code to solve math problems.",
"input": "Solve 3x + 11 = 14."
}'
Contenitori
Importante
L'interprete del codice ha addebiti aggiuntivi oltre alle tariffe basate su token per l'utilizzo di Azure OpenAI. Se l'API Risposte chiama l'interprete del codice contemporaneamente in due thread diversi, vengono create due sessioni dell'interprete del codice. Ogni sessione comporta addebiti al minuto, con un addebito minimo di cinque minuti. Una sessione rimane attiva finché si accede al relativo contenitore entro il timeout di inattività di 20 minuti.
Lo strumento Interprete del codice richiede un contenitore, ovvero una macchina virtuale con sandbox completa dove il modello può eseguire codice Python. I contenitori possono includere file o file caricati generati durante l'esecuzione.
Per creare un contenitore, specificare "container": { "type": "auto", "file_ids": ["file-1", "file-2"] } nella configurazione dello strumento quando si crea un nuovo oggetto Response. In questo modo viene creato automaticamente un nuovo contenitore o riutilizzato uno attivo da un code_interpreter_call precedente nel contesto del modello. L'oggetto code_interpreter_call nell'output dell'API conterrà l'oggetto container_id generato. Questo contenitore scade se non viene usato per 20 minuti.
Si applicano i limiti di file seguenti:
- Una richiesta può includere fino a 50 ID file.
- Un contenitore può contenere fino a 1.000 file in totale, inclusi i file di input e i file generati dall'interprete del codice.
Quando si esegue l'interprete del codice, il modello può creare i propri file. Ad esempio, se si chiede di costruire un tracciato o di creare un file CSV, queste immagini vengono create direttamente nel contenitore. Questi file verranno riportati nelle annotazioni del messaggio successivo.
Tutti i file nell'input del modello vengono caricati automaticamente nel contenitore. Non è necessario caricarlo in modo esplicito nel contenitore.
File compatibili
| Formato file |
Tipo MIME |
.c |
text/x-c |
.cs |
text/x-csharp |
.cpp |
text/x-c++ |
.csv |
text/csv |
.doc |
application/msword |
.docx |
application/vnd.openxmlformats-officedocument.wordprocessingml.document |
.html |
text/html |
.java |
text/x-java |
.json |
application/json |
.md |
text/markdown |
.pdf |
application/pdf |
.php |
text/x-php |
.pptx |
application/vnd.openxmlformats-officedocument.presentationml.presentation |
.py |
text/x-python |
.py |
text/x-script.python |
.rb |
text/x-ruby |
.tex |
text/x-tex |
.txt |
testo/puro |
.css |
text/css |
.js |
text/JavaScript |
.sh |
application/x-sh |
.ts |
application/TypeScript |
.csv |
application/csv |
.jpeg |
image/jpeg |
.jpg |
image/jpeg |
.gif |
image/gif |
.pkl |
application/octet-stream |
.png |
image/png |
.tar |
application/x-tar |
.xlsx |
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
.xml |
application/xml o "text/xml" |
.zip |
application/zip |
Recuperare gli elementi di input inviati a una risposta. Ciò è utile per esaminare il contesto di conversazione completo, inclusi gli elementi aggiunti dal modello (ad esempio, chiamate di funzione o elementi di compattazione).
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
items = client.responses.input_items.list("<response_id>")
print(items.model_dump_json(indent=2))
Nota
L'SDK .NET espone questo endpoint solo come metodo di protocollo. Vedere la scheda REST per la forma della chiamata o richiamare direttamente il metodo del protocollo.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const items = await client.responses.inputItems.list("<response_id>");
console.log(JSON.stringify(items, null, 2));
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.inputitems.ResponseInputItemListPage;
import com.openai.models.responses.inputitems.ResponseInputItemListParams;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
ResponseInputItemListPage page = openAIClient.responses().inputItems().list(
ResponseInputItemListParams.builder()
.responseId("<response_id>")
.build());
page.autoPager().stream().forEach(item -> System.out.println(item));
curl -X GET https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id>/input_items \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
Risposta di esempio
{
"object": "list",
"data": [
{
"id": "msg_...",
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": "This is a test."}]
}
]
}
I modelli abilitati per la visione possono interpretare le immagini insieme al testo. Possono riconoscere oggetti, forme, colori e trame e leggere il testo contenuto in un'immagine, soggetto alle limitazioni elencate più avanti in questo articolo.
È possibile fornire un'immagine come input a una richiesta in uno dei modi seguenti:
- URL completo di un file di immagine
- URI di dati con codifica Base64
- ID file creato con l'API Files
URL dell'immagine
Fare riferimento a un'immagine ospitata in un URL pubblico. Il modello recupera l'immagine e la include come parte del contenuto di input.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
input=[
{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image?"},
{"type": "input_image", "image_url": "<image_url>"}
]
}
]
)
print(response.output_text)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem(
[
ResponseContentPart.CreateInputTextPart("What is in this image?"),
ResponseContentPart.CreateInputImagePart(new Uri("<image_url>"))
])
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
input: [
{
role: "user",
content: [
{ type: "input_text", text: "What is in this image?" },
{ type: "input_image", image_url: "<image_url>" }
],
},
],
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputImage;
import com.openai.models.responses.ResponseInputItem;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
ResponseInputImage image = ResponseInputImage.builder()
.detail(ResponseInputImage.Detail.AUTO)
.imageUrl("<image_url>")
.build();
ResponseInputItem userMsg = ResponseInputItem.ofMessage(
ResponseInputItem.Message.builder()
.role(ResponseInputItem.Message.Role.USER)
.addInputTextContent("What is in this image?")
.addContent(image)
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.inputOfResponse(List.of(userMsg))
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": [
{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image?"},
{"type": "input_image", "image_url": "<image_url>"}
]
}
]
}'
Immagine con codifica Base64
Invia un'immagine in linea codificandone i byte come URI di dati base64. Usare questo modello quando l'immagine non è ospitata in un URL pubblico o quando si vuole evitare un recupero di rete aggiuntivo.
import base64
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
with open("path_to_your_image.jpg", "rb") as image_file:
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
response = client.responses.create(
model="MODEL_NAME",
input=[
{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image?"},
{"type": "input_image", "image_url": f"data:image/jpeg;base64,{base64_image}"}
]
}
]
)
print(response.output_text)
#pragma warning disable OPENAI001
using System.IO;
using System.Threading.Tasks;
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
byte[] imageBytes = await File.ReadAllBytesAsync("path_to_your_image.jpg");
BinaryData imageData = BinaryData.FromBytes(imageBytes);
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem(
[
ResponseContentPart.CreateInputTextPart("What is in this image?"),
ResponseContentPart.CreateInputImagePart(imageData, "image/jpeg")
])
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import { readFileSync } from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const base64Image = readFileSync("path_to_your_image.jpg").toString("base64");
const response = await client.responses.create({
model: "MODEL_NAME",
input: [
{
role: "user",
content: [
{ type: "input_text", text: "What is in this image?" },
{ type: "input_image", image_url: `data:image/jpeg;base64,${base64Image}` }
],
},
],
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputImage;
import com.openai.models.responses.ResponseInputItem;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
byte[] bytes = Files.readAllBytes(Paths.get("cat.jpg"));
String dataUrl = "data:image/jpeg;base64," + Base64.getEncoder().encodeToString(bytes);
ResponseInputImage image = ResponseInputImage.builder()
.detail(ResponseInputImage.Detail.AUTO)
.imageUrl(dataUrl)
.build();
ResponseInputItem userMsg = ResponseInputItem.ofMessage(
ResponseInputItem.Message.builder()
.role(ResponseInputItem.Message.Role.USER)
.addInputTextContent("What is in this image?")
.addContent(image)
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.inputOfResponse(List.of(userMsg))
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": [
{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image?"},
{"type": "input_image", "image_url": "data:image/jpeg;base64,<BASE64_IMAGE>"}
]
}
]
}'
ID del file
Caricare un'immagine con l'API File usando purpose="assistants", quindi fare riferimento all'ID file restituito nella richiesta. Questo approccio è utile quando si vuole riutilizzare la stessa immagine tra più richieste senza inviare nuovamente i byte.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
def create_file(file_path):
with open(file_path, "rb") as file_content:
result = client.files.create(
file=file_content,
purpose="assistants",
)
return result.id
file_id = create_file("path_to_your_image.jpg")
response = client.responses.create(
model="MODEL_NAME",
input=[
{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image?"},
{"type": "input_image", "file_id": file_id},
],
}
],
)
print(response.output_text)
#pragma warning disable OPENAI001
using System.IO;
using System.Threading.Tasks;
using Azure.Identity;
using OpenAI;
using OpenAI.Files;
using OpenAI.Responses;
using System.ClientModel;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
OpenAIFileClient fileClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new OpenAIClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
byte[] imageBytes = await File.ReadAllBytesAsync("path_to_your_image.jpg");
OpenAIFile uploadedFile = await fileClient.UploadFileAsync(
BinaryData.FromBytes(imageBytes),
"path_to_your_image.jpg",
FileUploadPurpose.Assistants);
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem(
[
ResponseContentPart.CreateInputTextPart("What is in this image?"),
ResponseContentPart.CreateInputImagePart(uploadedFile.Id)
])
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import fs from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const file = await client.files.create({
file: fs.createReadStream("path_to_your_image.jpg"),
purpose: "assistants",
});
const response = await client.responses.create({
model: "MODEL_NAME",
input: [
{
role: "user",
content: [
{ type: "input_text", text: "What is in this image?" },
{ type: "input_image", file_id: file.id },
],
},
],
});
console.log(response.output_text);
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.AzureApiKeyCredential;
import com.openai.models.files.FileCreateParams;
import com.openai.models.files.FileObject;
import com.openai.models.files.FilePurpose;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputImage;
import com.openai.models.responses.ResponseInputItem;
import java.nio.file.Paths;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
FileObject uploaded = openAIClient.files().create(
FileCreateParams.builder()
.file(Paths.get("path_to_your_image.jpg"))
.purpose(FilePurpose.ASSISTANTS)
.build());
ResponseInputImage image = ResponseInputImage.builder()
.detail(ResponseInputImage.Detail.AUTO)
.fileId(uploaded.id())
.build();
ResponseInputItem userMsg = ResponseInputItem.ofMessage(
ResponseInputItem.Message.builder()
.role(ResponseInputItem.Message.Role.USER)
.addInputTextContent("What is in this image?")
.addContent(image)
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.inputOfResponse(List.of(userMsg))
.build());
System.out.println(response.outputText());
# Upload the image
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/files \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-F purpose="assistants" \
-F file="@path_to_your_image.jpg"
# Use the returned file ID with Responses
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": [
{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image?"},
{"type": "input_image", "file_id": "<file_id>"}
]
}
]
}'
Nella tabella seguente sono elencati i tipi di file supportati per gli input di immagine.
| Tipo di file |
Tipo MIME |
| PNG |
image/png |
| JPEG |
image/jpeg |
| WebP |
image/webp |
| GIF non animata |
image/gif |
In una singola richiesta è possibile includere fino a 50 immagini. Ogni singolo file di immagine deve essere inferiore a 512 MB e anche le dimensioni combinate del prompt, incluse tutte le immagini nella richiesta, devono essere minori di 512 MB.
Le immagini devono soddisfare questi requisiti aggiuntivi:
- L'immagine deve essere rilevante per il prompt; il modello non è progettato per contenuto visivo non correlato.
- Le immagini non devono contenere contenuto dannoso o sensibile che viola i criteri di contenuto.
- I file di immagine non possono essere danneggiati o illeggibili. Se il modello non è in grado di elaborare un'immagine, la richiesta ha esito negativo.
Scegliere un livello di dettaglio immagine
Usare la detail proprietà in una input_image parte del contenuto per controllare il modo in cui il modello elabora l'immagine. I dettagli inferiori usano meno token ed è più veloce, mentre i dettagli più elevati usano più token, ma consentono al modello di acquisire funzionalità più dettagliate.
{
"type": "input_image",
"image_url": "<image_url>",
"detail": "high"
}
La tabella seguente descrive ogni livello di dettaglio.
| Livello dettagli |
Description |
low |
Il modello usa una versione con risoluzione inferiore dell'immagine. Questa opzione usa i token più piccoli e produce la risposta più veloce, ma il modello potrebbe perdere dettagli. |
high |
Il modello usa una versione con risoluzione superiore dell'immagine. Questa opzione acquisisce dettagli più sottili, ma usa più token e richiede più tempo per rispondere. |
auto |
Valore predefinito. Il modello seleziona il livello di dettaglio appropriato in base all'immagine e alla richiesta. |
I modelli abilitati per la visione hanno le limitazioni seguenti:
-
Immagini mediche: il modello non è adatto per interpretare immagini mediche specializzate come le scansioni CT e non deve essere usato per consulenza medica.
-
Testo non in inglese: il modello potrebbe non funzionare in modo ottimale quando si gestiscono immagini contenenti testo in alfabeti non latini, ad esempio giapponese o coreano.
-
Testo piccolo: ingrandire il testo all'interno di un'immagine per migliorare la leggibilità, ma evitare di ritagliare dettagli importanti.
-
Rotazione: il modello potrebbe aver interpretato erroneamente testo e immagini ruotate o capovolte.
-
Elementi visivi: il modello potrebbe avere difficoltà con grafici o testi in cui variano colori o stili, ad esempio linee continue, tratteggiate o puntinate.
-
Ragionamento spaziale: il modello ha difficoltà con le attività che richiedono una localizzazione spaziale precisa, ad esempio l'identificazione delle posizioni degli scacchi.
-
Accuratezza: il modello potrebbe generare descrizioni o didascalie non corrette in alcuni casi.
-
Formato dell'immagine: il modello ha difficoltà con le immagini panoramiche e fisheye.
-
Metadati e ridimensionamento: il modello non elabora i nomi o i metadati dei file originali e le immagini vengono ridimensionate prima dell'analisi, che influisce sulle dimensioni originali.
-
Conteggio: il modello potrebbe fornire conteggi approssimativi per gli oggetti nelle immagini.
-
CAPTCHAs: per motivi di sicurezza, è in atto un sistema per bloccare l'invio di CAPTCHA.
I modelli con funzionalità di visione supportano l'input PDF. È possibile fornire un file PDF in uno dei modi seguenti:
- Dati codificati in Base64
- ID file creato con l'API Files
- URL di file esterno (
file_url)
Per consentire ai modelli di interpretare il contenuto PDF, il contesto del modello include sia il testo estratto che un'immagine di ogni pagina. Questa funzionalità è utile quando le informazioni chiave vengono trasmesse tramite diagrammi o contenuto non testuale.
Nota
- Tutte le immagini e il testo estratti vengono inseriti nel contesto del modello. Assicurarsi di comprendere le implicazioni relative all'utilizzo dei prezzi e dei token dell'uso di PDF come input.
- In una singola richiesta API è possibile includere più file, ma ogni file deve essere inferiore a 50 MB. Il limite combinato per tutti i file nella richiesta è 50 MB.
- Solo i modelli che supportano input di testo e immagine possono accettare file PDF come input.
- Un
purpose di user_data non è attualmente supportato. Come soluzione alternativa temporanea è necessario impostare lo scopo su assistants.
Convertire il PDF in Base64 e analizzare
Inviare un PDF in linea codificandone i byte come URI di dati in Base64. Il modello riceve sia il testo estratto che un'immagine sottoposta a rendering di ogni pagina.
import base64
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
with open("PDF-FILE-NAME.pdf", "rb") as f:
base64_string = base64.b64encode(f.read()).decode("utf-8")
response = client.responses.create(
model="MODEL_NAME",
input=[
{
"role": "user",
"content": [
{
"type": "input_file",
"filename": "PDF-FILE-NAME.pdf",
"file_data": f"data:application/pdf;base64,{base64_string}",
},
{"type": "input_text", "text": "Summarize this PDF."},
],
},
]
)
print(response.output_text)
#pragma warning disable OPENAI001
using System.IO;
using System.Threading.Tasks;
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
byte[] pdfBytes = await File.ReadAllBytesAsync("PDF-FILE-NAME.pdf");
BinaryData pdfData = BinaryData.FromBytes(pdfBytes);
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem(
[
ResponseContentPart.CreateInputFilePart(pdfData, "application/pdf", "PDF-FILE-NAME.pdf"),
ResponseContentPart.CreateInputTextPart("Summarize this PDF.")
])
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import { readFileSync } from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const base64Pdf = readFileSync("PDF-FILE-NAME.pdf").toString("base64");
const response = await client.responses.create({
model: "MODEL_NAME",
input: [
{
role: "user",
content: [
{
type: "input_file",
filename: "PDF-FILE-NAME.pdf",
file_data: `data:application/pdf;base64,${base64Pdf}`,
},
{ type: "input_text", text: "Summarize this PDF." },
],
},
],
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputFile;
import com.openai.models.responses.ResponseInputItem;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
byte[] pdfBytes = Files.readAllBytes(Paths.get("document.pdf"));
String dataUrl = "data:application/pdf;base64," + Base64.getEncoder().encodeToString(pdfBytes);
ResponseInputFile file = ResponseInputFile.builder()
.filename("document.pdf")
.fileData(dataUrl)
.build();
ResponseInputItem userMsg = ResponseInputItem.ofMessage(
ResponseInputItem.Message.builder()
.role(ResponseInputItem.Message.Role.USER)
.addInputTextContent("Summarize this PDF.")
.addContent(file)
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.inputOfResponse(List.of(userMsg))
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": [
{
"role": "user",
"content": [
{"type": "input_file", "filename": "PDF-FILE-NAME.pdf", "file_data": "data:application/pdf;base64,<BASE64_PDF>"},
{"type": "input_text", "text": "Summarize this PDF."}
]
}
]
}'
Caricare pdf e analizzare
Caricare il file PDF con purpose="assistants". Un purpose di user_data non è attualmente supportato.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
file = client.files.create(
file=open("nucleus_sampling.pdf", "rb"),
purpose="assistants"
)
response = client.responses.create(
model="MODEL_NAME",
input=[
{
"role": "user",
"content": [
{"type": "input_file", "file_id": file.id},
{"type": "input_text", "text": "Summarize this PDF."},
],
},
]
)
print(response.output_text)
#pragma warning disable OPENAI001
using System.IO;
using System.Threading.Tasks;
using Azure.Identity;
using OpenAI;
using OpenAI.Files;
using OpenAI.Responses;
using System.ClientModel;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
OpenAIFileClient fileClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new OpenAIClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
byte[] pdfBytes = await File.ReadAllBytesAsync("nucleus_sampling.pdf");
OpenAIFile uploadedFile = await fileClient.UploadFileAsync(
BinaryData.FromBytes(pdfBytes),
"nucleus_sampling.pdf",
FileUploadPurpose.Assistants);
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem(
[
ResponseContentPart.CreateInputFilePart(uploadedFile.Id),
ResponseContentPart.CreateInputTextPart("Summarize this PDF.")
])
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import fs from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const file = await client.files.create({
file: fs.createReadStream("nucleus_sampling.pdf"),
purpose: "assistants",
});
const response = await client.responses.create({
model: "MODEL_NAME",
input: [
{
role: "user",
content: [
{ type: "input_file", file_id: file.id },
{ type: "input_text", text: "Summarize this PDF." },
],
},
],
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.files.FileCreateParams;
import com.openai.models.files.FileObject;
import com.openai.models.files.FilePurpose;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputFile;
import com.openai.models.responses.ResponseInputItem;
import java.nio.file.Paths;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
FileObject uploaded = openAIClient.files().create(
FileCreateParams.builder()
.file(Paths.get("document.pdf"))
.purpose(FilePurpose.ASSISTANTS)
.build());
ResponseInputFile file = ResponseInputFile.builder()
.fileId(uploaded.id())
.build();
ResponseInputItem userMsg = ResponseInputItem.ofMessage(
ResponseInputItem.Message.builder()
.role(ResponseInputItem.Message.Role.USER)
.addInputTextContent("Summarize this PDF.")
.addContent(file)
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.inputOfResponse(List.of(userMsg))
.build());
System.out.println(response.outputText());
# Upload the PDF
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/files \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-F purpose="assistants" \
-F file="@your_file.pdf"
# Use the returned file ID with Responses
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": [
{
"role": "user",
"content": [
{"type": "input_file", "file_id": "<file_id>"},
{"type": "input_text", "text": "Summarize this PDF."}
]
}
]
}'
Analizzare un PDF da un URL di file esterno
Fare riferimento a un PDF ospitato in un URL accessibile pubblicamente usando la file_url proprietà di un input_file elemento di contenuto. Non è necessario scaricare, codificare o caricare prima il file.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
input=[
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Analyze the letter and provide a summary of the key points.",
},
{
"type": "input_file",
"file_url": "https://www.berkshirehathaway.com/letters/2024ltr.pdf",
},
],
},
]
)
print(response.output_text)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem(
[
ResponseContentPart.CreateInputTextPart("Analyze the letter and provide a summary of the key points."),
ResponseContentPart.CreateInputFilePart(new Uri("https://www.berkshirehathaway.com/letters/2024ltr.pdf"))
])
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
input: [
{
role: "user",
content: [
{
type: "input_text",
text: "Analyze the letter and provide a summary of the key points.",
},
{
type: "input_file",
file_url: "https://www.berkshirehathaway.com/letters/2024ltr.pdf",
},
],
},
],
});
console.log(response.output_text);
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputFile;
import com.openai.models.responses.ResponseInputItem;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
ResponseInputFile file = ResponseInputFile.builder()
.fileUrl("https://www.berkshirehathaway.com/letters/2024ltr.pdf")
.build();
ResponseInputItem userMsg = ResponseInputItem.ofMessage(
ResponseInputItem.Message.builder()
.role(ResponseInputItem.Message.Role.USER)
.addInputTextContent("Analyze the letter and provide a summary of the key points.")
.addContent(file)
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.inputOfResponse(List.of(userMsg))
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Analyze the letter and provide a summary of the key points."
},
{
"type": "input_file",
"file_url": "https://www.berkshirehathaway.com/letters/2024ltr.pdf"
}
]
}
]
}'
Uso di server MCP remoti
È possibile estendere le funzionalità del modello collegandola agli strumenti ospitati in server MCP (Remote Model Context Protocol). Questi server vengono gestiti da sviluppatori e organizzazioni ed espongono strumenti accessibili dai client compatibili con MCP, ad esempio l'API Risposte.
Model Context Protocol (MCP) è uno standard aperto che definisce il modo in cui le applicazioni forniscono strumenti e dati contestuali a modelli di linguaggio di grandi dimensioni. Consente l'integrazione coerente e scalabile di strumenti esterni nei flussi di lavoro del modello.
L'esempio seguente illustra come usare un server MCP remoto per eseguire query su informazioni su un repository dell'API REST Azure. Il modello recupera il contenuto del repository e ragiona su di esso in tempo reale.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
tools=[
{
"type": "mcp",
"server_label": "github",
"server_url": "https://contoso.com/Azure/azure-rest-api-specs",
"require_approval": "never"
}
],
input="What transport protocols are supported in the 2025-03-26 version of the MCP spec?"
)
print(response.output_text)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("What transport protocols are supported in the 2025-03-26 version of the MCP spec?") },
Tools =
{
new McpTool(serverLabel: "github", serverUri: new Uri("https://contoso.com/Azure/azure-rest-api-specs"))
{
ToolCallApprovalPolicy = GlobalMcpToolCallApprovalPolicy.NeverRequireApproval
}
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
tools: [
{
type: "mcp",
server_label: "github",
server_url: "https://contoso.com/Azure/azure-rest-api-specs",
require_approval: "never",
},
],
input: "What is this repo in 100 words?",
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.Tool;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Tool mcpTool = Tool.ofMcp(
Tool.Mcp.builder()
.serverLabel("github")
.serverUrl("https://contoso.com/Azure/azure-rest-api-specs")
.requireApproval(Tool.Mcp.RequireApproval.ofMcpToolApprovalSetting(
Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER))
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("What is this repo in 100 words?")
.addTool(mcpTool)
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"tools": [
{
"type": "mcp",
"server_label": "github",
"server_url": "https://contoso.com/Azure/azure-rest-api-specs",
"require_approval": "never"
}
],
"input": "What is this repo in 100 words?"
}'
Lo strumento MCP funziona solo nell'API Risposte ed è disponibile in tutti i modelli più recenti (gpt-4o, gpt-4.1 e i modelli di ragionamento). Quando si usa lo strumento MCP, si paga solo per i token usati durante l'importazione di definizioni degli strumenti o l'esecuzione di chiamate agli strumenti, senza costi aggiuntivi.
Approvazioni
Per impostazione predefinita, l'API Risposte richiede l'approvazione esplicita prima che tutti i dati vengano condivisi con un server MCP remoto. Questo passaggio di approvazione consente di garantire la trasparenza e di controllare le informazioni inviate esternamente.
È consigliabile esaminare tutti i dati condivisi con i server MCP remoti e, facoltativamente, registrarlo a scopo di controllo.
Quando è necessaria un'approvazione, il modello restituisce un mcp_approval_request elemento nell'output della risposta. Questo oggetto contiene i dettagli della richiesta in sospeso e consente di esaminare o modificare i dati prima di procedere.
{
"id": "mcpr_682bd9cd428c8198b170dc6b549d66fc016e86a03f4cc828",
"type": "mcp_approval_request",
"arguments": {},
"name": "fetch_azure_rest_api_docs",
"server_label": "github"
}
Per procedere con la chiamata MCP remota, è necessario rispondere alla richiesta di approvazione creando un nuovo oggetto risposta che include un elemento mcp_approval_response. Questo oggetto conferma la finalità di consentire al modello di inviare i dati specificati al server MCP remoto.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
tools=[
{
"type": "mcp",
"server_label": "github",
"server_url": "https://contoso.com/Azure/azure-rest-api-specs",
"require_approval": "never"
}
],
previous_response_id="<previous_response_id>",
input=[
{
"type": "mcp_approval_response",
"approve": True,
"approval_request_id": "<approval_request_id>"
}
]
)
print(response.output_text)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
McpTool mcpTool = new(serverLabel: "github", serverUri: new Uri("https://contoso.com/Azure/azure-rest-api-specs"));
ResponseResult priorResponse = await openAIClient.GetResponseAsync("<previous_response_id>");
foreach (ResponseItem item in priorResponse.OutputItems)
{
if (item is McpToolCallApprovalRequestItem approvalRequest)
{
CreateResponseOptions followUp = new()
{
Model = "MODEL_NAME",
PreviousResponseId = priorResponse.Id,
InputItems = { new McpToolCallApprovalResponseItem(approvalRequest.Id, approved: true) },
Tools = { mcpTool }
};
ResponseResult finalResponse = await openAIClient.CreateResponseAsync(followUp);
Console.WriteLine(finalResponse.GetOutputText());
}
}
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
tools: [
{
type: "mcp",
server_label: "github",
server_url: "https://contoso.com/Azure/azure-rest-api-specs",
require_approval: "never",
},
],
previous_response_id: "<previous_response_id>",
input: [
{
type: "mcp_approval_response",
approve: true,
approval_request_id: "<approval_request_id>",
},
],
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.List;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.previousResponseId("<previous_response_id>")
.inputOfResponse(List.of(
ResponseInputItem.ofMcpApprovalResponse(
ResponseInputItem.McpApprovalResponse.builder()
.approvalRequestId("<approval_request_id>")
.approve(true)
.build())))
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"tools": [
{
"type": "mcp",
"server_label": "github",
"server_url": "https://contoso.com/Azure/azure-rest-api-specs",
"require_approval": "never"
}
],
"previous_response_id": "<previous_response_id>",
"input": [
{
"type": "mcp_approval_response",
"approve": true,
"approval_request_id": "<approval_request_id>"
}
]
}'
Autenticazione
Importante
- Il client MCP all'interno dell'API Risposte richiede TLS 1.2 o versione successiva.
- Mutual TLS (mTLS) attualmente non è supportato.
-
Tag di servizio di Azure non è attualmente supportato per il traffico client MCP.
A differenza del server MCP GitHub, la maggior parte dei server MCP remoti richiede l'autenticazione. Lo strumento MCP nell'API Risposte supporta intestazioni personalizzate, consentendo di connettersi in modo sicuro a questi server usando lo schema di autenticazione richiesto.
È possibile specificare intestazioni come chiavi API, token di accesso OAuth o altre credenziali direttamente nella richiesta. L'intestazione più comunemente usata è l'intestazione Authorization .
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
input="What is this repo in 100 words?",
tools=[
{
"type": "mcp",
"server_label": "github",
"server_url": "https://contoso.com/Azure/azure-rest-api-specs",
"headers": {"Authorization": "Bearer $YOUR_MCP_TOKEN"}
}
]
)
print(response.output_text)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("What is this repo in 100 words?") },
Tools =
{
new McpTool(serverLabel: "github", serverUri: new Uri("https://contoso.com/Azure/azure-rest-api-specs"))
{
AuthorizationToken = Environment.GetEnvironmentVariable("YOUR_MCP_TOKEN"),
ToolCallApprovalPolicy = GlobalMcpToolCallApprovalPolicy.NeverRequireApproval
}
}
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
input: "What is this repo in 100 words?",
tools: [
{
type: "mcp",
server_label: "github",
server_url: "https://contoso.com/Azure/azure-rest-api-specs",
headers: { Authorization: "Bearer $YOUR_MCP_TOKEN" },
},
],
});
console.log(response.output_text);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.Tool;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Tool mcpTool = Tool.ofMcp(
Tool.Mcp.builder()
.serverLabel("github")
.serverUrl("https://contoso.com/Azure/azure-rest-api-specs")
.headers(Tool.Mcp.Headers.builder()
.putAdditionalProperty("Authorization", JsonValue.from("Bearer $YOUR_MCP_TOKEN"))
.build())
.requireApproval(Tool.Mcp.RequireApproval.ofMcpToolApprovalSetting(
Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER))
.build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("What is this repo in 100 words?")
.addTool(mcpTool)
.build());
System.out.println(response.outputText());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "What is this repo in 100 words?",
"tools": [
{
"type": "mcp",
"server_label": "github",
"server_url": "https://contoso.com/Azure/azure-rest-api-specs",
"headers": {"Authorization": "Bearer $YOUR_MCP_TOKEN"}
}
]
}'
Attività in background
La modalità in background consente di eseguire attività con esecuzione prolungata in modo asincrono con modelli di ragionamento come o3 e o1-pro. È utile per le attività complesse che possono richiedere alcuni minuti per il completamento (ad esempio, agenti di tipo Codex o Deep Research). Quando una richiesta viene inviata con "background": true, l'operazione viene elaborata in modo asincrono e se ne interroga lo stato.
Avviare un'attività in background
Impostare background=true nella richiesta per accodare l'attività. Il servizio restituisce immediatamente un ID di risposta e uno stato queued: usa quell'ID per eseguire il polling, trasmettere in streaming o annullare l'operazione.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="MODEL_NAME",
input="Write me a very long story.",
background=True
)
print(response.status)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("Write me a very long story.") },
BackgroundModeEnabled = true
};
ResponseResult queued = await openAIClient.CreateResponseAsync(options);
Console.WriteLine($"Response id: {queued.Id}");
Console.WriteLine($"Status: {queued.Status}");
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: process.env.AZURE_OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "MODEL_NAME",
input: "Write me a very long story.",
background: true,
});
console.log(response.status);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("Write a 1000-word essay on the history of computing.")
.background(true)
.build());
System.out.println(response.status());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "Write me a very long story.",
"background": true
}'
Poll per completamento
Continuare a eseguire il polling mentre lo stato è queued o in_progress. Quando la risposta raggiunge uno stato terminale, è disponibile per il recupero.
from time import sleep
while response.status in {"queued", "in_progress"}:
print(f"Current status: {response.status}")
sleep(2)
response = client.responses.retrieve(response.id)
print(f"Final status: {response.status}\nOutput:\n{response.output_text}")
#pragma warning disable OPENAI001
using System.Threading.Tasks;
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
ResponseResult current = await openAIClient.GetResponseAsync("<response_id>");
while (current.Status == ResponseStatus.Queued || current.Status == ResponseStatus.InProgress)
{
Console.WriteLine($"Current status: {current.Status}");
await Task.Delay(TimeSpan.FromSeconds(2));
current = await openAIClient.GetResponseAsync(current.Id);
}
Console.WriteLine($"Final status: {current.Status}");
if (current.Status == ResponseStatus.Completed)
{
Console.WriteLine(current.GetOutputText());
}
let current = response;
while (current.status === "queued" || current.status === "in_progress") {
console.log(`Current status: ${current.status}`);
await new Promise((r) => setTimeout(r, 2000));
current = await client.responses.retrieve(current.id);
}
console.log(`Final status: ${current.status}\nOutput:\n${current.output_text}`);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Response current = openAIClient.responses().retrieve("<response_id>");
while (current.status().filter(s ->
s.equals(Response.Status.QUEUED) || s.equals(Response.Status.IN_PROGRESS)).isPresent()) {
System.out.println("Current status: " + current.status());
Thread.sleep(2000);
current = openAIClient.responses().retrieve(current.id());
}
System.out.println("Final status: " + current.status());
System.out.println("Output:\n" + current.outputText());
curl -X GET https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id> \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
Annullare un'attività in background
Annulla un'attività in background in esecuzione con l'endpoint cancel. L'annullamento è idempotente: le chiamate successive restituiscono l'oggetto di risposta finale.
response = client.responses.cancel("<response_id>")
print(response.status)
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
ResponseResult cancelled = await openAIClient.CancelResponseAsync("<response_id>");
Console.WriteLine($"Status: {cancelled.Status}");
const cancelled = await client.responses.cancel("<response_id>");
console.log(cancelled.status);
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Response cancelled = openAIClient.responses().cancel("<response_id>");
System.out.println(cancelled.status());
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id>/cancel \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
Per trasmettere una risposta in background, impostare sia background che stream su true. Questo modello consente di riprendere lo streaming in caso di eliminazione della connessione. Tieni traccia della tua posizione con sequence_number di ogni evento.
stream = client.responses.create(
model="MODEL_NAME",
input="Write me a very long story.",
background=True,
stream=True,
)
cursor = None
for event in stream:
print(event)
cursor = event["sequence_number"]
#pragma warning disable OPENAI001
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
CreateResponseOptions createOptions = new()
{
Model = "MODEL_NAME",
InputItems = { ResponseItem.CreateUserMessageItem("Write me a very long story.") },
BackgroundModeEnabled = true,
StreamingEnabled = true
};
string queuedResponseId = null;
int lastSequenceNumber = 0;
await foreach (StreamingResponseUpdate update in openAIClient.CreateResponseStreamingAsync(createOptions))
{
if (update is StreamingResponseQueuedUpdate queuedUpdate)
{
queuedResponseId = queuedUpdate.Response.Id;
lastSequenceNumber = queuedUpdate.SequenceNumber;
Console.WriteLine($"Queued response: {queuedResponseId}, sequence {lastSequenceNumber}");
break;
}
}
// Resume streaming from where we disconnected.
GetResponseOptions resumeOptions = new(queuedResponseId)
{
StartingAfter = lastSequenceNumber,
StreamingEnabled = true
};
await foreach (StreamingResponseUpdate update in openAIClient.GetResponseStreamingAsync(resumeOptions))
{
Console.WriteLine(update.GetType().Name);
if (update is StreamingResponseCompletedUpdate completed)
{
Console.WriteLine($"[done] final id: {completed.Response.Id}");
}
}
const stream = await client.responses.create({
model: "MODEL_NAME",
input: "Write me a very long story.",
background: true,
stream: true,
});
let cursor = null;
for await (const event of stream) {
console.log(event);
cursor = event.sequence_number;
}
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.ResponseRetrieveParams;
import com.openai.models.responses.ResponseStreamEvent;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
long cursor = 0L;
try (StreamResponse<ResponseStreamEvent> stream = openAIClient.responses().retrieveStreaming(
"<response_id>",
ResponseRetrieveParams.builder().startingAfter(cursor).build())) {
stream.stream().forEach(event -> System.out.println(event));
}
curl -N -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "MODEL_NAME",
"input": "Write me a very long story.",
"background": true,
"stream": true
}'
Le risposte in background hanno attualmente una latenza di tempo per il primo token più elevata rispetto alle risposte sincrone. Sono in corso miglioramenti per ridurre questo divario.
Limitazioni
- La modalità in background richiede
store=true. Le richieste senza stato non sono supportate.
- È possibile riprendere lo streaming solo se la richiesta originale includeva
stream=true.
- Per annullare una risposta sincrona, terminare direttamente la connessione.
Riprendere lo streaming da un punto specifico
Se una connessione di streaming si interrompe, è possibile riprendere da un evento noto passando stream=true insieme a starting_after=<sequence_number> in una GET alla risposta. Il servizio ripete gli eventi emessi dopo quel numero di sequenza.
curl -N -X GET "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses/<response_id>?stream=true&starting_after=42" \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
Ragionamento crittografato
Quando si usa un modello di ragionamento con la Responses API in modalità senza stato (store=false), l'applicazione fornisce il contesto per ogni richiesta successiva. I messaggi precedenti forniscono la cronologia delle conversazioni, ma non contengono il ragionamento interno del modello. Un elemento di ragionamento crittografato consente di trasferire un contesto di ragionamento compatibile in una richiesta successiva senza esporre tale ragionamento come testo leggibile all'applicazione.
Perché usare il ragionamento crittografato?
Usare il ragionamento crittografato quando l'applicazione gestisce lo stato della conversazione e deve continuare un flusso di lavoro di ragionamento a più turni. Ad esempio, un utente potrebbe porre una domanda successiva oppure il modello potrebbe chiamare uno strumento e quindi continuare dopo aver ricevuto il risultato.
Il passaggio dei messaggi precedenti da solo non passa il contesto di ragionamento del modello dal turno precedente. Un elemento di ragionamento crittografato mantiene il contesto conservando il contenuto opaco per l'applicazione.
Modalità d'uso
- Imposta
store=false. Per richiedere in modo esplicito il ragionamento crittografato, aggiungere reasoning.encrypted_content al include parametro , come illustrato negli esempi seguenti.
- Mantenere tutti gli elementi di output restituiti nell'ordine originale, inclusi gli elementi di ragionamento con una proprietà
encrypted_content.
- Nella chiamata successiva includere tali elementi con gli altri elementi di conversazione pertinenti in
inpute continuare a impostare store=false. Non usare previous_response_id per una risposta non memorizzata.
Le risposte senza stato restituiscono contenuto crittografato per impostazione predefinita; il include parametro rimane supportato per la compatibilità. La riproduzione di un elemento rende disponibile un ragionamento compatibile, ma il ragionamento usato dal modello dipende dalla modalità di contesto di ragionamento supportata. Per informazioni dettagliate, vedere Conservare il ragionamento tra le chiamate.
In modalità senza stato, l'elemento di ragionamento crittografato viene restituito all'applicazione. L'applicazione è responsabile di conservarlo in modo sicuro e di ritrasmetterlo in una richiesta successiva. Scegliere un percorso di archiviazione sul lato applicazione che soddisfi i requisiti di sicurezza e ciclo di vita.
Gli esempi seguenti utilizzano l'autenticazione tramite chiave API. Gli esempi di Python usano la libreria client OpenAI. Gli altri esempi chiamano direttamente l'endpoint REST Responses e mantengono gli elementi di output completi come JSON.
Installare le dipendenze per la tua lingua:
-
Python: installare il client con
pip install --upgrade openai.
-
C#: usare un'applicazione console .NET 8 o versione successiva. Non sono necessari pacchetti aggiuntivi.
-
JavaScript: usare Node.js 18 o versione successiva e salvare ogni esempio come un file
.mjs. Non sono necessari pacchetti aggiuntivi.
-
Java: Usare JDK 17 o versione successiva e aggiungere la dipendenza Maven
com.fasterxml.jackson.core:jackson-databind:2.22.4. Salvare ogni esempio con il nome del file visualizzato nella relativa scheda.
-
REST: eseguire gli esempi di PowerShell con PowerShell 7 o versione successiva.
Impostare queste variabili di ambiente per ogni lingua:
-
AZURE_OPENAI_ENDPOINT: Il tuo endpoint della risorsa, ad esempio https://YOUR-RESOURCE-NAME.openai.azure.com.
-
AZURE_OPENAI_API_KEY: La tua chiave API.
-
AZURE_OPENAI_DEPLOYMENT: nome di un deployment supportato del modello di ragionamento.
Entrambi gli esempi controllano la presenza di un elemento di ragionamento crittografato e generano un errore se non viene restituito nessuno. Usare una configurazione di deployment e ragionamento che produce elementi di ragionamento per le richieste di esempio.
Continuare una conversazione senza stato
Questo esempio mantiene gli elementi restituiti in un elenco gestito dall'applicazione e li passa a una richiesta successiva.
import os
from openai import BadRequestError, OpenAI
client = OpenAI(
api_key=os.environ["AZURE_OPENAI_API_KEY"],
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
)
deployment = os.environ["AZURE_OPENAI_DEPLOYMENT"]
# Application-managed state. This example keeps it in memory.
conversation = [
{"role": "user", "content": "Explain the trade-offs of this design."}
]
def add_response_items(response):
items = [item.model_dump(exclude_none=True) for item in response.output]
if not any(
item.get("type") == "reasoning" and item.get("encrypted_content")
for item in items
):
raise RuntimeError(
"No encrypted reasoning item was returned. Check the deployment "
"and the request's include parameter."
)
# Preserve the returned items, including encrypted reasoning.
conversation.extend(items)
try:
first = client.responses.create(
model=deployment,
input=conversation,
store=False,
include=["reasoning.encrypted_content"],
)
add_response_items(first)
print("First answer:", first.output_text)
conversation.append({
"role": "user",
"content": "Which trade-off matters most for reliability?",
})
second = client.responses.create(
model=deployment,
input=conversation,
store=False,
include=["reasoning.encrypted_content"],
)
add_response_items(second)
print("Follow-up answer:", second.output_text)
except BadRequestError as exc:
# Inspect the service error before deciding whether to restart.
print(f"Request rejected: {exc}")
raise
using System;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
string endpoint = RequiredEnvironment("AZURE_OPENAI_ENDPOINT").TrimEnd('/');
string deployment = RequiredEnvironment("AZURE_OPENAI_DEPLOYMENT");
using HttpClient openAIClient = new();
openAIClient.DefaultRequestHeaders.Add(
"api-key", RequiredEnvironment("AZURE_OPENAI_API_KEY"));
// Application-managed state. Preserve each complete output item.
JsonArray conversation = new()
{
new JsonObject
{
["role"] = "user",
["content"] = "Explain the trade-offs of this design."
}
};
JsonObject first = await CreateResponseAsync();
AddResponseItems(first);
Console.WriteLine($"First answer: {GetOutputText(first)}");
conversation.Add(new JsonObject
{
["role"] = "user",
["content"] = "Which trade-off matters most for reliability?"
});
JsonObject second = await CreateResponseAsync();
AddResponseItems(second);
Console.WriteLine($"Follow-up answer: {GetOutputText(second)}");
async Task<JsonObject> CreateResponseAsync()
{
JsonObject request = new()
{
["model"] = deployment,
["input"] = conversation.DeepClone(),
["store"] = false,
["include"] = new JsonArray("reasoning.encrypted_content")
};
using StringContent content = new(
request.ToJsonString(), Encoding.UTF8, "application/json");
using HttpResponseMessage response = await openAIClient.PostAsync(
$"{endpoint}/openai/v1/responses", content);
string body = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(
$"Request rejected ({(int)response.StatusCode}): {body}");
}
return JsonNode.Parse(body)?.AsObject()
?? throw new InvalidOperationException("No response body was returned.");
}
void AddResponseItems(JsonObject response)
{
JsonArray items = response["output"]?.AsArray()
?? throw new InvalidOperationException("No output items were returned.");
if (!items.OfType<JsonObject>().Any(item =>
item["type"]?.GetValue<string>() == "reasoning" &&
!string.IsNullOrEmpty(item["encrypted_content"]?.GetValue<string>())))
{
throw new InvalidOperationException(
"No encrypted reasoning item was returned.");
}
foreach (JsonNode? item in items)
{
conversation.Add(item?.DeepClone()
?? throw new InvalidOperationException("An output item was null."));
}
}
static string GetOutputText(JsonObject response) => string.Concat(
response["output"]!.AsArray().OfType<JsonObject>()
.Where(item => item["type"]?.GetValue<string>() == "message")
.SelectMany(item => item["content"]!.AsArray().OfType<JsonObject>())
.Where(part => part["type"]?.GetValue<string>() == "output_text")
.Select(part => part["text"]!.GetValue<string>()));
static string RequiredEnvironment(string name)
{
string? value = Environment.GetEnvironmentVariable(name);
return !string.IsNullOrEmpty(value) ? value
: throw new InvalidOperationException($"Set {name} before running.");
}
const requiredEnvironment = (name) => {
const value = process.env[name];
if (!value) throw new Error(`Set ${name} before running.`);
return value;
};
const endpoint = requiredEnvironment("AZURE_OPENAI_ENDPOINT").replace(/\/+$/, "");
const deployment = requiredEnvironment("AZURE_OPENAI_DEPLOYMENT");
const apiKey = requiredEnvironment("AZURE_OPENAI_API_KEY");
// Application-managed state. Preserve each complete output item.
const conversation = [
{ role: "user", content: "Explain the trade-offs of this design." },
];
async function createResponse() {
const response = await fetch(`${endpoint}/openai/v1/responses`, {
method: "POST",
headers: { "Content-Type": "application/json", "api-key": apiKey },
body: JSON.stringify({
model: deployment,
input: conversation,
store: false,
include: ["reasoning.encrypted_content"],
}),
});
if (!response.ok) {
throw new Error(
`Request rejected (${response.status}): ${await response.text()}`,
);
}
return response.json();
}
function addResponseItems(response) {
if (!Array.isArray(response.output)) {
throw new Error("No output items were returned.");
}
if (!response.output.some(
(item) => item.type === "reasoning" && item.encrypted_content,
)) {
throw new Error("No encrypted reasoning item was returned.");
}
conversation.push(...response.output);
}
function getOutputText(response) {
return response.output
.filter((item) => item.type === "message")
.flatMap((item) => item.content)
.filter((part) => part.type === "output_text")
.map((part) => part.text)
.join("");
}
const first = await createResponse();
addResponseItems(first);
console.log("First answer:", getOutputText(first));
conversation.push({
role: "user",
content: "Which trade-off matters most for reliability?",
});
const second = await createResponse();
addResponseItems(second);
console.log("Follow-up answer:", getOutputText(second));
Salva questo esempio come StatelessConversation.java.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class StatelessConversation {
private static final ObjectMapper JSON = new ObjectMapper();
public static void main(String[] args) throws Exception {
String endpoint = requiredEnvironment("AZURE_OPENAI_ENDPOINT")
.replaceAll("/+$", "");
String deployment = requiredEnvironment("AZURE_OPENAI_DEPLOYMENT");
String apiKey = requiredEnvironment("AZURE_OPENAI_API_KEY");
HttpClient openAIClient = HttpClient.newHttpClient();
// Application-managed state. Preserve each complete output item.
ArrayNode conversation = JSON.createArrayNode();
conversation.add(JSON.createObjectNode()
.put("role", "user")
.put("content", "Explain the trade-offs of this design."));
JsonNode first = createResponse(
openAIClient, endpoint, apiKey, deployment, conversation);
addResponseItems(conversation, first);
System.out.println("First answer: " + getOutputText(first));
conversation.add(JSON.createObjectNode()
.put("role", "user")
.put("content", "Which trade-off matters most for reliability?"));
JsonNode second = createResponse(
openAIClient, endpoint, apiKey, deployment, conversation);
addResponseItems(conversation, second);
System.out.println("Follow-up answer: " + getOutputText(second));
}
private static JsonNode createResponse(
HttpClient openAIClient, String endpoint, String apiKey,
String deployment, ArrayNode conversation) throws Exception {
ObjectNode payload = JSON.createObjectNode();
payload.put("model", deployment);
payload.set("input", conversation);
payload.put("store", false);
payload.set("include", JSON.createArrayNode()
.add("reasoning.encrypted_content"));
HttpRequest request = HttpRequest.newBuilder(
URI.create(endpoint + "/openai/v1/responses"))
.header("Content-Type", "application/json")
.header("api-key", apiKey)
.POST(HttpRequest.BodyPublishers.ofString(
JSON.writeValueAsString(payload)))
.build();
HttpResponse<String> response = openAIClient.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IllegalStateException(
"Request rejected (" + response.statusCode() + "): "
+ response.body());
}
return JSON.readTree(response.body());
}
private static void addResponseItems(
ArrayNode conversation, JsonNode response) {
JsonNode items = response.get("output");
if (items == null || !items.isArray()) {
throw new IllegalStateException("No output items were returned.");
}
boolean hasEncryptedReasoning = false;
for (JsonNode item : items) {
JsonNode encrypted = item.get("encrypted_content");
if ("reasoning".equals(item.path("type").asText())
&& encrypted != null && encrypted.isTextual()
&& !encrypted.asText().isEmpty()) {
hasEncryptedReasoning = true;
}
}
if (!hasEncryptedReasoning) {
throw new IllegalStateException(
"No encrypted reasoning item was returned.");
}
for (JsonNode item : items) {
conversation.add(item);
}
}
private static String getOutputText(JsonNode response) {
StringBuilder text = new StringBuilder();
for (JsonNode item : response.get("output")) {
if ("message".equals(item.path("type").asText())) {
for (JsonNode part : item.get("content")) {
if ("output_text".equals(part.path("type").asText())) {
text.append(part.get("text").asText());
}
}
}
}
return text.toString();
}
private static String requiredEnvironment(String name) {
String value = System.getenv(name);
if (value == null || value.isEmpty()) {
throw new IllegalStateException("Set " + name + " before running.");
}
return value;
}
}
Questo esempio di PowerShell invia richieste JSON direttamente all'endpoint REST.
$ErrorActionPreference = "Stop"
foreach ($name in "AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_API_KEY",
"AZURE_OPENAI_DEPLOYMENT") {
if (-not [Environment]::GetEnvironmentVariable($name)) {
throw "Set $name before running."
}
}
$endpoint = $env:AZURE_OPENAI_ENDPOINT.TrimEnd("/")
$deployment = $env:AZURE_OPENAI_DEPLOYMENT
$headers = @{ "api-key" = $env:AZURE_OPENAI_API_KEY }
# Application-managed state. Preserve each complete output item.
$conversation = [System.Collections.Generic.List[object]]::new()
$conversation.Add(@{
role = "user"
content = "Explain the trade-offs of this design."
})
function New-Response {
$body = @{
model = $deployment
input = $conversation.ToArray()
store = $false
include = @("reasoning.encrypted_content")
} | ConvertTo-Json -Depth 100
Invoke-RestMethod -Method Post -Uri "$endpoint/openai/v1/responses" `
-Headers $headers -ContentType "application/json" -Body $body
}
function Add-ResponseItems($response) {
$items = @($response.output)
if (-not ($items | Where-Object {
$_.type -eq "reasoning" -and $_.encrypted_content
})) {
throw "No encrypted reasoning item was returned."
}
foreach ($item in $items) {
$conversation.Add($item)
}
}
function Get-OutputText($response) {
$parts = foreach ($item in $response.output) {
if ($item.type -eq "message") {
foreach ($part in $item.content) {
if ($part.type -eq "output_text") { $part.text }
}
}
}
$parts -join ""
}
$first = New-Response
Add-ResponseItems $first
Write-Output "First answer: $(Get-OutputText $first)"
$conversation.Add(@{
role = "user"
content = "Which trade-off matters most for reliability?"
})
$second = New-Response
Add-ResponseItems $second
Write-Output "Follow-up answer: $(Get-OutputText $second)"
L'esempio stampa la prima risposta e la risposta successiva. Mantiene tutti gli elementi di output, incluso il ragionamento crittografato, anziché solo la risposta leggibile.
L'elenco conversation è il punto in cui l'applicazione di esempio mantiene gli elementi. Viene mantenuto in memoria e non sopravvive a un riavvio del processo. Un'applicazione che deve riprendere in un secondo momento deve scegliere e proteggere il proprio spazio di archiviazione.
In questo esempio vengono mantenuti il ragionamento e gli elementi della chiamata di funzione, viene eseguita una funzione di esempio e ne viene restituito il risultato usando call_id corrispondente.
import json
import os
from openai import BadRequestError, OpenAI
client = OpenAI(
api_key=os.environ["AZURE_OPENAI_API_KEY"],
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
)
deployment = os.environ["AZURE_OPENAI_DEPLOYMENT"]
tools = [{
"type": "function",
"name": "get_order_status",
"description": "Look up the status of an example order.",
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "string"}
},
"required": ["order_id"],
"additionalProperties": False,
},
}]
def get_order_status(order_id):
# Replace this example with your own trusted data source.
if order_id == "A123":
return {"order_id": order_id, "status": "Shipped"}
return {"order_id": order_id, "status": "Not found"}
conversation = [{
"role": "user",
"content": "What is the status of order A123?",
}]
def create_response():
return client.responses.create(
model=deployment,
input=conversation,
tools=tools,
store=False,
include=["reasoning.encrypted_content"],
)
try:
# Bound the number of tool rounds.
for _ in range(3):
response = create_response()
items = [item.model_dump(exclude_none=True) for item in response.output]
if not any(
item.get("type") == "reasoning" and item.get("encrypted_content")
for item in items
):
raise RuntimeError("No encrypted reasoning item was returned.")
# Preserve returned items in order, including reasoning and tool calls.
conversation.extend(items)
calls = [
item for item in response.output
if item.type == "function_call"
]
if not calls:
print(response.output_text)
break
for call in calls:
if call.name != "get_order_status":
raise ValueError(f"Unexpected tool: {call.name}")
arguments = json.loads(call.arguments)
result = get_order_status(arguments["order_id"])
conversation.append({
"type": "function_call_output",
"call_id": call.call_id,
"output": json.dumps(result),
})
else:
raise RuntimeError("The tool-call limit was reached.")
except BadRequestError as exc:
print(f"Request rejected: {exc}")
raise
using System;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
string endpoint = RequiredEnvironment("AZURE_OPENAI_ENDPOINT").TrimEnd('/');
string deployment = RequiredEnvironment("AZURE_OPENAI_DEPLOYMENT");
using HttpClient openAIClient = new();
openAIClient.DefaultRequestHeaders.Add(
"api-key", RequiredEnvironment("AZURE_OPENAI_API_KEY"));
JsonArray tools = JsonNode.Parse("""
[
{
"type": "function",
"name": "get_order_status",
"description": "Look up the status of an example order.",
"parameters": {
"type": "object",
"properties": { "order_id": { "type": "string" } },
"required": ["order_id"],
"additionalProperties": false
}
}
]
""")!.AsArray();
JsonArray conversation = new()
{
new JsonObject
{
["role"] = "user",
["content"] = "What is the status of order A123?"
}
};
// Preserve reasoning and tool calls before appending each tool result.
for (int round = 0; round < 3; round++)
{
JsonObject response = await CreateResponseAsync();
JsonArray items = response["output"]?.AsArray()
?? throw new InvalidOperationException("No output items were returned.");
if (!items.OfType<JsonObject>().Any(item =>
item["type"]?.GetValue<string>() == "reasoning" &&
!string.IsNullOrEmpty(item["encrypted_content"]?.GetValue<string>())))
{
throw new InvalidOperationException(
"No encrypted reasoning item was returned.");
}
foreach (JsonNode? item in items)
{
conversation.Add(item?.DeepClone()
?? throw new InvalidOperationException("An output item was null."));
}
JsonObject[] calls = items.OfType<JsonObject>()
.Where(item => item["type"]?.GetValue<string>() == "function_call")
.ToArray();
if (calls.Length == 0)
{
Console.WriteLine(GetOutputText(response));
return;
}
foreach (JsonObject call in calls)
{
if (call["name"]?.GetValue<string>() != "get_order_status")
{
throw new InvalidOperationException($"Unexpected tool: {call["name"]}");
}
JsonObject arguments = JsonNode.Parse(
call["arguments"]!.GetValue<string>())?.AsObject()
?? throw new InvalidOperationException("Invalid tool arguments.");
if (arguments["order_id"] is not JsonValue orderIdNode ||
!orderIdNode.TryGetValue<string>(out string? orderId) ||
orderId is null)
{
throw new InvalidOperationException("Missing or invalid order_id.");
}
// Replace this example data with your own trusted data source.
JsonObject result = new()
{
["order_id"] = orderId,
["status"] = orderId == "A123" ? "Shipped" : "Not found"
};
conversation.Add(new JsonObject
{
["type"] = "function_call_output",
["call_id"] = call["call_id"]!.GetValue<string>(),
["output"] = result.ToJsonString()
});
}
}
throw new InvalidOperationException("The tool-call limit was reached.");
async Task<JsonObject> CreateResponseAsync()
{
JsonObject request = new()
{
["model"] = deployment,
["input"] = conversation.DeepClone(),
["tools"] = tools.DeepClone(),
["store"] = false,
["include"] = new JsonArray("reasoning.encrypted_content")
};
using StringContent content = new(
request.ToJsonString(), Encoding.UTF8, "application/json");
using HttpResponseMessage response = await openAIClient.PostAsync(
$"{endpoint}/openai/v1/responses", content);
string body = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(
$"Request rejected ({(int)response.StatusCode}): {body}");
}
return JsonNode.Parse(body)?.AsObject()
?? throw new InvalidOperationException("No response body was returned.");
}
static string GetOutputText(JsonObject response) => string.Concat(
response["output"]!.AsArray().OfType<JsonObject>()
.Where(item => item["type"]?.GetValue<string>() == "message")
.SelectMany(item => item["content"]!.AsArray().OfType<JsonObject>())
.Where(part => part["type"]?.GetValue<string>() == "output_text")
.Select(part => part["text"]!.GetValue<string>()));
static string RequiredEnvironment(string name)
{
string? value = Environment.GetEnvironmentVariable(name);
return !string.IsNullOrEmpty(value) ? value
: throw new InvalidOperationException($"Set {name} before running.");
}
const requiredEnvironment = (name) => {
const value = process.env[name];
if (!value) throw new Error(`Set ${name} before running.`);
return value;
};
const endpoint = requiredEnvironment("AZURE_OPENAI_ENDPOINT").replace(/\/+$/, "");
const deployment = requiredEnvironment("AZURE_OPENAI_DEPLOYMENT");
const apiKey = requiredEnvironment("AZURE_OPENAI_API_KEY");
const tools = [{
type: "function",
name: "get_order_status",
description: "Look up the status of an example order.",
parameters: {
type: "object",
properties: { order_id: { type: "string" } },
required: ["order_id"],
additionalProperties: false,
},
}];
const conversation = [{
role: "user",
content: "What is the status of order A123?",
}];
async function createResponse() {
const response = await fetch(`${endpoint}/openai/v1/responses`, {
method: "POST",
headers: { "Content-Type": "application/json", "api-key": apiKey },
body: JSON.stringify({
model: deployment,
input: conversation,
tools,
store: false,
include: ["reasoning.encrypted_content"],
}),
});
if (!response.ok) {
throw new Error(
`Request rejected (${response.status}): ${await response.text()}`,
);
}
return response.json();
}
function getOutputText(response) {
return response.output
.filter((item) => item.type === "message")
.flatMap((item) => item.content)
.filter((part) => part.type === "output_text")
.map((part) => part.text)
.join("");
}
// Preserve reasoning and tool calls before appending each tool result.
let completed = false;
for (let round = 0; round < 3; round++) {
const response = await createResponse();
if (!Array.isArray(response.output)) {
throw new Error("No output items were returned.");
}
if (!response.output.some(
(item) => item.type === "reasoning" && item.encrypted_content,
)) {
throw new Error("No encrypted reasoning item was returned.");
}
conversation.push(...response.output);
const calls = response.output.filter((item) => item.type === "function_call");
if (calls.length === 0) {
console.log(getOutputText(response));
completed = true;
break;
}
for (const call of calls) {
if (call.name !== "get_order_status") {
throw new Error(`Unexpected tool: ${call.name}`);
}
const argumentsObject = JSON.parse(call.arguments);
if (typeof argumentsObject.order_id !== "string") {
throw new Error("Missing or invalid order_id.");
}
// Replace this example data with your own trusted data source.
const result = {
order_id: argumentsObject.order_id,
status: argumentsObject.order_id === "A123" ? "Shipped" : "Not found",
};
conversation.push({
type: "function_call_output",
call_id: call.call_id,
output: JSON.stringify(result),
});
}
}
if (!completed) throw new Error("The tool-call limit was reached.");
Salva questo esempio come StatelessToolCalling.java.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
public class StatelessToolCalling {
private static final ObjectMapper JSON = new ObjectMapper();
public static void main(String[] args) throws Exception {
String endpoint = requiredEnvironment("AZURE_OPENAI_ENDPOINT")
.replaceAll("/+$", "");
String deployment = requiredEnvironment("AZURE_OPENAI_DEPLOYMENT");
String apiKey = requiredEnvironment("AZURE_OPENAI_API_KEY");
HttpClient openAIClient = HttpClient.newHttpClient();
JsonNode tools = JSON.readTree("""
[{
"type": "function",
"name": "get_order_status",
"description": "Look up the status of an example order.",
"parameters": {
"type": "object",
"properties": { "order_id": { "type": "string" } },
"required": ["order_id"],
"additionalProperties": false
}
}]
""");
ArrayNode conversation = JSON.createArrayNode();
conversation.add(JSON.createObjectNode()
.put("role", "user")
.put("content", "What is the status of order A123?"));
// Preserve reasoning and tool calls before appending each tool result.
for (int round = 0; round < 3; round++) {
JsonNode response = createResponse(openAIClient, endpoint, apiKey,
deployment, conversation, tools);
JsonNode items = response.get("output");
if (items == null || !items.isArray()) {
throw new IllegalStateException("No output items were returned.");
}
boolean hasEncryptedReasoning = false;
List<JsonNode> calls = new ArrayList<>();
for (JsonNode item : items) {
JsonNode encrypted = item.get("encrypted_content");
if ("reasoning".equals(item.path("type").asText())
&& encrypted != null && encrypted.isTextual()
&& !encrypted.asText().isEmpty()) {
hasEncryptedReasoning = true;
}
if ("function_call".equals(item.path("type").asText())) {
calls.add(item);
}
}
if (!hasEncryptedReasoning) {
throw new IllegalStateException(
"No encrypted reasoning item was returned.");
}
for (JsonNode item : items) {
conversation.add(item);
}
if (calls.isEmpty()) {
System.out.println(getOutputText(response));
return;
}
for (JsonNode call : calls) {
if (!"get_order_status".equals(call.path("name").asText())) {
throw new IllegalArgumentException(
"Unexpected tool: " + call.path("name").asText());
}
JsonNode arguments = JSON.readTree(
call.get("arguments").asText());
JsonNode orderIdNode = arguments.get("order_id");
if (orderIdNode == null || !orderIdNode.isTextual()) {
throw new IllegalArgumentException(
"Missing or invalid order_id.");
}
String orderId = orderIdNode.asText();
// Replace this example data with your trusted data source.
ObjectNode result = JSON.createObjectNode()
.put("order_id", orderId)
.put("status", "A123".equals(orderId)
? "Shipped" : "Not found");
conversation.add(JSON.createObjectNode()
.put("type", "function_call_output")
.put("call_id", call.get("call_id").asText())
.put("output", JSON.writeValueAsString(result)));
}
}
throw new IllegalStateException("The tool-call limit was reached.");
}
private static JsonNode createResponse(
HttpClient openAIClient, String endpoint, String apiKey,
String deployment, ArrayNode conversation,
JsonNode tools) throws Exception {
ObjectNode payload = JSON.createObjectNode();
payload.put("model", deployment);
payload.set("input", conversation);
payload.set("tools", tools);
payload.put("store", false);
payload.set("include", JSON.createArrayNode()
.add("reasoning.encrypted_content"));
HttpRequest request = HttpRequest.newBuilder(
URI.create(endpoint + "/openai/v1/responses"))
.header("Content-Type", "application/json")
.header("api-key", apiKey)
.POST(HttpRequest.BodyPublishers.ofString(
JSON.writeValueAsString(payload)))
.build();
HttpResponse<String> response = openAIClient.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IllegalStateException(
"Request rejected (" + response.statusCode() + "): "
+ response.body());
}
return JSON.readTree(response.body());
}
private static String getOutputText(JsonNode response) {
StringBuilder text = new StringBuilder();
for (JsonNode item : response.get("output")) {
if ("message".equals(item.path("type").asText())) {
for (JsonNode part : item.get("content")) {
if ("output_text".equals(part.path("type").asText())) {
text.append(part.get("text").asText());
}
}
}
}
return text.toString();
}
private static String requiredEnvironment(String name) {
String value = System.getenv(name);
if (value == null || value.isEmpty()) {
throw new IllegalStateException("Set " + name + " before running.");
}
return value;
}
}
Questo esempio di PowerShell invia richieste JSON direttamente all'endpoint REST.
$ErrorActionPreference = "Stop"
foreach ($name in "AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_API_KEY",
"AZURE_OPENAI_DEPLOYMENT") {
if (-not [Environment]::GetEnvironmentVariable($name)) {
throw "Set $name before running."
}
}
$endpoint = $env:AZURE_OPENAI_ENDPOINT.TrimEnd("/")
$deployment = $env:AZURE_OPENAI_DEPLOYMENT
$headers = @{ "api-key" = $env:AZURE_OPENAI_API_KEY }
$tools = @(@{
type = "function"
name = "get_order_status"
description = "Look up the status of an example order."
parameters = @{
type = "object"
properties = @{ order_id = @{ type = "string" } }
required = @("order_id")
additionalProperties = $false
}
})
$conversation = [System.Collections.Generic.List[object]]::new()
$conversation.Add(@{
role = "user"
content = "What is the status of order A123?"
})
function New-Response {
$body = @{
model = $deployment
input = $conversation.ToArray()
tools = $tools
store = $false
include = @("reasoning.encrypted_content")
} | ConvertTo-Json -Depth 100
Invoke-RestMethod -Method Post -Uri "$endpoint/openai/v1/responses" `
-Headers $headers -ContentType "application/json" -Body $body
}
function Get-OutputText($response) {
$parts = foreach ($item in $response.output) {
if ($item.type -eq "message") {
foreach ($part in $item.content) {
if ($part.type -eq "output_text") { $part.text }
}
}
}
$parts -join ""
}
# Preserve reasoning and tool calls before appending each tool result.
$completed = $false
for ($round = 0; $round -lt 3; $round++) {
$response = New-Response
$items = @($response.output)
if (-not ($items | Where-Object {
$_.type -eq "reasoning" -and $_.encrypted_content
})) {
throw "No encrypted reasoning item was returned."
}
foreach ($item in $items) {
$conversation.Add($item)
}
$calls = @($items | Where-Object { $_.type -eq "function_call" })
if ($calls.Count -eq 0) {
Write-Output (Get-OutputText $response)
$completed = $true
break
}
foreach ($call in $calls) {
if ($call.name -cne "get_order_status") {
throw "Unexpected tool: $($call.name)"
}
$arguments = $call.arguments | ConvertFrom-Json
if ($arguments.order_id -isnot [string]) {
throw "Missing or invalid order_id."
}
# Replace this example data with your own trusted data source.
$status = if ($arguments.order_id -ceq "A123") {
"Shipped"
} else {
"Not found"
}
$result = @{
order_id = $arguments.order_id
status = $status
} | ConvertTo-Json -Compress
$conversation.Add(@{
type = "function_call_output"
call_id = $call.call_id
output = $result
})
}
}
if (-not $completed) { throw "The tool-call limit was reached." }
L'esempio stampa la risposta finale del modello dopo aver elaborato lo stato dell'ordine di esempio. La funzione usa dati di esempio, non un sistema di ordini live. Il ciclo limita il numero di richieste di risposta a tre e genera un errore se il modello continua a richiedere gli strumenti.
Mantenere intatti gli elementi di reasoning crittografati; non tentare di leggere o modificare i loro contenuti crittografati. Per le definizioni di funzione e i formati dei risultati degli strumenti, vedere Chiamata di funzioni.
Considerazioni sul routing
Se si esegue il routing attraverso Gestione API di Azure, convalidare la riproduzione crittografata del ragionamento tra i back-end configurati prima di ritenerla attendibile. Se il servizio restituisce invalid_encrypted_content, esaminare l'errore e il routing delle risorse prima di decidere se riavviare la conversazione.
Considerazioni sulla protezione dei dati personali
Gli elementi di reasoning crittografati trasportano un contesto di reasoning opaco tra le richieste. Non descrivono come il servizio crittografa i dati archiviati, quali chiavi proteggono le richieste archiviate o lo stato della conversazione o dove l'applicazione deve archiviare gli elementi restituiti.
L'impostazione di store=false non è una garanzia assoluta di assenza di conservazione in ogni processo di servizio. Per informazioni dettagliate sull'archiviazione sul lato servizio e sul monitoraggio degli abusi, vedere Dati, privacy e sicurezza per Azure OpenAI.
Creazione di immagini
L'API Risposte consente la generazione di immagini come parte di conversazioni e flussi di lavoro con più passaggi. Supporta input e output di immagini all'interno del contesto e include strumenti predefiniti per la generazione e la modifica di immagini.
Rispetto all'API immagine autonoma, l'API Risposte offre due vantaggi:
-
Streaming: consente di visualizzare output di immagini parziali durante la generazione per migliorare la latenza percepita.
-
Input flessibili: accetta gli ID dei file di immagine come input, oltre ai byte grezzi delle immagini.
Nota
Lo strumento di generazione di immagini nell'API Responses è supportato dai modelli della serie gpt-image-1, e puoi richiamarlo da una serie di modelli compatibili per chat e ragionamento. Per l'elenco corrente dei modelli di orchestrazione supportati, vedere la sezione Modelli supportati più avanti in questo articolo.
Lo strumento di generazione di immagini attualmente non supporta la modalità di streaming. Per trasmettere immagini parziali, chiamare l'API di generazione di immagini direttamente all'esterno dell'API Risposte.
Usare l'API Risposte per creare esperienze di immagini conversazionali con modelli di immagine GPT.
import base64
import os
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
default_headers={
"x-ms-oai-image-generation-deployment": os.getenv("IMAGE_MODEL_NAME"),
"api_version": "preview",
},
)
response = client.responses.create(
model="MODEL_NAME",
input="Generate an image of a gray tabby cat hugging an otter with an orange scarf.",
tools=[{"type": "image_generation"}],
)
image_data = [
output.result
for output in response.output
if output.type == "image_generation_call"
]
if image_data:
with open("otter.png", "wb") as f:
f.write(base64.b64decode(image_data[0]))
#pragma warning disable OPENAI001
using System.IO;
using System.Threading.Tasks;
using Azure.Identity;
using OpenAI.Responses;
using System.ClientModel.Primitives;
string endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
// API key authentication
ResponsesClient openAIClient = new(
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!),
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
// Microsoft Entra ID authentication (recommended)
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ResponsesClient openAIClientEntra = new(
authenticationPolicy: tokenPolicy,
options: new ResponsesClientOptions { Endpoint = new Uri(endpoint) });
ImageGenerationTool imageTool = ResponseTool.CreateImageGenerationTool(model: "gpt-image-1");
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem("Generate an image of an otter swimming in a pond.")
},
Tools = { imageTool }
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
foreach (ResponseItem item in response.OutputItems)
{
if (item is ImageGenerationCallResponseItem imageCall && imageCall.ImageResultBytes is not null)
{
await File.WriteAllBytesAsync("otter.png", imageCall.ImageResultBytes.ToArray());
Console.WriteLine($"Saved image. Revised prompt: {imageCall.RevisedPrompt}");
}
}
import fs from "fs";
import OpenAI from "openai";
import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
const tokenProvider = getBearerTokenProvider(
new DefaultAzureCredential(),
"https://ai.azure.com/.default"
);
const client = new OpenAI({
baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
apiKey: await tokenProvider(),
defaultHeaders: {
"x-ms-oai-image-generation-deployment": process.env.IMAGE_MODEL_NAME,
api_version: "preview",
},
});
const response = await client.responses.create({
model: "MODEL_NAME",
input: "Generate an image of a gray tabby cat hugging an otter with an orange scarf.",
tools: [{ type: "image_generation" }],
});
const imageBase64 = response.output
.filter((o) => o.type === "image_generation_call")
.map((o) => o.result)[0];
if (imageBase64) {
fs.writeFileSync("otter.png", Buffer.from(imageBase64, "base64"));
}
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.AuthenticationUtil;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.credential.BearerTokenCredential;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseOutputItem;
import com.openai.models.responses.Tool;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
String endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1";
OpenAIClient openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(endpoint)
.credential(AzureApiKeyCredential.create(System.getenv("AZURE_OPENAI_API_KEY")))
.build();
Tool imageGen = Tool.ofImageGeneration(Tool.ImageGeneration.builder().build());
Response response = openAIClient.responses().create(
ResponseCreateParams.builder()
.model("MODEL_NAME")
.input("Generate an image of a gray tabby cat hugging an otter with an orange scarf.")
.addTool(imageGen)
.build());
response.output().stream()
.filter(ResponseOutputItem::isImageGenerationCall)
.map(ResponseOutputItem::asImageGenerationCall)
.findFirst()
.flatMap(call -> call.result())
.ifPresent(b64 -> {
try {
Files.write(Paths.get("otter.png"), Base64.getDecoder().decode(b64));
} catch (IOException e) {
throw new RuntimeException(e);
}
});
curl -X POST https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/responses \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-H "x-ms-oai-image-generation-deployment: $IMAGE_MODEL_NAME" \
-d '{
"model": "MODEL_NAME",
"input": "Generate an image of a gray tabby cat hugging an otter with an orange scarf.",
"tools": [{ "type": "image_generation" }]
}'
Modelli di ragionamento
Per esempi di come usare i modelli di ragionamento con l'API delle risposte, vedere la guida ai modelli di ragionamento.
Uso del computer
L'uso del computer con Playwright è stato spostato nella guida sul modello d'uso del computer dedicato.
Risoluzione dei problemi
Perché la sessione API è terminata come precauzione?
Quando si usano modelli Astra, per garantire che gli agenti interpretino e seguano correttamente le istruzioni, è disponibile un sistema che arresta le sessioni nell'API Risposte se rileva che l'agente potrebbe non aver interpretato correttamente le istruzioni in casi come il trasferimento di dati sensibili, l'accesso ai dati sensibili o l'esecuzione di modifiche distruttive. Se la sessione è stata terminata, questo non significa necessariamente che l'agente abbia commesso un errore, ma solo che vale comunque la pena di rivederne le azioni per assicurarsi che abbia interpretato e seguito correttamente le istruzioni.
Quali richieste API vengono monitorate da questo sistema?
Lo stesso sistema descritto sopra monitora in modo asincrono le richieste a Astra nell'API Risposte. L'API Chat Completions non viene analizzata da questo specifico sistema di monitoraggio. È consigliabile usare l'API Risposte per ottenere il massimo grado di prestazioni e sicurezza per i casi d'uso agenti.
Come rilevare che una conversazione è stata terminata nell'API da questo sistema?
Quando il sistema di sicurezza rileva che un agente potrebbe aver interpretato le istruzioni in modo significativamente errato, l'API restituisce un codice di annotazione di sicurezza misalignment-enforcement. In questo caso, la sessione specificata non può essere ripresa.
Cosa deve fare l'applicazione se viene rilevato un caso di questo tipo?
È consigliabile configurare un sistema per consentire a qualcuno di esaminare le azioni eseguite dall'agente in tali conversazioni, ad esempio fornendo un'interfaccia utente all'utente finale da esaminare. Una volta arrestata una conversazione per questo motivo nell'API, non è possibile riprenderla.
Risolvere gli errori comuni dell'API
Usare le indicazioni seguenti per risolvere gli errori comuni dell'API:
-
401/403: se utilizzi Microsoft Entra ID, verifica che l'ambito del token sia
https://ai.azure.com/.default. Se si usa una chiave API, verificare di usare la chiave corretta per la risorsa.
-
404: Confermare che
model corrisponda al nome della distribuzione.
Contenuto correlato