Chat completions
Шлюз реализует тот же HTTP-слой, что и публичный API OpenAI Chat Completions: метод POST /v1/chat/completions, JSON-тело и ответ со списком choices. Это позволяет подключиться через официальный OpenAI SDK для Python (и аналоги в других языках), указав базовый URL вашего окружения.
Единственное жёсткое отличие: поле model
Строковое значение model всегда должно быть GUID агента в вашей инфраструктуре (Agent Engine ID), например "a1b2c3d4-e5f6-7890-abcd-ef1234567890". Имя тарифной модели в стиле gpt-4.1-mini здесь не применимо: шлюз сопоставляет запрос именно этому агенту.
Все отличия интеграции сводятся к базовому URL, ключу и корректному GUID в model.
Быстрый старт: OpenAI SDK (Python)
Установите пакет распространением из PyPI «openai»:
Соберите base_url как BASE_GATE без хвостового слэша плюс сегмент /v1 — именно его ожидает клиент при формировании пути /chat/completions.
import os
from openai import OpenAI
BASE_GATE = os.environ["BASE_GATE"].rstrip("/")
TOKEN = os.environ["TOKEN"]
AGENT_ID = os.environ["AGENT_ID"]
client = OpenAI(api_key=TOKEN, base_url=f"{BASE_GATE}/v1")
completion = client.chat.completions.create(
model=AGENT_ID,
messages=[{"role": "user", "content": "Кратко расскажи, для чего этот сервис."}],
temperature=0.7,
)
print(completion.choices[0].message.content)
import os
from openai import OpenAI
BASE_GATE = os.environ["BASE_GATE"].rstrip("/")
TOKEN = os.environ["TOKEN"]
AGENT_ID = os.environ["AGENT_ID"]
client = OpenAI(api_key=TOKEN, base_url=f"{BASE_GATE}/v1")
stream = client.chat.completions.create(
model=AGENT_ID,
messages=[{"role": "user", "content": "Привет"}],
stream=True,
)
for chunk in stream:
piece = chunk.choices[0].delta.content or ""
if piece:
print(piece, end="", flush=True)
Основные поля тела запроса
Поддерживаемые свойства следуют соглашению имен OpenAI. Ни абсолютный перечень сценариев бекенда, ни обязательность каждого поля для любого агента это руководство не фиксирует — экспериментируйте в рамках своих лимитов и правил тарификации аккаунта.
| Поле | Обязательно | Комментарий |
|---|---|---|
model |
да | Строковый GUID агента |
messages |
да | История сообщений с ролями system, user, assistant и т.д. |
stream |
нет | true включает Server-Sent Events (text/event-stream) |
temperature, top_p, max_tokens, stop, штрафы частотности, n, seed, … |
нет | Проброс при необходимости; поддержка каждого поля зависит от цепочки агента |
Успешный ответ без стриминга
Ответ имеет тип application/json. В составе данных обычно присутствуют поля наподобие id, created, имя модели, массив choices (message.role, message.content, причины завершения) и объект usage с подсчётом токенов.
Формат близок к документации OpenAI; полагайтесь при приёмке на фактический JSON вашей сборки для полей второго порядка.
Потоковая генерация
При stream: true транспорт — SSE. Формат порций может повторять OpenAI-совместимый поток через SDK; при ручном HTTP-клиенте читайте событие построчно и строки вида data: …, завершая по маркеру [DONE] у конвейера, который его испускает.
Ошибки в формате OpenAI
При корректной авторизации, но ошибке обработки пути /v1/chat/…, приложение может вернуть объект:
{
"error": {
"message": "Пояснение для человека",
"type": "invalid_request_error",
"param": null,
"code": null
}
}
Типичные случаи по семантике сервера:
| HTTP | Комментарий |
|---|---|
| 400 | Логические или синтаксические ошибки запроса; иногда вклад валидации модели состояния |
| 403 | Отключённый агент (agent_disabled и родственный код там, где они различаются) |
| 404 | Агент не найден для переданного model |
| 500 | Внутренний отказ узла генерации или шлюза |
Ошибки до успешной аутентификации см. текст 403 в Аутентификация и ключи.
Отдельно: раннее отклонение невалидного GUID в model может прийти с не зашитыми тем же объектом телом простого текстового ошибки или иным не-OpenAI сообщением при отладке смотрится Content-Type ответа.
Низкоуровневые вызовы (HTTP)
Ниже — те же сценарии без SDK: универсальный клиент httpx (удобнее для SSE) или requests, а также curl для воспроизведения минимальных запросов.
Окружение: BASE_GATE — без завершающего /; TOKEN — секрет без префикса Bearer; AGENT_ID — GUID агента.
Без потока
import os
import httpx
BASE_GATE = os.environ["BASE_GATE"].rstrip("/")
TOKEN = os.environ["TOKEN"]
AGENT_ID = os.environ["AGENT_ID"]
payload = {
"model": AGENT_ID,
"messages": [{"role": "user", "content": "Кратко опиши назначение API-шлюза."}],
"temperature": 0.7,
}
url = f"{BASE_GATE}/v1/chat/completions"
resp = httpx.post(
url,
headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
json=payload,
timeout=120.0,
)
resp.raise_for_status()
data = resp.json()
print(data["choices"][0]["message"]["content"])
export BASE_GATE="https://api.theta-cloud.ru"
export TOKEN='<ваш ключ>'
export AGENT_ID='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
curl -sS -X POST "${BASE_GATE}/v1/chat/completions" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"model\":\"${AGENT_ID}\",\"messages\":[{\"role\":\"user\",\"content\":\"Привет\"}]}"
С потоком (SSE руками)
import json
import os
import httpx
BASE_GATE = os.environ["BASE_GATE"].rstrip("/")
TOKEN = os.environ["TOKEN"]
AGENT_ID = os.environ["AGENT_ID"]
url = f"{BASE_GATE}/v1/chat/completions"
payload = {"model": AGENT_ID, "messages": [{"role": "user", "content": "Привет"}], "stream": True}
with httpx.Client(timeout=120.0) as client:
with client.stream(
"POST",
url,
headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
json=payload,
) as resp:
resp.raise_for_status()
for line in resp.iter_lines():
line = line.strip()
if not line.startswith("data:"):
continue
blob = line[5:].strip()
if blob == "[DONE]":
break
try:
print(json.loads(blob))
except json.JSONDecodeError:
continue
Ручной разбор SSE
Такой парсер годится для экспериментов; в продакшене чаще удобнее OpenAI SDK выше или готовый HTTP-клиент с политикой повторов.
export BASE_GATE="https://api.theta-cloud.ru"
export TOKEN='<ваш ключ>'
export AGENT_ID='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
curl -N -sS -X POST "${BASE_GATE}/v1/chat/completions" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"model\":\"${AGENT_ID}\",\"messages\":[{\"role\":\"user\",\"content\":\"Привет\"}],\"stream\":true}"