Jak wdrożyć AI w produkcji z Node.js? Przewaga JavaScript nad Pythonem w świecie LLM
W świecie sztucznej inteligencji, zwłaszcza w kontekście modeli językowych (LLM), Python przez wiele lat dominował jako język programowania. Wiele kursów, tutoriali oraz przykładów kodu zakłada, że prace nad AI wykonuje się głównie w Pythonie. Jednak dla programistów osadzonych w ekosystemie JavaScript, rzeczywistość jest nieco inna. Wdrażanie AI przy użyciu Node.js oraz JavaScript nie tylko jest możliwe, ale może być wyjątkowo efektywne i korzystne. Dlaczego warto postawić na JavaScript przy pracy z AI? Oto kilka kluczowych powodów, które sprawiają, że JavaScript to świetny wybór do implementacji nowoczesnych rozwiązań opartych na sztucznej inteligencji.
Node.js – Idealne środowisko dla usług i API AI
Większość procesów związanych z AI, w tym tych opartych na dużych modelach językowych, polega na prostym schemacie: „wysyłaj zapytanie → odbieraj odpowiedź → przetwarzaj odpowiedź”. W tym kontekście Node.js okazuje się być doskonałym wyborem, zwłaszcza w sytuacjach, gdy potrzebujemy efektywnego, skalowalnego środowiska do obsługi usług API.
W przypadku Node.js, uruchomienie serwera czy wysłanie zapytania do modelu AI wymaga zaledwie kilku linijek kodu, co znacząco przyspiesza proces developmentu. Dzięki asynchronicznej naturze Node.js, mamy do czynienia z wyjątkową wydajnością, szczególnie przy zadaniach opartych na API, które mogą wymagać obsługi wielu jednoczesnych zapytań w czasie rzeczywistym. To sprawia, że Node.js jest szybkie, skalowalne i idealnie nadaje się do tworzenia aplikacji, które potrzebują natychmiastowej reakcji na zapytania użytkowników – cechy, które są kluczowe przy pracy z dużymi modelami językowymi (LLM).
Ekosystem JavaScript – Potężne narzędzie w rękach programisty AI
JavaScript to nie tylko język frontendowy, ale także potężne narzędzie do pracy z danymi w czasie rzeczywistym, do obsługi WebSocketów, integracji z popularnymi frameworkami frontendowymi jak React, Vue czy Angular oraz pracy z serwisami zewnętrznymi. Kiedy połączymy to z szeroką gamą dostępnych bibliotek i narzędzi do obsługi sztucznej inteligencji, JavaScript staje się naturalnym wyborem do budowy nowoczesnych, inteligentnych aplikacji.
W ekosystemie JavaScript znajdziemy biblioteki, które umożliwiają łatwą integrację z modelami opartymi na sztucznej inteligencji, takimi jak OpenAI, TensorFlow.js, a także Hugging Face. Tego typu narzędzia pozwalają na budowę chatów, asystentów głosowych, aplikacji rozpoznających obrazy, czy nawet na pełnoprawne systemy rekomendacyjne. W przypadku JavaScriptu, ogromną zaletą jest również możliwość natychmiastowego podglądu wyników w przeglądarkach internetowych. Dzięki temu, zarówno proces rozwoju, jak i testowania aplikacji staje się znacznie prostszy i szybszy.
Bezproblemowa integracja – JavaScript vs Python
Chociaż Python jest często wybieranym językiem w kontekście AI, w tym dużych modeli językowych (LLM), warto zauważyć, że JavaScript również doskonale sprawdza się w tej roli. Dzięki popularnym API, takim jak OpenAI, i wsparciu dla frameworków takich jak HuggingFace, integracja z tymi technologiami w JavaScript odbywa się w sposób szybki i bezproblemowy.
Node.js zapewnia programistom elastyczność w integracji z różnymi technologiami i usługami zewnętrznymi, a jego ekosystem stale rośnie, dostosowując się do potrzeb nowoczesnych aplikacji AI. W przeciwieństwie do Pythona, który mimo swojej potężnej roli w dziedzinie sztucznej inteligencji, może wymagać bardziej rozbudowanego środowiska oraz większej liczby zewnętrznych narzędzi, JavaScript ma bardzo zwartą i efektywną strukturę do integracji w różnych środowiskach.
Korzyści z używania JavaScript w pracy nad AI
- Bezproblemowa integracja z aplikacjami webowymi
Jedną z największych zalet JavaScriptu jest jego integralność z aplikacjami webowymi. Programiści mogą od razu testować i wprowadzać zmiany w interfejsie użytkownika bez potrzeby kompilowania oddzielnych plików lub przeładowywania aplikacji. To ogromne udogodnienie, które pozwala na szybkie iteracje, testowanie i doskonalenie rozwiązań AI, w tym chatbotów, asystentów głosowych, czy aplikacji do przetwarzania danych w czasie rzeczywistym.
- Łatwiejsza współpraca z zespołem frontendowym
JavaScript jest wspólnym językiem zarówno dla backendu, jak i frontendowej warstwy aplikacji. Dzięki temu, zespoły frontendowe i backendowe mogą łatwiej współpracować, dzielić kod, wspólnie debugować i rozwijać aplikację. W przypadku większych projektów opartych na AI, współpraca między tymi zespołami jest kluczowa, aby szybko reagować na potrzeby użytkowników i dostosowywać interfejsy.
- Szeroka dostępność bibliotek i narzędzi
JavaScript oferuje ogromną ilość bibliotek i narzędzi do pracy z danymi oraz AI. Dla programistów, którzy już pracują z ekosystemem JavaScript, dostępność tych narzędzi ułatwia implementację rozwiązań opartych na AI bez konieczności uczenia się nowego języka. Narzędzia takie jak TensorFlow.js, Brain.js czy Synaptic pozwalają na szybkie prototypowanie i testowanie nowych pomysłów.
- Praca z dużymi modelami językowymi (LLM)
Współczesne aplikacje AI coraz częściej korzystają z dużych modeli językowych (LLM), takich jak GPT-4 czy BERT. JavaScript wspiera te technologie poprzez proste interfejsy API, które umożliwiają integrację z modelami OpenAI, Hugging Face czy Google. Dzięki temu, implementacja takich technologii staje się dostępna nawet dla tych, którzy nie są specjalistami w dziedzinie sztucznej inteligencji, ale chcą wykorzystać AI w swoich aplikacjach.
Przykłady pracy Node.js z API modelów AI
W poniższych dwóch przykładach pokażę, jak łatwo można połączyć się za pomocą Node.js API znanych modeli: OpenAI i różnych bibliotek z HuggingFace.
Po pierwsze: należy utworzyć plik .env, w którym zapiszesz klucze do połączenia. Powinien on znajdować się w katalogu głównym projektu.
Jeśli brakuje kluczy do API OpenAI - oto dobry artykuł na Medium, który krok po kroku pokazuje proces rejestracji na platformie OpenAI i tworzenia kluczy dla API.
Po drugie: zainicjuj projekt Node.js. Można to zrobić za pomocą terminala:
npm init
Odpowiedz na kilka pytań w terminalu, a system utworzy plik package.json. W rzeczywistości, jeśli mówimy o pracy z API, wystarczy zainstalować:
- axios
- cors
- dotenv
- express
- nodemon
Aby pracować z OpenAI, należy dodatkowo dodać pakiet openai, natomiast jeśli chodzi o HuggingFace, to w poniższym przykładzie użyję również @huggingface/inference i multer.
Nie będę szczegółowo opisywał działania strony HTML i dołączonego do niej skryptu JS, ponieważ jej jedyną funkcją jest wysłanie zapytania do naszego serwera i wyrenderowanie odpowiedzi. Wystarczy do tego użyć standardowej funkcji fetch.
Integracja OpenAI z serwerem Node.js
Więc piszemy nasz serwer na Node.js. W tym celu nie zapomnijmy zainstalować wszystkich pakietów wymienionych powyżej. Następnie uruchamiamy sam serwer i czytamy zawartość pliku .env (w którym przechowywane są klucze do API) i od razu rozwyązujemy ewentualny problemem z CORS.
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const OpenAI = require('openai');
const dotenv = require('dotenv');
dotenv.config();
const app = express();
app.use(bodyParser.json());
app.use(cors());
const openai = new OpenAI({
apiKey: process.env['OPENAI_API_KEY'],
});
Wskazujemy, z którym modelem OpenAI będziemy pracować:
const MODEL = 'gpt-5-nano';
Pozostało tylko dodać przetwarzanie przychodzącego requestu i uruchomić sam serwer. Zadaniem serwera jest odbieranie polecenia (prompt) i przekazywanie go do OpenAI.
app.post('/test-server', async (req, res) => {
const userPrompt = req.body.prompt || 'Hello!';
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('Transfer-Encoding', 'chunked');
try {
const stream = await openai.chat.completions.create({
model: MODEL,
stream: true,
messages: [
{ role: 'developer', content: 'You are a helpful assistant' },
{ role: 'user', content: userPrompt },
],
});
for await (const chunk of stream) {
const content = chunk.choices?.[0]?.delta?.content;
if (content) res.write(content);
}
res.end();
} catch (error) {
console.error('Stream error:', error);
res.status(500).send('Error streaming OpenAI response');
}
});
Należy pamiętać, że w zapytaniu do OpenAI znajduje się nie tylko polecenie (userPrompt), ale także rola, w której OpenAI będzie odpowiadać (role: 'developer'). Domyślnie jest to „You are a helpful assistant” (Jesteś pomocnym asystentem). Jest to odpowiednie w większości przypadków. Jeśli jednak chcemy przyjąć inną rolę (bardziej odpowiadającą naszym celom komercyjnym), można to zmienić bez żadnych problemów.
I druga rzecz, na którą mogliście zwrócić uwagę w kodzie: używam chunk i stream. Dlaczego? Chodzi o to, że OpenAI nie odpowiada zbyt szybko (generowanie odpowiedzi może zająć nawet minutę, zwłaszcza jeśli mówimy o obszernej odpowiedzi). Jeśli będziemy po prostu czekać na odpowiedź, może się wydawać, że czekasz wiecznie, aż system odpowie (lub że aplikacja w ogóle nie działa). Biorąc pod uwagę, że modele GPT generują odpowiedzi na podstawie tokenów (nie są to dokładnie sylaby, ale coś zbliżonego), serwer przyjmuje ten token i natychmiast przekazuje go na stronę. Nie zmienia to działanie aplikacji, ale jest znacznie bardziej przyjazne dla użytkownika, ponieważ użytkownik końcowy nie patrzy na wiecznie ładujący się loader, ale widzi przyjemną animację generowania tekstu.
Właściwie to wszystko. Pozostaje tylko „słuchać” przychodzących zapytań (jeśli port jest określony w pliku .env, należy go stamtąd pobrać, a jeśli nie, należy wpisać własną wartość; w tym projekcie używam 4001.):
app.listen(process.env.PORT || 4001, () => {
console.log('run here: http://localhost:4001');
});
Następnie wystarczy wykonać standardowe "npm run start", aby serwer był gotowy do przyjmowania przychodzących żądań.
No i oczywiście, jeśli chcecie dowiedzieć się więcej, przeczytajcie dokumentację.
Generowanie grafiki za pomocą HuggingFace i serwera Node.js
Połączenie z OpenAi nie jest zbyt skomplikowane, zwłaszcza że potrzebujemy jedynie odpowiedzi tekstowej. Przejdźmy do nieco bardziej złożonego zadania – generowania obrazów, a także podłączmy nie jedną, ale kilka modeli dostępnych bezpłatnie za pośrednictwem biblioteki HuggingFace.
Pierwszą rzeczą, którą musimy zrobić, jest zarejestrowanie się w serwisie HuggingFace i utworzenie klucza (mniej więcej tak samo jak w przypadku OpenAI). Zakładka z kluczami znajduje się w sekcji Settings -> Access Tokens. Podczas tworzenia klucza wystarczy nadać uprawnienie READ.
Okej, jeśli wszystko jest gotowe, zaczynamy. Po pierwsze, szybko stwórzmy interfejs HTML.
Można napisać go według własnego uznania i pozostawić jedynie miejsce na wynik. Jednak zalecam najpierw dodać wybór modeli:
- FLUX.1-dev
- FLUX.1-schnell
- SDXL Base 1.0
- SD3 Medium
Dlaczego właśnie te modele? Wszystkie te modele są wywoływane za pośrednictwem Hugging Face Inference API (bezserwerowego) i można z nich korzystać w ramach bezpłatnego limitu.
Również polecam dodać mały fragment dotyczący wyboru parametrów. To da trochę więcej elastyczności podczas pracy z obrazami.
- Wybór liczby kroków (liczba od 10 do 60, domyślnie 30)
- Classifier-Free Guidance (CFG) scale, czyli parametr w generatorach obrazów AI, który kontroluje, jak dokładnie wygenerowany obraz jest zgodny z podpowiedzią tekstową (liczba od 0 do 15, domyślnie 3.5).
Dla sekcji z wynikiem wystarczy zwykły div.
Wynik będzie wyglądał mniej więcej tak:

