Bot AI - Strumenti personalizzati

:bookmark: Questa guida spiega come creare, configurare e integrare strumenti AI personalizzati all’interno del plugin Discourse AI, consentendo agli amministratori di estendere le capacità del bot con funzioni JavaScript definite dall’utente.

:person_raising_hand: Livello utente richiesto: Amministratore

Gli strumenti sono funzionalità programmabili che possono essere utilizzate dal bot AI per eseguire attività specifiche o recuperare informazioni oltre le semplici risposte basate su testo. Questi strumenti sono script o integrazioni che consentono al bot di interagire con API esterne, manipolare dati o eseguire funzioni aggiuntive per estenderne le capacità.

Sommario

Questa documentazione copre:

  • Creazione di un nuovo strumento AI personalizzato
  • Configurazione dei parametri e degli script dello strumento
  • API disponibili per gli script degli strumenti
  • Integrazione di strumenti personalizzati con le persona AI
  • Test e risoluzione dei problemi degli strumenti personalizzati

Creazione di un nuovo strumento AI personalizzato

Per creare un nuovo strumento AI:

  1. Naviga su Pannello Amministrazione > Plugin > Discourse AI > Strumenti (Tools)
  2. Clicca su “Nuovo Strumento” (New Tool) (puoi usare le preimpostazioni esistenti per imparare le opzioni)
  3. Compila i seguenti campi:
    • Nome (Name): Il nome dello strumento presentato all’LLM
    • Descrizione (Description): La descrizione dello strumento presentata all’LLM
    • Sommario (Summary): Riepilogo di ciò che fa lo strumento per assistere gli utenti (visualizzato nei dettagli)
    • Parametri (Parameters): Definisci gli input di cui il tuo strumento ha bisogno come presentati all’LLM
    • Script: Il codice JavaScript che alimenta il tuo strumento
  4. Clicca su “Salva” (Save)

Configurazione degli script degli strumenti

API disponibili

