Agent o solució determinista
- Dos paradigmes, mateixes eines
- Una pregunta a cada tasca
- Tres tipus de problema
- Senyals per decidir
- Tasques deterministes mal delegades
- Per què guanya el determinista
- I si la tasca és única?
- I si la tasca demana judici?
- L’agent escriu l’script
- Donar eines fiables a l’agent
- Usar l’agent per no pensar
- Heurística final
Aquest capítol separa els casos on un agent aporta judici dels casos on una comanda, un script o una eina determinista resolen el problema millor.
Davant d’una tasca de desenvolupament, l’opció per defecte en un flux AI-first és demanar-la a l’agent. Però abans val la pena una pausa breu: la mateixa feina sovint la fa millor un codi determinista — terme paraigua que cobreix scripts (shell, Python), one-liners (sed, awk, jq), eines de refactoring de l’IDE, regex, Makefiles, linters, code generators, consultes SQL, o una funció escrita una sola vegada. Tot el que té un comportament reproduïble i una especificació explícita hi entra. Per concreció, en aquesta secció farem servir sovint la paraula script com a exemple, però la idea aplica a tot el ventall.
Dos paradigmes, mateixes eines
Hi ha dos paradigmes per resoldre una tasca:
- Solució determinista: el flux és definit i previsible. Mateixa entrada, mateixa sortida. El camí és conegut.
- Agent amb LLM: el sistema interpreta la tasca, decideix què fer i ho executa cridant eines (tool calling — vegeu Fonaments de programació amb IA). El flux és dinàmic. El camí és desconegut, però les eines disponibles sí.
L’observació clau — i la més útil per decidir — és que les eines que crida l’agent són les mateixes operacions deterministes que tu podries cridar directament: read_file, bash, grep, edicions de fitxers, git. Hi ha un paral·lelisme net: quan tu treballes deterministament també estàs cridant aquestes mateixes eines del sistema; només que la coreografia — quina eina, en quin ordre, amb quins arguments — surt del teu criteri en lloc del model. Tots dos accediu a la mateixa capa d’eines; el que canvia és d’on ve la decisió.
Això reformula la pregunta “agent o codi determinista?” d’una manera més precisa: de qui ve la coreografia? Quan el camí ja el coneixes tu, la teva és més ràpida, més precisa i sense cost per execució; quan és genuïnament incert, val la pena pagar la del model. Anar deterministe no és renunciar a les eines de l’agent — és cridar-les tu mateix, sense pagar la coreografia.
El problema típic no és triar malament entre els dos paradigmes — és no aturar-se a triar: delegar a l’agent una tasca que era determinista, o intentar codificar amb regles una que demanava judici.
Una pregunta a cada tasca
Puc descriure aquesta tasca com una transformació amb regles clares —
f(input) → output?
- Si la resposta és sí: tens un problema determinista. Vols un script, no l’agent.
- Si la resposta és no: cal preguntar-se per què no — la resposta determinarà si l’agent és realment la millor opció o si el que et falta és entendre el problema.
Tres tipus de problema
- Determinista (formalitzable). Les regles existeixen i les coneixes. Calcular la nota d’un examen, validar un format, executar tests, comptar ocurrències, transformar JSON. La feina és implementar les regles. Posar un agent al mig converteix una funció reproduïble en una resposta plausible.
- Ambigüitat real (cal judici). El problema depèn del context i no té una única resposta correcta. “Refactoritza aquest mòdul perquè respecti el patró de
UserService”, “per què falla aquest test inestable?”, “és segur aquest canvi de schema?”. Codificar totes les heurístiques explícitament és inviable o es desactualitza ràpid. És el cas legítim per a un agent. - Desconeixement temporal del domini. Les regles existeixen, però encara no les coneixes. És el cas més perillós: l’agent produeix sortida raonable, i això elimina la pressió per entendre-ho. La trampa: usar l’agent per evitar pensar, no per raonar millor. L’estratègia correcta és inversa — explora el problema amb l’agent, entén-lo, i un cop el tens clar formalitza-ho en codi.
Senyals per decidir
Els tres tipus es tradueixen en senyals concrets que pots reconèixer al moment.
Senyals que indiquen codi determinista:
- Flux conegut i estable — si pots dibuixar
dades → A → B → resultat, no necessites un agent que ho redescobreixi a cada execució. - Necessites garanties — correctesa, reproduïbilitat, idempotència. Un avaluador d’exàmens no pot retornar resultats lleugerament diferents a cada execució; un LLM, sí.
- Tasca repetitiva i d’alt volum — la pagaràs en temps i tokens cada cop. Un script l’executes infinites vegades a cost zero.
- Latència importa — git hooks, validació en temps real, comprovacions a CI.
- Transformació puntual i mecànica — renombrar, convertir formats, comptar.
Senyals que indiquen agent:
- Composició dinàmica d’eines — “per què falla aquest test?” pot requerir llegir logs, codi, executar de nou amb verbositat, mirar dependències; el camí canvia segons el que trobes.
- Raonament sobre el codi i el context — adaptar un patró d’un mòdul a un altre, decidir què refactoritzar dins una capa, identificar duplicació conceptual.
- Exploració — investigar un codebase nou, prototipar una aproximació abans de comprometre-t’hi, generar alternatives per comparar.
- Tasques d’una sola vegada on escriure el script costaria més que la sessió d’agent més la verificació.
El patró comú del costat agent: el camí no és previsible, però les eines disponibles sí. L’agent decideix la seqüència; les eines (REST, BD, scripts, fitxers) continuen sent codi determinista.
Tasques deterministes mal delegades
Casos on el problema és clarament determinista i, malgrat tot, es delega a l’agent per defecte:
- Renombrar variables, classes o fitxers → eines de refactoring de l’IDE: entenen sintaxi i abast.
- Cerca i substitució estructural →
sed,awk,grep,ripgrep,comby. - Operacions massives sobre fitxers →
find -exec, shell loops,xargs. - Conversió de formats →
jqper a JSON,csvkitper a CSV,pandocper a documents. - Generació de boilerplate a partir d’un esquema → un code generator (Protobuf, OpenAPI, Prisma…) produeix sempre el mateix codi.
- Validació o comptatge →
grep -c, scripts de validació, linters. - Migracions de dades o configuració → scripts amb passos explícits, idempotents i reversibles.
Per què guanya el determinista
Per què invertir cinc minuts a escriure un script — o un one-liner, o configurar un refactor de l’IDE — en lloc de delegar la tasca? Perquè aporta propietats que un agent estructuralment no pot oferir:
- Determinisme. Mateix input, mateixa sortida, sempre. Pots escriure un test que digui “aquest input ha de produir aquest output” i confiar-hi. Amb un agent, aquest test és impossible: dues execucions del mateix prompt poden divergir per temperature, actualitzacions del model, o mostreig estocàstic.
- Auditabilitat abans de l’execució. Llegint deu línies saps exactament què passarà — pots aprovar-ho abans que toqui res. Amb un agent, l’única revisió possible és a posteriori: ja ha tocat fitxers, i et toca examinar el diff per descobrir si ha fet el que volies. Si la tasca era destructiva, ja l’has pagada.
- El codi és l’especificació. No hi ha distància entre intenció i execució. Una instrucció a l’agent és una aproximació en llenguatge natural; el codi de l’agent en pot fer una interpretació diferent. El script no s’interpreta — s’executa.
- Cost de revisió baix. Revisar dotze línies que descriuen una transformació és molt més barat cognitivament que revisar el diff de cinquanta fitxers que aquella transformació ha produït. El script és l’abstracció.
- Persistència i reús. Una sessió d’agent és efímera; un script viu al repositori. La pròxima vegada el cost és zero, i qualsevol membre de l’equip el pot llançar i obtenir el mateix resultat.
- Composabilitat i cost zero per execució. Encaixa amb pipes, Makefiles, cron, git hooks, CI. Sense latència ni tokens: viable a qualsevol freqüència. Un agent no es composa fiablement i no és viable dins d’un git hook o en execucions massives.
Tot plegat es resumeix així: un script captura la solució; un agent reprodueix el procés. Quan el procés és el mateix cada vegada, capturar-lo és sempre millor que reproduir-lo.
I si la tasca és única?
La reusabilitat és una raó forta per formalitzar, però no és l’única. Hi ha casos on una tasca determinista d’una sola vegada s’expressa millor com a comanda o script encara que no la tornis a executar mai més:
- Operacions destructives o irreversibles. Esborrar fitxers en massa, modificar un schema, escriure dades a producció. El valor d’aprovar exactament què passarà abans que passi supera la conveniència de delegar. Una
rmomvla llegeixes en cinc segons; una sessió d’agent que fa el mateix només la pots revisar després — quan ja és massa tard. - Tasques tan petites que descriure-les costa més que fer-les. Un
:%s/foo/bar/g, un find-replace a l’IDE, una comandamv. La latència de l’agent — carregar context, planificar, executar, retornar — ja supera el cost manual de la tasca. - Quan saps exactament què vols i la precisió importa. Una regex o una crida explícita expressen la teva intenció sense marge d’interpretació. L’agent pot decidir que “de pas” arregla quelcom proper, o interpretar l’abast diferent del que esperes — desviacions silencioses molt difícils de detectar.
- Per mantenir l’hàbit i el criteri. Cada vegada que deixes a l’agent una tasca que podries fer reflexivament estàs reforçant el reflex de delegar — i atrofiant la fluïdesa amb les eines que durant dècades han fet aquesta feina millor que cap LLM.
grep,sed,awk,find, regex, refactors de l’IDE: són com un múscul. Sense aquest múscul, no sabràs reconèixer quan una tasca era senzilla — la veuràs sempre des del prompt.
La regla és més matisada que “si es repeteix → script, si no → agent”. Realment és:
Per a problemes deterministes, el camí determinista (script, comanda, refactor) és el bo per defecte. L’agent guanya només quan la fricció de fer-ho deterministement és real — no per defecte.
I si la tasca demana judici?
Hem dit que els problemes amb ambigüitat real són el cas legítim per a l’agent. Però legítim no vol dir automàtic. Hi ha casos on, fins i tot quan la tasca demana judici, la millor opció no és l’agent — ets tu:
- Decisions arquitecturals i de disseny. Triar un patró, definir una interfície pública, decidir on cau la frontera entre dos mòduls. Són judici — però el teu judici, no el del model. Vegeu Qui pren les decisions: la IA és un executor hàbil, no un arquitecte.
- Codi sensible o crític. Lògica de seguretat, manipulació de dades de pagament, criptografia, validació d’entrada. Vols entendre cada línia, no acceptar quelcom plausible. Una vulnerabilitat introduïda per l’agent passa la mateixa revisió superficial que qualsevol altre codi seu — i no la detectaràs llegint el diff.
- Quan tu ets l’únic que té el context. Decisions que depenen d’una conversa amb un client, d’un incident d’ahir a producció, d’un acord verbal de l’equip. L’agent treballa amb el que té al prompt i al codi; el coneixement implícit es perd.
- Quan vols mantenir o construir criteri. Si delegues tot judici al model, no construeixes el criteri que necessites per saber quan delegar amb confiança. Vegeu Per què seguir escrivint codi a mà: cada cop que passes una decisió al model és un cop que no l’has practicat tu — i la fluïdesa amb el sistema es construeix exactament aquí.
- Quan és la teva manera d’entendre el problema. Escriure el codi és sovint l’acte mateix d’entendre. Si saltes aquesta passa, et quedes amb una comprensió superficial — fins que el codi falla i et toca depurar quelcom que mai vas raonar.
El patró general: l’agent és més ràpid implementant; tu ets insubstituïble decidint, sentint el sistema i construint criteri. Quan la tasca toca aquestes tres dimensions, fer-la tu mateix no és lentitud — és la feina.
Productivitat vs aprenentatge
Hi ha una tensió que val la pena nomenar explícitament: productivitat vs aprenentatge. L’agent gairebé sempre guanya en productivitat immediata — fa la feina més ràpid del que la faries tu. Però el cost d’aquella velocitat és el criteri que no construeixes mentre delegues. Cada decisió que passa pel model és una decisió que no has practicat — i el criteri només es construeix prenent-les tu, vivint amb les conseqüències, i veient què falla.
Per a un sènior amb criteri ja construït, la tensió es resol cas a cas: prou judici per delegar amb seguretat el rutinari, prou disciplina per fer-ho a mà quan la decisió pesa o quan toca mantenir la fluïdesa. Per a un estudiant o un junior, la balança s’inverteix: l’aprenentatge és la feina principal. La productivitat immediata que guanyes delegant és una hipoteca contra la teva carrera futura — perquè sense criteri propi, ni tan sols sabràs si el que el model et dóna és correcte. La velocitat del primer any no és res comparada amb el sostre de la teva carrera sencera.
La regla pràctica: demana’t quina inversió estàs fent cada vegada que decideixes delegar. Si el que guanyes és temps i el que perds és criteri que no necessites refrescar — és una bona inversió. Si el que guanyes és temps i el que perds és precisament el criteri que t’està faltant — has fet exactament el contrari del que necessites.
L’agent escriu l’script
La decisió no sempre és “agent o script” — sovint és “l’agent escriu el script”. En lloc de demanar “renombra totes les ocurrències de foo a bar”, demana “escriu-me la comanda sed que renombri totes les ocurrències de foo a bar als fitxers .py”. Obtens el millor dels dos paradigmes:
- La intel·ligència de l’agent aplicada una sola vegada, en un artefacte concret.
- Un script revisable abans d’executar-lo (
--dry-run, sortida pas a pas). - Reusable: la pròxima vegada, ja el tens al repositori.
- Compartible amb l’equip.
És la regla d’or del paradigma:
Si ho reutilitzaràs → formalitza-ho. Si ho exploraràs → usa l’agent.
Quan una exploració amb agent fa visible el camí, el següent pas natural és convertir-lo en codi determinista — no consolidar l’agent com a part permanent del flux.
Donar eines fiables a l’agent
Si saps com fer una tasca de manera determinista, no deixis que l’agent l’endevini estocàsticament — dóna-li l’eina perquè la faci bé.
Pensa en un exemple concret. Demanes a l’agent “comprova si el JSON de configuració és vàlid”. L’agent llegeix el fitxer, raona sobre l’estructura, i et diu que sembla correcte — però ha generat la resposta més plausible, no l’ha verificat. Ara imagina que l’agent, en lloc d’endevinar, crida un validador d’esquema que ja tens al projecte — un script de deu línies que retorna pass/fail amb els errors concrets. El resultat ja no és plausible: és cert. L’agent segueix decidint què fer amb aquella informació, però la informació sobre la qual treballa és un fet, no una estimació.
El principi és general: cada operació determinista que formalitzes — un script de validació, una consulta SQL parametritzada, un linter configurat — és una eina que l’agent pot cridar amb garanties. Quan ho fa, les seves decisions es basen en resultats verificats, no en plausibilitat. Estàs aplicant harness engineering (descrit a Fer el projecte més automatitzable) dins del bucle de l’agent — no com a verificació posterior, sinó com a fonament de cada pas.
Com s’exposen aquests scripts perquè l’agent els pugui cridar? La via més simple és la més habitual: tenir-los al repositori i dir a l’agent que els faci servir — al prompt, o a les instruccions de projecte que l’agent carrega automàticament a cada sessió. Si el projecte té un scripts/validate-schema.sh, n’hi ha prou amb indicar a l’agent “per validar configuració, executa scripts/validate-schema.sh” perquè el cridi via terminal. Per a integracions més formals o sistemes externs, el MCP — introduït a Context, tools i MCP — permet declarar operacions com a tools que qualsevol agent compatible pot invocar directament. En tots dos casos, el valor d’enginyeria és al script, no a com l’exposes.
Tot això implica que decidir quines operacions exposar, amb quin contracte i a quina granularitat és una decisió de disseny que determina el sostre del que l’agent pot fer de manera fiable. Aprendre a escriure scripts, validadors i transformacions deterministes no és una habilitat “pre-IA” que perdrà valor — és el fonament per treure el màxim d’un agent.
Usar l’agent per no pensar
Tornem al tercer tipus de problema — el desconeixement temporal del domini. El cas perillós no és “tasca determinista delegada a l’agent” — és “tasca que semblava ambigua perquè encara no havíem entès el problema”. L’agent produeix una resposta raonable, i això elimina la pressió per fer la feina d’enginyeria de definir-lo.
Símptomes que indiquen que això està passant:
- El sistema “funciona” però es comporta diferent a cada execució.
- Cada vegada que cal modificar-lo, tornes a la sessió amb l’agent en lloc de canviar codi.
- Ningú a l’equip pot explicar les regles que el sistema segueix.
- Els bugs es manifesten com a “output inesperat”, no com a “line N exception”.
La mitigació no és deixar de fer servir l’agent — és fer servir l’agent per descobrir les regles, i llavors codificar-les. Si una tasca s’ha resolt amb l’agent dues o tres vegades, ja saps prou per formalitzar-la.
Heurística final
Abans de delegar, una pausa breu:
Podria expressar això com 5-20 línies de codi?
Si la resposta és sí, escriu-les — o demana a l’agent que les escrigui per tu, però conserva-les. Un script commitejat val més que deu sessions d’agent que han fet la mateixa feina.
L’ordre és el que importa: primer pensa com a enginyer — quines són les regles, quin és el flux, què és reusable — i només després decideix si una part del problema demana un agent. La fascinació per la potència de l’agent fa fàcil saltar-se aquest pas; les eines deterministes que tenim — scripts, Makefiles, linters, generators — segueixen sent les millors quan el problema es pot formular com una regla. Reconèixer quin tipus de problema tens al davant és la part de la feina que cap agent farà per tu.
Quan la tasca no és formalitzable fàcilment, o quan l’exploració i el judici sí que justifiquen un agent, el següent problema ja no és si delegar, sinó com fer-ho bé.