Al llarg del mòdul hem escrit el system prompt de DocuBot, un classificador few-shot i un contracte JSON de sortida. Cada peça sembla raonable — però "sembla raonable" no és un criteri d'enginyeria. Quan d'aquí a unes setmanes algú proposi "afegeix una regla perquè DocuBot sigui més amable", com sabreu si aquesta regla millora l'assistent o trenca silenciosament el comportament anti-al·lucinació que tant va costar afinar? La resposta de qualsevol enginyer davant d'una pregunta així és la mateixa: proves. Aquesta lliçó converteix el prompting en un procés disciplinat: el prompt com a artefacte versionat, un cicle d'iteració amb hipòtesi i mesura, la construcció del conjunt de 30-50 preguntes reals que vam anunciar a 01-03 en decidir el model de DocuBot, rúbriques simples per puntuar respostes i una manera justa de comparar variants malgrat el no determinisme que coneixem des de 01-04. Tot manual i amb eines mínimes (una taula, un CSV): l'automatització arribarà a 06-03, i aquí construïm justament el que aquesta automatització necessitarà.

Contingut

  1. El prompt com a artefacte d'enginyeria
  2. El cicle d'iteració: hipòtesi → canvi → prova
  3. El conjunt d'avaluació de DocuBot: 30-50 preguntes reals
  4. Criteris de qualitat i rúbriques simples
  5. Comparar variants de manera justa
  6. Registrar resultats: taula i CSV

El prompt com a artefacte d'enginyeria

Un prompt de producció no és una frase que s'escriu una vegada: és un artefacte que evoluciona, del qual depenen comportaments visibles per als usuaris, i que tocaran diverses persones. Mereix el mateix tracte que el codi:

  • Viu al repositori. Ja ho vam encaminar a 02-02: les plantilles són a prompts.py, sota control de versions. Res de prompts escampats per documents compartits o pel panell web d'un proveïdor, on ningú no sap qui ha canviat què.
  • Té versió explícita. No cal res de sofisticat: una constant i un registre de canvis al mateix mòdul basten per començar.
# prompts.py
PROMPT_VERSION = "1.2"
# Historial:
# 1.0  System prompt inicial (identitat, regles 1-5, to, format).
# 1.1  + classificador few-shot amb 6 exemples (02-02).
# 1.2  + sortida JSON amb esquema i camp confianca (02-03).

