LLevo unas semanas investigando cómo empezar a automatizar diferentes tareas que solemos necesitar durante el desarrollo software, y se me ocurrió empezar por algo pequeño y muy concreto en un repositorio propio, que ví hace unos meses en la charla de Gisela Torres en la Convex. La idea es que las issues que abro en español, se traduzcan automáticamente al inglés. Es la clase de tarea que uno automatizaría con un webhook y cuatro líneas de código pegamento, hasta que te das cuenta de que «detecta el idioma, traduce con criterio y publica un comentario ordenado» no es exactamente una regla fija, sino que necesita cierta capacidad reflexiva. Sabía que hacía unas semanas había salido GitHub Agentic Workflows en public preview, así que me parecía un buena prueba para entender cómo se llevan agentes SDLC a producción de verdad.

Lo cuento aquí tal cual lo fui aprendiendo: qué son, qué me chirriaba al principio, y una demo que monté con mi propia key, que funcionó, aunque no por donde la documentación oficial te lleva de la mano.

Qué son los Agentic Workflows

Un Agentic Workflow es, en una frase, automatización descrita en Markdown y lenguaje natural que un agente interpreta y ejecuta dentro de GitHub Actions. En lugar de escribir YAML condicional y rígido, describes el objetivo de la automatización en prosa, y un coding agent lo lleva a cabo leyendo el contexto del repo y decidiendo sobre la marcha en vez de seguir un árbol de if fijo.

El fichero es un .md con dos partes: un frontmatter YAML con la configuración (cuándo se dispara, a qué tiene acceso, qué herramientas puede usar) y un cuerpo Markdown con las instrucciones para el agente. Ese .md es la fuente de verdad editable; un compilador lo transforma en un .lock.yml, que es un workflow tradicional de GitHub Actions, endurecido y listo para ejecutar. Los dos ficheros viven en .github/workflows/ y los dos se commitean. Me gusta el encuadre que usa la propia documentación: escribes algo legible por humanos y lo compilas a algo que ejecuta la máquina, igual que con el código.

Los casos de uso que se repiten en la documentación son los previsibles y, a la vez, los que más duelen cuando se hacen a mano: triaje de issues, revisión de pull requests, análisis de fallos de CI, gestión de releases y mantenimiento del repositorio. No sustituyen a tu CI/CD determinista; mas bien conviven con él. De hecho, la documentación los describe como «100% aditivos», una capa de Continuous AI junto al pipeline de siempre.

Es imporante remarcar que, como decía al principio, esto está en public preview desde el 11 de junio de 2026, en línea de versiones 0.x y con varias releases al día (cuando escribo esto, la última es la v0.86.1, del 7 de agosto). Me da la impresión de que los conceptos ya están bastante asentados, pero los nombres concretos de flags, campos y versiones que cite aquí caducan rápido.

Por qué el modelo no basta sin el ecosistema

Aquí está la parte que a mí me reordenó la cabeza. Si ya has jugado con LLMs, la tentación es pensar que un agente es «un modelo bueno con acceso a mi repo». Y no. El modelo es la pieza más visible, pero es la que menos trabajo hace para que esto sea utilizable en producción. De hecho, la documentación de gh-aw describe al agente que interpreta y ejecuta las instrucciones como algo distinto del modelo. El LLM genera texto, pero quien actúa (quien decide qué herramienta invocar y la llama) es la capa que lo envuelve. Y esa infraestructura son, más o menos, cuatro capas.

La primera es el engine (el término que usa el producto para el runtime del agente), un coding agent que corre dentro de Actions, interpreta tu prompt y decide qué herramientas invocar. En la industria a esta capa se la llama a menudo harness. Anthropic, por ejemplo, describe su Agent SDK como «el harness que impulsa Claude Code», la capa que aporta el bucle de herramientas, la gestión de contexto y la compactación para que un agente trabaje una tarea larga sin agotar la ventana. Llámalo engine o harness, es lo que convierte un modelo stateless en un agente que persigue un objetivo.

La segunda son las herramientas, o sea, las manos. Un modelo no lee un fichero ni llama a la API de GitHub por su cuenta; necesita que se lo den. El estándar para conectarlas es MCP (Model Context Protocol), que su propia especificación resume como «un puerto USB-C para aplicaciones de IA», un protocolo abierto cliente-servidor para enchufar datos y herramientas al agente.

La tercera son las reglas de la casa, es decir, permisos y safe-outputs. Por diseño, estos workflows corren con permisos de solo lectura por defecto, y las escrituras no las hace el agente directamente. Las operaciones que modifican estado (abrir una issue, comentar, proponer un PR) pasan por safe-outputs, acciones preaprobadas que el agente solicita y que una capa determinista valida y aplica. El agente propone; otra cosa dispone. Es exactamente lo que hace sensato darle a un agente acceso a un repositorio real, y no un LLM «a pelo».

La cuarta es la orquestación, esto es, quién dispara al agente, cómo se compila a un pipeline reproducible y cómo se encadenan sus salidas. En gh-aw eso es el evento que lo activa más la compilación a Actions.

Y aquí es donde todo esto conecta con lo que vengo a contar. Si te fijas más abajo en qué capa vive el modelo, verás que es en una sola línea del frontmatter. El prompt en Markdown (el activo de verdad, lo que codifica qué quieres) no cambia si mañana cambias de engine o de modelo. Cambias una línea de configuración y el mismo workflow corre sobre otro cerebro.

El prompt es tuyo; el modelo es un detalle de configuración.

BYOK y no te casas con nadie

Ese desacople tiene un nombre práctico, BYOK, Bring Your Own Key. gh-aw admite cinco engines integrados, copilot (el de por defecto), claude, codex, gemini y pi (experimental), y cada uno se autentica con su propia credencial. Que cada engine use su propia API key es, de hecho, el patrón «trae tu propia clave», eliges proveedor y pones tu secret. gh-aw es software libre y gratuito; solo pagas la inferencia de tu proveedor más los minutos de Actions del run, y los minutos de Actions son gratis en repositorios públicos. Si no usas el engine de Copilot, no necesitas plan de Copilot.

Para mi demo quería dos cosas: no atarme a Copilot, y quedarme dentro del ecosistema Microsoft usando un modelo de Azure AI Foundry. La ruta que elegí es el engine codex, que solo exige OPENAI_API_KEY (ni plan de Copilot ni COPILOT_GITHUB_TOKEN) y admite apuntar a cualquier endpoint OpenAI-compatible fijando OPENAI_BASE_URL en engine.env. Foundry expone justamente endpoints OpenAI-compatible (.../openai/v1), así que sobre el papel la pieza encaja.

Es verdad que existe una ruta BYOK más «de primera clase» para Foundry, el modo BYOK del engine copilot (COPILOT_PROVIDER_BASE_URL, COPILOT_PROVIDER_TYPE: azure), que sí está documentado con una guía dedicada y smoke tests para Azure OpenAI. Pero usar el engine de Copilot para demostrar que no dependo de Copilot es un poco raro, y si esa ruta sigue exigiendo credenciales de Copilot es, ahora mismo, el punto menos claro y sin resolver de todo lo que investigué. En cambio, la vía codex + OPENAI_BASE_URL → Foundry no está documentada por GitHub. No hay guía ni smoke test que la dé por buena. Es mecánicamente plausible, pero no encontré un ejemplo claro que funcione. Así que la única forma de apoyarme en ella era crear una demo para ver si la idea funciona.

La demo, traducir issues ES→EN con tu modelo de Foundry

El workflow entero es lo que ves a continuación. El frontmatter dice cuándo se dispara, qué engine usa y a dónde manda la inferencia; el cuerpo Markdown es la instrucción:

---
description: "Traduce issues de español a inglés al abrirse"
on:
  issues:
    types: [opened]
permissions:
  contents: read
  issues: read
model: gpt-5.4-mini
engine:
  id: codex
  env:
    OPENAI_BASE_URL: https://<tu-recurso>.openai.azure.com/openai/v1
    OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
network:
  allowed:
    - defaults
    - <tu-recurso>.openai.azure.com
safe-outputs:
  add-comment:
    max: 1
---
 
# Traducir issue a inglés
 
Lee el título y el cuerpo de la issue que ha disparado este workflow.
Si están en español, tradúcelos a un inglés natural y técnico.
Publica un solo comentario con la traducción; no hagas nada más.

Fíjate en lo poco que hay ahí de «inteligencia artificial» y lo mucho que hay de las cuatro capas de antes: el disparador (on: issues) es la orquestación; OPENAI_BASE_URL es el BYOK; network.allowed es la regla de la casa que deja salir el tráfico solo hacia tu dominio de Foundry; safe-outputs: add-comment es la única escritura que el agente tiene permitido pedir. El único guiño al modelo es la línea model:.

Para probarlo sin ensuciar el repo real usé gh aw trial, que ejecuta el workflow en un repositorio privado temporal y aislado, sin abrir issues ni comentarios de verdad. Y funcionó end-to-end. Con gh aw v0.85.4, el agente llamó a gpt-5.4-mini en Foundry a través del proxy interno y devolvió el comentario traducido, correcto. Así que la duda central (¿reenvía el proxy mi Authorization: Bearer intacto hasta Azure y cuadra el nombre del deployment con el modelo?) quedó resuelta de primera mano. El engine codex no pidió Copilot en ningún momento (ni tampoco ninguna cuenta de OpenAI), solo mi OPENAI_API_KEY que, en este caso, era la clave del modelo desplegado de Azure Foundry.

Me encontré tres problemillas durante el proceso, ninguno relacionado con Foundry:

  • El secreto no se inyecta solo. gh aw trial no propaga tu OPENAI_API_KEY local; hay que darlo de alta en el repo anfitrión, o el job de activación falla validando el secreto:

    gh secret set OPENAI_API_KEY --body $env:MI_FOUNDRY_KEY --repo <owner>/<repo>
  • --logical-repo <otro-repo> rompe el checkout. El token del repo temporal no puede clonar un repo ajeno y salta un Not Found; para probar en aislamiento, se corre dentro del propio repo anfitrión.

  • Faltaba contents: read. Con solo issues: read, el checkout del propio repo da repository not found. Hay que declararlo en permissions.

Ninguna es «el modelo no traduce bien». Todas son de las capas de fuera (secretos, permisos, orquestación), que es justo donde vive la dificultad real de llevar un agente a producción.

Cierre

Empecé queriendo traducir issues y terminé con una convicción que va más allá de la tarea. Llevar agentes a producción se parece poco a elegir el mejor modelo y mucho a resolver las capas que lo rodean (el engine que lo convierte en agente, los permisos que lo hacen seguro, la orquestación que lo dispara). El modelo es intercambiable casi por definición; lo que construyes con cuidado es todo lo demás.

Y ese es, creo, el mejor motivo para no casarte con nadie (técnicamente hablando jeje). Si el prompt es el activo y el modelo cabe en una línea de configuración, entonces cambiar de proveedor deja de ser una migración y pasa a ser un experimento que puedes hacer en una tarde. La libertad de traer tu propia key no es solo una cuestión de facturación. Es lo que te permite mantener tu workflow vivo y útil, aunque el proveedor de inferencia cambie, o aunque el modelo que hoy es el mejor mañana quede obsoleto.