Bot IA - Outils personnalisés

:bookmark: Ce guide explique comment créer, configurer et intégrer des outils d’IA personnalisés dans le plugin Discourse AI, permettant aux administrateurs d’étendre les capacités du bot avec des fonctions JavaScript définies par l’utilisateur.

:person_raising_hand: Niveau d’utilisateur requis : Administrateur

Les outils sont des fonctionnalités programmables que le bot d’IA peut utiliser pour effectuer des tâches spécifiques ou récupérer des informations au-delà de simples réponses textuelles. Ces outils sont des scripts ou des intégrations qui permettent au bot d’interagir avec des API externes, de manipuler des données ou d’exécuter des fonctions supplémentaires pour étendre ses capacités.

Résumé

Cette documentation couvre :

  • Création d’un nouvel outil d’IA personnalisé
  • Configuration des paramètres et des scripts de l’outil
  • API disponibles pour les scripts d’outils
  • Intégration des outils personnalisés avec les personas d’IA
  • Test et dépannage des outils personnalisés

Création d’un nouvel outil d’IA personnalisé

Pour créer un nouvel outil d’IA :

  1. Naviguez vers Panneau d’administration > Plugins > Discourse AI > Outils
  2. Cliquez sur « Nouvel Outil » (vous pouvez utiliser des préréglages existants pour découvrir les options)
  3. Remplissez les champs suivants :
    • Nom : Le nom de l’outil tel que présenté au LLM
    • Description : La description de l’outil telle que présentée au LLM
    • Résumé : Résumé de ce que fait l’outil pour aider les utilisateurs (affiché dans les détails)
    • Paramètres : Définissez les entrées dont votre outil a besoin, telles que présentées au LLM
    • Script : Le code JavaScript qui alimente votre outil
  4. Cliquez sur « Enregistrer »

Configuration des scripts d’outils

API disponibles

