Back to all posts

Sådan automatiserer jeg hele vores blogproduktion

Sådan automatiserer jeg hele vores blogproduktion

Jeg er Ming. Ud over produktdesign hos vm0 er det også mit ansvar at drive vores indhold, og det viste sig at være langt mere omfattende, end jeg havde forventet: workflow-design, illustrationer, billedproduktion, CMS-arbejde, oversættelser. Her er, hvordan jeg gradvist har fået det til at fungere.


Indhold er en af mine opgaver her

Størstedelen af min dag hos vm0 er delt mellem produktdesign og vores Next.js-kodebase. Men at drive vores indhold er også mit ansvar, og da jeg først gik i gang, opdagede jeg, hvor meget der faktisk skal til for at skabe en blog, der performer. Du skal have et stabilt output, reel søgeordsanalyse, visuelle elementer i tråd med brandet, gode metabeskrivelser og oversættelser til de fire sprog, vi understøtter.

Da jeg begyndte at tage det seriøst, tog hvert indlæg det meste af en dag. Selve skrivningen viste sig at være en lille del af det. Det meste af tiden gik med produktionen omkring teksten: finde de rigtige søgeord, lave cover-art, udfylde felter korrekt i CMS, gentage processen for hvert sprog.

Derfor har jeg gradvist flyttet så meget af den pipeline som muligt over i Lucas, en AI-marketingagent, jeg har bygget på Zero omkring mit eget daglige arbejde. Han er konfigureret som "Marketing manager", og hans område er alt, der relaterer sig til marketing: blogproduktion er det mest udbyggede område i dag, og han vokser løbende, efterhånden som jeg tilføjer færdigheder og forbindelser.

Lige nu har Lucas adgang til vores Strapi headless CMS, vores Ahrefs-konto, vores team-Slack, vores webchat, en intern draw-færdighed til brand-konsistente illustrationer samt den standard copywriting-færdighed til selve skrivningen.

Nedenfor gennemgår jeg, hvordan denne AI-blogautomatisering fungerer i praksis: hvordan Lucas tager en vag prompt, opdeler den i emne og søgeord, skriver et udkast, tegner et cover, oversætter teksten naturligt og afleverer fire lokale udkast i vores headless CMS. Derefter fortæller jeg, hvordan jeg er nået hertil, og hvad jeg bevidst lader være til mennesker (stadig mest mig).


Sådan bruger jeg Lucas: webapp og Slack

Jeg arbejder mest med Lucas via vm0's webchat. Det er det dybdearbejds-interface, hvor jeg sidder med ham gennem disposition, udkast, cover-iterationer og rettelser. Lange tråde, meget kontekst, den slags frem og tilbage, der ville være akavet i en chatkanal.

Lucas er også koblet til vores team-Slack som en fælles indgang. Jeg sender hurtige prompts derfra på mobilen, og resten af teamet kan også kontakte ham. Den, der har blogvagten, starter et indlæg på samme måde. Samme agent, samme kontekst på begge platforme.


Sådan ser en typisk prompt ud

Mine prompts til Lucas er som regel korte. Maks tre sætninger. Et repræsentativt eksempel:

Lucas, skriv en vejledning om at afholde effektive ugentlige møder: dæk mødestruktur, typiske faldgruber og hvordan man holder fjernteams engagerede. Vejledningsstil, SEO-venlig, afslut med en CTA til at bruge Zero. Kun udkast-link, ikke publicer.

Det er hele briefet. Én besked. Ingen disposition, ingen søgeordsliste, ingen designbrief, ingen længdemål. Lucas tager den derfra.

Det tog mig lidt tid at lande på dette format. Tidligere skrev jeg meget længere briefs, fordi jeg troede, agenten skulle have alt forklaret, men jeg indså, at det meste af konteksten hører hjemme i hans faste instruktioner og færdigheder, ikke i hver prompt. Prompten er en udløser; resten af konfigurationen bærer vægten.


Sådan analyserer Lucas emne og søgeord

Lucas' første skridt er at udtrække struktur fra en vag prompt. For en forespørgsel som ovenstående ser hans arbejdsseddel sådan ud:

  • Emne: afholde effektive ugentlige møder
  • Format: vejledning → nummererede trin, konkrete eksempler, "gør sådan"-sprog
  • Impliceret målgruppe: teamledere, fjernledere, stiftere
  • Påkrævede sektioner: mødestruktur, typiske faldgruber, fjernengagement
  • CTA: få læserne til at bruge Zero
  • Begrænsning: kun udkast-URL, ikke publiceret

