# Knowledge Base

La knowledge base di Cognitor Assistant è organizzata in quattro componenti principali:

knowledge/
├── intents/          # Definizioni NLU (YAML)
├── rules/            # Mappatura intent → risposte (YAML)
├── responses/        # Template delle risposte (YAML)
└── conversations/    # Storie di conversazione (YAML)

Intents (`knowledge/intents/`)

Gli intenti definiscono cosa l'utente vuole fare. Ogni file YAML contiene un array di intenti con esempi di frasi.

Struttura

yaml
nlu:
  intents:
  - intent: greeting
    examples:
    - ciao
    - salve
    - buongiorno
  - intent: book_restaurant
    examples:
    - voglio prenotare un ristorante
    - prenota un tavolo

Annotazioni NER negli Esempi

Gli esempi possono contenere annotazioni per il riconoscimento delle entità:

yaml
nlu:
  intents:
  - intent: cerca_evento
    examples:
    - cerca evento [musicale](TYPE) a [Roma](LOCATION)
    - eventi [sportivi](TYPE) a [Milano](LOCATION)

Entità supportate:

  • [Mario](PERSON) - Persona
  • [Roma](LOCATION) - Località
  • [Juventus](TEAM) - Squadra sportiva
  • [oggi](DATE) - Data
  • [Python](PRODUCT) - Prodotto
  • [10](TIME) - Orario

Nomenclatura

  • Intent: snake_case (es. prenota_ristorante)
  • Slot: MAIUSCOLO (es. NUMERO_PERSONE)
  • Response key: __response

Rules (`knowledge/rules/`)

Le rules definiscono la mappatura tra intenti e risposte, con supporto per slot e condizioni.

Struttura Semplice

yaml
rules:
  greeting:
    default: greeting_response

Slot Required

yaml
rules:
  prenota_ristorante:
    slots:
      NUMERO_PERSONE:
        required: true
        type: integer
      DATA:
        required: true
        type: string
    default: prenota_ristorante_default_response
    wait: prenota_ristorante_wait_response
    fallback: prenota_ristorante_fallback_response

Slot Opzionali

yaml
rules:
  invia_messaggio:
    slots:
      DESTINATARIO:
        required: true
        type: string
        entity: PERSON
      MESSAGGIO:
        required: false
        type: string
    default: invia_messaggio_response

Slot con Cases

yaml
rules:
  cerca_meteo:
    slots:
      CITTA:
        required: true
        type: string
        entity: LOCATION
    cases:
      Roma: meteo_roma_response
      Milano: meteo_milano_response
      Napoli: meteo_napoli_response
    fallback: meteo_non_supportato_response
    wait: meteo_citta_wait_response

Bot Slots (set_slots)

Per impostare slot automaticamente dalla risposta:

yaml
rules:
  conferma_ordine:
    default: conferma_ordine_response
    set_slots:
      ORDINE_CONFERMATO: true
      DATA_CONFERMA: "$timestamp"

Responses (`knowledge/responses/`)

Le responses contengono i template delle risposte che l'assistente può dare.

Struttura

yaml
responses:
  greeting_response:
    - "Ciao! Come posso aiutarti?"
    - "Hey! Sono qui per te."

  book_restaurant_roma_response:
    - "Ottima scelta! A Roma ci sono ristoranti eccellenti. Quante persone siete?"

Placeholder

Le risposte possono contenere placeholder che vengono sostituiti dinamicamente:

  • {SLOT_NAME} - Sostituito con il valore dello slot
  • $timestamp - Data/ora corrente
  • {ALTRO_SLOT} - Riferimento ad altro slot

Risposte con Slot Inline

yaml
responses:
  conferma_ordine_response:
    - "Ho confermato il tuo ordine per {NUMERO_PERSONE} persone."

Conversations (`knowledge/conversations/`)

Le conversation definiscono flussi di dialogo completi per il training della Dialogue Policy.

Struttura

