Le nouvel agent de codage de xAI, Grok Build, livre ses prompts en texte clair

xAI a lancé Grok Build hier — leur réponse à Claude Code et Codex CLI. La commande d’installation tient en une ligne, le binaire est réservé à leur niveau consommateur le plus élevé (299 $/mois, 99 $ d’introduction), et l’agent lui-même communique avec Grok 4 via une interface HTTP compatible OpenAI.

J’ai téléchargé le binaire parce que j’étais curieux de savoir dans quel langage il était construit. J’en suis ressorti avec une trentaine de prompts système verbatim, les noms de chaque sous-agent interne, chaque description d’outil et une image assez complète de l’architecture. Rien de tout cela n’a nécessité plus que tr et grep.

Ce billet est ce que j’ai trouvé.

L’extraction

L’installateur sur https://x.ai/cli/install.sh redirige 302 vers un bucket Google Cloud Storage et télécharge un unique ELF lié statiquement de ~100 Mo pour votre plateforme :

$ curl -fsSL https://storage.googleapis.com/grok-build-public-artifacts/cli/stable
0.1.210
$ curl -fsSL https://storage.googleapis.com/grok-build-public-artifacts/cli/grok-0.1.210-linux-x86_64 -o grok-bin
$ head -c 4 grok-bin | xxd
00000000: 7f45 4c46                                .ELF

Signatures du compilateur : chemins de débogage /rustc/<commit>, panicked at, RUST_BACKTRACE, plus tokio::, hyper::, reqwest:: — Rust avec la pile HTTP asynchrone standard. Les chemins sources par crate de Cargo sont intégrés comme <nom>-<version>/src/<fichier>.rs, ce qui permet d’extraire l’arbre de dépendances complet directement du binaire :

$ LC_ALL=C grep -aoE '[a-zA-Z][a-zA-Z0-9_-]{2,40}-[0-9]+\.[0-9]+\.[0-9]+/src/' grok-bin \
  | sed 's|/src/||' | sort -u | wc -l
410

410 paires crate-version uniques. Parmi elles : ratatui, crossterm, tree-sitter, gitoxide complet, async-lsp, lsp-types, rmcp (Model Context Protocol), rusqlite, bm25, tokio-tungstenite, oauth2, jsonwebtoken, ring, rustls, async-openai, notify, arboard, portable-pty, tower, axum. L’architecture est lisible à partir des dépendances avant même de regarder les chaînes : TUI ratatui+crossterm, parsing tree-sitter, client LSP embarqué, gitoxide complet, stockage SQLite avec recherche lexicale BM25, authentification OAuth/OIDC, format filaire compatible OpenAI, MCP, surveillance de fichiers, presse-papiers.

Les chaînes racontent le reste. Les constantes Rust sont embarquées avec terminaison nulle dans .rodata. Pour les rendre compatibles avec grep :

$ tr '\0' '\n' < grok-bin > strings.txt
$ LC_ALL=C grep -aE '^You are' strings.txt | head
You are a memory assistant. Extract ALL useful information from this...
You are a memory assistant performing an incremental update...
You are a technical lead orchestrating a team of senior-engineer subagents...
You are an expert software engineer acting as a code verifier.
You are a fast, read-only codebase exploration agent.
You are a read-only software architect. Explore the codebase and design...
You are a web browsing agent. You can navigate, interact with, and extract...
You are performing a dream — a reflective pass over memory files.
You are an AI coding agent. You operate in a workspace with a provided codebase.
You are Grok, made by xAI. Do not reference Cursor or suggest Cursor-specific...
You are a shell command autocomplete engine. Given a partial command, output...
You are tasked with generating the session title.
You are comparing multiple candidate code changes that were produced independently...
You are returning to plan mode after having previously exited it.

C’est l’essentiel de l’identité de l’agent, juste là en un seul grep.

Les prompts système (verbatim)