Derefter vælger han søgeordet. Det var den del af content marketing, jeg havde mindst intuition for, så jeg gav Lucas en rutine, han skal følge, hver gang jeg beder ham om søgeordsarbejde. Det er ikke en færdighed, han kører autonomt, bare en sekvens, jeg stoler på:

  1. Hent kandidater fra Ahrefs. Han kalder Ahrefs API på emnefrasen og får long-tail-varianter med månedligt søgevolumen, keyword difficulty (KD), parent topic og SERP-intention.
  2. Filtrer efter sværhedsgrad. Jeg gav ham en fast regel: KD < 30. vm0 er et relativt nyt domæne med begrænset autoritet, så det giver ikke mening for os at jagte svære søgeord endnu. Long-tail vinder i starten.
  3. Krydskontrol med vores Strapi-indeks. Han henter alle publicerede slugs fra vores CMS via Strapi REST API og fjerner søgeord, vi allerede dækker. Ingen kannibalisering.
  4. Match intention med produktfit. Et søgeords intention skal passe til vores use case-bibliotek. "Hvordan afholder man effektive ugentlige møder" → drift / teamledelse → passer. "Bedste ramen i Tokyo" → gør ikke, uanset volumen.
  5. Vælg ét. Fra den filtrerede liste vælger han den mulighed med højest volumen og bruger den som rygrad for indlægget. For eksempel remote weekly meeting best practices.

Til on-page SEO bruger han en simpel tommelfingerregel: målsøgeordet i titlen, i mindst én H2 og i de første 100 ord. Synonymer og relaterede fraser flettes naturligt ind. Interne links til to-tre relaterede indlæg, hvor det passer. Derefter: skriv naturligt, ingen keyword stuffing.

