От LangGraph нужны ровно две настройки:
base_url = "https://speshu.ai/api/v1" и API-ключ. Модель совместима с OpenAI Chat Completions, поэтому ChatOpenAI из langchain-openai работает с ней без специального адаптера — меняются только адрес и ключ.Установка
Возьмите идентификатор модели из каталога
Идентификаторы текстовых моделей не зашивайте в код: состав каталога меняется, и зашитый в код идентификатор начинает падать с404 model_not_found. Возьмите id из GET /api/v1/models и сохраните его в SPESHU_MODEL — во всех примерах ниже используется именно эта переменная.
cURL
Настройка клиента
ChatOpenAI — pydantic-модель: model, base_url и api_key — алиасы её полей model_name, openai_api_base и openai_api_key. Принимаются оба написания, примеры используют короткие.
Python
Первый рабочий пример
Граф из одного узла с памятью. Checkpointer сохраняет состояние поthread_id, поэтому второй вызов с тем же идентификатором диалога видит историю.
Python
InMemorySaver хранит состояние в процессе и умирает вместе с ним — годится для примера и тестов. Имя актуально для langgraph 0.4 и новее — в более ранних версиях тот же класс назывался MemorySaver. Для продакшена поставьте постоянный checkpointer: pip install -U langgraph-checkpoint-postgres, затем langgraph.checkpoint.postgres.PostgresSaver. Отдельно: LangChain не пробрасывает usage.cost.total_cost в AIMessage — расход смотрите запросом GET /api/v1/balance, он бесплатный. Разбор — в разделе Тарификация и оплата.Инструменты
ToolNode исполняет вызванные моделью функции и возвращает их результаты в состояние. Модель ничего не знает о вашем коде: что и когда звать, она решает по name и description инструмента.
Python
tools_condition завершает цикл, когда модель перестала возвращать tool_calls. Ограничьте число шагов счётчиком в состоянии: без ограничения модель может зациклиться на одном инструменте и съесть бюджет. Полный цикл вызова инструмента, формат tool_calls и разбор ошибок — в гайде Вызов функций.
Потоковая передача
stream_mode="messages" на graph.stream отдаёт пары (фрагмент_сообщения, метаданные). Это тот же SSE, что и на потоковой передаче, только кадры разбирает библиотека.
Python
Структурированный вывод
with_structured_output заставляет модель вернуть объект заданной схемы. Аргумент method в разных версиях langchain-openai принимает разные значения, поэтому ниже он не указан — используется значение по умолчанию текущей версии.
Python
strict и поведения при невалидном результате — в гайде Структурированный вывод.
Генерация медиа
Медиа создаётся отдельным API: запрос создаёт задачу, деньги списываются сразу, результат приходит по опросу. Из узла графа это обычная блокирующая функция. Идентификатор медиа-модели, в отличие от текстовой, можно написать литералом — каталогGET /api/v1/media/models публичный и стабильный.
Python
@tool к узлу ToolNode — и агент сможет звать генерацию как обычный инструмент. Формат задачи, опрос и коды — в разделе Создание задачи.
Если нужен RAG с эмбеддингами
(а) Эмбеддинги — отдельный провайдер, генерация — SpeShu.AI. Так делают в большинстве проектов: векторизация дешевле, и её качество не зависит от модели, на которой вы пишете промпт. Держите адрес и ключ этого провайдера отдельной конфигурацией, чтобы он не перепутался с ключом SpeShu.AI.Python
Если что-то не работает
404 на первом же запросе, ошибок от модели нет
404 на первом же запросе, ошибок от модели нет
Проверьте адрес: он должен быть ровно
https://speshu.ai/api/v1 — с суффиксом /v1 и без слэша в конце. Варианты https://speshu.ai/api и https://speshu.ai/api/v1/ дают 404, и клиент OpenAI ничего к адресу не дописывает.404 model_not_found
404 model_not_found
Идентификатор устарел или скопирован с ошибкой. Возьмите его заново из
GET /api/v1/models и подставьте как есть. Список, зашитый в код, устаревает молча — поэтому в примерах используется переменная SPESHU_MODEL.История не помнится между вызовами
История не помнится между вызовами
Checkpointer не подключён или у вызовов разный
thread_id. compile(checkpointer=...) обязателен, иначе граф не имеет состояния. Идентификатор диалога передаётся вторым аргументом в invoke — по ключу config["configurable"]["thread_id"].Граф зациклился на одном инструменте
Граф зациклился на одном инструменте
Модель возвращает
tool_calls по кругу. Ограничьте число шагов: добавьте в состояние счётчик итераций и ведите из него ребро в конец графа.Что дальше
Вызов функций
Полный цикл вызова инструмента
Потоковая передача
Разбор SSE, таймауты и когда списываются деньги
Структурированный вывод
JSON Schema и валидация результата
Модели и цены
Каталог, фильтры и выбор модели под задачу
