📘 Documentation du module goblin-agents
Aperçu
Le module goblin-agents
fournit une infrastructure complète pour intégrer des agents d'intelligence artificielle (IA) dans l'écosystème Xcraft. Il permet de créer, configurer et interagir avec différents modèles de langage (LLM) via des fournisseurs comme Ollama et OpenAI. Ce module est conçu pour faciliter l'utilisation d'agents IA dans diverses applications, en offrant des fonctionnalités avancées comme la gestion de conversations, l'analyse de documents PDF, et l'utilisation d'outils externes.
Sommaire
Structure du module
- AiAgent : Acteur principal qui encapsule un agent IA et ses fonctionnalités
- Providers : Classes pour interagir avec différents fournisseurs de LLM (Ollama, OpenAI)
- Utilitaires : Fonctions pour le traitement de texte, l'OCR, et la manipulation de documents
Le module est organisé autour du pattern Elf, avec une séparation claire entre la logique métier (AiAgentLogic
) et l'interface de l'acteur (AiAgent
).
Fonctionnement global
Le module goblin-agents
permet de créer et gérer des agents IA qui peuvent interagir avec les utilisateurs via des conversations textuelles. Chaque agent est configuré avec un modèle spécifique, un fournisseur (Ollama ou OpenAI), et des paramètres qui définissent son comportement.
Les agents peuvent maintenir plusieurs contextes de conversation simultanément, ce qui permet d'avoir des conversations distinctes avec différents utilisateurs ou sur différents sujets. Chaque contexte conserve son propre historique de messages, ce qui permet à l'agent de maintenir la cohérence dans ses réponses.
Le module prend en charge diverses fonctionnalités avancées :
- Génération de texte à partir de prompts
- Conversations interactives avec historique
- Extraction de texte à partir d'images de documents PDF
- Génération d'embeddings vectoriels pour la recherche sémantique
- Utilisation d'outils externes via un système d'appels d'outils
- Paradigme ReAct (Reasoning and Acting) pour des agents plus autonomes
Les agents peuvent être configurés avec une grande variété d'options qui influencent leur comportement, comme la température (créativité), la taille du contexte, et diverses pénalités pour éviter les répétitions.
Exemples d'utilisation
Création d'un agent IA
const {AiAgent} = require('goblin-agents/lib/llm/aiAgent.js');
async initAgents() {
const feedId = await this.newQuestFeed();
const ollamaAgentId = 'aiAgent@ollama-mistral-assistant';
const agent = await new AiAgent(this).create(ollamaAgentId, feedId, {
name: 'Assistant Personnel',
role: 'assistant',
prompt: 'Tu es un assistant personnel serviable et précis.',
provider: 'ollama',
model: 'mistral-small',
host: 'http://127.0.0.1:11434',
options: {
temperature: 0.7
},
usability: 'stable'
});
const openAiAgentId = 'aiAgent@gpt-4o-assistant';
const cloudAgent = await new AiAgent(this).create(openAiAgentId, feedId, {
name: 'Assistant Personnel',
role: 'assistant',
provider: 'open-ai',
model: 'openai/gpt-4o',
host: 'https://openrouter.ai/api/v1',
headers: {
Authorization: `Bearer <votre-clef-api>`,
},
usability: 'stable'
});
}
Conversation avec un agent
async askAgent(desktopId, agentId, contextId, question, saveExchange = false) {
const feedId = await this.newQuestFeed();
const agent = await new AiAgent(this).create(agentId, feedId);
const response = await agent.chat(contextId, question, desktopId);
if(saveExchange) {
await agent.save();
}
return response;
}
Utilisation d'outils externes
async addWeatherToolSupportToAgent(agentId) {
const feedId = await this.newQuestFeed();
const agent = await new AiAgent(this).create(agentId, feedId);
await agent.patch({
toolServiceId: 'weather',
tools: [
{
type: 'function',
function: {
name: 'getWeather',
description: 'Obtenir la météo pour une ville',
parameters: {
type: 'object',
properties: {
city: {
type: 'string',
description: 'Nom de la ville'
}
},
required: ['city']
}
}
}
]
});
const question = "Quel temps fait-il à Paris aujourd'hui?";
const response = await agent.chat(contextId, question, desktopId);
}
Génération d'embeddings pour la recherche sémantique
async updateKnowledgeBase(articles) {
const feedId = await this.newQuestFeed();
const agent = await new AiAgent(this).create(agentId, feedId);
const texts = Object.values(articles);
const articlesIds = Object.keys(articles);
const vectorsBatch = await agent.embedInBatch(texts);
for(const articleId of articleIds) {
const index = articleIds.indexOf(articleId);
const vectors = vectorsBatch[index];
const text = texts[index];
const indexedContent = new IndexedContentState({
id: articleId,
text,
meta: {
locale: 'fr',
scope: 'knowledge-base',
vectors,
status: 'published',
}
});
await new IndexedContent(this).insertOrReplace(
articleId,
feedId,
indexedContent
);
}
}
Interactions avec d'autres modules
Le module goblin-agents
interagit avec plusieurs autres composants de l'écosystème Xcraft :
Le module peut également interagir avec d'autres services Goblin via le système d'appels d'outils, permettant aux agents d'effectuer des actions concrètes dans l'application.
Configuration avancée
version | Version des agents | Number | 2 |
defaultProfile | Profil par défaut des agents | String | null |
defaultSettings | Paramètres par défaut | Object | null |
profiles | Profils pour remplacer les paramètres | Object | {} |
settings | Paramètres par nom | Object | {} |
Détails des sources
aiAgent.js
Ce fichier est le point d'entrée du module, exportant les commandes Xcraft pour l'acteur AiAgent. Il importe l'acteur et sa logique depuis le fichier principal et les expose au système Xcraft via Elf.birth()
.
lib/llm/aiAgent.js
Ce fichier contient la définition complète de l'acteur AiAgent, avec :
- MessageShape : Définit la structure des messages échangés (rôle, contenu, images, appels d'outils)
- OptionsShape : Définit les nombreuses options de configuration des modèles LLM
- AiAgentShape : Définit la structure des données de l'agent
- AiAgentState : Classe d'état de l'agent basée sur le shape
- AiAgentLogic : Logique métier de l'agent (mutations d'état)
- AiAgent : Classe principale de l'acteur avec les méthodes d'interaction
État et modèle de données
L'état d'un agent IA est défini par la classe AiAgentShape
qui contient les propriétés suivantes :
id
: Identifiant unique de l'agent
version
: Version de l'agent
name
: Nom de l'agent
role
: Rôle de l'agent (assistant, etc.)
prompt
: Prompt par défaut utilisé pour définir le comportement de l'agent
provider
: Fournisseur LLM ('ollama' ou 'open-ai')
model
: Modèle de langage utilisé
host
: URL du serveur LLM
headers
: En-têtes HTTP pour les requêtes API
messages
: Historique des messages par contexte
options
: Options de configuration du modèle (voir OptionsShape)
format
: Format de sortie attendu
tools
: Outils externes disponibles pour l'agent
toolServiceId
: Identifiant du service d'outils
usability
: État d'utilisabilité ('disabled', 'experimental', 'stable', 'deprecated')
meta
: Métadonnées de l'agent
La classe OptionsShape
définit de nombreuses options de configuration pour les modèles LLM, incluant des paramètres comme la température, la taille du contexte, les pénalités de répétition, et les options d'optimisation mémoire.
Cycle de vie de l'acteur
L'acteur AiAgent suit le cycle de vie standard des acteurs Elf Archetype :
- Création : Via la méthode
create()
qui initialise l'agent avec un ID et un état
- Configuration : Via
patch()
pour modifier les paramètres ou upgrade()
pour les mises à jour de version
- Utilisation : Via les méthodes de conversation et de génération
- Persistance : Via
save()
pour sauvegarder l'état
- Suppression : Via
trash()
pour marquer comme supprimé ou delete()
pour suppression définitive
Méthodes publiques
create(id, desktopId, agentState)
— Crée un nouvel agent avec l'ID et l'état spécifiés. Persiste automatiquement l'agent après création.
patch(agentState)
— Met à jour l'état de l'agent avec les propriétés fournies et persiste les changements.
upgrade(version, agentState)
— Met à niveau l'agent vers une nouvelle version avec l'état spécifié, uniquement si la version est supérieure à la version actuelle.
gen(prompt)
— Génère du texte à partir d'un prompt en utilisant le modèle configuré de l'agent.
reset(contextId, save=false)
— Réinitialise l'historique des messages pour un contexte spécifique. Si aucun contextId n'est fourni, réinitialise tous les contextes.
readPDFpages(pdfPath)
— Extrait le texte des pages d'un document PDF en utilisant l'OCR via un modèle multimodal.
embed(rawText)
— Génère un embedding vectoriel pour un texte donné, retourné sous forme de littéral SQL hexadécimal.
embedInBatch(rawTexts=[])
— Génère des embeddings vectoriels pour plusieurs textes en une seule requête, optimisé pour les traitements par lots avec gestion des verrous.
set(contextId, messages)
— Définit directement l'historique des messages pour un contexte spécifique.
chat(contextId, question, userDesktopId, sessionId=null)
— Engage une conversation avec l'agent dans un contexte spécifique. Gère automatiquement l'historique et les appels d'outils.
ask(contextId, question, questionId)
— Pose une question à l'agent avec streaming de la réponse (uniquement pour Ollama). Émet des événements pour chaque partie de la réponse.
resumeExchange(resumePrompt, contextId)
— Reprend un échange existant avec un nouveau prompt système, en utilisant l'historique du contexte comme base.
react(reactPrompt, contextId, question)
— Utilise le paradigme ReAct (Reasoning and Acting) pour permettre à l'agent de raisonner et d'agir de manière autonome.
callAgent(contextId, agentId, action, feedId)
— Appelle un autre agent pour effectuer une action spécifique dans le cadre d'une orchestration multi-agents.
addAssistantMessage(contextId, message)
— Ajoute un message de l'assistant à l'historique d'un contexte spécifique.
change(path, newValue)
— Modifie une propriété spécifique de l'état de l'agent avec gestion automatique des types pour certains paramètres.
getUserChatContextHistory(contextId, filterTool=true)
— Récupère l'historique des messages pour un contexte spécifique avec option de filtrage des messages d'outils.
getBaseSettings()
— Retourne les paramètres de base de l'agent (provider, host, headers, model).
getUsability()
— Retourne l'état d'utilisabilité de l'agent.
trash()
— Marque l'agent comme supprimé en changeant son statut meta à 'trashed'.
save()
— Persiste l'état actuel de l'agent sur le disque.
lib/llm/providers.js
Ce fichier définit l'architecture des fournisseurs de LLM avec une classe abstraite LLMProvider
et ses implémentations concrètes :
LLMProvider (classe abstraite)
Définit l'interface commune que tous les fournisseurs doivent implémenter :
chat()
: Conversation avec le modèle
gen()
: Génération de texte
embed()
: Génération d'embeddings
embedInBatch()
: Génération d'embeddings par lots
OllamaProvider
Implémentation pour le fournisseur Ollama (serveur local) :
- Utilise la bibliothèque
ollama
pour communiquer avec le serveur
- Gère le streaming pour les conversations en temps réel
- Implémente un sémaphore pour limiter les requêtes d'embedding simultanées (max 4)
- Supporte tous les formats de sortie JSON structurés
OpenAIProvider
Implémentation pour OpenAI et services compatibles (OpenRouter, etc.) :
- Utilise
RestAPI
de xcraft-core-utils pour les appels HTTP
- Adapte les formats de requête entre Ollama et OpenAI
- Gère les schémas JSON pour les réponses structurées
- Supporte les en-têtes d'authentification personnalisés
lib/llm/utils.js
Ce fichier contient un ensemble complet d'utilitaires pour le traitement de texte et de documents :
Traitement de documents PDF
getPDFImages(pdfPath)
— Convertit les pages d'un PDF en images base64 pour l'OCR avec des options optimisées pour la qualité du texte.
OCR_SYSTEM_PROMPT
— Prompt système spécialisé pour guider les modèles multimodaux dans l'extraction de texte à partir d'images.
Traitement de texte et HTML
cleanHtmlContent(html)
— Nettoie le contenu HTML en supprimant les balises et en normalisant les espaces.
simplifyHtml(html)
— Simplifie le HTML en gardant uniquement les éléments sûrs via sanitize-html.
extractTitlesAndContent(html)
— Extrait intelligemment les titres et le contenu d'un document HTML en préservant la structure.
html2chunks(html, chunkSize=300, chunkOverlap=0)
— Découpe un document HTML en chunks en utilisant RecursiveCharacterTextSplitter de LangChain.
Gestion des tokens et découpage
estimateTokenCount(text)
— Estime le nombre de tokens d'un texte (approximation basée sur les mots × 1.33).
splitLongText(text, maxLength, baseId)
— Découpe un texte long en segments de taille maximale en préservant les mots entiers.
sliceText(text, chunkSize)
— Découpe un texte en chunks en respectant les limites de phrases.
groupSentences(text, maxSize)
— Groupe les phrases en chunks de taille optimale pour les modèles de langage.
Traitement par lots et optimisation
chunkArray(array, size)
— Divise un tableau en sous-tableaux de taille spécifiée pour le traitement par lots.
embedChunksInBatch(agent, allChunks, batchSize=50)
— Traite les embeddings par lots en associant chaque embedding à son contenu d'origine.
buildPromptFromArticlesMulti(initialQuestion, questionsWithArticles, maxTotalTokens)
— Construit des prompts optimisés à partir de multiples articles en respectant les limites de tokens.
Utilitaires de conversion
vectorToSqlLiteral(vec)
— Convertit un vecteur Float32Array en littéral SQL hexadécimal pour le stockage en base de données.
Ces utilitaires sont essentiels pour préparer les données avant de les envoyer aux modèles de langage et pour traiter les résultats. Ils permettent notamment de gérer les contraintes de taille de contexte des modèles en découpant intelligemment les textes longs tout en préservant la cohérence sémantique.
Cette documentation a été mise à jour automatiquement.