I tuoi script degli strumenti hanno accesso alle seguenti API:

  1. Richieste HTTP:

    http.get(url, options)
    http.post(url, options)
    http.put(url, options)
    http.patch(url, options)
    http.delete(url, options)
    

    Usale per interagire con servizi esterni. Puoi usare options per specificare intestazioni HTTP e corpo:

    http.get(url, { headers: { "Authorization": "Bearer key" } })
    http.post(url, { headers: { "Content-Type": "application/json" }, body: { key: "value" } })
    http.patch(url, { headers: { "Authorization": "Bearer key" }, body: "some body" })
    http.delete(url, { headers: { "Authorization": "Bearer key" } })
    http.put(url, { headers: { "Authorization": "Bearer key" }, body: "some body" })
    

    Tutti i metodi HTTP restituiscono { status: number, body: string }.

  2. Integrazione LLM (Language Model):

    llm.truncate(text, length)
    

    Tronca il testo a una lunghezza di token specificata in base al tokenizer dell’LLM configurato.

    llm.generate(prompt, options)
    

    Genera testo utilizzando l’LLM configurato. Il prompt può essere una semplice stringa o un oggetto strutturato come { messages: [{ type: "system", content: "..." }, { type: "user", content: "..." }] }. Le opzioni includono json: true per richiedere e analizzare automaticamente l’output JSON, oltre a temperature, top_p, max_tokens e stop_sequences.

  3. Integrazione caricamento personalizzato (RAG)

    index.search(query, { filenames: ["file.pdf"], limit: 10 })
    

    Cerca frammenti di documenti RAG indicizzati allegati a questo strumento. Restituisce Array<{ fragment: string, metadata: string | null }> ordinati per rilevanza. Il limite predefinito è 10, massimo 200.

    index.getFile(filename)
    

    Recupera il contenuto completo di un file RAG caricato tramite il suo nome esatto. Restituisce il testo completo o null se non trovato.

  4. Supporto per il caricamento (Upload)

    upload.create(filename, base_64_content)
    

    Crea un nuovo caricamento. Restituisce { id: number, url: string, short_url: string }.

    upload.getUrl(shortUrl)
    

    Dato un URL breve (es. upload://12345), restituisce l’URL completo compatibile con CDN.

    upload.getBase64(uploadIdOrShortUrl, maxPixels)
    

    Recupera il contenuto codificato in base64 di un caricamento esistente. Accetta un ID di caricamento (numero) o un URL breve (stringa). Parametro opzionale maxPixels per il ridimensionamento automatico delle immagini (default: 10.000.000).

  5. Controllo della catena di esecuzione (Execution chain control)

    chain.setCustomRaw(raw)
    

    Imposta il contenuto grezzo finale del post del bot e interrompe la catena di esecuzione dello strumento. Utile per strumenti che generano direttamente la risposta completa (ad esempio, strumenti di generazione di immagini).

  6. Gestione dei segreti (Secrets management)

    secrets.get(alias)
    

    Restituisce il valore della credenziale associata all’alias fornito. Gli alias sono definiti nella configurazione dei contratti segreti dello strumento e collegati ai Segreti AI nel pannello di amministrazione. Genera un errore se l’alias non è dichiarato, non è collegato o la credenziale è mancante.

    const apiKey = secrets.get("my_api_key");
    
  7. Integrazione Discourse

    Gli strumenti possono interagire direttamente con i dati di Discourse:

    discourse.baseUrl              // L'URL di base del sito
    discourse.search(params)       // Esegue una ricerca in Discourse
    discourse.getPost(post_id)     // Ottiene i dettagli del post (include il contenuto grezzo)
    discourse.getTopic(topic_id)   // Ottiene i dettagli del topic (tag, categoria, ecc.)
    discourse.getUser(id_or_username)  // Ottiene i dettagli dell'utente
    discourse.createTopic(params)  // Crea un nuovo topic
    discourse.createPost(params)   // Crea un nuovo post/risposta
    discourse.editPost(post_id, raw, options)    // Modifica il contenuto di un post
    discourse.editTopic(topic_id, updates, options) // Modifica le proprietà del topic (tag, categoria, visibilità)
    discourse.createChatMessage(params) // Invia un messaggio di chat
    discourse.createStagedUser(params)  // Crea un utente in attesa di conferma
    discourse.getAgent(name)       // Ottiene un altro agente AI (con metodo respondTo)
    discourse.updateAgent(name, updates) // Aggiorna la configurazione di un agente AI
    discourse.getCustomField(type, id, key)      // Legge un campo personalizzato su post/topic/utente
    discourse.setCustomField(type, id, key, value) // Imposta un campo personalizzato su post/topic/utente
    
  8. Oggetto Contesto (Context object)

    L’oggetto context fornisce informazioni su dove è in esecuzione lo strumento:

    • Contesto conversazione Bot: context.post_id, context.topic_id, context.private_message, context.participants, context.username, context.user_id
    • Contesto Chat: context.message_id, context.channel_id, context.username
    • Contesto Automazione: context.post_id, context.topic_id, context.username, context.user_id, context.feature_name, context.feature_context
    • Proprietà comuni: context.site_url, context.site_title, context.site_description

Funzioni richieste

Il tuo script deve implementare:

  • invoke(params): La funzione principale che viene eseguita quando viene chiamato lo strumento

Può implementare facoltativamente:

  • details(): Restituisce una stringa (può includere HTML di base) che descrive l’esecuzione dello strumento, visualizzata nell’interfaccia di chat
  • customSystemMessage(): Chiamata durante l’assemblaggio del prompt (non durante l’invocazione dello strumento). Restituisce una stringa aggiunta al prompt di sistema, o null/undefined per saltare. Ha accesso agli oggetti context, discourse e index.

Esempio di script:

function invoke(params) {
  let result = http.get("https://api.example.com/data?query=" + params.query);
  return JSON.parse(result.body);
}

function details() {
  return "Dati recuperati dall'API di Esempio";
}

Limitazioni e sicurezza

  • Timeout di Esecuzione: Timeout predefinito di 2000 ms di tempo di elaborazione dello script. Il timer si interrompe durante le richieste HTTP esterne (http.*) e le chiamate LLM (llm.generate), quindi conta solo il tempo di elaborazione dello script stesso.
  • Memoria: Limite massimo di heap V8 di 10MB
  • Richieste HTTP: Massimo 20 richieste per esecuzione dello strumento
  • Ambiente Sandboxed: Gli script vengono eseguiti in un ambiente JavaScript V8 ristretto (tramite MiniRacer). Nessun accesso alle globali del browser, al file system dell’host o alle librerie lato server. Le richieste di rete sono sottoposte a proxy tramite il backend di Discourse.

Test del tuo strumento

Dovresti testare ogni strumento che costruisci per assicurarti che i risultati forniti all’LLM corrispondano alle tue aspettative.

Integrazione degli strumenti con le persona AI

Per aggiungere il tuo strumento personalizzato a una Persona AI:

  1. Vai su Pannello Amministrazione > Plugin > Discourse AI > Persona (Personas)
  2. Modifica una persona esistente o creane una nuova
  3. Nella sezione “Strumenti” (Tools), vedrai elencati i tuoi strumenti personalizzati accanto agli strumenti predefiniti
  4. Seleziona il tuo strumento personalizzato per aggiungerlo alla persona

Strumenti personalizzati in azione

Una volta fornito lo strumento personalizzato al tuo LLM, questo può utilizzarlo per migliorare la conversazione.

Risoluzione dei problemi

Se il tuo strumento non funziona come previsto:

  1. Usa l’interfaccia di Test per assicurarti che si comporti come previsto per i tuoi input.
  2. Assicurati che il tuo gruppo sia in ai_bot_debugging_allowed_groups. I membri di questo gruppo hanno pieno accesso alle trascrizioni del bot; puoi visualizzare i log AI lì.
  3. Se sta succedendo qualcosa di inaspettato, visita https://NOME_SITO/logs per verificare la presenza di errori.

Risorse aggiuntive

14 Mi Piace

Mi sto avvicinando alla creazione di strumenti per le persone AI in Discourse, in parte per potermi concentrare davvero su questo; questo sembra molto utile dato quanti API utili e pubblici ci sono!

Ad esempio, sto ottenendo risultati come:

Comprensione del processo decisionale attraverso le strategie del poker AI

maiki:

Crea una scheda informativa per Breath of the Wild.

gpt-4o:

Ecco una scheda informativa per “The Legend of Zelda: Breath of the Wild”:


Titolo: The Legend of Zelda: Breath of the Wild
Sviluppatore: Nintendo
Editore: Nintendo
Data di uscita: 3 marzo 2017
Piattaforme: Nintendo Switch, Wii U
Genere: Avventura d’azione
Modalità: Giocatore singolo

Sinossi:
Ambientato in un vasto mondo aperto, i giocatori controllano Link, che si risveglia da un profondo sonno per sconfiggere Calamity Ganon e salvare il regno di Hyrule. Il gioco è elogiato per il suo ambiente immersivo, che consente ai giocatori di esplorare e interagire liberamente con il mondo e i suoi sistemi.

Premi:
Il gioco ha vinto numerosi premi, tra cui diversi riconoscimenti come Gioco dell’Anno, per il suo design innovativo, il mondo espansivo e il gameplay incantevole.

Maggiori informazioni: Wikidata Entry


“Breath of the Wild” è rinomato per aver ridefinito i giochi open-world e per aver offerto un’esperienza accattivante che incoraggia l’esplorazione e la scoperta.

maiki:

Lo stesso per Animal Crossing: New Horizons.

gpt-4o:

Ecco una scheda informativa per “Animal Crossing: New Horizons”:


Titolo: Animal Crossing: New Horizons
Sviluppatore: Nintendo
Editore: Nintendo
Data di uscita: 20 marzo 2020
Piattaforma: Nintendo Switch
Genere: Simulazione sociale
Modalità: Giocatore singolo, Multigiocatore

Sinossi:
In questo affascinante gioco di simulazione sociale, i giocatori assumono il ruolo di un personaggio personalizzabile che si trasferisce su un’isola deserta dopo aver acquistato un pacchetto da Tom Nook. Il gioco consente l’esplorazione in tempo reale, la raccolta di risorse, la creazione e la personalizzazione, promuovendo un’esperienza di gioco comunitaria e rilassante.

Premi:
Il gioco è stato acclamato per la sua libertà creativa e la tempistica di uscita, ricevendo riconoscimenti come Gioco dell’Anno e per i suoi contributi ai giochi sociali durante la pandemia globale.

Maggiori informazioni: Wikidata Entry


“Animal Crossing: New Horizons” è diventato un fenomeno culturale, celebrato per le sue coinvolgenti funzionalità sociali e il gameplay antistress durante i periodi difficili.

maiki:

A long way from Chicago

gpt-4o:

Ecco una scheda informativa per il libro “A Long Way from Chicago”:


Titolo: A Long Way from Chicago
Autore: Richard Peck
Anno di pubblicazione: 1998
Genere: Narrativa storica, Young Adult
ISBN: 978-0141303529

Sinossi:
Questo romanzo, vincitore del Newbery Honor, è una raccolta di racconti che narrano i viaggi estivi annuali di Joey e sua sorella Mary Alice da Chicago a una città rurale dell’Illinois per visitare la loro esuberante nonna Dowdel alla fine degli anni '20 e '30. Ogni capitolo presenta un episodio divertente e toccante che impartisce lezioni di vita sullo sfondo della Grande Depressione.

Premi:
Il libro è stato insignito del Newbery Honor nel 1999 ed è celebrato per il suo umorismo, la profondità e la rappresentazione della vita rurale americana all’inizio del XX secolo.

Maggiori informazioni: Wikidata Entry


Questo libro è apprezzato per la sua narrazione nostalgica e commovente, che cattura l’essenza dei legami familiari e dei tempi più semplici.

maiki:

Thinking in Bets

gpt-4o:

In precedenza ho trovato la voce Wikidata per “Thinking in Bets”, ma al momento non sono in grado di recuperare ulteriori dettagli specifici direttamente da Wikidata. Tuttavia, ecco una breve scheda basata sulle informazioni disponibili:


Titolo: Thinking in Bets: Making Smarter Decisions When You Don’t Have All the Facts
Autore: Annie Duke
Anno di pubblicazione: 2018
Genere: Saggistica, Processo decisionale, Psicologia
ISBN: 978-0735216358

Sinossi:
Il libro sfrutta le intuizioni del poker per aiutare i lettori a comprendere il processo decisionale in condizioni di incertezza. Annie Duke, unendo le sue esperienze di giocatrice di poker professionista e psicologa cognitiva, offre un quadro per prendere decisioni più intelligenti, valutare i risultati e adottare una mentalità probabilistica.

Maggiori informazioni: Wikidata Entry


Per approfondimenti, potresti considerare di consultare risorse o database aggiuntivi relativi alle pubblicazioni di libri.


Va bene, questo va bene, ma ho notato questa descrizione…

…e mi chiedo: dovrei costruire i miei prompt facendo riferimento diretto a quegli strumenti, per un uso efficiente?

Il mio approccio generale alla scrittura dei prompt è quello di affinare nel tempo e poi concentrarmi su uno schema di comportamento che desidero che gli strumenti AI adottino. Tuttavia, se potessi aggiungere istruzioni specifiche su, ad esempio, quando cercare un’entità Wikidata e quando elencare tutte le affermazioni di una particolare entità (due API diverse), allora sento che potrei affinare l’intero flusso di lavoro come intendo… :star_struck:

4 Mi Piace

Spiegare chiaramente lo strumento e fornire esempi nel prompt di sistema è effettivamente vantaggioso.

2 Mi Piace

È possibile inserire la chiave API e il progetto OpenAI dalle impostazioni dell’amministratore in uno strumento personalizzato?

1 Mi Piace

Puoi effettuare chiamate REST da uno strumento personalizzato e specificare tutte le intestazioni

2 Mi Piace

mi sono appena reso conto che lol… scusa per il lapsus

1 Mi Piace

Ho caricato alcuni documenti su una persona, ha generato gli embedding e ora può eseguire ricerche semantiche su di essi. Ma in alcuni casi, la ricerca semantica non è l’ideale, quindi vorrei migliorarla e avere una ricerca ibrida, ad esempio mantenere ciò che c’è già e aggiungere la ricerca per parole chiave. Al momento, se volessi farlo, dovrei scrivere uno strumento personalizzato, giusto?
So che potrei semplicemente pubblicare i documenti come argomenti e poi funzionerebbe subito con la ricerca nativa di Discourse, ma al momento non è un’opzione.

Sto riscontrando un errore dello schema dello strumento durante l’aggiunta di uno strumento personalizzato con un parametro di tipo array. Errore all’avvio della conversazione:

{
“error”: {
“code”: 400,
“message”: “* GenerateContentRequest.tools[0].function_declarations[3].parameters.properties[properties].items: campo mancante.\n”,
“status”: “INVALID_ARGUMENT”
}
}

Cosa ho provato:

  • Creato uno strumento personalizzato con un parametro denominato properties di tipo array.
  • L’interfaccia utente dell’elenco dei parametri non consente di specificare gli elementi (items).
  • Esportato/importato un JSON completo dello strumento che include items: { type: “string” } per properties.
  • Dopo l’importazione, l’errore persiste non appena lo strumento viene abilitato per una persona. Se rimuovo lo strumento, il bot funziona.

Previsto:

L’interfaccia utente dei parametri dovrebbe consentire la definizione dei tipi di elementi dell’array, oppure l’importazione dovrebbe rispettare gli elementi in modo che lo schema sia convalidato.

Qualcuno ha riscontrato questo problema? Esiste una limitazione nota o un percorso dell’interfaccia utente richiesto per definire i parametri di tipo array?

1 Mi Piace