В этой статье
Для обращения к локальному GPT-OSS API из Python отправьте POST на адрес:
http://localhost:11434/v1/chat/completions
В запросе нужны модель gpt-oss:20b, массив messages и stream: false. В ответе придёт готовый JSON, из которого программа прочитает choices[0].message.content. Это OpenAI-совместимый интерфейс Ollama: он использует схему Chat Completions, а запрос выполняет локальная модель. Документация Ollama об OpenAI-совместимости
Локальный сервер Ollama по умолчанию не требует авторизации. Заголовок Authorization и ключ OpenAI здесь не нужны. Документация об аутентификации Ollama
Если для ручного разбора этого кода вы также пользуетесь личным ChatGPT, Amber Market — сервис оплаты зарубежных сервисов — помогает оформить из России месячный ChatGPT Plus на своём аккаунте через менеджера. Заказ можно оплатить через СБП. Для оформления нужен аккаунт Free без действующей подписки; продление доступно после её окончания. Перед оплатой проверьте актуальные условия и итоговую стоимость. Сам локальный GPT-OSS не требует Plus и не расходует баланс OpenAI API. У облачных продуктов свои расчёты: ChatGPT Plus и API оплачиваются отдельно, подписка не пополняет API-баланс.
Подготовьте модель и проверьте адрес
Пример рассчитан на установленный Ollama, Python 3 и подходящий для модели компьютер. Python и Ollama работают на одной машине, без разделения через Docker или WSL. По умолчанию Ollama слушает 127.0.0.1:11434; в программе ниже используется соответствующий локальный адрес localhost:11434. FAQ Ollama
При работающем Ollama скачайте модель и проверьте её имя:
ollama pull gpt-oss:20b
ollama list
В списке должен быть точный тег gpt-oss:20b, без суффикса -cloud. Если модель уже загружена, достаточно ollama list. Уже запущенный сервис повторно запускать не нужно.
В руководстве OpenAI для GPT-OSS 20B рекомендуется от 16 ГБ видеопамяти или общей памяти. Программа обойдётся стандартной библиотекой Python, но саму модель всё равно нужно разместить в памяти. Требования к компьютеру сверяйте с официальным руководством по локальному запуску.
Полный файл gpt_oss_api.py
Сохраните этот код в gpt_oss_api.py. Он отправляет JSON, отдельно сообщает об HTTP-ошибках и проблемах соединения, затем извлекает текст ответа.
import json
import urllib.error
import urllib.request
URL = "http://localhost:11434/v1/chat/completions"
MODEL = "gpt-oss:20b"
payload = {
"model": MODEL,
"messages": [
{
"role": "user",
"content": (
"Письма: Мария — счёт; Олег — встреча; "
"Мария — договор. Верни только темы писем от Марии "
"через запятую, без вступления."
),
}
],
"stream": False,
}
request = urllib.request.Request(
URL,
data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=120) as response:
result = json.load(response)
except urllib.error.HTTPError as error:
details = error.read().decode("utf-8", errors="replace")
print(f"HTTP {error.code}: {details}")
raise SystemExit(1)
except urllib.error.URLError as error:
print(f"Ошибка соединения с Ollama: {error.reason}")
raise SystemExit(1)
except TimeoutError:
print("Истёк тайм-аут ожидания данных от Ollama.")
raise SystemExit(1)
except json.JSONDecodeError as error:
print(f"Ollama вернул некорректный JSON: {error}")
raise SystemExit(1)
try:
content = result["choices"][0]["message"]["content"]
except (KeyError, IndexError, TypeError):
print(f"В ответе нет ожидаемого поля content: {result}")
raise SystemExit(1)
if not isinstance(content, str) or not content.strip():
print(f"Поле content не содержит текста: {result}")
raise SystemExit(1)
print(content)
ensure_ascii=False оставляет русские символы в JSON, а encode("utf-8") превращает его в байты тела запроса. Content-Type: application/json сообщает серверу формат тела. При stream: false программа ждёт готовый JSON и читает его через json.load.
Значение timeout=120 задаёт 120 секунд ожидания для блокирующих сетевых операций. Это выбранный лимит программы, а не обещание скорости модели или строгий предел времени всего запуска. Первый запрос может ждать загрузки весов в память.
Здесь везде используется /v1/chat/completions. Нативный маршрут Ollama /api/chat — отдельный интерфейс: подставлять его в этот код нельзя, в частности, путь к тексту ответа будет другим. Облачный OpenAI Responses API и Ollama Cloud также не участвуют в запросе.
Если позже замените urllib на Python SDK openai, для этого локального сервера задайте base_url="http://localhost:11434/v1". SDK требует поле api_key, поэтому ему можно передать формальную строку "ollama": локальный сервер её игнорирует. В текущем примере нет ни SDK, ни этого поля.
Получите текст и проверьте две темы
Запустите файл:
python gpt_oss_api.py
После успешного ответа программа печатает choices[0].message.content. Для приведённых входных данных эталон — счёт, договор: две темы писем Марии в исходном порядке, без вступления. Это ожидаемый результат задания, а не записанный вывод запуска модели.
Сравните с ним полученный текст вручную. Ответ HTTP 200 и наличие content подтверждают, что запрос прошёл и текст получен; они не подтверждают правильность фильтра. В ответе не должно оказаться встречи Олега, лишней темы или переставленных местами писем.
Модельный ответ остаётся строкой данных. Для этой задачи его нужно напечатать, а не передавать в exec или другой интерпретатор.
Если запрос не проходит
Connection refused означает, что по указанному адресу не удалось подключиться к локальному процессу. Проверьте URL в файле, откройте приложение Ollama, если оно не запущено, и убедитесь, что Python выполняется на том же компьютере. Если Ollama уже работает, проверьте его локальный адрес. Облачный ключ эту ошибку не исправит.
HTTP-ошибка означает, что сервер ответил отказом. Код печатает и статус, и тело ответа. Если сообщение указывает на неизвестную модель, сверяйте тег с ollama list; для этого примера нужна именно gpt-oss:20b. При её отсутствии выполните ollama pull gpt-oss:20b и повторите запрос.
При долгом ожидании или тайм-ауте проверьте загрузку модели и доступную память. Увеличение timeout даст больше времени на ответ, но не ускорит вычисления. Покупка ChatGPT Plus на работу локального Ollama не повлияет.
Для этого сценария оставьте сервер на локальном адресе: открывать его в интернет, менять bind, порты или прокси не требуется. Если задача сменится на запрос к облачной модели OpenAI, используйте отдельный пример подключения к OpenAI API.
Источники
- Подписки ChatGPT — Amber MarketAmber Market
- What is ChatGPT Plus?OpenAI
- How to run gpt-oss locally with OllamaOpenAI
- OpenAI compatibility — OllamaOllama
- Authentication — OllamaOllama
- FAQ — OllamaOllama