Справочник API
Подробное руководство по API AITUNNEL. Узнайте о схемах запросов/ответов, аутентификации, параметрах и интеграции с различными провайдерами моделей ИИ.
Схемы запросов и ответов AITUNNEL очень похожи на OpenAI Chat API, с небольшими отличиями. В целом, AITUNNEL нормализует схему для всех моделей и провайдеров, поэтому вам нужно изучить только одну.
Запросы
Формат запроса на завершение
Вот схема запроса в виде TypeScript типа. Это будет тело вашего POST
запроса к эндпоинту /v1/chat/completions
(см. пример в быстром старте).
Для полного списка параметров см. раздел Параметры.
// Определения подтипов приведены ниже
type Request = {
// Требуется либо "messages", либо "prompt"
messages?: Message[];
prompt?: string;
model: string;
// Позволяет заставить модель производить определенный формат вывода.
response_format?: { type: "json_object" };
stop?: string | string[];
stream?: boolean; // Включить стриминг
// См. Параметры LLM
max_tokens?: number; // Диапазон: [1, context_length)
temperature?: number; // Диапазон: [0, 2]
// Вызов инструментов
// Будет передан как есть для провайдеров, реализующих интерфейс OpenAI.
// Для провайдеров с пользовательскими интерфейсами мы преобразуем и сопоставляем свойства.
// В противном случае мы преобразуем инструменты в YAML шаблон. Модель отвечает сообщением ассистента.
tools?: Tool[];
tool_choice?: ToolChoice;
// Расширенные необязательные параметры
seed?: number; // Только целые числа
top_p?: number; // Диапазон: (0, 1]
top_k?: number; // Диапазон: [1, Infinity) Недоступно для моделей OpenAI
frequency_penalty?: number; // Диапазон: [-2, 2]
presence_penalty?: number; // Диапазон: [-2, 2]
repetition_penalty?: number; // Диапазон: (0, 2]
logit_bias?: { [key: number]: number };
top_logprobs: number; // Только целые числа
min_p?: number; // Диапазон: [0, 1]
top_a?: number; // Диапазон: [0, 1]
// Уменьшите задержку, предоставив модели предсказанный вывод
// https://platform.openai.com/docs/guides/latency-optimization#use-predicted-outputs
prediction?: { type: "content"; content: string };
};
// Подтипы:
type TextContent = {
type: "text";
text: string;
};
type ImageContentPart = {
type: "image_url";
image_url: {
url: string; // URL или base64 закодированные данные изображения
detail?: string; // Необязательно, по умолчанию "auto"
};
};
type ContentPart = TextContent | ImageContentPart;
type Message =
| {
role: "user" | "assistant" | "system";
// ContentParts только для роли "user":
content: string | ContentPart[];
// Если включено "name", оно будет добавлено так
// для моделей не OpenAI: `{name}: {content}`
name?: string;
}
| {
role: "tool";
content: string;
tool_call_id: string;
name?: string;
};
type FunctionDescription = {
description?: string;
name: string;
parameters: object; // JSON Schema объект
};
type Tool = {
type: "function";
function: FunctionDescription;
};
type ToolChoice =
| "none"
| "auto"
| {
type: "function";
function: {
name: string;
};
};
Стриминг
Поддерживаются Server-Sent Events (SSE) для включения стриминга для всех моделей. Просто отправьте stream: true
в теле запроса.
Нестандартные параметры
Если выбранная модель не поддерживает параметр запроса (например, logit_bias
в моделях не OpenAI или top_k
для OpenAI), то параметр игнорируется. Остальные передаются в базовый API модели.
Предварительное заполнение ответа ассистента
AITUNNEL поддерживает запрос к моделям на завершение частичного ответа. Это может быть полезно для направления моделей к ответу определенным образом.
Чтобы использовать эту функцию, просто включите сообщение с role: "assistant"
в конец вашего массива messages
.
fetch("https://api.aitunnel.ru/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer <AITUNNEL_API_KEY>",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gpt-4o",
messages: [
{ role: "user", content: "В чем смысл жизни?" },
{
role: "assistant",
content: "Я не уверен, но мое лучшее предположение:",
},
],
}),
});
Ответы
Формат ответа на завершение
AITUNNEL нормализует схему для всех моделей и провайдеров в соответствии с OpenAI Chat API.
Это означает, что choices
всегда является массивом, даже если модель возвращает только одно завершение. Каждый выбор будет содержать свойство delta
, если был запрошен стриминг, и свойство message
в противном случае. Это упрощает использование одного и того же кода для всех моделей.
Вот схема ответа в виде TypeScript типа:
// Определения подтипов приведены ниже
type Response = {
id: string;
// В зависимости от того, установили ли вы "stream" в "true" и
// передали ли вы "messages" или "prompt", вы
// получите разную форму вывода
choices: (NonStreamingChoice | StreamingChoice | NonChatChoice)[];
created: number; // Unix timestamp
model: string;
object: "chat.completion" | "chat.completion.chunk";
system_fingerprint?: string; // Присутствует только если провайдер это поддерживает
// Данные об использовании всегда возвращаются для нестриминга.
// При стриминге вы получите один объект использования в
// конце, сопровождаемый пустым массивом choices.
usage?: ResponseUsage;
};
// Если провайдер возвращает использование, мы передаем его
// как есть. В противном случае мы считаем с помощью токенизатора GPT-4.
type ResponseUsage = {
/** Включая изображения и инструменты, если есть */
prompt_tokens: number;
/** Сгенерированные токены */
completion_tokens: number;
/** Сумма двух вышеуказанных полей */
total_tokens: number;
/** Сумма запроса в рублях */
cost_rub: number;
/** Баланс кабинета AITUNNEL после списания за запрос */
balance: number;
};
// Подтипы:
type NonChatChoice = {
finish_reason: string | null;
text: string;
error?: ErrorResponse;
};
type NonStreamingChoice = {
finish_reason: string | null;
native_finish_reason: string | null;
message: {
content: string | null;
role: string;
tool_calls?: ToolCall[];
};
error?: ErrorResponse;
};
type StreamingChoice = {
finish_reason: string | null;
native_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: string;
type: "function";
function: FunctionCall;
};
Вот пример:
{
"id": "gen-xxxxxxxxxxxxxx",
"choices": [
{
"finish_reason": "stop", // Нормализованный finish_reason
"native_finish_reason": "stop", // Исходный finish_reason от провайдера
"message": {
// будет "delta" если стриминг
"role": "assistant",
"content": "Привет!"
}
}
],
"usage": {
"prompt_tokens": 0,
"completion_tokens": 4,
"total_tokens": 4,
"cost_rub": 0.51,
"balance": 1212.38933
},
"model": "gpt-4o"
}
Причина завершения
AITUNNEL нормализует finish_reason
каждой модели к одному из следующих значений: tool_calls
, stop
, length
, content_filter
, error
.
Некоторые модели и провайдеры могут иметь дополнительные причины завершения. Исходная строка finish_reason, возвращаемая моделью, доступна через свойство native_finish_reason
.
Запрос стоимости и статистики
Количество токенов, возвращаемое в ответе API completions, не подсчитывается с помощью нативного токенизатора модели. Вместо этого используется нормализованный, не зависящий от модели подсчет (осуществляемый с помощью токенизатора GPT4o). Это происходит потому, что некоторые провайдеры не надежно возвращают нативные подсчеты токенов. Однако такое поведение становится все более редким, и мы можем добавить нативные подсчеты токенов в объект ответа в будущем.
Цены на модели основаны на нативных подсчетах токенов (не на "нормализованных" подсчетах токенов, возвращаемых в ответе API).
Обратите внимание, что подсчеты токенов доступны в поле usage
тела ответа для нестриминговых завершений.