Documentation

cloooooo

Un système d'IA entièrement local. Inférence de qualité production sans aucun appel API externe — recherche agentique profonde, RAG hybride, appel d'outils, mémoire sémantique et routage multi-modèles, tout sur votre matériel.

SGLang 0.5.9 Qwen3-32B-AWQ MiroFlow LanceDB SearXNG fastembed 100 % local Zéro API externe
Recherche agentique
MiroFlow orchestre Qwen3-32B en multi-tours : recherche web, Wikipedia, lecture de pages.
RAG hybride
Recherche dense + BM25 sur PDF, DOCX, TXT. Reranking bge-reranker pour la précision.
Appel d'outils
Exécution de code sandboxée, I/O fichiers, recherche web — avec validation de schéma JSON.
Mémoire sémantique
Mémoire inter-conversations avec LanceDB. Consolidation automatique à partir de 30 faits.
Routeur intelligent
Classification de tâches en sous-milliseconde — code / raisonnement / recherche / vision.
Sorties structurées
Schémas Pydantic v2 + mode JSON SGLang. Extraction typée garantie.

Installation

Requiert Python 3.10+ et un serveur SGLang tournant localement (voir ci-dessous).

bash
pip install clovis

Prérequis

cloooooo s'appuie sur un backend SGLang pour l'inférence. Le plus simple :

bash
# Démarrer SGLang avec Qwen3-32B-AWQ (RTX 3090 recommandé)
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-32B-AWQ \
  --host 0.0.0.0 --port 61005 \
  --quantization awq
Note : Si SGLang tourne déjà sur localhost:61005, l'objet cloooooo() s'y connecte automatiquement. Aucune configuration supplémentaire n'est nécessaire.

Quickstart

python
from clovis import cloooooo

ai = cloooooo()

# Inférence simple
print(ai("Explique les transformeurs en 3 phrases."))

# Avec recherche web
print(ai("Dernières avancées en IA en 2026 ?", use_web=True))

# Recherche agentique profonde (MiroFlow)
result = ai.deep_thinking("Quelles sont les causes de la crise des semi-conducteurs ?")
print(result["answer"])

Inférence de base

L'objet cloooooo est l'interface principale. Appelez-le directement comme une fonction.

python
from clovis import cloooooo
ai = cloooooo()

# Appel de base
reponse = ai("Qu'est-ce que l'attention multi-têtes ?")

# Avec contexte et invite négative
reponse = ai(
    "Résume ce texte.",
    context="Le mécanisme d'attention...",
    negative_prompt="Ne pas inclure de formules mathématiques."
)

# Mode thinking étendu (chain-of-thought Qwen3)
reponse = ai("Prouve que sqrt(2) est irrationnel.", thinking=True)

# Streaming token par token
for chunk in ai.stream("Raconte une histoire courte."):
    print(chunk, end="", flush=True)

Paramètres

ParamètreTypeDescription
prompt str requis La question ou instruction.
context str optionnel Contexte additionnel préfixé au prompt.
negative_prompt str optionnel Ce que la réponse doit éviter.
thinking bool False Active le chain-of-thought étendu de Qwen3. Les balises <think> sont retirées automatiquement de la sortie.
use_web bool False Préfixe les résultats SearXNG en contexte avant l'inférence.

Modes d'inférence

Cinq modes disponibles, du plus rapide au plus puissant.

python
# Mode simple — réponse directe, plus rapide
ai("Bonjour !")

# Mode thinking — chain-of-thought activé
ai("Quelle est la complexité de Dijkstra ?", thinking=True)

# Mode search — recherche web locale + inférence
ai("Cours du Bitcoin aujourd'hui ?", use_web=True)

# Mode deep_thinking — pipeline agentique MiroFlow (≤20 tours, ~3-10 min)
result = ai.deep_thinking("Analyse l'impact de GPT-4 sur le marché de l'emploi.")
print(result["answer"])

# Mode ultra_deep_thinking — recherche massive multi-axes (~20-120 min)
result = ai.ultra_deep_thinking(
    "Analyse complète de l'impact de l'IA sur l'économie mondiale.",
    preset="deep"   # "fast" | "deep" | "ultra"
)
print(result["answer"])
print(result["run_stats"])  # axes, gaps, sources, chars...
ModeDuréeRecherchesCas d'usage
simple<1 min0Questions factuelles, discussions
thinking<1 min0Raisonnement, maths, code
search~1 min3-5Actualités, données récentes
deep_thinking3-10 min20-60Recherche complexe, analyse approfondie
ultra_deep_thinking20-120 min50-400+Études exhaustives, rapports complets, sujets complexes