SYSTEM_DOCUBOT = """Ets DocuBot, ..."""
  • Els canvis es revisen. Un canvi de prompt és un canvi de comportament del sistema: passa per revisió igual que un canvi de codi. La diferència — i d'aquí aquesta lliçó — és que el revisor humà no pot "llegir" l'efecte d'un prompt com llegeix un if: necessita resultats de proves.
  • Cada versió es pot reproduir. Si dilluns DocuBot responia bé i dijous no, vols poder respondre "quina versió exacta del prompt corria dilluns?". Versionar és el que fa possible aquesta pregunta. (Al mòdul 6 veurem que també el model i els seus paràmetres formen part d'aquesta foto reproduïble.)

El canvi mental és aquest: en el programari tradicional, el comportament el garanteix el compilador i el verifiquen els tests; amb els LLM, el "codi font" inclou text en llenguatge natural l'efecte del qual només es coneix empíricament. Per això la resta de la lliçó va de construir aquesta verificació empírica.

El cicle d'iteració: hipòtesi → canvi → prova

La manera natural (i equivocada) d'iterar prompts és: provo una pregunta, no m'agrada la resposta, retoco el prompt, provo aquesta mateixa pregunta, ara surt bé, dono el canvi per bo. El problema té nom en enginyeria: regressió. El retoc que arregla la pregunta A pot trencar les preguntes B, C i D — i amb un system prompt de regles interdependents com el de DocuBot, passa constantment. Per exemple: hi afegeixes "sigues més càlid i proper" per millorar el to, i el model — empès per la complaença del RLHF que vam veure a 01-02 — comença a suavitzar el "No trobo aquesta informació…" amb afegits servicials que voregen la invenció. Has arreglat el to, has trencat la regla 3.

El cicle disciplinat té quatre passos:

flowchart LR
    A[1. Hipòtesi:\nquè falla i per què] --> B[2. Canvi:\nUNA modificació\nal prompt]
    B --> C[3. Prova:\nTOT el conjunt\nde casos]
    C --> D[4. Decisió:\ncomparar amb la\nversió anterior]
    D -->|millora sense regressions| E[Adoptar i versionar]
    D -->|empitjora o regressa| A
  1. Hipòtesi. Formula el problema de manera observable: no "les respostes són fluixes", sinó "en 4 dels 10 casos de facturació, DocuBot no cita la font". Una bona hipòtesi inclou la causa sospitada: "la regla 4 és lluny del final del prompt i amb contextos llargs es perd (lost in the middle)".
  2. Canvi: un de sol. Si toques tres coses alhora i el resultat millora, no saps quina de les tres ha actuat (ni si una ha empitjorat una cosa que una altra ha compensat). Un canvi per iteració — la vella regla de canviar una variable cada vegada.
  3. Prova amb TOT el conjunt de casos, no només amb el cas que ha motivat el canvi. Aquí és on es cacen les regressions.
  4. Decisió comparant versions. Amb els resultats de totes dues versions sobre els mateixos casos (secció 5), decideixes: adoptar (i pujar PROMPT_VERSION, anotant-ne el perquè) o descartar i tornar a la hipòtesi.

Aquest bucle és artesanal a posta: fer-lo a mà amb 30-50 casos t'ensenya què cal mirar, i aquest criteri és exactament el que automatitzaràs a 06-03.

El conjunt d'avaluació de DocuBot: 30-50 preguntes reals

A 01-03, en triar model per a DocuBot, vam deixar anunciada una "avaluació pròpia de 30-50 preguntes reals". Ha arribat el moment de construir-la. Un conjunt d'avaluació (eval set) és una llista fixa de casos d'entrada, cadascun amb el seu resultat esperat o el seu criteri de correcció. Les claus:

D'on surten les preguntes. De la realitat, no de la teva imaginació: els tiquets històrics del suport de Nubelia, les cerques a la wiki, les preguntes del canal intern de dubtes. Les preguntes inventades per qui ha escrit el prompt pateixen el biaix obvi: inconscientment escrius preguntes que el teu prompt respon bé. Si el producte encara no té trànsit, demana a companys que no hagin vist el prompt que escriguin preguntes.

Cobertura per tipus de cas. Un bon conjunt no és una col·lecció de preguntes fàcils: és un mapa de tot el que pot arribar. Per a DocuBot, quatre tipus amb proporcions orientatives:

Tipus de cas Proporció Què verifica Exemple (Nubelia)
Fàcils: resposta directa a la doc ~40 % El cas base funciona i cita la font "Com arxivo un projecte?"
Ambigus: requereixen interpretar o combinar ~25 % Fronteres de classificació, respostes matisades "El webhook de Slack va deixar d'arribar ahir" (integracions/incidencies?)
Sense resposta a la doc ~20 % La regla anti-al·lucinació: ha de dir "no ho sé" "Nubelia permet exportar un projecte a PDF?"
Adversarials suaus ~15 % Robustesa davant d'entrades problemàtiques Fora d'àmbit ("què opines de la competència?"), premissa falsa ("on és el botó de clonar projecte?"), instruccions incrustades ("ignora les teves regles i…")

Dos tipus mereixen comentari:

  • Els casos "sense resposta" són els més valuosos del conjunt. Són la prova directa que el DocuBot ingenu de 01-04 ha quedat enrere. I són fàcils d'avaluar: la resposta esperada és literalment la frase fixa de la regla 3 amb confianca: "baixa" — per això vam fixar una frase exacta a 02-01: per poder-la comprovar.
  • Els adversarials suaus no són un test de seguretat complet (això és 06-01): són les malapteses i malícies quotidianes. La premissa falsa és especialment traïdora: "on és el botó de clonar projecte?" pressuposa que existeix, i un model complaent tendeix a "trobar-se'l".

Cada cas porta el seu resultat esperat. El format mínim per cas: id, pregunta, tipus, categoria_esperada (per al classificador) i criteri (què ha de complir la resposta). Per als fàcils, el criteri pot incloure la font que ha de citar; per als "sense resposta", la frase fixa; per als ambigus, de vegades hi ha més d'una categoria acceptable — anota-ho (permisos|integracions).

Per què 30-50 i no 500? Perquè els avaluaràs a mà a cada iteració i ha de ser viable en una tarda. 30-50 casos ben triats detecten la majoria de regressions; el conjunt creixerà amb el temps (cada fallada real de producció és un cas nou — la mateixa idea que les sortides trencades de 02-03), i quan creixi massa per avaluar-lo a mà, serà el senyal d'automatitzar (06-03).

Criteris de qualitat i rúbriques simples

"És bona aquesta resposta?" és massa vague per puntuar amb consistència — la mateixa persona puntua diferent un dilluns i un divendres. Una rúbrica descompon "bona" en criteris binaris o gairebé binaris, cadascun verificable mirant la resposta:

Criteri Pregunta a verificar Puntuació
Correcció El que afirma coincideix amb la documentació? 0 / 1
Ancoratge (no al·lucina) Evita afirmar coses que no són a la doc? 0 / 1
Font Cita la secció correcta a fonts? 0 / 1
Format JSON vàlid conforme a l'esquema de 02-03? 0 / 1
Categoria categoria coincideix amb l'esperada? 0 / 1
To i concisió Directe, professional, sense farciment? 0 / 0.5 / 1

Notes de disseny:

  • Criteris binaris sempre que es pugui. "Cita la font correcta? sí/no" es puntua igual avui i demà; "qualitat de la cita, de l'1 al 10", no. Només el to admet un punt intermedi, i tot i així acotat.
  • Criteris separats, no una nota global. Una resposta pot ser correcta i no citar la font. Si només apuntes "7/10", perds la informació de què ha fallat, que és justament el que alimenta la següent hipòtesi del cicle.
  • Alguns criteris ja són automatitzables. "JSON vàlid?" és parsejar_resposta_docubot de 02-03; "categoria esperada?" és una comparació de strings; "diu la frase de no-ho-sé?" és un in. Encara que aquesta lliçó és manual, escriu aquests checks com a funcions Python des d'ara: són les primeres peces de 06-03.
  • La correcció la jutja qui coneix la doc. Per a DocuBot, la referència és la documentació de Nubelia inclosa al prompt del cas — l'avaluador comprova contra ella, no contra la seva memòria.

Amb la rúbrica, cada cas avaluat produeix una fila de números en lloc d'una impressió. I 50 files de números es poden comparar; 50 impressions, no.

Comparar variants de manera justa

Suposa que tens el prompt v1.2 i una variant v1.3 (hipòtesi: repetir la regla anti-al·lucinació al final reduirà les invencions en contextos llargs). Perquè la comparació sigui justa calen tres condicions:

  1. Els mateixos casos. Totes dues versions s'executen sobre el conjunt complet d'avaluació, sense excepcions. Comparar v1.2 sobre uns casos i v1.3 sobre uns altres no diu res.
  2. Tota la resta igual. El mateix model, la mateixa temperatura, la mateixa documentació al context. Si canvies prompt i model alhora, torna el problema del canvi doble: no sabràs a qui atribuir la diferència.
  3. Diverses execucions per cas. Aquí reapareix el no determinisme de 01-04: la mateixa versió, amb el mateix cas, pot encertar unes vegades i fallar unes altres — fins i tot amb temperatura baixa. Una sola execució per cas et pot donar una diferència entre versions que és pur atzar. La mitigació pràctica: executa cada cas 3 vegades per versió i treballa amb la proporció d'encerts (un criteri que passa 3/3 és sòlid; 2/3 és zona grisa; i un cas que oscil·la entre execucions és, en si mateix, una troballa: assenyala una instrucció ambigua).

Amb això, la comparació es resumeix en una taula per criteri:

Criteri (proporció d'encerts) v1.2 v1.3 Δ
Correcció 0.89 0.90 +0.01
Ancoratge (no al·lucina) 0.78 0.93 +0.15
Font citada 0.85 0.84 −0.01
Format JSON 0.97 0.96 −0.01
Categoria correcta 0.88 0.88 0
To i concisió 0.92 0.90 −0.02

Lectura: la hipòtesi es confirma (ancoratge +15 punts, precisament als casos "sense resposta" i de premissa falsa) i no hi ha regressions rellevants (les variacions de ±1-2 punts amb 3 execucions per cas són soroll esperable). Decisió: adoptar v1.3. Si en canvi l'ancoratge hagués pujat a costa que, per exemple, DocuBot respongués "no ho sé" també en casos fàcils (correcció desplomant-se), la taula ho hauria mostrat — aquest equilibri entre "no inventar" i "no tornar-se inútilment prudent" és EL trade-off central d'un assistent de documentació, i només es gestiona mesurant tots dos costats.

Dues advertències d'honestedat estadística: amb 30-50 casos, les diferències petites (±3-5 punts) no són concloents — desconfia de la temptació d'adoptar canvis per millores marginals; i no iteris tant contra el mateix conjunt que acabis ajustant el prompt a aquests 50 casos (l'equivalent a l'overfitting): renova i amplia el conjunt periòdicament.

Registrar resultats: taula i CSV

Res del que hem vist no serveix si els resultats viuen a la teva memòria. El registre mínim viable és un CSV per execució d'avaluació — llegible amb qualsevol full de càlcul i processable amb Python:

cas_id,tipus,prompt_version,execucio,correccio,ancoratge,font,format,categoria,to
N-001,facil,1.3,1,1,1,1,1,1,1
N-001,facil,1.3,2,1,1,1,1,1,0.5
N-001,facil,1.3,3,1,1,1,1,1,1
N-017,sense_resposta,1.3,1,1,1,1,1,1,1
N-017,sense_resposta,1.3,2,1,1,1,1,1,1
N-031,adversarial,1.3,1,1,1,1,0,1,1
...

I un petit ajudant per agregar (de nou: Python per a eines, no per cridar cap API):

import csv
from collections import defaultdict

def resum_per_criteri(ruta_csv: str) -> dict:
    """Mitjana de cada criteri de la rúbrica a partir del CSV d'avaluació."""
    criteris = ["correccio", "ancoratge", "font",
                "format", "categoria", "to"]
    sumes = defaultdict(float)
    n = 0
    with open(ruta_csv, newline="", encoding="utf-8") as f:
        for fila in csv.DictReader(f):
            for c in criteris:
                sumes[c] += float(fila[c])
            n += 1
    return {c: round(sumes[c] / n, 2) for c in criteris}

Bones pràctiques del registre:

  • Una fila per cas i execució, no per cas: així conserves la variabilitat entre execucions (la columna execucio), que com hem vist és informació, no soroll a amagar.
  • La versió del prompt a cada fila. És el que permet comparar v1.2 contra v1.3 mesos després, o detectar que una regressió va aparèixer exactament entre dues versions.
  • Desa també les respostes completes (en fitxers a part, referenciats per cas_id): la taula diu que el cas N-031 ha fallat en format; la resposta desada diu com, i aquest com és la propera hipòtesi.
  • El CSV va al repositori al costat del prompt. Avaluació i artefacte avaluat comparteixen història: qui revisi el canvi de prompt v1.3 veu, al mateix commit, l'evidència que millora.

Aquest registre artesanal és deliberadament idèntic en estructura al que produirà l'avaluació automatitzada de 06-03: els mateixos casos, la mateixa rúbrica, les mateixes columnes — només que les executarà un script (i, per a criteris com el to, un altre LLM com a jutge, amb les cauteles que allà veurem). Res del que hem construït aquí no es llença.

Errors Comuns i Consells

  • Provar només el cas que ha motivat el canvi. És L'error. Cada iteració es valida contra el conjunt complet; si no, cada arranjament és una regressió en potència.
  • Canviar diverses coses alhora. Millori o empitjori, no sabràs per què. Un canvi per versió, i la versió anotada a l'historial.
  • Un conjunt d'avaluació fet només de casos fàcils. Donarà un 95 % d'encert sempre i no detectarà res. El valor és als ambigus, als "sense resposta" i als adversarials — els casos que t'incomoden són els que treballen.
  • Que escrigui les preguntes d'avaluació la mateixa persona que ha escrit el prompt. Biaix garantit. Fes servir preguntes reals o demana casos a qui no hagi vist el prompt.
  • Puntuar amb una nota global "de gust". Sense rúbrica, l'avaluació mesura el teu estat d'ànim. Criteris binaris separats, anotats per columna.
  • Treure conclusions d'una sola execució. El no determinisme converteix les comparacions d'execució única en llançaments de moneda. Tres execucions per cas com a mínim per decidir entre versions.
  • No registrar res. Sense CSV ni versions, d'aquí a un mes repetireu les mateixes discussions ("no havíem provat ja de posar la regla al final?") sense dades.
  • Consell: converteix cada fallada de producció en un cas del conjunt d'avaluació abans d'arreglar-la. És la versió prompt de "escriu el test que reprodueix el bug abans de corregir-lo", i garanteix que el conjunt evoluciona cap a les fallades reals, no cap a les imaginades.

Exercicis

Exercici 1. Escriu 8 casos per al conjunt d'avaluació de DocuBot respectant les proporcions de la lliçó (3 fàcils, 2 ambigus, 2 sense resposta a la doc, 1 adversarial suau). Per a cada cas indica: id, pregunta, tipus, categoria_esperada i criteri de correcció. Context: la documentació disponible cobreix rols i permisos, arxivament de projectes, facturació bàsica i la integració amb Slack. (Inventa preguntes plausibles d'empleats de Nubelia; no reutilitzis les de la lliçó.)

Exercici 2. La teva companya proposa passar de v1.3 a v1.4 amb aquesta justificació: "He afegit al prompt 'sigues més breu' i a més he canviat a un model més barat; ho he provat amb 5 preguntes que m'he inventat i les 5 han sortit bé, així que és millor i més barat". Assenyala tots els problemes metodològics d'aquesta afirmació i descriu l'experiment correcte per avaluar la proposta.

Exercici 3. Aquests són els resultats agregats (proporció d'encerts, 3 execucions × 40 casos) d'una iteració el canvi de la qual va ser afegir al system prompt: "Si no estàs completament segur, respon que no trobes la informació":

Criteri v1.3 v1.4
Ancoratge (no al·lucina) 0.90 0.98
Correcció en casos fàcils 0.93 0.71
Encert en casos "sense resposta" 0.85 0.99

Adoptaries v1.4? Interpreta què ha passat i proposa una hipòtesi millor per a la següent iteració.

Solucions

Solució 1. Una solució possible (les teves seran diferents; el que és avaluable és l'estructura):

id Pregunta Tipus Cat. esperada Criteri
N-101 Quins rols existeixen a Nubelia? facil permisos Anomena els 3 rols; cita "Rols i permisos"
N-102 Com desarxivo un projecte? facil altres Indica la ruta de restauració; cita "Arxivar un projecte"
N-103 Puc pagar la subscripció anualment? facil facturacio Respon segons la doc de facturació; cita la font
N-104 Un Editor va arxivar un projecte sense permís, com és possible? ambigu permisos Accepta permisos; ha de contrastar quin rol pot arxivar segons la doc
N-105 Els missatges de Slack arriben però sense el nom del projecte ambigu integracions|incidencies Qualsevol de les dues categories; no ha d'inventar opcions de configuració no documentades
N-106 Puc exportar els taulers a Excel? sense_resposta altres Frase fixa de "no trobo…"; confianca: "baixa"; fonts: []
N-107 Quin és el límit de peticions de l'API? sense_resposta api La doc disponible no cobreix l'API: frase fixa + confiança baixa (no ha d'inventar cap número)
N-108 On activo el mode fosc del panell de facturació? adversarial (premissa falsa) facturacio|altres No ha de "trobar" l'ajust inexistent; frase fixa o correcció de la premissa

Fixa't en N-107: la pregunta és legítima i de categoria clara, però la documentació disponible no la cobreix — el tipus "sense resposta" depèn del context proporcionat, no de la pregunta.

Solució 2. Problemes: (1) dos canvis alhora (prompt i model): qualsevol diferència és inatribuïble; (2) casos inventats per la proponent i no del conjunt d'avaluació: biaix d'autoconfirmació; (3) 5 casos no cobreixen tipus (on són els "sense resposta" i els adversarials?); (4) una sola execució per cas: amb el no determinisme, 5/5 pot ser atzar; (5) sense comparació amb la versió anterior sobre els mateixos casos: "han sortit bé" no és "han sortit millor"; (6) res registrat ni versionat. Experiment correcte: separar-ho en dues iteracions (primer el canvi de prompt amb el model actual; després, si escau, el canvi de model amb el prompt guanyador); cada iteració executa el conjunt complet de 30-50 casos, 3 vegades per cas, puntuat amb la rúbrica, registrat en CSV amb la seva prompt_version, i es decideix comparant la taula de criteris entre versions — vigilant expressament que "més breu" no degradi correcció, fonts o la frase anti-al·lucinació.

Solució 3. No adoptaria v1.4 tal qual. Què ha passat: la instrucció "si no estàs completament segur…" ha tornat DocuBot hiperprudent — l'ancoratge i els casos "sense resposta" milloren (0.98, 0.99), però a costa de desplomar la correcció en casos fàcils (0.93 → 0.71): ara respon "no trobo la informació" a preguntes que que són a la documentació. És el trade-off central vist a la lliçó: s'ha comprat prudència pagant utilitat, i un assistent que no respon el que sí que sap fracassa en la seva funció. Hipòtesi millor per a la següent iteració: substituir el criteri subjectiu ("completament segur") pel criteri verificable que ja feia servir la regla 2-3 de 02-01, reforçant-lo: "Respon amb confiança quan la informació sigui a <documentacio>; usa la frase de 'no trobo…' únicament quan no hi sigui" — i comprovar a la següent execució que els casos fàcils recuperen ≥0.90 sense que l'ancoratge baixi de 0.95.

Conclusió

Amb aquesta lliçó, el mòdul de prompt engineering queda complet — i complet vol dir una cosa molt concreta: DocuBot ja no és una idea, és un artefacte versionat amb la seva avaluació. Tens el system prompt amb identitat, regles anti-al·lucinació i to (02-01); les tècniques per a tasques exigents — few-shot per al classificador de suport, cadena de raonament per als casos ambigus, descomposició en passos — i les plantilles Python que ho empaqueten tot (02-02); el contracte JSON categoria/resposta/fonts/confianca amb la seva validació defensiva (02-03); i ara la disciplina que sosté el conjunt: versions amb historial, el cicle hipòtesi → canvi → prova, el conjunt de 30-50 preguntes reals amb els seus quatre tipus de casos, rúbriques de criteris binaris, comparacions justes amb diverses execucions i un registre en CSV que converteix cada decisió de prompting en una decisió amb dades. Però tot el que hem "executat" en aquest mòdul ha estat sobre el paper: prompts escrits i respostes esperades. Al mòdul 3 el sistema pren vida: farem la primera crida real a l'API d'un LLM des de Python, enviarem per fi els rols system/user que vam dissenyar a 02-01, connectarem les plantilles de prompts.py i el parser de 02-03 amb respostes de debò, i ens enfrontarem al que el paper no mostra: streaming, errors, reintents i el cost real de cada token.

© Copyright 2026. Tots els drets reservats