Kimi K3.1 Pro and Highspeed are now live on CometAPI →
guide/CometAPI зерттеуі

Next.js және CometAPI көмегімен көп модельді ЖИ-чат қолданбасын қалай құруға болады

Бір CometAPI кілті мен бекэнд эндпоинті арқылы GPT, Claude және Gemini үлгілері арасында ауыса алатын ағындық Next.js ЖИ чат қолданбасын құрыңыз.

CometAPI
AnnaAI model және API зерттеу тобы
Жаңартылды Sep 3, 2026 12 мин оқу
Next.js және CometAPI көмегімен көп модельді ЖИ-чат қолданбасын қалай құруға болады
Осы үлгіні пайдалану

Бірінші API шақыруын жасаңыз.

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_COMETAPI_KEY",
    base_url="https://api.cometapi.com/v1",
)

response = client.chat.completions.create(
    model="gpt-5-mini",
    messages=[{"role": "user", "content": "Build this workflow."}],
)

print(response.choices[0].message.content)

Next.js чатына бірнеше модель провайдері қажет болғанда, ең тиімді бэкенд — аутентификацияны бір жерде шоғырландырып, қосымшаның әр сұраным үшін модельді таңдауға мүмкіндік беретін архитектура. CometAPI осындай үлгіні ұсынады: сервер бір API кілтін және OpenAI-мен үйлесімді базалық URL-ді https://api.cometapi.com/v1 сақтайды, ал сұранымдағы model өрісі қолжетімді GPT, Claude, Gemini немесе басқа чат моделін таңдайды. 

Бұл нұсқаулықта сервер жақта модельдер рұқсат тізімі (allowlist), ағындық Route Handler, браузерде модель таңдағыш, қорғалған орта айнымалылары, толық чат интерфейсі және орналастыруға арналған нұсқаулар бар жұмыс істейтін App Router жобасы құрылады. CometAPI кілті ешқашан браузерге жетпейді.

Көпмодельді AI чат қолданбасы деген не?

Көпмодельді AI чат архитектурасында пайдаланушы интерфейсі мен бірнеше модель провайдері арасындағы бір, қолданба бақылайтын бэкенд орналасады. Осы жобада браузер әңгімені /api/chat маршрутына жібереді, сервер CometAPI деректерін құпия ұстайды, сұралған модель ID-сін тексереді және сұранымды бір үйлесімді API арқылы бағыттайды.

Next.js-та модельдерді ауыстыру қалай жұмыс істейді?

Модельді өзгерту — бұл маршрутизация туралы шешім. Браузер сөйлесуді /api/chat маршрутына жібергенде, онымен бірге рұқсат етілген модель ID-сі де беріледі. Route Handler CometAPI деректерін қосады, POST /v1/chat/completions шақырады және таңдалған моделдің ағындық жауабын браузерге қайта жібереді.

Ортақ соңғы нүкте барлық модельдерді бірдей етпейді. Шығыс стилі, құралдар мінез-құлқы, қолдау көрсетілетін параметрлер, контекст шектеулері және баға айырмашылығы болуы мүмкін. Модель ID-сін сервер жақтағы рұқсат тізімінде сақтаңыз және пайдаланушыларға ұсынбас бұрын әр маршрутты бірдей қолданбалық prompt-пен сынаңыз.

Не құрасыз

Дайын қолданбада бір Next.js бэкенді және таңдауға болатын үш чат маршруты бар:

Model IDМысал рөліCometAPI бағасы
gemini-3.7-flashҚұны сезімтал, жоғары көлемді чат$0.60 input / $3.00 output
claude-opus-5Нысаналы премиум-ойлау$4 input / $20 output
gpt-5.6gpt-5.6 — GPT-5.6 үшін CometAPI-дің жалпы бағыты, қазір Sol деңгейіне сәйкес келеді.$3.2 input / $16 output (қысқа контекст деңгейі)

