PTENES
MÓDULO 3.1

📕 AGENTS.md, .codex/ y agentes en TOML

La configuración de Codex pieza por pieza — AGENTS.md como gemelo de CLAUDE.md, config.toml, sub-agents en TOML y la invocación explícita que toma a muchos por sorpresa.

7
Temas
35
Minutos
Inter.
Nivel
Práctico
Tipo

🎯Lo que obtienes aquí

Mapeo directo de Claude → Codex para cada elemento de configuración. Aprende dónde se encuentra cada archivo, qué sintaxis usar (TOML vs JSON) y por qué están separados .codex/ × .agents/.

Contenido detallado

1

📜 AGENTS.md — el hermano de CLAUDE.md

Archivo Markdown en la raíz del proyecto que Codex lee al inicio de la sesión e inyecta en el prompt del sistema. Función idéntica al CLAUDE.md. Quien migra copia el CLAUDE.md, lo renombra a AGENTS.md y funciona en el 90% de los casos.

Mapeo directo

Claude Code
Codex
~/.claude/CLAUDE.md
~/.codex/AGENTS.md
./CLAUDE.md
./AGENTS.md
./src/api/CLAUDE.md
./src/api/AGENTS.md

⚠️El 10% que NO se porta

  • • Backtick-bang dentro del AGENTS.md → no se interpreta, se convierte en texto literal
  • • Descripciones demasiado largas pueden truncarse (límite oculto de ~8K caracteres)
  • • Referencias a tools exclusivas de Claude (Task, plan mode) → ignoradas
  • • Hooks/permisos inline no funcionan: pertenecen a config.toml

Conceptos clave

La misma función
Prompt del sistema del proyecto
La misma jerarquía
Global → proyecto → subdirectorio
Sin bang nativo
Se convierte en texto
Tamaño conserv.
~1-2KB
2

📂 Por qué DOS carpetas — .codex/ y .agents/

Codex hace una separación intencional: lo que es propietario (config de Codex, agents en TOML) queda en .codex/; lo que es spec abierta (Agent Skills) está en .agents/. Compatibilidad con otras tools que adoptan la spec.

🔧 .codex/ — propietario

.codex/
├── config.toml         ← settings (TOML)
├── agents/             ← sub-agents (TOML)
│   ├── reviewer.toml
│   └── doc-writer.toml
└── commands/           ← slash commands
    └── review.md

Cosas específicas de Codex. Ninguna otra herramienta entiende esto.

🌐 .agents/ — especificación abierta

.agents/
└── skills/             ← Agent Skills spec
    └── my-skill/
        ├── SKILL.md
        ├── agents/openai.yaml  ← sidecar
        ├── scripts/
        └── references/

Compartible. Otras tools (Cursor, etc.) que respeten la spec también pueden leerlo.

🚨El error de path más frecuente

Lees "skill de Codex" y, por reflejo, la pones en .codex/skills/. Incorrecto. La skill está en .agents/skills/ — siempre. .codex/ es solo configuración propietaria y sub-agents en TOML.

📊 Comparación completa

