Analyse du fonctionnement interne d’OpenAI Codex CLI : boucle d’agent et stratégie de mise en cache des prompts
(openai.com)Résumé :
- Structure de la boucle d’agent (Agent Loop) : explication détaillée du processus cyclique par lequel Codex CLI orchestre l’entrée utilisateur, l’inférence du modèle et l’exécution d’outils pour réaliser des tâches concrètes.
- Construction des prompts et Responses API : analyse du processus par lequel les instructions système, les définitions d’outils et le contexte de l’environnement local sont convertis en payload JSON pour la
Responses API, ainsi que du flux de données associé. - Optimisation des performances et gestion de l’état : présentation des stratégies visant à maximiser la mise en cache des prompts (Prompt Caching), des techniques de compaction des conversations pour dépasser les limites de fenêtre de contexte, ainsi que des principes de conception sans état (Stateless) pour le ZDR (Zero Data Retention).
Résumé détaillé :
L’équipe d’ingénierie d’OpenAI a publié un article technique analysant en profondeur le fonctionnement de la « boucle d’agent » (Agent Loop), la logique centrale de Codex CLI, un agent logiciel local. L’article décrit, sous un angle technique, tout le cycle de vie : réception d’une commande utilisateur, interaction avec le modèle, exécution d’outils et retour du résultat.
1. La boucle d’agent (The Agent Loop)
La boucle d’agent est une structure cyclique qui reçoit l’entrée utilisateur et interagit avec le modèle jusqu’à l’achèvement de la tâche.
- Processus : entrée utilisateur -> génération du prompt -> inférence du modèle (Inference) -> (demande d’appel d’outil -> exécution de l’outil -> ajout du résultat -> nouvelle inférence) répétition -> réponse finale.
- Tour (Turn) : on appelle « tour » l’ensemble du processus allant de l’entrée utilisateur jusqu’au moment où le modèle envoie finalement un message à l’utilisateur (Assistant Message). Durant ce processus, l’agent peut effectuer des centaines d’appels d’outils, par exemple l’exécution de
lsou la modification de fichiers.
2. Inférence du modèle et Responses API
Codex CLI communique avec le modèle via la Responses API. Cette API peut être configurée avec https://chatgpt.com/backend-api/codex/responses, https://api.openai.com/v1/responses ou un hôte local, comme Ollama.
Construction du prompt initial (Building the Initial Prompt)
Le prompt n’est pas un simple texte, mais un ensemble de données structurées composé de instructions, tools, input, etc.
- Instructions : messages système ou développeur qui définissent les consignes de comportement du modèle. (Par exemple, référence au fichier de configuration
~/.codex/config.toml.) - Tools : liste des définitions d’outils utilisables par le modèle. Cela inclut l’exécution de shell, la mise à jour de plan (
update_plan), la recherche web, ainsi que des outils de serveur MCP (Model Context Protocol) personnalisés. - Input : liste des données effectivement transmises au modèle. Elle comprend les réglages de permissions du sandbox, les instructions propres au projet, ainsi que le contexte d’environnement (Environment Context), comme le répertoire de travail courant (
cwd) et le type de shell.
Exemple de payload JSON :
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Ajoute un diagramme d’architecture dans README.md"
}
]
// ... le contexte d’environnement et les réglages de permissions définis précédemment sont également envoyés
}
3. Exécution des outils et flux de données
Quand le modèle demande un appel d’outil (Function Call), l’agent l’exécute, ajoute le résultat à l’historique de conversation, puis rappelle le modèle.
Exemple de JSON de nouvelle requête après exécution d’un outil :
[
/* ... éléments d’entrée précédents ... */
{
"type": "reasoning", // processus de raisonnement du modèle (CoT)
"summary": [...],
"encrypted_content": "gAAAAABpaDW..." // contenu de raisonnement chiffré
},
{
"type": "function_call",
"name": "shell",
"arguments": "{\"command\":\"cat README.md\",\"workdir\":\"/Users/mbolin/code/codex5\"}",
"call_id": "call_8675309..."
},
{
"type": "function_call_output", // résultat de l’exécution de l’outil
"call_id": "call_8675309...",
"output": "<p align=\"center\"><code>npm i -g @openai/codex</code>..."
}
]
Il est important de construire la requête de façon à ce que le prompt précédent soit un préfixe exact (Prefix) du nouveau prompt. C’est ce qui détermine l’efficacité de la mise en cache des prompts décrite plus loin.
4. Considérations de performance : cache et ZDR
À mesure que la conversation s’allonge, la taille du prompt augmente linéairement, ce qui accroît les coûts et la latence.
-
Mise en cache des prompts (Prompt Caching) : les modèles d’OpenAI réutilisent des résultats de calcul antérieurs lorsque le début du prompt correspond (Prefix Match), ce qui accélère le traitement.
-
Éviter les cache miss : si la liste d’outils ou les réglages du sandbox changent au milieu d’une conversation, le cache peut être invalidé. Pour l’éviter, Codex traite les changements de configuration non pas en modifiant les messages existants, mais en ajoutant de nouveaux messages (Append).
-
Sans état (Stateless) et ZDR : des paramètres comme
previous_response_idne sont pas utilisés ; l’intégralité du contexte est renvoyée à chaque fois. Cela permet de respecter la politique de Zero Data Retention (ZDR), qui évite le stockage de données côté serveur. Grâce au fait que le client reçoit puis renvoie le contenu de raisonnement chiffré (encrypted_content) au serveur, celui-ci peut restaurer le contexte de raisonnement précédent sans conserver d’état.
5. Gestion de la fenêtre de contexte (Compaction)
Pour ne pas dépasser la limite de tokens, Codex utilise l’endpoint /responses/compact pour compresser l’historique de conversation. Il ne s’agit pas d’un simple résumé : l’endpoint renvoie une liste compacte d’éléments incluant encrypted_content, ce qui permet de préserver la compréhension latente du modèle et de remplacer les entrées existantes.
Aucun commentaire pour le moment.