GlossaryAI MCP Server
by theojoly2
README.md
# GlossaryAI — Serveur MCP
Serveur MCP (Model Context Protocol) pour **GlossaryAI**, un assistant IA spécialisé en vocabulaires, glossaires et textes juridiques/réglementaires. Il expose des outils de recherche vectorielle, de planification, de résolution de liens juridiques et de comparaison de concepts, alimentés par une base Qdrant et un LLM OpenAI-compatible.
---
## Overview
Le serveur est construit avec **FastMCP** et exécuté via **Uvicorn**. Il est appelé par le client Streamlit `AI4Semantics-MCP-client-fr` pour :
1. Planifier la réponse à une question utilisateur (`plan_workflow_with_tools`).
2. Rechercher dans les documents indexés (`retrieve_documents`).
3. Lister les sources disponibles (`get_available_tags`).
4. Résoudre les liens juridiques et RDF mentionnés dans les chunks (`resolve_links`).
5. Comparer/converger plusieurs termes (`compare_concepts`).
---
## Requirements
- Python 3.10 ou supérieur
- Docker (pour Qdrant via `docker-compose.yml`)
- Un GPU est recommandé pour le reranker local ; sinon le serveur bascule automatiquement sur ONNX CPU.
- Une clé API pour le LLM (`LLM_API_KEY` / `URL_LLM_API`) et éventuellement pour Albert (`ALBERT_API_KEY`) si le reranker API est activé.
---
## Setup
### 1. Cloner le dépôt
```bash
git clone https://github.com/pwc-be-adv-tc-cd/AI4semantics
cd AI4semantics/AI4Semantics-MCP-server-fr
```
### 2. Créer et activer un environnement virtuel
```bash
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
```
### 3. Installer les dépendances
```bash
pip install -r requirements.txt
```
### 4. Configurer les variables d'environnement
Copier `.env.sample` vers `.env` et renseigner les valeurs :
```bash
cp .env.sample .env
```
| Variable | Description |
|---|---|
| `SERVER_HOST` | Hôte Qdrant (`qdrant` en Docker, `localhost` en local) |
| `SERVER_PORT` | Port Qdrant (`6333`) |
| `QDRANT_API_KEY` | Clé API Qdrant (laisser vide si aucune) |
| `URL_LLM_API` | Endpoint OpenAI-compatible du LLM |
| `LLM_API_KEY` | Clé API du LLM |
| `LLM_MODEL` | Nom du modèle LLM |
| `ALBERT_API_KEY` | Clé pour le reranker Albert (si `reranker_api.enabled: true`) |
### 5. Démarrer Qdrant
```bash
docker-compose up -d
```
Qdrant est alors accessible sur `localhost:6333` avec un volume persistant dans `./data/qdrant`.
### 6. Indexer les documents
Placer les documents dans `tools/index_search/load_documents/documents/` puis lancer :
```bash
python tools/index_search/load_documents/load.py
```
Le script supporte de nombreux formats : PDF, HTML, TXT, CSV, JSON, XML/RDF/SKOS, Excel, Markdown, RTF, etc. Les fichiers HTML Eur-Lex (par exemple `Data-Act.html`) sont automatiquement découpés par articles/chapitres.
Pour tester la recherche :
```bash
python tools/index_search/load_documents/retrieve.py
```
### 7. Démarrer le serveur MCP
```bash
python -m server
```
Le serveur écoute par défaut sur `0.0.0.0:8001`.
---
## Tools
| Tool | Fichier | Description |
|---|---|---|
| `plan_workflow_with_tools` | `tools/planning_orchestrator/plan_workflow_with_tools.py` | Planifie l'enchaînement des outils pour répondre à la question utilisateur. |
| `retrieve_documents` | `tools/index_search/retrieve_documents.py` | Recherche hybride dense/sparse dans Qdrant, reranking, retour de chunks et de fenêtres de documents. |
| `get_available_tags` | `tools/index_search/get_available_tags.py` | Liste les tags de sources présents dans la collection Qdrant. |
| `resolve_links` | `tools/legal_link_resolver/resolve_links.py` | Détecte les références à articles juridiques et les liens RDF/SKOS, puis remonte les chunks liés. |
| `compare_concepts` | `tools/concept_comparator/compare_concepts.py` | Compare plusieurs termes via recherche vectorielle et propose une définition convergente via LLM. |
---
## File Structure
```
.
├── server.py # Point d'entrée FastMCP + Uvicorn
├── config.py # Chargement centralisé de la configuration
├── config.yaml # Paramètres de chunking, recherche, reranker, comparateur
├── docker-compose.yml # Service Qdrant
├── .env.sample # Variables d'environnement requises
├── requirements.txt # Dépendances Python
│
└── tools/
├── __init__.py # Export des outils enregistrés dans le serveur
│
├── concept_comparator/
│ └── compare_concepts.py # Comparaison/convergence de termes
│
├── index_search/
│ ├── retrieve_documents.py # Wrapper de recherche pour le serveur
│ ├── retrieve_search_documents.py # Logique de recherche hybride et aggregation
│ ├── get_available_tags.py # Liste des tags indexés
│ ├── init_qdrant_no_vocs.py # (legacy) initialisation sans vocabulaires
│ ├── init_qdrant_vocs.py # (legacy) initialisation avec vocabulaires
│ ├── old_init.py # (legacy)
│ └── load_documents/
│ ├── load.py # Indexation complète (parse, chunk, embed, upsert)
│ ├── retrieve.py # Script de test de recherche
│ ├── config.py # Client Qdrant, modèle d'embedding, rerankers
│ ├── config.yaml # Configuration de Qdrant, chunking, reranker
│ └── documents/ # Dossier contenant les documents à indexer
│ ├── AGIT/
│ ├── EU/
│ ├── FranceTerme/
│ ├── Legifrance/
│ ├── OFB/
│ └── OiEau/
│
├── legal_link_resolver/
│ └── resolve_links.py # Résolution de liens juridiques et RDF
│
└── planning_orchestrator/
├── plan_workflow_with_tools.py # Planner agent
└── prompts.py # Prompt système du planner
```
---
## Architecture de recherche
1. **Parsing** : `load.py` extrait le texte de nombreux formats.
2. **Chunking** : découpage par taille avec chevauchement. Les HTML Eur-Lex sont chunkés par articles/chapitres.
3. **Embeddings** : modèle `BAAI/bge-m3` (dense + sparse via la même API de modèle).
4. **Indexation** : upsert dans Qdrant avec métadonnées (tag, filename, chunk_index, article, concept_uri, etc.).
5. **Recherche** : recherche hybride dense/sparse, reranking local (bge-reranker-v2-m3) ou via API Albert, agrégation par document, retour des meilleurs chunks avec possibilité de fenêtre.
Les paramètres de recherche sont centralisés dans `tools/index_search/load_documents/config.yaml` :
| Paramètre | Description |
|---|---|
| `search.limit` | Nombre de résultats finaux retournés |
| `search.min_candidates` | Taille du pool initial de candidats |
| `search.rerank_pool_size` | Nombre de candidats rerankés |
| `search.hybrid_dense_weight` | Poids de la recherche dense vs sparse |
| `search.max_chunks_per_document` | Nombre de chunks maximum par document dans les résultats |
| `chunking.chunk_size` | Taille d'un chunk |
| `chunking.chunk_overlap` | Chevauchement entre chunks |
---
## Configuration
- `config.yaml` (racine) : paramètres pour le résolveur de liens (`link_resolver`) et le comparateur de concepts (`concept_comparator`).
- `tools/index_search/load_documents/config.yaml` : configuration Qdrant, modèles, chunking, reranker, recherche.
- `.env` : secrets et endpoints.
---
## Démarrage rapide
```bash
# 1. Démarrer Qdrant
docker-compose up -d
# 2. Indexer les documents
python tools/index_search/load_documents/load.py
# 3. Lancer le serveur MCP
python -m server
```
Puis lancer le client Streamlit `AI4Semantics-MCP-client-fr`.
---
## Notes importantes
- Le serveur utilise un `ThreadPoolExecutor(max_workers=2)` pour exécuter les recherches lourdes sans bloquer la boucle asyncio.
- `TOKENIZERS_PARALLELISM` est désactivé pour éviter les deadlocks du tokenizer HuggingFace.
- Le reranker local peut être remplacé par l'API Albert si `reranker_api.enabled` est à `true` dans `config.yaml`.
Pour plus de détails, consulter les commentaires dans chaque module.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues