Accueil / Articles

Une boucle de codage à deux agents sans tête utilisant OpenCode et Ollama

Comment répartir la planification et l’évaluation entre deux agents dans OpenCode avec Ollama, en utilisant des permissions, des compétences, des règles de censure, des captures d’écran et des commits réservés uniquement aux humains.

Éditeur : REACTAPP.TOP11 min de lecture2623 mots

Sources: Ollama on Steroids with OpenCode: A Headless Multi Agent Coding Workflow

La plupart des démonstrations de codage par IA impressionnent jusqu’au moment où quelqu’un pose une question technique banale : que s’est-il exactement passé, qui l’a examinée, quels tests ont été exécutés, et est-il possible de reproduire tout cela demain ?

Le flux de travail présenté ci-dessous cherche à y répondre. Au lieu d’une fenêtre de chat qui produit de temps en temps un correctif fiable, il considère le codage par IA comme un petit cycle de développement :

  • un agent planifie et met en œuvre
  • un deuxième agent examine et donne son accord
  • chaque demande reçoit sa propre boîte de session locale
  • chaque exécution laisse derrière elle des journaux et des preuves que des tests ont été effectués
  • un humain, jamais un agent, décide quand le code est commité ou poussé
  • les demandes privées et les résultats des sessions restent privés

La division du travail : MiniMax élabore des plans et écrit du code, GLM les examine et les approuve, OpenCode gère le flux de travail et Ollama dirige les demandes vers les modèles. Ce système n’offre pas une autonomie magique ; il s’agit d’un cycle reproductible qui génère des plans, des examens, des tests, des captures d’écran, des vérifications de sécurité, puis effectue des commits sous le contrôle d’une personne.

En ce qui concerne les outils, OpenCode propose une commande opencode run non interactive, des agents nommés, une sélection de modèles, un paramètre --dir, ainsi que la possibilité d’associer une exécution à une instance opencode serve sans interface graphique. Les sessions peuvent être exportées à l’aide du paramètre --sanitize. Ollama documente l’intégration avec OpenCode via la commande ollama launch opencode, et OpenCode lit les paramètres de configuration au niveau du projet, les agents, les permissions, les compétences ainsi que les serveurs MCP.

Le fichier de configuration d’exemple nomme ses modèles Ollama Cloud minimax-m3:cloud et glm-5.1:cloud ; MiniMax est destiné au codage et aux tâches d’agent, tandis que GLM est présenté comme un modèle phare pour l’ingénierie d’agents. Ce schéma ne dépend pas nécessairement de ces modèles précis. Considérez les noms de modèles comme des exemples et consultez le catalogue actuel d’Ollama avant de les copier. Les prompts bruts, les résultats des sessions, les chemins locaux, les clés ainsi que les captures d’écran provenant du projet original ne sont pas partagés ici, seule la méthode l’est.

Cessez de considérer le codage assisté par l’IA comme une simple conversation

Un agent de codage isolé partage une faiblesse avec un développeur travaillant seul sous pression : il peut se convaincre lui-même qu’il a terminé. Demander à nouveau au même modèle de le faire ne résout pas ce problème. Un processus, en revanche, le fait :

Prompt -> Plan -> Review -> Implement -> Test -> Review -> Fix -> Signoff -> Human commit

Le layout ressemble à ceci :

control-workspace/
  AGENTS.md
  opencode.json
  .opencode/
    agents/
      minimax-builder.md
      glm-reviewer.md
    skills/
      opencode-ollama-agent-guardrails/
        SKILL.md
  agent-sessions/
    project-slug/
      promptNN/
        PROMPTNN_CODER.md
        PROMPTNN_REVIEWER.md
        PROMPTNN_PLAN.md
        PROMPTNN_PLAN_REVIEW.md
        PROMPTNN_IMPLEMENTATION.md
        PROMPTNN_TEST_RESULTS.md
        PROMPTNN_IMPLEMENTATION_REVIEW.md
        PROMPTNN_SIGNOFF.md
        redacted logs
        screenshot references
  product-repo/

Pourquoi commencer par un espace de travail de contrôle parent ? Rien que dans le répertoire du produit, l’agent peut ne pas être en mesure de voir les fichiers de prompts, les fichiers de session, les règles partagées ou l’ensemble du flux de travail. Les chemins absolus, quant à eux, peuvent inclure des détails spécifiques à la machine dans les journaux. D’où la règle : lancer OpenCode depuis l’espace de travail parent, utiliser des chemins relatifs, conserver les modifications apportées au produit dans le répertoire du produit et placer les résultats de la session en dehors de celui-ci. Cela peut sembler ennuyeux, mais c’est justement pour cette raison que cela fonctionne.

Deux agents avec des tâches distinctes

Le choix de conception clé n’est pas le modèle exact, mais plutôt la séparation des tâches.

Le constructeur

minimax-builder peut planifier, modifier du code, exécuter des commandes et rédiger des notes d’implémentation. Ses responsabilités consistent à lire la demande et AGENTS.md, rédiger un plan, appliquer les retours du réviseur, n’implémenter que la portée approuvée, effectuer des validations, enregistrer ce qui a changé et ce qui a échoué, ainsi que s’arrêter en attendant l’approbation humaine pour tout commit. Interdits : effectuer des commits, des pushes, des rebases, des force-pushes, passer à la demande suivante, assouplir les tests et modifier des fichiers réservés au réviseur.

Le réviseur

glm-reviewer est conçu pour être strict. Sa liste de contrôle : le plan correspond-il à la demande ? L’implémentation reste-t-elle dans les limites prévues ? Les tests sont-ils pertinents ? Les fichiers générés ont-ils été modifiés intentionnellement ? Les captures d’écran du navigateur confirment-elles les affirmations ? La gestion des données sensibles est-elle adéquate ? Le constructeur exagère-t-il ses résultats ?

Son vocabulaire de décision est très restreint :

APPROVED
CHANGES_REQUESTED
SIGNED_OFF
NOT_SIGNED_OFF

Un vocabulaire limité ne laisse que peu de marge pour manœuvrer. « Ça a l’air bon dans l’ensemble » n’est pas une approbation définitive.

La configuration OpenCode

Voici à quoi ressemble la configuration :

{
  "$schema": "https://opencode.ai/config.json",
  "model": "ollama/minimax-m3:cloud",
  "default_agent": "minimax-builder",
  "share": "disabled",
  "instructions": ["AGENTS.md"],
  "enabled_providers": ["ollama"],
  "permission": {
    "read": {
      "*": "allow",
      "*.env": "deny",
      "*.env.*": "deny",
      "*.env.example": "allow"
    },
    "glob": "allow",
    "grep": "allow",
    "webfetch": "ask",
    "websearch": "ask",
    "external_directory": "deny",
    "skill": {
      "*": "allow"
    }
  },
  "agent": {
    "minimax-builder": {
      "description": "Main planning and implementation agent.",
      "mode": "primary",
      "model": "ollama/minimax-m3:cloud",
      "temperature": 0.2,
      "permission": {
        "edit": {
          "*": "deny",
          "product-repo/**": "allow",
          "agent-sessions/project-slug/**": "allow"
        },
        "bash": {
          "*": "ask",
          "cd product-repo && *": "ask",
          "git status *": "allow",
          "git diff *": "allow",
          "git log *": "allow",
          "git commit *": "deny",
          "git push *": "deny",
          "git rebase *": "deny",
          "rm *": "deny"
        }
      }
    },
    "glm-reviewer": {
      "description": "Strict reviewer. Must not edit product code.",
      "mode": "primary",
      "model": "ollama/glm-5.1:cloud",
      "temperature": 0.1,
      "permission": {
        "edit": {
          "*": "deny",
          "agent-sessions/project-slug/**": "allow"
        },
        "bash": {
          "*": "ask",
          "git status *": "allow",
          "git diff *": "allow",
          "git log *": "allow",
          "grep *": "allow",
          "rg *": "allow",
          "git commit *": "deny",
          "git push *": "deny",
          "git rebase *": "deny",
          "rm *": "deny"
        },
        "task": "deny"
      }
    }
  }
}

Deux détails méritent attention. Le partage est désactivé par défaut, et comme OpenCode dispose d’une option share, la définir sur "disabled" bloque une voie d’éventuelles fuites accidentelles. L’examinateur ne dispose pas non plus de droits d’édition étendus : il peut écrire des fichiers d’évaluation et de validation dans le dossier de session, mais ne devrait pas modifier le code en production. OpenCode propose des règles de permissions détaillées pour edit, bash, read, grep, glob, skill et d’autres fonctions, de sorte que la configuration elle-même devrait garantir le bon déroulement du workflow.

