Aller au contenu

Tâches programmées

Une tâche est un prompt réutilisable que vous configurez une fois, puis qui s’exécute à la demande, selon un planning, sur appel d’API, ou sur un événement d’une base de connaissance (un document ajouté, modifié ou supprimé). À chaque exécution, la tâche mobilise les ressources que vous lui avez données (bases de connaissance, connecteurs, recherche web, exécution de code) et livre son résultat par email, message Slack ou webhook, en texte ou en JSON.

Une tâche reste une requête différée : un déclenchement = un appel au modèle + une livraison. Il n’y a pas de chaînage entre tâches ni de processus permanent.

Les tâches se créent et se configurent dans le portail (/portal/taches) : prompt, variables, ressources, modèle, fréquence, sorties et format. La création demande une session (elle identifie le créateur, dont le périmètre est réutilisé à chaque exécution), elle n’est donc pas exposée par l’API.

L’API (/v1/tasks) sert ensuite à lister, lire, modifier, supprimer, déclencher une tâche et à consulter son historique, typiquement depuis une automatisation (Make, n8n, un cron, un script).

Les tâches sont propres à une organisation. L’API exige donc une clé d’organisation portant le scope tasks ; une clé personnelle est refusée.

Le champ Prompt du portail est un éditeur visuel : la mise en forme (titres, listes, gras, tableaux) s’applique directement et le prompt est enregistré en markdown. Une bascule Markdown donne accès à la source brute. Les variables ${nom} et les citations de document (@) s’écrivent normalement dans les deux modes.

Le prompt d’une tâche peut contenir des variables ${nom}. À chaque déclenchement, vous fournissez leurs valeurs dans un objet inputs. Les variables système ${date}, ${now} et ${task_name} sont toujours disponibles.

{ "inputs": { "dossier_id": "D-123", "priorite": "haute" } }

Toutes les routes exigent l’en-tête Authorization: Bearer sk-… (clé d’organisation, scope tasks).

RouteVerbeRôle
/v1/tasksGETListe les tâches de l’organisation.
/v1/tasks/{slug}GETDétail d’une tâche.
/v1/tasks/{slug}PATCHMet à jour partiellement une tâche.
/v1/tasks/{slug}DELETESupprime une tâche (et son historique).
/v1/tasks/{slug}/runPOSTDéclenche un run (trigger = api).
/v1/tasks/{slug}/runsGETHistorique des runs (statuts, dates, livraisons).
/v1/tasks/{slug}/runs/{run_id}GETExport complet d’un run (config, métriques, résultat, feedback, déroulé).

POST /v1/tasks/{slug}/run accepte { "inputs": {…}, "context": "…", "wait": false }.

Le champ context (optionnel, texte libre jusqu’à 32 000 caractères) est ajouté au prompt pour ce run précis — utile pour passer le contenu de l’enregistrement qui a déclenché votre scénario (Make, n8n…). Il est traité comme des données, pas des consignes : une instruction qui s’y trouverait n’est pas exécutée.

{ "inputs": { "client": "ACME" }, "context": "Extrait du dossier : …" }

Par défaut (wait absent ou false), l’appel est asynchrone : il répond 202 avec un run_id, et le résultat est livré par les sorties configurées.

Fenêtre de terminal
curl -X POST https://api.astrolabe.chat/v1/tasks/brief-quotidien/run \
-H "Authorization: Bearer sk-…" \
-H "Content-Type: application/json" \
-d '{"inputs":{"dossier_id":"D-123"}}'
{ "run_id": "", "status": "pending" }

Avec "wait": true, l’appel attend le résultat (borné par un délai côté serveur). Au-delà de ce délai, il répond 202 avec le run_id, à interroger via /runs.

{
"run_id": "",
"status": "done",
"output": "",
"error": null,
"delivered": [{ "type": "email", "ok": true, "detail": "vous@org.fr" }]
}

En format JSON (réglage de la tâche), output est l’objet déjà parsé, directement exploitable dans l’étape suivante d’un scénario no-code.

