6.1 KiB
6.1 KiB
#92 — Assistant IA — Écosystème d'outils : feuille de route technique
Statut : ⚪ Backlog (phase 1 livrée dans #91) Effort estimé : 3-5 jours pour la phase 2 | Impact : 🟠 Références : Roadmap · Outils & MCP #79 · Fenêtre de discussion #91 · Changelog
1. Ce qui existe déjà (phase 1, #91)
| Élément | État |
|---|---|
Registre d'outils typé (@tool, Pydantic, risque, scope, rate-limit, audit) |
✅ backend/tools/registry.py |
| Boucle agent multi-tours + confirmation en deux étapes | ✅ backend/agent/loop.py |
| Section « N étapes » Notion-style avec libellés humains + événements SSE en direct | ✅ backend/tools/labels.py |
Recherche web auto-hébergée (web_search via SearXNG) |
✅ backend/tools/web.py |
Lecture d'une page publique (fetch_url, garde SSRF, HTML→texte) |
✅ backend/tools/web.py |
| Outils vault (lecture, recherche, navigation, mutations confirmées) | ✅ backend/tools/service.py (26 outils) |
2. Frameworks d'agents — décision
ObsiGate ne migre pas vers un framework externe : la boucle maison
(run_agent) est déjà testée, typée, auditable et intégrée au flux SSE
(critique pour la section « steps » en direct). Les candidats restent suivis :
| Framework | Point fort | Verdict pour ObsiGate |
|---|---|---|
| Pydantic AI | validation type-safe, cœur léger | inspirant : la validation existe déjà via Pydantic dans registry.call_tool |
| LangChain / LangGraph | écosystème, workflows complexes | dépendance lourde ; à reconsidérer seulement si multi-agents |
| LlamaIndex | RAG clé en main | la recherche locale (TF-IDF + embeddings, #70) couvre déjà le besoin |
| SmolAgents | agents qui écrivent du code | risque d'exécution : hors périmètre |
| LightAgent | ultra-léger, mémoire | redondant avec la mémoire de session déjà fournie |
Règle : tout nouvel outil = @tool dans backend/tools/ + un libellé dans
labels.py + deux clés i18n (ai.step.<key> FR/EN) + un test. Aucune
réécriture de la boucle n'est nécessaire.
3. Phase 2 — catégories à implémenter
3.1 Recherche web étendue (web_search)
- Fallback sans clé : aujourd'hui SearXNG auto-hébergé (
OBSIGATE_SEARXNG_URL). Prévoir une chaîne de repli si l'instance est indisponible (DuckDuckGo HTML). - Fournisseurs optionnels (clé dans Infisical, jamais en dur) : Tavily
(résultats orientés agents), Brave Search API, SerpAPI (Google), Exa.
Interface unifiée type
anysearchpour un sélecteur de fournisseur unique. - Paramètres déjà exposés :
category(general/news/it/science),language,page,max_results.
3.2 Lecture de pages (fetch_url)
- Pages statiques : couvert (httpx + extraction texte maison).
- Pages dynamiques (SPA/React) :
playwright(async) en option, exécuté dans un worker isolé (jamais dans le process web) — images Docker lourdes à prévoir. - Crawl multi-pages :
scrapyuniquement en tâche de fond, jamais déclenché par le modèle sans confirmation (WRITE/confirm). - Alternative légère de parsing :
lxmloubeautifulsoup4si l'extraction maison devient insuffisante (aujourd'hui volontairement sans dépendance).
3.3 Sources connectées (« Searched connected sources »)
Chaque intégration reste derrière le registre (risque, scope, rate-limit, audit) et jamais avec un token en dur :
- Gitea / GitHub :
httpxdirect (déjà utilisé) ougitea-sdk/PyGithub. Priorité haute : ObsiGate est hébergé sur Gitea (issues, PR, commits). - Google Drive / Gmail / Calendar :
google-api-python-client(+PyDrive4pour les tâches simples). OAuth2 viaauthlib. - OneDrive / SharePoint :
onedrive-personal-sdk(async, Microsoft Graph). - Notion / Slack / Jira / Confluence / Salesforce : SDK officiels ou
httpx+ OAuth2 générique. - Voie recommandée : privilégier le serveur MCP externe (#79) pour les services tiers — l'attaque surface reste hors du cœur d'ObsiGate.
3.4 Fichiers et production de documents
- Conversion de formats, tableurs (
openpyxl), documents (python-docx,pypdf), graphiques (matplotlib) : outils WRITE (confirmation obligatoire), exécutés hors requête web si lourd (tâche de fond + SSE). - Pièces jointes : déjà couvert par l'upload vault +
python-multipart.
3.5 Raisonnement interne (« thought », « planned the task »)
- Livré : la note intermédiaire du modèle devient une étape visible.
- Extension possible : exposer les itérations de la boucle (
iterations) comme étapes de planification quand un outil de plan est ajouté.
4. Transverse — à faire avec la phase 2
| Sujet | Bibliothèque / approche | Où |
|---|---|---|
| Réessais avec backoff | tenacity (ou boucle maison) |
appels réseau des outils |
| Cache des résultats web | table SQLite dédiée + TTL (OBSIGATE_WEB_CACHE_TTL) |
backend/tools/web.py |
| Rate limiting | déjà en place (backend/tools/ratelimit.py) |
registre |
| Secrets | Infisical / variables d'environnement | jamais en dur |
| Async | httpx (async) pour ne pas bloquer la boucle |
nouveaux outils réseau |
| Fallback | chaque outil externe doit échouer proprement (ToolError + message) |
registre |
| Observabilité | audit déjà en place (backend/tools/audit.py) |
registre |
5. Points d'attention
- Sécurité d'abord : tout outil réseau passe par la garde SSRF (
_assert_public_http_url), des limites de taille, et n'est jamais exposé sans rate-limit. - Coût : chaque outil supplémentaire augmente le prompt système (schémas).
Mesurer (
/api/ai/status) et exposer les outils par lots si besoin. - Testabilité : les outils réseau se testent avec
httpxmocké (voirtests/test_web_tools.py), jamais contre Internet en CI. - Une seule source d'affichage : ne pas dupliquer les étapes côté frontend —
le libellé vient du backend (
labels.py), la traduction du locale.