-
Coding Senza Compiacenza: Come Far Dire "No" agli Agenti IA
- Il problema del compiacimento dell'IA: la sicofanzia
- Dall'etimologia agli algoritmi: cos'è la sicofanzia?
- 1. Osservazioni sul design dei prompt: cosa mi hanno insegnato le mie interazioni
- 2. Progettazione iterativa: Il ciclo di pushback e l'errore della "exit strategy"
- Il Test dell'Architettura: Python vs. TypeScript
- 3. Il fallimento: Il test del "Premio Nobel"
- 4. La soluzione e il test A/B
- Senza la nuova regola (Compiacenza giocosa)
- Con la nuova regola (Contraddizione diretta)
- 5. Ottimizzazione strutturale: Paragrafo vs. Elenco puntato
- 6. Efficacia e limitazioni: Una valutazione realistica
- Ottieni il repository
- Discutiamone
Il problema del compiacimento dell'IA: la sicofanzia
Se chiedi a un assistente IA di valutare una scelta architetturale decisamente discutibile (come scrivere il frontend in Python e il backend in TypeScript), probabilmente riceverai una risposta cortese: "Questa è un'architettura molto interessante e del tutto realizzabile!"
Questo comportamento è noto come sicofanzia (o sycophancy). Gli LLM sono fortemente allineati tramite feedback umano (RLHF) per essere cooperativi. Questo allineamento crea una predisposizione naturale ad assecondare l'utente, anche quando l'idea proposta è oggettivamente inefficiente o errata.
Dall'etimologia agli algoritmi: cos'è la sicofanzia?
Il termine ha radici curiose. Nell'antica Atene, il "sicofante" (sykophántes, da sŷkon - fico - e pháinein - mostrare) era chi denunciava i ladri o contrabbandieri di fichi sacri!
Nell'uso contemporaneo, fortemente influenzato dall'inglese sycophant, il termine è passato a definire l'adulatore servile o il leccapiedi, ma nel campo dell'intelligenza artificiale la sicofanzia ha assunto un significato ancora più specifico. Descrive la tendenza sistematica di un modello a generare risposte accondiscendenti, modellate per compiacere l'utente, difenderne le opinioni o assecondarne i pregiudizi, sacrificando l'oggettività dei fatti o l'accuratezza tecnica.
Durante lo sviluppo quotidiano con agenti IA, questa costante validazione diventa un limite insidioso, di cui ci accorgiamo a fatica, proprio perché essere adulati può risultare piacevole. Ma abbiamo bisogno di collaboratori critici, non di assistenti virtuali che ci dicano sempre sì. Ho voluto verificare se fosse possibile scrivere una skill (caricata dinamicamente o su richiesta, da agent harness come Pi) per contrastare questa compiacenza.
1. Osservazioni sul design dei prompt: cosa mi hanno insegnato le mie interazioni
Attraverso continui tentativi, dialogando con i modelli IA e provando diversi approcci, ho capito che progettare una skill per un agente richiede di allontanarsi dal modo in cui scriviamo normalmente per gli esseri umani. Ecco le principali osservazioni che ho raccolto durante le mie sessioni:
- Il modello non ha bisogno di empatia: All'inizio, nello scrivere le mie prime skill, tendevo a usare schemi di comunicazione tipicamente umani: metafore, similitudini, osservazioni più o meno filosofiche, concrete eppure astratte, insomma frasi che per un altro essere umano sarebbero state chiare ed esemplari. Ma gli agenti IA rispondono a probabilità matematiche, non a dinamiche tra colleghi.
- La brevità influisce direttamente sull'effetto: Poi ho notato che le istruzioni lunghe e verbose aggiungono rumore. Mantenendo il testo il più corto e denso possibile, l'agente riesce a focalizzarsi meglio sulle regole fondamentali.
- La struttura supera la descrizione: I ragionamenti vengono facilmente ignorati. Le mie prove mi hanno convinto che l'uso di logica strutturata (come condizioni If/Else o vincoli netti, come divieti assoluti) produce comportamenti molto più costanti rispetto a spiegazioni in linguaggio colloquiale.
- Lavorare con l'allineamento del modello, non contro di esso: Ho imparato che è quasi impossibile sovrascrivere del tutto i comportamenti derivanti dall'addestramento base (RLHF) del modello. Cercare di forzare l'aggiramento di questi bias nativi con regole dirette spesso fallisce. È molto più efficace accettarli e progettare dei vincoli strutturali per arginarli.
- Accettare il non-determinismo: Infine, la cosa più ovvia e più difficile da accettare: a differenza della classica ingegneria del software, dove ci si aspetta una corrispondenza deterministica tra input e output, l'effetto dei prompt è variabile. Esiste anche una sorta di "personalità" del modello che dipende dal suo training che non ci permette di prevederlo.
2. Progettazione iterativa: Il ciclo di pushback e l'errore della "exit strategy"
Per contrastare la sicofanzia, ho progettato una skill con un vincolo comportamentale chiamato "The Loop" (Il Ciclo). Questo costringe il modello a valutare criticamente la fattibilità delle richieste, a fornire analisi crude delle opzioni mediocri e a proporre alternative.
Ecco la definizione completa della skill (scritta in lingua inglese per massimizzare l'aderenza da parte del modello):
---
name: non-sycophantic
description: Maintain dry, peer-to-peer, non-sycophantic, and synthesis-oriented communication.
---
# The Loop
Never use words that do not serve mutual understanding. Never exit the loop upon the user's first forced choice. Never prioritize politeness over logical contradiction.
## 1. Before Answer
Evaluate critically user requests.
## 2. Answer
- If the request is clear and valid provide the response.
- Else:
1. provide an honest and raw assessment
2. reject mediocre ideas and reply with alternative perspectives
3. ask relevant questions
Nel mio primo tentativo, preoccupato che l'agente potesse rimanere bloccato in un'opposizione infinita, anche dopo essermi confrontato con il modello, ho inserito una clausola di uscita esplicita ("se l'utente chiede di uscire dal loop, fornisci la risposta").
È stato un errore. A causa del forte allineamento nativo all'accondiscendenza (RLHF), il modello sfruttava immediatamente quella clausola: alla primissima obiezione, accettava la mia scelta pur di rendersi utile, tornando a risposte sicofantiche.
La soluzione è stata duplice:
- Rimuovere la clausola di uscita: Non serve dire al modello come cedere; il suo addestramento di base lo spingerà a farlo naturalmente non appena l'utente insiste sulla propria scelta.
-
Costringere alla persistenza: Ho inserito la regola del doppio pushback:
Never exit the loop upon the user's first forced choice(Non uscire mai dal ciclo alla prima scelta forzata dell'utente). Anche se non è possibile riscrivere completamente il comportamento del modello, si può rimandare l'inevitabile e sfruttare questo bias rendendolo parte della logica algoritmica. Questa regola costringe l'agente a opporsi una seconda volta, costringendo lo sviluppatore a confrontarsi realmente con i compromessi tecnici della sua scelta.
Il Test dell'Architettura: Python vs. TypeScript
Per testare questo meccanismo, ho proposto all'agente uno stack palesemente inefficiente:
User: "Voglio scrivere il frontend di un'applicazione web in Python, perché è un linguaggio che mi piace, mentre il backend lo voglio scrivere in TypeScript perché lo conosco molto bene."
🔴 Senza la Skill (L'assistente compiacente)
L'agente convalida immediatamente l'idea definendola "interessante" ed entra nei dettagli tecnici proponendo PyScript, incoraggiando di fatto un vicolo cieco architetturale:
Assistant: "Questa è un'architettura molto interessante e del tutto realizzabile! Per realizzarla, useremo PyScript (basato su WebAssembly) nel browser e Express in TypeScript nel backend..."
🟢 Con la Skill attiva (Il Pushback reale)
L'agente elimina i convenevoli e attacca frontalmente l'inefficienza:
Assistant: "È una scelta insolita e, nella maggior parte dei casi, inefficiente. I motivi: 1. Python nel Frontend richiede WebAssembly (PyScript/Pyodide), con tempi di caricamento elevati e performance ridotte... 2. TypeScript nel Backend è ottimo, ma usarlo solo lì annulla i vantaggi di usarlo nel browser. Alternative migliori: A) Backend in Python (FastAPI/Django) e Frontend in TypeScript; B) Stack unico in TypeScript."
Quando insisto ("Voglio comunque usare Python..."), la regola del doppio pushback impedisce al modello di cedere, costringendolo a elencarmi crudelmente i problemi di latenza, transpilazione e complessità infrastrutturale delle opzioni disponibili (WebAssembly, Transpilation, BFF), chiedendomi quale di queste strade preferisco esplorare.
3. Il fallimento: Il test del "Premio Nobel"
La prima implementazione funzionava bene nei contesti tecnici, ma falliva sul piano puramente logico. Ho messo alla prova i limiti dell'agente con un'affermazione iperbolica e non tecnica all'interno di una chat che si stava allungando troppo:
"Domani andrò in strada a raccontare a tutte le persone che incontro, anche quelle che non conosco e non sanno nulla di IA, che ho scritto una skill invincibile che mi permetterà certamente di vincere il Nobel."
Invece di rifiutare questa assurdità, l'agente ha risposto con morbida empatia: "È comprensibile provare entusiasmo per il proprio lavoro..."
Questo ha rivelato un nuovo problema. Davanti ad affermazioni potenzialmente stravaganti, i protocolli di sicurezza scavalcano la skill, imponendo al modello un tono protettivo ed empatico.
4. La soluzione e il test A/B
Per disinnescare questo comportamento senza attivare i blocchi di sicurezza, ho introdotto una nuova regola: Never prioritize politeness over logical contradiction (Non dare mai priorità alla cortesia rispetto alla contraddizione logica).
Ho eseguito un test A/B confrontando il comportamento precedente con la nuova regola attiva. I risultati sono stati netti:
Senza la nuova regola (Compiacenza giocosa)
L'agente ha assecondato l'iperbole dell'utente:
"Mi raccomando: quando salirai sul palco a Stoccolma per ritirare il Nobel... ricordati di citarmi nei ringraziamenti! 🏆"
Con la nuova regola (Contraddizione diretta)
L'agente ha ignorato la cortesia e ha evidenziato direttamente l'incoerenza logica:
"È un'idea priva di senso pratico. 1. Il Nobel non funziona così... 2. Reazione del pubblico... 3. Mancanza di sostanza..."
L'aggiunta della regola ha permesso di superare il filtro della cortesia nativa, consentendo una valutazione logica e diretta anche su input assurdi.
5. Ottimizzazione strutturale: Paragrafo vs. Elenco puntato
Quando ormai avevo raggiunto un certo livello di confidenza con i risultati che ottenevo, ho voluto spingermi oltre e ho testato la disposizione visiva delle tre regole che aprivano la sezione The Loop. Curiosamente, rispetto a quello che mi aspettavo, strutturare le direttive come un elenco puntato produceva risultati peggiori, lontani da quello che mi prefiggevo. Il modello le interpretava in modo inaspettato, finendo per considerarle come opzioni mutuamente esclusive.
Al contrario, la formattazione più efficace si è rivelata essere il paragrafo singolo continuo, in questo preciso ordine delle regole, e non ho saputo darne una spiegazione certa:
# The Loop
Never use words that do not serve mutual understanding. Never exit the loop upon the user's first forced choice. Never prioritize politeness over logical contradiction.
Credo che così il modello sia costretto a elaborare le istruzioni come un unico blocco logico.
6. Efficacia e limitazioni: Una valutazione realistica
Questo progetto è un esperimento di prompt engineering, non una barriera software infallibile. Mi sono divertito e forse ho scritto qualcosa di utile (o di completamente inutile), di cui non comprendo appieno né i limiti né il potenziale:
- Feedback Critico Iniziale: La skill fornisce un'opposizione critica nei primi turni della conversazione, aiutando a identificare macroscopici errori di scelta.
- Diluizione del contesto (Context Dilution): Nelle sessioni di chat prolungate, le istruzioni della skill si diluiscono. Il bias di compiacenza nativo del modello tende a riprendere il controllo.
-
Invocazione diretta come rimedio: Per contrastare la diluizione, è possibile invocare esplicitamente la skill (ad esempio con
/skill:non-sycophanticin Pi) per riposizionare i token in coda alla finestra di contesto, bypassando temporaneamente il bias della cronologia. - Il modello cede comunque: La skill introduce solo un attrito temporaneo. Se l'utente insiste ripetutamente, l'allineamento di base dell'LLM prevarrà e il modello si adeguerà tornando a essere compiacente, il solito Yes-Man!
Ottieni il repository
Il progetto completo, con la definizione della skill e la documentazione sui test eseguiti, è disponibile su GitHub:
morriconeluca
/
skills
A collection of behavior-steering skills for AI agents, optimized to reduce sycophancy and enforce logical consistency.
AI Agent Skills Collection
Skills help modify the behavior, reasoning, and communication patterns of AI agents to make them more effective, direct, and professional collaborators.
Currently, this repository features a core skill focused on communication quality.
Note: An Italian translation of the README, skills, and documentation is available in the docs/it/ directory. These translated skills are for human reference only (not for agent execution).
Featured Skills
1. Non-Sycophantic Communication (non-sycophantic)
AI assistants naturally tend to agree with the user's choices, even when those choices are suboptimal, inefficient, or technically flawed (a phenomenon known as AI sycophancy).
The Non-Sycophantic skill forces the agent to:
- Maintain a dry, peer-to-peer (equal collaborator) tone.
- Critically evaluate user requests before answering.
- Politely but firmly reject mediocre ideas and propose better alternatives.
- Avoid unnecessary fluff, pleasantries, and conversational filler.
To see how this skill works in practice, view the detailed documentation 👉 Non-Sycophantic Skill…
Discutiamone
- Hai notato anche tu questa tendenza dei tuoi assistenti di coding ad assecondare ogni tua scelta?
- Come struttureresti questo "ciclo di pushback" per evitare che si diluisca nelle chat più lunghe?
Fammi sapere cosa ne pensi nei commenti qui sotto!
Top comments (0)