Mémoire sémantique

La mémoire persiste entre les conversations via LanceDB embarqué. Chaque échange est stocké sous forme de vecteur ; lors des prochains appels, les faits les plus pertinents sont injectés automatiquement dans le contexte.

python
from clovis import cloooooo
ai = cloooooo()

# Activer la mémoire pour un ID de conversation
reponse = ai(
    "Mon nom est Clovis, je travaille sur un moteur HFT.",
    conversation_id="session-1",
    use_memory=True
)

# Lors du prochain appel, la mémoire est réinjectée
reponse = ai(
    "Rappelle-moi sur quoi je travaille.",
    conversation_id="session-1",
    use_memory=True
)
# → "Tu travailles sur un moteur HFT..."

# Accès direct à la mémoire
faits = ai.memory.search("HFT", top_k=5)
ai.memory.clear(conversation_id="session-1")
Consolidation automatique : à partir de 30 faits par conversation, la mémoire est automatiquement consolidée — les doublons sont fusionnés, les informations obsolètes supprimées.

RAG — Retrieval-Augmented Generation

Indexez vos propres documents (PDF, DOCX, TXT, Markdown) et interrogez-les avec une recherche hybride dense + BM25, puis reranking bge-reranker pour la précision.

python
from clovis import cloooooo
ai = cloooooo()

# Ingérer un fichier
n = ai.ingest("/home/user/docs/these.pdf")
print(f"{n} chunks indexés")

# Ingérer un répertoire entier
n = ai.rag_pipeline.ingest_dir("/home/user/papers/")

# Poser une question sur les documents indexés
reponse = ai.rag("Quelle méthodologie est utilisée dans le chapitre 3 ?")
print(reponse)

# Recherche sans synthèse LLM (accès aux chunks bruts)
chunks = ai.rag_pipeline.search(
    "mécanisme d'attention",
    top_k=5,
    rerank=True
)
for chunk in chunks:
    print(chunk["text"][:200], chunk["source"])

# Lister les sources indexées
sources = ai.rag_pipeline.list_sources()
print(sources)  # ["these.pdf", "notes.md", ...]

Le pipeline RAG utilise nomic-embed-text-v1.5 (768d, ONNX CPU) pour les embeddings et bge-reranker-v2-m3 pour le reranking. Les chunks font environ 400 tokens avec overlap.


Appel d'outils

Le registre d'outils inclut exécution Python, shell, I/O fichiers et recherche web. L'exécution de code se fait dans un sous-processus avec timeout.

python
from clovis import cloooooo
ai = cloooooo()

# Lister les outils disponibles
outils = ai.tool_registry.get_schemas()
print([o["name"] for o in outils])
# ['python_exec', 'shell_exec', 'read_file', 'write_file', 'web_search', 'fetch_page']

# Exécuter un outil
result = ai.tool_registry.execute("python_exec", {
    "code": "import math; print(math.factorial(10))"
})
print(result.output)         # "3628800"
print(result.success)        # True
print(result.execution_time_ms)

# Recherche web via outil
result = ai.tool_registry.execute("web_search", {"query": "Python 3.14 release date"})
print(result.output)

Routeur intelligent

Le routeur classifie automatiquement chaque requête en sous-milliseconde et sélectionne le pipeline optimal. Utilisez ai.router directement pour contrôler le routage.

python
from clovis import cloooooo
ai = cloooooo()

# Classifier une requête sans l'exécuter
decision = ai.router.classify("Implémente un algorithme de tri rapide.")
print(decision.task_type)    # "code"
print(decision.confidence)   # 0.97

# Router et exécuter
reponse = ai.router.route("Explique la complexité de l'algorithme A*.")
# → détecte "reasoning", active thinking=True automatiquement

Types de tâches détectés

TypeDéclencheursComportement
codeimplémenter, écrire, déboguer, fonction, classe…SGLang avec prompt système code
reasoningexpressions math, expliquer, analyser, pourquoi, historique…SGLang avec thinking activé
searchdernier, actuel, actualité, prix, aujourd'hui…Recherche SearXNG + inférence
structuredjson, extraire, parser, schéma, format…Mode JSON forcé
visionimage, photo fourniePipeline vision
simplesalutations, requêtes courtesInférence directe rapide

Sorties structurées

Forcez une sortie JSON typée via le mode JSON SGLang + validation Pydantic v2. La conformité au schéma est garantie avec retry automatique.

python
from clovis import cloooooo
from clovis._structured import extract, plan, score_response
from clovis._structured import ExtractionResult, Plan, EvalScore

