Documentation
Trois choses : comment brancher, comment lire les chiffres, et ce que le produit refuse de faire.
Brancher vos agents
Lematev parle l’API d’OpenAI. Tout client qui accepte une URL de base fonctionne — aucun SDK à installer, rien à réécrire.
# before client = OpenAI(api_key=OPENAI_KEY) # after client = OpenAI( base_url="https://gw.lematev.dev/v1", api_key=LEMATEV_KEY, )
Idem pour les modèles Anthropic, Mistral, Groq et DeepSeek du catalogue : vous continuez d’appeler au format OpenAI, et Lematev parle au fournisseur. Votre propre clé fournisseur se met dans les paramètres ; la facture reste la vôtre, à vos tarifs.
Nommer vos agents
C’est l’en-tête qui transforme une facture en ventilation. Sans lui, tout atterrit sous « default » et vous voyez un seul bloc — c’est-à-dire le problème que vous vouliez résoudre.
client.chat.completions.create(
model="gpt-5",
messages=messages,
extra_headers={
"x-lematev-agent": "support-triage",
"x-lematev-run": run_id,
},
)
- x-lematev-agentQuel agent appelle. Une étiquette que vous choisissez : support-triage, bot-facturation, le nom que lui donne votre code.
- x-lematev-runÀ quelle tâche appartient cet appel. Plusieurs appels partagent un même identifiant d’exécution, et c’est ce qui permet de détecter une boucle et de calculer un coût par tâche.
Nous dire quand une tâche a échoué
Par défaut, un appel compte comme réussi dès que le fournisseur répond. Cela mesure si l’appel HTTP a fonctionné, pas si la réponse était bonne — le routage apprend donc sur un signal faible tant que vous ne fermez pas la boucle.
requests.post(
"https://gw.lematev.dev/v1/feedback",
headers={"x-lematev-key": LEMATEV_KEY},
json={"call_id": call_id, "success": False},
)
Un appel après un échec suffit. Il révise l’observation au lieu d’en ajouter une seconde, et le routeur cesse de préférer un modèle qui paraissait bon marché parce que ses échecs n’étaient jamais comptés.
Streaming
Passez `stream=True` comme vous le feriez au fournisseur. Vous recevez ses propres fragments, dans son format, donc le temps jusqu’au premier token n’est pas quelque chose que nous allongeons.
stream = client.chat.completions.create(
model="gpt-5", messages=messages, stream=True,
extra_headers={"x-lematev-agent": "support-triage"},
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")
Deux différences à connaître. La comptabilisation a lieu à la fin du flux — ou si votre client s’en va en cours de réponse, car les tokens ont été dépensés que quelqu’un les lise ou non. Et là où un fournisseur ne parle pas nativement le format de streaming OpenAI, nous tamponnons sa réponse et la réémettons en flux valide : le premier token arrive donc plus tard pour ces modèles. Le tableau de bord indique quels appels ont été réémis.
Lire les chiffres
Quatre chiffres, et ils ne veulent pas dire la même chose.
- DépenseCe que vos fournisseurs ont réellement facturé sur la période. Celui-là n’est pas une estimation.
- RéférenceCe que le même trafic aurait coûté sur le modèle que vous avez déclaré, facturé sur les mêmes tokens. La longueur de sortie retenue est celle réellement observée, ce qui la sous-estime — les modèles premium sont plus bavards — donc la comparaison est conservatrice par construction.
- ÉconomiséRéférence moins dépense, au centime. Réparti entre le choix du modèle et l’élagage du contexte, et les deux se radélitionnent toujours au total.
- ÉvitéCe qu’auraient coûté les exécutions arrêtées si elles avaient continué. Cela n’a jamais figuré sur une facture, donc c’est affiché à part et jamais ajouté à « économisé ».
Coût par tâche réussie
La colonne qui compte. Un modèle bon marché qui échoue et repart en retry coûte plus cher qu’un seul appel premium qui aboutit, et un prix par appel masque précisément cela.
C’est aussi pourquoi le routeur ne prend pas simplement le modèle le moins cher : il chiffre le coût espéré pour obtenir une tâche terminée, échecs compris. Sur certains agents, cela veut dire garder le modèle cher — et il le dit.
Rapprocher de votre facture fournisseur
La première chose que fait une équipe finance, c’est additionner la facture et comparer. Deux sommes doivent tomber juste, et le tableau de bord montre les deux.
your agents $ 81.72 + counterfactual replays $ 2.34 ────────────────────────────────────── = what your provider bills $ 84.06 baseline (what you would have paid) $127.96 − savings $ 46.24 ────────────────────────────────────── = your agents $ 81.72
- Ce qui correspond à la factureVos agents, plus les rejeux contrefactuels. Les rejeux passent par votre propre clé fournisseur, donc votre fournisseur les facture — ils sont affichés sur leur propre ligne plutôt que fondus dans le total, parce qu’un total qu’on ne peut pas décomposer est un total qu’on ne peut pas vérifier.
- Ce qui n’est sur aucune factureLa référence et l’économie. Une économie est de l’argent jamais dépensé, donc aucune facture ne peut la porter. Vous la voyez à votre facture qui rétrécit : comparez un mois avant à un mois après, à volume comparable.
- S’il reste un écartTrois raisons honnêtes, aucune n’est une erreur. Le trafic qui n’est jamais passé par nous — embeddings, images, une autre équipe sur le même compte fournisseur. Les remises que nous ne voyons pas, comme la mise en cache des prompts ou un tarif négocié, qui nous font surestimer. Et les tokens facturés sur un appel qui a ensuite échoué. Au-delà d’un ou deux pour cent sans qu’aucune de ces raisons l’explique, écrivez-nous.
Est-ce devenu plus lent ?
L’autre moitié de ce que coûtent les économies, et la première question de vos ingénieurs. Basculer du trafic sur un modèle moins cher ne vaut rien si vos utilisateurs attendent désormais.
- Lisez le 95e centile, pas la moyenneUne moyenne cache précisément la queue que les gens ressentent. Quatre-vingt-dix appels rapides et dix très lents donnent une moyenne que personne n’a vécue.
- Temps jusqu’au premier tokenPour une réponse en streaming, c’est ÇA la latence perçue — une longue réponse est longue sur n’importe quel modèle. Relevé uniquement pour le streaming : une réponse tamponnée n’a pas de premier token en avance, et remplir le chiffre le flatterait.
- Comparez par modèleLe tableau ventile la distribution par modèle, pour que le moins cher puisse être confronté à celui qu’il remplace au lieu d’être cru sur parole. Cette comparaison est l’argument.
Regarder un mois, ou une année
Les fenêtres glissantes répondent à « où en sommes-nous ». Elles ne répondent pas à « l’an dernier s’est-il remboursé », qui est la question dont dépend un renouvellement.
- 7, 30, 90 joursUne fenêtre qui se termine maintenant. Bonne pour surveiller, inutile pour comparer deux mois entre eux.
- Un mois ou une année civileChoisissez-en un dans le sélecteur, ou passez `?period=2026-08` ou `?period=2026` à n’importe quel endpoint de lecture. Les bornes sont exactes : un appel à 23:59:59 le 31 appartient à ce mois, un appel à 00:00:00 le 1er non.
- Jusqu’où vous pouvez remonterVotre offre fixe la rétention, de 7 jours à 2 ans. Une période plus ancienne est grisée plutôt que masquée, et une période partiellement couverte le dit — « vous n’avez rien économisé en mars » et « nous ne conservons pas mars » sont des conclusions opposées, et un graphique vide énonce la première.
Les écrans
- Offre et usageLa distance à chaque plafond — « 12 agents sur 15 » plutôt que « 15 agents » — pour qu’un mur soit quelque chose qu’on voit venir. Au-delà d’un plafond, rien n’est coupé : ce qui tourne continue, et le prochain NOUVEL agent est refusé.
- Budget et alertesUn plafond mensuel de dépense modèles. Il prévient tout le monde une fois quand le mois franchit votre seuil, et avec l’arrêt strict il refuse les appels au-delà de 100 % au lieu de vous le dire après coup.
- Règles par agentPar agent : quels modèles il peut utiliser, un plafond par appel, et ce que coûte une tâche ratée sur celui-là précisément. Relever le coût de l’échec sur un agent critique le protège sans rendre tous les autres chers.
- Clés APIRévoquer et remplacer la clé du projet. Tous les agents qui utilisent l’ancienne s’arrêtent immédiatement — c’est le but, le jour où une clé fuite.
Les règles que vous posez par agent
Le routage est automatique ; voici où vous le contredisez. Chacune est par agent, parce que l’agent qui traite les remboursements et celui qui rédige les notes de version ne méritent pas le même traitement.
- Épingler un modèleForcer un agent sur un modèle et cesser de le router. Utile pour un agent sous contrainte de conformité, ou pendant une investigation. Vous gardez la mesure et renoncez à l’économie.
- Liste blanche de modèles ou de fournisseursRestreindre ce parmi quoi le routage peut choisir — un contrat nommant un fournisseur, une exigence de région. Le routage optimise à l’intérieur de votre liste et jamais en dehors.
- Ce que vous coûte une tâche ratéeLe réglage le plus important, et le seul que nous ne pouvons pas connaître à votre place. Au-delà du réessai : un humain qui reprend le dossier, un geste commercial, une vente perdue. Proche de zéro, nous minimisons la dépense. Élevé, nous protégeons l’aboutissement — sur cet agent seulement.
- Un plafond par appelRefuser tout appel unitaire au-dessus d’un montant. Brutal, et parfois exactement ce qu’il faut sur un agent qui traite des entrées non fiables.
Budgets et alertes
Un plafond mensuel de dépense modèle, par espace de travail. Le seul contrôle ici qui puisse réellement empêcher l’argent de sortir.
- Avertissement seulFranchir le seuil lève un événement et déclenche votre webhook. Rien n’est refusé. C’est le défaut, parce qu’un budget qui arrête la production dès le premier jour apprend aux gens à désactiver les budgets.
- Arrêt strictAu-delà du plafond, les appels sont refusés en 402 jusqu’au mois suivant ou jusqu’à ce que vous le releviez. C’est ce qui transforme un mauvais week-end en petit week-end. Activez-le une fois que vous faites confiance au chiffre.
- WebhookUne URL, appelée sur les événements de budget et de garde-fou. Tout ce qui accepte un POST : Slack, PagerDuty, votre propre endpoint. Un bouton de test se trouve à côté du champ, et un webhook en échec ne bloque jamais un appel.
{
"event": "budget.exceeded",
"workspace": "Production",
"agent": "support-triage",
"spent_usd": 412.80,
"budget_usd": 400.00
}
D’où viennent les économies
Quatre mécanismes, affichés séparément plutôt qu’en un seul chiffre, pour que vous sachiez lequel travaille pour vous.
- RoutageL’essentiel. Une tâche qu’un modèle plus petit termine correctement n’a pas besoin du grand, et cela se décide par requête à partir de taux de réussite mesurés, plutôt qu’une fois pour toutes dans votre code.
- Élagage de contexteLes longues conversations traînent un historique qui n’influence plus la réponse. L’élaguer réduit les tokens d’entrée. Crédité au prix du modèle que vous avez déclaré, pas de celui vers lequel nous avons routé, pour qu’il ne soit pas compté deux fois avec le routage.
- CacheDes consultations répétées servies sans aucun appel fournisseur. Désactivé par défaut — c’est juste pour de la classification et de l’extraction, et faux pour tout ce dont l’utilisateur attend que ça varie. À activer par déploiement.
- Boucles arrêtéesAffiché à part et jamais facturé, parce que c’est de la dépense évitée et non réalisée : un agent qui allait se répéter a été arrêté. Prenez-le comme ce qui n’a pas eu lieu, pas comme de l’argent en main.
Mesuré, pas modélisé
Le point faible de toute promesse d’économie dans cette catégorie, c’est que la référence est un modèle : « vous auriez payé X » est une affirmation. Nous mettons de la preuve dessous.
- Ce qui se passeEnviron une requête sur vingt est aussi exécutée sur le modèle que vous avez déclaré, et les deux réponses sont comparées. Les verdicts figurent au tableau de bord avec leur marge, pour que vous puissiez lire les cas où le modèle moins cher a été jugé moins bon.
- Ce que ça coûteDe l’argent réel, sur votre propre clé fournisseur, comme le reste de votre trafic — c’est pourquoi l’échantillon est petit et pourquoi il apparaît sur sa propre ligne dans le rapprochement de facture. Nous dépensons un peu de votre budget pour que le reste de la page soit mesuré plutôt qu’affirmé.
- Le désactiverMettez le taux d’échantillonnage à zéro sur votre déploiement. Vous gardez le routage et perdez la preuve derrière la référence — arbitrage raisonnable une fois que vous en avez vu assez.
Ce qu’il refuse de faire
Lematev est dans votre chemin de requête, donc il peut arrêter un appel plutôt que le signaler. Trois choses renvoient une erreur au lieu d’une réponse.
- Une exécution emballéeLe même appel répété, ou deux actions qui alternent sans progresser. HTTP 409, avec ce qui a été arrêté et ce que ça aurait coûté.
- Un budget épuiséUniquement si vous avez activé l’arrêt strict. HTTP 402 jusqu’à ce que le budget soit relevé ou que le mois change.
- Un plafond d’offreUn nouvel agent au-delà du nombre prévu, ou un mois au-delà de son quota d’appels. HTTP 402 — la requête n’a rien d’invalide, le compte a atteint ce qu’il paie.
Aucun de ces cas n’est silencieux : chacun porte un code exploitable par machine et une phrase disant ce qui s’est passé, pour que votre gestion d’erreurs les distingue d’une panne fournisseur.
Gérer les erreurs
Un refus n’est pas une panne fournisseur, et votre code ne doit pas le traiter comme tel. Chacun porte un code exploitable et une phrase, à côté du format d’erreur OpenAI standard que votre client sait déjà lire.
{
"error": {
"message": "3 identical calls detected in this run…",
"type": "lematev_execution_stopped",
"code": "identical_repeat"
},
"lematev": {
"run_id": "run_9f2c…",
"estimated_usd_saved": 0.58
}
}
Deux codes sont les nôtres. 409 signifie qu’une exécution a été arrêtée — la relancer est exactement ce qu’il ne faut pas faire. 402 signifie qu’un plafond est atteint : la requête n’a rien d’invalide, le compte a atteint ce qu’il paie.
except openai.APIStatusError as e:
body = e.response.json()
# 409 is ours: the run was stopped, not the provider failing.
if e.status_code == 409:
alert("agent looping", body["lematev"]["run_id"])
elif e.status_code == 402:
alert("limit reached", body["error"]["code"])
else:
raise
Comptes, espaces de travail et équipe
Un compte est une personne. Un espace de travail est un ensemble d’agents avec ses propres chiffres. Ce n’est pas la même chose, et la différence compte le jour où quelqu’un s’en va.
- Un abonnement, par compteVous achetez une offre une fois, pas une fois par espace. Les quotas — agents, appels, sièges — appartiennent au compte et se comptent sur l’ensemble de ses espaces : un second espace réorganise ce que vous avez acheté au lieu de le multiplier.
- Plusieurs espacesUn par produit, par client ou par environnement. Agents, budgets, règles et clés fournisseur restent dans l’espace auquel ils appartiennent, donc la préproduction ne peut pas dépenser le budget de la production. Le nombre dépend de votre offre.
- Inviter des collèguesL’invitation part par e-mail et expire en sept jours. Quelqu’un qui a déjà un compte Lematev garde ses propres espaces et gagne un siège dans le vôtre. Une personne présente dans trois de vos espaces compte pour un siège, pas trois.
- Partir, transmettre, supprimerUn membre peut quitter sans demander au propriétaire. Un propriétaire peut transmettre l’espace à un membre — faites-le avant de quitter une entreprise, sinon l’espace part avec vous. Supprimer un espace et supprimer votre compte sont deux boutons distincts : le premier garde votre compte, le second vous retire et remet tout espace partagé à son membre le plus ancien.
Applications mobiles et tout ce que vous ne contrôlez pas
Un téléphone ne peut pas garder de clé permanente — n’importe qui peut dézipper un paquet d’application. Émettez plutôt un jeton de courte durée depuis votre propre serveur.
token = requests.post(
"https://gw.lematev.dev/v1/client-tokens",
headers={"authorization": f"Bearer {LEMATEV_KEY}"},
json={"agent": "chat-mobile",
"ttl_seconds": 600,
"max_calls": 20},
).json()["token"] # lmc_… — hand this to the phone
- Ce que le jeton permetAppeler la passerelle, et rien d’autre. Il est limité à un agent, expire en quelques minutes et porte un budget d’appels strict : un jeton qui fuit vaut à un attaquant une poignée d’appels, pas votre compte. Il ne peut ni lire votre tableau de bord ni changer un réglage.
- Ce qu’il ne supprime pasIl vous faut toujours un serveur : quelque chose doit détenir la clé de projet et décider qui mérite un jeton. Ce qu’il supprime, c’est la nécessité de relayer chaque appel par vous — ce qui coûte de la latence et de la bande passante sur mobile.
Vos données
- Ce que nous conservonsDes métadonnées d’appel — quel agent, quel modèle, combien de tokens, ce que ça a coûté, combien de temps. Il n’existe aucune colonne pour le contenu d’une requête ou d’une réponse : nous stockons ce qu’un appel a coûté, pas ce qu’il disait.
- ExportTout, en JSON, depuis le menu du compte. Sans ticket et sans délai.
- SuppressionEn libre-service et immédiate, depuis le même menu. Supprimer un espace efface son historique ; supprimer votre compte vous retire ainsi que les espaces dont vous êtes seul propriétaire. Ni l’un ni l’autre ne s’annule.
- Clés fournisseurEn écriture seule : une fois enregistrée, une clé n’est jamais réaffichée, seulement le fait qu’elle existe. Scellée au repos, chaque valeur liée à son espace pour qu’une ligne volée ne puisse pas être rejouée ailleurs.
Avant de brancher la production
- Ajoutez d’abord votre clé fournisseurSans elle, le tout premier appel repart en 401. Votre fournisseur vous facture directement, à vos tarifs — nous ne sommes jamais sur cette facture.
- Commencez par un seul agentNommez un agent, observez-le une journée, et comparez le coût par tâche réussie à ce que vous attendiez. C’est une façon moins coûteuse d’être en désaccord avec nous que de tout basculer d’un coup.
- Posez un budget dès le premier jourMême large. L’arrêt strict est la seule chose qui transforme un mauvais week-end en petit week-end, et le laisser actif ne coûte rien.
- Gardez un moyen de nous contournerUne variable d’environnement qui renvoie votre client directement chez le fournisseur. Nous sommes dans votre chemin de requête : si nous tombons, vos agents tombent, et vous devez pouvoir nous éviter sans redéployer.
- Fermez la boucle de retourTant que vous ne le faites pas, le routage apprend sur « l’appel n’a pas planté ». Une requête par tâche ratée suffit, et c’est la différence entre économiser de l’argent et baisser la qualité sans le voir.
Ce qu’il ne fait pas
Écrit noir sur blanc pour que vous l’appreniez ici plutôt qu’au milieu d’une intégration.
- Il ne parle que le format OpenAILa passerelle accepte les chat completions. Elle route VERS les modèles Anthropic, Google, Groq, Mistral et DeepSeek, mais un client utilisant le SDK Anthropic natif ne peut pas simplement changer son URL de base — c’est un autre format de fil.
- Les chat completions, pas le resteLes embeddings, la génération d’images, l’audio et l’API assistants ne sont pas routés. Ces appels doivent continuer d’aller directement chez votre fournisseur.
- Il ne peut pas juger une réponse seulLa qualité vient de ce que vous lui dites et de l’échantillonnage contrefactuel. Sans l’un ni l’autre, il optimise sur un signal faible — c’est pourquoi l’appel de retour compte plus qu’il n’en a l’air.