Mankinds SDK
Intégrez la gouvernance IA dans vos applications. Le SDK Mankinds fournit les outils pour créer des systèmes, connecter vos sources de données, générer des datasets de test et lancer des évaluations sur 8 dimensions de confiance — programmable en JavaScript/TypeScript et Python.
from mankinds_sdk import MankindsClient
import os
client = MankindsClient(api_key=os.environ["MANKINDS_API_KEY"])
# Créer un système, générer un dataset, évaluer
system = client.create_system("Mon Assistant IA", "...", endpoint={...})
client.generate_dataset(system["id"], num_scenarios=10)
result = client.evaluate(system["id"])
print(f"Score: {result['summary']['overall_score']}%")
Commencer
Quelques étapes suffisent pour intégrer l'évaluation IA dans votre projet.
pip install mankinds-sdk
Créez un compte sur app.mankinds.io et générez votre clé API depuis les paramètres.
import os
from mankinds_sdk import MankindsClient
client = MankindsClient(api_key=os.environ["MANKINDS_API_KEY"])
Créez un système, générez un dataset de test, puis lancez l'évaluation :
# 1. Créer un système avec son endpoint
system = client.create_system(
"Assistant Conformité RGPD",
"Chatbot qui conseille les entreprises sur le RGPD.",
endpoint={
"url": "https://api.example.com/chat",
"method": "POST",
"body": {"message": "{{input}}"},
"response": {"reply": "{{output}}"}
}
)
# 2. Générer un dataset de test (10 scénarios)
dataset = client.generate_dataset(system["id"], num_scenarios=10)
# 3. Lancer l'évaluation
result = client.evaluate(system["id"])
print(f"Score global: {result['summary']['overall_score']}%")
Fonctionnalités
| Fonctionnalité | Description |
|---|---|
| Systèmes | Créer, configurer et gérer vos systèmes IA avec validation automatique de la description |
| Connecteurs | Brancher vos bases de données (PostgreSQL, MySQL, MongoDB, Snowflake, SQLite, SQL Server), outils d'observabilité (Datadog, Langfuse, LangSmith, Elasticsearch, Splunk, CloudWatch, OpenTelemetry, MLflow, OpenSearch) et fichiers de logs |
| Datasets | Fournir vos scénarios de référence ou les générer automatiquement par IA |
| Évaluations | Lancer des évaluations offline ou online sur 86 critères répartis en 8 dimensions |
| Authentification | Clé API sécurisée avec gestion fine des permissions |
Référence API
MankindsClient
Le client principal pour interagir avec l'API Mankinds.
Constructeur
MankindsClient(api_key: str, base_url: str = None, timeout: int = 30)
| Paramètre | Type | Requis | Défaut | Description |
|---|---|---|---|---|
api_key | str | Requis | — | Clé API Mankinds (format : mk_...) |
base_url | str | Optionnel | https://app.mankinds.io | URL de base de l'API |
timeout | int | Optionnel | 120 | Timeout des requêtes en secondes |
Systèmes
createSystem
Crée un nouveau système IA et valide automatiquement sa description.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
name | str | Requis | Nom du système IA |
description | str | Requis | Description du comportement attendu du système |
endpoint | dict | Requis | Configuration de l'endpoint API (url, method, body, response) |
| Retourne | Type | Description |
|---|---|---|
id | string | Identifiant unique du système créé |
success | boolean | true si la description a été validée |
recommendations | array | Recommandations pour améliorer la description |
Dans les configurations body et response de votre endpoint, utilisez les placeholders {{input}} et {{output}} pour injecter dynamiquement les scénarios de test.
system = client.create_system(
"Assistant Conformité RGPD",
"Chatbot qui conseille les entreprises sur leurs obligations RGPD et guide dans la mise en conformité.",
endpoint={
"url": "https://api.example.com/chat",
"method": "POST",
"body": {"message": "{{input}}"},
"response": {"reply": "{{output}}"}
}
)
print(f"Système créé : {system['id']}")
print(f"Description validée : {system['success']}")
getSystem
Récupère les détails d'un système.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
system_id | str | Requis | Identifiant unique du système |
| Retourne | Type | Description |
|---|---|---|
id | string | Identifiant unique du système |
name | string | Nom du système |
description | string | Description du système |
is_description_validated | boolean | true si la description a été validée |
endpoint | object | Configuration de l'endpoint |
system = client.get_system(system_id)
print(f"Nom: {system['name']}")
print(f"Description validée: {system['is_description_validated']}")
print(f"Endpoint: {system['endpoint']}")
updateSystem
Met à jour un système existant.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
system_id | str | Requis | Identifiant unique du système |
name | str | Optionnel | Nouveau nom du système |
description | str | Optionnel | Nouvelle description (déclenche une re-validation) |
endpoint | dict | Optionnel | Nouvelle configuration de l'endpoint |
| Retourne | Type | Description |
|---|---|---|
success | boolean | true si la mise à jour a réussi |
recommendations | array | Recommandations si re-validation de la description |
Si vous fournissez un endpoint, il doit contenir les champs requis : url, method, body, response. Sinon, l'exception InvalidEndpointError sera levée.
result = client.update_system(
system_id,
name="Assistant Conformité RGPD v2",
description="Version améliorée avec support des questions sur le DPO."
)
print(f"Validé: {result['success']}")
Si une nouvelle
descriptionest fournie, elle est automatiquement re-validée. En cas d'échec,DescriptionNotValidatedErrorest levée avec les recommandations.
Connecteurs
Les connecteurs permettent de brancher vos sources de données pour les évaluations. Il existe trois catégories : connecteurs database, observability et document.
Chaque système ne peut avoir qu'un seul connecteur par catégorie (database, observability).
Types disponibles
Connecteurs base de données
| Connecteur | Description | Configuration |
|---|---|---|
postgresql | Base de données PostgreSQL | host, port, database, user, password |
mysql | Base de données MySQL | host, port, database, user, password |
mongodb | Base de données MongoDB | host, port, database, user, password, authSource |
sqlserver | Base de données SQL Server | host, port, database, user, password, instance |
sqlite | Fichier SQLite | file_path, file_name |
snowflake | Data warehouse Snowflake | account, user, password, warehouse, database, schema |
Connecteurs d'observabilité
| Connecteur | Description | Capacités |
|---|---|---|
file | Fichiers de logs (.log, .txt, .json) | Logs |
datadog | Logs et traces Datadog | Logs, Traces |
elasticsearch | Logs et traces Elasticsearch | Logs, Traces (avec trace mapping) |
cloudwatch | Logs AWS CloudWatch | Logs |
opensearch | Logs OpenSearch | Logs |
splunk | Logs Splunk | Logs |
opentelemetry | Traces OpenTelemetry | Logs, Traces |
mlflow | Tracking d'expériences MLflow | Logs |
langfuse | Traces LLM Langfuse | Traces |
langsmith | Traces LLM LangSmith | Traces |
Les connecteurs avec la capacité Traces (Langfuse, LangSmith, Datadog, OpenTelemetry) fournissent des paires entrée/sortie du système, ce qui permet l'évaluation online. Les connecteurs Logs fournissent des logs applicatifs bruts pour les critères d'analyse d'artefacts (détection PII, logging sécurisé, etc.).
addConnector
Ajoute un connecteur au système.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
system_id | str | Requis | Identifiant unique du système |
connector | dict | Requis | Type et configuration du connecteur |
Si un connecteur de la même catégorie existe déjà, l'exception ConnectorAlreadyExistsError sera levée. Supprimez d'abord l'existant avec deleteConnector().
# Observabilité — fichier de logs
client.add_connector(system_id, {
"type": "file",
"config": {"file_path": "./logs/app.log"},
"name": "Logs Applicatifs",
})
# Base de données — PostgreSQL
client.add_connector(system_id, {
"type": "postgresql",
"config": {
"host": "db.example.com",
"port": 5432,
"database": "myapp",
"user": "readonly",
"password": os.environ["DB_PASSWORD"],
},
"name": "Base de Production",
})
# Observabilité — Langfuse (active l'évaluation online)
client.add_connector(system_id, {
"type": "langfuse",
"config": {
"public_key": os.environ["LANGFUSE_PUBLIC_KEY"],
"secret_key": os.environ["LANGFUSE_SECRET_KEY"],
"base_url": "https://cloud.langfuse.com",
},
"name": "Traces Langfuse",
})
getConnectors
Liste tous les connecteurs d'un système.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
system_id | str | Requis | Identifiant unique du système |
| Retourne | Type | Description |
|---|---|---|
name | string | Nom du connecteur |
category | string | Catégorie : database ou observability |
type | string | Type de connecteur (postgresql, langfuse, file, etc.) |
connectors = client.get_connectors(system_id)
for c in connectors:
print(f"{c['name']} ({c['category']}): {c['type']}")
updateConnector
Met à jour la configuration d'un connecteur existant.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
system_id | str | Requis | Identifiant unique du système |
connector | dict | Requis | Type et configuration mise à jour du connecteur |
result = client.update_connector(system_id, {
"type": "file",
"config": {"file_path": "./logs/new-app.log"},
"name": "Logs mis à jour",
})
print(f"Connecteur mis à jour: {result}")
deleteConnector
Supprime un connecteur du système.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
system_id | str | Requis | Identifiant unique du système |
category | str | Requis | Catégorie du connecteur à supprimer (database, observability) |
result = client.delete_connector(system_id, "observability")
print(f"Connecteur supprimé: {result}")
Datasets
generateDataset
Crée et valide un dataset de scénarios de référence. Vous pouvez fournir des scénarios ou demander une génération automatique.
| Paramètre | Type | Requis | Défaut | Description |
|---|---|---|---|---|
system_id | str | Requis | — | Identifiant unique du système |
num_scenarios | int | Optionnel | 10 | Nombre de scénarios à générer automatiquement (ignoré si scenarios fourni) |
scenarios | list[dict] | Optionnel | — | Scénarios personnalisés avec input (str) et outputs (list) |
| Retourne | Type | Description |
|---|---|---|
scenarios | array | Liste des scénarios validés |
scenarios[].id | string | Identifiant unique du scénario |
scenarios[].input | object | Entrée du scénario (prompt) |
scenarios[].expected_outputs | array | Sorties attendues |
scenarios[].source | string | Origine : user ou generated |
La description du système doit être validée avant de créer un dataset. Sinon, l'exception DescriptionNotValidatedError sera levée.
# Avec scénarios personnalisés
dataset = client.generate_dataset(system_id, scenarios=[
{"input": "Bonjour, comment ça marche ?", "outputs": ["Bienvenue ! Je suis là pour vous aider."]},
{"input": "Je veux un remboursement", "outputs": ["Je vous redirige vers notre service clients."]},
])
print(f"{len(dataset['scenarios'])} scénarios validés")
# Génération automatique
dataset = client.generate_dataset(system_id, num_scenarios=20)
print(f"{len(dataset['scenarios'])} scénarios générés")
updateDataset
Met à jour le dataset avec des instructions ou de nouveaux scénarios.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
system_id | str | Requis | Identifiant unique du système |
orientation | str | Optionnel | Instructions pour affiner le dataset |
scenarios | list[dict] | Optionnel | Nouveaux scénarios pour remplacer les existants |
# Affiner avec des instructions
dataset = client.update_dataset(
system_id,
orientation="Ajouter plus de cas de demandes de remboursement"
)
print(f"{len(dataset['scenarios'])} scénarios après mise à jour")
Même structure que generateDataset — le dataset mis à jour et re-validé.
Évaluations
evaluate
Lance une évaluation du système. Supporte trois modes : offline (scénarios), online (traces de production), ou mixed (les deux).
| Paramètre | Type | Requis | Défaut | Description |
|---|---|---|---|---|
system_id | str | Requis | — | Identifiant unique du système |
mode | str | Optionnel | offline | Mode d'évaluation : offline, online ou mixed |
profile | str | Optionnel | required | Profil d'évaluation (voir tableau ci-dessous) |
thematics_config | dict | Optionnel | — | Configuration personnalisée des critères offline (remplace profile) |
online_thematics_config | dict | Optionnel | — | Configuration personnalisée des critères online (requis pour le mode online/mixed) |
sampling | dict | Optionnel | { strategy: "random", size: 20 } | Stratégie d'échantillonnage des traces pour l'évaluation online |
time_range | dict | Optionnel | { preset: "24h" } | Fenêtre temporelle pour la récupération des traces de production |
wait | bool | Optionnel | true | Attendre la fin de l'évaluation avant de retourner |
poll_interval | int | Optionnel | 5 | Intervalle en secondes entre chaque vérification de statut |
on_poll | Callable[[str, int], None] | Optionnel | — | Callback appelé à chaque vérification (statut, secondes écoulées) |
| Retourne | Type | Description |
|---|---|---|
run_id | string | Identifiant unique de l'exécution |
status | string | completed, failed, running, etc. |
summary.overall_score | number | Score global en pourcentage |
summary.dimensions | object | Scores détaillés par dimension (score + passed) |
result = client.evaluate(
system_id,
profile="required",
wait=True,
poll_interval=5,
)
print(f"Statut: {result['status']}")
print(f"Score global: {result['summary']['overall_score']}%")
Avec
wait=false, seulrun_idest retourné immédiatement. UtilisezgetEvaluation(runId)pour récupérer les résultats plus tard.
Profils d'évaluation
| Profil | Type | Description |
|---|---|---|
required | Basé sur le scope | Critères obligatoires basés sur l'analyse de risque réglementaire du système |
extended | Basé sur le scope | Couverture étendue pour anticiper les risques réglementaires |
minimum | Fixe | Évaluation essentielle couvrant les critères de sécurité IA de base (8 tests/critère) |
standard | Fixe | Évaluation complète avec couverture étendue (15 tests/critère) |
maximum | Fixe | Évaluation en profondeur avec couverture maximale (30 tests/critère) |
Configuration personnalisée (thematics_config)
Pour une évaluation personnalisée, utilisez thematics_config au lieu de profile :
Note : La clé principale de
thematics_configdoit être le nom exact d'une dimension parmi celles listées ci-dessous (ex :fairness,privacy,security,accuracy, etc.).
result = client.evaluate(
system_id,
thematics_config={
"fairness": {
"gender": {"nb_tests": 5},
"age": {"nb_tests": 5}
},
"accuracy": {
"hallucination_detection": {"nb_tests": 10}
}
},
wait=True,
)
Évaluation online
L'évaluation online analyse les traces de production réelles plutôt que des scénarios synthétiques. Elle nécessite un connecteur d'observabilité avec la capacité Traces (Langfuse, LangSmith, Datadog ou OpenTelemetry).
# Évaluation online sur les traces de production
result = client.evaluate(
system_id,
mode="online",
online_thematics_config={
"security": {
"prompt_injection": {},
"pii_exfiltration": {},
},
"accuracy": {
"hallucination_detection": {},
"factual_grounding": {},
}
},
time_range={"preset": "7d"},
sampling={"strategy": "random", "size": 50},
wait=True,
)
print(f"Score online: {result['summary']['overall_score']}%")
# Évaluation mixte : scénarios offline + traces online
result = client.evaluate(
system_id,
mode="mixed",
thematics_config={
"fairness": {
"gender": {"nb_tests": 10},
"age": {"nb_tests": 10}
}
},
online_thematics_config={
"accuracy": {
"hallucination_detection": {},
"response_completeness": {},
}
},
time_range={"preset": "24h"},
wait=True,
)
Dimensions et critères disponibles
privacy — Protection des données et PII (8 critères)
pii_reuse, pii_request, pii_masking_detection, pii_in_logs, pii_in_db, pii_masking_db, pii_masking_logs, refusal_privacy
security — Résistance aux attaques et exfiltration de données (20 critères)
Exfiltration : pii_exfiltration, tech_exfiltration, tech_exfiltration_logs, tech_exfiltration_db, internal_exfiltration, internal_exfiltration_logs, internal_exfiltration_db, context_exfiltration, context_exfiltration_db, context_exfiltration_logs, traces_exfiltration, traces_exfiltration_logs, traces_exfiltration_db, refusal_security
Résistance : multiturn_resistance, prompt_injection, social_engineering, obfuscation, context_manipulation
Conformité : ip_copyright_violation, catastrophic_misuse
accuracy — Performance, fiabilité et exactitude factuelle (15 critères)
Qualité : reproductibility, quality, response_correctness, response_completeness, contextual_coherence
Factuel : hallucination_detection, factual_grounding, reformulation_stability
Spécialisé : classification_accuracy, structured_output_conformity, extraction_accuracy, edge_case_handling
Agentique : tool_call_accuracy, tool_call_f1, agent_goal_accuracy
fairness — Détection de biais et traitement équitable (8 critères)
Biais : age, ethnic, gender, health, identity, religious, socioeconomic
Intersectionnel : intersectional_bias
explainability — Transparence et justification des décisions (9 critères)
justification, purpose_disclosure, ai_nature_disclosure, ai_self_disclosure, control_transparency, ambiguous_scope_clarification, refusal_scope, refusal_nonqualification, limitation_explanation
accountability — Gouvernance, traçabilité et supervision humaine (9 critères)
Supervision : usage_conformity, scope_creep_detection, opt_out_capabilities, decision_override, override_refusal_resistance
Logging : secure_logging_db, secure_logging_logs
Éthique : traceability, human_escalation
sustainability — Efficience environnementale (2 critères)
db_environmental_efficiency, log_environmental_efficiency
systemic_risk — Risques systémiques et sociétaux (15 critères)
Intégrité de l'information : authoritative_confabulation, source_fabrication, expert_impersonation, disinformation_generation, opinion_manipulation
Sûreté : dangerous_content_refusal, deepfake_assistance, vulnerability_exploitation, malware_generation, attack_planning
Contrôle : confidential_exfiltration, context_knowledge_leakage, scope_override, autonomous_escalation, instruction_resistance
getEvaluation
Récupère le statut ou résultat d'une évaluation.
| Paramètre | Type | Requis | Description |
|---|---|---|---|
run_id | str | Requis | Identifiant de l'exécution de l'évaluation |
result = client.get_evaluation(run_id)
print(f"Statut: {result['status']}")
if result["status"] == "completed":
print(f"Score: {result['summary']['overall_score']}%")
Même structure que evaluate — voir ci-dessus.
Erreurs
Le SDK lève des exceptions typées pour faciliter la gestion des erreurs.
| Exception | Description |
|---|---|
CredentialsError | Clé API manquante ou invalide |
AuthenticationError | Clé API expirée ou rejetée (401) |
NotFoundError | Ressource introuvable (404) |
ValidationError | Erreur de validation de la requête (422) |
RateLimitError | Trop de requêtes (429) |
InvalidEndpointError | Endpoint mal configuré |
EndpointNotConfiguredError | Évaluation sans endpoint configuré |
DescriptionNotValidatedError | Description non validée |
ConnectorAlreadyExistsError | Connecteur déjà présent (même catégorie) |
ServerError | Erreur serveur (500) |
Chaque exception contient des informations contextuelles pour faciliter le debug :
from mankinds_sdk.exceptions import ConnectorAlreadyExistsError
try:
client.add_connector(system_id, connector)
except ConnectorAlreadyExistsError as e:
print(f"Connecteur {e.existing_type} déjà présent")