Баға туралы ескерту: Төменде көрсетілген бағалар — миллион токенге USD түрінде, 2026 жылғы 21 тамызда тексерілген және өзгеруі мүмкін. Өндірісте қолданар алдында әрқашан модель беттеріндегі өзекті мөлшерлемелерді тексеріңіз. Бұл кесте — маршрутизация мысалы, сапа рейтингі емес. GPT-5.6 272,000 токеннен жоғарының бағасы жоғары деңгейге өтеді. Мұнда қолданылған бағалар үшін сілтемеленген Gemini 3.7 Flash, Claude Opus 5, және GPT-5.6 модель беттерін қараңыз.

CometAPI модельдерді провайдердің ресми API-леріне ашық сәйкестендірілген бағамен ұсынады. Біріктірілген ресми бағасы бар модельдер — OpenAI, Claude, Gemini және ұқсастары — токен бойынша ресми бағаның 0.8:1 қатынасы бойынша, яғни 20% жеңілдікпен тарифтеледі; ресми API-і жоқ модельдер (MidJourney, Kling, Luma) CometAPI белгілеген ставкалармен бір қоңырау үшін тарифтеледі, мұнда да 20% жеңілдік қолданылады. Есептеу формуласы, модельдер бойынша тарифтер және биллинг бірліктері үшін CometAPI Pricing Guide құжатын қараңыз.

Бұл үш маршрут әртүрлі компромистерді қамтиды. Gemini 3.7 Flash — Google-дың тиімді агентті жұмысшысы, мультимодальді кіріс пен 1,048,576 токендік контекст терезесін ұсынады, жоғары көлемді чат, код және білім жұмыс ағындарына лайық. Claude Opus 5 — Anthropic-тің алдыңғы қатарлы ойлау моделі, көпқадамды талдау, код және мұқият ұзақ мәтін жазуда мықты, премиум бағамен. GPT-5.6 — OpenAI-дің көпмақсатты моделі, кең контекст терезесінде рационал, құрал қолдану және мәтін дайындауды теңестіріп, күнделікті өндірістік трафикке сай.

Бастамас бұрын

Сізге Node.js, npm, CometAPI аккаунты және CometAPI Quick Start бетінде көрсетілген серверлік API кілті керек. Жоғарыдағы үш нақты модель ID 2026 жылғы 21 тамызда тірі каталогта қолжетімді болды, "upcoming" деп белгіленбеді және POST /v1/chat/completions endpoint-ін ұсынды.

Бұл нұсқаулық ортақ параметрлерді қолданады:

1-қадам: Next.js қолданбасын жасаңыз

npx create-next-app@latest multi-model-chat --ts --app --eslintcd multi-model-chatnpm run dev

Бұл нұсқада модель-провайдері үшін SDK қажет емес. Сервер кірістірілген fetch API-ін қолданады және жоғары жақтағы Server-Sent Events ағынын форвардтайды.

2-қадам: CometAPI кілтін серверде сақтаңыз

Жобаның түбірінде .env.local жасаңыз:

COMETAPI_API_KEY=replace_with_your_cometapi_keyCOMETAPI_BASE_URL=https://api.cometapi.com/v1

Кілтті NEXT_PUBLIC_ префиксімен бастамаңыз. Next.js тек осы префикспен басталатын айнымалыларды браузер бандлдеріне ашады; API кілті сервер жақтағы Route Handler-де болуы керек.

3-қадам: Модель саясатын анықтаңыз

Рұқсат етілген ID-лерді тек бэкендке қойыңыз, тек қана тізім ашылмалы мәзіріне емес. Пайдаланушы браузердегі бақылауларды айналып өтіп, маршрутыңызды тікелей шақыра алады, сондықтан сервер белгісіз модель мәндерін қабылдамауы тиіс.

const ALLOWED_MODELS = [  "gemini-3.7-flash",  "claude-opus-5",  "gpt-5.6",] as const;​type ModelId = (typeof ALLOWED_MODELS)[number];

Клиент осы үш ID-ді селектор үшін қолданады, ал сервер — ақиқаттың жалғыз көзі болып қалады.

4-қадам: CometAPI ағынын Route Handler арқылы өткізіңіз

app/api/chat/route.ts жасаңыз. Бұл маршрут тек қана мәтіндік чат пэйлоадын тексереді, CometAPI-ді stream: true параметрімен шақырады және деректерді жоғары жақтан келген оқиға ағыны ретінде, деректерді ашпай, қайтарады.