Adaptez les chemins à votre propre répertoire. Le principe reste inchangé :

builder can edit product code;
reviewer can write review notes;
neither agent can commit or push;
external directories are denied;
dangerous shell commands ask or deny.

Les compétences en tant que garde-fou portable

Le élément le plus réutilisable n’est pas seulement le fichier de configuration. C’est la compétence. Les compétences OpenCode sont des définitions SKILL.md réutilisables, conservées dans des dossiers de compétences projet ou globaux. L’emplacement canonique au niveau du projet est :

.opencode/skills/<skill-name>/SKILL.md

Il existe également des parcours de compétences compatibles avec Claude et avec les agents, mais pour ce flux de travail, il est judicieux de rester simple. Placez la compétence de protection ici :

.opencode/
  skills/
    opencode-ollama-agent-guardrails/
      SKILL.md

Chaque SKILL.md doit contenir du frontmatter incluant au minimum un name et une description. Le nom doit être en minuscules, séparé par des tirets, et identique au nom du dossier. Une compétence de contrôle peut indiquer aux agents des règles telles que :

- Do not publish raw prompts.
- Do not publish raw session logs.
- Do not use absolute local paths.
- Do not edit outside the approved product directory.
- Do not claim success without test output.
- Do not weaken tests to make validation pass.
- Do not commit, push, rebase, or force-push.
- Store review notes separately from production code.
- Treat screenshots as sensitive evidence.
- Stop for human approval after signoff.

Les règles semblent élémentaires, mais elles empêchent les erreurs réelles. Si elles se trouvent uniquement dans le AGENTS.md d’un répertoire, elles y restent. Une fois intégrées en tant que compétence, elles vous accompagnent partout.

Le mode sans interface rend les exécutions reproductibles

Le codage interactif convient à l’exploration. Le mode sans interface est plus adapté pour des exécutions reproductibles. Le paramètre builder ressemble à ceci :

opencode run \
  --model ollama/minimax-m3:cloud \
  --agent minimax-builder \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_CODER.md)"

Et le résultat de l’évaluation :

opencode run \
  --model ollama/glm-5.1:cloud \
  --agent glm-reviewer \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_REVIEWER.md)"

Pour les configurations plus lourdes avec des serveurs MCP, lancez un serveur OpenCode local une fois et reliez les exécutions ultérieures à celui-ci, afin d’éviter des démarrages répétés depuis zéro :

opencode serve --hostname 127.0.0.1 --port 4096

opencode run \
  --attach http://localhost:4096 \
  --agent minimax-builder \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_CODER.md)"

Attachez le serveur à 127.0.0.1. Toute personne qui le met à disposition d’un autre ordinateur doit définir OPENCODE_SERVER_PASSWORD et le faire fonctionner comme un véritable service de développement, car la documentation de la ligne de commande décrit l’authentification HTTP de base à l’aide de cette variable. Le modèle n’est pas devenu plus intelligent ; il est simplement plus difficile de le tromper.

Conserver les prompts et les résultats sans les divulguer

Il est utile de stocker localement les fichiers de prompts et les résultats des sessions afin de déboguer le comportement de l’agent. En revanche, il n’est pas conseillé de publier des prompts bruts ou des exportations brutes. Les journaux des agents peuvent contenir des chemins locaux, des prompts de shell, des noms de branches, des tâches internes en attente, des secrets liés à l’implémentation, des noms d’environnement, des chemins vers des captures d’écran, des identifiants égarés ainsi que des formulations de prompts que vous préféreriez réutiliser en privé.

La règle : stocker tout localement et ne publier que des résumés édité et des modèles réutilisables. L’outil opencode export [sessionID] d’OpenCode avec l’option --sanitize aide à la révision interne, mais il doit être considéré comme une première étape et non comme un bouton de publication. Tout ce qui est destiné au public doit faire l’objet d’une deuxième vérification d’édition.

Pour un dépôt public, committez ceci :

