HomeModelli AIRAGMCP OrchestrazionePrompt EngineeringQuando (Non) Usare AIChipsBotNews

Orchestrazione & Agenti

Come passare da un singolo prompt a sistemi AI complessi che ragionano, pianificano, usano strumenti e collaborano. L'architettura degli agenti, i pattern e i framework.

Cos'è un agente AI

Un agente AI è un sistema che usa un LLM come "cervello" per prendere decisioni, pianificare azioni e usare strumenti per raggiungere un obiettivo. La differenza fondamentale rispetto a un chatbot è il loop: un agente non si limita a rispondere, ma osserva il risultato delle sue azioni e decide il passo successivo.

┌─────────────┐ │ Obiettivo │ └──────┬──────┘ ▼ ┌───────────────────────┐ ┌───▶│ PENSA (LLM) │◀───┐ │ │ Analizza stato │ │ │ │ Decide prossima azione│ │ │ └───────────┬───────────┘ │ │ ▼ │ │ ┌───────────────────────┐ │ │ │ AGISCI (Tool) │ │ │ │ Esegui tool/API call │ │ │ │ Scrivi codice │ │ │ └───────────┬───────────┘ │ │ ▼ │ │ ┌───────────────────────┐ │ └────│ OSSERVA │────┘ │ Analizza risultato │ │ Obiettivo raggiunto? │──▶ FINE └──────────────────────┘

Questo loop — Pensa → Agisci → Osserva — è il cuore di ogni agente. Può essere eseguito una volta (single-step) o ripetuto decine di volte fino al completamento del task.

Pattern architetturali

ReAct (Reasoning + Acting)

Il pattern più usato. Il modello alterna tra pensiero (reasoning) e azione (acting). Ad ogni step, produce un "thought" che spiega il suo ragionamento, poi un'azione da eseguire, poi osserva il risultato.

# Pseudo-codice di un loop ReAct
while not task_complete:
    # 1. Il modello pensa e sceglie un'azione
    response = llm.generate(
        system="Sei un assistente con accesso a questi tool: ...",
        messages=conversation + ["Osservazione: " + last_result]
    )

    # 2. Parsing dell'azione dal response
    action = parse_tool_call(response)

    if action.name == "final_answer":
        return action.params["answer"]

    # 3. Esecuzione del tool
    result = tools[action.name].execute(action.params)

    # 4. Il risultato viene aggiunto al contesto
    conversation.append({"role": "tool", "content": result})python

Plan-and-Execute

Invece di agire step-by-step, l'agente prima crea un piano completo, poi esegue ogni step in sequenza. Utile per task complessi dove la pianificazione globale è importante. Il piano può essere ri-generato se uno step fallisce.

# Plan-and-Execute pattern
plan = planner_llm.generate(
    "Crea un piano step-by-step per: " + task
)
# plan = ["1. Cerca info su X", "2. Analizza Y", "3. Genera report"]

for step in plan:
    result = executor_llm.execute_step(step, context)
    if result.needs_replan:
        plan = planner_llm.replan(plan, step, result.error)python

Reflexion

L'agente valuta criticamente le proprie risposte e azioni passate, identificando errori e migliorando. Dopo ogni tentativo, genera un "self-reflection" che viene aggiunto al contesto per il tentativo successivo. Particolarmente efficace per task di coding e problem-solving.

Tool use e function calling

Il tool use è ciò che trasforma un LLM da "motore di testo" ad "agente". I modelli moderni supportano nativamente la generazione di chiamate a funzione strutturate:

# Tool use con Anthropic API
import anthropic
client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=[{
        "name": "search_database",
        "description": "Cerca nel database aziendale",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string"},
                "table": {"type": "string", "enum": ["clienti", "ordini", "prodotti"]}
            },
            "required": ["query"]
        }
    }],
    messages=[{"role": "user", "content": "Quanti ordini ha fatto Mario Rossi?"}]
)

# Il modello genera un tool_use block con i parametri
# {"name": "search_database", "input": {"query": "Mario Rossi", "table": "ordini"}}python

Il modello non esegue la funzione — genera solo la richiesta strutturata. L'esecuzione avviene nel codice dell'applicazione, e il risultato viene inviato al modello come "tool result" per continuare la conversazione. Con MCP, questo pattern diventa standardizzato e riutilizzabile.

Sistemi multi-agente

Quando un singolo agente non basta, si possono comporre più agenti specializzati. Le architetture principali:

Hub-and-Spoke (Orchestratore)

Un agente centrale (orchestratore) riceve le richieste e le delega ad agenti specializzati. L'orchestratore conosce le competenze di ogni specialista e decide chi può gestire ogni richiesta. Questo è il pattern usato da ChipsBot.

Utente │ ▼ ┌───────────────┐ │ Orchestratore │ └──┬─────┬────┬─┘ │ │ │ ┌────────▼┐ ┌──▼──┐ ┌▼────────┐ │Billing │ │Tech │ │Marketing│ │Specialist│ │Spec.│ │Specialist│ └─────────┘ └─────┘ └─────────┘