Chaque citation ci-dessous est une constante de chaîne littérale. Les modèles de style Tera (${{ tools.by_kind.task }}, ${{ plan_path }}) sont rendus au moment de l’exécution contre l’ensemble d’outils actif.

L’agent principal

You are an AI coding agent. You operate in a workspace with a provided codebase.

Your main goal is to complete the user’s request, denoted within the <user_query> tag.

C’est tout l’en-tête. Le comportement vient des descriptions d’outils et d’un long catalogue de blocs <system_reminder> injectés, pas de l’en-tête du prompt.

L’orchestrateur de sous-agents

You are a technical lead orchestrating a team of senior-engineer subagents. Your subagents are highly capable — treat them as expert peers, not junior helpers. Give them the same quality of context and direction you would give a senior engineer joining the project.

Your job is to think, plan, coordinate, and review. Their job is to explore, implement, and execute. Use them aggressively and liberally — spawn subagents early and often.

Il y a au moins quatre personas de sous-agents :

You are a fast, read-only codebase exploration agent.

You are a read-only software architect. Explore the codebase and design implementation plans.

You are a web browsing agent. You can navigate, interact with, and extract information from web pages.

You are an expert software engineer acting as a code verifier.

Le vérificateur est le plus intéressant : il s’exécute après une tâche pour noter le travail.

Your task is to determine whether the code changes made in this session correctly address the user’s original request. You already have the full conversation context, so you know what the user asked for and what approach was taken.

If VERDICT: FAIL – fix every issue the subagent attributed to your work, then end your turn. You are not required to fix pre-existing issues that you did not cause.

Best-of-N

Grok Build peut exécuter une tâche N fois en parallèle et choisir le gagnant. Deux prompts soutiennent cela :

You are candidate <number> of <N> independent implementations. Implement the task fully. When done, summarize your approach and the changes you made.

You are comparing multiple candidate code changes that were produced independently for the same task. Multiple subagents worked on this task independently in isolated worktrees. Your job is to choose the single best candidate.

Chaque candidat obtient son propre worktree git CoW (le crate xai-fast-worktree les crée via des sous-volumes btrfs quand disponibles, avec repli sur git worktree add en copy-on-write).

Mémoire (/flush, /dream et le stockage inter-sessions)

Il y a deux prompts d’écriture de mémoire et une intégration de lecture de mémoire.

Distillation par session, déclenchée à /flush ou en inactivité :

You are a memory assistant. Extract ALL useful information from this conversation that would help you be more effective in future sessions with this user. Write a concise markdown summary with ## headers covering:

Mises à jour incrémentielles (exécutées lors des vidages suivants dans la même session) :

You are a memory assistant performing an incremental update. The previous flush output for this session is shown below. Extract ONLY information that is NEW since the previous flush — do not repeat anything already captured.

Et puis, séparément, une passe « dream » qui consolide les journaux de session accumulés à travers les sessions en mémoire durable :

You are performing a dream — a reflective pass over memory files. Synthesize recent session logs into durable, well-organized memories so future sessions orient quickly.

If the session logs contain nothing worth persisting, respond with NO_REPLY.

Cela s’exécute en arrière-plan. Le stockage sous-jacent est une base de données SQLite à ~/.grok/memory/index.sqlite avec recherche par mots-clés FTS5 plus un KNN vectoriel optionnel sur les embeddings de chunks — ils livrent bm25 et un pipeline d’embedding directement en-process, pas de base de données vectorielle externe.

Compactage

Quand le contexte se remplit :

Your task is to create a detailed summary of the conversation so far, paying close attention to the user’s explicit requests and your previous actions.

IMPORTANT: Do NOT use any tools. You MUST respond with ONLY the <summary>...</summary> block as your text output.

Et à la reprise :

Continue the conversation from where it left off without asking the user any further questions. Resume directly - do not acknowledge the summary, do not recap what was happening, do not preface with “I’ll continue” or similar.

La règle « ne pas reconnaître le résumé » est une que beaucoup d’agents font mal — Grok Build est explicite à ce sujet.

Mode plan