Elemento
Claude — dónde
Codex — dónde
Prompt del sistema
./CLAUDE.md
./AGENTS.md
Settings
.claude/settings.json
.codex/config.toml
Subagentes
.claude/agents/*.md
.codex/agents/*.toml
Skills
.claude/skills/<n>/
.agents/skills/<n>/
Comandos slash
.claude/commands/*.md
.codex/commands/*.md
Servidores MCP
.mcp.json
[mcp_servers] en toml

Conceptos clave

Config/ext separados
.codex × .agents
Especificación abierta
.agents = portable
TOML vs. JSON
Sintaxis diferente
Mirror global
~/.codex y ~/.agents
3

⚙️ config.toml — ajustes en TOML

Equivalente de settings.json de Claude, pero en TOML. No es más difícil: es DIFERENTE. Sintaxis de secciones con corchetes, arrays con corchetes dobles y varias líneas con comillas triples.

config.toml comentado

# modelo padrão
model = "gpt-5-codex"
approval_policy = "on-failure"   # quando pedir aprovação
sandbox_mode = "workspace-write" # nível de sandbox

# profiles — perfis nomeados
[profiles.safe]
sandbox_mode = "read-only"
approval_policy = "always"

[profiles.danger]
sandbox_mode = "danger-full-access"
approval_policy = "never"

# MCP servers
[mcp_servers.github]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]

[mcp_servers.github.env]
GITHUB_TOKEN = "${GITHUB_TOKEN}"

# model providers
[model_providers.openai]
base_url = "https://api.openai.com/v1"
api_key_env_var = "OPENAI_API_KEY"

Sintaxis TOML en 30 segundos

# comentário
chave = "string"
numero = 42
booleano = true
array = ["a", "b", "c"]

[secao]               # seção (= objeto)
chave = "valor"

[secao.sub]           # sub-seção
outra = "outra"

[[lista_de_secoes]]   # array de seções
nome = "item1"

[[lista_de_secoes]]
nome = "item2"

multiline = """
texto
em várias
linhas
"""

Conceptos clave

[section]
Equivalente a objeto
[[arrays]]
Array de secciones
"""multi"""
Cadena multilínea
${ENV}
Interpolación env
4

👤 Sub-agents en TOML — no es Markdown

Los subagentes en Codex son archivos .toml en .codex/agents/. Estructura, no prosa. Rellenas los campos de una struct: name, description, model, tools, e instructions (cadena multilínea con el system prompt).

Ejemplo — .codex/agents/code-reviewer.toml

name = "code-reviewer"
description = "Reviews code for correctness bugs. Call explicitly with 'use code-reviewer to ...'"
model = "gpt-5-codex"
tools = ["read", "grep", "glob", "bash"]

instructions = """
You are a senior code reviewer focused on correctness.

## Your role
- Read the diff carefully
- Flag correctness bugs (NOT style — linter handles that)
- Check edge cases (null, empty, off-by-one, race conditions)
- Note security risks (SQLi, XSS, path traversal, auth bypass)

## Output format
A numbered list of findings:
1. **[severity]** file:line — what's wrong, why, suggested fix

Be terse. No fluff.
"""

🔷 Agente de Claude Code

---
name: code-reviewer
description: Use proactively...
tools: Read, Grep, Bash
---

You are a senior code reviewer.
...

Markdown con frontmatter. La prosa fluye con naturalidad.

🟣 Agente de Codex

name = "code-reviewer"
description = "Call with 'use code...'"
tools = ["read", "grep", "bash"]
instructions = """
You are a senior code reviewer.
...
"""

TOML estructurado. Prompt dentro de una cadena.

💡Conversión práctica

Para portar un sub-agent de Claude a Codex: toma el frontmatter y conviértelo en claves TOML. Toma el body del markdown y ponlo en instructions = """...""". Ajusta la description para mencionar "call explicitly".

Conceptos clave

Estructura TOML
No es Markdown
instructions
Cadena multilínea
tools array
["read", "bash"]
model override
Por agente
5

🚦 Invocación explícita — la trampa de Claude → Codex

En Codex, sub-agents NO se activan automáticamente por la description. Tienes que invocarla por su nombre en el prompt. Es la diferencia que más desconcierta a quienes vienen de Claude.

🔷 Claude — auto

User: "revisa essa PR"

→ Claude lê descriptions
→ Match: code-reviewer
→ Dispara sub-agent
→ Devolve findings

No necesitas saber que existe el agent.

🟣 Codex — explícito

User: "revisa essa PR"

→ Codex faz revisão genérica
→ Sub-agent code-reviewer NÃO roda

User: "use code-reviewer para
        revisar a PR #123"

→ AGORA dispara o sub-agent.

Tienes que recordar el agent y llamarlo.

🚨Síntoma del error

"¿Por qué no se está llamando a mi agent? ¡Está exactamente igual que en Claude!"

→ Porque no lo llamaste. En Codex, description solo sirve para que RECUERDES que el agent existe, no para activarlo. Llámalo por su nombre.

Trade-off de diseño

Ventaja (Codex):

Previsibilidad. Siempre sabes qué se ejecutará. Sin sorpresas como "Claude decidió llamar a X y no me lo esperaba".

Desventaja (Codex):

Menos ergonómico. TIENES que acordarte de los agents. Si lo olvidas, el agent se convierte en «código muerto».

Conceptos clave

Invocación por nombre
"use agent X..."
Sin auto-dispatch
Por diseño
Previsibilidad
Trade-off
Description = recordatorio
Para ti, no para el LLM
6

🏖️ Sandbox y modos de aprobación

Codex tiene sandbox configurable vía config.toml. Tres niveles de poder creciente + approval policies que controlan cuándo pedir confirmación. Más granular y explícito que el equivalente de Claude.

🔒

solo lectura

Solo lectura. Bash funciona para ls, cat, grep. Sin escritura ni red. El modo ideal para analizar sin riesgos.

📝

workspace-write (predeterminado)

Escribe en el proyecto. No escribe fuera. Red limitada. Modo del día a día.

⚠️

danger-full-access

Sin restricciones. Escribe en cualquier lugar, red abierta, comandos cualesquiera. Solo en un sandbox real (container/VM).

Políticas de aprobación

"always" — pide confirmación en CADA comando
"on-failure" — solo pregunta si el primer intento falló (opción razonable por defecto)
"on-request" — pide solo si el modelo considera que hace falta
"never" — nunca lo solicita (combina con un sandbox restrictivo)

Conceptos clave

3 niveles de sandbox
read / write / full
Política de aprobación
Cuándo preguntar
Profiles
Preacordados
Network gating
Por sandbox
7

🔄 Slash commands en Codex

Codex admite slash commands personalizados en .codex/commands/ (archivos .md). Concepto idéntico al de Claude: algunas diferencias en la sintaxis de los argumentos y ausencia de backtick-bang.

Ejemplo — .codex/commands/review.md

---
description: Revisa o diff atual procurando bugs
---

Revise o diff atual da branch (rode git diff).

Procure:
- Bugs de correção
- Casos não tratados
- Vulnerabilidades comuns

Se passar argumento, foque nesse arquivo.

Retorne lista numerada de findings + severity.

Uso: /review o /review src/api/auth.ts

⚠️Sin backtick-bang

En Claude, podrías escribir Branch atual: `!git branch --show-current` dentro del command y el resultado se incluía en el prompt. En Codex, se convierte en texto literal. Solución: pide al agente que EJECUTE el comando (prosa de respaldo) o llama a un script.

Conceptos clave

.codex/commands/
La misma convención
Frontmatter
description mínima
Sin bang
Prosa de respaldo
Script delegado
Alternativa a la inyección

🎯Resumen del módulo

✓
AGENTS.md ≡ CLAUDE.md — misma función, misma jerarquía, solo sin backtick-bang.
✓
Dos carpetas: .codex/ propietaria, .agents/ especificación abierta — las skills SIEMPRE en .agents/.
✓
config.toml en TOML — [section], [[arrays]], """multiline""", ${ENV}.
✓
Subagentes = estructura TOML — cadena de instrucciones multiline, no cuerpo markdown.
✓
Invocación EXPLÍCITA de agent — "usa el agent X..." o no pasa nada.
✓
Sandbox con 3 niveles + 4 políticas de aprobación — granularidad explícita.
✓
Comandos slash sin backtick-bang — usar prosa de respaldo o un script.

Siguiente módulo:

3.2 — Skills en Codex y el sidecar openai.yaml (la peculiaridad que más confunde)