GET /v1/tasks/{slug}/runs renvoie les métadonnées d’exécution : statut, dates, état des livraisons, et les métriques du runmodel (modèle effectif), duration_ms, cost_eur (coût en euros, remise de cache incluse) et co2_g (empreinte carbone en grammes de CO₂eq). Ces champs sont null pour les exécutions antérieures à leur capture. Le contenu du résultat n’est pas exposé par cette route ; utilisez wait:true sur /run pour récupérer le résultat d’une exécution.

GET /v1/tasks/{slug}/runs/{run_id} renvoie l’export complet d’une exécution, en un seul document autoportant : la configuration de la tâche (consigne, ressources, format de sortie, budget), les métriques et les entrées du déclenchement, le résultat, le feedback posé et le déroulé (tours de modèle, outils appelés, sources).

C’est le même document que le bouton Exporter en JSON du tableau de bord : un diagnostic se scripte comme il se clique. Utile pour joindre une exécution à un ticket, la relire hors ligne ou la faire analyser ailleurs.

{
"format": "astrolabe.task-run/v1",
"exported_at": "2026-07-23T10:00:00.000Z",
"task": { "slug": "veille-hebdo", "prompt": "", "kb_slugs": ["docs"] },
"run": { "id": "", "status": "done", "cost_eur": 0.0421, "usage": { } },
"result": "",
"feedback": "",
"trace": { "steps": [], "sources": [], "rounds": [] }
}

result, feedback et trace sont chiffrés au repos et déchiffrés pour cette réponse ; ils valent null quand l’exécution n’en a pas produit.

L’export porte tout ce qui est connu du run, pas seulement son résultat :

  • run : statut, déclencheur, entrées du déclenchement, dates, durée, coût en euros, carbone, modèle effectif, usage (tokens, part de cache) et l’état de chaque livraison ;
  • trace.steps : chaque appel d’outil — outil, base visée, requête et filtres, paramètres bruts, nombre de résultats, sortie, tour qui l’a demandé, et l’indicateur d’échec le cas échéant ;
  • trace.rounds : chaque tour de modèle avec ses tokens d’entrée/sortie, la part servie par le cache, son coût, sa durée et son carbone ;
  • trace.sources : les extraits cités (document, score, facettes, lien) ;
  • run.progress_rounds : les tours mesurés pendant l’exécution. C’est la seule mesure disponible sur un run échoué, annulé ou encore en cours, dont le déroulé complet n’est jamais écrit.

Chaque tâche a sa page dédiée au portail (cliquez sur sa carte dans Tâches) : la configuration en un coup d’œil, des totaux sur 30 jours (nombre d’exécutions, coût, carbone) et l’historique complet — chaque exécution avec sa durée, son coût en euros et son empreinte carbone. Cliquez sur une exécution réussie pour lire son résultat. La page s’actualise toute seule tant qu’une exécution est en cours ; les liens des emails de résultat mènent directement à ce tableau de bord.

Pendant qu’une exécution est en cours, l’historique affiche sa progression — le tour atteint et le temps déjà passé — au lieu d’un simple « En cours ». Sur une tâche longue, on voit ainsi qu’elle avance, et à quel rythme.

Sous le résultat, une exécution en mode agent affiche son déroulé : la chronologie complète de ce qu’elle a fait, dans l’ordre. Les outils appelés (recherches, lectures de page, écritures dans une base…) avec leurs paramètres et leur nombre de résultats, et entre eux les tours de modèle avec la taille du contexte, la part servie par le cache, les tokens produits, la durée et le coût.

Les deux sont côte à côte pour une raison : le contexte est réinjecté à chaque tour, donc il grossit avec les résultats accumulés juste au-dessus de lui. On voit ainsi quelle recherche a fait gonfler le contexte, et on distingue une boucle trop large (tour long avec un gros contexte) d’un appel qui traîne côté modèle (tour long avec un petit contexte).

Ce qui n’a pas abouti y figure aussi, signalé en rouge et compté dès l’en-tête : un tour en délai dépassé (avec le temps qu’il a coûté), un outil en échec — une écriture refusée, une recherche dont les moteurs n’ont pas répondu. C’est souvent ce qui explique qu’une exécution se soit déclarée terminée sans avoir produit l’effet attendu.

Le déroulé indique aussi les sources citées. Vous voyez ainsi ce que la tâche a fait pour arriver à son résultat, ce qui aide à écrire un feedback précis. Il est chiffré au repos comme le résultat et n’est pas relu par le modèle (affichage seul).

Une tâche qui a une base en Écriture peut changer les facettes d’un document — typiquement faire passer une fiche de « à faire » à « fait » une fois le travail livré. Les valeurs doivent exister dans le schéma de facettes de la base ; sinon l’appel échoue avec la liste des valeurs acceptées, et le modèle peut se corriger.

Pour chaque base de connaissance et chaque connecteur, une tâche a un niveau d’accès : Aucun (non utilisé), Lecture (le cas courant) ou Écriture. En écriture, la tâche peut modifier la ressource : ajouter, modifier ou supprimer des documents d’une base, ou appeler les opérations d’écriture d’un connecteur.

Le niveau est plafonné par les droits de la personne qui a créé la tâche : une tâche ne peut jamais écrire une ressource que son créateur ne peut pas écrire lui-même (le sélecteur « Écriture » est alors désactivé). Ce plafond est re-vérifié à chaque exécution — si l’accès du créateur est retiré entre-temps, la tâche retombe automatiquement en lecture seule. L’écriture n’est jamais accordée par défaut.

Une tâche peut se déclencher automatiquement quand un document bouge dans une base de connaissance : dans la fenêtre d’édition, activez « Déclencher sur un événement d’une base de connaissance », choisissez la base surveillée, les événements (ajout / modification / suppression) et, en option, une condition sur les facettes (ne déclenche que si le document porte, par exemple, type=facture).

Le document déclencheur est fourni à la tâche : sa référence, et — pour un ajout ou une modification — son contenu (si la base est aussi déclarée en Lecture dans les ressources de la tâche). Cas d’usage : « à chaque nouvelle facture, vérifie sa conformité », « à chaque compte-rendu ajouté, mets à jour le suivi ».

Comptent comme une modification : une édition du contenu, une mise à jour par synchronisation d’un connecteur, et un changement de facette — typiquement déplacer une fiche d’une colonne à l’autre dans la vue kanban. C’est ce qui permet le schéma « liste de tâches à faire » : on dépose une fiche, on la passe en à faire, et ce passage déclenche le traitement.

Plusieurs mouvements rapprochés sur le même document ne déclenchent qu’une seule exécution, sur l’état final. Déplacer une fiche puis la ramener aussitôt, ou enchaîner deux corrections, ne lance donc pas deux traitements redondants : c’est l’état du document au moment du traitement qui compte, et il est le même dans les deux cas. Deux documents distincts déclenchent bien, eux, deux exécutions.

Quand une tâche a un déclencheur KB, vous pouvez référencer les métadonnées du document qui l’a déclenchée, dans le prompt comme dans les champs de livraison (destinataires email, sujet, destinataire Slack) :

VariableContenu
${document.titre}Titre du document
${document.reference}Identifiant externe (external_id)
${document.date}Date métier (AAAA-MM-JJ)
${document.url}Lien source
${document.evenement}ajout, modification ou suppression
${document.base}Slug de la base surveillée
${document.facette.<clé>}Valeur(s) d’une facette, ex. ${document.facette.dossier}

Exemples : un sujet d’email Nouveau transcript : ${document.titre}, ou un destinataire Slack ${document.facette.responsable} (si la facette porte un email). Un destinataire templaté est re-vérifié membre de l’organisation au moment de l’envoi (même garde que les destinataires fixes) ; une variable absente se résout en vide.

Une tâche peut surveiller une base dans laquelle elle écrit. C’est même le schéma le plus courant : une base recense des demandes à traiter, la tâche se déclenche à chaque nouvelle fiche, fait le travail, puis reclasse la fiche (avancement, compte rendu).

Elle ne se re-déclenche pas pour autant : Astrolabe retient quelle tâche est à l’origine de chaque écriture, et n’envoie jamais un événement à la tâche qui vient elle-même d’écrire le document. Les autres tâches qui surveillent la même base, elles, sont bien déclenchées comme d’habitude ; et si quelqu’un d’autre (une personne, une synchronisation) modifie ensuite ce document, la tâche repart normalement.

