Wstęp
Z końcem roku pojawił się polski model SLM Bielik w wersji trzeciej, mający wsparcie dla tools, czyli narzędzi z których modele mogą korzystać. Moje krótki testy wykazały, że można bez problemu korzystać z niego za pomocą LM studio, w Ollama niestety trzeba parsować odpowiedzi ręcznie, co w przypadku planu nauki i używania frameworków (LangChain) do AI mija się troszkę z celem. Link do wątku na LinkedIn: https://www.linkedin.com
Projekt
Pomyślałem, jak go przetestować w jakimś real Case, i wpadłem na pomysł, asystenta do Wordpresa. W sumie, to można by potraktować Wordpresa jako bazę wiedzy dla bielika, oczywiście to w formie zabawy. A, że jestem w trakcie nauki TypeScripta, i wdrożenia się w to środowisko, pomyślałem, ze stworzę taki tutorial, korzystając oczywiście z innych źródeł wiedzy i ucząc się równocześnie.
Użyte technologie
Node.js i TypeScript
Node.js to środowisko uruchomieniowe JavaScript, które pozwala na wykonywanie kodu JavaScript poza przeglądarką. Używamy wersji 18 lub nowszej.
TypeScript to nadzbiór JavaScript dodający statyczne typowanie, co zwiększa bezpieczeństwo kodu i ułatwia jego utrzymanie. Kompilator TypeScript sprawdza typy podczas pisania kodu, co pozwala wychwycić błędy przed uruchomieniem aplikacji.
Bielik 11B v3.0 Instruct
Polski model językowy stworzony przez SpeakLeash i ACK Cyfronet AGH. Model wspiera 32 języki europejskie, z optymalizacją dla języka polskiego. Dostępny w różnych wersjach kwantyzacji:
- Q5_K_M – mniejszy rozmiar (około 7.5 GB), szybsze działanie, dobra jakość
- Q8_0 – większy rozmiar (około 11 GB), wyższa dokładność odpowiedzi
Model obsługuje wywołania narzędzi (function calling), co pozwala mu na wykonywanie konkretnych akcji zamiast tylko generowania tekstu.
LM Studio
Aplikacja desktopowa umożliwiająca uruchamianie modeli LLM lokalnie na własnym komputerze. Kluczowe cechy:
- Udostępnia API kompatybilne z OpenAI (endpoint: http://127.0.0.1:1234/v1)
- Obsługuje modele w formacie GGUF
- Pozwala na kontrolę parametrów generowania (temperatura, top-p, itp.)
- Działa offline – wszystko przetwarzane lokalnie
LangChain.js
Framework JavaScript/TypeScript i Pythona do budowania aplikacji wykorzystujących modele językowe. Oferuje:
- Abstrakcję dla różnych dostawców LLM (OpenAI, Anthropic, lokalne modele)
- Wsparcie dla narzędzi (tools) – definiowanie funkcji które model może wywoływać
- Zarządzanie promptami i historią konwersacji
- Integrację z różnymi źródłami danych
W naszym projekcie używamy LangChain do komunikacji z LM Studio i definiowania narzędzi WordPress.
Aplikacja działająca w konsoli, pozwalająca pytać o dane w wordpresie w języku naturalnym oraz dodawać posty.
Ważna uwaga, ja pracuję na Windows, więc, jeśli korzystasz z innego systemu, może to wyglądać (a nawet musi) inaczej.
Część 1: Przygotowanie projektu
Po Pierwsze, jeśli nie masz, to pobierz i zainstaluj NODE.JS: Node.js — Run JavaScript Everywhere
Po drugie, jeśli nie masz pobierz i zainstaluj VS Code (Albo użyj innego dowolnego edytora): Visual Studio Code – The open source AI code editor
Tworzymy nowy katalog i inicjalizujemy projekt Node.js:
konsola
mkdir bielik-wp
cd wp-ai-assistant
npm init -yCo to robi?
mkdir– tworzy nowy katalog (folder) użyj taką nazwę jaka jest dla ciebie wygodna.cd– wchodzi do katalogunpm init -y– tworzy plikpackage.jsonz domyślnymi ustawieniami
package.json to plik konfiguracyjny, który zawiera informacje o projekcie i listę bibliotek (zależności), których używamy.

Edytuj go, i w scripts dodaj „start”: „tsx src/index.ts”,

Instalacja bibliotek
konsola
npm install @langchain/openai @langchain/core langchain axios dotenv zod
npm install -D typescript @types/node tsxWyjaśnienie bibliotek:
Biblioteki główne (dependencies):
@langchain/openai– łączy się z LM Studio (serwer AI)@langchain/core– podstawowe narzędzia LangChainlangchain– główna biblioteka do pracy z AIaxios– wysyła zapytania HTTP do WordPressdotenv– wczytuje zmienne z pliku .env (hasła, adresy)zod– sprawdza poprawność danych (walidacja)
Biblioteki deweloperskie (-D):
typescript– kompilator TypeScript@types/node– definicje typów dla Node.jstsx– uruchamia pliki TypeScript bez kompilacji
W tej chwili nasz folder będzie wyglądał tak:

Konfiguracja TypeScript
Tworzymy plik tsconfig.json:
{
"compilerOptions": {
"target": "ES2020", // Wersja JavaScript na wyjściu
"module": "CommonJS", // System modułów (require/exports)
"strict": true, // Ścisłe sprawdzanie typów
"esModuleInterop": true, // Kompatybilność z różnymi modułami
"skipLibCheck": true, // Pomija sprawdzanie bibliotek
"forceConsistentCasingInFileNames": true, // Wymusza spójność nazw
"outDir": "./dist" // Katalog dla skompilowanych plików
},
"include": ["src/**/*"] // Które pliki kompilować
}WordPress i dane dostępowe – Zmienne środowiskowe
Dla celów tego tutoriala utworzyłem w dhosting.pl którego używam nową instalację wordpresa.
Tworzymy plik .env z danymi dostępowymi:
WP_API_URL=https://twoja-domena.pl/wp-json/wp/v2
WP_USER=twoja-nazwa-uzytkownika
WP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxxCzęść 2: Moduł WordPress (wordpress.ts)
Tworzymy katalog src i plik src/wordpress.ts. Ten plik zawiera funkcje do komunikacji z WordPress.

Krok po kroku wpisujemy kod, i tłumaczę od razu co jest co.
import axios from 'axios';
import * as dotenv from 'dotenv';
dotenv.config();Importujemy bibliotekę axios, która pozwala wysyłać zapytania HTTP do WordPress API. To jak przeglądarka, ale w kodzie. W Pythonie użył bym modułu requests.
Oraz ładujemy zmienne środowiskowe z pliku .env
Konfiguracja klienta HTTP
const client = axios.create({
baseURL: process.env.WP_API_URL,
auth: {
username: process.env.WP_USER,
password: process.env.WP_PASSWORD
}
});Wyjaśnienie linia po linii:
const client = axios.create({...})
Tworzymy „klienta” HTTP czyli obiekt, który będzie wysyłał zapytania do WordPress.
baseURL: process.env.WP_API_URL
Ustawiamy bazowy adres API. process.env to obiekt zawierający zmienne z pliku .env.
auth: { username: ..., password: ... }
Konfigurujemy uwierzytelnienie. Każde zapytanie będzie automatycznie zawierać te dane.
Definicja interfejsu
interface WPPost {
id: number;
title: { rendered: string };
link: string;
date: string;
}Czym jest interface?
Interface to definicja opisująca kształt obiektu. Mówi TypeScript: „obiekt WPPost musi mieć te pola z tymi typami”.
Jeśli używałeś Pythona i Pydentic, to wyda się znajome, prawda? 🙂
Przykład:id: number – pole „id” musi być liczbątitle: { rendered: string } – pole „title” to obiekt z polem „rendered” typu string
Dzięki temu TypeScript ostrzeże nas, jeśli spróbujemy użyć pola, którego nie ma.
Funkcja: createPost
export async function createPost(
title: string,
content: string,
status: 'publish' | 'draft' = 'draft'
) {
try {
const response = await client.post('/posts', {
title,
content,
status
});
return `Utworzono post: ${response.data.link} (ID: ${response.data.id})`;
} catch (error: any) {
return `Błąd podczas tworzenia wpisu: ${error.message}`;
}
}Wyjaśnienie szczegółowe:
export async function createPost(...)
– export – funkcja będzie dostępna w innych plikach
– async – funkcja asynchroniczna (może czekać na operacje)
– function createPost – nazwa funkcji
Parametry funkcji:title: string – tytuł wpisu (musi być tekstem)content: string – treść wpisu (też musi być tekstem)status: 'publish' | 'draft' = 'draft' – status wpisu:
– może być tylko „publish” lub „draft” (union type)
– domyślna wartość to „draft” (jeśli nie podamy)
try { ... } catch (error) { ... }
Blok try-catch łapie błędy. Jeśli coś pójdzie nie tak w try, wykonuje się catch.
const response = await client.post('/posts', {...})
– await – czeka na zakończenie operacji
– client.post – wysyła zapytanie POST czyli wysyła paczkę danych, w pythonie był by requests.post
– '/posts' – endpoint API (doda się do baseURL)
– {title, content, status} – dane wysyłane do API
return Utworzono post: ${response.data.link}...pozwala wstawiać w JS/TS zmienne:
Template string (backticki) ${zmienna} tak jak w pythonie byśmy uzyli f”zmienna: {zmienna}”
Funkcja: getRecentPosts
export async function getRecentPosts(count: number = 5) {
try {
const response = await client.get<WPPost[]>('/posts', {
params: { per_page: count }
});
if (response.data.length === 0) {
return "Nie znaleziono żadnych wpisów.";
}
return response.data.map(post =>
`- [${post.id}] ${post.title.rendered} (${post.date})`
).join('\n');
} catch (error: any) {
return `Błąd pobierania wpisów: ${error.message}`;
}
}Nowe elementy:
count: number = 5
Parametr z wartością domyślną. Jeśli nie podamy, będzie 5.
client.get<WPPost[]>('/posts', {...})
– get – zapytanie GET (pobiera dane)
– <WPPost[]> – typ generyczny: spodziewamy się tablicy WPPost czyli inaczej zmiennej zawierającej wiele interfejsów które wcześniej zadeklarowaliśmy. W pythonie była by to lista słowników albo obiektów Pydantic.
– params: { per_page: count } – parametry URL (?per_page=5)
if (response.data.length === 0)
Sprawdzamy czy tablica jest pusta. === to ścisłe porównanie. W TS 2 == „2” da true a 2 === „2” false.
response.data.map(post => ...)
– map – przekształca każdy element tablicy
– post => ... – funkcja strzałkowa (arrow function)
– Dla każdego wpisu tworzymy string z jego danymi
.join('\n')
Łączy elementy tablicy w jeden string, oddzielając znakiem nowej linii.
Metoda map – przykład:
const numbers = [1, 2, 3]; const doubled = numbers.map(n => n * 2); // Wynik: [2, 4, 6]
W naszym przypadku:
const posts = [{id: 1, title: "A"}, {id: 2, title: "B"}];
const formatted = posts.map(post => `- [${post.id}] ${post.title}`);
// Wynik: ["- [1] A", "- [2] B"]
Funkcja: searchPosts
export async function searchPosts(term: string) {
try {
const response = await client.get<WPPost[]>('/posts', {
params: { search: term }
});
if (response.data.length === 0) {
return `Nie znaleziono wpisów dla frazy "${term}".`;
}
return response.data.map(post =>
`- [${post.id}] ${post.title.rendered}: ${post.link}`
).join('\n');
} catch (error: any) {
return `Błąd wyszukiwania: ${error.message}`;
}
}Podobna do getRecentPosts, ale:
– Używa parametru search: term zamiast per_page
– WordPress API wyszuka wpisy zawierające frazę w zmiennej term
– Wyświetla link do wpisu zamiast daty
Część 3: Główna aplikacja (index.ts)
Tworzymy plik src/index.ts – serce naszej aplikacji.
Importy
import { ChatOpenAI } from '@langchain/openai';
import { DynamicStructuredTool } from '@langchain/core/tools';
import { z } from 'zod';
import * as dotenv from 'dotenv';
import { createPost, getRecentPosts, searchPosts } from './wordpress';Co importujemy:
ChatOpenAI– klasa do komunikacji z modelem AIDynamicStructuredTool– klasa do definiowania narzędziz– biblioteka Zod do walidacji danychdotenv– wczytuje zmienne z .env{createPost, ...}– nasze funkcje WordPress
import * as dotenv – importuje wszystko jako obiekt „dotenv”from './wordpress' – z naszego pliku (kropka = bieżący katalog)
Wczytanie zmiennych środowiskowych
dotenv.config();Ta linia wczytuje zmienne z pliku .env do process.env. Musi być na początku, zanim użyjemy zmiennych.
Konfiguracja modelu AI
const model = new ChatOpenAI({
modelName: 'bielik-11b-v3.0-instruct@q5_k_m',
apiKey: 'lm-studio',
configuration: {
baseURL: 'http://127.0.0.1:1234/v1',
},
temperature: 0.1,
});Tworzymy instancję modelu AI:
new ChatOpenAI({...})
Tworzymy nowy obiekt klasy ChatOpenAI. new to słowo kluczowe do tworzenia obiektów.
Parametry konfiguracji:modelName – nazwa modelu w LM StudioapiKey – klucz API (LM Studio nie wymaga prawdziwego)baseURL – adres serwera LM Studiotemperature: 0.1 – „kreatywność” modelu (0 = deterministyczny, 1 = losowy)
Czym jest klasa i instancja?
Klasa to „przepis” na obiekt (jak przepis na ciasto).
Instancja to konkretny obiekt stworzony z klasy (jak upieczone ciasto).
ChatOpenAI – klasa (przepis)new ChatOpenAI({...}) – tworzymy instancję (pieczemy ciasto)model – zmienna przechowująca naszą instancję
Definicja narzędzi
const tools = [
new DynamicStructuredTool({
name: 'get_recent_posts',
description: 'Pobiera listę ostatnich wpisów z bloga WordPress',
schema: z.object({
count: z.number().optional().describe('Liczba wpisów do pobrania (domyślnie 5)'),
}),
func: async ({ count }) => {
return await getRecentPosts(count);
},
}),Co to są narzędzia (tools)?
Narzędzia to funkcje, które model AI może wywoływać. Model „decyduje” kiedy użyć narzędzia na podstawie zapytania użytkownika.
Struktura narzędzia:
name: 'get_recent_posts'
Unikalna nazwa narzędzia. Model używa jej do identyfikacji.
description: '...'
Opis co robi narzędzie. To instrukcja dla modelu AI, model czyta to i decyduje czy użyć tego narzędzia.
schema: z.object({...})
Schemat parametrów używając biblioteki Zod:
– z.object – obiekt z polami
– count: z.number() – pole „count” musi być liczbą
– .optional() – pole jest opcjonalne
– .describe('...') – opis dla modelu AI
func: async ({ count }) => {...}
Funkcja wykonywana gdy model wywoła narzędzie:
– { count } – destrukturyzacja: wyciągamy pole „count” z parametrów
– await getRecentPosts(count) – wywołujemy naszą funkcję z pliku WordPress
Definicja narzędzi – Część 2 i 3
new DynamicStructuredTool({
name: 'search_posts',
description: 'Wyszukuje wpisy na blogu WordPress po słowie kluczowym',
schema: z.object({
term: z.string().describe('Szukana fraza lub słowo kluczowe'),
}),
func: async ({ term }) => {
return await searchPosts(term);
},
}),
new DynamicStructuredTool({
name: 'create_post',
description: 'Tworzy nowy wpis na blogu WordPress',
schema: z.object({
title: z.string().describe('Tytuł wpisu'),
content: z.string().describe('Treść wpisu w formacie HTML lub tekstowym'),
status: z.enum(['publish', 'draft']).optional()
.describe('Status wpisu: publish (opublikowany) lub draft (szkic). Domyślnie draft.'),
}),
func: async ({ title, content, status }) => {
return await createPost(title, content, status);
},
}),
];Narzędzie search_posts:
– Parametr: term: z.string() – tekst do wyszukania
– Wywołuje funkcję searchPosts(term)
Narzędzie create_post:
– Trzy parametry: title, content, status
– z.enum(['publish', 'draft']) – tylko te dwie wartości
– Destrukturyzacja trzech pól: { title, content, status }
Czyli jak widzisz, listę narzędzie dla modelu definiujemy jako tablicę metod.
Mapa funkcji – KLUCZOWE!
const toolFunctions: Record<string, Function> = {
get_recent_posts: getRecentPosts,
search_posts: searchPosts,
create_post: createPost,
};Dlaczego to jest potrzebne?
W moich testach Model Bielik zwraca nazwę narzędzia jako string (np. „get_recent_posts”).
Musimy przekształcić ten string na prawdziwą funkcję i ją wywołać.
Ta mapa pozwala nam zrobić: toolFunctions['get_recent_posts'] – funkcja getRecentPosts
Record<string, Function> – typ TypeScript: obiekt gdzie klucze to stringi, wartości to funkcje.
Funkcja główna – Część 1
async function main() {
const prompt = process.argv[2];
if (!prompt) {
console.error('Proszę podać prompt jako argument!');
console.log('Przykład: npm start "Znajdź wpisy o AI"');
process.exit(1);
}
console.log(`Przetwarzam zapytanie: "${prompt}"...\n`);Wyjaśnienie:
async function main()
Główna funkcja aplikacji. Asynchroniczna, bo będzie czekać na AI.
const prompt = process.argv[2]process.argv to tablica argumentów z linii komend:
– [0] – ścieżka do node
– [1] – ścieżka do skryptu
– [2] – pierwszy argument użytkownika
Przykład: npm start "Pokaż wpisy"process.argv[2] = „Pokaż wpisy”
if (!prompt)
Sprawdzamy czy użytkownik podał argument. ! to negacja (nie).
process.exit(1)
Kończy program z kodem błędu 1 (0 = sukces, inne = błąd).
Funkcja główna – Część 2
try {
const modelWithTools = model.bindTools(tools);
const result = await modelWithTools.invoke([
{
role: 'system',
content: `Jesteś pomocnym asystentem WordPress.
Twoim zadaniem jest zarządzanie blogiem użytkownika.
Możesz tworzyć wpisy, szukać ich i listować.
Zawsze odpowiadaj po polsku.
Jeśli wykonujesz akcję, potwierdź co zrobiłeś.`,
},
{
role: 'user',
content: prompt,
},
]);Wyjaśnienie krok po kroku:
try { ... }
Blok try-catch łapie błędy podczas wykonywania.
const modelWithTools = model.bindTools(tools)
„Podpinamy” narzędzia do modelu. Model teraz wie, że może je wywoływać.
const result = await modelWithTools.invoke([...])
Wywołujemy model z tablicą wiadomości:
Wiadomość systemowa (role: 'system’):
Instrukcje dla modelu. Definiują jego zachowanie i osobowość.
Model czyta to przed przetworzeniem zapytania użytkownika.
Wiadomość użytkownika (role: 'user’):
Zapytanie/polecenie od użytkownika (nasze prompt).
Jak działa konwersacja z AI?
AI otrzymuje tablicę wiadomości z różnymi rolami:
system– instrukcje systemowe (jak ma się zachowywać)user– wiadomości użytkownikaassistant– poprzednie odpowiedzi AI (w historii)
Model przetwarza całą historię i generuje odpowiedź.
Funkcja główna – Część 3
⚠️ BEZ TEGO KODU APLIKACJA NIE BĘDZIE DZIAŁAĆ!
Model Bielik generuje tool_calls, ale LangChain nie wykonywał ich automatycznie.
Musimy ręcznie sprawdzić czy są tool_calls i wykonać prawdziwe funkcje.
// Sprawdzamy czy model chce użyć narzędzia
if (result.tool_calls && result.tool_calls.length > 0) {
console.log('Wykryto wywołanie narzędzia, wykonuję...\n');
const toolCall = result.tool_calls[0];
const toolName = toolCall.name;
const toolArgs = toolCall.args;
console.log(`Narzędzie: ${toolName}`);
console.log(`Parametry:`, toolArgs);
// Wykonaj prawdziwe narzędzie WordPress
const toolFunction = toolFunctions[toolName];
if (toolFunction) {
const toolResult = await toolFunction(...Object.values(toolArgs));
console.log('\nWynik z WordPress:');
console.log(toolResult);
// Wygeneruj finalną odpowiedź na podstawie prawdziwego wyniku
const finalResult = await model.invoke([
{
role: 'system',
content: 'Jesteś pomocnym asystentem WordPress. Odpowiadaj po polsku.',
},
{
role: 'user',
content: `Użytkownik zapytał: "${prompt}"
Wykonałeś narzędzie ${toolName} i otrzymałeś wynik:
${toolResult}
Podaj użytkownikowi przyjazną odpowiedź na podstawie tego wyniku.`,
},
]);
console.log('\nOdpowiedź AI:');
console.log(finalResult.content);
} else {
console.log('Nie znaleziono funkcji dla narzędzia:', toolName);
}
} else {
// Jeśli nie było wywołań narzędzi, zwróć normalną odpowiedź
console.log('\nOdpowiedź AI:');
console.log(result.content);
}Krok po kroku co się dzieje:
1. if (result.tool_calls && result.tool_calls.length > 0)
Sprawdzamy czy model zwrócił jakieś wywołania narzędzi
2. const toolCall = result.tool_calls[0]
Bierzemy pierwsze wywołanie (dla uproszczenia obsługujemy jedno)
3. const toolName = toolCall.name
Nazwa narzędzia, np. „get_recent_posts”
4. const toolArgs = toolCall.args
Parametry, np. {count: 5}
5. const toolFunction = toolFunctions[toolName]
Znajdujemy funkcję w naszej mapie
6. await toolFunction(...Object.values(toolArgs))
Wykonujemy prawdziwą funkcję WordPress:
– Object.values(toolArgs) -> wyciąga wartości z obiektu do tablicy
– ... (spread) -> rozpakuje tablicę na argumenty
– Przykład: {count: 5} -> [5] -> getRecentPosts(5)
7. Drugie wywołanie modelu
Wysyłamy do modelu prawdziwy wynik z WordPress
Model generuje przyjazną odpowiedź dla użytkownika
Dlaczego dwa wywołania?
– Pierwsze: Model decyduje KTÓRE narzędzie użyć
– My: Wykonujemy PRAWDZIWE narzędzie
– Drugie: Model tworzy PRZYJAZNĄ odpowiedź z prawdziwych danych
Obsługa błędów i uruchomienie
} catch (error) {
console.error('Wystąpił błąd:', error);
}
}
main();catch (error) – jeśli coś pójdzie nie tak w try, wyświetl błąd
main(); – wywołujemy funkcję główną, startujemy aplikację
TESTY wersji pierwszej, z wywołaniem jednorazowym, w części drugiej zrobimy chata w konsoli a w trzeciej webową aplikację.
uruchamiamy program, i w parametrze przekazuje pytanie do modelu
npm start "Pokaż ostatnie wpisy" Widać wywołanie tools przez model:
Przetwarzam zapytanie: "Pokaż ostatnie wpisy"...
Wykryto wywołanie narzędzia, wykonuję...
Narzędzie: get_recent_posts
Parametry: { count: 5 }
Wynik z WordPress:
- [1346] Programowanie od zera: Lekcja 5: Program zyskuje pamięć trwałą (Pliki, JSON i Typy Danych) (2026-01-03T21:46:26)
- [1308] SQL od Zera, cz. 13: Podróże w czasie czyli analiza trendów za pomocą LAG i LEAD (2025-12-21T23:02:39)
- [1302] Garść info: kursy programowania i SQL, moja aplikacja niedługo dostępna, uczę się TypeScripta (2025-12-19T23:25:05)
- [1289] Kurs programowania od zera, lekcja: 4B: C# Dogania Pythona (Klasy, Obiekty i Listy Rekordów) (2025-12-14T22:13:05)
- [1279] SQL od Zera, cz. 12: Świat funkcji okien na grubo – suma i średnia krocząca (2025-12-12T22:47:50)Wynik z wordpresa trafia do modelu, a model zwraca odpowiedź wykorzystując ten kontekst:
Odpowiedź AI:
Oto najnowsze wpisy z bloga, które mogą Cię zainteresować:
1. **Programowanie od zera: Lekcja 5: Program zyskuje pamięć trwałą (Pliki, JSON i Typy Danych)**
Data publikacji: 3 stycznia 2026 r.
W tej lekcji dowiesz się, jak przechowywać dane w plikach oraz pracować z formatem JSON i typami danych.
2. **SQL od Zera, cz. 13: Podróże w czasie czyli analiza trendów za pomocą LAG i LEAD**
Data publikacji: 21 grudnia 2025 r.
Naucz się korzystać z funkcji `LAG` i `LEAD`, aby analizować dane w czasie, np. trendy sprzedaży lub zmiany cen.
3. **Garść info: kursy programowania i SQL, moja aplikacja niedługo dostępna, uczę się TypeScripta**
Data publikacji: 19 grudnia 2025 r.
Aktualizacja na temat nowych kursów online oraz postępów w rozwoju aplikacji do nauki programowania i SQL.
4. **Kurs programowania od zera, lekcja: 4B: C# Dogania Pythona (Klasy, Obiekty i Listy Rekordów)**
Data publikacji: 14 grudnia 2025 r.
Porównanie języków Python i C# w kontekście programowania obiektowego oraz tworzenia klas i list rekordów.
5. **SQL od Zera, cz. 12: Świat funkcji okien na grubo — suma i średnia krocząca**
Data publikacji: 12 grudnia 2025 r.
Praktyczne zastosowanie funkcji okien (window functions) do obliczania sumy i średniej kroczącej w bazach danych.
Mam nadzieję, że znajdziesz coś dla siebie!i Całość poniżej
PS E:\projekty\kurs JS TS\bielik-wp> npm start "Pokaż ostatnie wpisy"
> bielik-wp@1.0.0 start
> tsx src/index.ts Pokaż ostatnie wpisy
[dotenv@17.2.3] injecting env (3) from .env -- tip: ⚙️ write to custom object with { pprocessEnv: myObject }
[dotenv@17.2.3] injecting env (0) from .env -- tip: ⚙️ write to custom object with { pprocessEnv: myObject }
Przetwarzam zapytanie: "Pokaż ostatnie wpisy"...
Wykryto wywołanie narzędzia, wykonuję...
Narzędzie: get_recent_posts
Parametry: { count: 5 }
Wynik z WordPress:
- [1346] Programowanie od zera: Lekcja 5: Program zyskuje pamięć trwałą (Pliki, JSON i Typy Danych) (2026-01-03T21:46:26)
- [1308] SQL od Zera, cz. 13: Podróże w czasie czyli analiza trendów za pomocą LAG i LEAD (2025-12-21T23:02:39)
- [1302] Garść info: kursy programowania i SQL, moja aplikacja niedługo dostępna, uczę się TypeScripta (2025-12-19T23:25:05)
- [1289] Kurs programowania od zera, lekcja: 4B: C# Dogania Pythona (Klasy, Obiekty i Listy Rekordów) (2025-12-14T22:13:05)
- [1279] SQL od Zera, cz. 12: Świat funkcji okien na grubo – suma i średnia krocząca (2025-12-12T22:47:50)
Odpowiedź AI:
Oto najnowsze wpisy z bloga, które mogą Cię zainteresować:
1. **Programowanie od zera: Lekcja 5: Program zyskuje pamięć trwałą (Pliki, JSON i Typy Danych)**
Data publikacji: 3 stycznia 2026 r.
W tej lekcji dowiesz się, jak przechowywać dane w plikach oraz pracować z formatem JSON i typami danych.
2. **SQL od Zera, cz. 13: Podróże w czasie czyli analiza trendów za pomocą LAG i LEAD**
Data publikacji: 21 grudnia 2025 r.
Naucz się korzystać z funkcji `LAG` i `LEAD`, aby analizować dane w czasie, np. trendy sprzedaży lub zmiany cen.
3. **Garść info: kursy programowania i SQL, moja aplikacja niedługo dostępna, uczę się TypeScripta**
Data publikacji: 19 grudnia 2025 r.
Aktualizacja na temat nowych kursów online oraz postępów w rozwoju aplikacji do nauki programowania i SQL.
4. **Kurs programowania od zera, lekcja: 4B: C# Dogania Pythona (Klasy, Obiekty i Listy Rekordów)**
Data publikacji: 14 grudnia 2025 r.
Porównanie języków Python i C# w kontekście programowania obiektowego oraz tworzenia klas i list rekordów.
5. **SQL od Zera, cz. 12: Świat funkcji okien na grubo — suma i średnia krocząca**
Data publikacji: 12 grudnia 2025 r.
Praktyczne zastosowanie funkcji okien (window functions) do obliczania sumy i średniej kroczącej w bazach danych.
Mam nadzieję, że znajdziesz coś dla siebie!
PS E:\projekty\kurs JS TS\bielik-wp>WSZYSTKO DZIAŁA!
Zachęcam do eksperymentów

0 komentarzy