Intermedio 16 minSupport

Assistenza clienti multilingue con LLM locale: 6 lingue senza cloud

Gestisci un servizio di assistenza clienti che riceve ticket in francese, inglese, spagnolo, tedesco, italiano e arabo. Inviare ogni messaggio a un'API cloud significa esporre email, numeri d'ordine e talvolta dati personali a una terza parte — e pagare per token. Questa guida mostra come realizzare un chatbot di assistenza clienti multilingue al 100% locale con Qwen 3.8 27B, rilevamento automatico della lingua, tono adattato a ogni cultura e integrazione diretta con Zendesk o Freshdesk tramite webhook.

Di Marie L.·Agg. 2026-08-27·Testato su Windows, macOS e Linux

#Perché un LLM locale per il supporto multilingue

Le API cloud (GPT-4o, Claude, Gemini) fatturano per token e impongono il trasferimento dei messaggi dei clienti al di fuori dell'UE. Per un servizio di assistenza B2C che gestisce 5.000 ticket al giorno, la fattura mensile supera rapidamente i 1.500 € e rispettare il GDPR diventa un esercizio acrobatico non appena un cliente invia un IBAN o un numero di previdenza sociale nel corpo del ticket.

Un LLM locale risolve entrambi i problemi in un colpo solo. Qwen 3.8 27B (Alibaba, uscito il 14 agosto 2026) supporta nativamente più di 100 lingue, gestisce le sei lingue europee del brief con una qualità che rivaleggia con quella dei modelli cloud di fascia base e gira su una sola RTX 4090 o un Mac M4 Max. Costo marginale per ticket: zero.

i
Perché proprio Qwen 3.8 27B
È il modello generalista di punta di Alibaba per il 2026: finestra di contesto di 262.000 token, visione e licenza Apache 2.0 (uso commerciale libero). Per l'assistenza, questo contesto enorme permette di inserire l'intera cronologia di un ticket senza troncarla, e la qualità multilingue resta la migliore della sua categoria (18 GB in Q4, entra in una scheda da 24 GB). Un'impostazione da conoscere: imposta il suo livello di ragionamento su « low ». Per impostazione predefinita ragiona troppo, aumentando inutilmente la latenza nelle risposte di assistenza.

#Prerequisiti

Il kit IA Locale in Azienda

Implementare un'IA locale sul lavoro: GDPR, AI Act, architettura multiutente, costi, nota per la direzione.

  • Spazio online a vita
  • PDF + file
  • Aggiornamenti a vita
GPU con almeno 24 GB di VRAM
RTX 3090, 4090, 5090, o Mac M3/M4 Max con 32 GB di memoria unificata. Qwen 3.8 27B in Q4_K_M occupa circa 18 GB.
Ollama installato
Versione recente per il supporto nativo di Qwen 3.8 (visione e contesto lungo).
Un account Zendesk o Freshdesk
Con i diritti amministrativi per creare un'integrazione webhook e un trigger.
Un endpoint HTTPS accessibile
Un VPS che funge da reverse proxy verso il tuo Ollama, oppure ngrok / Cloudflare Tunnel per esporre il server locale.
Python 3.11+
Per lo strato di rilevamento della lingua e il router dei webhook. FastAPI + langdetect sono sufficienti.

#1. Installare Qwen 3.8 27B con Ollama

Il modello è disponibile direttamente nella libreria Ollama. Avvia il download e un test rapido:

Terminale
ollama pull qwen3.8:27b
ollama run qwen3.8:27b "Réponds en une phrase : qu'est-ce qu'un LLM open-weight ?"

Il pull scarica circa 18 GB. Su una RTX 4090, l'inferenza raggiunge 40–60 token/secondo in Q4, sufficienti per generare una risposta di assistenza in 3–5 secondi. Con il livello di ragionamento impostato su « low », la latenza si riduce ulteriormente.

→
Testare subito le capacità multilingui
Poni la stessa domanda in 6 lingue di seguito con ollama run. Qwen 3.8 non passa in modo latente da una lingua all'altra, a differenza delle precedenti generazioni di Llama, che talvolta scivolavano verso l'inglese. È esattamente ciò che vogliamo per l'assistenza clienti.

Esponi Ollama sulla rete perché il tuo webhook possa raggiungerlo:

systemd override
sudo systemctl edit ollama
# Ajoutez :
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_KEEP_ALIVE=30m"

sudo systemctl restart ollama

OLLAMA_KEEP_ALIVE=30m mantiene il modello in VRAM per 30 minuti dopo l'ultima richiesta, evitando così un cold start per ogni ticket durante le ore di scarsa attività.

#2. Rilevazione automatica della lingua

Prima di inviare un messaggio a Qwen3, se ne identifica la lingua per scegliere il prompt di sistema corretto. La libreria fast-langdetect (basata su fastText di Meta) rileva 176 lingue in meno di 5 ms per richiesta, con una precisione superiore al 99% su messaggi di più di 50 caratteri.

