Heli + Chainlit: чат-интерфейс на Python со стримингом

Chainlit — Python-фреймворк для быстрого чат-интерфейса: несколько функций-обработчиков, и у вас готовый веб-чат с историей и стримингом. Модель вызывается через официальный SDK openai, поэтому для Heli достаточно указать base_url https://getheli.ru/v1 и ключ sk-heli- из вкладки «Ключи».

app.py

Установка и запуск: pip install chainlit openai, затем chainlit run app.py -w. Флаг -w перезапускает приложение при изменении файла.

python
import os
import chainlit as cl
from openai import AsyncOpenAI

client = AsyncOpenAI(base_url="https://getheli.ru/v1", api_key=os.environ["HELI_API_KEY"])
MODEL = "openai/gpt-5.4-mini"

@cl.on_chat_start
async def start():
    cl.user_session.set("history", [
        {"role": "system", "content": "Ты полезный ассистент. Отвечай по-русски."}
    ])

@cl.on_message
async def on_message(message: cl.Message):
    history = cl.user_session.get("history")
    history.append({"role": "user", "content": message.content})

    msg = cl.Message(content="")
    stream = await client.chat.completions.create(
        model=MODEL, messages=history, stream=True, max_tokens=1500
    )
    async for chunk in stream:
        if chunk.choices and chunk.choices[0].delta.content:
            await msg.stream_token(chunk.choices[0].delta.content)

    history.append({"role": "assistant", "content": msg.content})
    await msg.update()

На что обратить внимание

  • Используйте AsyncOpenAI: обработчики Chainlit асинхронные, а синхронный клиент блокирует приложение для всех пользователей на время ответа.
  • Проверяйте chunk.choices: последний чанк потока Heli содержит только usage и пустой список choices.
  • История хранится в cl.user_session отдельно для каждой сессии. Обрезайте её до последних реплик — весь контекст оплачивается в каждом запросе.
  • Ключ держите в переменной окружения или файле .env, который не попадает в git.

Streaming в Heli API

Переменные окружения для Heli

Выбор модели в интерфейсе

Chainlit позволяет дать пользователю переключатель модели через настройки чата (cl.ChatSettings с элементом Select). Значения — обычные слаги каталога Heli, например openai/gpt-5.4-mini или anthropic/claude-sonnet-5. Ограничьте список несколькими моделями: так проще прогнозировать расход.

GPT-5.4 mini

Claude Sonnet 5

Gemini 3.5 Flash

Частые ошибки

  • 401 — неверный ключ или лишний пробел в переменной окружения.
  • Ошибка о неизвестной модели — слаг указан без префикса vendor/.
  • Ответ приходит целиком, а не по токенам, — включён stream=False или ответ буферизует прокси перед приложением.

Ошибка 401

Ошибка invalid model

Python SDK + Heli

Деплой и доступ

По умолчанию Chainlit слушает порт 8000 и общается с браузером через WebSocket. Если перед приложением стоит nginx, проксируйте заголовки Upgrade и Connection, иначе чат не подключится. Не публикуйте приложение без авторизации: любой, кто знает адрес, будет тратить ваш баланс.

В Chainlit есть встроенная авторизация, например по паролю через декоратор @cl.password_auth_callback. Для неё нужен секрет CHAINLIT_AUTH_SECRET — его генерирует команда chainlit create-secret. После входа в сессии доступен пользователь, и расход можно учитывать по нему.

Попробуйте Heli

Ключ sk-heli- появляется после подтверждения почты. Через Google и Яндекс — сразу в кабинете.

Документация API · Модели и цены

Читайте также