- AI SDK Core ujednolica wywołania modeli, a AI SDK UI daje hooki do interfejsów czatu.
- Czat składa się z trasy serwerowej ze streamText i komponentu z useChat.
- Klucze trzymaj na serwerze, ustaw limity i dodaj obsługę błędów oraz statusu.
Jeśli piszesz w TypeScripcie i chcesz dodać do aplikacji czat z modelem, najkrótsza droga prowadzi przez gotowy zestaw narzędzi. AI SDK opisuje się jako zestaw narzędzi TypeScript do budowania aplikacji i agentów z AI w React, Next.js, Vue, Svelte, Node.js i innych środowiskach. Standaryzuje integrację modeli różnych dostawców, dzięki czemu nie trzeba pisać osobnego kodu dla każdego z nich. Dokumentacja wskazuje główne części: AI SDK Core, czyli ujednolicone API do generowania tekstu, obiektów strukturalnych, wywołań narzędzi i budowy agentów, oraz AI SDK UI, czyli niezależne od frameworka hooki do interfejsów czatu.
Dwa elementy minimalnego czatu
Czat składa się z dwóch części. Po stronie serwera jest trasa, która przyjmuje wiadomości, wywołuje model i zwraca strumień. Po stronie klienta jest komponent, który wyświetla wiadomości i wysyła nowe. Poniższe przykłady pochodzą z dokumentacji czatu w AI SDK UI z dnia sprawdzenia; API tej biblioteki zmienia się między wersjami, więc przed użyciem porównaj je z bieżącą dokumentacją.
Trasa serwerowa używa funkcji streamText, która rozpoczyna generowanie i zwraca wynik jako strumień:
import { convertToModelMessages, createUIMessageStreamResponse, streamText, toUIMessageStream, UIMessage } from 'ai';
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: "anthropic/claude-sonnet-5.5",
instructions: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages),
});
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
});
}
Komponent korzysta z hooka useChat, który według dokumentacji zarządza strumieniowaniem wiadomości, stanem pól i statusem oraz błędami:
'use client';
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
import { useState } from 'react';
export default function Page() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: '/api/chat' }),
});
const [input, setInput] = useState('');
// wyświetl messages (message.parts) i formularz wywołujący sendMessage({ text: input })
}
Dokumentacja zaleca renderowanie wiadomości przez właściwość parts, która obsługuje różne typy części: tekst, wywołanie narzędzia i jego wynik. Dzięki temu ten sam komponent rozwiniesz później o narzędzia.
Co dzieje się po drodze
- 01WpisanieUżytkownik wysyła wiadomość w formularzu.
- 02ŻądanieuseChat wywołuje trasę /api/chat.
- 03ModelstreamText rozpoczyna generowanie.
- 04StrumieńTekst wraca fragmentami.
- 05InterfejsKomponent dopisuje części wiadomości.
- 06Statussubmitted, streaming, ready lub error.
Warto zrozumieć statusy, bo od nich zależy zachowanie interfejsu. Dokumentacja wymienia między innymi stan wysłania wiadomości i stan gotowości, a w przykładzie pole wejściowe jest wyłączone, dopóki status nie jest ready. To prosty sposób na uniknięcie wysłania drugiej wiadomości w trakcie odpowiedzi.
Co dodać w następnej kolejności
Gdy podstawowy czat działa, kolejne kroki są przewidywalne. Zapisuj rozmowy w bazie, żeby użytkownik mógł do nich wrócić, i ustal, jak długo je przechowujesz. Dodaj instrukcję systemową opisującą rolę asystenta i granice jego odpowiedzi. Ogranicz długość historii wysyłanej do modelu, bo wysyłanie całej rozmowy za każdym razem podnosi koszt i opóźnienie. Dopiero potem dodaj narzędzia, wyszukiwanie w dokumentach albo generowanie danych strukturalnych. Każdy z tych elementów warto dodawać pojedynczo i sprawdzać na zestawie przykładowych rozmów, tak by wiedzieć, który zmienił zachowanie.
Pułapki i dobre praktyki
| Ryzyko | Co zrobić | |
|---|---|---|
| Klucz API | Wyciek, jeśli trafi do kodu klienta | Trzymaj go w zmiennych środowiskowych na serwerze |
| Koszt | Nadużycie endpointu i długie rozmowy | Limity żądań, długości kontekstu i wydatków |
| Błędy | Przerwany strumień, limit dostawcy | Obsłuż status błędu i pozwól ponowić |
| Treść modelu | Niezaufane dane wyświetlane w interfejsie | Escapuj i nie wykonuj wyniku jako kodu |
| Prywatność | Wrażliwe dane w rozmowach | Informuj użytkownika, co jest wysyłane |
Najważniejsza zasada to klucz API wyłącznie po stronie serwera: kod w przeglądarce widzi każdy odwiedzający. Druga to ograniczenia, bo publiczny endpoint z modelem bez limitów jest zaproszeniem do nadużyć i rachunku, który zaskoczy; o liczeniu kosztów piszę w tekście Koszt zadania w tokenach. Trzecia to traktowanie wyniku modelu jak niezaufanych danych. Narzędzia i walidacja danych wejściowych to temat kolejnego artykułu, Narzędzia i walidacja w JavaScript, a całość materiałów znajdziesz w hubie JavaScript i Vercel AI SDK.
Stan wiedzy: 20 października 2026. API biblioteki zmienia się między wersjami; kod w tym tekście odpowiada dokumentacji z tego dnia.

