Spring til indhold
DApks-cli-toolboximage-generation

Samme prompt, to modeller: gpt-image-2 lander i pks image

Azure Foundry fik gpt-image-2. Vi tilføjede den til pks image — men ikke som en --provider switch. --model gpt-image-2 finder selv backenden. Her er hvordan sammenligningen mod Gemini ser ud på fire rigtige blog-bannere.

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:

human prompt
3 lines
I just noticed we got gpt image 2 on foundry, could we make our pks image support this together with google as we use now so we can use both going forward

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:

human prompt
1 lines
cant we we do the abstraction based on model instead, default google as now and we can do --model gpt-image-2 and then it finds out which auth/provider can provide the model and that could be foundry, because i assume we could also give it a openai directly and thats a 3th provider, so rather have it being model we specify and based on what we have authenticated we pick the token / url ect?

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å:

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-versionen af pks-brain banneret: en hjerne lavet af stablede indeks-kort med en skarp amber lyssprang fra øverste venstre

gpt-image-2-versionen af pks-brain banneret: samme grundkomposition men mere malerisk og dæmpet, hjerneformen mindre udtalt

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

Gemini-versionen af pks-brain-wiki: en kartotekskuffe trukket ud med faner og messing-håndtag, klare detaljer

gpt-image-2-versionen: samme kartotekskuffe, varmere belysning, mere cinematisk men de navngivne faner er forsvundet

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

Gemini-versionen af pks-brain-graph: fire stakke håndlavet papir bundet med snor i et 2×2 mønster, messing-ankre synlige

gpt-image-2-versionen: samme 2×2 layout, mørkere og mere skattekiste-agtigt, snoren ligner kabler

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

Gemini-versionen af pks-brain-commit-messages: en gammel håndtryk-presse over et ark med 'Conventional Commits' stemplet på, fortællingen er læsbar

gpt-image-2-versionen: samme presse, men 'Conventional Commits'-motivet er væk, det er nu et rent produktshot af maskinen

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:

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.