export const runtime = "nodejs";export const dynamic = "force-dynamic";​const ALLOWED_MODELS = [  "gemini-3.7-flash",  "claude-opus-5",  "gpt-5.6",] as const;​type ModelId = (typeof ALLOWED_MODELS)[number];type ChatMessage = {  role: "system" | "user" | "assistant";  content: string;};​function isModelId(value: unknown): value is ModelId {  return (    typeof value === "string" &&    (ALLOWED_MODELS as readonly string[]).includes(value)  );}​function isChatMessage(value: unknown): value is ChatMessage {  if (typeof value !== "object" || value === null) return false;​  const message = value as Record<string, unknown>;  return (    ["system", "user", "assistant"].includes(String(message.role)) &&    typeof message.content === "string" &&    message.content.length > 0 &&    message.content.length <= 20_000  );}​export async function POST(request: Request) {  const apiKey = process.env.COMETAPI_API_KEY;  const baseUrl = (    process.env.COMETAPI_BASE_URL || "https://api.cometapi.com/v1"  ).replace(/\/$/, "");​  if (!apiKey) {    return Response.json(      { error: "COMETAPI_API_KEY is not configured." },      { status: 500 },    );  }​  let payload: { model?: unknown; messages?: unknown };​  try {    payload = await request.json();  } catch {    return Response.json({ error: "Invalid JSON body." }, { status: 400 });  }​  if (!isModelId(payload.model)) {    return Response.json({ error: "Unsupported model ID." }, { status: 400 });  }​  if (    !Array.isArray(payload.messages) ||    payload.messages.length === 0 ||    payload.messages.length > 50 ||    !payload.messages.every(isChatMessage)  ) {    return Response.json(      { error: "messages must contain 1 to 50 valid text messages." },      { status: 400 },    );  }​  const upstream = await fetch(`${baseUrl}/chat/completions`, {    method: "POST",    headers: {      Authorization: `Bearer ${apiKey}`,      "Content-Type": "application/json",    },    body: JSON.stringify({      model: payload.model,      messages: payload.messages,      stream: true,    }),    cache: "no-store",    signal: request.signal,  });​  if (!upstream.ok) {    const requestId = upstream.headers.get("x-request-id");​    console.error("CometAPI request failed", {      status: upstream.status,      requestId,    });​    return Response.json(      {        error: "The selected model request failed.",        status: upstream.status,        requestId,      },      { status: upstream.status },    );  }​  if (!upstream.body) {    return Response.json(      { error: "The model returned no response body." },      { status: 502 },    );  }​  return new Response(upstream.body, {    status: 200,    headers: {      "Content-Type": "text/event-stream; charset=utf-8",      "Cache-Control": "no-cache, no-transform",    },  });}

Өңдегіш браузердің ажырату сигналын жоғары жаққа жібереді, сондықтан сұранымды жабу қажетсіз генерацияны тоқтатуы мүмкін. Сондай-ақ, сервер журналдарында диагностикалық бөлшектер қалдырып, клиентке тазартылған қате хабарын қайтарады.

5-қадам: Модель таңдағыш пен ағынды талдауды қосыңыз

app/page.tsx ішінде клиент компонентін жасаңыз. Ол таңдаулы модельмен әңгімені жібереді, әр data: оқиғасын талдайды және инкременталды delta.content мәтінін соңғы көмекші хабарламасына қосады.

Браузер ешқашан CometAPI-ді тікелей шақырмайды. Оның жалғыз бағыты — API кілтін құпия сақтайтын және рұқсат тізімін қамтамасыз ететін сіздің /api/chat маршрутыңыз.

Негізгі жоба коды

Жоғарыдағы Route Handler — app/api/chat/route.ts файлының толық нұсқасы. Жұмыс істейтін жобаны аяқтау үшін төмендегі бет, layout және stylesheet қосыңыз.

app/page.tsx

