P R O J E K T YK O N T A K T

[07]

GENERATOR ARTYKUŁÓW AI

TIER A · ROK 2026 · STATUS: DZIAŁA · JĘZYKI: TYPESCRIPT

Prompt jako produkt: twarde progi treści, grounding i eksport DOCX

[FIG. 1] MISJA

Projektuję prompt jako produkt: jeden parametryzowany kontrakt zamiast frameworka. Tak działa mój generator długich artykułów SEO, który z briefu (temat, słowa kluczowe, grupa docelowa, długość w stronach) robi gotowy, mięsisty tekst po polsku — ręczne pisanie takich tekstów jest wolne i stylistycznie niespójne, a prompt potrafi tę pracę ustandaryzować. Wymaganie biznesowe przekładam na twardy próg maszynowy: długość w stronach przeliczam na liczbę słów (~550 na stronę) i wymuszam minimalną liczbę sekcji H2/H3, a model kopiuje ton wklejonego tekstu wzorcowego. Grounding jest warunkowy: treść osadza się w faktach z podanych linków, a lista źródeł wraca sparsowana z metadanych odpowiedzi. W jednym produkcie składam dwie pętle modelu — generację i edycję przez rozmowę: poprawki idą przez function calling (update_article_content zwraca pełną nową treść plus streszczenie zmian), nie przez regenerację od zera ani ręczną przeróbkę. Wynik domykam eksportem do formatu, którego oczekuje odbiorca: DOCX budowany przez własne metatagi formatowania, z optymalizacją pod SGE/AI Search. React + Vite, deploy na Vercelu — narzędzie realnie używane do treści.

[FIG. 2] ARCHITEKTURA

najedź na blok, by zobaczyć opis

[FIG. 3] WYZWANIA

[+][CH-01]

LLM z natury streszcza: poproszony o 5 stron oddaje 2 i uważa, że wyświadczył przysługę. Prośby „napisz długo” nie działały — zadziałało dopiero przeliczenie stron na twardy próg słów (strony × ~550), wymuszona minimalna liczba sekcji H2/H3 i wprost zapisany zakaz zwięzłości w promptcie. Lekcja: z modelem nie negocjuje się długości przymiotnikami, tylko liczbami, które da się policzyć w outputcie.

[+][CH-02]

Edycja przez „wygeneruj jeszcze raz z poprawką” niszczyła po cichu wszystko, co już było dobre — nowa wersja potrafiła zgubić sekcje, o które nikt nie prosił. Przeszedłem na function calling: model wywołuje update_article_content i musi zwrócić pełną nową treść plus streszczenie zmian, więc kontrakt jest deterministyczny i od razu widać, co się zmieniło. Poprawki przestały być loterią — czat edytuje artykuł, nie pisze go od nowa.

[+][CH-03]

Na 2–3 tysiącach słów model dryfuje: zaczyna tonem wzorca, a kończy własnym. Spiąłem to z dwóch stron — prompt najpierw każe przeanalizować wklejony tekst wzorcowy (ton, rytm zdań, formatowanie), a zestaw reguł „immutable” (nie zmieniaj tytułu, nie usuwaj słów kluczowych, trzymaj strukturę) jest doklejany do każdego wywołania, także w pętli edycji. Bez powtarzania reguł przy każdej iteracji poprawka potrafiła po cichu unieważnić ustalenia z briefu.

[+][CH-04]

Aplikacja miała działać osadzona w iframe na obcej stronie — i tu czekała lekcja z nagłówków bezpieczeństwa. Domyślny X-Frame-Options: SAMEORIGIN Vercela blokował ramkę, więc pierwsza poprawka wymusiła X-Frame-Options: ALLOWALL — obejście kontrproduktywne, bo ALLOWALL nie jest poprawną wartością tego nagłówka i część przeglądarek degraduje ją do DENY. Godzinę później wycofałem stary nagłówek w całości i oparłem osadzanie na nowoczesnym standardzie: Content-Security-Policy: frame-ancestors. Do trybu embed doszło API postMessage (ustaw treść, wyzwól generację, pobierz wynik), a ukrywanie sidebara steruje parametr ?embed=true — strona-gospodarz dostaje generator jako komponent, nie jako całą aplikację. Wniosek zapisany na przyszłość: błędne obejście lepiej wyciąć, niż nawarstwiać na nim kolejne.

[FIG. 4] WARSTWA AI

Gemini 2.5 Flash (@google/genai, temperature 0.8, topP 0.95, thinkingBudget 4000) pracuje tu w dwóch pętlach: pierwsza generuje artykuł z parametryzowanego promptu — z warunkowym groundingiem Google Search, gdy podano linki źródłowe, i listą źródeł parsowaną z groundingMetadata pod artykułem — a druga edytuje treść przez function calling z deterministycznym kontraktem: pełna nowa treść plus streszczenie zmian. Bez tego kontraktu każda poprawka byłaby loterią regeneracji; z nim edycja jest przewidywalna jak commit. Sam dobór modelu też przeszedł chrzest produkcyjny: modele preview uderzyły na wdrożonym kluczu w limit free-tier (429 RESOURCE_EXHAUSTED, kwota 0) i generowanie umarło — diagnoza kodu błędu zamiast zgadywania i przełączenie na gemini-2.5-flash przywróciły usługę dwiema liniami diffa.

[FIG. 2A] ANATOMIA PROMPTA

services/geminiService.ts → PROMPT (1×, parametryzowany)

Napisz artykuł o długości MINIMUM 2 750 słów (5 stron × 550 słów/strona). Nie streszczaj, nie skracaj sekcji.

Przeanalizuj tekst wzorcowy poniżej i skopiuj jego ton, rytm zdań i formatowanie — artykuł ma brzmieć jak ta sama redakcja.

ZASADY BEZWZGLĘDNE (obowiązują w każdej iteracji edycji): nie zmieniaj tytułu, nie usuwaj słów kluczowych, trzymaj strukturę H2/H3.

Formatuj: # H1 · ## H2 · ### H3 · [CENTER] nagłówek wycentrowany — tagi mapowane 1:1 na strukturę DOCX (Roboto).

  • LLM domyślnie streszcza — twardy próg słów wymusza długość
  • mimikra tonu marki zamiast generycznego „AI-tekstu”
  • reguły trzymane w KAŻDYM wywołaniu, także w pętli edycji
  • eksport wierny co do nagłówka — metatagi zamiast parsowania HTML

[FIG. 5] GALERIA

Generator Artykułów AI — fig 5
[FIG. 5] 01/04
Generator Artykułów AI — fig 6
[FIG. 6] 02/04
Generator Artykułów AI — fig 7
[FIG. 7] 03/04
Generator Artykułów AI — fig 8
[FIG. 8] 04/04

[FIG. 6] STACK & LINKI

REACTVITETYPESCRIPTGOOGLE GEMINI (@GOOGLE/GENAI)FUNCTION CALLINGVERCELDOCX EXPORT
KOMPETENCJE W TYM PROJEKCIE: GEMINI · TOOL USE · PROMPT ENG · DOCX