Pipeline artykułów blogowych¶
Generowanie i publikacja artykułów blogowych dla buyspace.pl przez automatyczny pipeline. Strona ta opisuje: jak działa generator (modelem językowym przez Chutes.ai), jak artykuł trafia do WordPressa jako draft, oraz co zrobić, żeby uruchomić to ręcznie z dowolnym tematem.
Krótko
- Pipeline:
f/automations/articles/article_pipelinew Windmillu — dwa kroki: generate + publish. - Generator: Chutes.ai (model
deepseek-ai/DeepSeek-V3-0324domyślnie), 1500 słów, język polski, ton profesjonalny. - Publikacja: REST API WordPressa (
POST /wp/v2/posts), zapisuje post jako draft (chyba że ustawiszauto_publish=true). - Operatorski UI w panelu jest prowizoryczny — strona
Automatyzacje → Pipeline artykułówto placeholder linkujący do Windmilla. Pełny UI w roadmapie. - Co zrobiliśmy w ramach zlecenia (TASK-194): dostarczone 12 artykułów startowych + automat do generowania kolejnych.
Ogólny przepływ¶
flowchart LR
A[Operator<br/>Windmill UI] -->|Run flow| B[generate_article<br/>Python + httpx]
B -->|Chutes.ai REST| C[LLM<br/>DeepSeek V3]
C -->|JSON: title, slug,<br/>HTML, meta| B
B --> D[publish_to_wordpress<br/>Python + httpx]
D -->|REST WP /tags| E[Auto-create tagi]
D -->|REST WP /posts<br/>status=draft| F[WordPress<br/>buyspace.pl]
F -->|edit_url| G[WP-Admin<br/>operator dopina<br/>obrazek + publish]
Wynik wywołania flow: JSON z post_id, post_url, edit_url, statusem (draft / publish) i listą utworzonych tagów. Operator dostaje edit_url — klika, wchodzi do WP-Admin, dorzuca obrazek wyróżniający (opcjonalnie) i klika Opublikuj.
Jak uruchomić pipeline¶
Z UI Windmilla¶
- Otwórz
windmill.aiofactory.pl(workspaceaio= produkcyjny). - Flows →
f/automations/articles/article_pipeline. - Wypełnij formularz wejściowy:
topic(wymagane) — temat artykułu, np. „Jak wybrać legowisko dla psa".chutes_api_key(wymagane) — klucz API Chutes.ai. Schowany w sekretach (f/tokens/chutes_api_key).wp_base_url(wymagane) —https://buyspace.pl(lub odpowiednia instancja).wp_username(wymagane) — login WP-admin sklepu.wp_app_password(wymagane) — Application Password wygenerowany w WP-Admin (patrz Application Password).- (opcjonalne)
keywords— lista słów kluczowych SEO (np.["legowisko dla psa", "posłanie dla psa"]). - (opcjonalne)
language— domyślniepl. - (opcjonalne)
tone— domyślnieprofessional. - (opcjonalne)
target_word_count— domyślnie 1500. - (opcjonalne)
auto_publish—false(domyślnie draft) lubtrue(od razu opublikuj). - (opcjonalne)
tags,category,custom_instructions.
- Kliknij Run — flow trwa zwykle 30–90 s (większość to wywołanie LLM).
- W panelu wynikowym otwórz
result.publish.edit_urlw nowej karcie i pracuj dalej w WP-Admin.
Z panelu¶
Sekcja Automatyzacje → Pipeline artykułów (/automations/articles) jest na razie kafelkiem informacyjnym — wskazuje na flow w Windmillu i pokazuje krótki opis. Pełen operatorski formularz (lista tematów, kolejka, podgląd) jest na roadmapie poza zakresem oferty bug-fix mode.
Przez harmonogram (cron)¶
article_pipeline można uruchomić cyklicznie przez Windmill Schedule. Domyślnie nie ma aktywnego harmonogramu — operator decyduje, kiedy pisać. Jeśli chcesz np. „1 artykuł na tydzień":
- Schedules → New w Windmillu, ścieżka
f/automations/articles/article_pipeline. - Cron
0 0 8 * * 1(poniedziałek 08:00). - Wypełnij argumenty stałe (
wp_base_url, klucze, język).topiczostawiasz pusty — flow upadnie z błędem, dopóki nie podstawisz tematu (świadoma ochrona przed „ślepym" generowaniem).
Application Password¶
WordPress wprowadził w 5.6 mechanizm Application Passwords — alternatywę dla logowania hasłem zwykłego użytkownika, dedykowaną integracjom REST API.
Generowanie:
- WP-Admin → Użytkownicy → Profil, przewiń na dół.
- Sekcja Hasła aplikacji — wpisz nazwę (np. „Panel AIO — artykuły") i kliknij Dodaj nowe hasło aplikacji.
- WordPress pokaże hasło w formacie
xxxx xxxx xxxx xxxx xxxx xxxx— skopiuj od razu, więcej go nie zobaczysz. - Wklej w polu
wp_app_passwordw Windmillu (lub zachowaj w Bitwarden podpanel-aio / wp-buyspace-app-password).
Klucz REST API ≠ Application Password
Consumer Key / Consumer Secret z Konfiguracji WooCommerce są dla endpointów wc/v3 (produkty, zamówienia). Application Password jest dla endpointów wp/v2 (posty, tagi, użytkownicy). Pipeline artykułów używa wyłącznie wp/v2, więc nie potrzebujesz klucza WC.
Co dokładnie generuje LLM¶
generate_article.py wysyła do Chutes.ai prompt, który wymusza odpowiedź wyłącznie w JSON z tymi polami:
| Pole | Co znaczy |
|---|---|
title |
Pełny tytuł SEO. |
slug |
URL-friendly slug (jeśli LLM nie zwróci, panel sam slugifikuje tytuł). |
content_html |
Treść artykułu w HTML (<h2> / <h3> / <p> / <ul> / <strong> / <em> / <blockquote>). |
excerpt |
1–2 zdania podsumowania (max 160 znaków). |
meta_title |
Yoast SEO meta title (max 60 znaków). |
meta_description |
Yoast SEO meta description (max 155 znaków). |
focus_keyword |
Główne słowo kluczowe (Yoast). |
featured_image_prompt |
Opis pod generację obrazka wyróżniającego (do ręcznego prompta dla DALL-E / Midjourney — pipeline obrazków obecnie poza zakresem). |
tags |
Lista tagów do dodania w WP. |
Wszystkie pola Yoast (_yoast_wpseo_title, _yoast_wpseo_metadesc, _yoast_wpseo_focuskw) są zapisywane do meta posta — pod warunkiem, że Yoast SEO plugin jest aktywny i wypisuje te klucze przez REST. W ofercie zakładamy, że jest.
Co dokładnie publikuje skrypt¶
publish_to_wordpress.py:
- Resolve tagów — dla każdego z
article.tagsszuka istniejącego (GET /tags?search=...), jeśli nie znajdzie, tworzy nowy (POST /tags). - Buduje payload posta — używa
wordpress_payloadz generatora albo składa go z surowych pól (title,slug,content,excerpt,status=draft,meta). - Tworzy post —
POST /wp/v2/posts, zwracapost_id,link,status. - Zwraca operatorowi:
post_id(do dalszego edytowania przez REST jeśli chcesz),post_url(publiczny adres po publikacji),edit_url(https://<sklep>/wp-admin/post.php?post=<id>&action=edit) — operator klika i kończy ręcznie.
Domyślnie zapisuje jako draft
Pole auto_publish=false (domyślne) jest świadomie konserwatywne. LLM bywa kreatywny — ostatnia weryfikacja przed publikacją na żywej domenie zawsze jest po stronie operatora. Po przejrzeniu w WP-Admin klikasz Opublikuj.
Najczęstsze błędy¶
| Objaw | Co to oznacza |
|---|---|
httpx.HTTPStatusError: 401 Unauthorized przy POST /posts |
wp_username lub wp_app_password błędne. Wygeneruj nowy Application Password. |
httpx.HTTPStatusError: 401 przy GET /tags |
Application Password jest, ale użytkownik nie ma uprawnień edit_posts. Promuj go do roli Redaktor lub Administrator w WP-Admin. |
JSONDecodeError w generate |
LLM zwrócił niepoprawny JSON (zwykle gdy temat jest bardzo nietypowy lub temperature za wysokie). Spróbuj ponownie z temperature=0.5. |
400 Bad Request przy POST /tags |
Tag już istnieje, ale search go nie znalazł (różnica wielkości liter, znaków diakrytycznych). Dodaj go ręcznie w WP-Admin albo edytuj _extract_json żeby był bardziej tolerancyjny. |
| Generation_time_seconds > 120 | Chutes.ai pod obciążeniem. Klient httpx ma timeout 120 s — flow padnie. Ponów. |
Dane techniczne (appendix)¶
- Skrypty:
windmill/f/automations/articles/{generate_article.py, publish_to_wordpress.py}+ flowarticle_pipeline.flow/flow.yaml. - Generator:
Chutes.ai(https://llm.chutes.ai/v1/chat/completions), domyślny modeldeepseek-ai/DeepSeek-V3-0324,max_tokens=4096,temperature=0.7. - Publikacja: WordPress REST
POST /wp-json/wp/v2/posts+/wp/v2/tags, autoryzacja Basic Auth (Application Password). - Sekrety: klucz Chutes w Windmill variable
f/tokens/chutes_api_key. WP password trzymany przez operatora (Bitwarden) — nie zapisujemy go w sekretach systemowych, bo każdy sklep ma swój. - UI placeholder:
dashboard/src/routes/automations/articles/+page.svelte(statyczna karta info). - Status zlecenia: TASK-194 (strona produkcyjna — miniatury, 12 artykułów, kontakt, branding) zrealizowane; pełny operatorski UI poza zakresem oferty.