Vos scripts d’outils ont accès aux API suivantes :

  1. Requêtes HTTP :

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

    Utilisez-les pour interagir avec des services externes. Vous pouvez utiliser options pour spécifier les en-têtes HTTP et le corps :

    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" })
    

    Toutes les méthodes HTTP retournent { status: number, body: string }.

  2. Intégration LLM (Modèle de Langage) :

    llm.truncate(text, length)
    

    Tronque le texte à une longueur de jeton spécifiée en fonction du tokenizer du LLM configuré.

    llm.generate(prompt, options)
    

    Génère du texte en utilisant le LLM configuré. L’invite peut être une chaîne simple ou un objet structuré tel que { messages: [{ type: "system", content: "..." }, { type: "user", content: "..." }] }. Les options incluent json: true pour demander et analyser automatiquement la sortie JSON, ainsi que temperature, top_p, max_tokens et stop_sequences.

  3. Intégration de téléchargement personnalisé (RAG)

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

    Recherche les fragments de documents RAG indexés attachés à cet outil. Renvoie Array<{ fragment: string, metadata: string | null }> ordonné par pertinence. La limite par défaut est de 10, maximum 200.

    index.getFile(filename)
    

    Récupère le contenu complet d’un fichier RAG téléchargé par son nom de fichier exact. Renvoie le texte complet ou null s’il n’est pas trouvé.

  4. Prise en charge des téléchargements

    upload.create(filename, base_64_content)
    

    Crée un nouveau téléchargement. Renvoie { id: number, url: string, short_url: string }.

    upload.getUrl(shortUrl)
    

    Étant donné une URL courte (par exemple, upload://12345), renvoie l’URL complète conviviale CDN.

    upload.getBase64(uploadIdOrShortUrl, maxPixels)
    

    Récupère le contenu encodé en base64 d’un téléchargement existant. Accepte un identifiant de téléchargement (nombre) ou une URL courte (chaîne). Paramètre maxPixels optionnel pour le redimensionnement automatique des images (défaut : 10 000 000).

  5. Contrôle de la chaîne d’exécution

    chain.setCustomRaw(raw)
    

    Définit le contenu brut final de la publication du bot et arrête la chaîne d’exécution de l’outil. Utile pour les outils qui génèrent directement la réponse complète (par exemple, les outils de génération d’images).

  6. Gestion des secrets

    secrets.get(alias)
    

    Renvoie la valeur de l’identifiant lié à l’alias donné. Les alias sont définis dans la configuration des contrats secrets de l’outil et liés aux Secrets IA dans le panneau d’administration. Lève une erreur si l’alias n’est pas déclaré, non lié ou si l’identifiant est manquant.

    const apiKey = secrets.get("my_api_key");
    
  7. Intégration Discourse

    Les outils peuvent interagir directement avec les données Discourse :

    discourse.baseUrl              // L'URL de base du site
    discourse.search(params)       // Effectuer une recherche Discourse
    discourse.getPost(post_id)     // Obtenir les détails de la publication (inclut le contenu brut)
    discourse.getTopic(topic_id)   // Obtenir les détails du sujet (tags, catégorie, etc.)
    discourse.getUser(id_or_username)  // Obtenir les détails de l'utilisateur
    discourse.createTopic(params)  // Créer un nouveau sujet
    discourse.createPost(params)   // Créer une nouvelle publication/réponse
    discourse.editPost(post_id, raw, options)    // Modifier le contenu d'une publication
    discourse.editTopic(topic_id, updates, options) // Modifier les propriétés du sujet (tags, catégorie, visibilité)
    discourse.createChatMessage(params) // Envoyer un message de chat
    discourse.createStagedUser(params)  // Créer un utilisateur "staged"
    discourse.getAgent(name)       // Obtenir un autre agent IA (avec la méthode respondTo)
    discourse.updateAgent(name, updates) // Mettre à jour la configuration d'un agent IA
    discourse.getCustomField(type, id, key)      // Lire le champ personnalisé sur la publication/le sujet/l'utilisateur
    discourse.setCustomField(type, id, key, value) // Définir le champ personnalisé sur la publication/le sujet/l'utilisateur
    
  8. Objet Contexte

    L’objet context fournit des informations sur l’endroit où l’outil est exécuté :

    • Contexte de conversation du bot : context.post_id, context.topic_id, context.private_message, context.participants, context.username, context.user_id
    • Contexte de discussion : context.message_id, context.channel_id, context.username
    • Contexte d’automatisation : context.post_id, context.topic_id, context.username, context.user_id, context.feature_name, context.feature_context
    • Propriétés communes : context.site_url, context.site_title, context.site_description

Fonctions requises

Votre script doit implémenter :

  • invoke(params) : La fonction principale qui s’exécute lorsque l’outil est appelé

Il peut implémenter en option :

  • details() : Renvoie une chaîne (peut inclure du HTML de base) décrivant l’exécution de l’outil, affichée dans l’interface de discussion
  • customSystemMessage() : Appelée lors de l’assemblage de l’invite (pas pendant l’invocation de l’outil). Renvoie une chaîne ajoutée à l’invite système, ou null/undefined pour ignorer. A accès aux objets context, discourse et index.

Exemple de script :

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

function details() {
  return "Données récupérées depuis l'API Example";
}

Limitations et sécurité

  • Délai d’exécution : Délai par défaut de 2000 ms de temps de traitement du script. La minuterie s’arrête pendant les requêtes HTTP externes (http.*) et les appels LLM (llm.generate), donc seul le temps de traitement du script lui-même est comptabilisé.
  • Mémoire : Limite maximale de tas V8 de 10 Mo
  • Requêtes HTTP : Maximum de 20 requêtes par exécution d’outil
  • Environnement Sandboxed : Les scripts s’exécutent dans un environnement JavaScript V8 restreint (via MiniRacer). Pas d’accès aux globaux du navigateur, au système de fichiers de l’hôte ou aux bibliothèques côté serveur. Les requêtes réseau sont proxifiées via le backend Discourse.

Test de votre outil

Vous devez tester chaque outil que vous construisez pour vous assurer que les résultats fournis au LLM correspondent à vos attentes.

Intégration des outils avec les personas d’IA

Pour ajouter votre outil personnalisé à un Persona d’IA :

  1. Accédez à Panneau d’administration > Plugins > Discourse AI > Personas
  2. Modifiez un persona existant ou créez-en un nouveau
  3. Dans la section « Outils », vous verrez vos outils personnalisés répertoriés à côté des outils intégrés
  4. Sélectionnez votre outil personnalisé pour l’ajouter au persona

Outils personnalisés en action

Une fois que vous avez fourni l’outil personnalisé à votre LLM, celui-ci peut l’utiliser pour améliorer la conversation.

Dépannage

Si votre outil ne fonctionne pas comme prévu :

  1. Utilisez l’interface de test pour vous assurer qu’il se comporte comme prévu pour vos entrées.
  2. Assurez-vous que votre groupe est dans ai_bot_debugging_allowed_groups. Les membres de ce groupe ont un accès complet aux transcriptions du bot ; vous pouvez y consulter les journaux de l’IA.
  3. Si quelque chose d’inattendu se produit, visitez https://NOM_DU_SITE/logs pour vérifier les erreurs.

Ressources supplémentaires

14 « J'aime »

Je commence à créer des outils pour les personas IA dans Discourse, en partie pour pouvoir me concentrer dessus ; cela semble très utile étant donné le nombre d’API utiles et publiques disponibles !

Par exemple, j’obtiens des résultats tels que :

Comprendre la prise de décision grâce aux stratégies de poker IA

maiki :

Crée une fiche d’information pour Breath of the Wild.

gpt-4o :

Voici une fiche d’information pour “The Legend of Zelda: Breath of the Wild” :


Titre : The Legend of Zelda: Breath of the Wild
Développeur : Nintendo
Éditeur : Nintendo
Date de sortie : 3 mars 2017
Plateformes : Nintendo Switch, Wii U
Genre : Action-aventure
Mode : Solo

Synopsis :
Dans un vaste monde ouvert, les joueurs contrôlent Link, qui se réveille d’un long sommeil pour vaincre Calamity Ganon et sauver le royaume d’Hyrule. Le jeu est salué pour son environnement immersif, permettant aux joueurs d’explorer et d’interagir librement avec le monde et ses systèmes.

Récompenses :
Le jeu a remporté de nombreux prix, dont plusieurs prix du Jeu de l’année, pour sa conception innovante, son monde expansif et son gameplay enchanteur.

Plus d’informations : Entrée Wikidata


“Breath of the Wild” est réputé pour avoir redéfini les jeux en monde ouvert et pour offrir une expérience captivante qui encourage l’exploration et la découverte.

maiki :

La même chose pour Animal Crossing: New Horizons.

gpt-4o :

Voici une fiche d’information pour “Animal Crossing: New Horizons” :


Titre : Animal Crossing: New Horizons
Développeur : Nintendo
Éditeur : Nintendo
Date de sortie : 20 mars 2020
Plateforme : Nintendo Switch
Genre : Simulation sociale
Mode : Solo, Multijoueur

Synopsis :
Dans ce charmant jeu de simulation sociale, les joueurs incarnent un personnage personnalisable qui s’installe sur une île déserte après avoir acheté un forfait auprès de Tom Nook. Le jeu permet l’exploration en temps réel, la collecte de ressources, la fabrication et la personnalisation, favorisant une expérience de jeu communautaire et relaxante.

Récompenses :
Le jeu a été acclamé pour sa liberté créative et le moment de sa sortie, recevant des prix du Jeu de l’année et pour ses contributions aux jeux sociaux pendant la pandémie mondiale.

Plus d’informations : Entrée Wikidata


“Animal Crossing: New Horizons” est devenu un phénomène culturel, célébré pour ses fonctionnalités sociales engageantes et son gameplay anti-stress en période difficile.

maiki :

A long way from Chicago

gpt-4o :

Voici une fiche d’information pour le livre “A Long Way from Chicago” :


Titre : A Long Way from Chicago
Auteur : Richard Peck
Année de publication : 1998
Genre : Fiction historique, Jeunesse
ISBN : 978-0141303529

Synopsis :
Ce roman, honoré par la Newbery, est une série de nouvelles narrant les voyages annuels d’été de Joey et de sa sœur Mary Alice de Chicago à une ville rurale de l’Illinois pour rendre visite à leur grand-mère Dowdel, une personnalité exubérante, à la fin des années 1920 et 1930. Chaque chapitre présente un épisode amusant et poignant qui transmet des leçons de vie sur fond de Grande Dépression.

Récompenses :
Le livre a reçu une Mention d’honneur Newbery en 1999 et est célébré pour son humour, sa profondeur et sa représentation de la vie rurale américaine au début du XXe siècle.

Plus d’informations : Entrée Wikidata


Ce livre est apprécié pour sa narration nostalgique et réconfortante, capturant l’essence des liens familiaux et des temps plus simples.

maiki :

Thinking in Bets

gpt-4o :

J’ai précédemment trouvé l’entrée Wikidata pour “Thinking in Bets”, mais je ne suis pas en mesure de récupérer d’autres détails spécifiques directement de Wikidata pour le moment. Voici cependant une brève fiche basée sur les informations disponibles :


Titre : Thinking in Bets: Making Smarter Decisions When You Don’t Have All the Facts
Auteur : Annie Duke
Année de publication : 2018
Genre : Non-fiction, Prise de décision, Psychologie
ISBN : 978-0735216358

Synopsis :
Le livre s’inspire du poker pour aider les lecteurs à comprendre la prise de décision dans l’incertitude. Annie Duke, alliant ses expériences de joueuse de poker professionnelle et de psychologue cognitive, propose un cadre pour prendre de meilleures décisions, évaluer les résultats et adopter un état d’esprit probabiliste.

Plus d’informations : Entrée Wikidata


Pour des informations détaillées, vous pourriez envisager de consulter des ressources ou des bases de données supplémentaires relatives aux publications de livres.


C’est bien, mais j’ai remarqué cette description…

…et je me demande : devrais-je construire mes prompts en me référant directement à ces outils, pour une utilisation efficace ?

Mon approche générale de la rédaction de prompts est de peaufiner au fil du temps, puis de me fixer sur un schéma de comportement que je souhaite que l’outil d’IA adopte. Cependant, si je pouvais ajouter des instructions spécifiques sur, par exemple, quand rechercher une entité Wikidata, et quand lister toutes les affirmations d’une entité particulière (deux API différentes), alors je pense que je pourrais affiner l’ensemble du flux de travail comme je l’entends… :star_struck:

4 « J'aime »

En effet, expliquer clairement l’outil et fournir des exemples dans l’invite système est bénéfique.

2 « J'aime »

Est-il possible dans un outil personnalisé d’insérer la clé API et le projet OpenAI à partir des paramètres d’administration ?

1 « J'aime »

Vous pouvez effectuer des appels REST à partir d’un outil personnalisé et spécifier tous les en-têtes.

2 « J'aime »

Je viens de réaliser que lol… désolé pour mon lapsus.

1 « J'aime »

J’ai téléchargé des documents dans une persona, cela a généré les embeddings et permet maintenant une recherche sémantique. Mais dans certains cas, la recherche sémantique n’est pas idéale, j’aimerais donc l’améliorer et avoir une recherche hybride, par exemple garder ce qui existe déjà et ajouter une recherche par mots-clés. Pour le moment, si je veux faire cela, je devrais écrire un outil personnalisé, n’est-ce pas ?
Je sais que je pourrais simplement publier les documents comme des sujets et cela fonctionnerait immédiatement avec la recherche native de Discourse, mais ce n’est pas une option actuellement.

Je rencontre une erreur de schéma d’outil lors de l’ajout d’un outil personnalisé avec un paramètre de type tableau. Erreur au démarrage de la conversation :

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

Ce que j’ai essayé :

  • Créé un outil personnalisé avec un paramètre nommé properties de type array.
  • L’interface utilisateur de la liste des paramètres ne permet pas de spécifier les items.
  • Exporté/importé un fichier JSON d’outil complet qui inclut items: { type: “string” } pour properties.
  • Après l’importation, l’erreur persiste dès que l’outil est activé pour une persona. Si je supprime l’outil, le bot fonctionne.

Attendu :

Soit l’interface utilisateur des paramètres devrait permettre de définir les types d’éléments de tableau, soit l’importation devrait respecter les items afin que le schéma soit validé.

Quelqu’un a-t-il déjà rencontré cela ? Existe-t-il une limitation connue ou un chemin d’interface utilisateur requis pour définir des paramètres de type tableau ?

1 « J'aime »