ai = cloooooo()

# Schéma JSON arbitraire
resultat = ai.structured(
    "Apple Inc. fondée par Steve Jobs à Cupertino en 1976.",
    schema={
        "type": "object",
        "properties": {
            "entreprise": {"type": "string"},
            "fondateur": {"type": "string"},
            "annee": {"type": "integer"}
        },
        "required": ["entreprise", "fondateur", "annee"]
    }
)
# → {"entreprise": "Apple Inc.", "fondateur": "Steve Jobs", "annee": 1976}

# Extraction d'entités et relations (schéma pré-défini)
res: ExtractionResult = extract(
    "Marie Curie a reçu le Prix Nobel de Physique en 1903."
)
print(res.entities)    # [Entity(name="Marie Curie", type="person"), ...]
print(res.relations)

# Génération de plan actionnable
p: Plan = plan("Construire un système RAG pour des documents médicaux")
for step in p.steps:
    print(step.action, "→", step.expected_output)

# LLM-as-judge (évaluation de réponse)
score: EvalScore = score_response(
    question="Quelle est la capitale de la France ?",
    answer="Paris",
    expected="Paris"
)
print(score.score, score.reasoning)

Vision

Compréhension d'images via Qwen2.5-VL-3B-Instruct (CPU, chargement paresseux ~30s au premier appel).

python
from clovis._vision import describe

# À partir d'une URL
texte = describe("https://example.com/graphique.png", prompt="Extrais les données de ce graphique.")

# À partir d'un fichier local
texte = describe("/home/user/screenshot.png")

# Via le SDK principal
reponse = ai.vision("/home/user/chart.png", prompt="Résume ce graphique.")
print(reponse)

Formats acceptés : URL HTTP/HTTPS, chemin absolu, image encodée en base64.


Embeddings & Reranking

Vecteurs 768d via nomic-embed-text-v1.5 (ONNX CPU, chargement paresseux).

python
from clovis._embed import embed, rerank

# Embeddings
vecteurs = embed(
    ["Bonjour le monde", "Hello world"],
    prefix="search_query"   # "search_document" pour les passages
)
print(len(vecteurs[0]))  # 768

# Reranking
resultats = rerank(
    query="mécanisme d'attention transformer",
    documents=["L'auto-attention permet...", "Les CNN utilisent des filtres...", "Les transformeurs remplacent les RNN..."],
    top_k=2
)
for score, doc, idx in resultats:
    print(f"[{score:.3f}] {doc[:60]}")

MiroFlow — Orchestration agentique

Le moteur de recherche agentique profond. Qwen3-32B planifie, recherche, lit des pages et synthétise — avec appel d'outils complet orchestré par MiroFlow. Jusqu'à 20 tours agentiques par requête.

100 % local. google_search passe par le bridge SearXNG local → votre instance SearXNG → vrais résultats web. scrape_website utilise Trafilatura. Zéro appel API externe, zéro clé API requise.

Pipeline