Installazione
pip install fast-langdetect fastapi uvicorn httpx
detector.py
from fast_langdetect import detect

SUPPORTED = {"fr", "en", "es", "de", "it", "ar"}

def detect_language(text: str) -> str:
    text = text.replace("\n", " ").strip()
    if len(text) < 10:
        return "en"  # message trop court, fallback raisonnable
    result = detect(text, low_memory=False)
    lang = result["lang"]
    return lang if lang in SUPPORTED else "en"
!
Trappola dei messaggi misti
Un cliente francese che incolla un messaggio di errore in inglese può indurre il rilevatore a identificare la lingua sbagliata. Rileva la lingua solo nel primo paragrafo (prima della prima riga vuota), non nell'intero messaggio. Altrimenti rispondi in inglese a un cliente francofono.

#3. Prompt di sistema per lingua e tono adeguato

Un buon servizio di assistenza multilingue non traduce un prompt dal francese all'inglese: adatta il registro. Il francese professionale usa il « vous » come forma di cortesia, l'inglese aziendale resta più diretto, il tedesco richiede una cortesia formale marcata, lo spagnolo latinoamericano accetta più calore, l'italiano è più espressivo e l'arabo richiede formule di cortesia all'inizio e alla fine del messaggio.

prompts.py
SYSTEM_PROMPTS = {
    "fr": (
        "Tu es un agent de support client professionnel. "
        "Réponds en français, avec vouvoiement systématique. "
        "Sois concis, empathique, factuel. Ne promets jamais de remboursement "
        "sans validation. Si tu ne sais pas, propose une escalade humaine."
    ),
    "en": (
        "You are a professional customer support agent. "
        "Reply in English, business-friendly tone, direct and concise. "
        "Never commit to a refund without confirmation. "
        "Escalate to a human if uncertain."
    ),
    "es": (
        "Eres un agente de soporte profesional. Responde en español, "
        "trato de usted, tono cálido pero conciso. Nunca prometas reembolsos "
        "sin confirmación. Escala a un humano en caso de duda."
    ),
    "de": (
        "Du bist ein professioneller Kundensupport-Agent. Antworte auf Deutsch "
        "mit Sie-Form, höflich-formell, präzise und sachlich. Versprich nie eine "
        "Rückerstattung ohne Bestätigung. Eskaliere im Zweifel an einen Menschen."
    ),
    "it": (
        "Sei un agente di assistenza clienti professionale. Rispondi in italiano, "
        "forma di cortesia (Lei), tono cordiale e conciso. Mai promettere rimborsi "
        "senza conferma. Scala a un umano in caso di dubbio."
    ),
    "ar": (
        "أنت موظف دعم عملاء محترف. أجب باللغة العربية الفصحى، "
        "بأسلوب رسمي ومهذب يبدأ بتحية وينتهي بعبارة لطيفة. "
        "لا تعد بأي استرداد دون تأكيد. إذا لم تكن متأكدًا، اطلب تدخل موظف بشري."
    ),
}
→
Regole di salvaguardia operative nel prompt
Le tre righe "non promettere mai un rimborso", "se non sai rispondere, passa il caso al livello di assistenza superiore", "non concedere sconti" sono le uniche che impediscono a un LLM di causare danni reali nell'assistenza clienti. Inseriscile in tutte le lingue. Il tono cambia, le regole operative no.

#4. Integrare un webhook Zendesk o Freshdesk

Zendesk e Freshdesk attivano un webhook HTTP POST per ogni nuovo ticket. Si espone un endpoint FastAPI che rileva la lingua, sceglie il prompt, chiama Ollama e restituisce la risposta all'API del supporto affinché venga aggiunta come commento interno (l'agente umano la approva prima dell'invio).

webhook_server.py
from fastapi import FastAPI, Request
import httpx
from detector import detect_language
from prompts import SYSTEM_PROMPTS

app = FastAPI()
OLLAMA_URL = "http://localhost:11434/api/chat"

@app.post("/webhook/zendesk")
async def handle_ticket(req: Request):
    payload = await req.json()
    ticket_id = payload["ticket"]["id"]
    message = payload["ticket"]["description"]

    lang = detect_language(message)
    system = SYSTEM_PROMPTS[lang]

    async with httpx.AsyncClient(timeout=60) as client:
        r = await client.post(OLLAMA_URL, json={
            "model": "qwen3.8:27b",
            "messages": [
                {"role": "system", "content": system},
                {"role": "user", "content": message},
            ],
            "stream": False,
            "options": {"temperature": 0.3, "num_ctx": 8192},
        })
    draft = r.json()["message"]["content"]

    # Ajoute la réponse en note interne sur le ticket
    await post_internal_note(ticket_id, lang, draft)
    return {"status": "ok", "lang": lang}

