Перейти к содержимому
EN

Vercel AI SDK

Подключите Vercel AI SDK к Mixen — оплата с баланса в рублях, каталог из 105+ моделей через пакет @ai-sdk/openai.

Окно терминала
npm install ai @ai-sdk/openai

Для интерфейсных хуков (useChat) дополнительно:

Окно терминала
npm install @ai-sdk/react

Создайте провайдера с нашим base URL и ключом:

import { createOpenAI } from '@ai-sdk/openai'
import { generateText } from 'ai'
const mixen = createOpenAI({
baseURL: 'https://api.mixen.ai/v1',
apiKey: process.env.MIXEN_API_KEY,
})
const { text } = await generateText({
model: mixen('openai/gpt-5.6-sol'),
prompt: 'Придумай слоган для сервиса доставки книг',
})

Стриминг:

import { streamText } from 'ai'
const result = streamText({
model: mixen('z-ai/glm-5.3'),
prompt: 'Напиши короткий пост для блога о кофе',
})
for await (const chunk of result.textStream) {
process.stdout.write(chunk)
}

Ключевые моменты:

  • Провайдер — это функция: mixen('<ID модели>') возвращает модель для generateText, streamText и остальных вызовов AI SDK.
  • Опции называются именно baseURL и apiKey. Без них провайдер уйдёт на дефолт https://api.openai.com/v1 (или на переменные OPENAI_BASE_URL / OPENAI_API_KEY).
  • Ключ mxn-… выпускается в кабинете; process.env читается при старте процесса — после правки .env перезапустите dev-сервер.

Типовая связка: серверный роут стримит ответ модели, клиент на useChat рисует его по мере поступления токенов.

Сервер — app/api/chat/route.ts в Next.js:

import { createOpenAI } from '@ai-sdk/openai'
import {
streamText,
convertToModelMessages,
createUIMessageStreamResponse,
toUIMessageStream,
type UIMessage,
} from 'ai'
const mixen = createOpenAI({
baseURL: 'https://api.mixen.ai/v1',
apiKey: process.env.MIXEN_API_KEY,
})
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json()
const result = streamText({
model: mixen('z-ai/glm-5.3'),
system: 'Ты — консультант книжного магазина. Отвечай коротко и по делу.',
messages: await convertToModelMessages(messages),
})
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
})
}

Клиент — компонент чата:

'use client'
import { useChat } from '@ai-sdk/react'
import { DefaultChatTransport } from 'ai'
import { useState } from 'react'
export default function Chat() {
const [input, setInput] = useState('')
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({ api: '/api/chat' }),
})
return (
<div>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
sendMessage({ parts: [{ type: 'text', text: input }] })
setInput('')
}
}}
/>
{messages.map((message) => (
<div key={message.id}>
{message.parts.map((part, i) =>
part.type === 'text' ? <p key={i}>{part.text}</p> : null,
)}
</div>
))}
</div>
)
}

Что здесь происходит:

  • Клиент шлёт массив UIMessage на /api/chat; convertToModelMessages превращает их в сообщения модели.
  • streamText возвращает поток, toUIMessageStream + createUIMessageStreamResponse упаковывают его в протокол UI-стрима — useChat читает его из коробки.
  • system в streamText задаёт системную инструкцию — держите её постоянной, стабильный префикс попадает в промпт-кэш.
  • Стриминг настоящий: дельты приходят из модели по мере генерации, интерфейс печатает ответ сразу, не дождавшись его конца.
Задача Модель Цена за 1M токенов
Массовые вызовы: черновики, подсказки, классификация z-ai/glm-5.3-flash 8.4 ₽ вход / 27.9 ₽ выход
Сложные задачи, длинный контекст, аккуратный код anthropic/claude-sonnet-5 213.9 / 1069.5 ₽

Диалоговый чат — идеальный кандидат на промпт-кэш: каждый ход повторяет системную инструкцию и историю, и повторяющийся префикс считается по ~10% цены входа (у claude-sonnet-5 — 21.4 ₽ за 1M вместо 213.9 ₽, у glm-5.3-flash — 1.7 ₽). Окно кэша — 5 минут с продлением от каждого попадания, так что живой диалог дешевле, чем те же вопросы по одному. Практика: системный промпт в system не пересобирать, переменные данные — в сообщения.

Глубина рассуждения задаётся reasoning_effort API (значения off, low, medium, high, xhigh, max; поддерживаемые уровни — в GET /v1/modelscapabilities.reasoning_efforts). Учитывайте, что рассуждение расходует лимит ответа: под длинный вывод задавайте maxOutputTokens с запасом.

Модель ID
GPT-5.6 Sol openai/gpt-5.6-sol
Claude Opus 5 anthropic/claude-opus-5
GLM 5.3 z-ai/glm-5.3
DeepSeek V4 Pro deepseek/deepseek-v4-pro
Kimi K3 moonshotai/kimi-k3

Актуальный список — в каталоге.

  • 401 / Invalid API Key — переменная MIXEN_API_KEY не задана в окружении процесса или ключ скопирован не целиком; после правки .env перезапустите приложение.
  • Запросы уходят на api.openai.com — опечатка в имени опции: baseUrl вместо baseURL в JavaScript молча игнорируется, и провайдер использует дефолтный адрес (TypeScript подсветит ошибку).
  • «model not found» — ID модели передавайте посимвольно из каталога, включая префикс вендора (openai/…, anthropic/…).
  • useChat молчит, ответ не появляется — проверьте, что роут возвращает createUIMessageStreamResponse и api в DefaultChatTransport указывает на него; useChat ничего не знает о провайдере — он общается только с вашим роутом.
  • Роут возвращает текст, но не стримит — убедитесь, что возвращается стрим-ответ, а не result.text: ожидание этого свойства отдаёт ответ целиком, уже без потока.