Ключ и имя модели
Создайте отдельный ключ CLODEx и выберите модель из /v1/models с этим ключом. Gemini 3.8 Flash имеет ID gemini-3.8-flash. Названия Flash и Pro относятся к разным вариантам; нельзя заменить одно другим, сохранив предположения о цене, лимитах и функциях.
Ключ Google AI Studio здесь не подходит. Серверный ключ CLODEx хранится в CLODEX_API_KEY, а выбранное имя — в CLODEX_MODEL. Не считывайте эти значения из пользовательского сообщения и не отдавайте секрет в frontend.
Почему пример Google не вставляется без изменений
Нативный generateContent использует contents и parts. Этот пример CLODEx использует messages, затем читает choices. У этих интерфейсов разные тела запроса и схемы ошибок. Обёртка OpenAI-compatible не означает, что весь Google SDK можно направить на другой домен.
| Что переносится | Что нужно изменить |
|---|---|
| Текст задачи | Поместить в messages[].content |
| Название модели | Взять ID маршрута CLODEx |
| Google Search, выполнение кода | Проверить наличие отдельного инструмента; не включается автоматически |
| Настройки генерации Google | Сопоставить с полями выбранного endpoint, не копировать целиком |
Текстовый запрос на Python без сторонних пакетов
Код использует стандартную библиотеку Python. Он выполняет один платный запрос без повторов и принимает только законченный текстовый ответ. При HTTP-ошибке urlopen возбуждает исключение; не выводите в публичный лог заголовок Authorization или содержимое приватного запроса.
import json
import os
from urllib.request import Request, urlopen
payload = {
"model": os.environ["CLODEX_MODEL"],
"messages": [{"role": "user", "content": "Reply with one word: ready"}],
"stream": False,
}
request = Request(
"https://clodex.xyz/v1/chat/completions",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": "Bearer " + os.environ["CLODEX_API_KEY"],
"Content-Type": "application/json",
},
method="POST",
)
with urlopen(request, timeout=60) as response:
result = json.load(response)
choices = result.get("choices", [])
if not choices or choices[0].get("finish_reason") != "stop":
raise RuntimeError("Incomplete text response")
text = choices[0].get("message", {}).get("content")
if not isinstance(text, str) or not text.strip():
raise RuntimeError("Missing text")
print(text)
Пример задачи с однозначной проверкой
Передайте две конфигурации: A={"retries":0,"cache":false,"timeout":30} и B={"retries":2,"timeout":30}. Попросите перечислить только изменённые поля. Ожидается изменение retries и удаление cache, а не изменение timeout.
Это синтетический набор, не результат тестирования модели. Он полезен тем, что ловит распространённую ошибку обработки данных: 0 и false нельзя считать отсутствующими значениями. Если результат нужен программе, проверьте JSON и допустимые поля до записи в базу.
Изображения, поиск и ограничения
Для анализа картинки нужен поддерживаемый графический вход и сам файл. Ссылка на закрытое хранилище не передаёт изображение автоматически. Начните с безопасного снимка без персональных данных и убедитесь, что клиент отправляет его в поддерживаемом формате.
Не просите «найди последние новости», ожидая сетевой поиск только из-за слова Gemini. Поиск, выполнение кода и другие инструменты должны быть подключены явно. Если они не используются, ответ не является проверкой интернета.
Сравнивая модели, сохраните одинаковые данные и критерии. Расход сверяйте по журналу: длина объяснения и reasoning могут изменить стоимость задачи даже при одинаковом исходном вопросе.
Документация и проверка примера
Адреса и настройки подключения сверены с документацией CLODEx. Примеры предназначены для указанного протокола; они не являются журналом выполненных запросов и не обещают одинаковые функции у всех моделей. Рабочий запрос на генерацию может списать средства.
Частые вопросы
Можно ли использовать Google API key?
Нет, этот маршрут авторизуется ключом CLODEx. Прямой Google API — отдельная интеграция со своим аккаунтом и адресом.
Будет ли работать любой параметр generateContent?
Нет. Сначала сопоставьте параметр со схемой CLODEx. Неподдерживаемое поле не стоит повторять в запросе в надежде, что оно начнёт работать.
Почему сервер вернул 200, но ответ не готов?
При потоковом режиме HTTP 200 означает начало передачи. Пример выше использует непотоковый ответ и дополнительно проверяет finish_reason.