Qu'est-ce que Pyspur ?

Pyspur est une plateforme open source conçue pour accélérer le développement d'agents IA en fournissant un environnement visuel basé sur des nœuds. Elle permet aux ingénieurs de construire, déboguer et déployer des flux de travail IA complexes en connectant des composants modulaires sur un canevas glisser-déposer.
Drag & Drop to build AI Agents.
— Shubham Saboo (@Saboo_Shubham_) December 19, 2024
And deploy to API in one click with Nocode.
100% Opensource. pic.twitter.com/iPEJEzIHVI
Le problème principal que Pyspur résout est le manque de transparence et le cycle d'itération lent courants dans le développement d'IA. Il s'attaque à "l'enfer des prompts" et aux "angles morts des flux de travail" en permettant aux développeurs d'inspecter les entrées et sorties de chaque étape de la logique de leur agent en temps réel. La plateforme inclut un support intégré pour des modèles avancés comme la Génération Augmentée par Récupération (RAG), permet des points d'arrêt "human-in-the-loop", et peut déployer n'importe quel flux de travail en tant qu'API prête pour la production en un seul clic. En fin de compte, Pyspur aide les ingénieurs à construire des systèmes IA plus fiables et débogables plus rapidement.
Vous voulez une plateforme intégrée et tout-en-un pour que votre équipe de développeurs travaille ensemble avec une productivité maximale ?
Apidog répond à toutes vos exigences et remplace Postman à un prix beaucoup plus abordable !
We’re thrilled to share that MCP support is coming soon to Apidog! 🚀
— Apidog (@ApidogHQ) March 19, 2025
Apidog MCP Server lets you feed API docs directly to Agentic AI, supercharging your vibe coding experience! Whether you're using Cursor, Cline, or Windsurf - it'll make your dev process faster and smoother.… pic.twitter.com/ew8U38mU0K
Commençons !
1. Configuration de l'environnement
Choisissez l'option de configuration qui correspond le mieux à votre objectif. Pour le développement local et l'expérimentation, l'installation via pip
est suffisante. Pour les systèmes évolutifs ou de production, la configuration basée sur Docker est recommandée car elle fournit un environnement reproductible et conteneurisé avec une instance PostgreSQL dédiée.
Option A : Installation locale via pip
Prérequis : Python 3.11+
Installer depuis PyPI :
pip install pyspur
Initialiser le répertoire du projet : Cette commande crée une structure de projet, incluant un fichier .env
pour la configuration.
pyspur init my-pyspur-project && cd my-pyspur-project
Lancer le serveur : L'option --sqlite
indique à Pyspur d'utiliser une base de données SQLite locale, supprimant la dépendance à un serveur de base de données séparé.
pyspur serve --sqlite
Accéder à l'interface utilisateur : Naviguez vers http://localhost:6080
dans votre navigateur.
Option B : Configuration Docker
Prérequis : Docker Engine
Exécuter le script de configuration : Cette commande télécharge et exécute un script shell qui clone le dépôt Pyspur, configure le fichier docker-compose.dev.yml
et lance la pile d'application (frontend, backend, base de données).
curl -fsSL https://raw.githubusercontent.com/PySpur-com/pyspur/main/start_pyspur_docker.sh | bash -s pyspur-project
Accéder à l'interface utilisateur : Naviguez vers http://localhost:6080
.
2. Construisons un flux de travail avec Pyspur
Au lieu de construire à partir de zéro, nous allons charger et analyser un modèle Pyspur existant. Cette approche offre un aperçu réaliste d'un flux de travail non trivial.
Charger le modèle :
- Sur le tableau de bord Pyspur, cliquez sur "New Spur".
- Dans la fenêtre modale qui apparaît, sélectionnez l'onglet "Templates".
- Choisissez le modèle "Joke Generator". Le canevas se remplira avec un flux de travail pré-construit.
Analyse du flux de travail :
Ce flux de travail est conçu pour générer une blague, puis l'affiner. Il utilise un BestOfNNode
, un composant avancé qui exécute un prompt LLM N fois, utilise un autre appel LLM pour noter les N sorties, et sélectionne la meilleure.
Décortiquons les nœuds clés tels que définis dans joke_generator.json
:
input_node
(InputNode
) : Ce nœud définit le point d'entrée du flux de travail.
config.output_schema
:{ "topic": "string", "audience": "string" }
- Cela spécifie que le flux de travail nécessite deux entrées de type chaîne de caractères : le
topic
(sujet) de la blague et sonaudience
(public) cible.
JokeDrafter
(BestOfNNode
) : C'est la première étape de la création de la blague.
config.system_message
:"You are a stand-up comedian who uses dark humor like Ricky Gervais or Jimmy Carr..."
(Vous êtes un humoriste de stand-up qui utilise l'humour noir comme Ricky Gervais ou Jimmy Carr...)config.user_message
:"Your audience is: {{input_node.audience}}\nThe topic should be about {{input_node.topic}}"
(Votre public est : {{input_node.audience}}\nLe sujet doit être à propos de {{input_node.topic}})- Ce modèle Jinja2 insère dynamiquement les données du
input_node
. config.samples
:10
- Cela indique au nœud de générer 10 brouillons de blagues.
config.rating_prompt
:"Rate the following joke on a scale from 0 to 10..."
(Notez la blague suivante sur une échelle de 0 à 10...)- Après avoir généré 10 blagues, ce prompt est utilisé pour qu'un LLM note chacune d'elles. Le nœud sélectionne ensuite la blague la mieux notée.
config.output_schema
:{ "initial_joke": "string" }
- La sortie du nœud est une seule chaîne de caractères : la meilleure blague parmi les 10 échantillons.
JokeRefiner
(BestOfNNode
) : Ce nœud prend la blague ébauchée et l'améliore.
config.system_message
:"Your goal is to refine a joke to make it more vulgar and concise..."
(Votre objectif est d'affiner une blague pour la rendre plus vulgaire et concise...)config.user_message
:{{JokeDrafter.initial_joke}}
- De manière cruciale, l'entrée de ce nœud est la sortie du nœud
JokeDrafter
. config.samples
:3
- Il génère 3 versions affinées de la blague initiale.
- Il utilise également un prompt de notation pour sélectionner la meilleure des trois versions affinées.
config.output_schema
:{ "final_joke": "string" }
Liens : Le tableau links
dans le JSON définit le flux de données :input_node
-> JokeDrafter
-> JokeRefiner
.
Exécution et inspection :
- Dans le panneau de test à droite, utilisez l'entrée de test pré-remplie ou créez la vôtre (par exemple, Sujet : "Assistants IA", Public : "Ingénieurs logiciels seniors").
- Cliquez sur Run (Exécuter).
- Pendant l'exécution du flux de travail, cliquez sur le nœud
JokeDrafter
. Vous pouvez inspecter sesrun_data
, qui montreront les 10 échantillons générés et leurs notes correspondantes, vous donnant une vue transparente du "processus de pensée" de l'agent. - La blague finale, affinée, sera disponible dans la sortie du nœud
JokeRefiner
.
3. Implémentation d'un pipeline RAG
Bien que ne faisant pas partie du générateur de blagues, la Génération Augmentée par Récupération (RAG) est une capacité essentielle de Pyspur. Voici le processus technique pour ajouter des connaissances à un agent :
- Ingestion de documents (Collection) : Naviguez vers la section RAG. Lorsque vous créez une "Collection de documents" et téléchargez un fichier (par exemple, un PDF), Pyspur lance un processus backend qui analyse le document en texte, le segmente en morceaux configurables basés sur la longueur des tokens, et stocke ces morceaux avec les métadonnées sources dans sa base de données.
- Vectorisation (Index) : La création d'un "Index vectoriel" à partir d'une collection déclenche un autre processus. Pyspur itère sur chaque morceau de texte, effectue un appel API à un modèle d'embedding spécifié (par exemple,
text-embedding-ada-002
d'OpenAI) pour obtenir une représentation vectorielle, et insère ou met à jour (upserts) ces vecteurs dans une base de données vectorielle configurée (par exemple, ChromaDB, PGVector). - Récupération (Nœud de flux de travail) : Dans un flux de travail, le Nœud de récupération (Retriever Node) est configuré pour pointer vers un Index vectoriel spécifique. Lors de l'exécution, son entrée
query
est embarquée (embedded) en utilisant le même modèle, et une recherche sémantique (plus proche voisin approximatif) est effectuée sur la base de données vectorielle pour récupérer les morceaux de texte les plus pertinents. Ces morceaux sont ensuite passés comme contexte à un LLM en aval.
4. Déploiement en tant qu'API de production
Lorsque votre flux de travail est finalisé, vous pouvez l'exposer en tant que point d'accès HTTP sécurisé.
Lancer le déploiement : Cliquez sur le bouton "Deploy" (Déployer) dans la barre de navigation supérieure.
Sélectionner le type d'appel API :
- Blocking (Synchrone) : Pour les flux de travail à exécution rapide. Le client reçoit le résultat dans la même réponse HTTP.
- Point d'accès :
POST /api/wf/{workflow_id}/run/?run_type=blocking
- Non-Blocking (Asynchrone) : Pour les flux de travail de longue durée (comme notre générateur de blagues avec plus de 10 appels LLM). Le client reçoit immédiatement un
run_id
et doit interroger un point d'accès séparé pour le résultat. Cela évite les délais d'attente côté client. - Point d'accès de démarrage :
POST /api/wf/{workflow_id}/start_run/?run_type=non_blocking
- Point d'accès de statut :
GET /api/runs/{run_id}/status/
Intégrer avec votre application :
La fenêtre modale de déploiement génère le code client. Le corps de la requête POST
doit être un objet JSON où la clé initial_inputs
contient un objet dont les clés correspondent au title
de vos nœuds d'entrée.
Exemple de client Python (pour le générateur de blagues) :
import requests
import json
import time
PYSUR_HOST = "http://localhost:6080"
WORKFLOW_ID = "your_workflow_id_here" # Obtenez ceci depuis la fenêtre modale de déploiement
# Les clés de ce dictionnaire doivent correspondre au 'output_schema' du input_node
payload = {
"initial_inputs": {
"input_node": {
"topic": "Python decorators",
"audience": "Senior Software Engineers" # Ingénieurs logiciels seniors
}
}
}
# 1. Démarrer l'exécution non bloquante
start_url = f"{PYSUR_HOST}/api/wf/{WORKFLOW_ID}/start_run/?run_type=non_blocking"
start_resp = requests.post(start_url, json=payload)
run_id = start_resp.json()['id']
print(f"Workflow started with run_id: {run_id}") # Flux de travail démarré avec run_id : {run_id}
# 2. Interroger pour obtenir le résultat
status_url = f"{PYSUR_HOST}/api/runs/{run_id}/status/"
while True:
status_resp = requests.get(status_url)
data = status_resp.json()
status = data.get("status")
print(f"Current status: {status}") # Statut actuel : {status}
if status in ["COMPLETED", "FAILED"]: # COMPLETED (TERMINÉ), FAILED (ÉCHOUÉ)
print("Final Output:") # Sortie finale :
print(json.dumps(data.get("outputs"), indent=2))
break
time.sleep(2)
Conclusion
Pyspur offre un environnement robuste, transparent et techniquement fondé pour le développement d'agents IA. En abstraiant les opérations individuelles en nœuds modulaires et en fournissant un canevas visuel, il permet aux ingénieurs de se concentrer sur la logique de haut niveau de leurs agents. La véritable force de la plateforme réside dans sa profonde inspectabilité — vous permettant de tracer le flux de données et de déboguer les entrées/sorties de chaque composant — et sa transition transparente du prototype visuel à l'API prête pour la production. Le passage d'agents simples à appel unique à des flux de travail complexes en plusieurs étapes utilisant des modèles comme Best-of-N ou RAG n'est pas seulement possible, mais intuitif. En construisant avec Pyspur, vous ne connectez pas seulement des boîtes ; vous concevez des systèmes IA fiables, débogables et évolutifs.
Vous voulez une plateforme intégrée et tout-en-un pour que votre équipe de développeurs travaille ensemble avec une productivité maximale ?
Apidog répond à toutes vos exigences et remplace Postman à un prix beaucoup plus abordable !