AGENTS.md
opencode.json
.opencode/agents/*.md
.opencode/skills/*/SKILL.md
templates/*.md
scripts/*.zsh
scripts/redact_sessions.py
docs/publication-redaction-checklist.md

et ignorer ces fichiers :

agent-sessions/**
screenshots/**
.env
project.local.env
*.raw.log
*.events.jsonl
opencode-session-*.json

Le résultat sont des rapports partageables sans que le répertoire ne devienne une source de fuites d’informations.

Où les outils MCP ont été utiles

Les modèles ne constituent qu’une partie du système, et l’interface des outils est extrêmement importante. Une façon utile de considérer les MCP et les outils intégrés, c’est comme des sens et des mains spécialisés :

| Workflow stage   | Useful tool or MCP category                             | What it helped with                                |
| ---------------- | ------------------------------------------------------- | -------------------------------------------------- |
| Planning         | repo search, docs lookup, issue/context reader          | understand current architecture before changing it |
| Coding           | filesystem, shell, language server, package manager     | edit code, inspect symbols, run targeted commands  |
| Review           | git diff, grep, test reports, generated artifact reader | catch scope creep and weak tests                   |
| Unit tests       | test runner, coverage                                   | prove the patch did not only compile               |
| Browser tests    | Playwright/browser automation                           | validate real UI routes and flows                  |
| Security tests   | secret scan, dependency audit, SAST                     | catch obvious unsafe output before publish         |
| Docs/site checks | static-site build, route checks, smoke tests            | catch generated-output drift                       |

La meilleure configuration MCP n’active pas tout. Elle fournit à l’agent uniquement les outils dont il a besoin et pousse ceux qui sont risqués à demander l’autorisation avant utilisation. OpenCode définit les serveurs MCP sous la clé mcp dans opencode.json et dispose de commandes en ligne de commande pour les gérer. Traitez ces définitions comme des dépendances de production : fixez-les, examinez-les et supprimez celles qui ne sont pas utilisées.

Pourquoi les captures d’écran ont leur place

Les tests navigateur renvoient un résultat de réussite ou d’échec. Les captures d’écran fournissent des preuves visuelles. Elles ont aidé les reviewers à détecter ce que les tests unitaires manquent : un affichage défectueux après une compilation réussie, du contenu incorrect sur une route, des pages générées vides, des régressions de navigation, un bandeau d’erreur non vérifié par aucun test, ainsi que la preuve qu’une route de site statique existe et s’affiche correctement.

Ils présentent également des risques : les noms des profils de navigateur, les onglets privés, les chemins localhost, les titres des problèmes, les tokens URL ainsi que les résultats des outils de développement peuvent tous finir dans le cadre. La politique consiste à ne prendre que des captures d’écran de l’interface localhost, à les recadrer soigneusement, à les examiner avant publication, et à ne jamais capturer les pages d’authentification, les tableaux de bord de production, les onglets privés ou les terminaux affichant des valeurs d’environnement. Une capture d’écran constitue une preuve et n’est pas considérée par défaut comme un artefact public.

Étude de cas sur un projet wiki privé

L’auteur a appliqué cette méthode à un wiki privé basé sur un LLM ainsi qu’à un projet de site statique, et n’a publié qu’un rapport ayant fait l’objet de nettoyage. Ses notes de validation finale indiquaient 977 tests Python réussis, une reconstruction du site statique avec mise à jour, des vérifications de type smoke-site et de validation de domaine, une génération des documents, des vérifications des routes ainsi que 150 tests Playwright réussis. Pour les fonctionnalités achevées et définies dans le cadre du projet, la confiance de l’auteur était élevée, d’environ 8 à 9 sur 10, soutenue par des tests reproductibles, des vérifications du site généré, des contrôles des routes et des validations via navigateur. Ce score est subjectif et ne devrait pas être généralisé au-delà de ce projet.

Le point faible ne résidait pas dans le code du produit. Un script d’automatisation headless a échoué en raison d’une mauvaise configuration des noms des agents. Il utilisait des noms génériques :

planner
coder
tester
reviewer

alors que les agents configurés étaient en réalité :

minimax-builder
glm-reviewer

Cette incohérence a contraint le système à recourir à un comportement incorrect, ce qui a empêché l’achèvement de la procédure de validation prévue impliquant plusieurs agents. Cette panne s’est avérée utile, car elle a mis en évidence l’importance des noms simples, d’une configuration exacte, des chemins relatifs et du contrôle du dossier de session. Le schéma corrigé est le suivant :

opencode run \
  --model ollama/minimax-m3:cloud \
  --agent minimax-builder \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_CODER.md)"

opencode run \
  --model ollama/glm-5.1:cloud \
  --agent glm-reviewer \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_REVIEWER.md)"

Cela signifie pas de chemins absolus, pas de noms d’agents inventés, et pas de fichiers de prompt cachés en dehors du périmètre de travail.

À quel point cela ressemble-t-il à un flux de travail Frontier ?

C’est ici qu’il est facile de faire de la publicité exagérée. Une configuration MiniMax plus GLM sur OpenCode et Ollama n’est pas identique à l’exécution directe du meilleur modèle de codage Frontier. Les modèles Frontier disposent toujours d’un raisonnement brut plus puissant, d’un meilleur comportement avec de longs contextes et d’une meilleure capacité à suivre les instructions par défaut ; par conséquent, comparer modèle par modèle ne serait pas équitable. La comparaison qui compte, c’est la qualité du flux de travail : planification, révision, tests, captures d’écran, vérifications de sécurité et approbation humaine.

Le flux de travail revêt une grande importance. Pour les tâches bien définies et soutenues par de bons tests, l’organisation peut ressembler fortement à celle des modèles Frontier, grâce à l’attribution de rôles distincts, à une planification préalable, à des revues de part et d’autre de la mise en œuvre, à des points de validation obligatoires, à une mémoire de session locale, à des captures d’écran en guise de preuves, à des contrôles de sécurité et à des commits contrôlés par un humain.

Il se rapproche des modèles Frontier pour le développement déterministe de fonctionnalités, la génération de sites statiques, les mécanismes de récupération et de recherche, les tâches nécessitant de nombreux tests, l’examen des résultats générés, la détection de l’élargissement du périmètre des tâches et l’obligation pour les intervenants de documenter les échecs. Cependant, les modèles Frontier restent supérieurs pour les décisions architecturales ambiguës, les refacteurs profonds sur du code mal testé, les jugements liés au style et au produit, la capacité d’autocorrection à long terme, le besoin de moins de tentatives, le respect automatique des instructions et l’analyse de captures d’écran complexes.

Modèle de menace

Plusieurs dangers courants liés à l’IA et à la programmation diminuent avec ce flux de travail : des affirmations de succès non étayées, des développeurs qui s’éloignent du répertoire prévu, des reviewers qui deviennent des implémentateurs, des prompts bruts atteignant des répertoires publics, des journaux exposant des chemins ou des secrets, des captures d’écran révélant des onglets privés ou des tokens, des modifications silencieuses de fichiers générés, ainsi que des agents qui commettent ou poussent des modifications avant que quiconque ne les ait vues.

La révision par des humains reste nécessaire. L’autonomie totale n’est pas l’objectif ; un cycle plus strict, où chaque affirmation est accompagnée de preuves et où chaque action risquée est limitée, l’est.

Avantages et inconvénients

Avantages

  • Reproductibilité. Les prompts génèrent des dossiers, les exécutions laissent des notes et les validations peuvent être retracées.
  • Gouvernance. Le développeur ne peut pas ignorer discrètement les tests si le reviewer doit bloquer la validation en l’absence de preuves.
  • Flexibilité des modèles. Vous pouvez changer de modèles au fur et à mesure que Ollama et OpenCode évoluent, et ce processus survit aux changements fréquents.
  • Vitesse. Une fois les prompts et les scripts prêts, exécuter la tâche suivante est rapide.

Inconvénients

  • Procédures plus complexes. C’est plus lourd qu’un simple prompt de chat, et c’est le prix à payer.
  • La mise en œuvre nécessite des paramètres de configuration. Demander à l’examinateur de ne pas modifier le code de production est moins efficace que de l’imposer via des permissions et des vérifications CI.
  • Des prompts de mauvaise qualité produisent toujours des résultats médiocres. La boucle réduit le chaos, mais ne remplace pas une définition claire des tâches.
  • Les permissions doivent être gérées avec soin. Les serveurs MCP et l’accès au shell sont puissants, il faut donc les traiter comme un accès en environnement de production.
  • Les journaux sont sensibles. Plus vos journaux sont détaillés, plus la censure doit être rigoureuse.

L’allégation qui tient la route

Cette configuration ne fera pas de MiniMax ou de GLM des modèles de pointe. Ce qu’elle permet, c’est de rendre le codage agentiel, moins coûteux et géré par Ollama, plus discipliné, auditable et utile pour des projets d’ingénierie bien définis. C’est la seule allégation qu’elle puisse honnêtement faire.