AI Prompt DSL
Teknisk referanse for prompt-arkitekturen som styrer all AI-generert tekst i Impulse AI. Denne DSL-en sikrer konsistent kvalitet pa tvers av alle dataprodukter.
For workload-oversikt, modellvalg og kostnader, se AI Pipeline.
Arkitekturoversikt
heading.anchorLabelapps/api/src/ai/shared/├── conventions.ts # Lag 1: Globale regler (tone, grammatikk, skrivestil)├── prompt-builder.ts # Lag 2: PromptStructure DSL + buildPrompt()├── concept-types.ts # Lag 3: Formula/Bottling field definitions├── person-context.ts # Personalisering (opt-in)└── schemas/ # Zod-skjemaer for strukturert outputTre lag med tydelig ansvar og endringsrisiko:
| Lag | Fil | Ansvar | Endringsrisiko |
|---|---|---|---|
| Conventions | conventions.ts | Produktregler som gjelder alle workloads | Hoy — endring treffer ALT |
| Prompt Builder | prompt-builder.ts | Strukturert XML-format og convention-injeksjon | Medium — endrer prompt-struktur |
| Field Definitions | concept-types.ts | Per-felt Formula/Bottling-spesifikasjoner | Varierer — Formula er kritisk, Style er trygt |
Lag 1: Conventions
heading.anchorLabelGlobale regler definert i conventions.ts. Noen injiseres alltid, andre er opt-in.
Alltid injisert
heading.anchorLabelGRAMMAR_RULES injiseres automatisk i alle prompts via buildPrompt(), uavhengig av opt-in:
- Native-sprak (ikke oversatt engelsk)
- Pronomen-agreement (singular/plural)
- Grammatisk korrekthet (kjonn, bøyning)
- Naturlig setningskonstruksjon
- Perspektivkonsistens — alltid andreperson (“du”/“you”), aldri tredjeperson om brukeren
Opt-in konvensjoner
heading.anchorLabel| Konvensjon | Flagg i PromptStructure | Hva den injiserer |
|---|---|---|
| Tone | useStandardTone: true | Persona (varm venn), stemme, do/avoid |
| Vocabulary | vocabularyContext: 'clearing' | 'realization' | 'general' | Godkjente verb, banned ord |
| Safety | useSafety: true | Krise-keyword-deteksjon, eskaleringsregler |
| Acknowledgment | useStandardAcknowledgment: true | Banned fraser, variasjonskrav |
| Writing Style | Auto nar opt-in er aktiv | Anti-AI-speak (banned: “delve”, “tapestry”, “landscape” etc.) |
Workload-dekning
heading.anchorLabelAlle brukervendte workloads bor ha useStandardTone + vocabularyContext. Workloads med ra brukerinput bor ha useSafety:
| Workload | Tone | Vocabulary | Safety | Begrunnelse |
|---|---|---|---|---|
| Classification (enrichment) | x | x | x | Ra brukerinput |
| Classification (analytical) | — | — | — | Intern analyse, ikke brukervennlig tekst |
| Check-in | x | x | x | Ra brukerinput |
| Step Guidance | x | x | — | AI-generert input, ikke ra tekst |
| Session Summary | x | x | — | AI-generert input |
| Narrative | x | x | — | Analytisk, ikke ra tekst |
| Pulse | x | x | — | Analytisk |
| Distillation | x | x | — | Analytisk |
Lag 2: Prompt Builder
heading.anchorLabelbuildPrompt() tar en PromptStructure og produserer ferdig system-prompt i XML-format.
PromptStructure
heading.anchorLabelinterface PromptStructure { // Pakrevd role: PromptRole; // Hvem AI-en ER objective: string; // Hva som skal genereres
// Valgfritt personContext?: PersonContext; // Hvem den snakker TIL (navn, kjonn, alder) context?: string; // Bakgrunn + FieldDefinitions + NEVER-blokk instructions?: string[]; // Steg-for-steg examples?: PromptExample[]; // Few-shot laering constraints?: PromptConstraints; // Lengde, sprak, format
// Convention opt-in useStandardTone?: boolean; useStandardAcknowledgment?: boolean; vocabularyContext?: 'clearing' | 'realization' | 'general'; useSafety?: boolean; useNaturalWritingStyle?: boolean;}Seksjonrekkefølge i generert prompt
heading.anchorLabelbuildPrompt() produserer seksjoner i denne rekkefølgen (optimalisert for Anthropic):
<role>Hvem AI-en er</role><person>Hvem den snakker til (opt-in personalisering)</person><context>Bakgrunn + FieldDefinitions + NEVER-blokk</context><objective>Klar malbeskrivelse</objective><instructions>Steg-for-steg</instructions><examples>Few-shot laering</examples><constraints>Lengde, sprak, format</constraints><conventions> <tone_standard>...</tone_standard> <!-- opt-in --> <vocabulary_standard>...</vocabulary_standard> <!-- opt-in --> <writing_style>...</writing_style> <!-- auto --> <grammar_quality>...</grammar_quality> <!-- ALLTID --></conventions>PersonContext
heading.anchorLabelInjiseres mellom <role> og <context> for a prime modellen med mottakeren. Kun tilgjengelig nar ai_personalization_enabled = true pa profilen.
<person> <name>Jan Fredrik</name> <gender>male</gender> <age>30s</age> <name-usage>Use their name naturally and sparingly</name-usage></person>Hentet via fetchPersonContext() i person-context.ts — eneste sted som leser profildata for AI.
Lag 3: Field Definitions (Formula/Bottling)
heading.anchorLabelDefinert i concept-types.ts. Brukes for a spesifisere hvert output-felt i en workload.
FieldDefinition-struktur
heading.anchorLabelinterface FieldDefinition { name: string; // Feltnavn (brukes i prompt) concept: Concept; // Formula -- LAST, forretningskritisk style?: Style; // Bottling -- fritt tunable variation?: Variation; // Freshness -- for gjentatte sesjoner languageRequired?: boolean; // Default: true}Tre lag med ulik endringsrisiko
heading.anchorLabel| Lag | Interface | Endringsrisiko | Formaal |
|---|---|---|---|
| Formula | Concept | Hoy — forretningskritisk moat | Hva feltet betyr |
| Bottling | Style | Lavt — trygt a iterere | Hvordan det leveres |
| Variation | Variation | Lavt — dynamisk | Freshness pa tvers av sesjoner |
Concept (Formula)
heading.anchorLabelinterface Concept { essence: string; // En-setnings formaal requiredElements: string[]; // MA vaere med i output forbiddenDrift: string[]; // AI-en far IKKE ga hit}forbiddenDrift er der workload-spesifikke perspektivregler horer hjemme. Eksempel fra narrative.ts:
forbiddenDrift: [ // Generiske drifter 'Generic motivational text', // Produktavgrensning 'Situational language -- that is the Pulse product\'s job', // Perspektivregel (forsterker global GRAMMAR_RULES) 'Third-person language about the user -- always use "you"/"du"',]Style (Bottling)
heading.anchorLabelinterface Style { delivery: string[]; // Leveringsinstruksjoner}Variation (Freshness)
heading.anchorLabelBrukes av workloads der brukeren ser samme steg-type flere ganger (f.eks. sesjonsveiledning):
interface Variation { openingApproaches: string[]; // 4 roterende apninger deduplicationInstruction: string; // "Aldri apne likt to ganger"}Block builders
heading.anchorLabelHjelpefunksjoner som kompilerer FieldDefinitions til prompt-tekst:
| Funksjon | Bruk | Tokens |
|---|---|---|
buildCompactFieldBlock(field) | Standard — kompakt format | ~40% faerre |
buildFullFieldBlock(field) | Concept + Style + Variation | Full rendering |
buildMultiFieldContext(fields[]) | Flere felt, separert | Vanligst |
buildNeverBlock(items[]) | Delt forbidden-liste | For cross-field regler |
buildLanguageFieldsDirective(fields, target) | Sprakhaandhevelse | Per-felt |
NEVER-blokker
heading.anchorLabelHver workload definerer en NEVER-array med forbudte monstre som gjelder alle output-felt. Disse injiseres i <context> via buildNeverBlock().
Noen regler er universelle (gjentar seg i flere workloads):
| Regel | Narrative | Pulse | Distill | Summary | Classif |
|---|---|---|---|---|---|
| No generic motivation | x | x | x | ||
| No therapy-speak | x | x | x | x | |
| No corporate wellness | x | x | x | ||
| No advice/“you should” | x | x | x | ||
| No metrics/counting | x | x | x | ||
| No passive framing | x | x | x |
Produktspesifikke regler er unike per workload og avgrenser ansvarsomrader:
- Narrative: “No situational language — that is the Pulse product’s job”
- Pulse: “No trajectory language — that is the Narrative product’s job”
- Distillation: “No trajectory language — the Narrative product handles trajectories”
Legge til ny workload
heading.anchorLabel1. Definer Zod-schema
heading.anchorLabel// I schemas/index.ts eller egen filconst MyOutputSchema = z.object({ title: z.string(), body: z.string(),});2. Definer FieldDefinitions
heading.anchorLabelconst MY_CONCEPTS: Record<string, FieldDefinition> = { title: { name: 'TITLE', languageRequired: true, concept: { essence: 'Kort beskrivelse av feltets formaal', requiredElements: ['Element som MA vaere med'], forbiddenDrift: ['Ting AI-en IKKE far gjore'], }, style: { delivery: ['Hvordan AI-en bor levere dette'], }, },};3. Bygg PromptStructure
heading.anchorLabelfunction getMyPromptConfig( languageCode?: LanguageCode, personContext?: PersonContext,): PromptStructure { return { role: { identity: 'You are...', expertise: ['...'], tone: ['Warm', 'Direct'], }, personContext, objective: 'Generate...', context: `${buildMultiFieldContext(Object.values(MY_CONCEPTS))}${buildNeverBlock(MY_NEVER)}`, instructions: [ buildLanguageFieldsDirective(Object.values(MY_CONCEPTS), 'detected_language'), ], constraints: { output: { maxLength: 500, lengthUnit: 'tokens', format: 'json' }, language: languageCode, },
// Convention opt-in -- alle brukervendte workloads bor ha disse: useStandardTone: true, vocabularyContext: 'general', // useSafety: true, // Legg til om workloaden mottar ra brukerinput
metadata: { category: 'my_workload', version: '1.0.0' }, };}Sjekkliste for nye workloads
heading.anchorLabel-
useStandardTone: true(med mindre ren analytisk workload) -
vocabularyContextsatt (clearing/realization/general) -
useSafety: trueom workloaden mottar ra brukerinput -
personContextsendt inn (frafetchPersonContext()) -
forbiddenDriftinkluderer perspektivregel (andreperson) - NEVER-blokk definert med produktavgrensning
- Zod-schema validerer all output
Endringsprinsipper
heading.anchorLabelTrygt a endre
heading.anchorLabelStyle.delivery— leveringsinstruksjoner, tone, tilnaermingVariation.openingApproaches— rotasjonsalternativer- NEVER-elementer — legge til nye forbud
- Convention opt-in — aktivere flere konvensjoner
Krever review
heading.anchorLabelConcept.essence— endrer feltets kjernebetydningConcept.requiredElements— endrer hva som MA vaere medGRAMMAR_RULES— treffer alle workloadsTONE/VOCABULARY— treffer alle opt-in workloads
Aldri
heading.anchorLabel- Fjerne
forbiddenDrift-elementer uten a forstaa hvorfor de ble lagt til - Endre
buildPrompt()seksjonrekkefølge uten Anthropic-testing - Fjerne convention opt-in fra eksisterende workloads