I månedsvis har pks image peget på én model: gemini-3.1-flash-image-preview. Det har leveret hver eneste banner her på siden. Så dukkede gpt-image-2 op på Azure Foundry, og pludselig var der noget at sammenligne med.
Det her indlæg handler om to ting på én gang. Først: hvordan vi tilføjede gpt-image-2-supporten uden at ende med en --provider-switch som brugeren skulle huske at sætte. Bagefter: hvad der sker når man kører den samme prompt gennem begge modeller på fire rigtige blog-bannere fra pks-brain-serien.
Sessionen startede med at jeg så modellen lande på vores Foundry-resource:
Mit første instinkt var den åbenlyse løsning: tilføj et --provider-flag. pks image --provider foundry. Det er hvordan halvdelen af alle multi-backend CLI'er gør det. Men brugeren slog det fra med det samme:
Den prompt er sproglig rod — blandet dansk-engelsk syntaks, manglende kommaer, et cant uden apostrof — men teknisk er den krystalklar. Brugeren tænker ikke i providers. Brugeren tænker i modeller. gpt-image-2 betyder noget. foundry er en implementeringsdetalje. Hvis CLI'en tvinger en til at oversætte fra det første til det andet hver gang, er den i vejen for arbejdet.
Model-driven routing
Resultatet blev en lille abstraktion: IImageProvider. Tre metoder, og hver provider svarer på spørgsmålet "kan jeg levere den her model?":
public interface IImageProvider
{
string Name { get; }
Task<bool> IsAuthenticatedAsync();
Task<bool> CanServeModelAsync(string model);
Task<IReadOnlyList<ImageModelInfo>> ListModelsAsync();
Task<byte[]> GenerateAsync(ImageGenerationRequest request);
string AuthHint { get; }
}
pks image itererer over de registrerede providers (Google, Foundry — og OpenAI direct når den dag kommer), tager den første der både er autentificeret og kan servere den ønskede model, og lader den tage over. Default-modellen er stadig gemini-3.1-flash-image-preview — alt eksisterende blog-tooling blev ved at virke. Men hvis man skriver --model gpt-image-2, finder pks selv Foundry-credentialene og routes derhen.
Der findes stadig et --provider-flag, men det er en escape hatch til det dag hvor to providers begge påstår at de kan servere gpt-image-1 (Foundry og OpenAI direct). Ikke noget brugeren skal tænke på til daglig.
Auth: ingen ny credential-dans
Det fede var at Foundry-providerens auth-path slet ikke krævede ny opsætning. Vi har allerede pks foundry init til at hente og persistere et OAuth refresh-token i ~/.pks-cli/. Det token har scope mod cognitiveservices.azure.com. Image-generations-endpointet er ét af cognitiveservices-services. Altså:
- Hvis credentialen indeholder en eksplicit API-key, brug den.
- Ellers: mint et access token fra refresh-tokenet med Cognitive Services-scope og send det som
Bearer.
Ingen ekstra ENV-vars. Ingen separat pks image login. Foundry-credentialen brugeren allerede har, er image-credentialen.
Sammenligningen: fire bannere, to modeller
For at finde ud af om gpt-image-2 faktisk var bedre — eller bare anderledes — tog vi de fire pks-brain-banners der lige var blevet leveret af Gemini, og kørte de samme prompts gennem gpt-image-2. Side om side:
pks-brain (hovedindlægget)


Gemini holder skarpheden. Kortskællene er læsbare, lyssprangen rammer præcis hvor den skal. gpt-image-2 er blødere — mere studiefoto, mindre teknisk produktshot — men har mistet det diagonale amber-lys der gav Gemini-versionen retning.
pks-brain-wiki


Her er det omvendt. gpt-image-2 leverer atmosfæren — varmere, dybere skygger, kuffen ser brugt ud. Men de "labelled tabs" prompten beder om er forsvundet ind i skyggerne. Gemini holdt fanetekst og messing-skilt synligt.
pks-brain-graph


Begge respekterer kompositionen — fire stakke i graf-layout. Men tonen er vidt forskellig. Gemini er arkiv-papir. gpt-image-2 er møblér-din-skattekiste.
pks-brain-commit-messages


Den her er den tydeligste illustration af forskellen. Gemini læser prompten — den ser Conventional Commits som en konkret reference og stempler den ind på arket. gpt-image-2 leverer en flot pressemaskine men har frasorteret det specifikke. Det er smukt produktfoto, men det fortæller ikke historien.
Mønstret
Efter fire sammenligninger er mønstret tydeligt:
- Gemini Flash Image er bogstavelig. Den læser prompten som en specifikation og forsøger at få hver detalje med. Hvis du beder om
labelled tabsellerConventional Commits stamp, kommer det med. Tradeoff: kompositionen kan virke teknisk og kølig. - gpt-image-2 er filmisk. Den læser prompten som en stemning og pusher kontrast, dybde og atmosfære. Tradeoff: små specifikke krav forsvinder i moodboard-energien.
Til vores blogbannere — hvor metaforen er indholdet — vinder gpt-image-2 alligevel. Den ekstra mood gør forskellen mellem "stock-foto-agtigt" og "redaktionelt cover". Vi har flippet make-blog-post-skillet til at bruge --model gpt-image-2 som default. Nye posts kommer som .png i 1792×1024 fra Foundry; gamle .jpg-banners bliver liggende fra Gemini-æraen.
Hvor det fører hen
Næste skridt på listen er den tredje provider: OpenAI direct. Det er en enkelt klasse der implementerer IImageProvider plus én linje DI-registrering. Når der så er to providers der begge påstår de kan servere et givet model-navn (Foundry og OpenAI deler gpt-image-*), bliver --provider escape hatchen faktisk relevant — eller registreringsrækkefølgen afgør stille hvem der vinder, hvilket også er fint.
Det interessante er at vi nåede dertil uden at give pks image en eneste ekstra argumenttype. Modellen er navnet. Modellen er valget. Resten finder sig selv.