Une modification que vous faites ensuite (reclasser la fiche, éditer son contenu, la supprimer) réveille normalement la tâche : la trace d’auteur ne vaut que pour l’écriture de la tâche elle-même.

Ce mécanisme couvre l’auto-déclenchement d’une tâche par elle-même. Pour les cas indirects (deux tâches qui s’écrivent mutuellement), posez un budget (ci-dessous).

Pendant qu’une tâche travaille sur une fiche, celle-ci porte un indicateur « n tâches en cours » dans la liste des documents de la base (Connaissances), avec le nom des tâches concernées au survol. Il se met à jour tout seul et disparaît une fois les exécutions terminées : on voit d’un coup d’œil qu’un document est en train d’être traité, et par combien de tâches à la fois. Vous n’y voyez que les tâches que vous avez le droit de consulter (les vôtres, ou toutes si vous administrez l’organisation).

Par défaut, une tâche envoie sa réponse finale aux destinations configurées. C’est simple, mais ça impose au livrable de tenir dans une seule réponse, donc sous le plafond de tokens.

Dès qu’une tâche a au moins une destination (email ou Slack), l’agent dispose en plus d’un outil deliver : il peut envoyer un contenu pendant son exécution, autant de fois qu’il le souhaite. Un rapport en cinq parties peut ainsi partir en cinq messages, sans être contraint par le plafond d’une génération unique.

Deux règles à connaître :

  • L’agent choisit le contenu, jamais le destinataire. Les adresses et canaux restent ceux que vous avez configurés dans la tâche, avec leurs variables (${document.titre}, ${date}…) rendues exactement comme pour un envoi automatique. C’est délibéré : un destinataire choisi par le modèle serait choisi par ce qu’il lit, donc détournable par une page web ou un document piégé.
  • Si l’agent a livré, la réponse finale n’est pas ré-envoyée. Sans quoi vous recevriez les morceaux, puis le tout une seconde fois. La réponse sert alors de compte rendu et reste consultable dans le tableau de bord.

Vous n’avez rien à activer : l’outil apparaît dès qu’une destination existe. Pour l’inciter à s’en servir, dites-le dans le prompt — par exemple « envoie le rapport section par section, puis résume en trois lignes ce que tu as envoyé ».

Par défaut, il n’y en a pas. Le modèle s’arrête quand il a fini de répondre, qu’il lui faille trois lignes ou quinze pages. Une tâche peut produire un livrable (rapport de veille, synthèse mensuelle) bien plus long qu’une réponse de chat, et rien ne vient le raboter.

Le champ Longueur maximale de la réponse sert donc à l’inverse : imposer une limite, en tokens de sortie (minimum 256 ; comptez environ 750 mots pour 1 000 tokens). Utile pour garantir des réponses courtes, ou pour borner une dépense. Laissé vide, il reprend le réglage de l’organisation (page Assistant), et à défaut il n’y a aucune limite.

Ce qu’il faut savoir si vous en posez un : au-delà du plafond, la réponse est coupée — et le dit. Le résultat porte alors une mention explicite de troncature, dans le tableau de bord comme dans l’email. Une réponse incomplète ne se fait jamais passer pour complète.

Reste que générer prend du temps, et qu’un run n’est pas éternel : s’il dépasse le temps qui lui est imparti, la tâche rend ce qu’elle a produit jusque-là, avec une mention de réponse partielle. Si votre tâche produit régulièrement de longs documents, deux approches valent mieux qu’une seule réponse massive :

  • donnez-lui une base de connaissance en écriture et demandez-lui d’y écrire le document, la réponse ne portant qu’un résumé. Le document est alors consultable, cherchable et versionné, au lieu de vivre dans un email ;
  • ou faites-lui envoyer le livrable en plusieurs fois avec l’outil de livraison (section précédente) : chaque envoi a son propre budget.

Par API : champ output_max_tokens sur PATCH /v1/tasks/{slug}, ou le paramètre standard max_tokens sur /v1/chat/completions.