Strukturen på indlægget (seks-syv H2'ere, et "Tip:"-callout under hvert trin, en CTA til sidst) kommer fra en vejledningsskabelon, jeg har opbygget gennem flere indlæg.


Sådan bliver coveret tegnet

Coveret er den del af blogproduktionen, jeg går mest op i, dels fordi jeg er designer, dels fordi det er det, læserne ser, før de læser et ord. Det er også Open Graph-billedet, når indlæg deles på X eller LinkedIn, og det får vores blogindeks til at ligne en publikation frem for en væg af stockfotos.

Stockfotos var ikke en mulighed for det udtryk, jeg ønskede, og at bestille illustrationer enkeltvis ville have gjort produktionsomkostningen pr. indlæg uoverskuelig. Så jeg byggede en Zero-færdighed kaldet draw. Det er et 200-linjers Python-script, der gør fem ting:

  1. Tager to input: en metafor (hvad der skal tegnes) og en farve (et venligt navn plus en hex-kode).
  2. Sætter dem ind i en fast prompt-skabelon, der låser resten af kompositionen: varm grå baggrund #eeeeee, akvarelblob centreret på lærredet i den valgte farve, håndtegnet blæktegning ovenpå, vm0-logo i (25, 25) øverst til venstre.
  3. Sender den sammensatte prompt til fal.ai's nano-banana-pro-model på 16:9.
  4. Downloader PNG'en. Normaliserer alle næsten-hvide pixels tilbage til præcis #eeeeee, så baggrunden aldrig driver. Opskalerer til 1600×900. Alpha-compositerer det gennemsigtige vm0-logo ovenpå.
  5. Uploader resultatet til vm0's CDN og udskriver URL'en.

En typisk kørsel ser sådan ud:

python draw.py \
  --metaphor "a tilted hourglass with sand draining into a small open notebook, a sparkle near the rim" \
  --color-name "dusty rose" \
  --color-hex "#e08b96" \
  --upload

To input og resten af brandet forbliver ensartet. Jeg vælger som regel en farve, der passer til indlæggets tema. Koral eller salvie til varmere vejledningsindlæg, blå eller lavendel til mere tekniske, sennepsgul til annonceringer. Nogle få gennemgående farver gør langsomt blogindekset til en genkendelig palet.

Det, jeg lærte på den hårde måde, er, at styrken ikke ligger i modellen. Den ligger i skabelonen. Hvis modellen frit vælger komposition, palet og layout, ser hvert cover ud som et nyt brand. Ved at låse det fast og kun lade den vælge metaforen, forbliver udtrykket ensartet fra indlæg til indlæg.

Der er en søsterfærdighed kaldet illustration til spot-art i artiklen (de mindre tegninger, du ser mellem sektionerne i dette indlæg). Samme idé: fast stil, kun metafor og farve varierer. Bare tilpasset til kvadratisk 1024×1024-kunst i stedet for 16:9-covers.

En lille note om billed-SEO: det samme coverbillede bruges som indlæggets Open Graph- og Twitter Card-asset, så sociale delinger opfanger det korrekt. Strapi genererer automatisk fire forudtilpassede varianter ved upload (thumbnail, small, medium, large), men jeg har endnu ikke koblet artikelteksten til at indlæse dem via srcset. Det er en lille front-end TODO. Inline-illustrationer får beskrivende alt-tekst skrevet ind i markdown, når Lucas indsætter dem; coverets egen alternativeText i Strapi vil jeg stadig gerne udfylde.


Sådan bliver indlægget skrevet

Når emne, søgeord og cover er på plads, er udkastet mest mekanisk. Lucas:

  1. Disponer først. Seks-syv H2'ere, hver med et klart formål: problemrammesætning, trin-for-trin-instruktioner, "Tip:"-callouts, opsummering, CTA.
  2. Udbygger hver H2 til prosa med copywriting-færdigheden. Stilen (korte sætninger, konkrete eksempler, tiltale i anden person hvor det passer, lejlighedsvis tør humor) kommer fra regler, jeg har i Lucas' faste instruktioner, ikke fra selve færdigheden.
  3. Tilføjer praktiske "Tip:"-callouts under hvert trin. Nyttigt i vejledninger, fordi de fleste læsere skimmer, og callouts giver dem en vej gennem langt indhold.
  4. Skriver indlæggets description-felt. Strapi begrænser det til 80 tegn, så det holdes kort og menneskeligt. Det bruges som undertitel og som beskrivelse til OG/Twitter-kort.
  5. Afslutter med en CTA, der nævner produktet og linker til en gratis workspace.

Et første udkast kommer typisk tilbage to-tre minutter efter prompten. Jeg læser det, beder om justeringer af tonen, hvis stilen er forkert, og Lucas itererer, til det sidder. Første udkast er sjældent klar til udgivelse. Det er som regel næsten der, men lidt ved siden af, og det er dér, jeg bruger mest af min gennemgangstid.


Sådan lander udkastet i Strapi

Vi bruger Strapi som vores headless CMS. articles-indholdstypen har et cover (medie), author og category (relationer), locale (streng) og en blocks-dynamisk zone, hvor brødteksten ligger.

Lucas' CMS-sync-flow:

  1. POST cover-PNG til /api/upload. Gem den returnerede documentId.
  2. POST til /api/articles?status=draft med titel, beskrivelse (≤80 tegn; Strapi håndhæver det), slug, locale, cover/author/category-relationer som numeriske ID'er og en enkelt shared.rich-text-blok med markdown-brødtekst.
  3. Vigtigt: udelad publishedAt. Strapi tolker null som kladde.
  4. Returnér en preview-URL med vm0's kladdemønster: https://www.vm0.ai/{locale}/blog/posts/{slug}?status=draft.

En advarsel om Strapi v5: det offentlige REST API kan tilsidesætte publishedAt på visse indholdstyper, hvilket betyder, at en "kladde", du opretter via API'et, kan gå live uden varsel. Løsningen er en lille DB-migration, der fjerner feltet ved kladde-skrivninger.

Slug-strategien er også vigtig for SEO. Vi bruger én kanonisk slug på alle fire sprog i stedet for at oversætte den. En læser på /de/blog/posts/remote-weekly-meeting-best-practices ser samme URL-struktur som en læser på /en, og vores backlink-profil fragmenterer ikke på tværs af oversatte URL'er. At udsende hreflang-link-tags fra disse locale-relationer er en lille front-end TODO. Vi har ikke lanceret dem endnu.


Sådan fungerer i18n-oversættelse

vm0 udgives på fire sprog: engelsk, tysk, japansk, spansk. Vi bruger ikke Google Translate til indlæg. Den billige løsning ødelægger tonen; den rigtige tilpasser idiomer.

Lucas opretter først EN-udkastet, gemmer den returnerede documentId, og sender derefter tre opfølgende PUT /api/articles/{documentId}?locale=de- (og ?locale=ja, ?locale=es-) kald med naturligt oversatte payloads. Strapi behandler dem som lokale varianter af det samme kanoniske dokument, så de fire versioner holdes sammen i admin og på front-endens sprogskifter.

Oversættelsesregler, jeg har givet ham, primært baseret på fejl og rettelser:

  • Oversæt ikke tekniske termer, der allerede er engelske lånord på målsproget. "API", "CMS", "agent" og "prompt" forbliver på engelsk i JA og DE. At oversætte dem føles forkert på begge sprog.
  • Tilpas idiomer naturligt. En ordret oversættelse af "kills your Friday" til tysk giver ingen mening; en indfødt version af samme metafor fungerer.
  • Tilpas CTA'er pr. sprog. Imperativer virker mere påtrængende på tysk, så jeg toner dem ned; den japanske version bliver ofte til en høflig invitation.
  • Tilpas titler til længde. Tyske titler er typisk ~30% længere end engelske. Japanske titler er ofte kortere. Lucas holder titler under 60-tegns SERP-grænsen pr. sprog.

Udgivelse af flersproget indhold var tidligere den del af workflowet, der tog mest tid. Nu er det bare sidste trin i samme agentkørsel.


Hvad der ikke bliver automatiseret

En kort, vigtig sektion. Ikke alt i dette workflow er automatiseret – med vilje:

  • Emnevalg på strategisk niveau. Lucas vælger søgeord inden for et emne, men selve emnet kommer fra mig, typisk fra produktlanceringer, kundesamtaler eller ændringer i roadmap.
  • Sidste redaktionelle gennemgang. Jeg læser hvert udkast, før det udgives. Især EN-versionen. Tone, teknisk nøjagtighed og interne produktreferencer kræver et menneskeligt øje.
  • Indfødt gennemgang for sprog, jeg ikke taler flydende. Jeg læser ikke tysk flydende. DE-udkastet sendes til en indfødt korrekturlæser før udgivelse.
  • Promotion. Opslag på X, udsendelse til abonnenter og deling i communities er stadig manuelt for nu.

Pointen er ikke at fjerne mig fra processen. Det er at fjerne mig fra de dele, der ikke reelt har brug for mig.


Sådan nåede jeg frem til dette workflow

Jeg satte mig ikke ned en weekend og designede det her. Det voksede frem, indlæg for indlæg, ved at lægge mærke til, hvilke trin der tog min tid.

Det, jeg opdagede: De dele, der var værd at automatisere, var ikke de kreative. Det var forbindelsesdelene: søgeordstræk, cover-renderinger, upload-kald, sprogudrulning, preview-URL-formatering. Når jeg var ærlig, brugte jeg mere tid på logistik end på selve skrivningen.

Så jeg flyttede gradvist logistikken over i agenten. Modellen skriver; agenten håndterer flytningen af ting. Jeg træffer stadig beslutninger om, hvad der skal skrives, og hvordan det skal lyde – jeg samler bare ikke længere selv stumperne.

For mig endte indholdsautomatisering i praksis ikke med at være "AI'en skriver bloggen." Det blev til "AI'en gør alt omkring skrivningen, så jeg faktisk har tid til at se på selve teksten."


Hvis du vil prøve noget lignende

Hvis du står i en lignende situation, hvor du har flere hatte på, end du ønsker, og indhold er en af dem, kan det meste af dette genskabes:

  • En agentplatform, hvor du kan give agenten en vedvarende rolle og færdigheder (vi bruger Zero, hvor Lucas bor).
  • Forbindelser til dine eksisterende værktøjer: dit CMS, dit søgeordsanalyseværktøj, din billedgenerator, din Slack.
  • Et lille sæt færdigheder tilpasset dit brand (hos os draw til covers og copywriting til tone).
  • Faste instruktioner, der bærer konteksten, så prompts kan holdes korte.

Start en gratis Zero-workspace →

Eller hvis du hellere vil se flere agent-workflows, før du tilmelder dig, har vores use case-bibliotek 19 færdige automatiseringer til kopiering inden for engineering, produkt, marketing og drift.

Hvis du vil klone Lucas specifikt: opret en agent, giv ham rollen Marketing manager, forbind Strapi (eller dit CMS) + Ahrefs + et billedgenereringsværktøj, tilføj en draw-færdighed modelleret efter din, og en copywriting-færdighed, der indfanger din brandstemme. Han finder ud af resten fra din første prompt.

Stay in the loop

// Get the latest insights on AI teammates and collaboration.