"use client";​import { FormEvent, useState } from "react";​const MODEL_OPTIONS = [  { id: "gemini-3.7-flash", label: "Gemini 3.7 Flash" },  { id: "claude-opus-5", label: "Claude Opus 5" },  { id: "gpt-5.6", label: "GPT-5.6" },] as const;​type Role = "user" | "assistant";type Message = { role: Role; content: string };​function textFromSseLine(line: string): string {  const trimmed = line.trim();  if (!trimmed.startsWith("data:")) return "";​  const data = trimmed.slice(5).trim();  if (!data || data === "[DONE]") return "";​  try {    const event = JSON.parse(data);    return event.choices?.[0]?.delta?.content ?? "";  } catch {    return "";  }}​export default function Home() {  const [model, setModel] = useState("gemini-3.7-flash");  const [messages, setMessages] = useState<Message[]>([]);  const [input, setInput] = useState("");  const [loading, setLoading] = useState(false);  const [error, setError] = useState("");​  function appendAssistantText(text: string) {    if (!text) return;​    setMessages((current) => {      const next = [...current];      const lastIndex = next.length - 1;​      if (lastIndex >= 0 && next[lastIndex].role === "assistant") {        next[lastIndex] = {          ...next[lastIndex],          content: next[lastIndex].content + text,        };      }​      return next;    });  }​  async function sendMessage(event: FormEvent<HTMLFormElement>) {    event.preventDefault();​    const content = input.trim();    if (!content || loading) return;​    const outgoing: Message[] = [...messages, { role: "user", content }];    setMessages([...outgoing, { role: "assistant", content: "" }]);    setInput("");    setError("");    setLoading(true);​    try {      const response = await fetch("/api/chat", {        method: "POST",        headers: { "Content-Type": "application/json" },        body: JSON.stringify({ model, messages: outgoing }),      });​      if (!response.ok) {        const body = await response.json().catch(() => ({}));        throw new Error(body.error || `Request failed with ${response.status}`);      }​      if (!response.body) throw new Error("Streaming is not available.");​      const reader = response.body.getReader();      const decoder = new TextDecoder();      let buffer = "";​      while (true) {        const { value, done } = await reader.read();        buffer += decoder.decode(value, { stream: !done });​        const lines = buffer.split("\n");        buffer = lines.pop() ?? "";​        for (const line of lines) {          appendAssistantText(textFromSseLine(line));        }​        if (done) {          appendAssistantText(textFromSseLine(buffer));          break;        }      }    } catch (requestError) {      setError(        requestError instanceof Error ? requestError.message : "Request failed.",      );    } finally {      setLoading(false);    }  }​  return (    <main className="shell">      <section className="chat">        <header>          <p className="eyebrow">Next.js + CometAPI</p>          <h1>Multi-model chat</h1>          <label>            Model            <select              value={model}              onChange={(event) => setModel(event.target.value)}              disabled={loading}            >              {MODEL_OPTIONS.map((option) => (                <option key={option.id} value={option.id}>                  {option.label}                </option>              ))}            </select>          </label>        </header>​        <div className="messages" aria-live="polite">          {messages.length === 0 ? (            <p className="empty">Choose a model and send a message.</p>          ) : (            messages.map((message, index) => (              <article className={message.role} key={`${message.role}-${index}`}>                <b>{message.role === "user" ? "You" : "Assistant"}</b>                <p>{message.content || "…"}</p>              </article>            ))          )}        </div>​        <form onSubmit={sendMessage}>          <textarea            value={input}            onChange={(event) => setInput(event.target.value)}            placeholder="Ask something…"            rows={3}            maxLength={20_000}          />          <button disabled={loading || !input.trim()} type="submit">            {loading ? "Streaming…" : "Send"}          </button>        </form>​        {error ? <p className="error">{error}</p> : null}      </section>    </main>  );}

app/layout.tsx

import type { Metadata } from "next";import "./globals.css";​export const metadata: Metadata = {  title: "Multi-Model Chat",  description: "A streaming Next.js chat app powered by CometAPI.",};​export default function RootLayout({  children,}: Readonly<{ children: React.ReactNode }>) {  return (    <html lang="en">      <body>{children}</body>    </html>  );}

app/globals.css

