Схемы запросов и ответов NeuroAPI очень похожи на OpenAI Chat API, с несколькими небольшими отличиями. На высоком уровне NeuroAPI нормализует схему между моделями и провайдерами, поэтому вам нужно изучить только одну.
Это схема тела вашего POST
запроса к эндпоинту /v1/chat/completions
. Она представлена в виде TypeScript-типа с подробными комментариями к каждому полю.
// Определения подтипов приведены ниже
type Request = {
// Идентификатор модели для использования. См. таблицу совместимости моделей для получения информации о том, какие модели доступны.
model?: string;
// Список сообщений, составляющих диалог.
messages?: Message[];
// Формат, в котором модель должна выводить ответ.
// Установка 'json_object' включает режим JSON, который заставляет модель генерировать валидный JSON.
response_format?: { type: 'text' | 'json_object' };
// До четырех последовательностей, при которых API прекратит генерацию токенов.
stop?: string | string[];
// Если установлено, будет отправляться частичный прогресс сообщений.
// Токены будут отправляться как server-sent events по мере их доступности.
stream?: boolean;
// Опции для управления потоковой передачей.
stream_options?: {
// Если true, в конце потока будет отправлено событие usage.
include_usage: boolean;
};
// Максимальное количество токенов для генерации в чате.
// для семейства gpt-5 параметр max_completion_tokens автоматически конвертируется в max_tokens
max_tokens?: number;
// Какую температуру сэмплинга использовать, от 0 до 2.
// Более высокие значения (например, 0.8) делают вывод более случайным,
// в то время как более низкие значения (например, 0.2) делают его более сфокусированным и детерминированным.
// не работает для моделей семейства gpt-5
temperature?: number;
// Альтернатива сэмплингу с температурой, называемая nucleus sampling.
// Модель рассматривает результаты токенов с вероятностной массой top_p.
// Так, 0.1 означает, что рассматриваются только токены, составляющие верхние 10% вероятностной массы.
// не работает для моделей семейства gpt-5
top_p?: number;
// Список инструментов, которые модель может вызывать.
// В настоящее время поддерживаются только функции.
tools?: Tool[];
// Определяет, как модель будет использовать инструменты.
// 'none' - не вызывать инструменты. 'auto' - модель решает. 'required' - вызвать хотя бы один инструмент.
// Можно указать конкретную функцию для вызова.
tool_choice?: 'none' | 'auto' | 'required' | { type: 'function'; function: { name: string; } };
};
// Подтипы:
type Message = {
// Роль автора этого сообщения.
role: 'user' | 'assistant' | 'system' | 'tool';
// Содержимое сообщения. Может быть строкой или массивом частей контента.
content: string | ContentPart[];
// Имя автора этого сообщения. Может содержать a-z, A-Z, 0-9 и знаки подчеркивания, с максимальной длиной 64 символа.
name?: string;
// Если роль 'tool', это ID вызова инструмента.
tool_call_id?: string;
};
type ContentPart = {
// Тип части контента.
type: 'text' | 'image_url';
// Текст сообщения.
text?: string;
// URL изображения для анализа моделью.
image_url?: {
// URL-адрес изображения или данные изображения в кодировке base64.
url: string;
// Определяет уровень детализации, который модель использует для анализа изображения.
// 'low' - меньше затрат, 'high' - более детальный анализ.
detail?: 'auto' | 'low' | 'high';
};
};
type Tool = {
// Тип инструмента. В настоящее время поддерживается только 'function'.
type: 'function';
function: {
// Описание того, что делает функция.
description?: string;
// Имя функции, которую нужно вызвать.
name: string;
// Параметры, которые принимает функция, в формате JSON Schema.
parameters: object;
};
};
Потоковая передача (SSE): Для включения потоковой передачи (streaming) для всех моделей используется технология Server-Sent Events (SSE). Просто установите параметр stream: true
в теле вашего запроса. Это позволяет получать ответ от модели по частям, по мере их генерации.
Неподдерживаемые параметры: Если выбранная модель не поддерживает какой-либо из параметров запроса (например, top_k
для моделей OpenAI), этот параметр будет автоматически проигнорирован.
NeuroAPI нормализует схему между моделями и провайдерами для соответствия OpenAI Chat API. Ниже представлена схема ответа в формате TypeScript.
// Определения подтипов приведены ниже
type Response = {
// Уникальный идентификатор чата.
id: string;
// В зависимости от того, установили ли вы "stream" в "true", вы
// получите различную форму вывода.
choices: (NonStreamingChoice | StreamingChoice)[];
// Unix-метка времени (в секундах) создания чата.
created: number;
// Модель, использованная для генерации.
model: string;
// Тип объекта, всегда 'chat.completion' или 'chat.completion.chunk'.
object: 'chat.completion' | 'chat.completion.chunk';
// Уникальный идентификатор, представляющий внутреннюю конфигурацию бэкенда,
// которая была использована для этого запроса.
system_fingerprint?: string;
// Данные об использовании токенов для запроса.
// При потоковой передаче это поле отправляется в последнем сообщении.
usage?: ResponseUsage;
};
type ResponseUsage = {
// Количество токенов в промпте.
prompt_tokens: number;
// Количество токенов в сгенерированном ответе.
completion_tokens: number;
// Общее количество токенов в запросе и ответе.
total_tokens: number;
};
// Подтипы для НЕ-потокового ответа:
type NonStreamingChoice = {
// Причина, по которой модель прекратила генерацию токенов.
// 'stop' - естественная остановка, 'length' - достигнут лимит токенов,
// 'tool_calls' - вызов инструмента, 'content_filter' - отфильтровано.
finish_reason: string | null;
// Сгенерированное сообщение.
message: {
// Содержимое сообщения.
content: string | null;
// Роль автора ('assistant').
role: string;
// Инструменты, вызванные моделью.
tool_calls?: ToolCall[];
};
// Информация об ошибке, если она произошла.
error?: ErrorResponse;
};
// Подтипы для ПОТОКОВОГО ответа:
type StreamingChoice = {
// Причина, по которой модель прекратила генерацию токенов.
// Появляется только в последнем фрагменте потока.
finish_reason: string | null;
// Дельта-фрагмент сообщения.
delta: {
// Часть содержимого сообщения.
content: string | null;
// Роль автора (обычно только в первом фрагменте).
role?: string;
// Инструменты, вызванные моделью (появляются по частям).
tool_calls?: ToolCall[];
};
// Информация об ошибке, если она произошла.
error?: ErrorResponse;
};
// Информация об ошибке
type ErrorResponse = {
code: number;
message: string;
metadata?: Record<string, unknown>;
};
// Вызов инструмента
type ToolCall = {
// ID вызова инструмента.
id: string;
// Тип инструмента (всегда 'function').
type: 'function';
// Функция, которую вызвала модель.
function: {
// Имя функции.
name: string;
// Аргументы функции в виде JSON-строки.
arguments: string;
};
};
{
"id": "chatcmpl-xxxxxxxxxxxxxx",
"choices": [
{
"finish_reason": "stop", // Нормализованный finish_reason
"message": {
// будет "delta" если потоковая передача
"role": "assistant",
"content": "Привет!"
}
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 2,
"total_tokens": 12
},
"model": "gpt-4o" // Может также быть "claude-3-sonnet", и т.д., в зависимости от модели
}
NeuroAPI нормализует finish_reason
каждой модели к одному из следующих значений: tool_calls
, stop
, length
, content_filter
, function_call
.
Некоторые модели и провайдеры могут иметь дополнительные причины завершения. Исходная строка finish_reason, возвращаемая моделью, доступна через свойство native_finish_reason
.
Система подсчитывает общее количество токенов перед обработкой запроса для оценки стоимости и проверки лимитов. Подсчет производится на основе содержимого сообщений и используемых инструментов.
Для текстового содержимого используется токенизатор, совместимый с моделями OpenAI. Общее количество токенов включает в себя токены из ролей (например, 'user', 'assistant') и содержимого каждого сообщения в диалоге, а также токены из описаний функций, если они переданы в параметре tools
.
Стоимость обработки изображений зависит от их размера и параметра detail
в объекте image_url
.
detail: 'low'
: Изображение обрабатывается с низким разрешением, что соответствует фиксированной и меньшей стоимости в токенах. detail: 'high'
: Изображение обрабатывается в высоком разрешении. В этом режиме его сначала масштабируют, а затем "нарезают" на плитки размером 512x512 пикселей. Итоговая стоимость зависит от количества таких плиток.