La funzione post_internal_note pubblica la bozza come commento privato tramite l'API Zendesk (PUT /api/v2/tickets/{id}.json) o Freshdesk (POST /api/v2/tickets/{id}/notes). L'agente umano la rilegge, la modifica e clicca su "Invia". Risparmi circa il 60% del tempo di redazione senza mai lasciare che il bot risponda da solo.

  1. 01
    Esporre l'endpoint
    Cloudflare Tunnel o ngrok punta a http://localhost:8000. Annota l'URL pubblico HTTPS.
  2. 02
    Creare la destinazione webhook
    In Zendesk Admin → Applicazioni e integrazioni → Webhooks, crea una destinazione con il tuo URL e il metodo POST.
  3. 03
    Collegare un trigger
    In Triggers, condizione "Ticket Created", azione "Notify webhook" con un payload JSON contenente {ticket: {id, description, requester}}.
  4. 04
    Testare con un ticket fittizio
    Crea un ticket in tedesco. L'endpoint deve ricevere l'evento, rilevare "de" e pubblicare una bozza in tedesco nelle note interne.
  5. 05
    Attivare progressivamente in produzione
    Inizia con una sola coda (ad esempio la coda spagnola). Misura la qualità per una settimana. Estendi l'uso una coda alla volta.
!
Non rispondere mai direttamente al cliente
Il LLM redige, una persona verifica e approva. Questa è la regola. Se Qwen 3.8 genera un numero d'ordine inesistente o inventa una politica di rimborso, il risultato è una recensione Trustpilot a 1 stella. Finché non hai raccolto 6 mesi di misurazioni della qualità per ogni lingua, resta in modalità bozza.

#5. Misurare la qualità per lingua

Qwen 3.8 non offre la stessa qualità nelle sei lingue. Il francese e l'inglese sono eccellenti, lo spagnolo e l'italiano molto buoni, il tedesco discreto, l'arabo variabile a seconda del dialetto (l'arabo standard MSA funziona bene, i dialetti maghrebini meno). Servono misurazioni per orientare le scelte.

Tre indicatori da registrare per lingua, già dal primo giorno:

Tasso di approvazione senza modifiche
Percentuale di bozze che l'agente invia senza modifiche. È l'indicatore più semplice e significativo. Obiettivo: 40–60 % a 3 mesi.
Tasso di modifica (parole cambiate / parole generate)
Misura con un diff tra la risposta finale e la bozza. Se in una lingua le modifiche superano il 30 %, il prompt va rielaborato.
CSAT per lingua
Il sondaggio di soddisfazione dopo la risoluzione del ticket, incrociato con la lingua del ticket. Se il tedesco scende a 3,5/5 mentre il francese rimane a 4,5, hai un problema di tono.
i
Caso concreto di aggiustamento
In un deployment reale presso un e-commerce francese esteso alla Germania, il tasso di validazione in tedesco ristagnava al 18%. Causa identificata: il prompt tradotto letteralmente diceva "sii empatico". Nel tedesco aziendale, "empathisch" suona come un termine da terapeuta. Sostituito con "verbindlich und lösungsorientiert" (coinvolgente e orientato alle soluzioni) → 45% in due settimane.

#Insidie comuni

Il bot risponde nella lingua sbagliata
È quasi sempre un messaggio misto (firma in inglese sotto un ticket in francese). Rileva la lingua dal primo paragrafo, oppure imposta la lingua della bozza con un'istruzione esplicita "Reply in {lang}" oltre al prompt di sistema.
Latenza > 10 secondi
Verifica che OLLAMA_KEEP_ALIVE sia attivo e che il modello rimanga in VRAM. ollama ps deve mostrare il 100 % GPU. Se no, riduci num_ctx a 4096 per i ticket brevi.
Risposte in arabo formattate male (RTL)
Qwen3 genera bene testi in arabo, ma alcune interfacce di supporto non visualizzano automaticamente il testo da destra a sinistra (RTL). Aggiungi dir="rtl" lang="ar" al blocco di risposta in Zendesk/Freshdesk.
Allucinazione di promozioni inesistenti
Riduci la temperature a 0.2 e specifica nel prompt: "non menzionare alcuna promozione o codice sconto a meno che non sia presente nel ticket". Il LLM ama offrire regali che non esistono.
Webhook eseguito più volte
Zendesk può riprovare in caso di timeout. Salva ticket_id in Redis con un TTL di 10 minuti per garantire l'idempotenza — altrimenti generi 3 bozze per lo stesso ticket.

#Per approfondire

Una volta che la base è stabile, due estensioni aumentano notevolmente il tasso di validazione: collegare un RAG locale alla tua base di conoscenze (FAQ, politica di reso, condizioni di garanzia) per ancorare le risposte ai fatti, e aggiungere uno strato di fine-tuning LoRA su alcune migliaia di ticket risolti per adattare il tono a quello aziendale. Per la messa in produzione su più postazioni, il deployment in intranet dietro Nginx copre gli aspetti di rete e autenticazione.

Questa guida ti è stata utile?

Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.