A la lliçó anterior vam fixar el system prompt v1 de DocuBot i vam aprendre a estructurar un prompt en parts ben delimitades. Amb això cobrim les tasques directes: preguntar, resumir, respondre amb context. Però DocuBot té al davant tasques més fines — per exemple, classificar cada pregunta de suport de Nubelia per adreçar-la a l'equip adequat — on una bona instrucció no basta: el model necessita veure exemples, o necessita espai per raonar abans de respondre, o la tasca és senzillament massa gran per a un sol prompt. Aquesta lliçó presenta les tres tècniques fonamentals del prompting — few-shot, cadena de raonament i descomposició en passos — i acaba convertint els nostres prompts en plantilles Python reutilitzables, el format en què viatjaran al mòdul 3 quan comencem a cridar l'API des de codi. Seguim sense tocar cap API: Python apareix només per construir el text dels prompts.
Contingut
- Zero-shot: la tècnica per defecte
- Few-shot: ensenyar amb exemples
- Cadena de raonament: donar espai per pensar
- Descomposició de tasques: prompt chaining conceptual
- Plantilles de prompts en Python
- Taula comparativa: quina tècnica usar en cada cas
Zero-shot: la tècnica per defecte
Zero-shot vol dir demanar la tasca sense mostrar cap exemple resolt: només instruccions. Tot el que vam fer a 02-01 era zero-shot. Gràcies al fine-tuning amb instruccions que vam veure a 01-02, els models actuals resolen així una quantitat enorme de tasques: resumir, traduir, respondre amb context, extreure dades evidents.
Prenguem la nova tasca de DocuBot: classificar preguntes de suport de Nubelia en categories per enrutar-les. Versió zero-shot:
Classifica la pregunta de suport de Nubelia següent en UNA d'aquestes categories: facturacio, permisos, integracions, api, incidencies, altres. Respon únicament amb el nom de la categoria. <pregunta> No aconsegueixo que la meva companya vegi el tauler del projecte Atlas tot i que li vaig enviar la invitació. </pregunta>
Resposta esperada: permisos. I per a molts casos funcionarà. El problema apareix a les fronteres entre categories, que les instruccions no poden acabar de definir amb paraules:
- "Per què m'heu cobrat dues vegades aquest mes?" →
facturaciooincidencies? (És un possible error, però de cobrament.) - "El webhook de Slack va deixar d'arribar ahir" →
integracions,apioincidencies?
Podries intentar cobrir cada frontera amb més regles escrites ("si és un error relacionat amb cobraments, fes servir facturacio; si…"), però les regles es multipliquen, es contradiuen i mai no ho cobreixen tot. Quan notis que estàs escrivint el cinquè paràgraf de matisos, és el senyal de canviar de tècnica.
Few-shot: ensenyar amb exemples
Few-shot consisteix a incloure al prompt diversos exemples resolts (típicament de 2 a 8) abans de l'entrada real. El model, que com vam veure a 01-02 és una màquina de continuar patrons, capta dels exemples matisos que costaria verbalitzar: on són les fronteres, quin format exacte vols, quin to. És la mateixa tasca de classificació, ara amb exemples triats precisament a les fronteres difícils:
Classifica la pregunta de suport de Nubelia en UNA d'aquestes categories:
facturacio, permisos, integracions, api, incidencies, altres.
Respon únicament amb el nom de la categoria.
Exemples:
Pregunta: Com descarrego la factura de març?
Categoria: facturacio
Pregunta: Per què m'heu cobrat dues vegades aquest mes?
Categoria: facturacio
Pregunta: La pàgina de taulers triga més d'un minut a carregar-se des d'ahir.
Categoria: incidencies
Pregunta: El webhook que vaig configurar cap a Slack ha deixat d'enviar missatges.
Categoria: integracions
Pregunta: Quin límit de peticions per minut té l'endpoint de tasques?
Categoria: api
Pregunta: Teniu descomptes per a ONG?
Categoria: altres
Pregunta: {pregunta_usuari}
Categoria:Fixa't en les decisions de disseny, perquè triar els exemples és el 90 % del few-shot:
- Els exemples defineixen les fronteres, no el centre. "Com descarrego la factura?" sola no aporta gairebé res (zero-shot ja l'encerta); l'exemple valuós és "m'heu cobrat dues vegades" →
facturacio, que resol per demostració l'ambigüitat facturació/incidència. Igual que el webhook de Slack →integracions(i noapiniincidencies). - Cobreix totes les categories si pots, o com a mínim les conflictives. Un few-shot on 5 de 6 exemples són
facturacioesbiaixa el model cap a aquesta etiqueta (els models són sensibles a la distribució i fins i tot a l'ordre dels exemples; convé barrejar-los). - El format dels exemples ÉS el format de la sortida. Com que cada exemple acaba en
Categoria: <etiqueta>i res més, el model continuarà el patró amb l'etiqueta i prou. El few-shot és també la manera més eficaç de fixar format — idea que reapareixerà amb els JSON de la lliçó 02-03. - Els exemples han de ser correctes i ficticis però realistes. Un exemple mal etiquetat ensenya l'error amb la mateixa eficàcia que un de bo ensenya l'encert.
- Cada exemple costa tokens a cada crida (recorda els costos de 01-04). Sis exemples curts són ~150 tokens: irrellevant. Cinquanta exemples llargs a cada classificació, no. Comença amb 3-5 i afegeix-hi només els que corregeixin errors observats.
Quan usar few-shot en lloc de zero-shot? Regla pràctica:
| Situació | Tècnica |
|---|---|
| Tasca comuna i ben definida (resumir, traduir, respondre amb context) | Zero-shot |
| Categories o criteris amb fronteres difuses | Few-shot |
| Format de sortida molt específic o inusual | Few-shot |
| To/estil difícil de descriure amb adjectius | Few-shot (mostres de l'estil) |
| El prompt zero-shot falla en casos concrets identificables | Few-shot amb aquests casos com a exemples |
Cadena de raonament: donar espai per pensar
Recorda la mecànica de 01-02: el model genera token a token, i cada token es recolza en els anteriors. Si obligues DocuBot a respondre facturacio com a primer i únic token, tota la "deliberació" ha de cabre en una sola predicció. La tècnica de cadena de raonament (chain-of-thought, CoT) consisteix a demanar-li que raoni per escrit abans de donar la resposta final: cada pas de raonament generat passa a formar part del context del següent, i la conclusió es recolza en ells. És, literalment, donar-li espai per pensar.
Exemple amb un cas ambigu de Nubelia:
Classifica la pregunta de suport en UNA categoria: facturacio, permisos, integracions, api, incidencies, altres. Primer, en una secció "Anàlisi:", raona breument: què demana l'usuari, quines categories podrien aplicar-se i per què en tries una. Després, en una línia final "Categoria:", escriu només l'etiqueta. <pregunta> Des que hem connectat Nubelia amb el nostre SSO corporatiu, els usuaris nous entren com a Lectors i no els puc pujar a Editors. </pregunta>
Resposta esperada:
Anàlisi: l'usuari esmenta la integració amb SSO, però el seu problema real és que no pot canviar el rol dels usuaris nous: és una qüestió de gestió de rols. La integració funciona (els usuaris entren); el que falla o es desconeix és l'assignació de permisos. Dubto entre integracions i permisos; el problema accionable és de permisos. Categoria: permisos
Punts clau per usar bé el CoT:
- L'ordre importa: raonament primer, resposta després. Si demanes "la categoria i després una justificació", el model decideix primer (sense espai per pensar) i després racionalitza la seva elecció — la justificació no haurà influït en la resposta. El CoT només funciona si la conclusió va al final.
- Estructura el raonament. "Raona pas a pas" funciona; funciona millor dir-li quins passos: "què demana l'usuari, quines categories podrien aplicar-se, per què en tries una". I delimita la resposta final amb un marcador fix (
Categoria:) per poder-la extreure de manera fiable. - El CoT té cost. Més tokens de sortida = més latència i més despesa (01-04). Reserva'l per a tasques amb raonament real: casos ambigus, decisions amb diversos factors, aritmètica, anàlisi d'errors. Per a "com descarrego la factura?" és llençar diners.
- Nota de context: els models més recents incorporen modes de raonament natius que fan això internament. La tècnica segueix sent vàlida i necessària com a eina de prompting — i entendre-la t'explica per què aquests modes existeixen.
- CoT i few-shot es combinen bé: exemples que inclouen el raonament escrit ensenyen alhora el criteri i el procés.
Descomposició de tasques: prompt chaining conceptual
Hi ha peticions que cap prompt únic no resol bé. Pensa en el flux complet que Nubelia vol per a DocuBot al web de suport:
- Classificar la pregunta de l'usuari (de què va?).
- Amb la categoria, seleccionar la documentació rellevant.
- Redactar la resposta basada en aquesta documentació.
- Comprovar que la resposta compleix les regles (cita la font, no inventa).
Ficar-ho tot en un megaprompt ("classifica, i segons la categoria busca en aquests 12 documents, i redacta, i revisa que…") produeix resultats mediocres: massa instruccions competint (el problema de sobrerestricció de 02-01), un context enorme amb risc de "lost in the middle" (01-04), i una fallada en qualsevol pas arruïna el conjunt sense que sàpigues quin ha fallat.
L'alternativa és l'encadenament de prompts (prompt chaining): dividir la tasca en passos, cadascun amb el seu propi prompt enfocat, on la sortida d'un pas és l'entrada del següent:
flowchart LR
A[Pregunta de l'usuari] --> B[Prompt 1:\nclassificar]
B -->|categoria| C[Seleccionar docs\nd'aquesta categoria]
C -->|context| D[Prompt 2:\nredactar resposta]
D -->|esborrany| E[Prompt 3:\nverificar regles]
E --> F[Resposta final]Avantatges per al desenvolupador — i fixa't que són els mateixos que els de descompondre funcions en codi:
- Cada prompt és simple i fa una sola cosa: el de classificar no necessita saber redactar; el de verificar només comprova regles.
- Depurable: si la resposta final és dolenta, inspecciones les sortides intermèdies i localitzes el pas culpable.
- Testejable per parts: pots avaluar el classificador per separat del redactor — això serà or a la lliçó 02-04.
- Optimitzable per parts: el pas de classificar pot fer servir un model més barat i ràpid que el de redactar (criteris de 01-03).
El cost: més crides = més latència total i més complexitat d'orquestració. De moment ens quedem al nivell conceptual i en el disseny dels prompts de cada pas; la "cola d'enganxar" (codi que executa la cadena, gestiona errors i passa sortides a entrades) és matèria del mòdul 3, i la seva evolució — que el mateix model decideixi quin pas executar — són els agents del mòdul 5.
Plantilles de prompts en Python
Fins ara hem escrit els prompts com a text acabat. Però fixa't en el few-shot del classificador: acabava en {pregunta_usuari} — un buit. Un prompt de producció és sempre una plantilla: part fixa (instruccions, exemples) + buits per a allò variable (dades de cada petició). Formalitzar-ho en Python és el pont cap al mòdul 3. Sense crides HTTP ni SDK: funcions que retornen text.
# prompts.py — plantilles de prompts de DocuBot (v1)
SYSTEM_DOCUBOT = """Ets DocuBot, l'assistent intern de documentació \
i suport de Nubelia, una plataforma SaaS de gestió de projectes.
...
(el system prompt v1 complet de la lliçó 02-01)
"""
def prompt_resposta(documentacio: str, pregunta: str) -> str:
"""Construeix el missatge d'usuari per respondre una pregunta
a partir de documentació seleccionada."""
return f"""<documentacio>
{documentacio}
</documentacio>
<pregunta>
{pregunta}
</pregunta>
Recorda: si la resposta no és a <documentacio>, digues exactament
"No trobo aquesta informació a la documentació disponible."."""
CATEGORIES = ["facturacio", "permisos", "integracions",
"api", "incidencies", "altres"]
EXEMPLES_CLASSIFICACIO = [
("Com descarrego la factura de març?", "facturacio"),
("Per què m'heu cobrat dues vegades aquest mes?", "facturacio"),
("La pàgina de taulers triga més d'un minut a carregar-se.", "incidencies"),
("El webhook cap a Slack ha deixat d'enviar missatges.", "integracions"),
("Quin límit de peticions té l'endpoint de tasques?", "api"),
("Teniu descomptes per a ONG?", "altres"),
]
def prompt_classificacio(pregunta: str) -> str:
"""Construeix el prompt few-shot de classificació de preguntes."""
exemples = "\n\n".join(
f"Pregunta: {p}\nCategoria: {c}" for p, c in EXEMPLES_CLASSIFICACIO
)
return f"""Classifica la pregunta de suport de Nubelia en UNA d'aquestes
categories: {", ".join(CATEGORIES)}.
Respon únicament amb el nom de la categoria.
Exemples:
{exemples}
Pregunta: {pregunta}
Categoria:"""Desglossament per a qui comença amb Python:
SYSTEM_DOCUBOTés una constant: el system prompt és estable (lliçó 02-01: asystemallò estable), així que viu com a constant de mòdul, no es reconstrueix cada vegada.- Les f-strings (
f"""...""") interpolen variables dins del text:{pregunta}se substitueix pel valor real. És la forma més simple de plantilla en Python. - Els exemples viuen en una llista de tuples, no incrustats al text. Avantatge enorme: afegir o corregir un exemple és tocar una dada, no editar un bloc de text fràgil; i a 02-04 podrem provar variants amb diferents conjunts d'exemples sense duplicar la plantilla.
- Separació instruccions-dades, ara en codi: la plantilla (instruccions, del desenvolupador) i els arguments (
pregunta,documentacio, de l'usuari) entren per camins diferents i les dades queden sempre dins de delimitadors. No construeixis mai prompts concatenant text d'usuari fora de les seves etiquetes. - Funcions pures: reben dades, retornen un
str. Fàcils de testejar (assert "Com arxivo" in prompt_resposta(doc, "Com arxivo...?")), de versionar a git com qualsevol codi, i llestes per endollar a l'API a 03-01.
Un ús il·lustratiu:
print(prompt_classificacio("No puc convidar un usuari extern"))
# → imprimeix el prompt complet amb els 6 exemples i la pregunta al final,
# a punt per enviar-se al model (mòdul 3).Taula comparativa: quina tècnica usar en cada cas
| Tècnica | Què és | Quan usar-la | Cost extra | Exemple a DocuBot |
|---|---|---|---|---|
| Zero-shot | Només instruccions | Tasques comunes i ben definides | Cap | Respondre preguntes amb documentació al context |
| Few-shot | Instruccions + 2-8 exemples resolts | Fronteres difuses, format exacte, estil difícil de descriure | Tokens d'entrada per crida | Classificar preguntes de suport en 6 categories |
| Cadena de raonament | Raonar per escrit abans de respondre | Ambigüitat real, diversos factors, anàlisi, aritmètica | Tokens de sortida i latència | Decidir la categoria d'un cas frontera SSO/permisos |
| Descomposició (chaining) | Diversos prompts encadenats, sortida → entrada | La tasca té fases diferents o un prompt únic falla/és indepurable | Diverses crides, orquestració | Classificar → seleccionar docs → redactar → verificar |
I es combinen: la cadena de DocuBot farà servir few-shot al pas de classificar i zero-shot al de redactar; el pas de verificar pot usar CoT. Triar tècnica és una decisió per pas, no per sistema.
Errors Comuns i Consells
- Exemples few-shot "de llibre" que no ensenyen res. Si tots els teus exemples són casos obvis que el zero-shot ja encerta, pagues tokens sense guanyar precisió. Els exemples valuosos són els que a tu mateix et costaria classificar a la primera.
- Exemples amb format inconsistent entre si. Si un exemple acaba en
Categoria: permisosi un altre enResposta: la categoria és permisos., el model no sap quin patró continuar. Format idèntic en tots. - Demanar la justificació després de la resposta creient que és CoT. Conclusió primer = racionalització, no raonament. La resposta final sempre al final.
- Aplicar CoT a tot per defecte. En tasques trivials només afegeix cost i latència, i de vegades fins i tot empitjora: el model s'inventa complexitat on no n'hi ha.
- El megaprompt que ho fa tot. Si el teu prompt té tres tasques diferents ("classifica i a més redacta i a més comprova"), gairebé sempre hi sortiràs guanyant si el parteixes en una cadena.
- Construir prompts concatenant strings sense delimitadors (
"Resumeix: " + text_usuari). Reintrodueix el problema instrucció/dada que vam resoldre a 02-01. Les dades, sempre dins de les seves etiquetes i a través dels paràmetres de la plantilla. - Consell: desa les teves plantilles en un mòdul propi (
prompts.py) des del primer dia. Els prompts són codi: es revisen, es versionen i — com veurem a 02-04 — es testegen.
Exercicis
Exercici 1. El classificador few-shot de DocuBot confon sistemàticament aquestes dues preguntes: "L'API retorna 500 des d'aquest matí a /v1/tasques" (hauria de ser incidencies: alguna cosa està trencada) i "Quins codis d'error pot retornar /v1/tasques?" (hauria de ser api: dubte d'ús). Escriu els dos exemples few-shot que afegiries al prompt per corregir-ho i justifica per què aquests.
Exercici 2. Escriu un prompt amb cadena de raonament per a aquest cas de suport de Nubelia: "Vull que els clients externs vegin l'avanç del projecte però sense que puguin veure els costos." El prompt ha d'estructurar el raonament (què necessita l'usuari, quines opcions dóna la documentació, quina hi encaixa) i acabar amb una recomanació delimitada pel marcador Recomanació:. Inclou un bloc <documentacio> inventat amb dues opcions plausibles del producte (per exemple, "convidats amb rol Lector" i "pàgina d'estat pública del projecte").
Exercici 3. Escriu en Python una funció prompt_resum(titol: str, text: str, max_punts: int = 5) -> str que generi un prompt per resumir un document de la wiki de Nubelia en com a màxim max_punts punts, orientat a agents de suport, amb el text delimitat a <document> i la instrucció crítica repetida al final (recorda el "lost in the middle").
Solucions
Solució 1. Exemples a afegir:
Pregunta: L'API retorna error 500 des d'aquest matí a /v1/tasques. Categoria: incidencies Pregunta: Quins codis d'error pot retornar l'endpoint /v1/tasques? Categoria: api
Justificació: són un parell mínim contrastiu — gairebé idèntics en superfície (tots dos esmenten l'API i errors) però amb etiquetes diferents. Col·locats junts ensenyen exactament la frontera que el model confon: una cosa funcionava i s'ha trencat → incidencies; dubte sobre el comportament documentat → api. És l'estratègia general: convertir cada error observat en l'exemple que el corregeix.
Solució 2. Una solució possible:
Ets DocuBot. Un empleat de Nubelia planteja una necessitat d'un client. Analitza la situació fent servir NOMÉS la documentació proporcionada. Estructura la teva resposta així: Anàlisi: (1) què necessita exactament l'usuari, (2) quines opcions de la documentació podrien servir, (3) què ofereix i què no cobreix cadascuna. Recomanació: l'opció triada i la seva limitació principal, en 2 frases. <documentacio> ## Convidats externs Pots convidar usuaris externs amb rol Lector: veuen taulers, tasques i avanç, inclosos els camps de pressupost si el projecte els té visibles. ## Pàgina d'estat del projecte Cada projecte pot publicar una pàgina d'estat de només lectura amb fites i percentatge d'avanç. No mostra tasques, comentaris ni camps de pressupost. </documentacio> <pregunta> Vull que els clients externs vegin l'avanç del projecte però sense que puguin veure els costos. </pregunta>
Resposta esperada (abreujada): l'anàlisi hauria de detectar que el rol Lector exposa els camps de pressupost (no compleix el requisit d'amagar costos) i que la pàgina d'estat mostra l'avanç sense pressupost, i concloure Recomanació: usar la pàgina d'estat del projecte; limitació: els clients no veuran el detall de tasques. El valor del CoT aquí és que obliga a contrastar cada opció amb el requisit "sense costos" abans de triar.
Solució 3.
def prompt_resum(titol: str, text: str, max_punts: int = 5) -> str:
"""Prompt per resumir un document de la wiki de Nubelia."""
return f"""Resumeix el document de la wiki de Nubelia titulat
"{titol}" en un màxim de {max_punts} punts, orientat a un agent
de suport que necessita respondre tiquets. Prioritza passos accionables
i limitacions del producte; omet història i agraïments.
<document>
{text}
</document>
Recorda: màxim {max_punts} punts i només informació present a
<document>."""Claus: max_punts amb valor per defecte s'interpola dues vegades (instrucció inicial i recordatori final), el text va delimitat, i la funció és pura — rep dades i retorna el prompt com a str.
Conclusió
La teva caixa d'eines de prompting ja té fons: zero-shot com a opció per defecte, few-shot per ensenyar fronteres i formats mitjançant exemples ben triats (els del classificador de suport de Nubelia queden fixats a EXEMPLES_CLASSIFICACIO), cadena de raonament per donar al model espai de deliberació abans de la resposta, i descomposició en passos quan la tasca desborda un sol prompt — el disseny en cadena de DocuBot (classificar → seleccionar → redactar → verificar) que anirem materialitzant als propers mòduls. I tot plegat viu ja com a plantilles Python a prompts.py: funcions pures que retornen text, a punt per connectar-se a una API real. Però hi ha un serrell pendent: el classificador retorna una etiqueta en text lliure, i el web de suport de Nubelia necessitarà força més — categoria, resposta, fonts i nivell de confiança — en un format que el codi pugui parsejar sense sorpreses. Aquest és el tema de la propera lliçó: sortides estructurades, o com aconseguir que un model probabilístic retorni JSON en què puguis confiar.
Curs d'IA Generativa i LLMs per a Desenvolupadors
Mòdul 1: Fonaments de la IA generativa
- Què és la IA generativa i per què importa als desenvolupadors
- Com funciona un LLM: tokens, embeddings i atenció
- Panorama de models i proveïdors
- Limitacions i riscos: al·lucinacions, context i costos
Mòdul 2: Prompt engineering
- Anatomia del prompt: rols, instruccions i context
- Tècniques de prompting: few-shot, cadena de raonament i plantilles
- Sortides estructurades: JSON i control de format
- Iteració i avaluació de prompts
Mòdul 3: Integració de LLMs en aplicacions
- Primera integració amb l'API d'un LLM
- Streaming, errors i reintents
- Converses i gestió del context
- Costos, latència i caching
Mòdul 4: RAG - Generació augmentada per recuperació
- Embeddings i cerca semàntica
- Bases de dades vectorials
- Ingesta i chunking de documents
- Construcció d'un pipeline RAG complet
- Avaluació de sistemes RAG
Mòdul 5: Function calling i agents
- Function calling: connectar el LLM amb el teu codi
- De LLM a agent: el bucle de raonament i acció
- Frameworks d'orquestració
