hubris

Instructor

Подключение Hubris к Instructor — библиотеке структурированного вывода на Python. Ответ модели приходит готовым объектом Pydantic.

Instructor — библиотека для структурированного вывода: вы описываете нужную форму ответа моделью Pydantic, а Instructor следит, чтобы модель вернула ровно её. Если ответ не проходит валидацию, библиотека сама переспрашивает модель с текстом ошибки.

Hubris подключается как OpenAI-совместимая точка — отдельного пакета не нужно.

Требования

Подключение

import os

import instructor
from openai import OpenAI
from pydantic import BaseModel


class User(BaseModel):
    name: str
    age: int


client = instructor.from_openai(
    OpenAI(
        api_key=os.environ["HUBRIS_API_KEY"],
        base_url="https://api.hubris.pw/v1",
    )
)

user = client.create(
    model="openai/gpt-5.6-luna",
    messages=[{"role": "user", "content": "Ivan is 28 years old"}],
    response_model=User,
)

print(user)
#> name='Ivan' age=28

Адрес — именно api.hubris.pw, с api. в начале и /v1 в конце. Домен hubris.pw — это сайт и личный кабинет: запросы к API он не обслуживает.

ID модели пишется полностью, вместе с вендором: openai/gpt-5.6-luna, anthropic/claude-sonnet-5. Здесь, в отличие от CrewAI, никакого лишнего префикса не нужно — Instructor работает через клиент OpenAI напрямую, без LiteLLM.

Вложенные структуры

class Address(BaseModel):
    street: str
    city: str


class Person(BaseModel):
    name: str
    age: int
    addresses: list[Address]


person = client.create(
    model="anthropic/claude-sonnet-5",
    messages=[{"role": "user", "content": "Джейсон, 25 лет, живёт на Мейн-стрит 123 в Нью-Йорке"}],
    response_model=Person,
)

Режимы

По умолчанию Instructor использует вызов инструментов (Mode.TOOLS) — модель «вызывает» функцию с нужной схемой. Есть и другие:

РежимКак работаетКогда брать
Mode.TOOLSсхема уходит как инструментпо умолчанию, самый надёжный
Mode.JSON_SCHEMAresponse_format со схемойкогда модель поддерживает structured_outputs
Mode.MD_JSONсхема описывается в промптезапасной вариант, работает у любой модели
client = instructor.from_openai(
    OpenAI(api_key=..., base_url="https://api.hubris.pw/v1"),
    mode=instructor.Mode.JSON_SCHEMA,
)

Какие режимы потянет конкретная модель, видно в её карточке в каталоге: tools в supported_parameters — работает Mode.TOOLS, structured_outputs — работает Mode.JSON_SCHEMA.

Потоковая выдача

Частичный объект по мере генерации — удобно, когда форма большая и хочется показывать её пользователю по ходу:

for partial in client.create_partial(
    model="openai/gpt-5.6-luna",
    messages=[{"role": "user", "content": "Ivan is 28 years old"}],
    response_model=User,
):
    print(partial)
#> name=None age=None
#> name='Ivan' age=None
#> name='Ivan' age=28

Асинхронный клиент — через instructor.from_openai(AsyncOpenAI(...)).

Выбор моделей

IDКогда подходит
google/gemini-3.7-flashдешёвое извлечение полей на потоке
openai/gpt-5.6-lunaуниверсальный выбор
anthropic/claude-sonnet-5длинные документы, сложные схемы, картинки
deepseek/deepseek-v4-proнедорогое рассуждение и код

Каталог у нас открыт без ключа — список можно посмотреть прямо в браузере: api.hubris.pw/v1/models.

Встроенный провайдер «Hubris»

Мы отправили в Instructor отдельного провайдера — pull request на ревью. После приёма подключение станет однострочным:

client = instructor.from_provider("hubris/openai/gpt-5.6-luna")

с ключом из переменной HUBRIS_API_KEY. Пока PR не принят, работает описанный выше способ через from_openai — это то же самое подключение, просто клиент создаётся руками.

Решение проблем

AuthenticationError

Ключ неверный или отозван. Он начинается на sk-gw-, без пробелов по краям; целиком виден только при создании. Новый — в разделе «Ключи».

Ошибка про модель

ID должен совпадать с каталожным символ в символ, вместе с вендором перед косой чертой. Короткие имена без вендора и имена с датой на конце мы не принимаем.

Модель не держит схему, Instructor переспрашивает по кругу

Смените режим на Mode.MD_JSON — он работает у любой модели, потому что схема уходит текстом в промпт. Либо возьмите модель, у которой в карточке есть structured_outputs.

Ошибка про недостаточный баланс

Пополните баланс в кабинете — от 300 ₽, через СБП, банковской картой или по счёту для юридических лиц.

Проверено на Instructor 1.16.0, 9 сентября 2026.

Что дальше

Обновлено: