# Cosa insegna il key management bancario sugli eval harness per agenti

> Cinque discipline dalla sicurezza bancaria — stato persistente, recovery deterministica, dual control, audit trail — applicate agli agenti LLM.

Published: 2026-04-18
Canonical: https://gianlucamazza.it/it/blog/bank-grade-agent-evals
Tags: Agent Evals, Verifiable Systems, LLM Production, Banking, MCP

## Perché conta

Vedo ancora molti sistemi agentici in produzione valutati come demo: un umano legge una traccia, alza le spalle, rilascia. In domini regolamentati — banking, fintech, compliance, assicurazioni — quel pattern non è rilasciabile. La domanda non è _"l'agente sembra ragionevole?"_, ma _"posso dimostrare, a posteriori, perché ha fatto quello che ha fatto — e rieseguire gli stessi input per riprodurlo?"_

Per gran parte del periodo precedente al 2024 ho costruito architetture wallet, prototipi UI Lightning e soluzioni di custodia per banche. Il modello mentale che mi è rimasto non è "crittografia per la crittografia", ma **sistemi progettati perché ogni affermazione possa essere verificata da chi non si fida di te**. Vedo questo approccio trasferirsi quasi direttamente agli agenti LLM in produzione. È anche uno dei gap più frequenti nei team che arrivano dall'ingegneria web.

Ecco le cinque discipline che porto con me, con la mappatura sui sistemi agentici.

## 1. Stato persistente, non contesto effimero

**Banking:** una chiave non vive mai solo in memoria. Esiste in un HSM, in un HSM di backup, in un set di shard cifrati e in un audit log che registra ogni accesso. Niente di effimero è considerato affidabile.

**Parallelo agentico:** salvo lo stato dell'agente _prima_ di qualsiasi tool call con effetti collaterali, non dopo. Il checkpointer di LangGraph è il punto di partenza minimo. Senza stato persistente non posso rispondere a _"cosa sapeva l'agente al passo N?"_ — che è la prima domanda di ogni analisi post-incidente.

```python
# Non così:
result = agent.invoke(input)  # stato solo in RAM

# Così:
checkpoint = graph.invoke(
    input,
    config={"configurable": {"thread_id": session_id}},  # persistito
)
```

Nel mio setup, il costo aggiuntivo è in latenza e storage per step. Il beneficio è poter fare replay, audit e debug di ogni traiettoria.

## 2. Modalità di fallimento deterministiche

**Banking:** le operazioni sulle chiavi o riescono o falliscono in modo pulito. Non esiste "successo parziale". Una firma a metà è un incidente di sicurezza.

**Parallelo agentico:** per ogni tool contract uso modalità di fallimento tipizzate ed esaustive. Niente `except Exception: pass`. Niente _"tanto l'LLM riprova"_ senza terminazione esplicita. Uso schema Pydantic per ogni I/O di tool, con union type per i casi di errore che l'LLM deve gestire:

```python
class SearchResult(BaseModel):
    status: Literal["ok", "rate_limited", "empty", "auth_error"]
    hits: list[Hit] = []
    retry_after_s: int | None = None
```

L'LLM può ragionare su `status: rate_limited` → aspetta. Non può ragionare su uno stack trace incompleto.

## 3. Doppio controllo per azioni ad alto impatto

**Banking:** muovere denaro sopra una soglia richiede due autorizzazioni. Nessuna chiave singola, nessun umano singolo, può farlo da solo.

**Parallelo agentico:** faccio passare ogni azione con impatto finanziario, legale o rivolta ai clienti da un **human-in-the-loop checkpoint** OPPURE da un validatore deterministico — non dallo stesso agente che l'ha proposta. È uno dei gap più frequenti che vedo negli audit di deployment agentici enterprise. Trovo spesso agenti che mandano email, committano codice o aprono ticket _senza una seconda firma_.

La primitiva `interrupt` di LangGraph è il meccanismo. La uso su: comunicazioni esterne, scritture su sistemi di record, qualunque azione che richieda un rollback manuale o una correzione operativa.

## 4. Audit trail come evidenza, non log

**Banking:** ogni azione produce un'evidenza che reggerebbe in uno studio di un regolatore. Significa firmata, con timestamp, tamper-evident — non solo _"ci sono i log"_.