texte
Requête utilisateur
  → Orchestrateur MiroFlow
  → Qwen3-32B planifie les recherches
  → Appels outils parallèles (google_search, wiki, scrape_website)
  → Résultats injectés dans le contexte
  → Nouveau tour si des lacunes détectées
  → Synthèse finale (jusqu'à 20 tours)

Outils disponibles

OutilServeur MCPDescription
google_searchtool-searchingRecherche web via bridge SearXNG. Retourne titre, lien, extrait, questions associées.
wiki_get_page_contenttool-searchingContenu complet d'une page Wikipedia avec résumé structuré.
search_wiki_revisiontool-searchingHistorique de révision Wikipedia pour un mois donné.
search_archived_webpagetool-searchingRécupération d'archive Wayback Machine.
scrape_websitetool-searchingTexte complet d'une page via Trafilatura (bridge Jina local).
read_filetool-readingLecture de fichiers locaux.

Mode deep_thinking

Pipeline MiroFlow complet avec intégration mémoire. Recommandé pour les tâches de recherche complexes nécessitant plusieurs sources et une synthèse longue.

python
from clovis import cloooooo
ai = cloooooo()

result = ai.deep_thinking(
    "Quelles ont été les conséquences économiques de la crise COVID-19 en France ?",
    conversation_id="recherche-covid",
    use_memory=True,
    use_web=True,
)

print(result["answer"])          # Réponse complète structurée
print(result["sources"])         # URLs trouvées
print(result["model_used"])      # "miroflow:Qwen/Qwen3-32B-AWQ"
print(result["fallback_used"])   # False si MiroFlow a réussi
print(result["memory_updated"])  # True si mémoire mise à jour
print(result["run_id"])          # ID unique de la session MiroFlow

Réponse

ChampTypeDescription
answerstrRéponse complète synthétisée, en Markdown.
sourceslist[str]URLs trouvées et consultées par l'agent.
model_usedstrModèle utilisé, ex : miroflow:Qwen/Qwen3-32B-AWQ.
fallback_usedboolTrue si MiroFlow a échoué et le pipeline interne a pris le relais.
memory_updatedboolTrue si la mémoire a été mise à jour après la réponse.
run_idstrIdentifiant unique de la session MiroFlow (log JSON disponible dans MiroFlow/runs/).
errorstr | NoneMessage d'erreur si le fallback a été déclenché.

Pipeline deep_think

Pipeline de recherche itératif interne. Plus rapide que deep_thinking, sans mémoire persistante. Idéal pour les questions ponctuelles nécessitant plusieurs sources mais pas de suivi de conversation.

python — non streamé
from clovis._deep_think import deep_think

reponse = deep_think(
    "Comment fonctionne RLHF pour l'alignement des LLM ?",
    max_iterations=4,
    searches_per_step=3,
)
print(reponse)
python — streamé avec mises à jour
from clovis._deep_think import deep_think_stream

for chunk in deep_think_stream(
    "Analyse des stratégies de trading algorithmique en 2026.",
    max_iterations=4,
    searches_per_step=3,
):
    print(chunk, end="", flush=True)
# Les mises à jour de progression s'affichent en temps réel

Boucle interne

Chaque itération : planifier des requêtes → recherche parallèle SearXNG → extraire les informations clés → réfléchir aux lacunes → répéter si nécessaire. La synthèse finale utilise thinking=True pour un raisonnement approfondi. Les citations sont automatiquement incluses dans la réponse.


Ultra Deep Thinking

Le mode de recherche le plus puissant. Qwen3-32B décompose la question en axes indépendants, lance des recherches profondes en parallèle sur chacun, identifie les lacunes et les comble en plusieurs rounds, puis synthétise tout en une analyse exhaustive.

texte — architecture
1. Décomposition  → LLM découpe en N axes (ex: historique, technique, économique, comparatif...)
2. Recherche //   → deep_think() lancé en parallèle sur chaque axe (semaphore GPU)
                    chaque axe = jusqu'à 6 itérations × 5 recherches web = ~30 recherches/axe
3. Analyse gaps   → LLM identifie ce qui manque dans l'ensemble des axes
4. Comblement     → deep_think() ciblé sur chaque lacune identifiée
5. Répéter 3→4   → jusqu'à N rounds de lacunes
6. Synthèse       → contexte agrégé (120k chars max) + thinking=True → réponse définitive

Presets

PresetAxesDepth/axeGap roundsRecherches/stepDurée estiméeTotal recherches
fast43135-10 min~50
deep843420-40 min~200
ultra1265560-120 min400+
python — SDK
from clovis import cloooooo
ai = cloooooo()

# Preset "deep" — 8 axes, 3 rounds de lacunes
result = ai.ultra_deep_thinking(
    "Quel est l'impact de l'intelligence artificielle sur le marché du travail ?",
    preset="deep",
)

# Contrôle fin des paramètres
result = ai.ultra_deep_thinking(
    "Histoire complète de la cryptographie",
    preset="ultra",
    max_axes=10,           # override le preset
    depth_per_axis=5,
    gap_rounds=4,
    searches_per_step=4,
)

print(result["answer"])
print(f"Sources : {len(result['sources'])}")
print(f"Axes : {result['axes_count']}")
print(f"Rounds de lacunes : {result['gap_rounds_done']}")
print(result["run_stats"])
curl — avec streaming de progression
curl -s -X POST http://cloooooo.com/ultra_deep_thinking \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Analyse complète des stratégies de trading algorithmique en 2026",
    "preset": "deep",
    "stream": true
  }'
# Affiche les événements de progression puis la réponse finale :
# [décomposition] Génération de 8 axes de recherche...
# [axe:Stratégies HFT] recherche en cours...
# [axe:Market Making] recherche en cours...
# ...
# [lacunes round 1] 5 lacunes identifiées...
# [synthèse] 12 sections, 180k chars...
# 
# ===RÉPONSE===
# ## Analyse complète des stratégies de trading algorithmique...

Réponse