yaml
conversations:
  prenotazione_ristorante_flow:
    description: "Flusso completo prenotazione ristorante"
    steps:
      - user: greeting
        bot: greeting_response
      - user: cerca_ristorante
        bot: cerca_ristorante_response
      - user: prenota_ristorante
        bot: prenota_ristorante_response
      - user: conferma_prenotazione
        bot: conferma_prenotazione_response
      - user: farewell
        bot: farewell_response

Gestione degli Slot

Gli slot permettono di raccogliere informazioni strutturate dall'utente.

Slot Types

  • required: Obbligatorio, il bot chiede se mancante
  • optional: Opzionale, il bot procede senza

Bot Slots

  • Impostati automaticamente dalla rule (set_slots)
  • Estratti inline dalla response

Logica di Selezione Risposta

  1. Se slot richiesto mancante → rispondi con wait
  2. Se slot fornito, cerca nei cases → risposta specifica
  3. Se non trovato → fallback
  4. Altrimenti → default

Operazioni Custom

Le operazioni permettono di eseguire codice Python durante la generazione della risposta.

Metodo 1: Classe Operation

Crea un file in agent/operations/:

python
from agent.operations.base import Operation

class Calculate(Operation):
    @property
    def name(self) -> str:
        return "calculate"

    def execute(self, intent_name: str, slots: dict = None) -> dict:
        expression = slots.get("expression", "0")
        
        try:
            result = eval(expression, {"__builtins__": {}}, {})
            return {
                "response": f"Il risultato è: {result}",
                "slots": {"result": result},
                "metadata": {}
            }
        except Exception as e:
            return {
                "response": f"Errore nel calcolo: {e}",
                "slots": {},
                "metadata": {}
            }

Metodo 2: Funzione

python
def action_geocode(address: str, slots: dict, entity_manager) -> dict:
    # Logica di geocoding
    return {
        "response": f"Coordinate per {address}: 41.9028, 12.4964",
        "slots": {},
        "metadata": {}
    }

Richiamare l'operazione nella Rule

yaml
rules:
  calcola:
    default: __calculate

Il prefisso __ indica che è un'operazione.

Auto-discovery

Il sistema fa auto-discovery delle operations nella cartella agent/operations/:

  • Supporta classi che ereditano da Operation
  • Supporta funzioni con pattern action_* o *_action

Aggiunta di Nuovi Intenti

Step 1: Definire gli esempi in `knowledge/intents/`

Crea o modifica un file in knowledge/intents/:

yaml
# knowledge/intents/my_intents.yaml
nlu:
  intents:
  - intent: my_new_intent
    examples:
    - esempio uno
    - esempio due
    - altra frase di esempio

Step 2: Definire la rule in `knowledge/rules/`

Crea o modifica un file in knowledge/rules/:

yaml
# knowledge/rules/my_rules.yaml
rules:
  my_new_intent:
    default: my_new_intent_response

Step 3: Definire la response in `knowledge/responses/`

Crea o modifica un file in knowledge/responses/:

yaml
# knowledge/responses/my_responses.yaml
responses:
  my_new_intent_response:
    - "Hai attivato il nuovo intent!"
    - "Ecco la risposta per il tuo nuovo intent."

Step 4: Riaddestrare i modelli

bash
python -m pipeline

Best Practices

  1. Esempi Diversificati: Fornire almeno 10-20 esempi per intent, coprendo diverse formulazioni
  2. Risposte Multiple: Definire almeno 2-3 varianti per ogni risposta per rendere la conversazione più naturale
  3. Gestione Errori: Sempre definire una risposta di fallback
  4. Slot Obbligatori: Usare wait quando un'informazione è necessaria
  5. Ordine dei file: Mantieni i file base in knowledge/base.yaml, aggiungi file specifici per dominio (es. culture.yaml, command.yaml)

Testing

bash
# Test conversazione
python -m agent.agent

# Test modello
pytest tests/

Debug

Il sistema stampa informazioni di debug durante l'esecuzione:

  • Intent predetto e confidenza
  • Entità estratte
  • Slot attesi e ricevuti
  • Risposta generata