Chaque tâche a un réglage Exécutions simultanées (1 à 20, défaut 3) : le nombre de runs qui peuvent tourner en parallèle. Quand plusieurs déclenchements arrivent en même temps (par exemple plusieurs documents qui bougent lors d’un import), les runs au-delà de cette limite sont mis en file et s’exécutent dès qu’un créneau se libère, dans l’ordre d’arrivée. Aucun déclenchement n’est perdu (contrairement à un simple « saut »).

  • 1 : les runs s’enchaînent un par un — utile pour une tâche qui relit son historique (mode Dernier résultat), où l’ordre compte.
  • 3 (défaut) et au-delà : jusqu’à N runs en parallèle — plus rapide sur une rafale. Au-delà de ~3 runs agentiques d’une même personne, le débit est de toute façon borné par la limite de la clé (les runs supplémentaires patientent en file).

Un plafond de sécurité borne la file en cas d’emballement (import très volumineux) : au-delà, les déclenchements supplémentaires sont ignorés et tracés.

Si le serveur est interrompu pendant une exécution (coupure, déploiement, plantage), le run est repris automatiquement à la minute suivante : il n’est ni perdu, ni laissé indéfiniment « en cours ». Le plafond d’exécutions simultanées reste respecté pendant la reprise.

L’exécution redémarre depuis le début du prompt — le travail déjà effectué par le modèle n’est pas rejoué à l’identique. Une tâche qui écrit dans une base doit donc rester idempotente (utiliser external_id pour un ajout, par exemple) si elle peut être reprise.

Chaque tâche accepte un plafond de dépense, au total et/ou par jour (en euros, vides par défaut = pas de plafond). Une fois le plafond atteint, les déclenchements suivants sont ignorés plutôt qu’exécutés, avec une trace dans l’historique expliquant le blocage. Le budget quotidien se réinitialise à minuit, dans le fuseau de la tâche.

C’est le garde-fou à poser sur une tâche déclenchée par événement, dont le rythme dépend d’une source que vous ne maîtrisez pas entièrement (un import massif, une synchronisation, une autre tâche qui écrit). Un plafond en euros borne ce qui compte vraiment, la dépense, là où un simple nombre d’exécutions ne dit rien du coût réel.

Le coût d’une exécution n’étant connu qu’une fois celle-ci terminée, le contrôle porte sur la dépense déjà engagée : la dernière exécution peut donc dépasser légèrement le plafond. Réglez-le en conséquence si votre marge est serrée.

Une tâche peut, en option, relire ses propres exécutions passées (réglage dans le portail) : soit son dernier résultat, soit tout son historique (recherche). C’est utile pour des tâches incrémentales, par exemple « ne me signale que les nouveautés depuis le dernier passage ». C’est une lecture seule de ses propres sorties.

Sur le tableau de bord d’une tâche, ouvrez une exécution réussie et laissez un feedback (« trop long », « cite tes sources », « tu as oublié les factures d’achat »). Ce retour est relu par la tâche à ses exécutions suivantes — via la mémoire d’exécution ci-dessus (il faut donc que « Accès à l’historique » soit réglé sur Dernier résultat ou Historique complet). C’est ainsi qu’une tâche s’améliore au fil du temps, sans que vous ayez à réécrire son prompt.

Écrire un bon feedback suppose de relire le résultat et le déroulé. Le bouton Demander un avis, au-dessus du champ, fait ce travail pour vous : le modèle relit la consigne de la tâche, ce qu’elle a réellement fait (outils appelés, échecs) et ce qu’elle a produit, puis propose un retour en quelques consignes actionnables.

Vous choisissez le modèle et, si votre organisation en a défini, la personnalité qui donne le ton. La proposition atterrit dans le champ, éditable : relisez-la, ajustez-la, puis enregistrez. Rien n’est posé sans votre validation, et l’analyse est facturée comme une requête ordinaire (sur votre consommation, au sein de l’organisation).

Deux actions no-code, identiques d’une plateforme à l’autre :

  • Lister les tâches (GET /v1/tasks) : pour construire un menu dynamique de tâches.
  • Déclencher une tâche (POST /v1/tasks/{slug}/run) : sélection de la tâche dans une liste, inputs (objet JSON) et une option Attendre le résultat. Combinée à une sortie webhook de la tâche, cela ferme la boucle : votre scénario déclenche la tâche, la tâche répond sur le webhook du scénario.

Voir n8n / Make / code pour la configuration des connexions.