Det første af de kiilske principper for AI er et spørgsmål.
Hvilke dele er regler, og hvilke er model?
Det spørgsmål stiller jeg først. Svaret afgør formen på alt det andet. Tager man fejl her, kan ingen mængde prompt-tuning redde én.
To slags arbejde #
Næsten enhver opgave, man giver et AI-system, indeholder to slags arbejde.
Noget af det er skøn. Hvilket af disse ti projekter er mest relevant i forhold til jobopslaget? Er denne mail vred eller bare kortfattet? Hvad er en bedre måde at formulere dette afsnit på? Der er ikke ét rigtigt svar, og en sprogmodel er faktisk god til det.
Noget af det er regler. Momssatsen er 25 procent. Fristen er fredag. En kunde i restance får ikke kredit. Mit CV må ikke indeholde erfaringer, jeg ikke har. Der er et rigtigt svar, og det er det samme hver gang.
En sprogmodel kan klare den første slags. Den kan ikke betros den anden. Ikke fordi den er dum, men fordi den producerer plausibel tekst. Plausibelt er ikke det samme som korrekt. Den vil følge jeres regel 98 ud af 100 gange. I ved ikke, hvilke to gange den ikke gjorde.
»Husk altid at« er et ønske #
I kan få øje på regler, der gemmer sig det forkerte sted, ved at læse prompten. Kig efter vendinger som:
- »Husk altid at …«
- »Aldrig …«
- »Sørg for at …«
- »Under ingen omstændigheder …«
Hver af dem er en regel formuleret som en anmodning. Modellen vil som regel overholde den. Men I kan ikke teste den, I kan ikke bevise, at den holdt, og I får ikke øje på den dag, den brister.
Løsningen er at beholde anmodningen i prompten – for den hjælper – og derefter håndhæve reglen i kode bagefter. Prompten beder. Koden sørger for det.
Et eksempel: et CV, modellen kun må beskære #
Jeg har et system, der tilpasser mit CV til jobopslag. Modellen får mit master-CV og opslaget og vælger de linjer, der passer. Det er skøn, og det gør den godt.
Reglen er, at den kun må beskære. Den må ikke omformulere en linje til noget lidt mere storladent, og den må ikke tilføje noget. I prompten beder jeg pænt om det. I koden kontrollerer jeg hver linje, den returnerer, ord for ord mod mit master-CV.
Her er en forenklet version i Nushell. Jeg bruger aichat til modelkaldet, men ethvert kommandolinje-LLM-værktøj kan bruges.
# Rule: the model may only cut. Every proposed line must exist verbatim in the master CV.
export def assert-cut-only [master: list<string>]: list<string> -> list<string> {
let proposed = $in
let invented = $proposed | where $it not-in $master
if ($invented | is-not-empty) {
error make {
msg: $"The model proposed ($invented | length) line\(s\) that are not in the master CV"
help: ($invented | str join (char newline))
}
}
# Keep the master order, whatever order the model answered in
$master | where $it in $proposed
}
# Judgement: let the model pick the lines that fit the job ad
export def propose-lines [master: list<string>, job_ad: string]: nothing -> list<string> {
let prompt = [
"Below is my CV, one item per line, followed by a job ad."
"Return the lines from the CV that are most relevant to the job."
"Copy each line exactly as written. Do not rewrite, merge or add anything."
"Return only the lines, one per line."
""
"CV:"
...$master
""
"Job ad:"
$job_ad
] | str join (char newline)
^aichat $prompt | lines | str trim | compact --empty
}
export def tailor-cv [master_file: path, job_ad_file: path]: nothing -> list<string> {
let master = open --raw $master_file | lines | str trim | compact --empty
propose-lines $master (open --raw $job_ad_file) | assert-cut-only $master
}Gem den som cv.nu og kør den sådan her:
use cv.nu tailor-cv
tailor-cv master-cv.txt job-ad.txt | save tailored-cv.txtLæg mærke til, hvordan arbejdet er delt. propose-lines er det eneste sted, modellen optræder, og den træffer kun et valg. assert-cut-only indeholder slet ingen AI. Det er en almindelig funktion, der tager en liste og enten returnerer den eller stopper.
To detaljer betyder noget.
For det første stopper kommandoen med en fejl, når reglen brydes. Den dropper ikke stille og roligt den dårlige linje og fortsætter. Hvis modellen begynder at opfinde ting, vil jeg gerne vide det, for det betyder sandsynligvis, at prompten eller modellen har ændret sig under mig.
For det andet afgøres CV’ets rækkefølge af koden, ikke af modellen. Det er også en regel. En lille en, men der er ingen grund til at overlade den til tilfældighederne.
Regler kan testes #
Fordi reglen ligger i en almindelig funktion, kan jeg teste den uden at kalde en model overhovedet. Det gør testene hurtige, gratis og ens hver gang.
use std/assert
use cv.nu assert-cut-only
let master = [
"Built a Nushell module for Drupal publishing"
"Ran workshops on AI for teachers"
"Wrote a book on prompting"
]
# A pure cut passes, and comes back in master order
assert equal (
["Wrote a book on prompting" "Built a Nushell module for Drupal publishing"]
| assert-cut-only $master
) ["Built a Nushell module for Drupal publishing" "Wrote a book on prompting"]
# Invented experience fails
assert error { ["Led a team of 40 engineers"] | assert-cut-only $master }
# So does a line that is only almost the same
assert error { ["Ran workshops on AI for teachers."] | assert-cut-only $master }Den sidste test er min yndling. Et enkelt punktum er nok til at fejle. Det er hårdt, og det er meningen. En model, der tilføjer et punktum i dag, tilføjer måske »senior« i morgen, og så fanger jeg hellere punktummet.
Testene viser også kontrollen, der fejler – ikke bare består. Det betyder mere, end det lyder, og det er faktisk det andet princip, så det gemmer jeg til næste indlæg.
Hvor går grænsen? #
Man finder ikke altid en opdeling så ren som i CV-eksemplet. Et par spørgsmål hjælper mig:
- Er der et rigtigt svar? Hvis to omhyggelige mennesker altid ville være enige, er det en regel. Skriv den i kode.
- Kunne jeg skrive en test for det? Hvis ja, så skriv testen, og lad koden bestå den – ikke modellen.
- Hvad koster det, hvis det er forkert én gang ud af halvtreds? Hvis svaret er »en lidt klodset sætning«, så lad modellen gøre det. Hvis det er »en falsk påstand på mit CV«, så lad være.
Og ofte er det bedste design begge dele: modellen foreslår, koden kontrollerer. Modellen kan frit være kreativ inden for et hegn, og koden er hegnet.
Modellen kan ændre sig. Reglerne kan ikke. #
Der er endnu en grund til at holde regler ude af prompten. Modeller ændrer sig. En ny version kommer, en udbyder justerer noget, I skifter til en billigere model for at spare penge. Jeres prompt kan pludselig virke lidt anderledes.
Hvis jeres regler ligger i kode, gør det ikke noget. Modellen kan blive bedre eller dårligere til at vælge CV-linjer, og mit CV vil stadig kun indeholde ting, jeg faktisk har lavet.
Det er det, det første princip giver jer. Ikke et klogere system, men et hvor I ved præcis, hvilke dele I kan stole på.
Og vil I have hjælp til at finde de regler, der gemmer sig i jeres egne prompts, så skriv eller ring.