Démarrage
Installation
Une seule commande. Aucune clé API. Aucun compte. Python 3.10+.
# Stable pip install candy-ai # v21 BETA pip install candy-ai==21.0.0b1
candy se connecte automatiquement au moteur Cedric8-Thinking. Fonctionne sur Windows, macOS et Linux.
Démarrage
Premier appel
Un import, une ligne. Comme depuis le premier jour.
from candy import Coding print(Coding.ask("Écris une fonction Python qui inverse une chaîne"))
Personnalités
120 personnalités spécialisées
On a commencé à 50 en 2023. On est maintenant à 120. Chacune optimisée pour son domaine.
from candy import Math, Writing, Medicine, Law, Finance print(Math.ask("Quelle est la dérivée de x³ + 2x ?")) print(Writing.ask("Écris un email pour décliner une réunion")) print(Medicine.ask("Symptômes du diabète de type 2 ?")) print(Finance.ask("Explique les intérêts composés"))
Configuration
Système de profils
Contrôle la langue, le style, le ton, la longueur, la température. Tout.
from candy import cfg, Coding cfg.A.lang = "FR" cfg.A.style = "detailed" cfg.A.tone = "encouraging" cfg.A.expertise = "beginner" cfg.A.max_tokens = 2000 cfg.A.temperature = 0.7 cfg.A.max_retries = 3 print(Coding.use("A").ask("Explique la récursivité"))
| Paramètre | Type | Valeurs |
|---|---|---|
| lang | str | FR, EN, ES, DE, IT, PT, JA, ZH, AR, RU… |
| style | str | detailed, concise, technical, casual, bullet, markdown, eli5 |
| tone | str | neutral, encouraging, strict, humorous, empathetic, socratic |
| expertise | str | beginner, intermediate, expert |
| max_tokens | int | tokens max dans la réponse |
| temperature | float | 0.0 (précis) → 2.0 (très créatif) |
| output_format | str | text, markdown, json, html |
| max_retries | int | tentatives en cas d'échec — défaut 3 |
Configuration
Presets
14 profils prêts à l'emploi.
cfg.A = cfg.preset("coder") # expert, markdown, 3000 tokens cfg.B = cfg.preset("french_beginner") # FR, détaillé, encourageant cfg.C = cfg.preset("creative") # casual, temp=1.1 cfg.D = cfg.preset("quick") # concis, 120 tokens
| Preset | Langue | Style | Tokens |
|---|---|---|---|
| french_beginner | FR | detailed · encouraging | — |
| french_expert | FR | concise · strict · expert | — |
| coder | EN | markdown · expert | 3000 |
| academic | EN | markdown · expert | 2000 |
| creative | EN | casual · temp=1.1 | 1500 |
| teacher | EN | detailed · encouraging | 2000 |
| quick | EN | concise | 120 |
| storyteller | EN | casual · temp=1.2 | 4096 |
| analyst | EN | bullet · expert | 2000 |
| debug | EN | markdown · expert | 3000 |
Fonctionnalités
Streaming
Réponses token par token pour les interfaces terminal et les apps web.
from candy import Writing Writing.stream_print("Raconte une histoire courte") for token in Writing.stream("Raconte une histoire courte"): print(token, end="", flush=True)
Fonctionnalités
Batch
Plusieurs prompts en un seul appel. En parallèle avec batch_async.
from candy import cfg, Summarizer cfg.A.lang = "FR" ; cfg.A.max_tokens = 300 textes = ["Article 1…", "Article 2…", "Article 3…"] resumes = Summarizer.use("A").batch([f"Résume :\n{t}" for t in textes]) for r in resumes: print(r)
Fonctionnalités
Conversations multi-tours
Sessions avec mémoire du contexte. Sauvegarde JSON. Rechargement possible.
from candy import cfg, Tutor cfg.s.lang = "FR" ; cfg.s.tone = "encouraging" session = Tutor.chat(profile="s") print(session.say("Je veux apprendre Python. Par où commencer ?")) print(session.say("Et les listes ?")) session.save("session.json") session.show_history() session.clear()
Intégration
Intégration web
Flask, FastAPI, Django. Avec ask_async pour FastAPI natif.
Flask
from flask import Flask, request, jsonify from candy import cfg, Full app = Flask(__name__) ; cfg.web.lang = "FR" @app.route("/ask", methods=["POST"]) def ask(): q = request.get_json().get("question", "") return jsonify({"answer": Full.use("web").ask(q)})
FastAPI — async natif
from fastapi import FastAPI from pydantic import BaseModel from candy import Full app = FastAPI() class Query(BaseModel): question: str @app.post("/ask") async def ask(q: Query): answer = await Full.ask_async(q.question) return {"answer": answer}
CLI
CLI & fichiers .cdy
candy est aussi une commande système complète.
candy --ask "mon prompt" # one-liner candy --score "prompt" # score qualité 0-100 candy --fix "prompt" # auto-optimise candy --status # statut API candy helper # fenêtre Helper graphique candy -- script.cdy # exécuter un fichier .cdy
Helper
Helper — génération de code
Génère du code candy complet depuis un template ou une description.
from candy import Helper Helper.list() Helper.run("chatbot", lang="FR", module="Full") Helper.run("traduction", texte="Bonjour", langues=["ES","DE","JA"])
Fonctionnalités
Candy — One-liner universel
Détecte automatiquement la meilleure personnalité selon le prompt.
from candy import Candy print(Candy.ask("Explique les décorateurs Python")) # → Coding print(Candy.ask("Recette de tiramisu", lang="FR")) # → Cooking score = Candy.score("fais un truc") print(score["score"], score["grade"]) # → 20 F print(Candy.fix("fais un truc en python"))
Fonctionnalités
Multi-agents
Orchestre plusieurs personnalités en séquence.
from candy import Agent, Coding, Debugger, Reviewer result = Agent.run( modules=[Coding, Debugger, Reviewer], task="Écris un client REST Python", verbose=True ) print(result["final"])
Fonctionnalités
Mémoire persistante
Sessions nommées dans ~/.candy/sessions/. Auto-versioning inclus.
from candy import Memory mem = Memory("mon_projet") mem.add("user", "Bonjour !") mem.save() mem.save_version("avant-refactor") print(Memory("mon_projet").as_context(last_n=5))
Fonctionnalités
Validation & JSON
Format garanti. Régénère automatiquement si non conforme.
from candy import Cooking, Analytic, ask_validated, ask_json page = ask_validated(Cooking, "default", prompt="Recette. Format:\n- Plat:\n- Ingrédients:\n- Étapes:", required_fields=["- Plat:", "- Ingrédients:", "- Étapes:"]) result = ask_json(Analytic, "default", prompt='JSON: {"ton": "", "score": 0}\nTexte: Super !') print(result["ton"], result["score"])
Utilitaires
candy.utils — 20 fonctions
Importables directement depuis candy, sans profil ni config.
from candy import detect_lang, translate, summarize, sentiment, keywords from candy import codegen, cached_ask, pipeline, full_report print(detect_lang("Hello world")) # → EN print(translate("Hello", to="FR")) # → Bonjour s = sentiment("Ce produit est fantastique !") print(s["label"], s["score"]) # → positive 0.95
Fonctionnalités
ImageGen — Génération d'images
Images, variations, descriptions et batch via Cedric8-Thinking.
from candy import ImageGen ImageGen.create("un chat astronaute", save="chat.png") ImageGen.create("robot steampunk", style="photorealistic", size="1024x1024") ImageGen.variation("orig.png", strength=0.6, save="var.png") desc = ImageGen.describe("photo.jpg", lang="FR") print(ImageGen.styles())
Nouveautés v20
Async — toutes les méthodes
Toutes les personnalités supportent l'async natif. Compatible FastAPI, asyncio, Jupyter.
ask_async() est non-bloquant. batch_async() parallélise toutes les requêtes — 10× plus rapide qu'un batch séquentiel.
import asyncio from candy import Coding, Math, Writing result = asyncio.run(Coding.ask_async("Write a bubble sort")) async def stream_it(): async for token in Writing.stream_async("Raconte une histoire"): print(token, end="", flush=True) results = asyncio.run(Coding.batch_async(["sort", "reverse", "search"])) async def multi(): code, math, text = await asyncio.gather( Coding.ask_async("Write a REST client"), Math.ask_async("Solve: ∫x²sin(x)dx"), Writing.ask_async("Write a haiku about AI"), )
Nouveautés v20
Mix & Chain — Fusion d'expertises
Mix combine plusieurs expertises en une requête. Chain les enchaîne séquentiellement.
from candy import Mix, Chain, Coding, Security, Reviewer, Debugger result = Mix(Coding, Security).ask("Écris un serveur HTTP sécurisé") result = Mix(Coding, Security).use("A").ask("Audite ce code") result = Chain([Coding, Reviewer, Debugger]).run("Écris une API REST") print(result["final"]) # réponse finale print(result["steps"]) # résultats intermédiaires result = Chain([Coding, Reviewer], profile="A").run("...")
Nouveautés v20
Retry & Cache
Backoff exponentiel automatique. Si l'API est down, candy répond depuis son cache local.
from candy import cfg, Coding cfg.A.max_retries = 5 # 1.5s → 3s → 6s → 12s → 24s result = Coding.use("A").ask("Explain decorators", use_cache=True) from candy.client import _client _client.clear_response_cache()
Nouveautés v20
Conversation+ — Titre, compression, Markdown
Titre auto, compression intelligente de l'historique, export Markdown.
from candy import Conversation, Coding chat = Conversation(Coding, profile="A", auto_compress=True) print(chat.say("Explique les décorateurs Python")) print(chat.title) # → "Décorateurs Python — exemples" chat.export_md("conversation.md") chat.save("chat.json", append=True) # fusionne
Nouveautés v20
ImageGen+ — Inpainting & Upscale
Édition ciblée par masque et amélioration de résolution x2 ou x4.
from candy import ImageGen ImageGen.edit("photo.jpg", mask="mask.png", prompt="remplace le fond par un coucher de soleil", save="editee.png") ImageGen.upscale("small.png", scale=4, save="big.png") ImageGen.upscale("photo.jpg", scale=2, save="hd.jpg")
Nouveautés v20
CLI+ — candy --doctor & --update
Diagnostic complet et mise à jour automatique en une commande.
candy --doctor [1/4] Version candy-ai v21.0.0b1 · Cedric8-Thinking [2/4] Connexion ● en ligne (42 ms) [3/4] Quota ████████░░░░ 82/500 (418 restants) [4/4] Cache 12 fichiers (38 Ko) candy --update # pip install --upgrade candy-ai
Nouveautés v21
AutoMemory
candy se souvient automatiquement de tes préférences entre les conversations, sans rechargement manuel. Persisté dans ~/.candy/user_memory.json.
Quand AutoMemory est activée, chaque message de l'utilisateur est analysé. Si candy détecte une préférence ou un fait ("je travaille avec FastAPI", "je préfère le FR"), il le stocke. À la prochaine conversation, ce contexte est injecté automatiquement dans chaque requête.
from candy import AutoMemory, Coding AutoMemory.enable() chat = Coding.chat() chat.say("Je préfère toujours des réponses en français") chat.say("Je travaille sur un projet FastAPI avec Python 3.12") # La prochaine fois, candy s'en souvient automatiquement chat2 = Coding.chat() # → répond en FR, avec le contexte FastAPI/Python 3.12 print(AutoMemory.summary()) AutoMemory.remember("Mon stack : React + FastAPI + PostgreSQL") AutoMemory.forget("FastAPI") # oublier un fait précis AutoMemory.forget() # tout effacer AutoMemory.disable() # désactiver sans effacer
Nouveautés v21
Compare
Pose la même question à plusieurs personnalités en parallèle et compare les réponses côte à côte.
from candy import Compare, Coding, Security, Reviewer import asyncio result = Compare(Coding, Security, Reviewer).ask("Comment sécuriser une API REST ?") result.show() # affichage formaté terminal print(result["coding"]) # réponse de Coding print(result["security"]) # réponse de Security name, resp = result.best() # la plus longue md = result.to_markdown() # export Markdown # Async — toutes en parallèle result = asyncio.run(Compare(Coding, Security).ask_async("...")) # Avec profil result = Compare(Coding, Security).use("A").ask("...")
Nouveautés v21
stream_to_file
Streame la réponse directement dans un fichier. Idéal pour les romans, les rapports de 10 000 mots, les bases de code volumineuses.
from candy import Writing, Coding # Génère et écrit directement sur disque, barre de progression incluse Writing.stream_to_file( "roman.txt", "Écris un roman de science-fiction de 5000 mots", show_progress=True ) # → [candy] ✓ 24,831 chars → roman.txt (18.3s) Coding.stream_to_file("api.py", "Génère une API REST complète avec FastAPI") # Append mode — ajoute à un fichier existant Writing.stream_to_file("journal.txt", "Entrée du jour…", append=True) # Avec profil personnalisé Writing.use("A").stream_to_file("article.md", "Écris un article complet sur le RAG")
Nouveautés v21
CandyLogger
Loggue chaque appel API en JSONL avec timestamp, personnalité, latence et prompt. Utile pour auditer, débugger en production, analyser les usages.
from candy import CandyLogger, Coding CandyLogger.enable() # → ~/.candy/logs/candy.jsonl CandyLogger.enable("mes_logs.jsonl") # fichier custom Coding.ask("Write a sort") # loggué automatiquement Coding.ask("Explain recursion") CandyLogger.tail(n=10) # 10 derniers appels print(CandyLogger.stats()) # stats complètes # → {"total_calls": 42, "avg_latency_ms": 312, "top_personality": "coding", …} logs = CandyLogger.read(last_n=50, personality="coding") CandyLogger.clear() CandyLogger.disable()
Nouveautés v21
ImageGen++ — Animate, StyleTransfer, CompareStyles
Trois nouvelles opérations : génération d'animations GIF, transfert de style artistique, et comparaison de tous les styles en batch.
from candy import ImageGen # animate() — génère un GIF animé ImageGen.animate("un chat qui saute sur la lune", frames=8, save="anim.gif") ImageGen.animate("vague de l'océan", frames=16, style="watercolor", save="vague.gif") # style_transfer() — applique le style d'une image sur une autre ImageGen.style_transfer( "mon_portrait.jpg", # image source (contenu) "van_gogh.jpg", # image style strength=0.8, save="portrait_van_gogh.png" ) # compare_styles() — génère la même image dans tous les styles # → styles/default.png, styles/anime.png, styles/painting.png … ImageGen.compare_styles("un château médiéval", save_dir="./styles/")
Nouveautés v21
CLI+ — candy logs
Consulte et analyse tes logs directement depuis le terminal.
candy logs # 10 derniers appels candy logs --n 50 # 50 derniers appels candy logs --stats # statistiques complètes candy logs --clear # vider les logs # Toutes les commandes CLI v21 : candy --ask "prompt" candy --score "prompt" candy --fix "prompt" candy --dry-run "prompt" candy --status candy --doctor candy --update candy --version candy logs candy helper candy -- script.cdy
Référence
Toutes les méthodes
| Méthode | Retour | Description |
|---|---|---|
| .ask(prompt) | str | Appel simple |
| .ask(prompt, use_cache=True) | str | Avec cache offline |
| .ask_async(prompt) | Coroutine[str] | Async non-bloquant — v20 |
| .stream_async(prompt) | AsyncGenerator | Streaming async — v20 |
| .batch_async(prompts) | Coroutine[list] | Batch parallèle — v20 |
| .stream_to_file(path, prompt) | dict | Streaming vers fichier — v21 |
| .use("profil") | BoundModule | Attache un profil nommé |
| .stream(prompt) | Generator | Tokens un par un |
| .stream_print(prompt) | str | Affiche les tokens |
| .batch(prompts) | list[str] | Batch séquentiel |
| .chat(profile) | Conversation | Session multi-tours |
| session.say(msg) | str | Envoie un message |
| session.title | str | Titre auto-généré — v20 |
| session.export_md(path) | None | Export Markdown — v20 |
| session.save(path, append) | None | Sauvegarde JSON |
| Mix(*modules).ask(prompt) | str | Fusion d'expertises — v20 |
| Chain([...]).run(prompt) | dict | Pipeline séquentiel — v20 |
| Compare(*modules).ask(prompt) | CompareResult | Comparaison parallèle — v21 |
| AutoMemory.enable() | None | Active la mémoire inter-sessions — v21 |
| AutoMemory.remember(fact) | None | Mémorise un fait — v21 |
| CandyLogger.enable(path?) | None | Active les logs JSONL — v21 |
| CandyLogger.stats() | dict | Statistiques d'utilisation — v21 |
| ImageGen.animate(prompt) | bytes | GIF animé — v21 |
| ImageGen.style_transfer(c,s) | bytes | Transfert de style — v21 |
| ImageGen.compare_styles(prompt) | dict | Tous les styles en batch — v21 |
| ImageGen.edit(img, prompt) | bytes | Inpainting — v20 |
| ImageGen.upscale(img, scale) | bytes | Upscale x2/x4 — v20 |
| ping() | float | Latence en ms |
| is_online() | bool | Vérifie la connexion |