:root {  color-scheme: dark;  font-family: Arial, sans-serif;  background: #07111f;  color: #eef4ff;}* { box-sizing: border-box; }body { margin: 0; }button, select, textarea { font: inherit; }​/* Layout shell and chat card */.shell { min-height: 100vh; display: grid; place-items: center; padding: 32px 16px; }.chat { width: min(820px, 100%); background: #0d1b2e; border: 1px solid #223957; border-radius: 20px; padding: 24px; }​/* Message list and bubbles */.messages { min-height: 360px; display: grid; align-content: start; gap: 12px; margin: 24px 0; }.messages article { max-width: 85%; padding: 12px 14px; border-radius: 14px; white-space: pre-wrap; }.user { justify-self: end; background: #164f8f; }.assistant { justify-self: start; background: #182a42; }​/* Form controls, buttons, and error states follow the same dark theme. */

6-қадам: Қолданбаны іске қосу және орналастыру

npm run dev

http://localhost:3000 ашыңыз, модельді таңдаңыз және хабарлама жіберіңіз. Өндірістік Node.js орналастыруы үшін COMETAPI_API_KEY және COMETAPI_BASE_URL мәндерін хосттың серверлік орта параметрлеріне қосыңыз, содан кейін келесіні іске қосыңыз:

npm run buildnpm run start

Ағындық жауаптарды қолдайтын хостингті пайдаланыңыз. Статикалық экспорт /api/chat Route Handler-ін іске қоса алмайды.

Ағындық маршрутты тексеріңіз

Даму сервері жұмыс істеп тұрғанда, бэкендіңізді тікелей шақырыңыз:

curl -N http://localhost:3000/api/chat \  -H "Content-Type: application/json" \  -d '{    "model": "gemini-3.7-flash",    "messages": [      {"role": "user", "content": "Explain model routing in two sentences."}    ]  }'

Сәтті сұраным Server-Sent Events қайтарады. Дәл ID-лер мен мәтін өзгеруі мүмкін, бірақ ағын келесі пішінді ұстанады:

data: {"choices":[{"delta":{"content":"Model"}}]}​data: {"choices":[{"delta":{"content":" routing"}}]}​data: [DONE]

Браузердегі парсер әр SSE оқиғасын оқып, choices[0].delta.content мәнін шығарып алады және келіп түскен әр бөлшекпен көмекші хабарламасына мәтінді қосып отырады.

Тиімді біріктіру кезіндегі жиі қателер

БелгісіСебебіШешімі
401 аутентификация қатесіСерверлік кілт жоқ немесе жарамсызCOMETAPI_API_KEY орнатыңыз; оны NEXT_PUBLIC_ арқылы жария етпеңіз.
404 немесе қате маршрутБазалық URL-да /v1 жоқhttps://api.cometapi.com/v1 қолданыңыз.
400 қолдау көрсетілмейтін модельID бэкендтегі рұқсат тізімінде жоқДәл, тірі мәтіндік модель ID қолданыңыз және екі селекторды да жаңартыңыз.
Жауап бірден толық пайда боладыХост немесе прокси оқиға ағынын буферлейдіЖауап трансформациясын өшіріңіз және ағынды қолдайтын Node.js орналастыруын қолданыңыз.

Өндіріс үшін чат бэкендін дайындаңыз

  • Өз пайдаланушыларыңызды аутентификациялаңыз. Анонимді трафик үшін кредит жұмсайтын ашық маршрут ұсынбаңыз.
  • Пайдаланушы және IP бойынша rate limit қойыңыз. Бір уақытта ағындар санын, минутына сұранымдар, хабарлама саны мен ұзындығын шектеңіз.
  • Модель рұқсат тізімін сервер жақта сақтаңыз. Браузердегі селектор — ыңғайлылық үшін, қауіпсіздік шекарасы емес.
  • Орналастыру кезінде тірі каталогты тексеріңіз. GET https://api.cometapi.com/api/models сұранымын орындаңыз және конфигурацияланған ID "upcoming", қолжетімсіз немесе chat-completions endpoint-ін ұсынбайтын болса, релизді тоқтатыңыз.
  • Құнды маршрут бойынша қадағалаңыз. Таңдалған модельді, request ID-ні, кідірісті, токен қолданысын және пайдаланушы ID-ні логтаңыз. Қажет болса, CometAPI дашбордында кілт квоталары немесе шығын шектерін орнатыңыз.
  • Ажыратулар мен таймауттарды өңдеңіз. request.signal сақтаңыз, қолданбалық таймаут орнатыңыз және клиент кеткенде жұмысты тоқтатыңыз.
  • Қателерді fallback-пен жасырмаңыз. 400 және 401 жауаптарын нақты көрсетіңіз. Тек қайталануы мүмкін аздаған қателер үшін ғана және сұраным сұлбасы үйлескенде басқа модельді қолданыңыз; екі деңгейлі fallback тізбегі үшін CometAPI Model Fallback Guide құжатын қараңыз (CometAPI негізгі → CometAPI fallback моделі → ресми провайдер).
  • Журналдарды реттеңіз. API кілттері, толық prompt-тар және сезімтал модель шығыстарын өндірістік қате журналдарында сақтамаңыз.

Бір Next.js бэкенді, бірнеше модель таңдауы

Модельді ауыстыру — сервер саясатына жатады, бөлек провайдер аккаунттарына емес. Next.js Route Handler бір CometAPI кілтін құпия ұстай алады, әр сұраныммен рұқсат етілген модель ID-сін қабылдайды және таңдалған модельді OpenAI-мен үйлесімді бір endpoint арқылы ағынмен өткізеді. Фронтенд қарапайым болып қалады, ал бэкенд қолжетімділік, тексеріс, бақылау және құнды басқаруды өз қолында ұстайды. Сол аккаунт пен кілт CometAPI-дің Flux секілді кескін, Kling секілді бейне API-леріне де жетеді, сондықтан бұл чат бэкенді екінші интеграциясыз мультимодальді жұмыс ағындарына кеңейтіле алады.

Модельдерді табу үшін CometAPI public model directory каталогын және автоматтандырылған маршрутизацияны тексеру үшін GET https://api.cometapi.com/api/models endpoint-ін қолданыңыз.

Жиі қойылатын сұрақтар

Бір Next.js қолданбасында бірнеше AI моделін қолдана аламын ба?

Иә. Бір серверлік маршрутты сақтаңыз және әр сұраныммен рұқсат етілген модель ID-сін өткізіңіз. Браузер UI модель таңдауларын ұсына алады, ал сервер қай ID-лер қабылданатынын бақылайды.

GPT, Claude және Gemini арасында қалай ауысамын?

Таңдалған модель ID-сін сұраным денесіне жіберіңіз. Сервер оны рұқсат тізіміне сәйкестігіне тексереді және сол чат пэйлоадын OpenAI-мен үйлесімді endpoint арқылы таңдалған модельге форвардтайды.

CometAPI API кілтін қайда сақтау керек?

Оны COMETAPI_API_KEY сияқты серверлік орта айнымалысында сақтаңыз. Ешқашан NEXT_PUBLIC_ айнымалысы немесе клиенттік код арқылы жария етпеңіз.

OpenAI-мен үйлесімді API барлық модельдерді алмастырмалы етеді ме?

Жоқ. Сұраным пішіні портативті болғанмен, модельдер қолдау көрсетілетін параметрлер, контекст шектеулері, құрал мінез-құлқы, шығыс стилі, латенттілік және баға бойынша айырмашылықтарға ие болуы мүмкін. Рұқсат тізіміндегі әр модельді өндірістік prompt-тарыңызбен тексеріңіз.

Next.js Route Handler AI жауаптарын ағынмен бере ала ма?

Иә. Егер орналастыру платформасы және алдындағы кез келген прокси жауапты буферлемесе, Route Handler text/event-stream content type-пен жоғары жақтағы Server-Sent Events ағынын қайтара алады.

Бұл қолданбаны статикалық Next.js сайты ретінде орналастыра аламын ба?

Жоқ. Статикалық экспорт серверлік /api/chat Route Handler-ін іске қоса алмайды және API кілтін қорғай алмайды. Ағындық жауаптарды қолдайтын Node.js немесе сәйкес сервер рантаймын пайдаланыңыз.

Оқуды жалғастыру

Осы мақаланы келесі шешіммен байланыстырыңыз.

Барлық тақырыптарды көру
Жарияланды Aug 25, 2026
Соңғы жаңарту Sep 3, 2026
11 көрілім
Түсініктілік, дереккөзге сілтеме және ағымдағы API терминологиясы бойынша тексерілді.

Толығырақ оқу