Bliv en del af mit community / gratis nyhedsbrev — tilmeld dig her
- Client
- GrN.dk — internt projekt
- Sector
- Personlig automatisering, scraping af offentlige kilder og AI-assisteret filtrering
- Periode
- Bygget juli 2026 · henter hver morgen kl. 06:45 siden 9. juli 2026
At a glance
Denne case har intet link på sig, og det er netop pointen: jobs.grn.dk svarer 401 til internettet og har altid gjort det. Det er et internt værktøj — en jobradar bygget til ejerens egen jagt på arbejde. Hver morgen læser den syv kontrakt- og jobportaler, dropper alt, der ikke kan matche en skreven profil, lader en sprogmodel bedømme det overlevende mod samme profil og præsenterer den håndfuld, der er værd at læse, som én skærm med tre knapper: søgt, udkast til mail, kassér.
Fordi den rummer ét virkeligt menneskes live jobsøgning, publiceres intet af den her. Screenshotet ovenfor er en engangs-demokopi af samme interface, seedet med opdigtede rækker — hvert firma, hver titel, lokation og adresse i den er en pladsholder, og den mærker sig selv "demo data" i headeren, så den aldrig kan forveksles med det rigtige board.
The challenge
Den manuelle udgave af dette er tyve minutter om dagen med at læse syv portaler for — på en god dag — at finde én annonce, der er værd at svare på. Det, der gør det svært at automatisere, er ikke skrabningen. Det er, at de to ting, der afgør, om et opslag er relevant, er de to ting, jobportaler beskriver dårligst.
"Remote" på en jobportal betyder sjældent remote. Et opslag mærket Poland · Remote eller Portugal · Remote betyder remote inde fra det land — lokal bopæl, arbejdstilladelse, lokal skattepligt. Kravet her er det modsatte: arbejde, der kan udføres remote fra Danmark, eller arbejde, der reelt er åbent for hele verden. Opslag placeret i Danmark kvalificerer, worldwide-opslag kvalificerer, opslag åbne for hele EU/EØS/Norden kvalificerer, og det gør Øresundsregionen på den anden side af broen også — et landenavn ved siden af ordet "remote" diskvalificerer som regel. Ingen portal har et filter for den skelnen, for kun annoncens egne ord kan afgøre den.
Den ønskede samarbejdsform er ikke den, portalerne er bygget til. Målet er deltids- og leverancebaseret arbejde — en defineret opgave med et aftalt resultat, på en tidsplan man selv sætter — ikke en fast fuldtidsstilling. Portalerne har faktisk facetter for ansættelsesform, og hvor de udstiller én, er den guld værd; men en nøgen søgning på freelance eller konsulent på en generel portal returnerer mest fast on-site-ansættelse, der tilfældigvis bruger ordet.
To yderligere begrænsninger formede designet. En sprogmodel kan ikke være filteret — at bedømme hvert eneste af hundredvis af daglige opslag med en model er langsomt og dyrt, så modellen skulle kun bruges dér, hvor et maskinlæsbart felt reelt ikke kan besvare spørgsmålet. Og et filter, der smider for meget væk, er værre end intet filter — for man ser aldrig, hvad det kasserede: alt, det droppede, skulle kunne droppes med en angivet begrundelse, og mennesket skulle kunne rette det uden at røre koden.
The solution
Syv kilder, hver læst på den billigste ærlige måde. jobindex.dk gennem sit RSS-endpoint — som svarer på samme query-streng som HTML-søgningen, så portalens egne facetter (Freelance, Deltid, 100% hjemmearbejde) klarer første filtreringsrunde gratis; emagine og Verama gennem deres offentlige JSON-API'er; rightpeoplegroup ud af den JSON, dens egne sider selv leverer; amino.dk gennem RSS plus dens offentlige detaljesider; freelancermap gennem dens offentlige facetsider; weworkremotely gennem det ene alle-kategorier-feed, som er det eneste, der bærer ansættelsesform, landeliste og skills. Hver kilde har et hårdt høflighedsloft for, hvor mange detaljesider én kørsel må hente, og et stop for løbsk paginering.
Strukturerede felter filtreres ved hentning; kun prosa sendes til modellen. Hvor en kilde udgiver et reelt struktureret land eller en ansættelsesform, anvendes geografi- og samarbejdsreglerne, før annoncens brødtekst overhovedet downloades. Målt på probedagene: 160 af 173 åbne Verama-opgaver, 21 af 35 freelancermap-rækker og 96 af de 100 nyeste weworkremotely-annoncer blev droppet ved hentning — uscoret, ugemt og uden nogensinde at koste et modelkald. Modellen spørges kun om de opslag, hvor svaret reelt bor i prosaen.
Én JSON-fil er hele tuning-fladen. Ekskluderede teknologier, uønskede sprogkrav, forespørgsler og til/fra-kontakter pr. kilde, geografi-acceptlisterne, præferencerangeringen af samarbejdsformer og beskæringsvinduet bor alle i rules.json ved siden af scriptet — ingen kodeændring for at genindstille radaren. Interfacet redigerer filen direkte og validerer, mens det gemmer: hvert mønster kompileres som et regulært udtryk, før det accepteres, og den rå JSON-editor afviser alt, der ikke er et gyldigt objekt.
Dommeren læser en skrevet profil, ikke en nøgleordsliste. Hver scoring-prompt samles af en kandidatprofil i almindeligt sprog, de aktuelle geografi- og samarbejdsregler og den akkumulerede feedback, og den returnerer en score fra 1 til 5 pr. opslag. To domme eksekveres automatisk — en annonce, der kræver tilbagevendende fysisk fremmøde, og én hvis "remote" er bundet til et andet land — og hver auto-kassering skrives tilbage med begrundelsen for droppet, så en forkert afgørelse er synlig frem for tavs. Annoncetekst, der når prompten, er eksplicit indrammet som upålidelige data og ikke som instruktioner.
Feedback er varig — og bevidst asymmetrisk. At bede om et mail-udkast eller markere et opslag som søgt er et positivt signal; at kassere det med en note er et negativt, med brugerens egne ord. Begge går i en learnings-tabel, der aldrig beskæres og læses ind i hver senere scoring-prompt, så en rettelse foretaget én gang bliver ved med at gælde. Alt andet udløber: opslag, der forsvinder fra deres feed eller kasseres, slettes efter fjorten dage — medmindre der er søgt på dem, hvilket aldrig fjernes.
Interfacet er én skærm, og det er låst. Jobs sorteret bedst-først efter AI-score, kilde- og score-chips, kontaktadresser løftet ud af annonceteksten og de tre handlinger. Det ligger bag HTTP basic authentication med endnu en lås bagved: fordi browsere automatisk gensender basic auth på hver forespørgsel, skal hver tilstandsændrende POST også bevise, at dens origin matcher den vært, den blev nået på — ellers afvises den.
Den skriver morgenmailen, og den fodrer et godkendelsesloop frem for en ansøgningsrobot. En daglig digest mailer, hvad der er nyt. En separat connector læser samme database og foreslår de bedste én-to kandidater som Trello-kort, et menneske kan godkende eller afvise — og kun en godkendelse udløser den dyre halvdel, der bygger en skræddersyet ansøgning. Intet indsendes nogensinde automatisk til en arbejdsgiver: det sidste skridt er en mail til et menneske, og det menneske trykker selv send. Betalingssporet leveres afvæbnet bag en eksplicit kontakt.
The results
Hvad der findes — aflæst af den live installation den 26. juli 2026: en radar, der har hentet ubemandet hver morgen siden 9. juli, med 522 opslag gemt og bedømt i den periode på tværs af syv kilder — 259 fra jobindex, 230 fra emagine og resten fra Verama, freelancermap, rightpeoplegroup, weworkremotely og amino. 474 af dem er scoret af modellen. 47 står stadig åbne i interfacet; 388 blev kasseret, de fleste af reglerne eller dommeren med begrundelsen bogført, og 87 forsvandt fra deres egne feeds og blev pensioneret automatisk. Otte ansøgningsmails er der lavet udkast til. Alt, der blev droppet ved hentning på geografi eller samarbejdsform — langt størstedelen af det, de syv portaler faktisk udgiver — indgår slet ikke i de tal, for det blev aldrig gemt.
Hvad det ikke har bevist, sagt ligeud: dette er en sourcing- og filtreringsmaskine, ikke et ansættelsesresultat. Ét opslag er markeret som søgt. Ingen opgave er vundet gennem den, og der er endnu ingen svarprocent eller samtalerate, der er værd at citere — pipelinen, der ville måle det, er bygget men bevidst slået fra, og sporet, der bruger penge på skræddersyede ansøgninger, kører kun for et job, et menneske eksplicit har godkendt på et kort. Den ærlige påstand handler om tragten: den daglige læsning klares af maskinen, kasseringerne bærer deres begrundelser, og en rettelse lært én gang bliver ved med at holde.
Hvorfor der hverken er link eller rigtigt screenshot. Værktøjet er privat by design — ét menneskes live jobsøgning, komplet med hvilke arbejdsgivere der er kontaktet, og hvad der blev sagt om dem. Det svarer 401 på enhver uautentificeret forespørgsel, så der er intet at demonstrere offentligt og intet ønske om det. Interfacet vist her er en engangs-kopi af samme kode fodret med opdigtede rækker; det rigtige boards indhold hverken publiceres, citeres eller beskrives i denne case.
"Remote" alene er ikke nok — arbejdet skal kunne udføres remote fra Danmark eller være reelt åbent for hele verden.