Jeśli chodzi o skrypty, ich zadaniem jest pobranie wszystkich naszych parametrów i wysłanie ich na serwer, a także ewentualna obsługa błędów (tutaj są one znacznie bardziej prawdopodobne, choćby dlatego, że może się skończyć darmowy limit HuggingFace). Podobnie jak w przypadku OpenAI, wystarczy użyć zwykłego fetch.
Przejdźmy do serwera. Najpierw zbieramy sam serwer (i importujemy port, jeśli jest określony w .env) i podłączamy klucze HuggingFace, nie zapominając, że należy zaimportować samą bibliotekę HuggingFace.
import express from "express";
import cors from "cors";
import "dotenv/config";
import { InferenceClient } from "@huggingface/inference";
const app = express();
const port = process.env.PORT || 3000;
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static("public"));
const HF_TOKEN = process.env.HF_ACCESS_TOKEN;
const hf = HF_TOKEN ? new InferenceClient(HF_TOKEN) : null;
Następnie dodajemy wybór modelu, jeśli został on dodany na stronie:
const MODELS = {
"flux-dev": {
label: "FLUX.1-dev",
provider: "hf-inference",
hfModelId: "black-forest-labs/FLUX.1-dev",
defaultSteps: 30,
defaultGuidance: 3.5
},
"flux-schnell": {
label: "FLUX.1-schnell",
provider: "hf-inference",
hfModelId: "black-forest-labs/FLUX.1-schnell",
defaultSteps: 18,
defaultGuidance: 3.0
},
"sdxl-base": {
label: "SDXL Base 1.0",
provider: "hf-inference",
hfModelId: "stabilityai/stable-diffusion-xl-base-1.0",
defaultSteps: 28,
defaultGuidance: 7.0
},
"sd3-medium": {
label: "Stable Diffusion 3 Medium",
provider: "hf-inference",
hfModelId: "stabilityai/stable-diffusion-3-medium-diffusers",
defaultSteps: 28,
defaultGuidance: 7.0
}
};
Właściwie zbieramy dane z naszego interfejsu i wysyłamy je do HuggingFace. Ważne - coś może się zepsuć na każdym kroku, dlatego należy się zabezpieczyć i dodać domyślne stany, a także wyświetlać błędy w konsoli, aby zrozumieć, na jakim etapie coś poszło nie tak.
app.post("/api/generate", async (req, res) => {
try {
if (!HF_TOKEN || !hf) {
return res.status(500).json({
error: "HF_ACCESS_TOKEN не настроен на сервере"
});
}
const prompt = (req.body.prompt || "").trim();
const modelKey = (req.body.model || "flux-dev").trim();
const modelConfig = MODELS[modelKey] || MODELS["flux-dev"];
const steps =
req.body.steps !== undefined
? Number(req.body.steps)
: modelConfig.defaultSteps;
const guidance =
req.body.guidance !== undefined
? Number(req.body.guidance)
: modelConfig.defaultGuidance;
if (!prompt) {
return res.status(400).json({ error: "No prompt" });
}
console.log(
`text-to-image: model=${modelConfig.hfModelId}, provider=${modelConfig.provider}, steps=${steps}, guidance=${guidance}`
);
const resultBlob = await hf.textToImage({
provider: modelConfig.provider,
model: modelConfig.hfModelId,
inputs: prompt,
parameters: {
num_inference_steps: steps,
guidance_scale: guidance,
width: 1024,
height: 1024
}
});
const arrayBuffer = await resultBlob.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
res.set("Content-Type", resultBlob.type || "image/png");
res.send(buffer);
} catch (err) {
console.error("Generation error:", err);
res.status(500).json({
error: "Generation Error",
details: err?.message || String(err)
});
}
});
Właściwie to wszystko. Słuchamy serwera na wskazanym porcie.
app.listen(port, () => {
console.log(`Multi-model server is here: http://localhost:${port}`);
});
I uruchamiamy przez npm run start.
Zobaczmy, czy to działa. Poprosimy model o wygenerowanie uroczego kotka, który patrzy przez okno na zaśnieżoną ulicę.

Nie wiem jak uwazacie, ale moim zdaniem wyszło bardzo ładnie.
JavaScript i Node.js – Doskonały wybór do pracy z AI
JavaScript i Node.js to świetny wybór do pracy z AI, zwłaszcza jeśli zależy Ci na efektywności, integracji z aplikacjami webowymi i łatwej współpracy z zespołem frontendowym. Dzięki asynchronicznej naturze Node.js, programiści mogą szybko implementować i testować rozwiązania AI, zachowując dużą skalowalność aplikacji. Jeśli poszukujesz prostego, elastycznego i wydajnego rozwiązania do wdrażania modeli AI w produkcji, JavaScript będzie doskonałym wyborem. Nie musisz rezygnować z nowoczesnych rozwiązań AI, aby pozostać w ekosystemie JavaScript. Jeśli chcesz zgłębić temat jeszcze bardziej i odkryć, jak rozpocząć pracę z AI w Node.js, zapraszam do śledzenia mojego #AIEngineerJourney.
