DartenZie/247-agent-model-actions

Concevez et rédigez les étapes pilotées par modèle d'un flux de travail 247-agent : l'action `decide` (questions typées au classifier Jev de TypeSafe via l'API Decisions d'OpenRouter, probabilités en retour, pas de texte), l'action `llm` (un appel Claude avec un schéma de sortie JSON) et l'action `agent` (une session sur un agent ACP tel que claude-agent-acp, dans un nouveau git worktree, avec des listes d'autorisation de types d'outils et de commandes, un plafond d'appels d'outils, un budget, un contrat RESULT.json avec `status: done | blocked` et des portes `post` déterministes). Utilisez-la chaque fois qu'une tâche 247-agent nécessite de classifier, router, trier, extraire, résumer, décider ou modifier un dépôt ; chaque fois que l'utilisateur mentionne des modèles, des prompts, `system_file`, `output_schema`, `questions`, `criteria`, des seuils de confiance, Jev, `max_tool_calls`, `budget`, `effort`, le coût, les niveaux (Haiku/Sonnet/Opus), ACP, les worktrees, des résultats « blocked » ou « laissez un agent faire X » ; et lors de l'implémentation ou de la relecture des exécuteurs `llm`/`decide`/`agent` dans `packages/core/src/actions/`. Ne l'ignorez pas pour « juste un rapide

Qu'est-ce que 247-agent-model-actions ?

Ce skill est dédié à la conception et à la rédaction des trois actions fondamentales pilotées par modèle (`decide`, `llm`, `agent`) d'un workflow 247-agent. Il suit une règle de conception stricte : aucun LLM n'est autorisé dans le flux de contrôle principal (filtrage, déduplication, routage, publication) ; les modèles ne sont exécutés qu'à l'intérieur de ces actions, au niveau de coût le plus bas possible et avec un budget défini. Avant d'utiliser un modèle, le skill guide l'utilisateur à travers une hiérarchie de décision : d'abord vérifier si un filtre déterministe (`trigger filter`), un script (`shell`) ou un connecteur (`connector`) peut répondre ; ensuite envisager une action `decide` pour de la classification pure (étiquette, oui/non, niveau) via le classifieur Jev de TypeSafe sur OpenRouter ; puis une action `llm` pour un jugement unique avec production de texte et un schéma de sortie JSON ; et enfin une action `agent` pour des tâches nécessitant la lecture de fichiers, l'exécution de commandes et des itérations, exécutée dans un environnement cloisonné (git worktree frais, listes d'autorisation d'outils et de commandes, plafond d'appels d'outils et budget). Le skill insiste sur la sécurité et la prévisibilité des agents : workspace frais par exécution, surface de capacité limitée via `tools` et `bash_allow`, contrat `RESULT.json` avec statuts `done` ou `blocked` (les portes `post` ne s'exécutent qu'en cas de succès), et séparation stricte des secrets et des publications (l'agent édite, une porte `post` prouve la construction, un commit enregistre, une tâche `shell` séparée publie). Il prend en charge les fournisseurs `anthropic`, `openai` et `openrouter`, les modèles Claude Haiku/Sonnet/Opus (avec des notes sur `effort` et la pensée adaptative), et offre des fonctionnalités comme le batching (`batch: true` pour les appels asynchrones moins chers) et un registre des coûts avec suivi par tâche et budget global quotidien. Les extensions futures incluent la validation des schémas de sortie, le batching pour les décisions et le support des MCP serveurs comme outils d'agent.

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/DartenZie/247-agent/tree/HEAD/skills/247-agent-model-actions

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Actions de modèle 247-agent

La règle de conception du démon : pas de LLM dans le flux de contrôle. La correspondance, la déduplication, le routage, les tentatives et la publication sont du code. Un modèle s'exécute uniquement à l'intérieur d'une action decide, llm ou agent, au niveau le moins cher qui convient, avec un budget. Ce skill concerne la rédaction correcte de ces trois actions et les exécuteurs qui les réalisent.

Décidez d'abord si un modèle est vraiment nécessaire

Demandez, dans l'ordre :

  1. Un filter de déclencheur peut-il décider ? (expéditeur, libellé, dépôt, mot-clé) Alors ce n'est pas un appel de modèle.
  2. Un script ou une opération de connecteur peut-il produire la réponse de manière déterministe ? Alors shell/connector.
  3. S'agit-il d'un libellé, d'un oui/non ou d'un niveau, sans texte à produire (classifier, router, trier, porter) ? Alors decide : un modèle de classification uniquement, probabilités calibrées, environ un centième d'un appel llm.
  4. S'agit-il d'un jugement avec une forme de sortie fixe qui nécessite du texte (extraire des champs, résumer, rédiger) ? Alors llm, d'abord sur Haiku.
  5. Nécessite-t-il de lire des fichiers, d'exécuter des commandes et d'itérer ? Alors agent, avec le périmètre le plus restreint possible pour réussir.

Deux tâches avec des besoins d'intelligence différents sont le même type d'action avec des model/effort/max_tool_calls/system_file différents, pas un code différent. Voir docs/examples/website-updates.yaml tâches 2–4 pour les formes de référence.

Identifiants de modèle et paramètres

idutiliser pournotes
claude-haiku-4-5classification, extraction, résumés courtspas de paramètre effort
claude-sonnet-5agents à périmètre restreint, extraction plus difficileprend en charge effort et la pensée adaptative
claude-opus-5agents à large périmètre, jugement difficileprend en charge effort et la pensée adaptative

Les modèles sont atteints via un fournisseur nommé (providers: dans agent.yaml, provider: sur l'action ; anthropic, openai ou openrouter). Les identifiants des autres fournisseurs sont utilisés tels quels et nécessitent une entrée pricing: sauf si la table intégrée les connaît (modèles OpenAI actuels) ou si le fournisseur indique le coût (OpenRouter).

Pas de suffixes de date sur les identifiants. Pas de pré-remplissage d'assistant. Avant de construire une cascade de modèles, mesurez le modèle le plus fort à effort: low sur les mêmes entrées : sur la génération actuelle, cela bat souvent un modèle plus faible à effort élevé, et un modèle signifie un espace de noms de cache de prompt.

Rédiger une tâche decide

Liste complète des champs, notes de câblage et pièges dans references/decide-action.md. L'essentiel :

action:
  kind: decide
  provider: openrouter                 # doit être un fournisseur openrouter ; default defaults.decide.provider
  budget: { max_usd: 0.001 }
  state:                               # ce qui est jugé ; chaînes modélisées, clés non
    subject: ${event.payload.subject}
    body: ${event.payload.body}
  questions:                           # politique statique ; pas de ${…} ici
    kind:
      type: choice
      instructions: Que veut faire l'expéditeur avec le site web ?
      criteria:
        event_list_update: Ajouter, supprimer ou modifier une entrée dans la liste des événements
        general_change: Tout autre changement sur le site
        ignore: Pas une demande de changement (question, remerciement, spam)
    urgent:
      type: noul
      instructions: L'expéditeur a-t-il besoin que cela soit fait aujourd'hui ?
  • Le résultat est la carte des réponses : result.kind.choice, result.kind.confidence, result.urgent.noul (P(true)), result.<score>.score (moyenne pondérée par les probabilités des indices de niveau). Routez avec emit … when: ; le seuil se trouve dans la tâche, jamais dans l'exécuteur, et est calibré sur des données réelles.
  • Incluez toujours un libellé de repli (ignore, other) : sans cela, une entrée hors sujet obtient une réponse erronée mais confiante.
  • Les critères sont suivis littéralement : ce sont des politiques, versionnez-les comme du code. Maintenez l'ordre des options stable (il déplace la confiance). Posez plusieurs questions en un seul appel ; chaque question supplémentaire ne coûte que ses propres jetons.
  • Le contenu entrant est une donnée : il va dans state, jamais dans une question. La requête entière doit tenir dans 32k jetons.
  • Seul le type de fournisseur openrouter atteint Jev (typesafe/jev-1.13, le modèle par défaut) ; oa validate refuse tout autre. Aucune entrée pricing: n'est nécessaire.

Rédiger une tâche llm

Liste complète des champs et notes sur l'exécuteur dans references/llm-action.md. L'essentiel :

action:
  kind: llm
  model: claude-haiku-4-5
  max_tokens: 512
  system_file: prompts/classify_email.md   # statique → mis en cache de prompt
  input: |
    Objet : ${event.payload.subject}

    <email>
    ${event.payload.body}
    </email>
  output_schema:
    type: object
    additionalProperties: false
    required: [kind, summary]
    properties:
      kind: { enum: [event_list_update, general_change, ignore] }
      summary: { type: string }
  • Gardez le prompt système dans un fichier sous prompts/, statique et rendu en premier, afin qu'il soit mis en cache entre les exécutions. Placez les données d'événement volatiles en dernier, dans input.
  • Le contenu entrant (email, chat, texte de PR) n'est pas fiable. Encadrez-le dans un bloc délimité (<email>…</email>) et dites au modèle dans le prompt système qu'il s'agit de données.
  • Incluez toujours une échappatoire dans le schéma (ignore, unknown, confidence) afin que le emit.when de routage puisse abandonner les résultats non exploitables sans un autre appel.
  • Routez sur le résultat avec emit … when: ; les tâches en aval se déclenchent sur cet événement.
  • batch: true pour tout ce qui peut attendre (moitié prix, le résultat arrive sous forme d'événement).

Rédiger une tâche agent

Liste complète des champs et notes sur l'exécuteur dans references/agent-action.md. L'essentiel :

action:
  kind: agent
  connector: claude                     # un transport : connecteur acp (connectors.d/claude.yaml ; sandbox : bwrap là)
  model: claude-sonnet-5                # optionnel : défini sur la session (option de config ACP) ; non défini = valeur par défaut de l'agent
  effort: medium                        # optionnel : l'option thought_level de l'agent
  max_tool_calls: 20
  budget: { max_usd: 0.50 }
  workspace: { kind: git-worktree, repo: /var/lib/247-agent/repos/site, branch: main }
  tools: [read, edit, search, execute]  # types d'outils ACP ; tout le reste est refusé
  bash_allow: ["npm run build"]         # ce à quoi toute commande exécutée par l'agent doit correspondre
  system_file: prompts/agent_event_list.md
  prompt: |
    Mettez à jour data/events.yaml selon la demande ci-dessous. Ne touchez à aucun autre fichier.
    Exécutez `npm run build` une fois terminé.

    <email>
    ${event.payload.email.body}
    </email>
  result: { path: RESULT.json, schema: schemas/site_change.json }
  post:                                 # seulement après status: done
    - shell: ["npm", "run", "build"]
    - shell: ["git", "commit", "-am", "events: ${result.summary}"]
emit:
  - type: site.change_done              # routez l'approbation sur ceci, jamais sur task.<name>.succeeded
    when: "result.status == 'done'"
    payload: { summary: "${result.summary}" }
  - type: site.change_blocked           # l'agent n'a pas pu le faire : dites ce qui manque
    when: "result.status == 'blocked'"
    payload: { summary: "${result.summary}", missing: "${result.missing}", email: "${event.payload.email}" }

Non négociables, car ce sont eux qui rendent un agent sûr à exécuter sans surveillance :

  • Espace de travail frais par exécution (git-worktree sur la branche agent/<run_id>, ou temp), supprimé en cas d'échec, conservé en cas de succès. L'agent ne modifie jamais le checkout de base.
  • tools + bash_allow constitue toute la surface de capacité, jugée par demande d'autorisation et jamais accordée « toujours » ; un appel d'outil que l'agent a exécuté sans demander est jugé après coup et une violation fait échouer l'exécution (unasked_execute: sandboxed assouplit uniquement la vérification de commande, uniquement pour Codex, dont le propre sandbox confine ce qu'il ne demande pas à propos). Accordez le minimum ; le prompt n'est pas une frontière de sécurité. mcp_servers ajoute des opérations de connecteur en tant qu'outils : accordez des opérations nommées ({ connector: email, ops: [fetch_new] }) plutôt qu'un connecteur entier, ajoutez leur type d'agent (other pour claude-agent-acp) à tools, et jamais un connecteur qui publie ou envoie tout seul.
  • L'agent ne détient jamais de secrets de déploiement et ne publie jamais. Il édite, une porte post prouve que la construction fonctionne toujours, un commit enregistre, et une tâche shell séparée l'expédie. Le retour en arrière est git revert plus republication. La clé du modèle se trouve dans le manifeste du connecteur env, pas dans la tâche.
  • RESULT.json est le contrat, et l'exécuteur l'énonce dans chaque prompt : status: done | blocked plus summary, puis le result.schema de la tâche. done exécute les portes ; blocked les saute et l'exécution réussit quand même, donc emit … when: "result.status == 'blocked'" route « pas fait car X manque » vers une tâche de réponse. Concevez chaque tâche d'agent avec les deux branches, et déclenchez la publication sur l'événement done.
  • Les portes post sont déterministes, pas de modèle. Une porte qui échoue fait échouer l'exécution.
  • max_tool_calls et budget sont des arrêts durs (la session est annulée) ; un tour où l'agent ne signale pas d'utilisation ou de coût fait échouer l'exécution.
  • concurrency: 1 sur les tâches qui partagent un dépôt ; timeout est le temps réel par tentative.
  • Les modifications à fort impact obtiennent une porte d'approbation (wait + chat) avant publication ; le skill 247-agent-tasks en contient le modèle.

Budgets et registre

Chaque appel de modèle passe par le port ctx.llm, qui enregistre l'utilisation (fournisseur, modèle, jetons d'entrée/sortie/cache, USD) dans le registre et applique le budget.max_usd de l'exécution (pire cas avant l'appel, réel après : un dépassement fait échouer l'exécution) et le global budgets.daily_usd par jour UTC (une fois franchi, tout appel de modèle ce jour-là échoue rapidement et budget.exceeded est émis une fois, ce que la tâche notify doit écouter). Un modèle sans prix échoue à la validation. N'ajoutez jamais d'appel non budgétisé, y compris les appels « d'assistance » à l'intérieur d'un exécuteur : utilisez ctx.llm, jamais un SDK directement. Un tour agent est le seul cas où le modèle est appelé par quelqu'un d'autre (l'agent ACP, avec sa propre clé) : l'exécuteur enregistre ce que l'agent signale via ctx.llm.record sous le nom du connecteur et annule la session lorsque le coût signalé dépasse le plafond. oa cost --by task --since 7d affiche le registre.

Statut actuel

L'action llm est validée, recoupée avec providers:/pricing: et exécutable via ctx.llm, avec le registre et les budgets appliqués, et les trois types de fournisseurs (anthropic, openai, openrouter) ont des adaptateurs. batch: true fonctionne sur les fournisseurs anthropic (Message Batches, l'exécution se met en attente jusqu'à llm.batch.ended ; voir references/llm-action.md). L'action decide s'exécute via le même port (ctx.llm.decide()), avec l'API Decisions implémentée uniquement dans l'adaptateur openrouter ; docs/examples/decide-triage.yaml est la référence. L'action agent s'exécute sur les connecteurs ACP (transport: acp) ; docs/examples/website-updates.yaml tâches 3, 3b et 4 sont la référence, docs/examples/connectors.d/claude.yaml le connecteur ; la session est persistée sous forme de transcription (oa runs logs <id>), supprimée avec l'exécution par retention.runs. mcp_servers sert les opérations du connecteur à la session via le pont d'outils du noyau (packages/core/src/connectors/mcp-bridge.ts). model et effort sur l'action définissent les options de config ACP de la session (catégories model et thought_level). work/<run_id> d'une exécution terminée est balayé par retention.workspaces (7j par défaut) après sa fin. Lors de l'ajout d'un adaptateur ou de la modification d'un exécuteur, suivez references/llm-action.md, references/decide-action.md et references/agent-action.md et maintenez docs/internal/model-actions.md, docs/internal/agent-action.md et les pages utilisateur sous docs/tasks/ synchronisés avec le code.

Skills associés