До и после
Вот типичный клиент OpenAI на Python:
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
r = client.chat.completions.create(
model="your-current-model",
messages=[{"role": "user", "content": "Draft a tense dialogue between two rivals."}],
)
И тот же клиент указывает на альтернативу без фильтров:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.chatgptunfiltered.com/v1",
api_key=os.environ["UNFILTERED_API_KEY"],
)
r = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Draft a tense dialogue between two rivals."}],
)
Две строки изменены в конструкторе, а строка модели изменена в вызове. Формат сообщения, объект ответа и способ чтения r.choices[0].message.content остаются такими же, как и были. Альтернатива — это другая модель, запущенная независимым провайдером. Это не ChatGPT и не официальный API от OpenAI или кого-либо ещё.
Переключение только с помощью переменных окружения
Последние версии официальных SDK для Python и Node.js считывают OPENAI_BASE_URL и OPENAI_API_KEY при создании клиента без аргументов. Это означает, что код приложения можно не изменять:
export OPENAI_BASE_URL="https://api.chatgptunfiltered.com/v1"
export OPENAI_API_KEY="YOUR_KEY"
python app.py
Вам всё ещё нужно убедиться, что код передаёт model="uncensored". Если имя модели жёстко задано во многих местах, сначала вынесите его в одно значение конфигурации. Этот небольшой рефакторинг сделает любое будущее переключение столь же недорогим, в любом направлении.
Та же идея работает в Node:
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.chatgptunfiltered.com/v1",
apiKey: process.env.UNFILTERED_API_KEY,
});
const r = await client.chat.completions.create({
model: "uncensored",
messages: [{ role: "user", content: "Give me five villain names." }],
});
console.log(r.choices[0].message.content);Фреймворки и формат Responses
Библиотеки, оборачивающие клиент OpenAI, обычно предоставляют настройку базового URL. В обёртке LangChain для чата OpenAI это выглядит так:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.chatgptunfiltered.com/v1",
api_key="YOUR_KEY",
)
print(llm.invoke("Name three moods for a chase scene.").content)
Если вы используете новый формат Responses, поддерживается также POST /v1/responses наряду с POST /v1/chat/completions. GET /v1/models перечисляет модель, что является быстрой проверкой правильности вашего ключа и URL.
Ожидаемые отличия
| Область | Что вы заметите |
|---|---|
| Готовность отвечать | Отвечает без отказов по контенту для законного использования взрослыми. Промпты, которые отклоняет модель с фильтрами, обычно получают ответ. |
| Формулировки и стиль | Другая модель — другой голос. Тон, длина и привычки форматирования не будут совпадать с вашей предыдущей моделью. |
| Выбор модели | Одна модель, ID uncensored. Нет уровней для выбора. |
| Возможности | Только текст: нет генерации изображений, аудио или видео, нет эмбеддингов, нет дообучения. |
| Контекст | 100 000 токенов, промпт плюс генерация. max_tokens является необязательным. |
| Лимиты | Полный ключ: 8 параллельных запросов, 300 в минуту. Пробный ключ: 2 параллельных, 60 в минуту. Тело запроса до 8 МБ. |
| Ошибки | HTTP 429 с кодом rate_limited или concurrency; временная перегрузка возвращает 429 с Retry-After: 5. |
Поддерживаются потоковая передача, вызов функций и JSON-режим, а также temperature, top_p, stop, seed и штрафы. Заголовки ответа включают X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests и X-RateLimit-Limit-Concurrency. Документация содержит подробности.
Ещё два отличия заслуживают упоминания. Во-первых, другая модель может считать токены иначе, поэтому подсчёты для одного и того же текста могут отличаться от отчётов вашего старого провайдера; используйте данные об использовании в ответах, а не свои оценки. Во-вторых, функции, зависящие от хостинговых инструментов провайдера, такие как встроенный поиск в интернете или хранение файлов на стороне провайдера, не входят в этот сервис. Вызов функций: вы определяете функции, и ваш код их выполняет.
Скрипт проверки паритета для ваших промптов
Вместо визуального осмотра нескольких ответов запустите набор промптов через новый эндпоинт в цикле и сохраните всё, что нужно для проверки.
import csv, json
with open("prompts.json", encoding="utf-8") as f:
prompts = json.load(f) # a list of strings
with open("results.csv", "w", newline="", encoding="utf-8") as out:
w = csv.writer(out)
w.writerow(["prompt", "reply", "in_tokens", "out_tokens"])
for p in prompts:
r = client.chat.completions.create(
model="uncensored",
temperature=0.7,
messages=[{"role": "user", "content": p}],
)
w.writerow([p, r.choices[0].message.content, r.usage.prompt_tokens, r.usage.completion_tokens])
Откройте CSV и просматривайте столбцы по одному. Столбцы токенов дают прогноз стоимости для того же трафика: умножьте суммы на $0,15 и $0,50 за 1 млн. Пробный ключ позволяет 60 запросов в минуту и 2 одновременно, поэтому набор из нескольких сотен промптов завершится за минуты, если вы держите цикл последовательным.
Краткий чек-лист миграции
- Получите ключ. На странице API-ключ войдите через Google или электронную почту и получите пробный кредит $0,50. Он действует 7 дней и не требует карты.
- Перенесите имя модели и URL в конфигурацию. Одно место, чтение из переменных окружения.
- Запустите снова ваши тестовые промпты. Используйте от 20 до 50 реальных примеров, включая те, которые ваша предыдущая модель отказалась обрабатывать, и изучите результаты.
- Настройте системный промпт. Удалите текст, который существовал только для того, чтобы убедить отфильтрованную модель ответить. Оставьте то, что описывает роль, аудиторию и формат.
- Добавьте обработчик 429. Подождите 5 секунд и повторите попытку. Ограничьте параллельные запросы, чтобы соответствовать вашему ключу.
- Проверьте использование. Следите за
X-Balance-USDв ответах во время работы реального трафика.
Вспомогательная функция повтора, покрывающая шаг 5:
import time
from openai import RateLimitError
def create_with_retry(**kwargs):
for _ in range(4):
try:
return client.chat.completions.create(**kwargs)
except RateLimitError:
time.sleep(5)
raise RuntimeError("rate limited after 4 tries")
Храните сохранённые ответы старой модели несколько недель. Если пользователь пожалуется, что что-то пошло не так после переключения, вы сможете сравнить с тем, что сказала бы старая модель, и понять, является ли разница следствием промпта, модели или входных данных.
Внедрение без риска
Не переключайте всё сразу. Поместите выбор провайдера за конфигурацию, чтобы вы могли перенаправить часть трафика и откатиться за секунды.
import os, random
from openai import OpenAI
old = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
new = OpenAI(base_url="https://api.chatgptunfiltered.com/v1", api_key=os.environ["UNFILTERED_API_KEY"])
SHARE = float(os.environ.get("NEW_SHARE", "0.05"))
def pick():
if random.random() < SHARE:
return new, "uncensored"
return old, os.environ["OLD_MODEL"]
Начните с 5%, наблюдайте за долей ошибок, количеством 429 и отзывами пользователей в течение нескольких дней, затем увеличьте долю. Установите NEW_SHARE в 0, чтобы откатить изменения. Выбор по пользователю или по функции лучше, чем выбор по запросу, когда разговоры должны оставаться на одной модели, поскольку смена модели в середине чата меняет голос.
Стоимость и когда стоит остаться
Цены составляют $0,15 за 1M входных токенов и $0,50 за 1M выходных токенов из предоплаченного баланса. Запрос с 1 500 токенами на входе и 400 на выходе стоит 1 500 x $0,15 / 1M = $0,000225, плюс 400 x $0,50 / 1M = $0,0002, итого $0,000425, или $0,425 за 1 000 запросов. Для других провайдеров проверьте их текущие страницы с ценами; тарифы меняются, и сравнение из памяти быстро устаревает. Пополнения — целыми суммами от $20 до $500, оплачиваемые криптовалютой, с бонусами от $50. Подробности на странице цены.
Остаться с вашим текущим провайдером — правильный выбор, если вам нужны изображения или эмбеддинги, если вашей аудитории нужна строгая модерация или если модель конкретного вендора является жёстким требованием. Для получения информации о том, что представляет собой этот класс моделей, прочитайте понимание моделей ChatGPT без цензуры. Жёсткое ограничение никогда не меняется: запрещён сексуальный контент с участием несовершеннолетних.
Также можно запускать обоих провайдеров параллельно. Многие команды направляют обычные запросы к одной модели, а запросы, которые продолжают получать отказы, — к другой. Поскольку оба используют один формат, такая маршрутизация занимает несколько строк кода и правило, когда какую из них использовать.