Peer-to-Peer

Gli agenti comunicano direttamente tra loro senza un coordinatore centrale. Ogni agente può delegare a qualsiasi altro. Più flessibile ma più difficile da debuggare e controllare.

Gerarchico

Struttura ad albero: un manager coordina team leader, che a loro volta coordinano agenti operativi. Adatto per organizzazioni complesse con responsabilità chiare.

Framework per agenti

AutoGen (Microsoft)

Framework per conversazioni multi-agente. Gli agenti "parlano" tra loro come in una chat di gruppo. Supporta agenti basati su LLM, agenti basati su codice, e agenti umani nella stessa conversazione. Ottimo per task collaborativi come brainstorming, code review, planning.

CrewAI

Ispirato alle metodologie di team management. Ogni agente ha un ruolo, un obiettivo e un backstory. I task vengono assegnati come in un team di lavoro reale. Più opinato di AutoGen, più semplice da configurare.

# Esempio CrewAI
from crewai import Agent, Task, Crew

researcher = Agent(
    role="Ricercatore AI",
    goal="Trovare le ultime novità su MCP",
    backstory="Esperto di protocolli e integrazioni AI",
    tools=[search_tool, web_scraper]
)

writer = Agent(
    role="Technical Writer",
    goal="Scrivere articoli tecnici chiari",
    backstory="Divulgatore con 10 anni di esperienza"
)

research_task = Task(
    description="Ricerca le ultime novità su MCP di Anthropic",
    agent=researcher
)

writing_task = Task(
    description="Scrivi un articolo basato sulla ricerca",
    agent=writer
)

crew = Crew(agents=[researcher, writer], tasks=[research_task, writing_task])
result = crew.kickoff()python

LangGraph

Parte dell'ecosistema LangChain. Permette di definire flussi agentici come grafi diretti. Ogni nodo è un'azione (chiamata LLM, tool use, logica custom). Gli archi sono le transizioni condizionali. Massima flessibilità, ma richiede più codice.

Anthropic Agent SDK

SDK ufficiale di Anthropic per costruire agenti. Integrato nativamente con Claude e MCP. Supporta loop agentici, tool use, guardrails e handoff tra agenti. Il più semplice per chi usa già Claude.

Guardrails e safety

Gli agenti hanno più autonomia dei chatbot, quindi servono più controlli:

  • Output validation — verificare che le risposte rispettino formato, lunghezza e contenuto atteso
  • Content filtering — bloccare contenuti inappropriati, offensivi o pericolosi
  • Action approval — richiedere conferma umana per azioni irreversibili (delete, send, pay)
  • Budget limits — impostare limiti di costo per sessione/utente/giorno
  • Max iterations — limitare il numero di step nel loop per evitare loop infiniti
  • Sandboxing — eseguire codice generato in ambienti isolati (container, VM, sandbox)
Regola d'oro degli agenti Più autonomia dai all'agente, più guardrails servono. Un agente che può solo leggere richiede meno controlli di uno che può scrivere, inviare email o eseguire codice.

Monitoring e observability

In produzione, un sistema agentico è una scatola nera senza monitoring adeguato. Le dimensioni da monitorare:

Traces

Ogni esecuzione dell'agente deve essere tracciata: input, output di ogni step, tool invocati, risultati, decisioni. Tool come LangSmith, Langfuse, Arize Phoenix e Helicone offrono dashboard di tracing.

Costi

Un loop agentico può fare decine di chiamate API. Senza monitoraggio, i costi esplodono. Traccia token usati per step, costo per sessione, costo per utente.

Latenza

Ogni step aggiunge latenza. Un agente che fa 10 step da 2 secondi ciascuno impiega 20 secondi per rispondere. Monitora la latenza end-to-end e per step. Considera streaming per dare feedback immediato all'utente.

Success rate

Quale percentuale di task l'agente completa con successo? Quali tipi di task falliscono più spesso? Dove nel loop si verificano gli errori?

Error handling e retry

Gli agenti falliscono. Il tool non risponde, l'API ritorna un errore, il modello genera output invalido. Strategie:

  • Retry con backoff — per errori transienti (rate limit, timeout), riprovare con attesa esponenziale
  • Fallback — se un tool non funziona, provare un tool alternativo o un approccio diverso
  • Self-correction — passare l'errore al modello e chiedergli di riprovare con un approccio diverso
  • Graceful degradation — se il task completo non è possibile, completarne una parte e informare l'utente
  • Human escalation — se dopo N tentativi l'agente non riesce, passare a un umano
# Pattern di retry con self-correction
for attempt in range(max_retries):
    try:
        result = agent.execute_step(step)
        if validate_result(result):
            break
        else:
            # Chiedi al modello di correggere
            step = agent.self_correct(step, result, "Output non valido")
    except ToolError as e:
        if attempt < max_retries - 1:
            sleep(2 ** attempt)  # exponential backoff
        else:
            return escalate_to_human(step, e)python

Per approfondire