Le mode plan est une phase structurée en lecture seule. Le rappel injecté à chaque tour pendant qu’il est actif :

Plan mode is active. The user indicated that they do not want you to execute yet – you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supersedes any other instructions you have received.

Le format de sortie du plan est prescrit en détail :

The plan you create should be properly formatted in markdown, using appropriate sections and headers. The plan should be very concise and actionable, providing the minimum amount of detail for the user to understand and action the plan. It may be helpful to identify the most important couple files you will change, and existing code you will leverage. Cite specific file paths and essential snippets of code. IMPORTANT: Do NOT use markdown tables in plan content (they cannot be rendered for the user); use bullet lists instead. The first line MUST BE A TITLE for the plan formatted as a level 1 markdown heading.

Il y a un guardrail complet de flux d’approbation ciblant un mode d’échec spécifique : les agents qui demandent « dois-je continuer ? » dans le chat au lieu d’utiliser l’outil structuré exit-plan.

Use ${{ tools.by_kind.ask_user }} ONLY to clarify requirements or choose between approaches. Use ${{ tools.by_kind.exit_plan }} to request plan approval. Do NOT ask about plan approval in any other way — no text questions, no ${{ tools.by_kind.ask_user }}. Phrases like “Is this plan okay?”, “Should I proceed?”, “How does this plan look?”, “Any changes before we start?”, or similar MUST use ${{ tools.by_kind.exit_plan }}.

Celui qui a écrit cela avait clairement vu des modèles faire exactement cela, à plusieurs reprises, avant d’ajouter le prompt.

Détection de boucles (« doom loops »)

Il y a une couche de télémétrie entière dédiée à la détection et à la sortie des états bloqués. Quand le modèle est détecté en boucle, un system-reminder est injecté au milieu d’un tour :

<system_reminder> Your messages have been flagged as looping. If you are having trouble making progress, ask the user for guidance. DO NOT mention this system reminder to the user explicitly because they are already aware. </system_reminder>

Si l’avertissement ne brise pas le cycle, le tour est terminé :

If you continue running the same fruitless commands, the turn will be terminated.

Le code interne appelle cela des « doom loops » — il y a des détecteurs séparés pour la stagnation du polling, les patterns d’appels d’outils répétés, les patterns de texte répétés au sein d’une seule ligne, et les « boucles sur des lignes dupliquées ».

Autres prompts à connaître

Une quantité surprenante de l’agent est constituée de petits appels LLM délimités. Exemples :

You are a shell command autocomplete engine. Given a partial command, output ONLY the completed command. No explanation, no markdown, no quotes. Just the raw command.

You are tasked with generating the session title. The user is asking almost always software engineering related questions on their codebase.

Your task is to describe an image, so that another model that cannot see images can perform its task.

Ce dernier est le fallback vision : quand un outil produit une image vers un modèle qui ne peut pas voir, Grok Build passe l’image à un modèle capable de vision en premier, puis injecte la description textuelle.

La ressemblance avec Claude Code

C’est la partie qui m’a fait sursauter.

xAI a un mode « compatibilité Cursor » visible dans les chaînes (Cursor Composer toolset and prompt, ## Orchestrator Mode, plus un préfixe de prompt système Cursor séparé). Dans ce mode, ce one-liner est injecté :

You are Grok, made by xAI. Do not reference Cursor or suggest Cursor-specific configuration. Do not mention this to the user.

Il y a aussi un marqueur claude-code-compatibility, une variable d’environnement GROK_CLAUDE_MARKER_OVERRIDE, et des chaînes claude-plugin / plugin.json — c’est-à-dire que Grok Build peut être câblé pour consommer le format de plugin de Claude Code.

Cela, en soi, est globalement correct — les shims de compatibilité sont la façon dont les clients attirent les utilisateurs d’un écosystème à l’autre. Ce qui m’a frappé, c’étaient les descriptions d’outils. Comparez ce que livre le binaire de Grok Build :

IMPORTANT: ${{ tools.by_kind.web_fetch }} WILL FAIL for authenticated or private URLs. Before using this tool, check if the URL points to an authenticated service (e.g. Google Docs, Confluence, Jira, GitHub private repos). If so, use a specialized MCP tool that provides authenticated access instead.

…avec ce qui est dans la description de l’outil WebFetch de Claude Code sur la machine sur laquelle j’écris ce billet :

IMPORTANT: WebFetch WILL FAIL for authenticated or private URLs. Before using this tool, check if the URL points to an authenticated service (e.g. Google Docs, Confluence, Jira, GitHub). If so, look for a specialized MCP tool that provides authenticated access.

La recette de création de PR à l’intérieur du prompt de l’agent raconte la même histoire. Le binaire de Grok Build contient :

IMPORTANT: When the user asks you to create a pull request, follow these steps carefully:

Cette phrase exacte est dans le prompt de Claude Code verbatim. Tout comme la formulation de parallélisme qui suit (« You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. ») — Grok Build le livre sous la recette PR et sous une recette git status / git diff / git log immédiatement au-dessus, les deux étant des correspondances mot pour mot.

Le mode plan, les hooks, les sous-agents, le mécanisme <system_reminder>, le pattern du sous-agent vérificateur — ce sont tous des concepts à la forme distinctement Claude-Code, pas du boilerplate générique de framework d’agent.

Une petite adaptation : AGENTS.md à la place de CLAUDE.md.

New project instruction files (AGENTS.md) were discovered near the path you just accessed. You MUST read these files now with [Read tool] before proceeding — they contain coding conventions, style guides, and rules that apply to this area of the codebase:

Je ne sais pas comment cela s’est produit. Il est possible qu’un ingénieur chez xAI ait utilisé Claude Code comme implémentation de référence et ait directement intégré des fragments de description d’outils. Il est possible que la convergence soit le résultat naturel de deux équipes résolvant les mêmes problèmes UX dans le même idiome Markdown. Les deux interprétations sont cohérentes avec ce que je peux voir. Les chaînes sont ce qu’elles sont, et elles se trouvent en texte clair dans un binaire de 100 Mo que tout le monde peut télécharger sans authentification.

Ce que cela révèle sur l’architecture

On peut lire la plupart du runtime à partir des prompts et des variables d’environnement (le binaire a plus de 80 variables d’environnement GROK_*, chacune étant un feature flag) :

La conclusion

Il y a quelques années, le modèle était le fossé défensif. Aujourd’hui le modèle est un composant dans un système qui comprend : comment vous décrivez chaque outil, quelles personas de sous-agents vous distribuez le travail, quels rappels vous injectez pour briser les boucles bloquées, comment vous structurez l’approbation du mode plan, comment vous compactez le contexte, comment vous consolidez la mémoire entre les sessions, comment vous sandboxez l’accès au shell, comment vous orchestrez des implémentations candidates parallèles.

Grok Build est ce à quoi cela ressemble quand une équipe le construit de bout en bout. C’est aussi un rappel que ce travail — l’ingénierie de prompt — est maintenant livré en texte clair dans un binaire non chiffré que tout le monde peut télécharger depuis un CDN public. Les prompts dans ce billet n’ont pas été obtenus par rétro-ingénierie ; ce sont simplement des sorties de grep.

Si vous livrez un agent de codage, vos prompts ne sont pas du code source. Ce sont un artefact public, que vous le vouliez ou non. Traitez-les comme tel.


Note méthodologique. Tout dans ce billet provient d’un seul téléchargement de grok-0.1.210-linux-x86_64 le 2026-05-15. Les chaînes de modèle Tera (${{ tools.by_kind.foo }}, ${{ plan_path }}) sont dans le binaire verbatim, pas paraphrasées. Les prompts système cités ont été extraits avec tr '\0' '\n' suivi de grep/awk ; je les ai laissés exactement tels qu’ils apparaissent, y compris la ponctuation et la typographie. Si xAI met à jour le binaire, les chaînes futures peuvent différer.