ChampTypeDescription
answerstrSynthèse finale exhaustive, structurée en Markdown avec références.
sourceslist[str]Toutes les URLs collectées (jusqu'à 100 uniques).
axes_countintNombre d'axes de recherche réussis.
gap_rounds_doneintRounds de lacunes effectués (peut être < max si aucune lacune détectée).
total_charsintVolume total de recherche brute collectée.
run_statsdictStatistiques détaillées : axes, depth, searches, sections, sources uniques.
Conseil : Utilisez stream=true pour voir la progression en temps réel. Sans streaming, l'appel peut prendre plusieurs dizaines de minutes sans retour intermédiaire.

API HTTP

Le SDK Python est la méthode recommandée. L'API HTTP est exposée au port 8000 et accessible via http://cloooooo.com ou http://localhost:8000.

POST /ia

Endpoint universel. Supporte tous les modes.

curl
curl -s -X POST http://cloooooo.com/ia \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Explique les transformeurs.", "mode": "deep_thinking"}'
ParamètreTypeDéfautDescription
promptstringrequisLa requête.
modestringnullnull = simple, "deep_thinking" = MiroFlow agentique.
thinkingboolfalseActive le chain-of-thought étendu.
use_webboolfalseRecherche web SearXNG en contexte.
use_memoryboolfalseInjecte la mémoire sémantique.
conversation_idstringnullID pour la persistance mémoire.
streamboolfalseStream la réponse en texte brut.

Autres endpoints HTTP

POST/rag/ingest
curl
curl -X POST http://cloooooo.com/rag/ingest \
  -H "Content-Type: application/json" \
  -d '{"path": "/home/user/these.pdf"}'
# → {"chunks": 47, "source": "/home/user/these.pdf"}
POST/rag/ask
curl
curl -X POST http://cloooooo.com/rag/ask \
  -H "Content-Type: application/json" \
  -d '{"question": "Quelle méthodologie ?", "top_k": 5}'
POST/embed
curl
curl -X POST http://cloooooo.com/embed \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Bonjour le monde"], "prefix": "search_query"}'
# → {"embeddings": [[...]], "model": "nomic-embed-text-v1.5", "dim": 768}
POST/deep_thinking

Pipeline MiroFlow complet avec mémoire.

curl
curl -X POST http://cloooooo.com/deep_thinking \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Analyse la bulle dotcom.", "conversation_id": "recherche-1"}'
POST/deep_think

Pipeline itératif interne, sans mémoire persistante.

curl
curl -X POST http://cloooooo.com/deep_think \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Exlique le RLHF.", "stream": true}'
POST/route
curl
curl -X POST http://cloooooo.com/route \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Implémente une recherche binaire."}'
# → {"response": "...", "task_type": "code", "confidence": 0.97}

GET /health

GET/health
json — réponse
{
  "status": "ok",
  "sglang": "ok",
  "model": "Qwen/Qwen3-32B-AWQ",
  "version": "0.5.0",
  "search": {
    "searxng": {"status": "ok", "results": 10},
    "trafilatura": "ok"
  }
}

Modèles & matériel

ComposantValeur
Moteur d'inférenceSGLang 0.5.9 — API OpenAI-compatible, port 61005
LLM principalQwen3-32B-AWQ (quantification 4 bits)
GPURTX 3090 24 Go VRAM (SM86)
Cache KV max13 661 tokens (fp16)
Modèle d'embeddingnomic-embed-text-v1.5 (768d, ONNX CPU)
Rerankerbge-reranker-v2-m3 (ONNX CPU)
Modèle visionQwen2.5-VL-3B-Instruct (CPU, chargement paresseux)
Stockage vectorielLanceDB v0.33 (embarqué, fichiers locaux)
Recherche webSearXNG sur le port 8888 + fallback DuckDuckGo

Bridges de recherche locale

Deux endpoints de bridge traduisent les formats d'API payants vers les services locaux. Ils permettent aux outils MiroFlow de fonctionner sans abonnement Serper ou Jina.

POST/serper-miro-bridge/search

Accepte le format API Serper, interroge SearXNG local, retourne JSON format Serper.

curl
curl -X POST http://localhost:8000/serper-miro-bridge/search \
  -H "Content-Type: application/json" \
  -d '{"q": "Python 3.14 features", "num": 5}'
GET/jina-miro-bridge/{url}

Accepte le format lecteur Jina (URL en chemin), extrait avec Trafilatura, retourne Markdown.

curl
curl http://localhost:8000/jina-miro-bridge/https://python.org
Configuration MiroFlow : ces bridges sont configurés automatiquement dans MiroFlow/.envSERPER_BASE_URL=http://localhost:8000/serper-miro-bridge et JINA_BASE_URL=http://localhost:8000/jina-miro-bridge. Aucune clé API n'est nécessaire.