**Parallelo agentico:** considero l'eval harness e il trace store di produzione come lo stesso artefatto, ruotato nel tempo. Ogni run dell'agente deve scrivere: input, hash del prompt template, model name + version, invocazioni dei tool con argomenti e ritorni, output finale e un timestamp di catena di custodia. Nel mio caso, OpenTelemetry + LangSmith copre il requisito minimo; in altri contesti serve altro, oppure può bastare una tabella postgres con colonne `jsonb` e un constraint append-only. Cercare con grep nelle trascrizioni Slack non produce evidenza probatoria.

Perché conta: le regressioni nei sistemi LLM sono spesso invisibili nelle metriche aggregate ma evidenti nei singoli trace. Senza evidenza riproducibile, diagnostico a intuito.

## 5. Recovery playbook per i fallimenti, non solo per i successi

**Banking:** ogni servizio di custodia ha un runbook per compromissione di chiavi, perdita di chiavi, compromissione dell'operatore. Il playbook viene scritto _prima_ dell'incidente, non dopo.

**Parallelo agentico:** prima del rilascio, scrivo le modalità di fallimento che mi aspetto di vedere in produzione e l'azione di recovery per ognuna:

- Modello deprecato / rate-limited → fallback model routing
- Tool che restituisce output malformato → circuit breaker + escalation
- Prompt injection rilevata → abort della traiettoria + voce di audit
- State store non disponibile → modalità read-only, non degrado silenzioso

Se non riesco a nominare almeno tre modalità di fallimento plausibili con un piano di recovery scritto, non lo considero pronto per la produzione.

## Il framing di categoria

Chiamo questa cosa **sistemi agentici verificabili per domini regolamentati**. Non sono "evals" (Hamel Husain ha descritto molto bene quel framing, e consiglio il suo lavoro). È un perimetro più stretto e più specifico: sistemi agentici progettati dal giorno uno con gli stessi vincoli che la custodia bancaria impone — durabilità, determinismo, doppio controllo, audit con valore probatorio, recovery.

È un'area che vedo crescere nell'adozione enterprise degli LLM. Molti casi d'uso più standardizzati, come chatbot di supporto clienti e Q&A su knowledge base interne, sono già coperti da piattaforme orizzontali. Il budget rimanente tende a spostarsi su workflow dove il raggio d'impatto di un'azione sbagliata è reale. In quel contesto, la soglia di valutazione si sposta da _"sembra ragionevole?"_ a _"posso dimostrare perché ha fatto quello che ha fatto?"_.

Se vuoi confrontare questo approccio con un workflow agentico in dominio regolamentato, posso aiutarti a mappare stato persistente, recovery, audit trail e punti di controllo.

## FAQ

### Perché persistere lo stato prima di una tool call?

Salvo lo stato dell’agente prima di qualsiasi tool call con effetti collaterali, non dopo. Il checkpointer di LangGraph è il punto di partenza minimo. Senza stato persistente non posso rispondere a cosa sapeva l’agente al passo N. Non posso nemmeno fare replay, audit e debug affidabile della traiettoria.

### Come rendere deterministiche le modalità di fallimento dei tool?

Per ogni tool contract uso modalità di fallimento tipizzate ed esaustive. Applico schema Pydantic a ogni I/O e union type ai casi di errore che l’LLM deve gestire, come ok, rate_limited, empty o auth_error. L’LLM può ragionare su uno status esplicito. Uno stack trace incompleto non offre lo stesso livello di controllo.

### Quando applicare il doppio controllo a un agente LLM?

Faccio passare ogni azione con impatto finanziario, legale o rivolta ai clienti da un human-in-the-loop checkpoint oppure da un validatore deterministico. Non uso lo stesso agente che ha proposto l’azione come unico controllo. Uso interrupt per comunicazioni esterne, scritture su sistemi di record e azioni con rollback manuale.

### Quali dati servono in un audit trail agentico?

Considero eval harness e trace store di produzione come lo stesso artefatto, ruotato nel tempo. Ogni run deve scrivere input, hash del prompt template, model name e version, invocazioni dei tool con argomenti e ritorni, output finale e timestamp di catena di custodia.

### Che recovery playbook preparo prima del rilascio?

Prima del rilascio scrivo le modalità di fallimento attese e l’azione di recovery per ciascuna: modello deprecato o rate-limited con fallback model routing, output malformato del tool con circuit breaker ed escalation, prompt injection con abort e voce di audit, state store non disponibile con modalità read-only.
