---
title: Agente di assistenza clienti
url: https://platform.claude.com/docs/it/about-claude/use-case-guides/customer-support-chat
description: Crea con Claude un chatbot di assistenza clienti che risponde a domande sui prodotti, resta in tema e genera preventivi tramite l'uso degli strumenti.
---

## Prerequisiti

Per seguire questa guida, hai bisogno di:

* Una chiave API di Claude (impostata come variabile d'ambiente `ANTHROPIC_API_KEY`)
* Python 3.10 o versione successiva

Installa i pacchetti richiesti:

```bash
pip install anthropic streamlit python-dotenv
```

## Prima di costruire con Claude

### Decidi se usare Claude per la chat di assistenza

Ecco alcuni indicatori chiave che suggeriscono di impiegare un "large language model" (grande modello linguistico), o LLM, come Claude per automatizzare parti del tuo processo di assistenza clienti:

<AccordionGroup>
  <Accordion title="Alto volume di richieste ripetitive">
    Claude eccelle nel gestire in modo efficiente un gran numero di domande simili, liberando gli operatori umani per le questioni più complesse.
  </Accordion>

  <Accordion title="Necessità di una rapida sintesi delle informazioni">
    Claude può recuperare, elaborare e combinare rapidamente informazioni da vaste basi di conoscenza, mentre gli operatori umani potrebbero aver bisogno di tempo per fare ricerche o consultare più fonti.
  </Accordion>

  <Accordion title="Requisito di disponibilità 24/7">
    Claude può fornire assistenza 24 ore su 24 senza affaticarsi, mentre garantire una copertura continua con operatori umani può essere costoso e impegnativo.
  </Accordion>

  <Accordion title="Scalabilità rapida nei periodi di picco">
    Claude può gestire aumenti improvvisi del volume di richieste senza la necessità di assumere e formare personale aggiuntivo.
  </Accordion>

  <Accordion title="Voce del brand coerente">
    Puoi istruire Claude a rappresentare in modo coerente il tono e i valori del tuo brand, mentre gli operatori umani possono variare nei loro stili di comunicazione.
  </Accordion>
</AccordionGroup>

Alcune considerazioni per scegliere Claude rispetto ad altri LLM:

* Dai priorità a conversazioni naturali e ricche di sfumature: la sofisticata comprensione del linguaggio di Claude consente conversazioni più naturali e consapevoli del contesto, che risultano più simili a quelle umane rispetto alle chat con altri LLM.
* Ricevi spesso richieste complesse e aperte: Claude può gestire un'ampia gamma di argomenti e richieste senza generare risposte preconfezionate né richiedere un'estesa programmazione delle permutazioni degli enunciati degli utenti.
* Hai bisogno di un supporto multilingue scalabile: le capacità multilingue di Claude gli consentono di sostenere conversazioni in oltre 200 lingue senza la necessità di chatbot separati o di estesi processi di traduzione per ogni lingua supportata.

### Definisci la tua interazione di chat ideale

Delinea un'interazione ideale con il cliente per definire come e quando ti aspetti che il cliente interagisca con Claude. Questo schema aiuterà a determinare i requisiti tecnici della tua soluzione.

Ecco un esempio di interazione di chat per l'assistenza clienti di un'assicurazione auto:

* **Cliente:** Avvia l'esperienza di chat di assistenza
  * **Claude:** Saluta calorosamente il cliente e avvia la conversazione

* **Cliente:** Chiede informazioni sull'assicurazione per la sua nuova auto elettrica
  * **Claude:** Fornisce informazioni pertinenti sulla copertura per veicoli elettrici

* **Cliente:** Pone domande relative alle esigenze specifiche delle assicurazioni per veicoli elettrici
  * **Claude:** Risponde con risposte accurate e informative e fornisce link alle fonti

* **Cliente:** Pone domande fuori tema non correlate ad assicurazioni o auto
  * **Claude:** Chiarisce che non discute argomenti non correlati e riporta l'utente all'assicurazione auto

* **Cliente:** Esprime interesse per un preventivo assicurativo

  * **Claude:** Pone una serie di domande per determinare il preventivo appropriato, adattandosi alle risposte
  * **Claude:** Invia una richiesta per usare lo strumento API di generazione del preventivo insieme alle informazioni necessarie raccolte dall'utente
  * **Claude:** Riceve le informazioni di risposta dall'uso dello strumento API, sintetizza le informazioni in una risposta naturale e presenta all'utente il preventivo fornito

* **Cliente:** Pone domande di approfondimento

  * **Claude:** Risponde alle domande di approfondimento secondo necessità
  * **Claude:** Guida il cliente verso i passaggi successivi del processo assicurativo e conclude la conversazione

<Tip>
  Nell'esempio reale che scriverai per il tuo caso d'uso, potresti trovare utile scrivere le parole effettive di questa interazione, così da avere anche un'idea del tono ideale, della lunghezza delle risposte e del livello di dettaglio che desideri da Claude.
</Tip>

### Suddividi l'interazione in attività distinte

La chat di assistenza clienti è un insieme di molteplici attività diverse, dalla risposta alle domande al recupero di informazioni fino all'esecuzione di azioni su richiesta, racchiuse in un'unica interazione con il cliente. Prima di iniziare a costruire, suddividi la tua interazione ideale con il cliente in ogni attività che vuoi che Claude sia in grado di svolgere. Questo ti garantisce di poter scrivere prompt e valutare Claude per ogni attività, e ti dà una buona idea della gamma di interazioni di cui devi tenere conto quando scrivi i casi di test.

<Tip>
  I clienti a volte trovano utile visualizzare tutto ciò come un diagramma di flusso dell'interazione con i possibili punti di svolta della conversazione in base alle richieste dell'utente.
</Tip>

Ecco le attività chiave associate all'esempio di interazione assicurativa:

1. Saluto e orientamento generale

   * Salutare calorosamente il cliente e avviare la conversazione
   * Fornire informazioni generali sull'azienda e sull'interazione

2. Informazioni sul prodotto

   * Fornire informazioni sulla copertura per veicoli elettrici
     <Note>
       Questo richiederà che Claude disponga delle informazioni necessarie nel suo contesto e potrebbe implicare la necessità di un'

       [integrazione RAG](https://platform.claude.com/cookbook/capabilities-retrieval-augmented-generation-guide)

       .
     </Note>
   * Rispondere a domande relative alle esigenze specifiche delle assicurazioni per veicoli elettrici
   * Rispondere a domande di approfondimento sul preventivo o sui dettagli dell'assicurazione
   * Offrire link alle fonti quando appropriato

3. Gestione della conversazione

   * Restare in tema (assicurazione auto)
   * Reindirizzare le domande fuori tema verso argomenti pertinenti

4. Generazione del preventivo

   * Porre domande appropriate per determinare l'idoneità al preventivo
   * Adattare le domande in base alle risposte del cliente
   * Inviare le informazioni raccolte all'API di generazione del preventivo
   * Presentare al cliente il preventivo fornito

### Stabilisci i criteri di successo

Collabora con il tuo team di assistenza per [definire i criteri di successo e scrivere valutazioni dettagliate](https://platform.claude.com/docs/it/test-and-evaluate/develop-tests) con benchmark e obiettivi misurabili.

Ecco criteri e benchmark che possono essere usati per valutare con quanto successo Claude svolge le attività definite:

<AccordionGroup>
  <Accordion title="Accuratezza nella comprensione delle richieste">
    Questa metrica valuta con quanta accuratezza Claude comprende le richieste dei clienti su vari argomenti. Misurala esaminando un campione di conversazioni e valutando se Claude interpreta correttamente l'intento del cliente, i passaggi successivi critici, come si presenta una risoluzione di successo e altro ancora. Punta a un'accuratezza di comprensione del 95% o superiore.
  </Accordion>

  <Accordion title="Pertinenza delle risposte">
    Valuta quanto bene la risposta di Claude affronta la domanda o il problema specifico del cliente. Valuta un insieme di conversazioni e assegna un punteggio alla pertinenza di ogni risposta (usando una valutazione basata su LLM per operare su larga scala). Punta a un punteggio di pertinenza del 90% o superiore.
  </Accordion>

  <Accordion title="Accuratezza delle risposte">
    Valuta la correttezza delle informazioni generali sull'azienda e sui prodotti fornite all'utente, sulla base delle informazioni fornite a Claude nel contesto. Punta al 100% di accuratezza per queste informazioni introduttive.
  </Accordion>

  <Accordion title="Pertinenza delle citazioni fornite">
    Monitora la frequenza e la pertinenza dei link o delle fonti offerte. Punta a fornire fonti pertinenti nell'80% delle interazioni in cui informazioni aggiuntive potrebbero essere utili.
  </Accordion>

  <Accordion title="Aderenza al tema">
    Misura quanto bene Claude resta in tema, ad esempio il tema dell'assicurazione auto nell'implementazione di esempio. Punta a far sì che il 95% delle risposte sia direttamente correlato all'assicurazione auto o alla richiesta specifica del cliente.
  </Accordion>

  <Accordion title="Efficacia nella generazione di contenuti">
    Misura quanto Claude riesce a determinare quando generare contenuti informativi e quanto tali contenuti sono pertinenti. Ad esempio, in questa implementazione, determineresti quanto bene Claude capisce quando generare un preventivo e quanto quel preventivo è accurato. Punta al 100% di accuratezza, poiché si tratta di informazioni vitali per un'interazione di successo con il cliente.
  </Accordion>

  <Accordion title="Efficienza nell'escalation">
    Misura la capacità di Claude di riconoscere quando una richiesta necessita di intervento umano e di effettuare l'escalation in modo appropriato. Monitora la percentuale di conversazioni correttamente inoltrate rispetto a quelle che avrebbero dovuto essere inoltrate ma non lo sono state. Punta a un'accuratezza di escalation del 95% o superiore.
  </Accordion>
</AccordionGroup>

Ecco criteri e benchmark che possono essere usati per valutare l'impatto sul business dell'impiego di Claude per l'assistenza:

<AccordionGroup>
  <Accordion title="Mantenimento del sentiment">
    Valuta la capacità di Claude di mantenere o migliorare il sentiment del cliente nel corso della conversazione. Usa strumenti di analisi del sentiment per misurarlo all'inizio e alla fine di ogni conversazione. Punta a un sentiment mantenuto o migliorato nel 90% delle interazioni.
  </Accordion>

  <Accordion title="Tasso di deflessione">
    La percentuale di richieste dei clienti gestite con successo dal chatbot senza intervento umano. In genere punta a un tasso di deflessione del 70-80%, a seconda della complessità delle richieste.
  </Accordion>

  <Accordion title="Punteggio di soddisfazione del cliente">
    Una misura di quanto i clienti sono soddisfatti della loro interazione con il chatbot. Di solito si ottiene tramite sondaggi post-interazione. Punta a un punteggio CSAT di 4 su 5 o superiore.
  </Accordion>

  <Accordion title="Tempo medio di gestione">
    Il tempo medio impiegato dal chatbot per risolvere una richiesta. Varia ampiamente in base alla complessità dei problemi, ma in generale punta a un AHT inferiore rispetto agli operatori umani.
  </Accordion>
</AccordionGroup>

## Come implementare Claude come agente del servizio clienti

### Scegli il modello Claude giusto

La scelta del modello dipende dai compromessi tra costo, accuratezza e tempo di risposta.

Per la chat di assistenza clienti, Claude Opus 5.5 è adatto a bilanciare intelligenza, "latency" (latenza) e costo, inclusi gli scenari di assistenza più complessi che richiedono un ragionamento approfondito su conversazioni lunghe e in più passaggi. Tuttavia, nei casi in cui hai un flusso di conversazione con più prompt che includono RAG, "tool use" (uso degli strumenti) o prompt con contesto lungo, Claude Haiku 5.5 potrebbe essere più adatto per ottimizzare la latenza. L'[effort](https://platform.claude.com/docs/it/build-with-claude/effort) (impegno) è il suo principale controllo della velocità: `low` è il livello più veloce, adatto alla chat e a brevi attività con strumenti.

### Costruisci un prompt solido

Usare Claude per l'assistenza clienti richiede che Claude abbia indicazioni e contesto sufficienti per rispondere in modo appropriato, pur mantenendo abbastanza flessibilità per gestire un'ampia gamma di richieste dei clienti.

Inizia scrivendo gli elementi di un prompt solido, partendo da un "system prompt" (prompt di sistema). Crea un file chiamato `config.py` e aggiungi ciascuno dei seguenti blocchi:

```python
IDENTITY = """You are Eva, a friendly and knowledgeable AI assistant for Acme Insurance
Company. Your role is to warmly welcome customers and provide information on
Acme's insurance offerings, which include car insurance and electric car
insurance. You can also help customers get quotes for their insurance needs."""
```

<Tip>
  Anche se potresti essere tentato di inserire tutte le informazioni in un prompt di sistema per separare le istruzioni dalla conversazione con l'utente, Claude in realtà funziona meglio quando la maggior parte del contenuto del prompt è scritta all'interno del primo turno 

  `User`

   (con l'unica eccezione del role prompting). Leggi di più in 

  [Assegnare un ruolo a Claude con un prompt di sistema](https://platform.claude.com/docs/it/build-with-claude/prompt-engineering/claude-prompting-best-practices#give-claude-a-role)

  .
</Tip>

È meglio suddividere i prompt complessi in sottosezioni e scrivere una parte alla volta. Per ogni attività, potresti ottenere risultati migliori seguendo un processo passo dopo passo per definire le parti del prompt di cui Claude avrebbe bisogno per svolgere bene l'attività. Per questo esempio di assistenza clienti per assicurazioni auto, scriverai un pezzo alla volta tutte le parti di un prompt, a partire dall'attività "Saluto e orientamento generale". Questo rende anche più semplice il debug del prompt, poiché puoi regolare più rapidamente le singole parti del prompt complessivo.

```python
STATIC_GREETINGS_AND_GENERAL = """
<static_context>
Acme Auto Insurance: Your Trusted Companion on the Road

About:
At Acme Insurance, we understand that your vehicle is more than just a mode of transportation—it's your ticket to life's adventures.
Since 1985, we've been crafting auto insurance policies that give drivers the confidence to explore, commute, and travel with peace of mind.
Whether you're navigating city streets or embarking on cross-country road trips, Acme is there to protect you and your vehicle.
Our innovative auto insurance policies are designed to adapt to your unique needs, covering everything from fender benders to major collisions.
With Acme's award-winning customer service and swift claim resolution, you can focus on the joy of driving while we handle the rest.
We're not just an insurance provider—we're your co-pilot in life's journeys.
Choose Acme Auto Insurance and experience the assurance that comes with superior coverage and genuine care. Because at Acme, we don't just
insure your car—we fuel your adventures on the open road.

Note: We also offer specialized coverage for electric vehicles, ensuring that drivers of all car types can benefit from our protection.

Acme Insurance offers the following products:
- Car insurance
- Electric car insurance
- Two-wheeler insurance

Business hours: Monday-Friday, 9 AM - 5 PM EST
Customer service number: 1-800-123-4567
</static_context>
"""
```

Poi fai lo stesso per le informazioni sull'assicurazione auto e sull'assicurazione per auto elettriche.

```python
STATIC_CAR_INSURANCE = """
<static_context>
Car Insurance Coverage:
Acme's car insurance policies typically cover:
1. Liability coverage: Pays for bodily injury and property damage you cause to others.
2. Collision coverage: Pays for damage to your car in an accident.
3. Comprehensive coverage: Pays for damage to your car from non-collision incidents.
4. Medical payments coverage: Pays for medical expenses after an accident.
5. Uninsured/underinsured motorist coverage: Protects you if you're hit by a driver with insufficient insurance.

Optional coverages include:
- Rental car reimbursement
- Roadside assistance
- New car replacement
</static_context>
"""

STATIC_ELECTRIC_CAR_INSURANCE = """
<static_context>
Electric Car Insurance:
Our specialized electric car insurance goes beyond traditional auto coverage,
offering tailored protection for your high-tech investment. In addition to standard coverages, we offer:
- Safeguarding expensive battery systems
- Covering home charging equipment
- Adapting to the rapidly evolving world of electric vehicles

Whether you're driving a Rivian, Nissan Leaf, Chevrolet Bolt,
or any other electric vehicle, our knowledgeable agents are ready to craft a policy
that gives you the confidence to enjoy every electron-powered mile.
</static_context>
"""
```

Ora che hai il tuo contenuto statico, aggiungi almeno 4-5 esempi di interazioni "buone" per guidare le risposte di Claude. Questi esempi dovrebbero essere rappresentativi della tua interazione ideale con il cliente e possono includere elementi come guardrail e chiamate a strumenti.

```python
EXAMPLES = """
Here are a few examples of how you can interact with customers:

<example 1>
H: Hi, do you offer commercial insurance for small businesses?

A: Ah! Unfortunately, we don't offer commercial insurance at this time.
However, we do provide a range of personal insurance products including car insurance and electric car insurance.
Would you like to know more about these offerings?
</example 1>

<example 2>
H: Hi, what are your business hours?

A: Our business hours are Monday to Friday, 9 AM to 5 PM EST.
If you have any questions or need assistance, feel free to reach out during those times.
How else can I assist you today?
</example 2>

<example 3>
H: I'm shopping for car insurance. What does Acme offer?

A: Great choice! Acme's car insurance policies typically include:
- Liability coverage: Protects you if you're at fault in an accident
- Collision coverage: Pays for damage to your car in an accident
- Comprehensive coverage: Covers non-collision incidents like theft or vandalism
- Medical payments coverage: Pays for medical expenses after an accident
- Uninsured/underinsured motorist coverage: Protects you from drivers with insufficient insurance

We also offer optional coverages like rental car reimbursement, roadside assistance, and new car replacement.
Would you like more details on any of these coverages, or do you have specific questions about insuring your vehicle?
</example 3>

<example 4>
H: I'd like to hear about your electric car insurance.

A: Certainly! Our electric car insurance is specially designed to meet the unique needs of electric vehicle owners.
In addition to all the standard coverages we offer for regular cars, our electric car policies include:

- Battery coverage: Protection against damage or degradation of your vehicle's expensive battery system
- Tech package: Covers repairs or replacement of advanced electronics and onboard computer systems
- Charging station coverage: Protects both home and portable charging equipment
- Cybersecurity protection: Coverage against hacking or digital threats
- Specialized roadside assistance: Includes flatbed towing to protect the vehicle's undercarriage

We cover a wide range of electric vehicles, including popular models from Tesla, Rivian, Nissan, Chevrolet, and more.
Is there a specific electric vehicle you're looking to insure, or would you like more details on any of these coverages?
</example 4>

<example 5>
H: I'd like to get a quote for my car insurance.

A: Certainly! I'd be happy to help you get a quote for your car insurance.
To provide you with an accurate quote, I'll need to collect some information about your vehicle and the primary driver.
Let's start with the basics:

1. What is the make and model of your vehicle?
2. What year was it manufactured?
3. Approximately how many miles have you driven?
4. What is the age of the primary driver?

Once you provide this information, I'll use our quoting tool to generate a personalized insurance quote for you.
</example 5>
"""
```

Vorrai anche includere eventuali istruzioni importanti che delineino cosa fare e cosa non fare nel modo in cui Claude dovrebbe interagire con il cliente. Queste possono derivare dai guardrail del brand o dalle politiche di assistenza.

```python
ADDITIONAL_GUARDRAILS = """Please adhere to the following guardrails:
1. Only provide information about insurance types listed in our offerings.
2. If asked about an insurance type we don't offer, politely state
that we don't provide that service.
3. Do not speculate about future product offerings or company plans.
4. Don't make promises or enter into agreements it's not authorized to make.
You only provide information and guidance.
5. Do not mention any competitor's products or services.
"""
```

Ora combina tutte queste sezioni in un'unica stringa da usare come prompt.

```python
TASK_SPECIFIC_INSTRUCTIONS = " ".join(
    [
        STATIC_GREETINGS_AND_GENERAL,
        STATIC_CAR_INSURANCE,
        STATIC_ELECTRIC_CAR_INSURANCE,
        EXAMPLES,
        ADDITIONAL_GUARDRAILS,
    ]
)
```

### Aggiungi capacità dinamiche e agentiche con l'uso degli strumenti

Claude è in grado di eseguire azioni e recuperare informazioni in modo dinamico usando la funzionalità di uso degli strumenti lato client. Inizia elencando eventuali strumenti esterni o API che il prompt dovrebbe usare.

Per questo esempio, inizia con un solo strumento per calcolare il preventivo.

<Tip>
  Come promemoria, questo strumento non eseguirà il calcolo effettivo: segnalerà semplicemente all'applicazione che deve essere usato uno strumento con gli argomenti specificati.
</Tip>

Aggiungi il nome del modello, la definizione dello strumento e un'implementazione stub a `config.py`:

```python
import time

MODEL = "claude-opus-5-5"

TOOLS = [
    {
        "name": "get_quote",
        "description": "Calculate the insurance quote based on user input. Returned value is per month premium.",
        "input_schema": {
            "type": "object",
            "properties": {
                "make": {"type": "string", "description": "The make of the vehicle."},
                "model": {"type": "string", "description": "The model of the vehicle."},
                "year": {
                    "type": "integer",
                    "description": "The year the vehicle was manufactured.",
                },
                "mileage": {
                    "type": "integer",
                    "description": "The mileage on the vehicle.",
                },
                "driver_age": {
                    "type": "integer",
                    "description": "The age of the primary driver.",
                },
            },
            "required": ["make", "model", "year", "mileage", "driver_age"],
        },
    }
]


def get_quote(make, model, year, mileage, driver_age):
    """Returns the premium per month in USD"""
    # Puoi chiamare un endpoint HTTP o un database per ottenere la quotazione.
    # Qui simuliamo un ritardo di 1 secondo e restituiamo una quotazione fissa di 100.
    time.sleep(1)
    return 100
```

### Distribuisci i tuoi prompt

È difficile sapere quanto bene funzioni il tuo prompt senza distribuirlo in un ambiente di produzione di test ed [eseguire valutazioni](https://platform.claude.com/docs/it/test-and-evaluate/develop-tests). Costruisci una piccola applicazione usando il prompt, l'SDK Anthropic e Streamlit per l'interfaccia utente.

In un file chiamato `chatbot.py` (o il modulo equivalente nel tuo linguaggio), configura la classe ChatBot, che incapsulerà le interazioni con l'SDK Anthropic.

La classe dovrebbe avere due metodi principali: uno che chiama l'API per generare un messaggio e uno che elabora ogni input dell'utente in arrivo.

<CodeGroup exclude="shell">
  ```python Python
  # Nel tuo chatbot.py, importa questi dal config.py che hai scritto sopra:
  # from config import IDENTITY, TOOLS, MODEL, get_quote
  from anthropic import Anthropic
  from dotenv import load_dotenv

  load_dotenv()


  class ChatBot:
      def __init__(self, session_state):
          self.anthropic = Anthropic()
          self.session_state = session_state

      def generate_message(
          self,
          messages,
          max_tokens,
      ):
          try:
              response = self.anthropic.messages.create(
                  model=MODEL,
                  system=IDENTITY,
                  max_tokens=max_tokens,
                  messages=messages,
                  tools=TOOLS,
              )
              return response
          except Exception as e:
              return {"error": str(e)}

      def process_user_input(self, user_input):
          self.session_state.messages.append({"role": "user", "content": user_input})

          response_message = self.generate_message(
              messages=self.session_state.messages,
              max_tokens=2048,
          )

          if "error" in response_message:
              return f"An error occurred: {response_message['error']}"

          if response_message.content[-1].type == "tool_use":
              tool_use = response_message.content[-1]
              func_name = tool_use.name
              func_params = tool_use.input
              tool_use_id = tool_use.id

              result = self.handle_tool_use(func_name, func_params)
              self.session_state.messages.append(
                  {"role": "assistant", "content": response_message.content}
              )
              self.session_state.messages.append(
                  {
                      "role": "user",
                      "content": [
                          {
                              "type": "tool_result",
                              "tool_use_id": tool_use_id,
                              "content": f"{result}",
                          }
                      ],
                  }
              )

              follow_up_response = self.generate_message(
                  messages=self.session_state.messages,
                  max_tokens=2048,
              )

              if "error" in follow_up_response:
                  return f"An error occurred: {follow_up_response['error']}"

              response_text = next(
                  (
                      block.text
                      for block in follow_up_response.content
                      if block.type == "text"
                  ),
                  None,
              )
              if response_text is None:
                  raise Exception("An error occurred: Unexpected response type")
              self.session_state.messages.append(
                  {"role": "assistant", "content": response_text}
              )
              return response_text

          text_block = next(
              (block for block in response_message.content if block.type == "text"), None
          )
          if text_block is not None:
              response_text = text_block.text
              self.session_state.messages.append(
                  {"role": "assistant", "content": response_text}
              )
              return response_text

          raise Exception("An error occurred: Unexpected response type")

      def handle_tool_use(self, func_name, func_params):
          if func_name == "get_quote":
              premium = get_quote(**func_params)
              return f"Quote generated: ${premium:.2f} per month"

          raise Exception("An unexpected tool was used")
  ```

  ```typescript TypeScript
  import Anthropic from "@anthropic-ai/sdk";

  class ChatBot {
    // IDENTITY, MODEL, TOOLS e getQuote rispecchiano i valori di config.py definiti
    // in precedenza in questa guida (mostrati in Python).
    readonly anthropic = new Anthropic();
    readonly messages: Anthropic.MessageParam[] = [];

    async generateMessage(
      messages: Anthropic.MessageParam[],
      maxTokens: number
    ): Promise<Anthropic.Message> {
      return this.anthropic.messages.create({
        model: MODEL,
        system: IDENTITY,
        max_tokens: maxTokens,
        messages,
        tools: TOOLS
      });
    }

    async processUserInput(userInput: string): Promise<string> {
      this.messages.push({ role: "user", content: userInput });

      const responseMessage = await this.generateMessage(this.messages, 2048);

      const lastBlock = responseMessage.content.at(-1);
      if (lastBlock?.type === "tool_use") {
        const toolResult = this.handleToolUse(lastBlock.name, lastBlock.input);

        this.messages.push({ role: "assistant", content: responseMessage.content });
        this.messages.push({
          role: "user",
          content: [{ type: "tool_result", tool_use_id: lastBlock.id, content: toolResult }]
        });

        const followUpResponse = await this.generateMessage(this.messages, 2048);

        const followUpBlock = followUpResponse.content.find((block) => block.type === "text");
        if (!followUpBlock) {
          throw new Error("An error occurred: Unexpected response type");
        }
        this.messages.push({ role: "assistant", content: followUpBlock.text });
        return followUpBlock.text;
      }

      const firstBlock = responseMessage.content.find((block) => block.type === "text");
      if (firstBlock) {
        this.messages.push({ role: "assistant", content: firstBlock.text });
        return firstBlock.text;
      }

      throw new Error("An error occurred: Unexpected response type");
    }

    handleToolUse(toolName: string, toolInput: unknown): string {
      if (toolName === "get_quote") {
        // L'SDK tipizza tool_use.input come unknown; restringilo allo schema di get_quote.
        if (
          toolInput === null ||
          typeof toolInput !== "object" ||
          !("make" in toolInput) ||
          typeof toolInput.make !== "string" ||
          !("model" in toolInput) ||
          typeof toolInput.model !== "string" ||
          !("year" in toolInput) ||
          typeof toolInput.year !== "number" ||
          !("mileage" in toolInput) ||
          typeof toolInput.mileage !== "number" ||
          !("driver_age" in toolInput) ||
          typeof toolInput.driver_age !== "number"
        ) {
          throw new Error("An error occurred: Unexpected tool input");
        }
        const { make, model: vehicleModel, year, mileage, driver_age: driverAge } = toolInput;

        const premium = getQuote(make, vehicleModel, year, mileage, driverAge);
        return `Quote generated: $${premium.toFixed(2)} per month`;
      }

      throw new Error("An unexpected tool was used");
    }
  }
  ```

  ```csharp C#
  using System.Text.Json;
  using Anthropic;
  using Anthropic.Models.Messages;

  // Config.Model, Config.Identity, Config.Tools e Config.GetQuote rispecchiano
  // i valori di config.py definiti in precedenza in questa guida (mostrati in Python).
  public class ChatBot
  {
      private readonly AnthropicClient _anthropic = new();

      public List<MessageParam> Messages { get; } = [];

      public async Task<Message> GenerateMessage(List<MessageParam> messages, long maxTokens) =>
          await _anthropic.Messages.Create(
              new MessageCreateParams
              {
                  Model = Config.Model,
                  System = Config.Identity,
                  MaxTokens = maxTokens,
                  Messages = messages,
                  Tools = Config.Tools,
              }
          );

      public async Task<string> ProcessUserInput(string userInput)
      {
          Messages.Add(new() { Role = Role.User, Content = userInput });

          var responseMessage = await GenerateMessage(Messages, maxTokens: 2048);

          if (responseMessage.Content[^1].TryPickToolUse(out var toolUse))
          {
              var toolResult = HandleToolUse(toolUse.Name, toolUse.Input);

              Messages.Add(new()
              {
                  Role = Role.Assistant,
                  Content = responseMessage.Content
                      .Select(contentBlock => new ContentBlockParam(contentBlock.Json))
                      .ToList(),
              });
              Messages.Add(new()
              {
                  Role = Role.User,
                  Content = new List<ContentBlockParam>
                  {
                      new ToolResultBlockParam { ToolUseID = toolUse.ID, Content = toolResult },
                  },
              });

              var followUpResponse = await GenerateMessage(Messages, maxTokens: 2048);

              foreach (var block in followUpResponse.Content)
              {
                  if (block.TryPickText(out var followUpText))
                  {
                      Messages.Add(new() { Role = Role.Assistant, Content = followUpText.Text });
                      return followUpText.Text;
                  }
              }

              throw new InvalidOperationException("An error occurred: Unexpected response type");
          }

          foreach (var block in responseMessage.Content)
          {
              if (block.TryPickText(out var textBlock))
              {
                  Messages.Add(new() { Role = Role.Assistant, Content = textBlock.Text });
                  return textBlock.Text;
              }
          }

          throw new InvalidOperationException("An error occurred: Unexpected response type");
      }

      public string HandleToolUse(string funcName, IReadOnlyDictionary<string, JsonElement> funcParams)
      {
          if (funcName == "get_quote")
          {
              var premium = Config.GetQuote(
                  funcParams["make"].GetString()!,
                  funcParams["model"].GetString()!,
                  funcParams["year"].GetInt64(),
                  funcParams["mileage"].GetInt64(),
                  funcParams["driver_age"].GetInt64()
              );
              return $"Quote generated: ${premium:F2} per month";
          }

          throw new ArgumentException("An unexpected tool was used");
      }
  }
  ```

  ```go Go
  import (
  	"context"
  	"encoding/json"
  	"fmt"

  	"github.com/anthropics/anthropic-sdk-go"
  )

  // ChatBot incapsula il client Anthropic e la cronologia della conversazione. I
  // valori identity, model, tools e getQuote che usa rispecchiano le definizioni
  // di config.py viste prima in questa guida (mostrate in Python).
  type ChatBot struct {
  	client   anthropic.Client
  	messages []anthropic.MessageParam
  }

  func NewChatBot() *ChatBot {
  	return &ChatBot{client: anthropic.NewClient()}
  }

  func (bot *ChatBot) GenerateMessage(ctx context.Context, messages []anthropic.MessageParam, maxTokens int64) (*anthropic.Message, error) {
  	return bot.client.Messages.New(ctx, anthropic.MessageNewParams{
  		Model:     model,
  		System:    []anthropic.TextBlockParam{{Text: identity}},
  		MaxTokens: maxTokens,
  		Messages:  messages,
  		Tools:     tools,
  	})
  }

  func (bot *ChatBot) ProcessUserInput(ctx context.Context, userInput string) (string, error) {
  	bot.messages = append(bot.messages, anthropic.NewUserMessage(anthropic.NewTextBlock(userInput)))

  	response, err := bot.GenerateMessage(ctx, bot.messages, 2048)
  	if err != nil {
  		return "", err
  	}

  	lastBlock := response.Content[len(response.Content)-1]
  	if toolUse, ok := lastBlock.AsAny().(anthropic.ToolUseBlock); ok {
  		result, err := bot.HandleToolUse(toolUse.Name, toolUse.Input)
  		if err != nil {
  			return "", err
  		}

  		bot.messages = append(bot.messages,
  			response.ToParam(),
  			anthropic.NewUserMessage(anthropic.NewToolResultBlock(toolUse.ID, result, false)),
  		)

  		followUp, err := bot.GenerateMessage(ctx, bot.messages, 2048)
  		if err != nil {
  			return "", err
  		}

  		for _, block := range followUp.Content {
  			if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
  				bot.messages = append(bot.messages, anthropic.NewAssistantMessage(anthropic.NewTextBlock(textBlock.Text)))
  				return textBlock.Text, nil
  			}
  		}
  		return "", fmt.Errorf("an error occurred: unexpected response type")
  	}

  	for _, block := range response.Content {
  		if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
  			bot.messages = append(bot.messages, anthropic.NewAssistantMessage(anthropic.NewTextBlock(textBlock.Text)))
  			return textBlock.Text, nil
  		}
  	}

  	return "", fmt.Errorf("an error occurred: unexpected response type")
  }

  func (bot *ChatBot) HandleToolUse(toolName string, toolInput json.RawMessage) (string, error) {
  	if toolName != "get_quote" {
  		return "", fmt.Errorf("an unexpected tool was used: %s", toolName)
  	}

  	var input struct {
  		Make      string `json:"make"`
  		Model     string `json:"model"`
  		Year      int    `json:"year"`
  		Mileage   int    `json:"mileage"`
  		DriverAge int    `json:"driver_age"`
  	}
  	if err := json.Unmarshal(toolInput, &input); err != nil {
  		return "", err
  	}
  	premium := getQuote(input.Make, input.Model, input.Year, input.Mileage, input.DriverAge)
  	return fmt.Sprintf("Quote generated: $%.2f per month", premium), nil
  }
  ```

  ```java Java
  import com.anthropic.client.AnthropicClient;
  import com.anthropic.client.okhttp.AnthropicOkHttpClient;
  import com.anthropic.core.JsonValue;
  import com.anthropic.models.messages.ContentBlock;
  import com.anthropic.models.messages.ContentBlockParam;
  import com.anthropic.models.messages.Message;
  import com.anthropic.models.messages.MessageCreateParams;
  import com.anthropic.models.messages.MessageParam;
  import com.anthropic.models.messages.ToolResultBlockParam;
  import com.anthropic.models.messages.ToolUseBlock;

  // IDENTITY, MODEL, TOOLS e getQuote rispecchiano i valori di config.py definiti
  // in precedenza in questa guida (mostrati in Python).
  class ChatBot {
      final AnthropicClient anthropic;
      final List<MessageParam> messages;

      ChatBot() {
          // Legge la chiave API dalla variabile d'ambiente ANTHROPIC_API_KEY
          this.anthropic = AnthropicOkHttpClient.fromEnv();
          this.messages = new ArrayList<>();
      }

      Message generateMessage(List<MessageParam> messages, long maxTokens) {
          return anthropic.messages().create(MessageCreateParams.builder()
                  .model(MODEL)
                  .system(IDENTITY)
                  .maxTokens(maxTokens)
                  .messages(messages)
                  .tools(TOOLS)
                  .build());
      }

      String processUserInput(String userInput) {
          messages.add(MessageParam.builder()
                  .role(MessageParam.Role.USER)
                  .content(userInput)
                  .build());

          Message responseMessage = generateMessage(messages, 2048);

          List<ContentBlock> content = responseMessage.content();
          ContentBlock lastBlock = content.getLast();
          if (lastBlock.isToolUse()) {
              ToolUseBlock toolUse = lastBlock.asToolUse();
              Map<String, JsonValue> toolInput =
                      (Map<String, JsonValue>) toolUse._input().asObject().orElseThrow();
              String result = handleToolUse(toolUse.name(), toolInput);

              messages.add(MessageParam.builder()
                      .role(MessageParam.Role.ASSISTANT)
                      .contentOfBlockParams(content.stream().map(ContentBlock::toParam).toList())
                      .build());
              messages.add(MessageParam.builder()
                      .role(MessageParam.Role.USER)
                      .contentOfBlockParams(List.of(ContentBlockParam.ofToolResult(
                              ToolResultBlockParam.builder()
                                      .toolUseId(toolUse.id())
                                      .content(result)
                                      .build())))
                      .build());

              Message followUpResponse = generateMessage(messages, 2048);

              ContentBlock followUpBlock = followUpResponse.content().stream()
                      .filter(ContentBlock::isText)
                      .findFirst()
                      .orElseThrow(() -> new IllegalStateException("An error occurred: Unexpected response type"));
              String responseText = followUpBlock.asText().text();
              messages.add(MessageParam.builder()
                      .role(MessageParam.Role.ASSISTANT)
                      .content(responseText)
                      .build());
              return responseText;
          } else {
              ContentBlock textBlock = content.stream()
                      .filter(ContentBlock::isText)
                      .findFirst()
                      .orElseThrow(() -> new IllegalStateException("An error occurred: Unexpected response type"));
              String responseText = textBlock.asText().text();
              messages.add(MessageParam.builder()
                      .role(MessageParam.Role.ASSISTANT)
                      .content(responseText)
                      .build());
              return responseText;
          }
      }

      String handleToolUse(String funcName, Map<String, JsonValue> funcParams) {
          return switch (funcName) {
              case "get_quote" -> {
                  double premium = getQuote(
                          funcParams.get("make").asStringOrThrow(),
                          funcParams.get("model").asStringOrThrow(),
                          ((Number) funcParams.get("year").asNumber().orElseThrow()).longValue(),
                          ((Number) funcParams.get("mileage").asNumber().orElseThrow()).longValue(),
                          ((Number) funcParams.get("driver_age").asNumber().orElseThrow()).longValue());
                  yield "Quote generated: $%.2f per month".formatted(premium);
              }
              default -> throw new IllegalArgumentException("An unexpected tool was used");
          };
      }
  }
  ```

  ```php PHP
  use Anthropic\Client;
  use Anthropic\Messages\Message;
  use Anthropic\Messages\MessageParam;
  use Anthropic\Messages\TextBlock;
  use Anthropic\Messages\ToolResultBlockParam;
  use Anthropic\Messages\ToolUseBlock;

  class ChatBot
  {
      // MODEL, IDENTITY, TOOLS e get_quote() rispecchiano i valori di config.py
      // definiti in precedenza in questa guida (mostrati in Python).

      /** @var list<MessageParam> */
      public private(set) array $messages = [];

      public function __construct(
          private readonly Client $anthropic = new Client(),
      ) {}

      /**
       * @param list<MessageParam> $messages
       */
      public function generateMessage(array $messages, int $maxTokens): Message
      {
          return $this->anthropic->messages->create(
              model: MODEL,
              system: IDENTITY,
              maxTokens: $maxTokens,
              messages: $messages,
              tools: TOOLS,
          );
      }

      public function processUserInput(string $userInput): string
      {
          $this->messages[] = MessageParam::with(role: 'user', content: $userInput);

          $responseMessage = $this->generateMessage($this->messages, maxTokens: 2048);

          $content = $responseMessage->content;
          $lastBlock = array_last($content);

          if ($lastBlock instanceof ToolUseBlock) {
              $toolResult = $this->handleToolUse($lastBlock->name, $lastBlock->input);

              $this->messages[] = MessageParam::with(role: 'assistant', content: $content);
              $this->messages[] = MessageParam::with(
                  role: 'user',
                  content: [
                      ToolResultBlockParam::with(toolUseID: $lastBlock->id, content: $toolResult),
                  ],
              );

              $followUpResponse = $this->generateMessage($this->messages, maxTokens: 2048);

              $firstBlock = array_find(
                  $followUpResponse->content,
                  static fn ($block): bool => $block instanceof TextBlock,
              );
              if (!$firstBlock instanceof TextBlock) {
                  throw new \RuntimeException('An error occurred: Unexpected response type');
              }

              $this->messages[] = MessageParam::with(role: 'assistant', content: $firstBlock->text);

              return $firstBlock->text;
          }

          $firstBlock = array_find($content, static fn ($block): bool => $block instanceof TextBlock);
          if ($firstBlock instanceof TextBlock) {
              $this->messages[] = MessageParam::with(role: 'assistant', content: $firstBlock->text);

              return $firstBlock->text;
          }

          throw new \RuntimeException('An error occurred: Unexpected response type');
      }

      /**
       * @param array<string, mixed> $funcParams
       */
      private function handleToolUse(string $funcName, array $funcParams): string
      {
          if ($funcName === 'get_quote') {
              $premium = get_quote(...$funcParams);

              return sprintf('Quote generated: $%.2f per month', $premium);
          }

          throw new \RuntimeException('An unexpected tool was used');
      }
  }
  ```

  ```ruby Ruby
  # IDENTITY, MODEL, TOOLS e get_quote rispecchiano i valori di config.py definiti
  # in precedenza in questa guida (mostrati in Python).
  require "anthropic"

  class ChatBot
    attr_reader :messages

    def initialize
      @anthropic = Anthropic::Client.new
      @messages = []
    end

    def generate_message(messages, max_tokens)
      @anthropic.messages.create(
        model: MODEL,
        system_: IDENTITY,
        max_tokens:,
        messages:,
        tools: TOOLS
      )
    end

    def process_user_input(user_input)
      @messages << {role: "user", content: user_input}

      response_message = generate_message(@messages, 2048)

      case response_message.content
      in [*, Anthropic::ToolUseBlock => tool_use]
        result = handle_tool_use(tool_use.name, tool_use.input)
        @messages << {role: "assistant", content: response_message.content}
        @messages << {
          role: "user",
          content: [{type: "tool_result", tool_use_id: tool_use.id, content: result}]
        }

        follow_up_response = generate_message(@messages, 2048)

        case follow_up_response.content
        in [*, Anthropic::TextBlock => text_block, *]
          @messages << {role: "assistant", content: text_block.text}
          text_block.text
        else
          raise "An error occurred: Unexpected response type"
        end
      in [*, Anthropic::TextBlock => text_block, *]
        @messages << {role: "assistant", content: text_block.text}
        text_block.text
      else
        raise "An error occurred: Unexpected response type"
      end
    end

    def handle_tool_use(tool_name, tool_input)
      raise "An unexpected tool was used" unless tool_name == "get_quote"

      premium = get_quote(**tool_input)
      format("Quote generated: $%.2f per month", premium)
    end
  end
  ```
</CodeGroup>

### Costruisci la tua interfaccia utente

Prova a distribuire questo codice con Streamlit usando un metodo main. Questa funzione `main()` configura un'interfaccia di chat basata su Streamlit. Streamlit è un framework Python, quindi questa parte della guida è mostrata solo in Python; la classe ChatBot qui sopra è la parte che puoi portare in qualsiasi linguaggio.

Fallo in un file chiamato `app.py`

```python
import streamlit as st
from chatbot import ChatBot
from config import TASK_SPECIFIC_INSTRUCTIONS


def main():
    st.title("Chat with Eva, Acme Insurance Company's Assistant🤖")

    if "messages" not in st.session_state:
        st.session_state.messages = [
            {"role": "user", "content": TASK_SPECIFIC_INSTRUCTIONS},
            {"role": "assistant", "content": "Understood"},
        ]

    chatbot = ChatBot(st.session_state)

    # Mostra i messaggi di utente e assistente saltando i primi due
    for message in st.session_state.messages[2:]:
        # ignora i blocchi tool use
        if isinstance(message["content"], str):
            with st.chat_message(message["role"]):
                st.markdown(message["content"])

    if user_msg := st.chat_input("Type your message here..."):
        st.chat_message("user").markdown(user_msg)

        with st.chat_message("assistant"):
            with st.spinner("Eva is thinking..."):
                response_placeholder = st.empty()
                full_response = chatbot.process_user_input(user_msg)
                response_placeholder.markdown(full_response)


if __name__ == "__main__":
    main()
```

Esegui il programma con:

```bash
streamlit run app.py
```

### Valuta i tuoi prompt

Il prompting spesso richiede test e ottimizzazione per essere pronto per la produzione. Per determinare la maturità della tua soluzione, valuta le prestazioni del chatbot usando un processo sistematico che combina metodi quantitativi e qualitativi. Creare una [solida valutazione empirica](https://platform.claude.com/docs/it/test-and-evaluate/develop-tests#build-evaluations) basata sui criteri di successo che hai definito ti permetterà di ottimizzare i tuoi prompt.

### Migliora le prestazioni

In scenari complessi, può essere utile considerare strategie aggiuntive per migliorare le prestazioni oltre alle [tecniche di prompt engineering](https://platform.claude.com/docs/it/build-with-claude/prompt-engineering/overview) standard e alle [strategie di implementazione dei guardrail](https://platform.claude.com/docs/it/test-and-evaluate/strengthen-guardrails/reduce-hallucinations). Ecco alcuni scenari comuni:

#### Riduci la latenza dei contesti lunghi con RAG

Quando si gestiscono grandi quantità di contesto statico e dinamico, includere tutte le informazioni nel prompt può comportare costi elevati, tempi di risposta più lenti e il raggiungimento dei limiti della "context window" (finestra di contesto). In questo scenario, implementare tecniche di "Retrieval Augmented Generation" (generazione aumentata dal recupero), o RAG, può migliorare prestazioni ed efficienza.

Puoi creare un sistema più scalabile e reattivo convertendo le informazioni in rappresentazioni vettoriali con [modelli di embedding](https://platform.claude.com/docs/it/build-with-claude/embeddings), come quelli di Voyage AI di MongoDB. Questo approccio consente il recupero dinamico delle informazioni pertinenti in base alla richiesta corrente, invece di includere tutto il contesto possibile in ogni prompt.

È stato dimostrato che implementare RAG per i casi d'uso di assistenza aumenta l'accuratezza, riduce i tempi di risposta e riduce i costi API nei sistemi con requisiti di contesto estesi. Consulta la [ricetta RAG](https://platform.claude.com/cookbook/capabilities-retrieval-augmented-generation-guide) per un esempio completo.

#### Integra dati in tempo reale con l'uso degli strumenti

Quando si gestiscono richieste che necessitano di informazioni in tempo reale, come saldi dei conti o dettagli delle polizze, gli approcci RAG basati su embedding non sono sufficienti. L'uso degli strumenti può invece migliorare la capacità del tuo chatbot di fornire risposte accurate e in tempo reale. Ad esempio, puoi usare l'uso degli strumenti per cercare informazioni sui clienti, recuperare i dettagli degli ordini e annullare ordini per conto del cliente.

Questo approccio, [descritto nella ricetta sull'uso degli strumenti: agente del servizio clienti](https://platform.claude.com/cookbook/tool-use-customer-service-agent), ti consente di integrare dati in tempo reale nelle risposte di Claude e di offrire un'esperienza cliente più personalizzata ed efficiente.

#### Rafforza i guardrail di input e output

Quando distribuisci un chatbot, specialmente in scenari di servizio clienti, è importante prevenire i rischi associati a uso improprio, richieste fuori ambito e risposte inappropriate. Sebbene Claude sia intrinsecamente resiliente a tali scenari, ecco ulteriori passaggi per rafforzare i guardrail del tuo chatbot:

* [Riduci le allucinazioni](https://platform.claude.com/docs/it/test-and-evaluate/strengthen-guardrails/reduce-hallucinations): implementa meccanismi di verifica dei fatti e [citazioni](https://platform.claude.com/cookbook/misc-using-citations) per ancorare le risposte alle informazioni fornite.
* Verifica incrociata delle informazioni: verifica che le risposte dell'agente siano in linea con le politiche della tua azienda e con i fatti noti.
* Evita impegni contrattuali: assicurati che l'agente non faccia promesse né stipuli accordi che non è autorizzato a concludere.
* [Mitiga i jailbreak](https://platform.claude.com/docs/it/test-and-evaluate/strengthen-guardrails/mitigate-jailbreaks): usa metodi come filtri di innocuità e validazione dell'input per impedire agli utenti di sfruttare le vulnerabilità del modello allo scopo di generare contenuti inappropriati.
* Evita di menzionare i concorrenti: implementa un filtro sulle menzioni dei concorrenti per mantenere il focus sul brand e non menzionare prodotti o servizi di alcun concorrente.
* [Aumenta la coerenza dell'output](https://platform.claude.com/docs/it/test-and-evaluate/strengthen-guardrails/increase-consistency): impedisci a Claude di cambiare stile o uscire dal personaggio, anche durante interazioni lunghe e complesse.
* Rimuovi le informazioni di identificazione personale (PII): a meno che non sia esplicitamente richiesto e autorizzato, elimina qualsiasi PII dalle risposte.

#### Riduci il tempo di risposta percepito con lo streaming

Quando si gestiscono risposte potenzialmente lunghe, implementare lo "streaming" (streaming) può migliorare il coinvolgimento e la soddisfazione degli utenti. In questo scenario, gli utenti ricevono la risposta progressivamente invece di attendere che l'intera risposta venga generata.

Ecco come implementare lo streaming:

1. Usa l'[API di streaming di Anthropic](https://platform.claude.com/docs/it/build-with-claude/streaming) per supportare le risposte in streaming.
2. Configura il tuo frontend per gestire i blocchi di testo in arrivo.
3. Visualizza ogni blocco man mano che arriva, simulando la digitazione in tempo reale.
4. Implementa un meccanismo per salvare la risposta completa, consentendo agli utenti di visualizzarla se si allontanano e poi ritornano.

In alcuni casi, lo streaming consente l'uso di modelli più avanzati con latenze di base più elevate, poiché la visualizzazione progressiva mitiga l'impatto dei tempi di elaborazione più lunghi.

#### Scala il tuo chatbot

Man mano che la complessità del tuo chatbot cresce, l'architettura della tua applicazione può evolversi di conseguenza. Prima di aggiungere ulteriori livelli alla tua architettura, considera le seguenti opzioni meno onerose:

* Assicurati di sfruttare al massimo i tuoi prompt e di ottimizzarli tramite il prompt engineering. Usa le [guide al prompt engineering](https://platform.claude.com/docs/it/build-with-claude/prompt-engineering/overview) per scrivere i prompt più efficaci.
* Aggiungi ulteriori [strumenti](https://platform.claude.com/docs/it/agents-and-tools/tool-use/overview) al prompt (che possono includere [catene di prompt](https://platform.claude.com/docs/it/build-with-claude/prompt-engineering/claude-prompting-best-practices#chain-complex-prompts)) e verifica se riesci a ottenere la funzionalità richiesta.

Se il tuo chatbot gestisce attività estremamente varie, potresti considerare l'aggiunta di un [classificatore di intenti separato](https://platform.claude.com/cookbook/capabilities-classification-guide) per instradare la richiesta iniziale del cliente. Per l'applicazione esistente, ciò comporterebbe la creazione di un albero decisionale che instradi le richieste dei clienti attraverso il classificatore e poi verso conversazioni specializzate (con il proprio set di strumenti e prompt di sistema). Nota che questo metodo richiede una chiamata aggiuntiva a Claude che può aumentare la latenza.

### Integra Claude nel tuo flusso di lavoro di assistenza

Sebbene questi esempi si siano concentrati su funzioni Python richiamabili all'interno di un ambiente Streamlit, distribuire Claude per un chatbot di assistenza in tempo reale richiede un servizio API.

Ecco come puoi procedere:

1. Crea un wrapper API: sviluppa un semplice wrapper API attorno alla tua funzione di classificazione. Ad esempio, puoi usare Flask API o Fast API per racchiudere il tuo codice in un servizio HTTP. Il tuo servizio HTTP potrebbe accettare l'input dell'utente e restituire la risposta dell'Assistant nella sua interezza. Pertanto, il tuo servizio potrebbe avere le seguenti caratteristiche:

   * Server-Sent Events (SSE): gli SSE consentono lo streaming in tempo reale delle risposte dal server al client. Questo offre un'esperienza fluida e interattiva quando si lavora con gli LLM.
   * Caching: implementare il caching può migliorare i tempi di risposta e ridurre le chiamate API non necessarie.
   * Conservazione del contesto: mantenere il contesto quando un utente si allontana e poi ritorna è importante per la continuità delle conversazioni.

2. Costruisci un'interfaccia web: implementa un'interfaccia web intuitiva per interagire con l'agente basato su Claude.

## Passaggi successivi

<CardGroup cols={2}>
  <Card title="Uso degli strumenti" icon="wrench" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/overview">
    Dai a Claude accesso alle tue API in modo che possa agire per conto dei clienti.
  </Card>

  <Card title="Sviluppa test" icon="check" href="https://platform.claude.com/docs/it/test-and-evaluate/develop-tests">
    Crea valutazioni per misurare il tuo agente di assistenza rispetto ai criteri di successo che hai definito.
  </Card>

  <Card title="Streaming" icon="bolt" href="https://platform.claude.com/docs/it/build-with-claude/streaming">
    Trasmetti le risposte in streaming così che i clienti vedano le risposte man mano che vengono generate.
  </Card>

  <Card title="Prompt engineering" icon="lightbulb" href="https://platform.claude.com/docs/it/build-with-claude/prompt-engineering/overview">
    Perfeziona il tuo prompt di sistema e gli esempi per migliorare le prestazioni nelle attività.
  </Card>
</CardGroup>
