Responses API
НовоеPOST /v1/responses принимает инструкции и список элементов ввода и возвращает объект ответа, состоящий из элементов вывода, в формате OpenAI Responses. Используйте его с responses API в OpenAI SDK и с построенными на нем инструментами, например Codex CLI. Эндпоинт не хранит состояние: отправляйте весь разговор с каждым запросом.
POST https://api.shannon-ai.com/v1/responses
Самый маленький запрос — это id модели и текст. Ответ приходит без стриминга, пока вы его не запросите.
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
response = client.responses.create(
model="shannon-3",
input="Say hello in one sentence.",
)
print(response.output_text) import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const response = await client.responses.create({
model: "shannon-3",
input: "Say hello in one sentence.",
});
console.log(response.output_text); curl https://api.shannon-ai.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"input": "Say hello in one sentence."
}' Ответ — это объект response. В его output находятся рассуждения, если модель рассуждала, и сообщение:
{
"id": "resp_5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"object": "response",
"created_at": 1791625200,
"model": "shannon-3",
"status": "completed",
"error": null,
"incomplete_details": null,
"instructions": null,
"metadata": {},
"parallel_tool_calls": true,
"temperature": null,
"tool_choice": "auto",
"tools": [],
"top_p": null,
"output": [
{
"id": "rs_8a2e6c1f4b7d4e03b9c5a1d70f3e2b64",
"type": "reasoning",
"summary": [
{
"type": "summary_text",
"text": "The user wants a greeting in one sentence. Keep it short and friendly."
}
]
},
{
"id": "msg_1c7b9e3a5d2f4a86b0e4c8d19a6f7e25",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "Hello, it is good to meet you.",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 1184,
"output_tokens": 46,
"total_tokens": 1230
}
} Поля запроса
Для запроса нужны model и input. В столбце Applied by указаны модели, на которых поле меняет ответ. Размещенные модели с открытыми весами — это двенадцать id из списка моделей; семейство Shannon 3 — это shannon-3, shannon-3-pro, shannon-3.1 и shannon-3.1-pro. Модели и цены
| Поле | Тип | По умолчанию | Описание | Применяется |
|---|---|---|---|---|
model | string | Обязательное. Id из списка моделей. Регистр не учитывается. Отсутствующий или неопубликованный id возвращает 400 unknown model. | Все модели | |
input | string | array | Строка, которая читается как одно сообщение пользователя, или массив элементов ввода. См. «Элементы ввода» ниже. | Все модели | |
instructions | string | Инструкции для модели, системный промпт этого формата. | Размещенные модели с открытыми весами, shannon-1.6-*, shannon-2-*, shannon-coder-1 | |
stream | boolean | false | true отправляет ответ как server-sent events. См. «Стриминг» ниже. | Все модели |
max_output_tokens | integer | 4096 | Верхний предел ответа в токенах. Значение вне диапазона от 1 до 65,536 приводится к этому диапазону. Это также сумма, которая откладывается на вашем балансе, пока выполняется запрос. См. «Лимит вывода» ниже. | Размещенные модели с открытыми весами, shannon-1.6-*, shannon-2-*, shannon-coder-1 |
temperature | number | Температура сэмплирования. У размещенных моделей с открытыми весами значения ограничиваются диапазоном от 0 до 2. | Размещенные модели с открытыми весами; shannon-1.6-*, shannon-2-* и shannon-coder-1 в ответах без стриминга | |
top_p | number | Nucleus-сэмплирование. Значения ограничиваются диапазоном от 0 до 1. | Размещенные модели с открытыми весами | |
tools | array | Функции, которые модель может вызывать, в плоской форме этого формата: {"type": "function", "name", "description", "parameters"}. См. «Инструменты» ниже. | Все модели | |
tool_choice | string | object | auto | "auto" позволяет модели решать самой. "required" заставляет ее вызвать инструмент. {"type": "function", "name": "…"} заставляет ее вызвать именно этот инструмент. | Размещенные модели с открытыми весами |
reasoning | object | {"effort": "…"} со значением off, low, medium или high. Любое другое значение возвращает 400. | Размещенные модели с открытыми весами | |
text | object | {"format": {…}} запрашивает ответ в JSON. См. «Структурированный вывод» ниже. | Все уровни Shannon; размещенные модели с открытыми весами — как указано для каждого id |
previous_response_id, store, metadata, parallel_tool_calls, truncation, include, user и prompt_cache_key принимаются, чтобы существующий клиентский код работал без изменений. На ответ они не влияют. Поскольку разговор не хранится, последующий запрос передает предыдущие ходы в input.
Элементы ввода
Элемент ввода — это либо сообщение с role и content, либо типизированный элемент, несущий вызов инструмента или его результат. content — строка или массив частей.
| Элемент | Описание | Применяется |
|---|---|---|
{"role": "user", "content": …} | Ваш вопрос. content — строка или части input_text и input_image. | Все модели |
{"role": "assistant", "content": …} | Предыдущий ответ модели. content — строка или части output_text. | Все модели |
{"role": "system", "content": …}{"role": "developer", "content": …} | Инструкции внутри разговора. | Размещенные модели с открытыми весами |
{"type": "function_call", "call_id": "…", "name": "…", "arguments": "…"} | Вызов инструмента, который модель сделала в предыдущем ответе. arguments — строка JSON. | Все модели |
{"type": "function_call_output", "call_id": "…", "output": "…"} | Результат этого вызова. call_id — id вызова, output — результат в виде строки. | Все модели |
Помещайте инструкции в поле instructions. Если используется id из семейства Shannon 3, инструкции, которые должны соблюдаться, помещайте в сообщение user.
Элементы output ответа можно отправить обратно в input как есть: элементы message и function_call читаются, элементы reasoning пропускаются.
Части контента
| Часть | Описание | Доступно на |
|---|---|---|
{"type": "input_text", "text": "…"} | Текст сообщения пользователя. | Все модели |
{"type": "output_text", "text": "…"} | Текст сообщения ассистента. | Все модели |
{"type": "input_image", "image_url": "…"} | Изображение в виде URL data: с содержимым base64 или в виде URL http(s). | Семейство Shannon 3, shannon-1.6-lite, shannon-1.6-pro и размещенные модели с открытыми весами, у которых указан ввод изображений |
{"type": "input_file", "file_data": "data:application/pdf;base64,…"} | Документ (PDF, Word, PowerPoint или Excel): file_data содержит URL data:, а file_url — URL http(s). | Семейство Shannon 3 |
На уровнях Shannon изображения и файлы читаются из последнего элемента user в input. Размеры и лимиты описаны на отдельной странице. Изображения и файлы
Запрос с инструкциями и параметрами
Этот запрос отправляет инструкции, разговор в виде элементов ввода, лимит вывода, температуру и усилие reasoning. Он использует размещенную модель с открытыми весами, которая применяет все это.
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
response = client.responses.create(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
instructions="You are a physics teacher. Answer in two sentences.",
input=[
{"role": "user", "content": "Why is the sky blue?"},
{"role": "assistant", "content": "Air scatters blue light more than red light."},
{"role": "user", "content": "And why are sunsets red?"},
],
max_output_tokens=512,
temperature=0.3,
reasoning={"effort": "low"},
)
for item in response.output:
if item.type == "reasoning":
print("reasoning:", item.summary[0].text)
elif item.type == "message":
print("answer:", item.content[0].text)
print(response.usage) import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const response = await client.responses.create({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
instructions: "You are a physics teacher. Answer in two sentences.",
input: [
{ role: "user", content: "Why is the sky blue?" },
{ role: "assistant", content: "Air scatters blue light more than red light." },
{ role: "user", content: "And why are sunsets red?" },
],
max_output_tokens: 512,
temperature: 0.3,
reasoning: { effort: "low" },
});
for (const item of response.output) {
if (item.type === "reasoning") console.log("reasoning:", item.summary[0].text);
if (item.type === "message") console.log("answer:", item.content[0].text);
}
console.log(response.usage); curl https://api.shannon-ai.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"instructions": "You are a physics teacher. Answer in two sentences.",
"input": [
{"role": "user", "content": "Why is the sky blue?"},
{"role": "assistant", "content": "Air scatters blue light more than red light."},
{"role": "user", "content": "And why are sunsets red?"}
],
"max_output_tokens": 512,
"temperature": 0.3,
"reasoning": {"effort": "low"}
}' В ответе размещенной модели с открытыми весами есть id, object, model, created_at, status, output и usage. Ее usage дополнительно содержит токены, прочитанные из кэша, и токены, потраченные на reasoning:
{
"usage": {
"input_tokens": 58,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 67,
"output_tokens_details": {
"reasoning_tokens": 19
},
"total_tokens": 125
}
} Объект ответа
id, object, status, output и usage есть в каждом ответе. Стройте свой код на них.
| Поле | Тип | Описание | Отправляется |
|---|---|---|---|
id | string | resp_ и за ним 32 шестнадцатеричных символа. | Все модели |
object | string | Всегда response. | Все модели |
status | string | completed. В потоке сначала in_progress, а в событии response.failed — failed. | Все модели |
output | array | Элементы вывода в том порядке, в каком их создала модель: reasoning, message, function_call. | Все модели |
usage | object | input_tokens, output_tokens и total_tokens. | Все модели |
usage.input_tokens_details | object | cached_tokens: входные токены, прочитанные из кэша промпта. | Размещенные модели с открытыми весами |
usage.output_tokens_details | object | reasoning_tokens: выходные токены, потраченные на reasoning. | Размещенные модели с открытыми весами |
model | string | Канонический id модели, которая ответила. | Семейство Shannon 3, размещенные модели с открытыми весами |
created_at | integer | Время ответа в секундах Unix. | Семейство Shannon 3, размещенные модели с открытыми весами |
instructions, tools, temperature, … | instructions, tools и temperature повторяют запрос. error и incomplete_details равны null, metadata равно {}, parallel_tool_calls равно true, tool_choice равно auto, а top_p равно null. | Семейство Shannon 3 |
Элементы вывода
| Элемент | Описание |
|---|---|
{"id": "rs_…", "type": "reasoning", "summary": [{"type": "summary_text", "text": "…"}]} | Рассуждения модели одной частью summary_text. Есть, только если модель рассуждала. |
{"id": "msg_…", "type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "…"}]} | Ответ: одна часть output_text с текстом. |
{"id": "fc_…", "type": "function_call", "call_id": "call_…", "name": "…", "arguments": "…"} | Вызов инструмента. arguments — строка JSON. Отправьте результат обратно с тем же call_id. |
OpenAI SDK сами склеивают текст сообщения в response.output_text.
Стриминг
Задайте stream равным true, чтобы получать server-sent events. В каждом фрейме есть строка event: с именем события и строка data: с JSON-объектом; объект повторяет имя в type. Сопоставляйте дельты с их элементом по output_index.
В OpenAI SDK читайте события по их type:
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
stream = client.responses.create(
model="shannon-3",
input="Explain server-sent events in three sentences.",
stream=True,
)
for event in stream:
kind = getattr(event, "type", "error") # an event without a type is an error event
if kind == "response.reasoning_summary_text.delta":
pass # a piece of reasoning: event.delta
elif kind == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif kind == "response.output_item.done" and event.item.type == "function_call":
print("\ntool call:", event.item.name, event.item.arguments)
elif kind == "response.completed":
print("\n", event.response.usage)
elif kind in ("response.failed", "error"):
raise RuntimeError("the stream failed, send the request again") import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const stream = await client.responses.create({
model: "shannon-3",
input: "Explain server-sent events in three sentences.",
stream: true,
});
for await (const event of stream) {
if (event.type === "response.reasoning_summary_text.delta") {
// a piece of reasoning: event.delta
} else if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
} else if (event.type === "response.output_item.done" && event.item.type === "function_call") {
console.log("\ntool call:", event.item.name, event.item.arguments);
} else if (event.type === "response.completed") {
console.log("\n", event.response.usage);
} else if (event.type === "response.failed" || event.type === "error") {
throw new Error("the stream failed, send the request again");
}
} curl -N https://api.shannon-ai.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"input": "Explain server-sent events in three sentences.",
"stream": true
}' События приходят в таком порядке. Группы для reasoning, сообщения и вызовов инструментов появляются, только если они есть в ответе.
| Событие | Данные | Когда |
|---|---|---|
response.created | response | Всегда первым. response.status равен in_progress, а response.output пуст. |
response.in_progress | response | Всегда вторым, с тем же объектом. |
response.output_item.added | output_index, item | Начинаются рассуждения: элемент reasoning с пустым summary. |
response.reasoning_summary_text.delta | output_index, summary_index, delta | Фрагмент рассуждений. |
response.reasoning_summary_text.done | output_index, summary_index, text | Рассуждения завершены: их полный text. |
response.output_item.done | output_index, item | Завершенный элемент reasoning. |
response.output_item.added | output_index, item | Начинается ответ: элемент message со статусом in_progress и без контента. |
response.content_part.added | output_index, content_index, part | Открывается пустая часть output_text. |
response.output_text.delta | output_index, content_index, delta | Фрагмент ответа. |
response.output_text.done | output_index, content_index, text | Ответ завершен: его полный text. |
response.content_part.done | output_index, content_index, part | Завершенная часть output_text. |
response.output_item.done | output_index, item | Завершенный элемент message со статусом completed. |
response.output_item.added | output_index, item | Начинается вызов инструмента: элемент function_call с call_id, name и пустыми arguments. |
response.function_call_arguments.delta | output_index, delta | Аргументы вызова, целиком в одной дельте. |
response.function_call_arguments.done | output_index, arguments | Те же аргументы, как arguments. |
response.output_item.done | output_index, item | Завершенный элемент function_call. |
response.completed | response | При успехе всегда последним: весь объект response с output и usage. |
event: response.created
data: {"type":"response.created","response":{"id":"resp_5f0c…","object":"response","status":"in_progress","output":[], …}}
event: response.in_progress
data: {"type":"response.in_progress","response":{"id":"resp_5f0c…","object":"response","status":"in_progress","output":[], …}}
event: response.output_item.added
data: {"type":"response.output_item.added","output_index":0,"item":{"id":"msg_1c7b…","type":"message","role":"assistant","status":"in_progress","content":[]}}
event: response.content_part.added
data: {"type":"response.content_part.added","output_index":0,"content_index":0,"part":{"type":"output_text","text":""}}
event: response.output_text.delta
data: {"type":"response.output_text.delta","output_index":0,"content_index":0,"delta":"Server-sent"}
event: response.output_text.delta
data: {"type":"response.output_text.delta","output_index":0,"content_index":0,"delta":" events let a server push text over one HTTP reply."}
event: response.output_text.done
data: {"type":"response.output_text.done","output_index":0,"content_index":0,"text":"Server-sent events let a server push text over one HTTP reply."}
event: response.content_part.done
data: {"type":"response.content_part.done","output_index":0,"content_index":0,"part":{"type":"output_text","text":"Server-sent events let a server push text over one HTTP reply."}}
event: response.output_item.done
data: {"type":"response.output_item.done","output_index":0,"item":{"id":"msg_1c7b…","type":"message","role":"assistant","status":"completed","content":[{"type":"output_text","text":"Server-sent events let a server push text over one HTTP reply.","annotations":[]}]}}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_5f0c…","object":"response","status":"completed","output":[…],"usage":{"input_tokens":1190,"output_tokens":18,"total_tokens":1208}, …}} Поток, который завершился сбоем
На уровнях Shannon неудавшийся ответ заканчивается событием response.failed вместо response.completed. Его response.status равен failed, а response.error содержит code (rate_limit_exceeded или server_error) и message.
У размещенных моделей с открытыми весами сбой — это событие error с code api_error и message. После него все равно следует response.completed.
Считайте поток неудавшимся, если в нем есть событие response.failed или error, и отправьте запрос снова.
Инструменты
Инструмент — это функция, которую выполняет ваш код. Опишите ее в tools; когда модель хочет ее вызвать, ответ содержит элемент function_call вместо сообщения или рядом с ним.
Определение инструмента в tools:
[
{
"type": "function",
"name": "get_weather",
"description": "Current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
}
}
] output ответа, в котором она вызывается:
[
{
"id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"type": "function_call",
"name": "get_weather",
"call_id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"arguments": "{\"city\":\"Paris\"}"
}
] Выполните функцию, затем отправьте запрос снова, добавив в input вызов и его результат:
[
{
"role": "user",
"content": "What is the weather in Paris?"
},
{
"type": "function_call",
"call_id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
},
{
"type": "function_call_output",
"call_id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"output": "{\"temperature_c\": 18, \"sky\": \"cloudy\"}"
}
] Читаются только инструменты типа function. На shannon-1.6-*, shannon-2-* и shannon-coder-1 схема parameters сокращается до общих ключевых слов JSON Schema: oneOf читается как anyOf, а такие ключевые слова, как $ref, additionalProperties, const, default и title, модели не передаются.
Значения tool_choice required и именованная функция применяются размещенными моделями с открытыми весами.
Цикл работы с инструментами полностью описан на отдельной странице. Вызов функций
Структурированный вывод
В этом формате структурированный вывод записывается как text.format. Схема лежит прямо в format, рядом с name и strict, а не внутри члена json_schema, как в Chat Completions.
{"type": "json_object"}запрашивает любой JSON-объект.{"type": "json_schema", "name", "schema", "strict"}запрашивает JSON, соответствующий вашей схеме. Еслиstrictне указан, он равенtrue.
{
"model": "shannon-1.6-lite",
"input": "Extract the city and the date: 'The conference opens in Lisbon on 12 May 2027.'",
"text": {
"format": {
"type": "json_schema",
"name": "event",
"strict": true,
"schema": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"date": {
"type": "string",
"description": "ISO 8601 date"
}
},
"required": [
"city",
"date"
]
}
}
}
} JSON приходит текстом в части output_text сообщения; разберите его сами. Размещенная модель с открытыми весами без структурированного вывода возвращает 400.
{"city": "Lisbon", "date": "2027-05-12"} Какая модель принимает какую форму, перечислено на отдельной странице. Структурированные ответы
Reasoning
Модель, которая рассуждает, возвращает рассуждения как элемент вывода типа reasoning перед сообщением. В потоке они приходят событиями response.reasoning_summary_text.delta.
Размещенные модели с открытыми весами применяют reasoning.effort: off, low, medium или high; если ничего не отправлять, действует high. При off элемент reasoning не возвращается. Отправляйте его как объект; простая строка на этом эндпоинте не читается.
Уровни усилия описаны на отдельной странице. Усилие рассуждения
Лимит вывода
max_output_tokens равен 4,096, если вы его не отправляете. Это число токенов, которое откладывается на вашем балансе при старте запроса; когда ответ завершен, эта сумма заменяется фактически использованной. Значение, не помещающееся в остаток баланса, возвращает 429 Quota exceeded.
Он ограничивает длину ответа у shannon-1.6-*, shannon-2-* и shannon-coder-1, а у размещенных моделей с открытыми весами — длину текста ответа.
На этом эндпоинте shannon-coder-1 тарифицируется токенами с вашего баланса, как и любая другая модель.
Тело запроса может быть до 32 MiB. Лимиты и баланс
Ошибки
Ошибки используют тело ошибки OpenAI: объект error с type и message; у некоторых также есть code и param со значением null. В таблице перечислено то, что этот эндпоинт возвращает чаще всего. Полный список с указанием, что стоит повторять, вынесен на отдельную страницу. Обработка ошибок
| Статус | Тип | Сообщение | Когда |
|---|---|---|---|
401 | authentication_error | Missing authenticationInvalid API key | API-ключ не отправлен, либо ключ неизвестен или отозван. |
400 | invalid_request_error | unknown model: <id> | model отсутствует или не является опубликованным id. |
400 | invalid_request_error | No user message provided. | Уровни Shannon: в input нет пользовательского текста. |
400 | invalid_request_error | <id> does not accept image input | Изображение отправлено размещенной модели с открытыми весами, которая не принимает изображения. |
400 | invalid_request_error | <id> does not accept response_format | text.format отправлен размещенной модели с открытыми весами, которая не поддерживает структурированный вывод. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | reasoning.effort содержит значение вне списка. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Тело — корректный JSON, но у поля неверный тип. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | max_output_tokens больше, чем осталось на вашем балансе. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Защита от флуда: более 120 запросов за одну минуту с вашего аккаунта. |
500 | api_error | The model backend failed to answer. Please retry. | Модель не создала ответ. Отправьте запрос снова. |
502 | api_error | The model backend failed to answer. Please retry. | То же самое, для размещенных моделей с открытыми весами. |
504 | api_error | upstream timed out | Размещенная модель с открытыми весами потратила больше времени, чем допускает лимит ответа без стриминга. Отправьте запрос с stream, равным true. |