<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Khavel</title>
    <description>The latest articles on DEV Community by Khavel (@khavel).</description>
    <link>https://dev.to/khavel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F908485%2F809342dc-ba24-482e-a5b9-6ab3dbd61290.png</url>
      <title>DEV Community: Khavel</title>
      <link>https://dev.to/khavel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/khavel"/>
    <language>en</language>
    <item>
      <title>Backtest 63.7%, production AUC 0.51 - a postmortem</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Sat, 05 Sep 2026 23:07:00 +0000</pubDate>
      <link>https://dev.to/khavel/backtest-637-production-auc-051-a-postmortem-2alc</link>
      <guid>https://dev.to/khavel/backtest-637-production-auc-051-a-postmortem-2alc</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://nbaproplab.com/learn/model-postmortem" rel="noopener noreferrer"&gt;nbaproplab.com/learn/model-postmortem&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A model that looks excellent offline and random in production is usually blamed on the serving code. Ours was not: the two computations matched to 2e-16. The cause was a calibration snapshot whose export query nobody wrote down.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built
&lt;/h2&gt;

&lt;p&gt;We score NBA and WNBA player props through seven independent blocks: player form, matchup, game context, market line, teammate synergy, analysis quality and external signals. Each returns a 0-100 score with a confidence index, and a confidence-weighted mean produces the final score that decides whether a pick is published.&lt;/p&gt;

&lt;p&gt;On top of that engine we fitted a logistic meta-learner. It takes the seven block scores plus the pick direction and outputs a single calibrated probability that the pick hits. The idea was sound: a weighted mean treats every block as positively predictive, while signed coefficients let an anti-predictive block subtract instead.&lt;/p&gt;

&lt;p&gt;Offline it looked excellent. The top tier came out at a 63.7% hit rate with an AUC of 0.56. We deployed it in shadow mode, writing its probability next to every saved pick without letting it influence anything, and planned the switch for the following release.&lt;/p&gt;

&lt;h2&gt;
  
  
  What went wrong
&lt;/h2&gt;

&lt;p&gt;The switch never happened, because the backtest never reproduced.&lt;/p&gt;

&lt;p&gt;Measured against clean live-only data, the deployed model scored an AUC of about 0.51. That is a coin flip. Worse than the flat result, the ordering was inverted: the band the model was most confident about hit 53%, while the band immediately below it hit 67.6%. A model whose top tier underperforms its second tier is not a weak model, it is a broken one.&lt;/p&gt;

&lt;p&gt;The obvious suspect is the serving path, so we checked it first. We recomputed the probability for saved picks using the production code and compared it against the training-time computation. The difference was 2e-16, which is floating point noise. The code was correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual cause: a CSV nobody documented
&lt;/h2&gt;

&lt;p&gt;The training set had been exported once, into a file, from a database snapshot. The export query was never recorded. Neither was the date window, which turned out to be a narrow slice of spring. Nobody wrote down how the file had been produced, so nobody could check whether it matched what production actually served.&lt;/p&gt;

&lt;p&gt;It did not match. The training population and the serving population were different, which is the textbook train-serve mismatch. What made it survive review for weeks was not the mismatch itself but its invisibility: with no provenance recorded, there was nothing to compare against, and the impressive offline numbers had no way of being challenged.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we changed
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The model is parked.&lt;/strong&gt; It is still computed and stored next to every pick, and it still drives nothing user-facing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provenance is mandatory.&lt;/strong&gt; Any dataset that informs a decision carries its exact query, its date window and its reason in the changelog, in the same commit that uses it. If it is not written down, it did not happen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The replacement only graduates on forward data.&lt;/strong&gt; A gradient boosting combiner runs as a frozen forward shadow, writing predictions to its own table. It replaces the live engine only if its volume-matched top tier stays ahead over several hundred forward-settled picks. No backtest can promote it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calibration is monitored daily.&lt;/strong&gt; Brier score, log loss, AUC and per-tier hit rates over a trailing window, with the window floored at the model finalize date so training data cannot leak into the metric that is supposed to police it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The numbers that replaced it
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Population&lt;/th&gt;
&lt;th&gt;Settled picks&lt;/th&gt;
&lt;th&gt;Hit rate&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Everything the engine graded&lt;/td&gt;
&lt;td&gt;58,459&lt;/td&gt;
&lt;td&gt;54.3%&lt;/td&gt;
&lt;td&gt;Includes internal tiers that are never published&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top tier, live only, since April 2026&lt;/td&gt;
&lt;td&gt;1,357&lt;/td&gt;
&lt;td&gt;55.6%&lt;/td&gt;
&lt;td&gt;Break-even at -110 odds is 52.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top tier, 2026 WNBA season&lt;/td&gt;
&lt;td&gt;546&lt;/td&gt;
&lt;td&gt;62.3%&lt;/td&gt;
&lt;td&gt;Fully live: the season began after the backtest cutoff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top tier, full public record&lt;/td&gt;
&lt;td&gt;3,340&lt;/td&gt;
&lt;td&gt;62.5%&lt;/td&gt;
&lt;td&gt;Includes the backtested span up to 2026-04-02&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every settled pick is public and filterable by league, tier and date at &lt;a href="https://nbaproplab.com/track-record" rel="noopener noreferrer"&gt;nbaproplab.com/track-record&lt;/a&gt;, and the raw JSON is open at &lt;code&gt;/api/v1/track-record&lt;/code&gt; with no key and no signup. Figures cover 2026-01-01 to 2026-08-30.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you build these things
&lt;/h2&gt;

&lt;p&gt;A public record that shows only the good parts is marketing, not evidence. We publish the misses next to the hits for the same reason we published this postmortem: a claim nobody can falsify is worth nothing.&lt;/p&gt;

&lt;p&gt;If you are fitting a meta-learner on top of your own scoring stack, the cheapest insurance is not a better model. It is writing down, in the commit that uses it, exactly which rows your training file contains and how you got them.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>mlops</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Memoria de agentes de IA: arquitectura, privacidad y borrado en producción</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Tue, 01 Sep 2026 09:08:47 +0000</pubDate>
      <link>https://dev.to/khavel/memoria-de-agentes-de-ia-arquitectura-privacidad-y-borrado-en-produccion-35a</link>
      <guid>https://dev.to/khavel/memoria-de-agentes-de-ia-arquitectura-privacidad-y-borrado-en-produccion-35a</guid>
      <description>&lt;p&gt;La keyword principal es &lt;code&gt;memoria de agentes de IA&lt;/code&gt;; la intención es práctica: un equipo busca hacer que un agente recuerde lo útil entre conversaciones sin crear un historial infinito, compartido o imposible de borrar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Separa tres cosas. El estado de sesión mantiene una tarea en curso; la memoria persistente conserva datos seleccionados entre sesiones; RAG recupera conocimiento documental externo. Parecen similares porque los tres aportan contexto, pero tienen propietarios, ciclos de vida y fallos distintos.&lt;/p&gt;

&lt;p&gt;Mi postura: no empieces por una base vectorial ni por un extractor automático de preferencias. Empieza por una tabla de memoria con ámbito de tenant, dueño, tipo, procedencia, caducidad y borrado. Si no puedes responder quién escribió un dato, por qué se recuperó y cómo se elimina, todavía no tienes memoria de producción.&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué es memoria de un agente — y qué no
&lt;/h3&gt;

&lt;p&gt;La memoria de un agente es información conservada para cambiar de forma útil una decisión futura. Una preferencia explícita como ‘responde en español’, una restricción de cuenta o el resumen de un ticket abierto pueden ahorrar repetición. Un transcript completo, un log de tool calls o una copia del manual interno no se convierten automáticamente en memoria solo por persistirlos.&lt;/p&gt;

&lt;p&gt;El estado corto vive dentro de una conversación, thread o ejecución. LangGraph lo modela como estado persistido por thread; un store de largo plazo cruza threads mediante namespaces. RAG tampoco es memoria de usuario: responde ‘qué dice el corpus permitido’, mientras la memoria responde ‘qué dato estable y autorizado tengo sobre este actor o tarea’.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncgxumqz4l0gf478phl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncgxumqz4l0gf478phl2.png" alt="Diagrama del flujo de conversación hacia estado temporal, filtro de extracción y memoria persistente aislada por tenant, con recuperación filtrada y controles de expiración y borrado" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La memoria útil entra por una puerta de extracción, se recupera con filtros y conserva una salida explícita: caducidad o borrado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  El modelo de datos mínimo
&lt;/h3&gt;

&lt;p&gt;Una memoria durable necesita más que &lt;code&gt;text&lt;/code&gt; y un embedding. Guarda &lt;code&gt;tenant_id&lt;/code&gt;, &lt;code&gt;actor_id&lt;/code&gt;, &lt;code&gt;memory_id&lt;/code&gt;, &lt;code&gt;kind&lt;/code&gt;, &lt;code&gt;content&lt;/code&gt;, &lt;code&gt;source&lt;/code&gt;, &lt;code&gt;confidence&lt;/code&gt;, &lt;code&gt;created_at&lt;/code&gt;, &lt;code&gt;expires_at&lt;/code&gt;, &lt;code&gt;deleted_at&lt;/code&gt; y una versión de extracción. Así puedes restringir la query antes de la similitud, explicar el origen y cambiar el extractor sin fingir que todas las notas son equivalentes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kind&lt;/code&gt; evita mezclar hechos, preferencias, resúmenes y reglas operativas. Una preferencia explícita puede entrar con alta confianza; una inferencia de un modelo debería tener vida corta, fuente y una revisión más estricta. La procedencia no es burocracia: el agente debe poder mostrar, corregir o ignorar una memoria.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Código: contrato de escritura y recuperación
&lt;/h3&gt;

&lt;p&gt;memory_contract.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALLOWED_SOURCES = {"explicit_user", "trusted_system"}&amp;lt;br&amp;gt;def can_persist(m):&amp;lt;br&amp;gt;    return (m.source in ALLOWED_SOURCES and m.kind in {"preference", "fact", "task_summary"} and len(m.content) &amp;lt;= 500)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;def retrieval_scope(identity):&amp;lt;br&amp;gt;    # identity comes from authentication, never from prompt text&amp;lt;br&amp;gt;    return {"tenant_id": identity.tenant_id, "actor_id": identity.actor_id, "not_expired": True, "limit": 4}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;# Apply this scope BEFORE vector similarity or model context injection.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El modelo puede proponer una candidata, pero identidad, tipos permitidos, tamaño, retención y filtros los decide el runtime autenticado. El &lt;code&gt;tenant_id&lt;/code&gt; no se extrae del prompt ni se acepta como argumento de una tool generalista.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aísla antes de buscar
&lt;/h2&gt;

&lt;p&gt;La similitud vectorial debe ocurrir dentro de un ámbito ya autorizado. Primero filtra tenant, actor, clase de memoria y vigencia; después calcula similitud; por último limita la cantidad de contexto. Hacerlo al revés convierte una búsqueda ‘inteligente’ en una fuga entre clientes.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;En una base relacional, Row-Level Security puede ser una segunda barrera para que una consulta mal construida no lea filas de otro tenant. No sustituye la autorización de aplicación, pero evita depender de que cada developer recuerde el &lt;code&gt;WHERE tenant_id = ...&lt;/code&gt; correcto.&lt;/p&gt;

&lt;p&gt;Los namespaces de LangGraph y los filtros de metadata de AgentCore expresan el mismo principio: la memoria no es una colección global. Diseña la clave de aislamiento antes de escoger el motor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extrae poco, consolida con reglas
&lt;/h2&gt;

&lt;p&gt;Hay dos momentos para crear memoria. En el hot path, el agente propone o guarda un dato antes de responder: es inmediato, pero añade latencia y riesgo. En segundo plano, un job revisa eventos cerrados y consolida candidatos: permite mejores reglas, aunque el recuerdo llega después. Para preferencias o acciones sensibles, prefiero confirmación explícita.&lt;/p&gt;

&lt;p&gt;Consolidar significa decidir entre añadir, actualizar, ignorar o expirar. AgentCore documenta estrategias distintas para semántica, preferencias, resúmenes y episodios; incluso si no usas AWS, cada tipo necesita reglas de extracción y de conflicto distintas.&lt;/p&gt;

&lt;p&gt;Da fecha de caducidad a lo que puede quedar obsoleto: estado de un incidente, proyecto activo, configuración temporal o inferencias. Una memoria sin &lt;code&gt;expires_at&lt;/code&gt; suele vivir más que su verdad. Para datos de alto impacto, ‘olvidar’ debe eliminar texto, embedding e índices derivados.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  La memoria es input no confiable
&lt;/h3&gt;

&lt;p&gt;Una memoria recuperada se parece a una tool response: puede contener instrucciones hostiles, datos equivocados o una preferencia revocada. No la concatentes como si fuera una orden del sistema. Etiquétala como contexto, conserva procedencia y no permitas que una frase almacenada habilite pagos, despliegues o acceso a datos.&lt;/p&gt;

&lt;p&gt;El riesgo no se limita a un atacante. Un extractor puede convertir ‘estoy de viaje esta semana’ en una preferencia permanente; un tool puede incorporar texto de una web; una migración puede duplicar registros. La defensa es la misma: allowlist de tipos, confianza limitada, auditoría de escritura y evaluación de conflictos.&lt;/p&gt;

&lt;p&gt;Añade casos de memoria en tus evals: dato correcto, dato caducado, dato de otro tenant, instrucción adversarial persistida, corrección explícita y borrado. Mide no solo si el agente recuerda, sino si ignora un recuerdo cuando su procedencia, ámbito o fecha no permiten usarlo.&lt;/p&gt;
&lt;h3&gt;
  
  
  Privacidad, retención y coste
&lt;/h3&gt;

&lt;p&gt;Persistir memoria en tu base de datos no elimina los datos que envías al proveedor de modelo. Si reinyectas una preferencia en cada prompt, ese contenido sigue sujeto a los controles de datos y retención del proveedor. OpenAI, por ejemplo, distingue logs de abuse monitoring de application state y documenta opciones por endpoint; revisa el contrato del proveedor que realmente usas.&lt;/p&gt;

&lt;p&gt;Minimiza antes de cifrar. No guardes secretos, identificadores completos, transcripciones crudas ni atributos sensibles si el caso de uso funciona con una preferencia breve y controlada. Cifrado, acceso mínimo y auditoría son necesarios; no justifican coleccionar datos que el agente no necesita.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El coste tiene tres partes: extracción, embeddings/almacenamiento y tokens al recuperar. Recuperar ocho recuerdos vagos puede empeorar una respuesta y subir coste. Empieza con tres o cuatro registros muy relevantes y mide si cambian la decisión.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observabilidad y evals
&lt;/h2&gt;

&lt;p&gt;Registra para cada turno: memoria candidata, decisión de persistencia, versión de extractor, namespace, filtros aplicados, IDs recuperados, score, caducidad, tokens añadidos y si la respuesta la usó. Redacta contenido sensible en los logs; los IDs y metadatos suelen bastar para depurar.&lt;/p&gt;

&lt;p&gt;Una métrica útil es la tasa de recuperación accionable: de las memorias inyectadas, cuántas cambiaron una respuesta o tool call de forma correcta. Otra es la tasa de corrección o borrado. Si hay muchas correcciones, el extractor está promoviendo ruido o las reglas son demasiado amplias.&lt;/p&gt;

&lt;p&gt;Conecta esos eventos a tus trazas. La observabilidad GenAI explica la ejecución; aquí debes poder responder otra pregunta: ‘¿qué recuerdo entró y por qué este agente lo creyó?’. Sin esa relación, una personalización errónea no se puede reproducir.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Plan de adopción en una semana
&lt;/h3&gt;

&lt;p&gt;Día 1: elige un único caso de bajo riesgo, como idioma, formato de salida o resumen de ticket. Escribe qué dato puede guardar y qué queda prohibido.&lt;/p&gt;

&lt;p&gt;Día 2: modela tenant, actor, tipo, origen, caducidad y borrado; obliga a que identidad venga de autenticación, no del prompt.&lt;/p&gt;

&lt;p&gt;Día 3: implementa lectura filtrada y limitada con un test de aislamiento cruzado y otro de expiración.&lt;/p&gt;

&lt;p&gt;Día 4: permite candidatos de escritura con allowlist y confirmación para preferencias; rechaza tool output y texto web por defecto.&lt;/p&gt;

&lt;p&gt;Día 5: crea listar, corregir y borrar, incluyendo embeddings e índices derivados; deja evidencia auditable sin conservar contenido eliminado.&lt;/p&gt;

&lt;p&gt;Día 6: ejecuta evals con memoria correcta, falsa, caducada, revocada y adversarial; mide utilidad, latencia y tokens.&lt;/p&gt;

&lt;p&gt;Día 7: activa para una cohorte pequeña y revisa recuperaciones, correcciones y costes antes de ampliar tipos de memoria o usuarios.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Errores que no aceptaría en producción
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Usar todo el historial del chat como memoria de largo plazo.&lt;/li&gt;
&lt;li&gt;Dejar que el modelo elija tenant, usuario o namespace desde lenguaje natural.&lt;/li&gt;
&lt;li&gt;Buscar por embedding antes de aplicar filtros obligatorios.&lt;/li&gt;
&lt;li&gt;Persistir tool output, páginas web o texto de usuario sin tipo, fuente y política de promoción.&lt;/li&gt;
&lt;li&gt;No tener &lt;code&gt;expires_at&lt;/code&gt;, borrado verificable ni gestión de correcciones.&lt;/li&gt;
&lt;li&gt;Inyectar recuerdos recuperados como instrucciones privilegiadas.&lt;/li&gt;
&lt;li&gt;Medir solo recall y no fugas, correcciones, coste ni decisiones erróneas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es la memoria de un agente de IA?
&lt;/h3&gt;

&lt;p&gt;Es un conjunto selectivo de datos persistentes que puede cambiar una decisión en una sesión futura. No es el historial completo ni un RAG documental; debe llevar ámbito, procedencia, tipo y ciclo de vida.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuál es la diferencia entre estado y memoria a largo plazo?
&lt;/h3&gt;

&lt;p&gt;El estado pertenece a una conversación o ejecución y suele recuperarse por thread. La memoria a largo plazo cruza sesiones y debe aislarse por tenant, usuario o aplicación con namespaces y controles explícitos.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Necesito una base vectorial para memoria de agentes?
&lt;/h3&gt;

&lt;p&gt;No siempre. Preferencias y claves estructuradas se resuelven mejor con consultas exactas. Usa búsqueda semántica solo cuando el tipo de recuerdo y el volumen justifican recuperar por significado, siempre después de filtrar ámbito y vigencia.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cómo evito que un agente recuerde datos de otro cliente?
&lt;/h3&gt;

&lt;p&gt;Obtén identidad desde autenticación, filtra tenant y actor antes de la similitud, limita resultados y añade una barrera de datos. Prueba explícitamente la fuga cruzada en CI.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuánto tiempo debe vivir una memoria?
&lt;/h3&gt;

&lt;p&gt;Lo mínimo que haga útil el caso. Preferencias estables pueden durar más con control de corrección; contexto de tareas e inferencias necesitan expiración o revisión.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿La memoria persistente es segura frente a prompt injection?
&lt;/h3&gt;

&lt;p&gt;No por sí sola. Todo recuerdo recuperado es input no confiable: conserva fuente, etiqueta contexto, evita que habilite acciones y evalúa instrucciones adversariales o datos envenenados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo añadir memoria segura a un agente de IA
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Acotar el caso.&lt;/strong&gt; Elige una preferencia o resumen de bajo riesgo y define qué datos nunca se guardan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Definir el ámbito.&lt;/strong&gt; Obtén tenant y actor desde la identidad autenticada, no desde texto libre ni argumentos de una tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modelar procedencia.&lt;/strong&gt; Guarda tipo, fuente, confianza, fecha, caducidad y versión del extractor junto al contenido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filtrar antes de recuperar.&lt;/strong&gt; Aplica tenant, actor, tipo y vigencia antes de búsqueda semántica; devuelve pocos resultados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlar escritura.&lt;/strong&gt; Permite solo fuentes y tipos en allowlist; confirma preferencias importantes y procesa candidatos inciertos en segundo plano.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dar salida al dato.&lt;/strong&gt; Implementa listar, corregir, expirar y borrar eliminando también índices y embeddings derivados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluar adversarialmente.&lt;/strong&gt; Prueba recuerdos caducados, cruzados, falsos, revocados y hostiles; mide utilidad, fugas y coste.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desplegar con trazas.&lt;/strong&gt; Registra decisiones e IDs redactados, revisa una cohorte pequeña y amplía solo cuando los datos sean defendibles.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/oss/python/concepts/memory" rel="noopener noreferrer"&gt;LangChain: conceptos de memoria&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/oss/python/langchain/long-term-memory" rel="noopener noreferrer"&gt;LangChain: memoria a largo plazo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/oss/python/langgraph/add-memory" rel="noopener noreferrer"&gt;LangGraph: añadir memoria&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/harness-memory.html" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore Memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/long-term-memory-metadata.html" rel="noopener noreferrer"&gt;AgentCore: filtros de metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/16/sql-createpolicy.html" rel="noopener noreferrer"&gt;PostgreSQL: Row-Level Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/models/default-usage-policies-by-endpoint" rel="noopener noreferrer"&gt;OpenAI API: controles de datos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/" rel="noopener noreferrer"&gt;OWASP: prompt injection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/langgraph-agentes-python-estado-produccion/" rel="noopener noreferrer"&gt;LangGraph: agentes Python con estado y checkpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/busqueda-hibrida-rag-bm25-vectorial-reranking/" rel="noopener noreferrer"&gt;Búsqueda híbrida RAG: BM25, vectores y reranking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/prompt-injection-agentes-ia-seguridad-evals/" rel="noopener noreferrer"&gt;Prompt injection en agentes: prevención y evals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/opentelemetry-genai-observabilidad-agentes/" rel="noopener noreferrer"&gt;OpenTelemetry GenAI para observar agentes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/openai-responses-api-function-calling-produccion/" rel="noopener noreferrer"&gt;OpenAI Responses API y function calling fiable&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>Pydantic AI: cómo crear agentes Python tipados sin perder control en producción</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Mon, 31 Aug 2026 09:10:03 +0000</pubDate>
      <link>https://dev.to/khavel/pydantic-ai-como-crear-agentes-python-tipados-sin-perder-control-en-produccion-2h5o</link>
      <guid>https://dev.to/khavel/pydantic-ai-como-crear-agentes-python-tipados-sin-perder-control-en-produccion-2h5o</guid>
      <description>&lt;p&gt;Pydantic AI no es otro wrapper bonito para prompts. Su valor está en obligarte a tratar un agente como software: contratos de salida, dependencias explícitas, herramientas validadas, límites de uso, trazas y evals.&lt;/p&gt;

&lt;p&gt;Pydantic AI es un framework Python para construir aplicaciones y agentes de IA con el estilo mental de FastAPI: tipos, validación, inyección de dependencias, herramientas declarativas, salida estructurada, observabilidad y evals.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;Pydantic AI agentes&lt;/code&gt;; la intención de búsqueda en español es aprender cuándo usar Pydantic AI y cómo montar un agente Python de producción con output tipado, tools, límites de uso, MCP y trazas.&lt;/p&gt;

&lt;p&gt;Mi postura: Pydantic AI tiene sentido cuando el agente va a tocar datos o decisiones reales. Si solo quieres un chat demo, cualquier wrapper sirve. Si necesitas que la salida sea validable, testeable y observable, aquí empieza a compensar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Por qué Pydantic AI importa para devs Python
&lt;/h3&gt;

&lt;p&gt;Una definición citable: Pydantic AI es un framework de agentes para Python que convierte prompts, herramientas, dependencias y resultados de modelos en contratos tipados que puedes validar, probar y observar como parte de una aplicación normal.&lt;/p&gt;

&lt;p&gt;La mayoría de demos de agentes fallan por el mismo motivo: tratan el LLM como una caja mágica que devuelve texto. En producción eso no basta. Necesitas saber qué forma debe tener la respuesta, qué herramientas puede llamar, cuántas veces, con qué datos y bajo qué límites.&lt;/p&gt;

&lt;p&gt;Pydantic AI ataca ese problema desde una idea muy pragmática: si ya usas Pydantic para validar entradas y salidas en APIs, usa el mismo músculo para validar decisiones generadas por modelos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Si quieres seguir frameworks de agentes como Pydantic AI, OpenAI Agents SDK, Claude Agent SDK, MCP y evals sin leer veinte changelogs a la semana, DevAI Semanal te lo resume en un email de 5 minutos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  La arquitectura mínima de un agente serio
&lt;/h3&gt;

&lt;p&gt;Un agente Pydantic AI razonable tiene cinco piezas. Primero, un &lt;code&gt;Agent&lt;/code&gt; con instrucciones y modelo. Segundo, un &lt;code&gt;output_type&lt;/code&gt; con un &lt;code&gt;BaseModel&lt;/code&gt; que define qué debe devolver. Tercero, dependencias explícitas para pasar servicios, tenant, usuario o conexiones. Cuarto, tools con argumentos validados. Quinto, límites y observabilidad para no descubrir el coste en la factura.&lt;/p&gt;

&lt;p&gt;La ventaja no es que el modelo sea más inteligente. La ventaja es que el contrato alrededor del modelo se vuelve más estrecho. Menos texto libre, menos estado implícito y menos magia escondida en el prompt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdbcfx8gvmxl4c5dwyg92.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdbcfx8gvmxl4c5dwyg92.png" alt="Diagrama de arquitectura de un agente Pydantic AI con prompt, Agent, tools, dependencias, output model, Logfire y evals" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La frontera sana: el LLM razona, pero tu aplicación define contratos, dependencias, tools permitidas, límites de uso y trazas revisables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Primer ejemplo ejecutable: salida tipada
&lt;/h2&gt;

&lt;p&gt;Este ejemplo no intenta ser sofisticado. La idea es mostrar el patrón: un &lt;code&gt;BaseModel&lt;/code&gt; define la salida, el agente la valida y tu código consume &lt;code&gt;result.output&lt;/code&gt; como objeto Python, no como JSON pegado con cinta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from pydantic import BaseModel, Field
from pydantic_ai import Agent

class ReviewDecision(BaseModel):
    verdict: str = Field(description="approve, request_changes or needs_human")
    risk: int = Field(ge=0, le=10)
    reasons: list[str]

agent = Agent(
    "openai:gpt-5.2",
    output_type=ReviewDecision,
    instructions=(
        "Eres un revisor senior. Devuelve una decision breve, "
        "un riesgo de 0 a 10 y razones accionables."
    ),
)

result = agent.run_sync(
    "El PR cambia autenticacion, no trae tests y toca sesiones."
)

decision = result.output
print(decision.verdict, decision.risk, decision.reasons)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Qué gana el output tipado
&lt;/h3&gt;

&lt;p&gt;Ganas una frontera concreta entre IA y producto. Si el modelo responde con una forma inválida, no lo conviertes silenciosamente en estado de negocio. Lo validas, reintentas dentro del presupuesto o fallas de forma explícita.&lt;/p&gt;

&lt;p&gt;Esto es especialmente importante en agentes que clasifican tickets, generan acciones, evalúan riesgos, enrutan incidencias, preparan PRs o deciden si una tarea necesita humano. En esos casos, texto bonito no es un contrato.&lt;/p&gt;

&lt;p&gt;La documentación de Pydantic AI también remarca que el resultado conserva tipos genéricos, historial y uso de la ejecución. Esa metadata importa cuando quieres depurar por qué una decisión salió cara o mala.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Dependencias: no metas datos vivos en el prompt
&lt;/h3&gt;

&lt;p&gt;El patrón correcto es pasar dependencias por &lt;code&gt;deps&lt;/code&gt;, no pegar media base de datos en instrucciones. Las dependencias permiten que tools e instrucciones dinámicas accedan a servicios concretos con tipos claros: cliente HTTP, conexión a DB, tenant, usuario, feature flags o repositorio.&lt;/p&gt;

&lt;p&gt;Esto reduce tres riesgos: fuga accidental de contexto, prompts imposibles de testear y herramientas que leen datos que no deberían. Si una tool necesita &lt;code&gt;tenant_id&lt;/code&gt;, que venga de una dependencia controlada, no de un texto que el modelo puede reinterpretar.&lt;/p&gt;
&lt;h3&gt;
  
  
  Segundo ejemplo ejecutable: tool con deps y límite de uso
&lt;/h3&gt;

&lt;p&gt;El siguiente patrón es el que usaría para un agente interno que consulta deuda técnica. La tool recibe argumentos validados, accede a servicios desde &lt;code&gt;RunContext&lt;/code&gt; y la ejecución aplica límites para que una pregunta torpe no dispare diez llamadas innecesarias.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from dataclasses import dataclass

from pydantic import BaseModel
from pydantic_ai import Agent, RunContext, UsageLimits

class Finding(BaseModel):
    file: str
    problem: str
    next_step: str

@dataclass
class RepoDeps:
    repo_name: str
    index: object

agent = Agent(
    "anthropic:claude-sonnet-4-6",
    deps_type=RepoDeps,
    output_type=list[Finding],
    instructions="Encuentra problemas concretos y devuelve acciones pequenas.",
)

@agent.tool
async def search_code(ctx: RunContext[RepoDeps], query: str) -&amp;gt; list[str]:
    """Busca fragmentos relevantes en el indice del repositorio."""
    return await ctx.deps.index.search(ctx.deps.repo_name, query, limit=5)

async def review(repo_index):
    deps = RepoDeps(repo_name="billing-api", index=repo_index)
    return await agent.run(
        "Busca riesgos en el modulo de invoices.",
        deps=deps,
        usage_limits=UsageLimits(request_limit=4, tool_calls_limit=3),
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tools: la docstring también es interfaz
&lt;/h2&gt;

&lt;p&gt;En Pydantic AI, las funciones registradas como tools exponen argumentos al modelo. Eso significa que nombres, tipos y docstrings son parte de la interfaz. Una tool vaga produce llamadas vagas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;Regla práctica: una tool debe hacer una cosa, aceptar pocos parámetros y devolver datos que no obliguen al modelo a inferir demasiado. Si devuelves una lista gigante de strings, has trasladado el problema al prompt. Si devuelves objetos pequeños y consistentes, reduces alucinaciones operativas.&lt;/p&gt;

&lt;p&gt;También conviene separar tools de lectura y tools mutantes. Las primeras pueden tener permisos amplios dentro de un entorno controlado; las segundas necesitan scopes mínimos, logging y aprobación humana cuando tocan repos, tickets, cloud o datos de clientes.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP: úsalo para capacidades externas, no para saltarte diseño
&lt;/h3&gt;

&lt;p&gt;Pydantic AI puede actuar como cliente MCP y conectar tools locales o remotas mediante &lt;code&gt;MCPToolset&lt;/code&gt; o la capacidad &lt;code&gt;MCP&lt;/code&gt;. Eso encaja muy bien con el ecosistema actual: servidores MCP para documentación, repos, observabilidad, datos internos o automatización.&lt;/p&gt;

&lt;p&gt;Pero MCP no arregla una arquitectura mala. Si conectas diez servidores sin política, solo has dado más botones al modelo. La pregunta correcta es: qué tool necesita esta tarea, con qué transporte, con qué lifecycle, con qué credenciales y qué salida espero validar después.&lt;/p&gt;

&lt;p&gt;Para equipos que ya usan MCP en Copilot, Claude Code o Cursor, Pydantic AI puede ser la capa Python donde conviertes esas capacidades en producto: controlas el cliente, los tipos, el flujo de ejecución y las pruebas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modelos y proveedores: no cases tu dominio con una API
&lt;/h3&gt;

&lt;p&gt;Pydantic AI abstrae modelos y proveedores: puedes instanciar agentes con nombres tipo &lt;code&gt;openai:gpt-5.2&lt;/code&gt; o usar clases de modelo/proveedor más explícitas cuando necesitas Azure, OpenAI-compatible providers, LiteLLM, Ollama, GitHub Models u otro gateway.&lt;/p&gt;

&lt;p&gt;Esto no significa que cambiar de modelo sea gratis. Cada proveedor tiene límites, perfiles, capacidades de herramientas y detalles de JSON schema. Pero sí te permite aislar el dominio de la aplicación del SDK de un proveedor concreto.&lt;/p&gt;

&lt;p&gt;Mi recomendación: empieza con un proveedor explícito en configuración, registra métricas por modelo y guarda casos de evaluación. Cambiar de modelo sin evals es fe, no ingeniería.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Observabilidad y evals: el punto donde deja de ser demo
&lt;/h3&gt;

&lt;p&gt;Pydantic AI se integra con Logfire y Pydantic Evals. Esa combinación importa porque los agentes fallan de formas no deterministas: hoy responden bien, mañana el modelo cambia, una tool tarda más, un prompt arrastra contexto viejo o un output validator empieza a reintentar demasiado.&lt;/p&gt;

&lt;p&gt;Las evals no sustituyen tests unitarios. Sirven para otra capa: casos representativos, outputs esperados, evaluadores deterministas o LLM judges, métricas por experimento y comparación entre implementaciones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una batería mínima debería incluir: casos felices, inputs ambiguos, intentos de prompt injection, datos incompletos, límite de tools, errores de proveedor, salida inválida y ejemplos donde el agente debe decir &lt;code&gt;necesita humano&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Durable execution: solo si el agente dura más que una request
&lt;/h3&gt;

&lt;p&gt;Para tareas cortas, &lt;code&gt;run_sync&lt;/code&gt; o &lt;code&gt;run&lt;/code&gt; basta. Para flujos largos, multi-step o con reintentos de infraestructura, necesitas ejecución durable. La documentación de Pydantic AI cubre integraciones como Temporal, DBOS, Prefect y Restate.&lt;/p&gt;

&lt;p&gt;No metas durable execution el primer día si no sabes todavía qué workflow quieres preservar. Primero define contrato de salida, tools, límites y evals. Después, si el agente tarda minutos, llama APIs externas o debe sobrevivir a caídas, añade durable execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Checklist de producción
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Define &lt;code&gt;output_type&lt;/code&gt; para cualquier decisión que consuma tu aplicación.&lt;/li&gt;
&lt;li&gt;Pasa datos vivos por &lt;code&gt;deps&lt;/code&gt;, no por prompts enormes.&lt;/li&gt;
&lt;li&gt;Separa tools de lectura y tools mutantes.&lt;/li&gt;
&lt;li&gt;Pon &lt;code&gt;UsageLimits&lt;/code&gt; en runs que puedan llamar tools.&lt;/li&gt;
&lt;li&gt;Registra modelo, tokens, tool calls, latencia, reintentos y coste.&lt;/li&gt;
&lt;li&gt;Crea evals antes de cambiar de modelo o prompt principal.&lt;/li&gt;
&lt;li&gt;Conecta MCP solo para capacidades concretas y auditables.&lt;/li&gt;
&lt;li&gt;Haz que el agente pueda decir &lt;code&gt;no sé&lt;/code&gt; o &lt;code&gt;necesita humano&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Versiona prompts, schemas y datasets de evaluación junto al código.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Errores que evitaría
&lt;/h2&gt;

&lt;p&gt;El primero es vender Pydantic AI como garantía de verdad. Validar estructura no valida factualidad. Un &lt;code&gt;BaseModel&lt;/code&gt; puede contener basura perfectamente tipada si no hay tools, fuentes o evaluadores.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;El segundo es meter todos los datos en instrucciones. Si el prompt contiene secretos, datos de cliente o reglas efímeras, cada run se vuelve más caro, menos auditable y más difícil de limpiar.&lt;/p&gt;

&lt;p&gt;El tercero es conectar MCP como catálogo infinito. Un agente con demasiadas tools se parece a un junior con permisos de producción y una wiki enorme: quizá acierte, pero no es un control.&lt;/p&gt;

&lt;p&gt;El cuarto es no medir reintentos de validación. Si tu schema es demasiado estricto o ambiguo, el agente puede gastar tokens intentando satisfacer una forma que el prompt no explica bien.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cuándo elegir Pydantic AI frente a OpenAI o Claude SDK
&lt;/h3&gt;

&lt;p&gt;Elige Pydantic AI si tu equipo trabaja en Python, ya usa Pydantic/FastAPI, necesita salida tipada, quiere cambiar de proveedor con menos fricción y va a tratar agentes como componentes de backend.&lt;/p&gt;

&lt;p&gt;Elige el SDK nativo de OpenAI o Anthropic si necesitas exprimir una capacidad específica del proveedor, si tu app depende de una superficie muy concreta o si prefieres controlar directamente cada request.&lt;/p&gt;

&lt;p&gt;La decisión práctica no es framework contra framework. Es capa de dominio contra API de proveedor. Pydantic AI brilla cuando quieres una capa de dominio estable por encima de modelos que van a cambiar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plan de adopción de una semana
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Día 1: elige un caso acotado donde la salida pueda representarse como &lt;code&gt;BaseModel&lt;/code&gt;: clasificación de tickets, revisión de riesgo, resumen técnico o extracción estructurada.&lt;/li&gt;
&lt;li&gt;Día 2: escribe el agente con una sola tool de lectura y &lt;code&gt;UsageLimits&lt;/code&gt; bajos. No conectes todavía acciones mutantes.&lt;/li&gt;
&lt;li&gt;Día 3: añade diez casos de evaluación: cinco normales, tres ambiguos y dos hostiles.&lt;/li&gt;
&lt;li&gt;Día 4: instrumenta trazas y registra uso por ejecución. Mira reintentos, tool calls y latencia antes de optimizar prompts.&lt;/li&gt;
&lt;li&gt;Día 5: prueba un segundo modelo o gateway y compara evals. Si no puedes comparar, todavía no estás listo para producción.
&amp;gt; ### Conclusión
&amp;gt;
&amp;gt; Pydantic AI es interesante porque baja los agentes al suelo: tipos, validación, dependencias, límites, trazas y evals. No promete que el modelo piense mejor. Promete que tu aplicación tenga mejores fronteras alrededor del modelo.
&amp;gt;
&amp;gt; Esa es exactamente la dirección correcta para equipos Python. Los agentes no deberían ser prompts sueltos con permisos. Deberían parecerse a servicios: contratos claros, herramientas pequeñas, límites explícitos, tests probabilísticos y logs que expliquen qué pasó cuando algo sale mal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es Pydantic AI?
&lt;/h3&gt;

&lt;p&gt;Pydantic AI es un framework Python para construir aplicaciones y agentes de IA con contratos tipados, herramientas validadas, dependencias explícitas, observabilidad y evals.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Pydantic AI reemplaza a OpenAI Agents SDK o Claude Agent SDK?
&lt;/h3&gt;

&lt;p&gt;No necesariamente. Puede usarse como capa Python de dominio cuando quieres tipos, validación y portabilidad; los SDK nativos siguen siendo útiles para capacidades específicas del proveedor.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Pydantic AI soporta MCP?
&lt;/h3&gt;

&lt;p&gt;Sí. Pydantic AI puede actuar como cliente MCP y conectar servidores locales o remotos para usar sus tools dentro de ejecuciones de agente.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿La salida tipada evita alucinaciones?
&lt;/h3&gt;

&lt;p&gt;No. Evita que la forma sea inválida, pero no garantiza que el contenido sea verdadero. Para factualidad necesitas fuentes, tools, validadores y evals.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuándo merece la pena usar Pydantic Evals?
&lt;/h3&gt;

&lt;p&gt;Cuando vas a cambiar prompts, modelos, tools o workflows y necesitas comparar comportamiento con casos representativos, no solo confiar en una demo.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Pydantic AI sirve para producción?
&lt;/h3&gt;

&lt;p&gt;Sí, si lo usas con límites de uso, observabilidad, evals, control de tools y revisión humana en acciones de riesgo. Sin eso, sigue siendo una demo con buen tipado.&lt;/p&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/overview/" rel="noopener noreferrer"&gt;Pydantic AI overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/core-concepts/agent/" rel="noopener noreferrer"&gt;Pydantic AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/core-concepts/output/" rel="noopener noreferrer"&gt;Pydantic AI Output&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/models/overview/" rel="noopener noreferrer"&gt;Pydantic AI model providers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/mcp/client/" rel="noopener noreferrer"&gt;Pydantic AI MCP client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/api/pydantic-ai/agent/" rel="noopener noreferrer"&gt;Pydantic AI agent API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/evals/evals/" rel="noopener noreferrer"&gt;Pydantic Evals overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/evals/how-to/logfire-integration/" rel="noopener noreferrer"&gt;Pydantic Evals Logfire integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pydantic.dev/docs/ai/project/changelog/" rel="noopener noreferrer"&gt;Pydantic AI changelog and V2 upgrade guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pydantic/pydantic-ai" rel="noopener noreferrer"&gt;pydantic/pydantic-ai GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/openai-agents-sdk-mcp-guardrails-tracing/" rel="noopener noreferrer"&gt;OpenAI Agents SDK: MCP, guardrails y tracing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/claude-agent-sdk-python-typescript-agentes/" rel="noopener noreferrer"&gt;Claude Agent SDK en Python y TypeScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/litellm-proxy-gateway-llm-costes/" rel="noopener noreferrer"&gt;LiteLLM Proxy: gateway IA, costes y modelos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-outputschema-structuredcontent-agentes/" rel="noopener noreferrer"&gt;MCP outputSchema y structuredContent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/metricas-agentes-codigo-productividad-coste/" rel="noopener noreferrer"&gt;Métricas para agentes de código&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>python</category>
    </item>
    <item>
      <title>Codex Skills: cómo crear workflows reutilizables sin inflar el contexto del agente</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Sun, 30 Aug 2026 13:37:44 +0000</pubDate>
      <link>https://dev.to/khavel/codex-skills-como-crear-workflows-reutilizables-sin-inflar-el-contexto-del-agente-386</link>
      <guid>https://dev.to/khavel/codex-skills-como-crear-workflows-reutilizables-sin-inflar-el-contexto-del-agente-386</guid>
      <description>&lt;p&gt;Una Codex Skill es un directorio con un &lt;code&gt;SKILL.md&lt;/code&gt; obligatorio y, cuando hace falta, scripts, referencias y assets. La keyword principal es &lt;code&gt;Codex Skills&lt;/code&gt;; la intención es de implementación: un developer busca convertir un procedimiento repetido en un workflow que el agente pueda descubrir y ejecutar de forma consistente.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;La idea clave es la carga progresiva: Codex conoce al principio solo el nombre y la descripción; lee las instrucciones completas cuando la tarea encaja. Las referencias largas no deben vivir en el prompt permanente. Se cargan solo desde el &lt;code&gt;SKILL.md&lt;/code&gt; si el workflow las necesita. Eso conserva contexto para el código y evita que una 'ayuda' acabe empeorando el razonamiento.&lt;/p&gt;

&lt;p&gt;Mi postura: empieza por una skill que elimine una decisión repetitiva y verificable —por ejemplo, reproducir un bug de CI o preparar una migración—, no por una que intente convertir al agente en el experto universal de tu empresa. Una skill buena reduce ambigüedad; una enorme solo es otro sitio donde esconder políticas contradictorias.&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué es una skill y qué no es
&lt;/h3&gt;

&lt;p&gt;Una skill empaqueta una capacidad orientada a tarea. Su &lt;code&gt;description&lt;/code&gt; explica cuándo debe activarse; &lt;code&gt;SKILL.md&lt;/code&gt; define el procedimiento; los scripts encapsulan operaciones frágiles; las referencias aportan detalle bajo demanda. El resultado ideal es que dos personas obtengan el mismo checklist y la misma evidencia aunque formulen la petición de manera distinta.&lt;/p&gt;

&lt;p&gt;No es un sustituto de &lt;code&gt;AGENTS.md&lt;/code&gt;. &lt;code&gt;AGENTS.md&lt;/code&gt; contiene reglas duraderas del repositorio: comandos de test, fronteras de seguridad, convenciones y rutas sensibles. Una skill contiene un workflow especializado: qué hacer para esta clase de tarea y cómo comprobar que quedó bien. Si copias todo &lt;code&gt;AGENTS.md&lt;/code&gt; dentro de cada skill, tendrás varias políticas que divergirán.&lt;/p&gt;

&lt;p&gt;Tampoco es una vía para elevar permisos. Una skill puede recomendar un script, pero la sandbox, la política de aprobaciones y las credenciales de la sesión siguen siendo los controles que deciden qué puede ocurrir. Trata cada comando incluido como código de producción: revisable, acotado e idempotente cuando sea posible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fim7edb8c7vua8hveajk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fim7edb8c7vua8hveajk6.png" alt="Flujo conceptual de una tarea de desarrollo que activa una skill, carga instrucciones, referencias y script bajo demanda, pasa una verificación y produce un cambio revisable" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La skill decide el procedimiento; los controles de la sesión y la verificación siguen decidiendo si el cambio es aceptable.&lt;/p&gt;

&lt;h3&gt;
  
  
  La arquitectura mínima que sí escala
&lt;/h3&gt;

&lt;p&gt;Deja &lt;code&gt;SKILL.md&lt;/code&gt; corto y ejecutable. Si necesita 20 páginas de contexto, separa las ramas del proceso y coloca el detalle en &lt;code&gt;references/&lt;/code&gt;. Si necesita copiar comandos complejos, muévelos a &lt;code&gt;scripts/&lt;/code&gt; y dale parámetros explícitos. El agente debe leer instrucciones, no reconstruir shell heredada a partir de párrafos vagos.&lt;/p&gt;

&lt;p&gt;Usa &lt;code&gt;agents/openai.yaml&lt;/code&gt; solo para metadata o dependencias de presentación cuando sea útil; no lo confundas con un mecanismo de autorización. La política real de red, filesystem y aprobación se aplica fuera del paquete. Esa separación evita el error clásico de creer que una lista declarativa protege un secreto o un servicio externo.&lt;/p&gt;

&lt;p&gt;Una estructura pequeña suele bastar: &lt;code&gt;SKILL.md&lt;/code&gt; para el contrato, &lt;code&gt;scripts/&lt;/code&gt; para pasos repetibles, &lt;code&gt;references/&lt;/code&gt; para documentación que no debe ocupar contexto siempre y &lt;code&gt;assets/&lt;/code&gt; para plantillas consumidas por el resultado. No añadas README, changelog y cinco guías auxiliares por reflejo: son más superficie que el agente tendrá que elegir mal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Crea un SKILL.md que el agente pueda elegir
&lt;/h3&gt;

&lt;p&gt;El frontmatter solo necesita un nombre estable y una descripción concreta. La descripción es un selector: menciona el resultado, las señales de activación y una frontera. 'Ayuda con desarrollo' no selecciona nada; 'reproduce fallos intermitentes de pytest y guarda evidencia sin cambiar producción' sí.&lt;/p&gt;

&lt;p&gt;Después escribe imperativos observables: inspecciona primero, preserva cambios existentes, ejecuta un comando de repro, aplica el cambio mínimo, corre la regresión y reporta evidencia. Evita instrucciones como 'usa tu criterio' precisamente donde el equipo espera uniformidad. El criterio humano debe aparecer como una condición de parada o una aprobación requerida.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ejemplo mínimo para un repositorio Python:&lt;/p&gt;

&lt;p&gt;.agents/skills/pytest-regresion/SKILL.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
name: pytest-regresion
description: Reproduce y corrige un fallo de pytest cuando hay un test, un stack trace o un comando que falla. No usar para refactors ni cambios de infraestructura.
---

1. Lee AGENTS.md y conserva los cambios no relacionados.
2. Ejecuta el test indicado; si no hay repro, detente y pide el comando exacto.
3. Añade primero un test de regresión mínimo.
4. Modifica solo el módulo que explica el fallo.
5. Ejecuta pytest sobre el test y la suite afectada.
6. Entrega archivos tocados, comando, resultado y riesgos restantes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Carga contexto por capas, no por acumulación
&lt;/h2&gt;

&lt;p&gt;La documentación de Codex describe la carga progresiva para que el listado inicial de skills no consuma el contexto del trabajo. Aprovecha ese diseño: en &lt;code&gt;SKILL.md&lt;/code&gt; enlaza una referencia solo cuando hay una bifurcación real, como el proveedor cloud, el framework o un protocolo de seguridad. No precargues tres SDKs por si acaso.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;Un patrón útil es 'contrato arriba, detalle abajo'. Arriba: entrada esperada, salida, límites, comando de validación y cuándo parar. Abajo: enlaces a &lt;code&gt;references/postgres.md&lt;/code&gt;, &lt;code&gt;references/aws.md&lt;/code&gt; o una tabla de compatibilidad. Así una tarea de SQLite no lee reglas de producción para Postgres y el agente conserva espacio para inspeccionar tu código.&lt;/p&gt;

&lt;p&gt;Mide el fracaso con una señal simple: si los agentes vuelven a pedir instrucciones que ya existen, falta claridad en el contrato. Si empiezan a leer referencias que no usan o ignoran el código local, la skill está cargando demasiado. La solución rara vez es añadir otro documento; normalmente es separar dos workflows que no comparten intención.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Scripts: encapsula lo frágil, no la decisión
&lt;/h3&gt;

&lt;p&gt;Un script es apropiado cuando la secuencia es mecánica y peligrosa de reescribir: inicializar fixtures, recopilar logs redactados, validar un manifiesto o crear un informe. Pide argumentos explícitos y devuelve códigos de salida útiles. No entierres decisiones de arquitectura, despliegues irreversibles o prompts opacos dentro de un helper.&lt;/p&gt;

&lt;p&gt;Haz que el script sea seguro ante reintentos. Comprueba precondiciones, usa rutas relativas al repositorio, no imprimas secretos y ofrece &lt;code&gt;--dry-run&lt;/code&gt; antes de mutar un recurso externo. Si una skill necesita una base de datos o cloud, separa la fase de observación de la fase de escritura y deja claro qué aprobación hace falta para cada una.&lt;/p&gt;

&lt;p&gt;Un buen contrato de script expresa entrada, salida y fallo: &lt;code&gt;collect_failure.py --test tests/api/test_auth.py&lt;/code&gt; puede guardar un artefacto local redactado; no debería llamar a producción porque el nombre del test se parece a un incidente. La capacidad reutilizable debe reducir el radio de explosión, no hacerlo más cómodo.&lt;/p&gt;
&lt;h3&gt;
  
  
  Validación antes de convertirlo en plugin
&lt;/h3&gt;

&lt;p&gt;Prueba la skill en tres casos: el caso feliz, un input incompleto y un repositorio con cambios locales. El caso incompleto debe detenerse con una pregunta concreta; el repositorio sucio debe preservar el trabajo ajeno. Si el procedimiento no tiene una salida segura en esos dos casos, aún no merece automatizarse ni distribuirse.&lt;/p&gt;

&lt;p&gt;Mantén una prueba rápida junto a la skill cuando sea viable: valida el frontmatter, comprueba que las rutas referenciadas existen y ejecuta el helper en modo seco. Para un workflow de código, la evidencia mínima incluye el comando ejecutado, código de salida, diff revisable y test de regresión. 'El agente dijo que funciona' no es una verificación.&lt;/p&gt;

&lt;p&gt;No evalúes una skill por lo largo que parece el resultado. Evalúala por reducción de retrabajo: menos instrucciones repetidas, menos cambios fuera de alcance, menos intentos fallidos y una revisión humana más rápida. Si sube la velocidad pero nadie entiende qué hizo, has trasladado el coste al reviewer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  De skill local a plugin distribuible
&lt;/h2&gt;

&lt;p&gt;Mantén la skill local mientras el workflow sigue cambiando cada semana. Cuando ya tiene activación estable, validación repetible y usuarios fuera del repositorio, un plugin es la capa de distribución: puede agrupar skills, conectores, MCP, hooks o plantillas de tareas programadas según la documentación de OpenAI.&lt;/p&gt;

&lt;p&gt;Distribuir no elimina el threat model. Revisa especialmente hooks, conectores y servidores MCP: pueden introducir ejecución o acceso a sistemas externos. Un plugin debe declarar dependencias y guiar el setup, pero no pedir permisos amplios 'para que funcione'. El usuario debe poder instalar la parte de lectura sin conceder la parte mutante.&lt;/p&gt;

&lt;p&gt;No migres a ciegas desde catálogos antiguos. El repositorio &lt;code&gt;openai/skills&lt;/code&gt; indica que ahora dirige los ejemplos actuales al repositorio de plugins y a la guía de Build plugins. Usa la documentación actual como fuente de empaquetado y conserva tests de la skill antes de cambiar el canal de distribución.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errores que convierten una skill en deuda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Descripción genérica que se activa para tareas incompatibles.&lt;/li&gt;
&lt;li&gt;Duplicar AGENTS.md y terminar con políticas distintas en cada skill.&lt;/li&gt;
&lt;li&gt;Meter documentación extensa en SKILL.md y agotar el contexto antes de mirar el repositorio.&lt;/li&gt;
&lt;li&gt;Llamar a scripts con secretos implícitos, rutas absolutas o efectos externos no anunciados.&lt;/li&gt;
&lt;li&gt;Confundir metadata de plugin con una barrera de permisos.&lt;/li&gt;
&lt;li&gt;No definir condición de parada cuando faltan datos, permisos o un comando de reproducción.&lt;/li&gt;
&lt;li&gt;Distribuir el workflow antes de haber probado éxito, fallo seguro y repositorio sucio.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Checklist de publicación interna
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;El nombre es estable y la descripción expresa tarea, activadores y límites.&lt;/li&gt;
&lt;li&gt;SKILL.md contiene entrada, salida, pasos verificables y condición de parada.&lt;/li&gt;
&lt;li&gt;Las reglas globales permanecen en AGENTS.md y no se copian sin motivo.&lt;/li&gt;
&lt;li&gt;Las referencias grandes se cargan solo cuando una rama del workflow las necesita.&lt;/li&gt;
&lt;li&gt;Los scripts aceptan argumentos, no exponen secretos y separan dry-run de escritura.&lt;/li&gt;
&lt;li&gt;La skill preserva cambios ajenos y declara qué no puede hacer.&lt;/li&gt;
&lt;li&gt;Existe una prueba del caso feliz, del input incompleto y del árbol de trabajo sucio.&lt;/li&gt;
&lt;li&gt;Una persona puede revisar comando, diff y resultado sin confiar en una narración del agente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es una Codex Skill?
&lt;/h3&gt;

&lt;p&gt;Es un paquete local de instrucciones para un workflow concreto. Incluye como mínimo un directorio y &lt;code&gt;SKILL.md&lt;/code&gt;; puede incluir scripts, referencias y assets si aportan una capacidad que no conviene reescribir en cada tarea.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Una skill sustituye a AGENTS.md?
&lt;/h3&gt;

&lt;p&gt;No. &lt;code&gt;AGENTS.md&lt;/code&gt; gobierna el repositorio y sus reglas duraderas; una skill describe un procedimiento especializado. Usa ambos para que las reglas globales no se dupliquen ni entren en conflicto.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Las skills otorgan permisos al agente?
&lt;/h3&gt;

&lt;p&gt;No. La sandbox, las aprobaciones, las credenciales y los controles del host siguen aplicando. Una skill no debe presentarse como una excepción de seguridad.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuándo debo añadir un script?
&lt;/h3&gt;

&lt;p&gt;Cuando un paso sea mecánico, repetible y verificable. Si encapsula una decisión de producto, un despliegue irreversible o una acción externa amplia, conserva esa decisión fuera del helper y exige aprobación.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuándo convierto una skill en plugin?
&lt;/h3&gt;

&lt;p&gt;Cuando el workflow ya es estable, tiene validación y necesita instalarse o compartirse entre varios proyectos o equipos. Empieza local: distribuir demasiado pronto fija una mala interfaz.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Puedo usar la misma skill en Claude Code y Codex?
&lt;/h3&gt;

&lt;p&gt;El formato &lt;code&gt;SKILL.md&lt;/code&gt; pertenece al estándar abierto de Agent Skills, pero la disponibilidad, rutas, metadata y capacidades del host pueden diferir. Verifica el comportamiento y permisos en cada entorno antes de declararla portátil.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo crear una Codex Skill reutilizable y verificable
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Elegir una tarea repetida.&lt;/strong&gt; Selecciona un workflow con entrada, salida y evidencia claras; evita procedimientos que aún dependen de decisiones de arquitectura abiertas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escribir el selector.&lt;/strong&gt; Crea nombre y descripción que expliquen cuándo usar la skill y cuándo no, para impedir activaciones genéricas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Definir el contrato.&lt;/strong&gt; En SKILL.md fija pasos, límites, condición de parada y comando de validación; deja AGENTS.md para reglas globales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separar el detalle.&lt;/strong&gt; Mueve documentación grande a references y operaciones mecánicas a scripts con argumentos explícitos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aislar efectos.&lt;/strong&gt; Añade comprobaciones, dry-run y aprobación para operaciones externas; nunca conviertas la skill en un atajo de permisos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Probar fallos seguros.&lt;/strong&gt; Ejecuta caso feliz, input incompleto y repositorio con cambios locales; conserva evidencia reproducible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medir utilidad.&lt;/strong&gt; Revisa si reduce reintentos, cambios fuera de alcance y tiempo de revisión, no solo si genera más texto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distribuir después.&lt;/strong&gt; Empaqueta como plugin únicamente cuando activación, dependencias y validación estén estables y documentadas.
&amp;gt; ### Límite sano
&amp;gt;
&amp;gt; Paraleliza investigación y tareas acotadas. No paralelices criterio técnico ni integración final.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/skills" rel="noopener noreferrer"&gt;OpenAI Codex: crear skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/plugins" rel="noopener noreferrer"&gt;OpenAI Codex: plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/plugins/build/plugins" rel="noopener noreferrer"&gt;OpenAI: construir y distribuir plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.chatgpt.com/docs/extend/record-and-replay" rel="noopener noreferrer"&gt;OpenAI: Record &amp;amp; Replay para workflows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/openai/skills" rel="noopener noreferrer"&gt;OpenAI Skills: catálogo y migración a plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agentskills.io/specification" rel="noopener noreferrer"&gt;Agent Skills: especificación abierta&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/codex-cli-configuracion-agents-md-permisos/" rel="noopener noreferrer"&gt;Codex CLI: configuración, AGENTS.md y permisos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/claude-code-skills-skill-md-agentes/" rel="noopener noreferrer"&gt;Claude Code Skills: cómo escribir SKILL.md útiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/agents-md-claude-md-memoria-proyecto/" rel="noopener noreferrer"&gt;AGENTS.md y memoria de proyecto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-inspector-testing-servidores/" rel="noopener noreferrer"&gt;MCP Inspector: testing y depuración de servidores&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/git-worktree-agentes-ia-paralelo/" rel="noopener noreferrer"&gt;Git worktree para agentes de IA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>codex</category>
    </item>
    <item>
      <title>Copilot Spaces: cómo crear capas de contexto sin meter todo el repositorio en cada prompt</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Fri, 28 Aug 2026 09:08:34 +0000</pubDate>
      <link>https://dev.to/khavel/copilot-spaces-como-crear-capas-de-contexto-sin-meter-todo-el-repositorio-en-cada-prompt-4nl9</link>
      <guid>https://dev.to/khavel/copilot-spaces-como-crear-capas-de-contexto-sin-meter-todo-el-repositorio-en-cada-prompt-4nl9</guid>
      <description>&lt;p&gt;Copilot Spaces no va de guardar chats bonitos. Va de crear una capa de contexto curada para una misión concreta. La diferencia entre buen contexto y contexto infinito es lo que separa a un agente útil de un asistente caro y confundido.&lt;/p&gt;

&lt;p&gt;Copilot Spaces es una forma de agrupar contexto para Copilot Chat: repositorios, archivos, carpetas, issues, pull requests, notas, texto libre, imágenes y uploads, de manera que las respuestas se anclen en evidencia relevante para una tarea.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;Copilot Spaces&lt;/code&gt;; la intención de búsqueda en español es aprender a usar Spaces junto a instrucciones, MCP, Memory y content exclusion para construir capas de contexto útiles sin sobrecargar al agente.&lt;/p&gt;

&lt;p&gt;Mi postura: Spaces debe ser la capa de misión, no el vertedero de todo el conocimiento del equipo. Si metes medio monorepo, todos los issues y notas antiguas, el problema deja de ser falta de contexto y pasa a ser exceso de ruido.&lt;/p&gt;
&lt;h3&gt;
  
  
  El error: pensar que más contexto siempre mejora al agente
&lt;/h3&gt;

&lt;p&gt;Una definición citable: Copilot Spaces es una colección curada de contexto que Copilot puede usar para responder preguntas sobre una tarea, área de producto o sistema concreto, y que puede compartirse con otras personas para alinear conocimiento técnico.&lt;/p&gt;

&lt;p&gt;La intuición rápida dice: si el agente falla por falta de contexto, añadamos más. Esa intuición rompe rápido. Más contexto también significa más ambigüedad, más tokens, más material obsoleto, más riesgo de filtrar datos sensibles y más posibilidades de que el modelo preste atención a lo incorrecto.&lt;/p&gt;

&lt;p&gt;El objetivo no es que Copilot vea todo. El objetivo es que vea lo suficiente, en la capa correcta, con una frontera clara entre evidencia, reglas, herramientas y memoria.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Si quieres seguir Copilot Spaces, Agent Finder, MCP, memoria e instrucciones de agentes sin perseguir documentación dispersa, DevAI Semanal te lo resume cada semana en un email de 5 minutos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  La arquitectura mental: cinco capas de contexto
&lt;/h3&gt;

&lt;p&gt;Yo separaría el contexto de Copilot en cinco capas. No porque GitHub lo venda así, sino porque operativamente evita mezclar cosas que cambian a ritmos distintos.&lt;/p&gt;

&lt;p&gt;Capa 1: política y exclusión. Lo que nunca debe entrar al modelo: secretos, datos regulados, rutas sensibles, repos que no deberían informar respuestas y archivos excluidos por configuración.&lt;/p&gt;

&lt;p&gt;Capa 2: instrucciones estables. Cómo trabaja el repo: convenciones, comandos, estilo, testing, arquitectura, ownership y reglas que aplican casi siempre.&lt;/p&gt;

&lt;p&gt;Capa 3: Space de misión. Evidencia concreta para una tarea: archivos, carpetas, issues, PRs, notas, transcripciones, imágenes o documentos necesarios para entender un cambio.&lt;/p&gt;

&lt;p&gt;Capa 4: herramientas vivas. Contexto que no conviene congelar en un Space porque cambia: GitHub MCP, toolsets, issues activos, PRs, datos externos y sistemas internos.&lt;/p&gt;

&lt;p&gt;Capa 5: memoria. Preferencias y convenciones que Copilot aprende o conserva con el tiempo, y que debes revisar porque una memoria antigua puede convertirse en una regla falsa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fren02d7ztvyfc2u5fpyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fren02d7ztvyfc2u5fpyi.png" alt="Diagrama de cinco capas de contexto para Copilot: exclusión, instrucciones estables, Copilot Spaces, herramientas MCP y memoria" width="799" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una arquitectura práctica: lo permanente vive en instrucciones, lo específico de una misión vive en un Space, lo dinámico entra por MCP y lo sensible se excluye antes de empezar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dónde encaja Copilot Spaces
&lt;/h2&gt;

&lt;p&gt;Spaces encaja en la tercera capa: contexto de misión. Un Space debería responder a una pregunta concreta: qué necesita saber Copilot para razonar sobre este módulo, esta migración, este bug, este rediseño o esta decisión técnica.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;La documentación de GitHub indica que un Space puede incluir repositorios, código, pull requests, issues, texto libre como notas o transcripciones, imágenes y archivos subidos. También puede compartirse con el equipo o hacerse público según el caso.&lt;/p&gt;

&lt;p&gt;La parte clave es que Copilot no usa necesariamente todo el contenido del Space en cada respuesta. Lo usa como base recuperable. Por eso añadir fuentes muy relevantes suele funcionar mejor que adjuntar un repo entero por costumbre.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Qué pondría dentro de un Space
&lt;/h3&gt;

&lt;p&gt;Para una feature nueva: el issue de producto, el ADR o spec, los archivos del área afectada, el contrato de API, dos PRs recientes buenos y una nota breve con restricciones no obvias.&lt;/p&gt;

&lt;p&gt;Para onboarding de un módulo: README, diagrama de arquitectura, carpeta principal, tests representativos, issues cerrados que explican decisiones, y una nota con vocabulario del dominio.&lt;/p&gt;

&lt;p&gt;Para depurar un bug: issue original, logs saneados, pasos de reproducción, archivos sospechosos, test fallido, PR que introdujo el cambio y capturas o imágenes si el bug es visual.&lt;/p&gt;

&lt;p&gt;Para una migración: guía oficial, lista de breaking changes, wrappers internos, ejemplos actuales, decisiones de compatibilidad y un checklist de rollout.&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué no pondría dentro de un Space
&lt;/h3&gt;

&lt;p&gt;No pondría secretos, dumps, datos reales de clientes, tickets con PII, logs sin limpiar ni configuraciones internas que el agente no necesita para razonar.&lt;/p&gt;

&lt;p&gt;Tampoco pondría todo el monorepo si la tarea toca tres carpetas. La opción de incluir repositorios completos es útil para exploración, pero no debería ser el patrón por defecto en tareas de precisión.&lt;/p&gt;

&lt;p&gt;Y no pondría documentación obsoleta para que &lt;code&gt;quizá ayude&lt;/code&gt;. En un Space, lo viejo compite con lo correcto. Si quieres conservar historia, etiquétala como historia y explica por qué no debe guiar la implementación actual.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Instrucciones estables: el contexto que no debería vivir en Spaces
&lt;/h2&gt;

&lt;p&gt;Las instrucciones de repositorio, como &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;, son mejores para reglas permanentes: cómo ejecutar tests, estilo de código, frameworks, estructura de carpetas, convenciones de commits, restricciones de seguridad y criterios de revisión.&lt;/p&gt;

&lt;p&gt;GitHub también documenta soporte variable por superficie para instrucciones de repo, instrucciones por ruta y archivos de agente como &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;CLAUDE.md&lt;/code&gt; o &lt;code&gt;GEMINI.md&lt;/code&gt;. Eso importa porque no todas las experiencias de Copilot cargan las mismas capas igual.&lt;/p&gt;

&lt;p&gt;Regla práctica: si una frase debería aplicarse a casi todas las interacciones del repo, no la escondas en un Space. Ponla en instrucciones versionadas. Si solo aplica a una iniciativa concreta, ahí sí tiene sentido el Space.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path-specific instructions: contexto por zona del repo
&lt;/h3&gt;

&lt;p&gt;En repos grandes, una instrucción global tiende a volverse genérica. Las instrucciones por ruta permiten decir: en &lt;code&gt;api/&lt;/code&gt; usamos contratos OpenAPI; en &lt;code&gt;frontend/&lt;/code&gt; usamos accesibilidad y snapshots visuales; en &lt;code&gt;infra/&lt;/code&gt; no se cambian permisos sin plan de rollback.&lt;/p&gt;

&lt;p&gt;Esta capa reduce el tamaño mental del problema. Copilot no necesita una biblia de todo el sistema para tocar un endpoint. Necesita las reglas de esa zona y la evidencia de la tarea.&lt;/p&gt;

&lt;p&gt;La combinación buena es: instrucciones globales cortas, instrucciones por ruta concretas y Spaces para misiones que cruzan varias zonas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  MCP: contexto vivo, no documentación congelada
&lt;/h3&gt;

&lt;p&gt;MCP sirve para conectar Copilot con herramientas y sistemas externos. GitHub lo presenta como una forma de extender Copilot con servicios existentes en IDEs, CLI, la app y agentes en GitHub.com.&lt;/p&gt;

&lt;p&gt;Esto no compite con Spaces. Lo complementa. Un Space puede contener la explicación de la migración; MCP puede consultar el issue vivo, listar PRs, ver metadata del repo o interactuar con herramientas autorizadas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La frontera sana: si el dato cambia cada minuto, no lo copies al Space. Conéctalo por una herramienta con permisos mínimos. Si el dato es evidencia estable para la tarea, inclúyelo en el Space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copilot Memory: útil, pero con caducidad mental
&lt;/h2&gt;

&lt;p&gt;Copilot Memory permite conservar convenciones, preferencias y detalles aprendidos de interacciones. Bien usado, evita repetir cada vez que prefieres cierto estilo de test o patrón de arquitectura.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;El riesgo es convertir memoria en dogma. Una preferencia personal puede no aplicar al repo. Una convención puede cambiar. Una decisión temporal puede quedarse pegada a respuestas futuras.&lt;/p&gt;

&lt;p&gt;Yo revisaría Memory como revisas dependencias: de vez en cuando, con intención. Lo que aplica al repo debería estar versionado en instrucciones. Lo personal puede vivir en memoria, pero no debería contradecir al proyecto.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Content exclusion: la primera capa, no el último parche
&lt;/h3&gt;

&lt;p&gt;Content exclusion permite configurar archivos y rutas que Copilot debe ignorar. Según GitHub, el contenido excluido no informa sugerencias inline, respuestas de Chat ni revisiones de código afectadas.&lt;/p&gt;

&lt;p&gt;No lo trates como un ajuste de privacidad al final. Es la primera capa de arquitectura de contexto. Antes de construir Spaces, instrucciones o MCP, decide qué no debe entrar nunca.&lt;/p&gt;

&lt;p&gt;Ejemplos: &lt;code&gt;.env&lt;/code&gt;, fixtures con datos reales, exports de clientes, claves, dumps, modelos propietarios, contratos bajo NDA o cualquier carpeta donde una respuesta útil no compensa el riesgo.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cómo diseñar un Space bueno
&lt;/h3&gt;

&lt;p&gt;Nómbralo por misión, no por herramienta: &lt;code&gt;checkout-refactor-q3&lt;/code&gt;, &lt;code&gt;onboarding-billing-service&lt;/code&gt;, &lt;code&gt;incident-postmortem-payments&lt;/code&gt;, &lt;code&gt;migration-react-compiler&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Añade una nota inicial con tres cosas: objetivo, límites y definición de terminado. Sin esa nota, el Space puede tener documentos buenos pero carecer de intención.&lt;/p&gt;

&lt;p&gt;Incluye evidencia mínima suficiente: cinco archivos buenos valen más que quinientos archivos indiferentes. Añade el issue o PR que motivó la tarea, no toda la historia del proyecto.&lt;/p&gt;

&lt;p&gt;Cierra el Space cuando la misión termine o archívalo con una nota de resultado. Un Space abandonado se convierte en contexto fósil.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Checklist de capas de contexto
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Excluye primero rutas sensibles o irrelevantes.&lt;/li&gt;
&lt;li&gt;Mantén &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; corto y estable.&lt;/li&gt;
&lt;li&gt;Usa instrucciones por ruta para reglas específicas de carpetas.&lt;/li&gt;
&lt;li&gt;Crea Spaces por misión, feature, bug, migración o onboarding.&lt;/li&gt;
&lt;li&gt;Añade al Space archivos concretos antes que repos completos.&lt;/li&gt;
&lt;li&gt;Incluye issues y PRs solo si explican decisiones vigentes.&lt;/li&gt;
&lt;li&gt;Usa MCP para información viva o acciones, no para reemplazar documentación.&lt;/li&gt;
&lt;li&gt;Revisa Copilot Memory para evitar preferencias obsoletas.&lt;/li&gt;
&lt;li&gt;Mide si el Space reduce preguntas repetidas y cambios fuera de alcance.&lt;/li&gt;
&lt;li&gt;Elimina contexto que no haya cambiado ninguna respuesta.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Errores que evitaría
&lt;/h3&gt;

&lt;p&gt;El primero es crear un Space por equipo y meterlo todo. Eso se convierte en wiki desordenada, no en contexto operativo.&lt;/p&gt;

&lt;p&gt;El segundo es duplicar reglas en todos los sitios: instrucciones, Space, Memory y prompt. Cuando una regla cambia, no sabrás cuál manda.&lt;/p&gt;

&lt;p&gt;El tercero es tratar issues antiguos como verdad. Un issue cerrado puede explicar una decisión, pero también puede estar obsoleto. Añade notas que distingan evidencia histórica de regla vigente.&lt;/p&gt;

&lt;p&gt;El cuarto es usar MCP con permisos amplios para compensar Spaces pobres. Las herramientas vivas necesitan menos permisos, no más confianza.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementación recomendada para un equipo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Semana 1: crea instrucciones globales mínimas y content exclusion para rutas sensibles.&lt;/li&gt;
&lt;li&gt;Semana 2: define tres plantillas de Space: feature, bug y migración. Cada plantilla debe pedir objetivo, límites, archivos clave, issues/PRs y definición de terminado.&lt;/li&gt;
&lt;li&gt;Semana 3: añade instrucciones por ruta para dos zonas críticas del repo y conecta MCP solo en modo lectura si aporta información viva.&lt;/li&gt;
&lt;li&gt;Semana 4: revisa sesiones reales. Qué contexto sobró, qué faltó, qué respuestas fueron mejores y qué archivos se repitieron en varios Spaces.&lt;/li&gt;
&lt;li&gt;Después: convierte conocimiento repetido en instrucciones versionadas. Deja en Spaces solo lo que pertenece a una misión concreta.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Copilot Spaces es más interesante como disciplina de contexto que como feature de organización. Obliga a decidir qué evidencia necesita una tarea y qué debe quedar fuera.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;La arquitectura ganadora no es un Space enorme. Es una pila: exclusión para lo sensible, instrucciones para lo estable, Spaces para misiones, MCP para datos vivos y Memory para preferencias revisables. Si separas esas capas, Copilot responde mejor y tu equipo puede auditar por qué el agente sabía lo que sabía.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es Copilot Spaces?
&lt;/h3&gt;

&lt;p&gt;Copilot Spaces es una forma de organizar contexto para GitHub Copilot usando repositorios, archivos, issues, PRs, notas, imágenes y uploads relevantes para una tarea o área.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Copilot usa todo lo que pongo en un Space?
&lt;/h3&gt;

&lt;p&gt;No necesariamente. GitHub indica que Copilot usa contexto relevante del Space para responder, por eso conviene añadir fuentes muy seleccionadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿En qué se diferencia un Space de &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Las instrucciones son reglas persistentes del repo; un Space es contexto curado para una misión, feature, bug o área concreta.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuándo uso MCP en vez de un Space?
&lt;/h3&gt;

&lt;p&gt;Usa MCP cuando el dato cambia o requiere interacción con sistemas vivos. Usa un Space para evidencia estable que quieres que Copilot tenga presente.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Copilot Memory reemplaza a las instrucciones?
&lt;/h3&gt;

&lt;p&gt;No. Memory sirve para preferencias y convenciones aprendidas, pero las reglas de proyecto deberían vivir en archivos versionados.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué debería excluir antes de crear Spaces?
&lt;/h3&gt;

&lt;p&gt;Secretos, datos reales de clientes, dumps, fixtures sensibles, archivos bajo NDA y cualquier ruta que no deba informar respuestas ni revisiones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Límite sano
&lt;/h3&gt;

&lt;p&gt;Paraleliza investigación y tareas acotadas. No paralelices criterio técnico ni integración final.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/concepts/context/spaces" rel="noopener noreferrer"&gt;GitHub Docs: About GitHub Copilot Spaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/provide-context/use-copilot-spaces/use-copilot-spaces" rel="noopener noreferrer"&gt;GitHub Docs: Using GitHub Copilot Spaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/tutorials/speed-up-development-work" rel="noopener noreferrer"&gt;GitHub Docs: Speeding up development work with GitHub Copilot Spaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/provide-context" rel="noopener noreferrer"&gt;GitHub Docs: Provide context to GitHub Copilot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/configure-custom-instructions-in-your-ide/add-repository-instructions-in-your-ide" rel="noopener noreferrer"&gt;GitHub Docs: Adding repository custom instructions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/reference/custom-instructions-support" rel="noopener noreferrer"&gt;GitHub Docs: Custom instructions support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/concepts/context/mcp" rel="noopener noreferrer"&gt;GitHub Docs: About Model Context Protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/concepts/context/content-exclusion" rel="noopener noreferrer"&gt;GitHub Docs: Content exclusion for Copilot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/use-copilot-agents/copilot-memory/manage-for-yourself" rel="noopener noreferrer"&gt;GitHub Docs: Managing Copilot Memory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/agents-md-claude-md-memoria-proyecto/" rel="noopener noreferrer"&gt;AGENTS.md, CLAUDE.md y memoria de proyecto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/github-agent-finder-ard-copilot/" rel="noopener noreferrer"&gt;GitHub Agent Finder y ARD para Copilot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/copilot-coding-agent-mcp-hooks-produccion/" rel="noopener noreferrer"&gt;Copilot coding agent en producción&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-produccion-seguridad-permisos-supply-chain/" rel="noopener noreferrer"&gt;MCP en producción: seguridad y permisos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/rtk-proxy-cli-reducir-tokens-ia/" rel="noopener noreferrer"&gt;RTK: reducir tokens en agentes de IA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>Git worktree para agentes de IA: trabajo paralelo sin pisar tu repositorio</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Thu, 27 Aug 2026 09:08:43 +0000</pubDate>
      <link>https://dev.to/khavel/git-worktree-para-agentes-de-ia-trabajo-paralelo-sin-pisar-tu-repositorio-347a</link>
      <guid>https://dev.to/khavel/git-worktree-para-agentes-de-ia-trabajo-paralelo-sin-pisar-tu-repositorio-347a</guid>
      <description>&lt;p&gt;&lt;code&gt;git worktree&lt;/code&gt; permite tener varios directorios de trabajo conectados al mismo repositorio, cada uno con su &lt;code&gt;HEAD&lt;/code&gt; e índice. La keyword principal es &lt;code&gt;git worktree agentes IA&lt;/code&gt;; la intención es práctica: un developer quiere ejecutar tareas de agentes en paralelo sin que compartan el árbol de archivos que están editando.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Un worktree es aislamiento de checkout, no aislamiento de ejecución. Evita que un agente borre el build de otro o cambie su lockfile a mitad de una prueba; no separa credenciales, procesos que escuchan en el mismo puerto, recursos cloud, cachés globales ni la decisión de mergear.&lt;/p&gt;

&lt;p&gt;Mi postura: asigna un worktree por cambio pequeño y verificable, no uno por cada pensamiento del modelo. Paraleliza investigación, documentación, tests o módulos con fronteras claras; integra de uno en uno con CI y revisión humana. Si dos tareas necesitan tocar la misma abstracción, el cuello de botella no es Git: es una decisión de diseño que nadie ha tomado todavía.&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué aísla realmente un Git worktree
&lt;/h3&gt;

&lt;p&gt;Un repositorio puede tener un worktree principal y varios worktrees enlazados. Git comparte el almacén de objetos y la mayoría de las refs, pero cada checkout enlazado tiene su propio &lt;code&gt;HEAD&lt;/code&gt;, índice y directorio de trabajo. Por eso dos agentes pueden partir del mismo commit y modificar archivos distintos sin sobrescribir el disco del otro.&lt;/p&gt;

&lt;p&gt;Git protege una frontera importante: normalmente rechaza que la misma rama esté checkout en dos worktrees. No fuerces ese bloqueo con &lt;code&gt;--force&lt;/code&gt; para 'hacerlo funcionar'. Si dos agentes trabajan sobre la misma rama, has recuperado el problema original con una topología más difícil de depurar.&lt;/p&gt;

&lt;p&gt;La frase útil para documentar en tu repositorio es: un worktree representa una tarea y una rama; un agente representa un ejecutor temporal de esa tarea. La rama sobrevive a la conversación, el worktree puede desecharse después de que el cambio esté validado y fusionado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi3q3bcyua4wlcb6j4cue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi3q3bcyua4wlcb6j4cue.png" alt="Flujo desde un repositorio Git limpio hacia tres worktrees aislados para agentes, con validación de tests y diff antes de una cola de revisión y merge" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los worktrees separan archivos, índice y rama de cada tarea; la integración vuelve a ser una cola única con pruebas y revisión.&lt;/p&gt;

&lt;h3&gt;
  
  
  La unidad correcta de paralelismo
&lt;/h3&gt;

&lt;p&gt;No distribuyas una petición como 'mejora la autenticación' entre cuatro agentes. Divide por contrato comprobable: uno añade una validación de entrada, otro actualiza documentación y ejemplos, otro escribe tests de regresión. Cada tarea debe tener rutas permitidas, una salida observable y un comando de validación que no dependa de adivinar la intención del otro agente.&lt;/p&gt;

&lt;p&gt;Evita el paralelismo si varias tareas tocan la misma migración, interfaz pública, lockfile o selector central. También evítalo si todas requieren el mismo entorno mutable: un emulador con un puerto fijo, una base de datos de desarrollo compartida o una cuenta de pruebas que no resetea el estado. Un worktree no convierte esos recursos en seguros para concurrencia.&lt;/p&gt;

&lt;p&gt;Empieza por dos worktrees. Si la integración termina generando conflictos repetidos, baja el paralelismo y mejora la división de tareas. Más agentes no arreglan límites de módulo mal definidos; solo generan más diffs que una persona tendrá que entender.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Crear un worktree por rama de agente
&lt;/h3&gt;

&lt;p&gt;Parte de una referencia explícita y actualizada. Nombrar rama y directorio hace que la intención sea auditable y reduce el riesgo de que un agente trabaje contra un &lt;code&gt;HEAD&lt;/code&gt; local olvidado. La opción &lt;code&gt;-b&lt;/code&gt; falla si la rama ya existe, que es una protección útil para una automatización que se reintenta.&lt;/p&gt;

&lt;p&gt;terminal&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git fetch origin
git worktree add -b agent/authz-input ../miapp-agent-authz origin/main
git worktree add -b agent/docs-authz ../miapp-agent-docs origin/main
git worktree list --porcelain
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;No uses el nombre del modelo como rama (&lt;code&gt;claude-fix&lt;/code&gt;, &lt;code&gt;codex-fix&lt;/code&gt;). Usa el resultado técnico (&lt;code&gt;agent/authz-input&lt;/code&gt;) y guarda en la tarea quién la ejecutó, el prompt o issue, el commit base y el comando de verificación. Así puedes cambiar de herramienta sin perder trazabilidad ni convertir el historial Git en marketing involuntario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contexto y configuración: lo que viaja y lo que no
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los archivos versionados viajan con la rama: &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;README&lt;/code&gt;, scripts de bootstrap, linters y fixtures deberían estar ahí. Codex compone sus instrucciones desde el root del proyecto hasta el directorio actual; por tanto, un &lt;code&gt;AGENTS.md&lt;/code&gt; comprometido es una forma reproducible de dar a cada worktree los mismos límites, comandos y rutas sensibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;Los archivos no versionados no aparecen por magia. &lt;code&gt;.env&lt;/code&gt;, claves SSH, credenciales de cloud, bases SQLite locales y caches deben ser creados por un bootstrap explícito de desarrollo, preferiblemente con datos de prueba y privilegios mínimos. Copiar el &lt;code&gt;.env&lt;/code&gt; de producción a cada worktree es una comodidad que transforma una mejora de productividad en una multiplicación de secretos.&lt;/p&gt;

&lt;p&gt;La configuración de Git es compartida por defecto. Si un worktree necesita &lt;code&gt;sparse-checkout&lt;/code&gt;, hooks o una opción local distinta, activa &lt;code&gt;extensions.worktreeConfig&lt;/code&gt; y escribe con &lt;code&gt;git config --worktree&lt;/code&gt;. No pongas una configuración de una tarea en el config común: terminará sorprendiendo al siguiente agente que use el repositorio.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Recorta el checkout sin contaminar a los demás
&lt;/h3&gt;

&lt;p&gt;En monorepos grandes, un agente que cambia un paquete no necesita indexar todo el producto. &lt;code&gt;git sparse-checkout set&lt;/code&gt; configura la selección para el worktree actual y Git actualiza a configuración específica cuando hace falta. Es una optimización de I/O y de contexto, no una frontera de seguridad: el agente puede seguir acceder a otras rutas si le das permisos de sistema amplios.&lt;/p&gt;

&lt;p&gt;desde el worktree del agente&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git sparse-checkout set --cone apps/api packages/auth
git sparse-checkout list
git config --show-origin --get core.sparseCheckout
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Prueba primero con un worktree desechable. Algunas herramientas de generación, IDEs y scripts de release esperan rutas que un checkout disperso no contiene. Si la tarea necesita ejecutar integración end-to-end del monorepo, un checkout completo y un agente menos paralelo suelen ser la decisión más barata.&lt;/p&gt;
&lt;h3&gt;
  
  
  Un contrato operativo antes de arrancar el agente
&lt;/h3&gt;

&lt;p&gt;El prompt debe describir una frontera, no solo un objetivo: rutas que puede modificar, archivos prohibidos, datos de prueba, comandos de setup, tests obligatorios y condición para pedir ayuda. Escríbelo junto al trabajo, no solo en la conversación, para que un reintento o una revisión humana pueda comprobar el mismo contrato.&lt;/p&gt;

&lt;p&gt;Una plantilla mínima: &lt;code&gt;base_sha&lt;/code&gt;, &lt;code&gt;branch&lt;/code&gt;, &lt;code&gt;worktree_path&lt;/code&gt;, &lt;code&gt;allowed_paths&lt;/code&gt;, &lt;code&gt;forbidden_paths&lt;/code&gt;, &lt;code&gt;setup&lt;/code&gt;, &lt;code&gt;verify&lt;/code&gt;, &lt;code&gt;network_policy&lt;/code&gt; y &lt;code&gt;handoff&lt;/code&gt;. El handoff debe incluir resumen, archivos tocados, pruebas ejecutadas, pruebas no ejecutadas y riesgos. Si el agente no puede completar &lt;code&gt;verify&lt;/code&gt;, su resultado es un borrador bloqueado, no un cambio listo para merge.&lt;/p&gt;

&lt;p&gt;Los límites de permisos siguen fuera de Git. Ejecuta tareas de lectura en un sandbox de lectura, separa la red de la escritura de código y solicita aprobación para operaciones que afecten recursos externos. El worktree organiza el checkout; el sandbox y la política controlan lo que el proceso puede hacer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Validar cada worktree antes de mirar el diff
&lt;/h2&gt;

&lt;p&gt;Un diff bonito no demuestra que el agente partió de una base sana. Primero registra la revisión inicial y confirma que no heredó cambios locales. Después ejecuta setup y pruebas en el propio directorio del worktree. Nunca valides desde el worktree principal 'por comodidad': eso abre la puerta a probar una cosa y entregar otra.&lt;/p&gt;

&lt;p&gt;checklist ejecutable por tarea&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git status --porcelain
git rev-parse HEAD
make setup
make test
git diff --check
git diff --stat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Añade pruebas negativas cuando el cambio toca permisos, aislamiento de tenant o acciones mutantes. El caso feliz debe usar fixtures estables; un agente no debe necesitar credenciales de producción para demostrar que una validación de entrada funciona. Conserva logs redactados y el SHA probado como artefactos de la tarea.&lt;/p&gt;

&lt;h3&gt;
  
  
  La integración sigue siendo secuencial
&lt;/h3&gt;

&lt;p&gt;Los worktrees aceleran la exploración, pero no autorizan merges simultáneos sobre una misma rama objetivo. Rebasea o actualiza cada rama contra una referencia reciente, ejecuta la suite que corresponda y revisa el diff con contexto. Fusiona un cambio, vuelve a calcular la base del siguiente y repite. Es menos espectacular que un enjambre, y bastante más fiable.&lt;/p&gt;

&lt;p&gt;En CI, protege despliegues y migraciones con un grupo de concurrencia. GitHub Actions garantiza que solo un job o workflow con la misma clave de concurrencia se ejecuta a la vez; úsalo para impedir que dos pipelines publiquen el mismo entorno o apliquen cambios incompatibles mientras tus agentes trabajan en ramas separadas.&lt;/p&gt;

&lt;p&gt;.github/workflows/deploy.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;concurrency:
  group: deploy-staging
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/deploy-staging.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Limpieza: no borres directorios a ciegas
&lt;/h3&gt;

&lt;p&gt;Después de mergear, usa &lt;code&gt;git worktree remove&lt;/code&gt; sobre un worktree limpio. Git se niega a eliminar un worktree con cambios rastreados o archivos no rastreados salvo que fuerces la operación; esa fricción es una revisión final de bajo coste, no algo que debas automatizar con un &lt;code&gt;rm -rf&lt;/code&gt; genérico.&lt;/p&gt;

&lt;p&gt;Si un directorio se perdió fuera de Git, inspecciona primero &lt;code&gt;git worktree list --verbose&lt;/code&gt; y usa &lt;code&gt;git worktree prune --dry-run&lt;/code&gt; antes de limpiar metadatos obsoletos. &lt;code&gt;prune&lt;/code&gt; arregla registros de worktrees ausentes; no recupera el contenido que alguien eliminó manualmente. Para worktrees en un disco externo o efímero, &lt;code&gt;git worktree lock --reason&lt;/code&gt; evita que Git los considere basura mientras están desconectados.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Evita &lt;code&gt;git clean -xfd&lt;/code&gt; como final automático de una tarea de agente. La documentación de Git confirma que &lt;code&gt;-x&lt;/code&gt; borra también archivos ignorados: ahí suelen vivir &lt;code&gt;.env&lt;/code&gt;, artefactos locales y estado que no podrás reconstruir sin ayuda. Si necesitas limpieza, empieza siempre con &lt;code&gt;git clean -nd&lt;/code&gt; y limita un path concreto que hayas comprobado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist para agentes en paralelo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Crear una rama y un worktree por tarea, ambos con un nombre técnico y una base SHA registrada.&lt;/li&gt;
&lt;li&gt;Dar a cada agente rutas permitidas, rutas prohibidas, setup, tests obligatorios y un handoff verificable.&lt;/li&gt;
&lt;li&gt;Mantener &lt;code&gt;AGENTS.md&lt;/code&gt;, scripts de bootstrap y fixtures versionados; no copiar secretos reales entre worktrees.&lt;/li&gt;
&lt;li&gt;Configurar por worktree sparse-checkout, hooks o ajustes locales que no deban filtrarse al repositorio común.&lt;/li&gt;
&lt;li&gt;Ejecutar setup, tests y &lt;code&gt;git diff --check&lt;/code&gt; dentro del worktree que generó el cambio.&lt;/li&gt;
&lt;li&gt;Serializar merge, migraciones y despliegues aunque la investigación y edición hayan sido paralelas.&lt;/li&gt;
&lt;li&gt;Usar &lt;code&gt;git worktree remove&lt;/code&gt; en árboles limpios y simular cualquier prune o clean antes de borrar algo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es un Git worktree?
&lt;/h3&gt;

&lt;p&gt;Es un checkout adicional enlazado al mismo repositorio. Tiene su propio directorio de trabajo, HEAD e índice, por lo que permite trabajar en ramas distintas al mismo tiempo sin cambiar el checkout principal.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Un worktree permite que dos agentes modifiquen la misma rama?
&lt;/h3&gt;

&lt;p&gt;No es el diseño seguro. Git normalmente impide que una rama esté checkout en dos worktrees; usa una rama por tarea y resuelve la integración mediante commits, rebase, CI y revisión.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Los worktrees comparten node_modules, .env o puertos?
&lt;/h3&gt;

&lt;p&gt;No comparten el directorio de trabajo, pero tampoco aíslan recursos externos. Cada worktree necesita su bootstrap; procesos, caches globales, puertos, bases de datos y credenciales requieren controles propios.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Debo usar sparse-checkout para cada agente?
&lt;/h3&gt;

&lt;p&gt;Solo cuando el monorepo y la tarea lo justifican. Reduce I/O y contexto, pero puede romper scripts que esperan el árbol completo y no es un control de seguridad.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Puedo borrar un worktree con rm -rf?
&lt;/h3&gt;

&lt;p&gt;No como procedimiento normal. Usa git worktree remove cuando esté limpio; si hay inconsistencias, inspecciona y prueba git worktree prune --dry-run antes de tocar metadatos.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Los worktrees sustituyen la revisión humana?
&lt;/h3&gt;

&lt;p&gt;No. Aíslan la edición, pero no validan arquitectura, permisos, pruebas, impacto de migraciones ni calidad del merge. La cola de integración debe seguir teniendo gates explícitos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo ejecutar dos tareas de agentes con Git worktree sin colisiones
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Registrar la base.&lt;/strong&gt; Parte de un commit o rama remota explícita y anota su SHA junto a cada tarea.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dividir el trabajo.&lt;/strong&gt; Define dos cambios con rutas y contratos separados; no paralelices una misma interfaz o migración.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear las ramas.&lt;/strong&gt; Ejecuta git worktree add -b para cada rama y directorio de tarea, sin forzar ramas ya checkout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preparar el entorno.&lt;/strong&gt; Ejecuta el bootstrap del repositorio en cada worktree con fixtures y secretos de desarrollo mínimos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cargar instrucciones.&lt;/strong&gt; Mantén AGENTS.md y los comandos de verify versionados para que cada agente reciba el mismo contexto comprobable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acotar el agente.&lt;/strong&gt; Entrega rutas permitidas, prohibiciones, política de red y condición de handoff antes de que edite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verificar localmente.&lt;/strong&gt; Corre tests, lint y git diff --check desde el worktree que produjo el cambio; guarda SHA y resultados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrar de uno en uno.&lt;/strong&gt; Actualiza la rama objetivo, revisa el diff y CI, mergea un cambio y recalcula la base del siguiente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retirar con seguridad.&lt;/strong&gt; Cuando el árbol esté limpio y el cambio integrado, elimina con git worktree remove; simula prune o clean antes de cualquier limpieza.
&amp;gt; ### Límite sano
&amp;gt;
&amp;gt; Paraleliza investigación y tareas acotadas. No paralelices criterio técnico ni integración final.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-worktree" rel="noopener noreferrer"&gt;Git: documentación oficial de git worktree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-config#Documentation/git-config.txt-extensionsworktreeConfig" rel="noopener noreferrer"&gt;Git: configuración por worktree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-sparse-checkout" rel="noopener noreferrer"&gt;Git: sparse-checkout por worktree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-clean" rel="noopener noreferrer"&gt;Git: limpieza segura de archivos no rastreados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency" rel="noopener noreferrer"&gt;GitHub Actions: grupos de concurrencia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/guides/agents-md" rel="noopener noreferrer"&gt;OpenAI Codex: instrucciones de proyecto con AGENTS.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/coordinar-varios-agentes-codex-claude-cursor/" rel="noopener noreferrer"&gt;Cómo coordinar varios agentes de código&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/codex-cli-configuracion-agents-md-permisos/" rel="noopener noreferrer"&gt;Codex CLI: configuración, AGENTS.md y permisos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/pull-requests-agentes-ia-gobernanza-humana/" rel="noopener noreferrer"&gt;PRs de agentes de IA: gobernanza humana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/claude-code-subagents-contexto-permisos/" rel="noopener noreferrer"&gt;Claude Code: subagentes, contexto y permisos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/hooks-agentes-codigo-guardrails-validacion/" rel="noopener noreferrer"&gt;Hooks para agentes de código: guardrails y validación&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>Microsoft Foundry Agent Service: cómo desplegar agentes con identidad, tools y trazas</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Wed, 26 Aug 2026 09:14:05 +0000</pubDate>
      <link>https://dev.to/khavel/microsoft-foundry-agent-service-como-desplegar-agentes-con-identidad-tools-y-trazas-3p8o</link>
      <guid>https://dev.to/khavel/microsoft-foundry-agent-service-como-desplegar-agentes-con-identidad-tools-y-trazas-3p8o</guid>
      <description>&lt;p&gt;&lt;code&gt;Microsoft Foundry Agent Service&lt;/code&gt; es el runtime gestionado de Microsoft para ejecutar agentes basados en prompts o código. La keyword principal es &lt;code&gt;Microsoft Foundry Agent Service&lt;/code&gt;; la intención es de implementación: un equipo Azure quiere saber cuándo usarlo, cómo dar tools a un agente y qué controles necesita antes de producción.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;La decisión no es entre 'gestionar todo' o 'hacer magia con un prompt'. Foundry puede encargarse del endpoint, escalado, identidad Entra, sesiones, versionado y trazas; tu equipo sigue siendo responsable de la política de acceso, la validación de negocio, los límites de coste y la aprobación de acciones mutantes.&lt;/p&gt;

&lt;p&gt;Mi postura: empieza con un prompt agent si tu workflow cabe en instrucciones y un conjunto estrecho de tools. Elige un hosted agent cuando tu código necesita orquestación propia, protocolos o estado. No empaquetes un microservicio normal como agente solo por subirte al término: si un &lt;code&gt;if&lt;/code&gt; y una API determinista resuelven la tarea, será más barato y comprobable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Qué es y qué no es Agent Service
&lt;/h3&gt;

&lt;p&gt;Un agente combina modelo, instrucciones y tools. En Foundry, la Responses API es el punto de entrada común: permite usar modelos del catálogo y herramientas de plataforma desde un prompt agent, un contenedor propio o un proceso que ya existe. Esa capa no convierte cualquier respuesta en una decisión correcta; organiza el runtime alrededor de ella.&lt;/p&gt;

&lt;p&gt;El servicio actual distingue dos rutas. Un &lt;code&gt;prompt agent&lt;/code&gt; se define por configuración y Foundry ejecuta el runtime; un &lt;code&gt;hosted agent&lt;/code&gt; es tu código —Agent Framework, LangGraph, OpenAI Agents SDK o un runtime propio— empaquetado y ejecutado con endpoint e identidad administrados. No confundas esta generación con los 'Agents (classic)': Microsoft marca el portal y SDK clásicos como deprecados, con retirada anunciada para marzo de 2027.&lt;/p&gt;

&lt;p&gt;La frontera citable es sencilla: Foundry administra cómo se ejecuta y observa un agente; tu producto determina qué puede hacer, contra qué datos y quién responde cuando se equivoca.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fexjihjrruc39xl4a05tj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fexjihjrruc39xl4a05tj.png" alt="Arquitectura de agente gestionado con despliegue, identidad empresarial, Toolbox MCP versionado, trazas y una aprobación humana antes de una acción externa" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Un runtime gestionado reduce trabajo de plataforma; Toolbox, identidad, aprobación y evaluación siguen siendo decisiones de ingeniería explícitas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Prompt agent, hosted agent o tu proceso actual
&lt;/h3&gt;

&lt;p&gt;Usa un prompt agent para un copiloto interno que consulta documentación, resume un expediente o prepara una propuesta sin orquestación de aplicación compleja. La ganancia es operativa: no mantienes contenedor ni servidor. Antes de abrirle una tool de escritura, define scopes, retención, casos de denegación y un modo de revisión humana.&lt;/p&gt;

&lt;p&gt;Usa un hosted agent cuando necesitas código propio, webhooks, una API no compatible con Responses, una máquina de estados, workers, bibliotecas existentes o un protocolo específico. El servicio ejecuta cada sesión en un sandbox aislado y proporciona identidad y endpoint, pero no audita si tu función de Python respeta el tenant. Tu backend debe derivar identidad y permisos de credenciales fiables, no de parámetros que el modelo inventa.&lt;/p&gt;

&lt;p&gt;Mantén tu proceso fuera de Foundry si ya tienes una aplicación sana y solo quieres acceder a modelos o a una tool concreta. Migrar runtime sin una necesidad de escalado, distribución, identidad o estado añade otra superficie de despliegue. La portabilidad razonable es aislar tu lógica de negocio y tratar la integración con Foundry como un adaptador.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Toolbox: centraliza capacidades, no confianza
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Un Toolbox es un paquete versionado de tools que se expone por un endpoint MCP. Sirve para evitar que cada agente tenga su propia copia de URLs, credenciales, allowlists y políticas. Un consumidor puede seguir el &lt;code&gt;default_version&lt;/code&gt; para recibir una versión promovida, mientras un entorno de prueba se conecta a una URL versionada e inmutable antes de aprobarla.&lt;/p&gt;

&lt;p&gt;La ventaja real no es que MCP sea moderno; es que puedes gobernar una colección. Empieza con dos tools de lectura, por ejemplo búsqueda web y documentación interna. Después añade una integración remota, separada por dominio y con una conexión de proyecto. Un Toolbox que mezcla GitHub de escritura, facturación, producción y búsqueda pública es una forma elegante de esconder una política pésima.&lt;/p&gt;

&lt;p&gt;La documentación es explícita con un detalle que muchos omiten: cuando una tool devuelve &lt;code&gt;require_approval: always&lt;/code&gt;, el endpoint MCP no bloquea &lt;code&gt;tools/call&lt;/code&gt;; el runtime debe presentar la acción y esperar confirmación. No declares aprobación en metadata y des por resuelto el control. Prueba que tu interfaz y tu executor lo imponen realmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Un piloto reproducible con Azure Developer CLI
&lt;/h2&gt;

&lt;p&gt;El quickstart oficial permite crear un hosted agent de ejemplo, usar una Toolbox y ejecutarlo localmente antes de desplegar. Este flujo es deliberadamente pequeño: valida el endpoint, el descubrimiento de &lt;code&gt;tools/list&lt;/code&gt; y el comportamiento de una tool de lectura antes de conectar recursos sensibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;PowerShell / terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir foundry-toolbox-pilot
cd foundry-toolbox-pilot
azd ai agent init -m "https://github.com/microsoft-foundry/foundry-samples/blob/main/samples/python/hosted-agents/agent-framework/responses/04-foundry-toolbox/azure.yaml" --src src/toolbox-agent

azd ai toolbox create docs-tools --from-file ./src/toolbox-agent/toolbox.yaml
azd env set TOOLBOX_NAME docs-tools
azd ai agent run

# En otra terminal: comprueba tools y una consulta de solo lectura
azd ai agent invoke --local "Enumera las tools disponibles y no ejecutes ninguna acción mutante."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fija versiones de &lt;code&gt;azd&lt;/code&gt;, la extensión &lt;code&gt;microsoft.foundry&lt;/code&gt;, Python y las dependencias del sample en tu CI. El comando scaffold es una base, no una arquitectura aprobada. Revisa el &lt;code&gt;azure.yaml&lt;/code&gt;, el &lt;code&gt;toolbox.yaml&lt;/code&gt;, las conexiones y cualquier endpoint antes de asociarlo a recursos de empresa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identidad, secretos y aislamiento
&lt;/h3&gt;

&lt;p&gt;Al desplegar un hosted agent, Foundry crea una identidad Entra dedicada para ese agente. Esa identidad puede usar el endpoint del proyecto y el almacenamiento de sesión por defecto; para Storage, Search u otros recursos debes conceder roles específicos. Ese diseño es preferible a copiar una clave de administrador en el contenedor, pero mínimo privilegio sigue significando una asignación por recurso y entorno.&lt;/p&gt;

&lt;p&gt;No guardes API keys ni OAuth tokens dentro de la imagen ni en el repositorio. Foundry permite resolver valores desde project connections al iniciar el sandbox. Para tools MCP, la conexión decide la identidad downstream; separa conexiones de desarrollo y producción y rota las credenciales con el mismo rigor que las de cualquier servicio.&lt;/p&gt;

&lt;p&gt;Las tools externas pueden sacar datos fuera del perímetro de cumplimiento de Foundry. Documenta ese flujo antes de activar un conector: datos enviados, proveedor, región, retención, scopes y respuesta ante un fallo. La red privada y RBAC ayudan, pero no corrigen una tool que devuelve demasiado contexto al modelo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Despliegue, trazas y evaluación
&lt;/h3&gt;

&lt;p&gt;La secuencia sana es build local, prueba de tools y casos negativos, despliegue de una versión, espera a estado activo, canary con identidad de prueba y solo después promoción. Los hosted agents pueden desplegarse como contenedor o desde código fuente empaquetado; elige el primero si ya controlas la imagen y el segundo para un inner loop sencillo, no por comodidad ciega.&lt;/p&gt;

&lt;p&gt;Foundry puede inyectar la conexión de Application Insights y habilitar OpenTelemetry. Eso permite ver latencia, excepciones, llamadas de modelo y dependencias, pero puede incluir contenido personal o de cliente en trazas. Define redacción, muestreo, retención y quién puede leer Application Insights antes de celebrar que ya tienes observabilidad.&lt;/p&gt;

&lt;p&gt;Evalúa tres capas por separado: resultado final (¿la respuesta sirve?), trayectoria (¿eligió la tool permitida?) y ejecución (¿respetó identidad, timeout y coste?). Cada fallo de producción debe convertirse en un caso de dataset antes de cambiar instrucciones o modelo. Sin ese bucle, el versionado solo te deja volver atrás sin saber por qué.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist antes de producción
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Elegir una tarea que justifique autonomía y escribir el contrato de entrada, salida, tools permitidas y acciones prohibidas.&lt;/li&gt;
&lt;li&gt;Crear una Toolbox versionada de bajo riesgo; probar su endpoint versionado y promover a &lt;code&gt;default_version&lt;/code&gt; solo tras revisión.&lt;/li&gt;
&lt;li&gt;Conceder RBAC mínimo a la identidad de agente y usar una conexión distinta por entorno; no meter secretos en código o imagen.&lt;/li&gt;
&lt;li&gt;Forzar confirmación en runtime para tools mutantes y probar una denegación, no solo el camino feliz.&lt;/li&gt;
&lt;li&gt;Trazar sin registrar secretos: decidir qué prompts, outputs y argumentos se redactan, durante cuánto tiempo y quién los consulta.&lt;/li&gt;
&lt;li&gt;Medir éxito, tool calls, errores, latencia, coste y tasa de escalado a humano con un dataset de casos normales, ambiguos y hostiles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es Microsoft Foundry Agent Service?
&lt;/h3&gt;

&lt;p&gt;Es una plataforma gestionada para construir, ejecutar, escalar y observar prompt agents y hosted agents, con modelos, tools, identidad y endpoints de Foundry.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuándo conviene un hosted agent?
&lt;/h3&gt;

&lt;p&gt;Cuando necesitas ejecutar código propio, una orquestación o protocolo personalizado, estado de aplicación o una integración que no cabe en la configuración de un prompt agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Toolbox sustituye a una política de permisos?
&lt;/h3&gt;

&lt;p&gt;No. Centraliza configuración, versiones y credenciales de tools; tu runtime y backend deben imponer scopes, aprobación y reglas de negocio.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Foundry gestiona por sí solo la aprobación humana?
&lt;/h3&gt;

&lt;p&gt;No. La metadata de una tool puede pedir aprobación, pero el runtime que llama la tool debe detener la acción y esperar confirmación.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Puedo usar LangGraph u OpenAI Agents SDK?
&lt;/h3&gt;

&lt;p&gt;Sí. Los hosted agents pueden ejecutar código con esos frameworks; no necesitas reescribir toda la orquestación para usar el runtime gestionado.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Las trazas son privadas por defecto?
&lt;/h3&gt;

&lt;p&gt;Trátalas como datos sensibles. Revisa contenido capturado, permisos de Application Insights, retención y redacción antes de usarlas con tráfico real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo lanzar un piloto seguro con Microsoft Foundry Agent Service
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Escoger una tarea de lectura.&lt;/strong&gt; Empieza con una consulta de documentación o búsqueda interna que no cambie sistemas externos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear un proyecto y modelo.&lt;/strong&gt; Configura un Foundry project y un deployment de modelo compatible en una región soportada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaffold del agente.&lt;/strong&gt; Inicializa el sample oficial con Azure Developer CLI y revisa azure.yaml antes de ejecutar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear Toolbox mínima.&lt;/strong&gt; Añade una o dos tools de solo lectura y guarda la URL de la versión concreta para pruebas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ejecutar localmente.&lt;/strong&gt; Comprueba tools/list, una respuesta útil, timeout y comportamiento ante una tool no permitida.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asignar identidad mínima.&lt;/strong&gt; Da a la identidad del agente solo los roles necesarios para los recursos que realmente consume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configurar trazas seguras.&lt;/strong&gt; Conecta Application Insights, redacta campos sensibles y limita quién puede consultar los spans.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desplegar canary.&lt;/strong&gt; Publica una versión, invócala con una identidad de prueba y compara resultado, trayectoria, latencia y coste con el dataset.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promover con evidencia.&lt;/strong&gt; Cambia el Toolbox o el agente por versiones revisadas y conserva un rollback probado antes de ampliar permisos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/agents/overview" rel="noopener noreferrer"&gt;Microsoft Foundry: Agent Service overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/agents/concepts/hosted-agents" rel="noopener noreferrer"&gt;Microsoft Foundry: hosted agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/deploy-hosted-agent" rel="noopener noreferrer"&gt;Microsoft Foundry: desplegar un hosted agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/agents/concepts/toolbox-overview" rel="noopener noreferrer"&gt;Microsoft Foundry: qué es Toolbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/toolbox" rel="noopener noreferrer"&gt;Microsoft Foundry: crear y gobernar un Toolbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/use-toolbox-hosted-agent" rel="noopener noreferrer"&gt;Microsoft Foundry: usar Toolbox con hosted agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/observability/how-to/trace-agent-setup" rel="noopener noreferrer"&gt;Microsoft Foundry: trazas de agentes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/agents/quickstarts/quickstart-toolbox-agent" rel="noopener noreferrer"&gt;Microsoft Foundry: quickstart Toolbox + hosted agent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/openai-responses-api-function-calling-produccion/" rel="noopener noreferrer"&gt;OpenAI Responses API y function calling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/langgraph-agentes-python-estado-produccion/" rel="noopener noreferrer"&gt;LangGraph: agentes Python con estado&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/opentelemetry-genai-observabilidad-agentes/" rel="noopener noreferrer"&gt;OpenTelemetry GenAI para observabilidad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-produccion-seguridad-permisos-supply-chain/" rel="noopener noreferrer"&gt;MCP en producción: seguridad y permisos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/evaluacion-rag-produccion-metricas-datasets/" rel="noopener noreferrer"&gt;Evaluación RAG en producción&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>MCP Inspector: cómo probar y depurar servidores MCP antes de conectar un agente</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Tue, 25 Aug 2026 09:23:05 +0000</pubDate>
      <link>https://dev.to/khavel/mcp-inspector-como-probar-y-depurar-servidores-mcp-antes-de-conectar-un-agente-1bcf</link>
      <guid>https://dev.to/khavel/mcp-inspector-como-probar-y-depurar-servidores-mcp-antes-de-conectar-un-agente-1bcf</guid>
      <description>&lt;p&gt;MCP Inspector no sustituye tus tests: convierte el protocolo real en una superficie comprobable. Úsalo para detectar tools que no se anuncian, schemas que mienten, transportes incompatibles y permisos que tu suite unitaria no ve.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MCP Inspector&lt;/code&gt; es la herramienta oficial para inspeccionar, probar y depurar un servidor Model Context Protocol (MCP). La keyword principal es &lt;code&gt;MCP Inspector&lt;/code&gt;; la intención es técnica y práctica: un developer quiere comprobar un servidor real antes de entregárselo a Claude Code, Cursor, VS Code o a un agente propio.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Úsalo en dos capas. La interfaz web es útil para descubrir una tool, ver argumentos y reproducir un fallo; el modo CLI es el que debes automatizar para probar &lt;code&gt;tools/list&lt;/code&gt;, llamadas representativas, recursos y prompts en CI. Un host de agente no es una suite de tests: si ese es tu primer cliente, llegarás tarde a los errores de contrato.&lt;/p&gt;

&lt;p&gt;Mi postura: un servidor MCP no está listo porque el Inspector consigue conectar una vez. Está listo cuando su catálogo, sus schemas, sus fallos esperados y sus límites de autorización se comprueban en un entorno sin secretos reales. La conexión feliz es el smoke test, no la definición de calidad.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Qué prueba MCP Inspector y qué no
&lt;/h3&gt;

&lt;p&gt;El Inspector actúa como cliente MCP y ofrece tres superficies: web, CLI y TUI. Puede abrir un proceso local por &lt;code&gt;stdio&lt;/code&gt; o conectar con un endpoint remoto, negociar la versión que corresponda y ejecutar operaciones como listar tools, recursos y prompts o llamar una tool. Eso prueba el protocolo y el empaquetado que verá un host, no solo una función TypeScript aislada.&lt;/p&gt;

&lt;p&gt;No prueba por sí solo tu autorización de negocio, el aislamiento entre tenants, la calidad de la decisión del modelo ni el comportamiento del proveedor que hay detrás. Tampoco convierte una tool mutante en segura. Es la capa de contrato: confirma que el servidor expone exactamente lo que prometes y que falla de forma útil cuando recibe entradas inválidas.&lt;/p&gt;

&lt;p&gt;La diferencia importa desde MCP 2026-07-28. En el flujo moderno se abandona el handshake &lt;code&gt;initialize&lt;/code&gt; y aparece &lt;code&gt;server/discover&lt;/code&gt;; las peticiones llevan metadata por llamada y Streamable HTTP es stateless a nivel de protocolo. Si mantienes tests que asumen sesiones antiguas, pueden pasar contra un fixture legado y fallar con un cliente moderno.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgy8atpylvvocl1l0e7zi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgy8atpylvvocl1l0e7zi.png" alt="Flujo de pruebas MCP desde un servidor local, pasando por Inspector CLI, validación de contrato y casos de seguridad, hasta una puerta de calidad en CI" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El Inspector comprueba la conversación real de protocolo; CI decide si ese resultado cumple el contrato y devuelve el cambio al servidor si no lo cumple.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  El contrato mínimo antes de abrir un host
&lt;/h3&gt;

&lt;p&gt;Escribe primero una tabla de contrato pequeña y revisable. Para cada tool declara nombre, descripción, &lt;code&gt;inputSchema&lt;/code&gt;, campos de salida, efectos, scope requerido, timeout, máximo de elementos y errores recuperables. Si una tool necesita leer tickets del tenant, el &lt;code&gt;tenant_id&lt;/code&gt; debe venir del token o del backend, no de un argumento que el modelo pueda cambiar.&lt;/p&gt;

&lt;p&gt;Haz lo mismo para resources y prompts. Un recurso debe tener URI, MIME type y límites de tamaño que puedas verificar; un prompt debe declarar los argumentos obligatorios y no filtrar secretos en ejemplos. El Inspector te deja consultar esas superficies, pero la aserción importante vive en tu repositorio: compara la respuesta normalizada con el contrato que el equipo aprueba.&lt;/p&gt;

&lt;p&gt;No hagas snapshot de párrafos enteros ni de IDs aleatorios. Normaliza orden, timestamps, trazas y URLs efímeras; afirma solo los campos que un cliente necesita para decidir. Un snapshot enorme enseña ruido y hace que una regresión importante se pierda entre cambios legítimos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Smoke test reproducible por CLI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para un servidor &lt;code&gt;stdio&lt;/code&gt;, la forma más rápida de probar el wire protocol es ejecutar el Inspector como cliente, no arrancar una ventana y hacer clic. El comando siguiente lista las tools de un build ya compilado; fija Node y dependencias en el lockfile para que CI y tu portátil ejecuten el mismo artefacto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;package.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc -p tsconfig.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mcp:tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx @modelcontextprotocol/inspector --cli node dist/index.js --method tools/list"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ese comando prueba que el proceso arranca, que no ensucia &lt;code&gt;stdout&lt;/code&gt; con logs y que responde al catálogo MCP. En CI redirígelo a un JSON de artefacto, analiza el exit code y comprueba que aparecen solo las tools permitidas. Los logs de diagnóstico van a &lt;code&gt;stderr&lt;/code&gt;; escribir texto de debug en &lt;code&gt;stdout&lt;/code&gt; rompe &lt;code&gt;stdio&lt;/code&gt; aunque el servidor parezca sano localmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prueba una llamada real y sus errores
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tools/list&lt;/code&gt; no detecta una tool registrada con argumentos mal definidos o una credencial usada demasiado pronto. Selecciona por tool un caso exitoso con fixture y al menos dos fallos: argumentos inválidos y una decisión de autorización denegada. Para una tool de búsqueda, no necesitas un LLM: usa un índice falso que devuelva resultados conocidos y verifica el &lt;code&gt;structuredContent&lt;/code&gt; validado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;La CLI del Inspector permite invocar una tool con &lt;code&gt;--method tools/call&lt;/code&gt;, &lt;code&gt;--tool-name&lt;/code&gt; y &lt;code&gt;--tool-arg&lt;/code&gt;. Mantén las entradas en un fichero o script del repo para que no haya JSON escapado y frágil en YAML. El test debe esperar una respuesta de error explícita o un código de negocio documentado; no debe aceptar que el proceso termine con cualquier texto que contenga 'denied'.&lt;/p&gt;

&lt;p&gt;Un patrón útil es probar la misma llamada con dos identidades de prueba. La primera puede leer un documento de su tenant; la segunda recibe &lt;code&gt;permission_denied&lt;/code&gt; sin que la respuesta revele si el documento existe. Esa aserción protege tanto confidencialidad como calidad de la experiencia del agente: un modelo que recibe un 403 claro no debería reintentar diez veces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compatibilidad: prueba el servidor que publicas, no el que recuerdas
&lt;/h3&gt;

&lt;p&gt;El Inspector v2 convive con servidores de la era antigua y de la moderna. La configuración, flags y el modo de apuntar a un servidor cambiaron respecto a v1, así que no copies un blog post sin fijar la versión y leer la ayuda del paquete instalado. El repositorio oficial incluye una guía de migración: úsala como parte de la actualización de dependencias.&lt;/p&gt;

&lt;p&gt;Para remoto, prueba la URL y el transporte exactos que verá el host. Un endpoint que funciona contra &lt;code&gt;stdio&lt;/code&gt; no demuestra CORS, cabeceras, proxy inverso, &lt;code&gt;Content-Type&lt;/code&gt;, autenticación ni los requisitos del transporte HTTP. En MCP moderno las cabeceras de método y nombre permiten a gateways y rate limiters validar y enrutar sin inspeccionar el body; una prueba HTTP debe fallar cuando cabecera y request discrepan.&lt;/p&gt;

&lt;p&gt;Mantén una matriz pequeña: transportes soportados × versión de protocolo × identidad de prueba × operación. No hace falta probar todos los hosts del mercado en cada commit. Sí hace falta una prueba de compatibilidad por rama de protocolo que prometes soportar y una prueba de regresión cuando subes SDK o Inspector.&lt;/p&gt;

&lt;h3&gt;
  
  
  El Inspector también es una frontera de seguridad
&lt;/h3&gt;

&lt;p&gt;La interfaz web del Inspector se apoya en un proxy local capaz de lanzar procesos y conectar con servidores MCP. No lo expongas a una red no confiable ni desactives su autenticación para evitar una molestia de desarrollo. El propio proyecto advierte que ese atajo puede permitir que una web maliciosa use tu máquina como puente hacia procesos locales.&lt;/p&gt;

&lt;p&gt;En CI, ejecuta el Inspector contra un contenedor o proceso efímero con un usuario sin privilegios, directorio temporal y fixtures no sensibles. No pases tokens de producción por &lt;code&gt;-e&lt;/code&gt;, no imprimas cabeceras de Authorization y no dejes un puerto expuesto entre jobs. Para un servidor remoto, usa una identidad de test con scopes mínimos y revócala igual que cualquier otro secreto de integración.&lt;/p&gt;

&lt;p&gt;La prueba negativa más valiosa no es un payload exótico: es confirmar que la tool no puede ampliar sus propios permisos. Simula un argumento que pide otra cuenta, una URL privada o una operación de escritura y verifica que tu backend impone la política antes de que la tool llegue al proveedor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  De Inspector a una puerta de calidad en CI
&lt;/h3&gt;

&lt;p&gt;Divide la pipeline en cuatro jobs cortos: compilar y hacer unit tests; arrancar el servidor con fixtures; ejecutar Inspector CLI para catálogo, tools, resources y prompts; y correr pruebas negativas de autorización y límites. Conserva como artefacto el resultado normalizado y la versión de protocolo, no credenciales ni contexto de usuarios.&lt;/p&gt;

&lt;p&gt;Bloquea un merge cuando desaparece una tool pública, cambia un schema sin versión, una llamada segura devuelve datos de otro tenant o el proceso emite basura por &lt;code&gt;stdout&lt;/code&gt;. No bloquees por variaciones cosméticas de descripciones mientras el contrato semántico siga siendo válido; de lo contrario, el equipo aprenderá a ignorar rojo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El test de protocolo debe convivir con observabilidad. Asigna un &lt;code&gt;traceparent&lt;/code&gt; de prueba, registra nombre de tool, latencia, resultado y motivo de denegación de forma redactada. Cuando una integración falla en un host real podrás unir el trace con la misma operación de CI en vez de pedir al modelo que reconstruya el incidente desde una conversación.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Checklist antes de conectar un agente
&lt;/h3&gt;

&lt;p&gt;Compilar el servidor y ejecutar Inspector CLI contra el artefacto, no contra un archivo fuente sin build.&lt;/p&gt;

&lt;p&gt;Afirmar tools, recursos y prompts esperados, con schemas y límites que el consumidor realmente use.&lt;/p&gt;

&lt;p&gt;Probar una llamada feliz con fixtures y errores de validación, timeout y upstream controlados.&lt;/p&gt;

&lt;p&gt;Probar dos identidades de test y comprobar aislamiento entre tenants, scopes y operaciones mutantes.&lt;/p&gt;

&lt;p&gt;Ejecutar la matriz mínima de transporte y versión de protocolo que anuncias como compatible.&lt;/p&gt;

&lt;p&gt;Mantener Inspector, servidor y SDK versionados; releer la migración al actualizar de era MCP.&lt;/p&gt;

&lt;p&gt;Ejecutar proxy y fixtures sin secretos de producción, puertos públicos ni privilegios innecesarios.&lt;/p&gt;

&lt;p&gt;Guardar resultados normalizados y trazas redactadas como artefactos de CI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es MCP Inspector?
&lt;/h3&gt;

&lt;p&gt;Es la herramienta oficial del ecosistema MCP para inspeccionar, probar y depurar servidores mediante una interfaz web, una CLI y una TUI. Actúa como cliente MCP para comprobar la conversación de protocolo real.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿MCP Inspector sustituye Jest, pytest o pruebas de integración?
&lt;/h3&gt;

&lt;p&gt;No. Complementa esas pruebas: valida que el build que expones habla MCP correctamente. Las reglas de negocio, aislamiento de datos, rendimiento y proveedores externos necesitan tests propios.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Puedo usar MCP Inspector en CI?
&lt;/h3&gt;

&lt;p&gt;Sí, el modo CLI está pensado para automatización. Ejecútalo contra un proceso o contenedor efímero, analiza el resultado y conserva artefactos redactados; no conviertas la UI web en un paso interactivo de CI.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Debo desactivar la autenticación del proxy del Inspector?
&lt;/h3&gt;

&lt;p&gt;No. El proxy puede iniciar procesos locales y conectarse a servidores; mantenlo limitado a localhost y usa su autenticación. Desactivarla es un riesgo, no una optimización.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Por qué falla un test MCP tras actualizar a 2026-07-28?
&lt;/h3&gt;

&lt;p&gt;La era moderna elimina el handshake initialize y la sesión de transporte. Revisa qué versión promete tu servidor, deja que el cliente negocie o fija una matriz explícita y actualiza fixtures heredados.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué debo verificar en una tool mutante?
&lt;/h3&gt;

&lt;p&gt;Además del schema, verifica scopes, identidad derivada en backend, idempotencia, confirmación humana cuando aplique, auditoría y que una identidad de otro tenant no pueda inferir datos ni ejecutar la acción.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo añadir MCP Inspector a CI para un servidor MCP
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Definir el contrato.&lt;/strong&gt; Documenta tools, resources y prompts públicos con schemas, efectos, scopes, límites y errores esperados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compilar el artefacto.&lt;/strong&gt; Ejecuta el build del servidor y prueba el binario o archivo resultante, no una ruta de desarrollo distinta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arrancar con fixtures.&lt;/strong&gt; Inicia el servidor en stdio o un contenedor efímero con datos controlados y sin secretos de producción.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listar superficies.&lt;/strong&gt; Ejecuta Inspector CLI para consultar tools, resources y prompts y compara una salida normalizada con el contrato aprobado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Llamar una tool segura.&lt;/strong&gt; Ejecuta una llamada representativa con argumentos válidos y valida structuredContent, límites y resultado de negocio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Añadir casos negativos.&lt;/strong&gt; Prueba schema inválido, timeout, proveedor caído y dos identidades de test para confirmar autorización y aislamiento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Probar compatibilidad.&lt;/strong&gt; Repite sobre cada transporte y versión MCP que declares soportar, especialmente tras actualizar SDK o Inspector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cerrar el entorno.&lt;/strong&gt; Recoge trazas y resultados redactados, detén el proceso efímero y falla el job si cambia el contrato o se filtran datos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/modelcontextprotocol/inspector" rel="noopener noreferrer"&gt;MCP Inspector: repositorio y CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/modelcontextprotocol/inspector/blob/main/docs/v1-to-v2-migration.md" rel="noopener noreferrer"&gt;MCP Inspector: migración v1 a v2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.modelcontextprotocol.io/posts/2026-07-28/" rel="noopener noreferrer"&gt;MCP: especificación 2026-07-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ts.sdk.modelcontextprotocol.io/v2/protocol-versions" rel="noopener noreferrer"&gt;MCP TypeScript SDK: versiones de protocolo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2" rel="noopener noreferrer"&gt;MCP TypeScript SDK: migrar a v2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices" rel="noopener noreferrer"&gt;MCP: buenas prácticas de seguridad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-produccion-seguridad-permisos-supply-chain/" rel="noopener noreferrer"&gt;MCP en producción: seguridad y permisos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-outputschema-structuredcontent-agentes/" rel="noopener noreferrer"&gt;MCP outputSchema y structuredContent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/oauth-21-mcp-servidores-remotos/" rel="noopener noreferrer"&gt;OAuth 2.1 para servidores MCP remotos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/playwright-mcp-agentes-ia-testing-ui/" rel="noopener noreferrer"&gt;Playwright MCP para testing de UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-registry-publicar-descubrir-servidores/" rel="noopener noreferrer"&gt;MCP Registry: publicar y descubrir servidores&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Codex CLI: configura AGENTS.md, perfiles y permisos sin convertir el repo en una excepción</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Mon, 24 Aug 2026 09:15:32 +0000</pubDate>
      <link>https://dev.to/khavel/codex-cli-configura-agentsmd-perfiles-y-permisos-sin-convertir-el-repo-en-una-excepcion-55h7</link>
      <guid>https://dev.to/khavel/codex-cli-configura-agentsmd-perfiles-y-permisos-sin-convertir-el-repo-en-una-excepcion-55h7</guid>
      <description>&lt;p&gt;Codex CLI es el cliente local de terminal para inspeccionar, editar, ejecutar comandos y automatizar trabajo repetible sobre un repositorio. La keyword principal es &lt;code&gt;Codex CLI&lt;/code&gt;; la intención de búsqueda es práctica: instalarlo no basta, un developer quiere saber qué poner en &lt;code&gt;AGENTS.md&lt;/code&gt;, dónde vive &lt;code&gt;config.toml&lt;/code&gt;, cómo usar perfiles y cómo evitar permisos globales que nadie pueda explicar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;La configuración que recomiendo tiene tres capas: instrucciones de repo para el comportamiento, configuración personal para preferencias de máquina y perfiles para el riesgo de cada tarea. No metas todas las reglas en un prompt, ni todos los permisos en un &lt;code&gt;config.toml&lt;/code&gt; global.&lt;/p&gt;

&lt;p&gt;Mi postura: el preset cómodo de escritura en workspace es buen punto de partida para desarrollo local; &lt;code&gt;danger-full-access&lt;/code&gt; y red abierta no son un perfil de productividad. Son excepciones temporales que deben tener un motivo, una tarea y una revisión.&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué configura Codex CLI exactamente
&lt;/h3&gt;

&lt;p&gt;Codex CLI puede trabajar de forma interactiva, con &lt;code&gt;codex exec&lt;/code&gt; en scripts o CI, y con la misma base de configuración que la extensión de IDE. La CLI tiene comandos visibles para iniciar instrucciones (&lt;code&gt;/init&lt;/code&gt;), consultar el estado (&lt;code&gt;/status&lt;/code&gt;), elegir permisos (&lt;code&gt;/permissions&lt;/code&gt;) y revisar cambios (&lt;code&gt;/review&lt;/code&gt;). El valor no es el terminal en sí: es poder convertir ese ciclo en una configuración reproducible.&lt;/p&gt;

&lt;p&gt;Separa dos preguntas que suelen mezclarse: qué sabe el agente sobre el proyecto y qué puede hacer. &lt;code&gt;AGENTS.md&lt;/code&gt; explica comandos, restricciones y criterios de aceptación; sandbox, red y approval policy controlan capacidades reales. Una frase que prohíbe publicar no bloquea un token con permisos para publicar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4zl301glzdmquei6j3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4zl301glzdmquei6j3d.png" alt="Flujo conceptual de configuración de Codex CLI: instrucciones del repositorio, perfil de configuración, sandbox, punto de aprobación y ejecución validada" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La instrucción guía la tarea; el perfil y el sandbox delimitan lo que el agente puede hacer; la aprobación decide cuándo debe detenerse.&lt;/p&gt;

&lt;h3&gt;
  
  
  La jerarquía que evita sorpresas
&lt;/h3&gt;

&lt;p&gt;Las opciones no viven en un único archivo. Codex aplica primero flags de CLI y valores &lt;code&gt;--config&lt;/code&gt;, después &lt;code&gt;.codex/config.toml&lt;/code&gt; desde la raíz al subdirectorio actual, después el perfil seleccionado, después &lt;code&gt;~/.codex/config.toml&lt;/code&gt; y finalmente valores por defecto. Los ficheros de proyecto solo se cargan cuando confías en el proyecto; eso evita que clonar un repo active configuración, hooks o reglas sin tu decisión.&lt;/p&gt;

&lt;p&gt;Usa esa precedencia para no crear una bola de nieve. En &lt;code&gt;~/.codex/config.toml&lt;/code&gt; deja defaults personales que no dependen del repo. En &lt;code&gt;.codex/config.toml&lt;/code&gt; deja solo ajustes de proyecto que el equipo puede revisar. En un perfil coloca la diferencia de riesgo: por ejemplo, revisión de solo lectura frente a edición local con red controlada.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  AGENTS.md es un contrato operativo, no un README duplicado
&lt;/h3&gt;

&lt;p&gt;Codex construye una cadena de instrucciones al inicio de cada ejecución: lee una guía global y después recorre desde la raíz Git hasta el directorio actual. En cada nivel, &lt;code&gt;AGENTS.override.md&lt;/code&gt; gana a &lt;code&gt;AGENTS.md&lt;/code&gt;; los archivos más cercanos al código aparecen al final y por tanto refinan las reglas generales. No conviertas esto en una enciclopedia: el límite combinado es de 32 KiB por defecto y una instrucción crítica enterrada deja de ser una instrucción.&lt;/p&gt;

&lt;p&gt;Un &lt;code&gt;AGENTS.md&lt;/code&gt; de raíz debería responder a preguntas operativas: cómo instalar, qué comandos validan, qué rutas son sensibles, qué cambio exige migración o revisión, y qué nunca debe incluirse en logs o commits. Un override bajo &lt;code&gt;services/payments/&lt;/code&gt; puede añadir comandos y límites de esa zona sin contaminar el resto del monorepo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No guardes secretos, claves, playbooks de incidente completos ni datos de clientes. El archivo se entrega como contexto a un agente: es un contrato de trabajo, no una caja fuerte.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ejemplo mínimo: un repo con guardrails verificables
&lt;/h2&gt;

&lt;p&gt;Este ejemplo es deliberadamente corto. No intenta describir el producto; declara las pocas reglas que cambian el resultado de una tarea. Las políticas reales de aprobación y red viven en configuración, no en Markdown.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;AGENTS.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Contrato de trabajo del repositorio

## Antes de editar
- Lee docs/architecture.md y ejecuta npm ci.
- No modifiques .github/workflows, infra/ ni migraciones sin pedir aprobación.

## Validación
- Ejecuta npm run lint y npm test para cambios en src/.
- Explica en el resultado los tests que no pudiste ejecutar.

## Datos
- Nunca imprimas variables de entorno ni copies datos de producción a fixtures.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para comprobar qué se cargó, inicia una sesión nueva desde la raíz y pide a Codex que enumere las instrucciones activas; desde un subdirectorio, repite la comprobación. Si la explicación no coincide con tu jerarquía, corrige el archivo más cercano o un override olvidado antes de automatizar nada.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Perfiles: el permiso debe seguir la tarea
&lt;/h3&gt;

&lt;p&gt;Un perfil no es una identidad de persona; es una política para un tipo de trabajo. Crea uno de lectura para explorar o revisar, uno de edición de workspace para cambios locales y uno aislado para una tarea que necesita red. Evita el perfil todopoderoso que se convierte en el default por pereza.&lt;/p&gt;

&lt;p&gt;Los perfiles viven junto a la configuración de usuario y se seleccionan con &lt;code&gt;--profile&lt;/code&gt;. Eso permite que &lt;code&gt;config.toml&lt;/code&gt; guarde una base común mientras cada perfil cambia lo mínimo: sandbox, política de aprobación y, cuando sea imprescindible, la política de red. No intentes mover credenciales de proveedor o telemetría a &lt;code&gt;.codex/config.toml&lt;/code&gt; del repo: la documentación reserva esas claves para el nivel de usuario.&lt;/p&gt;

&lt;p&gt;La regla que funciona: el CI no hereda el perfil de tu portátil, y el repositorio no puede rebajar la política de tu máquina. Define la cuenta, secretos y permisos del runner por separado y ejecuta un modo no interactivo solo si ya tienes un contrato de validación y rollback.&lt;/p&gt;
&lt;h3&gt;
  
  
  Un config.toml razonable para empezar
&lt;/h3&gt;

&lt;p&gt;El siguiente perfil permite editar dentro del workspace y deja las decisiones que amplían capacidad bajo aprobación. No es una configuración universal: es un punto de partida que debes probar en un repositorio sin datos sensibles.&lt;/p&gt;

&lt;p&gt;~/.codex/local-edit.config.toml&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;approval_policy = "on-request"
sandbox_mode = "workspace-write"

[sandbox_workspace_write]
network_access = false
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Lánzalo con &lt;code&gt;codex --profile local-edit&lt;/code&gt; y consulta &lt;code&gt;/status&lt;/code&gt; antes de la primera tarea. Si necesitas documentación o una dependencia, no conviertas la sesión entera en red abierta: crea un perfil de investigación limitado o pide aprobación para esa operación concreta.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sandbox, aprobación y red son controles distintos
&lt;/h2&gt;

&lt;p&gt;El sandbox define la frontera técnica —por ejemplo, lectura, escritura en workspace o acceso más amplio—; la approval policy define cuándo Codex se detiene para pedir autorización. Con el modo Auto (&lt;code&gt;workspace-write&lt;/code&gt; y &lt;code&gt;on-request&lt;/code&gt;), puede editar y ejecutar dentro del directorio de trabajo, pero debe pedir permiso para salir de ese límite o usar la red.&lt;/p&gt;

&lt;p&gt;La red merece una decisión aparte. Con &lt;code&gt;workspace-write&lt;/code&gt;, está apagada salvo que la actives. Si la activas sin proxy, el tráfico saliente es directo y no queda limitado por una lista de dominios. Para restringir destinos, activa &lt;code&gt;features.network_proxy&lt;/code&gt; y declara reglas allowlist; el proxy no concede red por sí solo. &lt;code&gt;*&lt;/code&gt; equivale a red pública amplia, no a una lista de seguridad.&lt;/p&gt;

&lt;p&gt;Las tools MCP y las integraciones no quedan automáticamente filtradas por ese proxy de comandos. Revisa sus propios scopes, sus anotaciones de efectos y sus políticas de aprobación. El modelo puede encadenar herramientas: analizar cada permiso aislado es menos útil que mirar el flujo completo de datos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Qué no automatizar todavía
&lt;/h3&gt;

&lt;p&gt;No ejecutes con &lt;code&gt;approval_policy = "never"&lt;/code&gt; una acción que publique, borre, migre datos, rote secretos, cambie infraestructura o escriba fuera de un entorno de pruebas. El modo no interactivo es para operaciones repetibles cuyo diff, test, destino y rollback ya están definidos; no para eliminar fricción cuando aún no hay control.&lt;/p&gt;

&lt;p&gt;Tampoco confundas tests verdes con autorización. Un test puede demostrar comportamiento local y aun así no saber si el usuario tiene permiso para enviar un correo, desplegar un cambio o leer un recurso de otro tenant. Esas barreras viven en el backend, los tokens y los entornos, no en la conversación.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist de adopción para un equipo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Añadir un AGENTS.md raíz de menos de dos pantallas con setup, validación, rutas sensibles y manejo de datos.&lt;/li&gt;
&lt;li&gt;Crear un override solo donde la regla sea realmente local, y probar qué archivos carga Codex desde esa carpeta.&lt;/li&gt;
&lt;li&gt;Definir perfiles de lectura, edición y red limitada; empezar por lectura o edición sin red.&lt;/li&gt;
&lt;li&gt;Mantener &lt;code&gt;on-request&lt;/code&gt; para cambios de entorno, red, rutas protegidas y herramientas con efectos.&lt;/li&gt;
&lt;li&gt;Separar la configuración del runner de CI de la configuración personal de un developer.&lt;/li&gt;
&lt;li&gt;Revisar el diff, los comandos y los tests, y registrar por qué se permitió una excepción de permisos.&lt;/li&gt;
&lt;li&gt;Medir bloqueos, reintentos, revisiones rechazadas y tiempo ahorrado antes de ampliar autonomía.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es Codex CLI?
&lt;/h3&gt;

&lt;p&gt;Es el cliente de terminal de Codex para inspeccionar repositorios, editar archivos, ejecutar comandos y automatizar flujos repetibles desde el directorio del proyecto.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Dónde vive config.toml?
&lt;/h3&gt;

&lt;p&gt;La configuración personal vive en &lt;code&gt;~/.codex/config.toml&lt;/code&gt;; los repos pueden añadir &lt;code&gt;.codex/config.toml&lt;/code&gt;, que Codex carga solo para proyectos de confianza y que no puede reemplazar claves sensibles de nivel máquina.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué diferencia hay entre AGENTS.md y config.toml?
&lt;/h3&gt;

&lt;p&gt;AGENTS.md aporta instrucciones y contexto; config.toml controla opciones del cliente como perfiles, sandbox, aprobaciones, red y servidores MCP. Un archivo de instrucciones no concede ni revoca permisos técnicos.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Debo usar approval_policy never?
&lt;/h3&gt;

&lt;p&gt;Solo en automatizaciones estrechas y verificadas donde la acción, el entorno, el rollback y los límites de datos ya estén definidos. Para trabajo exploratorio o mutaciones sensibles, conserva aprobación humana.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿La allowlist de red se activa sola al declarar dominios?
&lt;/h3&gt;

&lt;p&gt;No. Debes habilitar red y el network proxy; con red apagada el proxy no hace nada, y con red encendida sin proxy el tráfico sigue siendo directo.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Puedo usar el mismo perfil en mi portátil y CI?
&lt;/h3&gt;

&lt;p&gt;No es buena idea. CI necesita una identidad, secretos, permisos y rollback específicos; no debe heredar una configuración interactiva personal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo configurar Codex CLI en un repositorio de forma segura
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Crear un checkpoint.&lt;/strong&gt; Confirma que el repositorio está limpio o registra el estado actual antes de pedir un cambio al agente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escribir el contrato raíz.&lt;/strong&gt; Añade AGENTS.md con setup, comandos de validación, rutas sensibles y reglas de datos que el equipo pueda comprobar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Probar la jerarquía.&lt;/strong&gt; Desde la raíz y desde un subdirectorio, pide a Codex que enumere las instrucciones activas y corrige overrides inesperados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elegir el perfil base.&lt;/strong&gt; Empieza con lectura o workspace-write con approval_policy on-request y red desactivada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separar excepciones.&lt;/strong&gt; Crea un perfil de investigación o una aprobación puntual para red; no rebajes el perfil base por una única tarea.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configurar la red con límites.&lt;/strong&gt; Si necesitas red, activa network_proxy y permite solo hosts concretos necesarios para la tarea.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ejecutar una tarea reversible.&lt;/strong&gt; Usa documentación, tests o un cambio pequeño en un repositorio de riesgo medio y revisa comandos, diff y evidencia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medir antes de ampliar.&lt;/strong&gt; Registra bloqueos de permisos, tests fallidos, reintentos y hallazgos de revisión durante varias tareas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatizar al final.&lt;/strong&gt; Usa codex exec en CI solo cuando las entradas, acciones permitidas, aprobación, validación y rollback estén definidos fuera del prompt.
&amp;gt; ### Límite sano
&amp;gt;
&amp;gt; Paraleliza investigación y tareas acotadas. No paralelices criterio técnico ni integración final.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/cli/" rel="noopener noreferrer"&gt;OpenAI Docs: Codex CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/config-basic/" rel="noopener noreferrer"&gt;OpenAI Docs: Config basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/guides/agents-md/" rel="noopener noreferrer"&gt;OpenAI Docs: AGENTS.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/config-reference/" rel="noopener noreferrer"&gt;OpenAI Docs: Config reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/sandbox/" rel="noopener noreferrer"&gt;OpenAI Docs: Agent approvals &amp;amp; security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/codex-acceso-internet-sandbox-seguridad/" rel="noopener noreferrer"&gt;Codex con internet: sandbox y seguridad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/agents-md-claude-md-memoria-proyecto/" rel="noopener noreferrer"&gt;AGENTS.md y CLAUDE.md: contexto para agentes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/hooks-agentes-codigo-guardrails-validacion/" rel="noopener noreferrer"&gt;Hooks para agentes de código&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/metricas-agentes-codigo-productividad-coste/" rel="noopener noreferrer"&gt;Métricas para agentes de código&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/coordinar-varios-agentes-codex-claude-cursor/" rel="noopener noreferrer"&gt;Cómo coordinar varios agentes de código&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>An embedding model's price is a one-time cost. Its dimensions are a subscription.</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Tue, 18 Aug 2026 11:44:06 +0000</pubDate>
      <link>https://dev.to/khavel/an-embedding-models-price-is-a-one-time-cost-its-dimensions-are-a-subscription-2528</link>
      <guid>https://dev.to/khavel/an-embedding-models-price-is-a-one-time-cost-its-dimensions-are-a-subscription-2528</guid>
      <description>&lt;p&gt;Embedding models are billed per 1M input tokens, so that's the number that ends up in the comparison. Here are the nine generally-available embedding models that publish a token price, every rate re-read off the provider's own page this morning (2026-08-17):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;$/1M input&lt;/th&gt;
&lt;th&gt;Default dims&lt;/th&gt;
&lt;th&gt;Max input tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;text-embedding-3-small&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;1536&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;amazon.titan-embed-text-v2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Amazon&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;text-embedding-v4&lt;/code&gt; (Qwen)&lt;/td&gt;
&lt;td&gt;Alibaba&lt;/td&gt;
&lt;td&gt;$0.07&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;embed-v4.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cohere&lt;/td&gt;
&lt;td&gt;$0.12&lt;/td&gt;
&lt;td&gt;1536&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;128,000&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;text-embedding-3-large&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;$0.13&lt;/td&gt;
&lt;td&gt;3072&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nova-2-multimodal-embeddings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Amazon&lt;/td&gt;
&lt;td&gt;$0.135&lt;/td&gt;
&lt;td&gt;3072&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemini-embedding-001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;$0.15&lt;/td&gt;
&lt;td&gt;3072&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;codestral-embed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mistral&lt;/td&gt;
&lt;td&gt;$0.15&lt;/td&gt;
&lt;td&gt;1536&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemini-embedding-2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;3072&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(The Model column is the provider's own model string; the ids in our feed are normalised slightly differently — you'll see both at the end.)&lt;/p&gt;

&lt;p&gt;Top to bottom, that's a &lt;strong&gt;10x spread&lt;/strong&gt;. It is also, for most retrieval workloads, the least consequential number on the row.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ingestion bill is one-time, and it is small
&lt;/h2&gt;

&lt;p&gt;Take a corpus of 1,000,000 documents averaging 800 tokens. That's 800M tokens to embed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At $0.02/1M: &lt;strong&gt;$16.00&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;At $0.20/1M: &lt;strong&gt;$160.00&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The entire 10x spread is &lt;strong&gt;$144&lt;/strong&gt;, once. You will spend more than that deciding which model to use. The token price only becomes interesting again when you re-embed — a model migration, or a corpus that grows continuously — and even then it's a function of &lt;em&gt;new&lt;/em&gt; tokens, not of the corpus you already indexed.&lt;/p&gt;

&lt;p&gt;Meanwhile the thing you're actually buying is a pile of float vectors that you will store, index, and hold in RAM for as long as the product exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vector is what recurs
&lt;/h2&gt;

&lt;p&gt;One million vectors, float32:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimensions&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3072&lt;/td&gt;
&lt;td&gt;12.29 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1536&lt;/td&gt;
&lt;td&gt;6.14 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;4.10 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;td&gt;3.07 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;td&gt;1.02 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I'm deliberately not multiplying that by a vector-database rate — every managed vector store prices differently and I'm not going to invent a number. Use your own. The point is the shape: this one is &lt;strong&gt;monthly&lt;/strong&gt;, it scales linearly with the dimension count, and picking the 3072-dim model over the 1024-dim one triples it forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  …except the dimension is usually a knob, not a spec
&lt;/h2&gt;

&lt;p&gt;This is the part that makes the comparison table misleading rather than merely incomplete. On most current models, the dimension count you see published is a &lt;strong&gt;default&lt;/strong&gt;, and you can ask for a smaller vector:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI&lt;/strong&gt; — a &lt;code&gt;dimensions&lt;/code&gt; request parameter, which its API reference says is supported on &lt;code&gt;text-embedding-3&lt;/code&gt; and later models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cohere&lt;/strong&gt; — &lt;code&gt;embed-v4.0&lt;/code&gt;'s docs table gives its dimensions as a choice of 256, 512, 1024 or 1536, with 1536 the default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google&lt;/strong&gt; — an &lt;code&gt;output_dimensionality&lt;/code&gt; parameter, via Matryoshka Representation Learning. Both Gemini embedding models default to 3072 and Google's docs say you can truncate below that without losing quality, recommending 768, 1536 or 3072.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon&lt;/strong&gt; — Titan Text Embeddings V2 is documented as having &lt;em&gt;"configurable output dimensions"&lt;/em&gt;, set via &lt;code&gt;dimensions&lt;/code&gt; in the request body.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And Google publishes the trade-off as a table, which is the most useful thing I found all week. MTEB score by truncated dimension, for &lt;code&gt;gemini-embedding-001&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;MRL dimension&lt;/th&gt;
&lt;th&gt;MTEB score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;68.16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1536&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;68.17&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;td&gt;67.99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;67.55&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;td&gt;66.19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;63.31&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read that carefully. &lt;strong&gt;1536 scores fractionally higher than 2048.&lt;/strong&gt; Going from 1536 down to 768 costs &lt;strong&gt;0.18 MTEB points&lt;/strong&gt; and halves your storage, your index size and your RAM. The cliff doesn't arrive until 256, and it doesn't get steep until 128.&lt;/p&gt;

&lt;p&gt;So the honest version of "this model is 3072-dimensional" is "this model defaults to 3072 and its own vendor recommends 768 as a supported option". Those imply storage bills a factor of four apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number that really is fixed: the input ceiling
&lt;/h2&gt;

&lt;p&gt;The context window is the field on these rows that you cannot negotiate, and it varies more than the other two. Cohere's own current lineup spans the entire range:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;embed-english-v3.0&lt;/code&gt; — &lt;strong&gt;512&lt;/strong&gt; tokens&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;embed-v4.0&lt;/code&gt; — &lt;strong&gt;128,000&lt;/strong&gt; tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's &lt;strong&gt;250x&lt;/strong&gt;, same vendor, both generally available today. Google moved from 2048 on &lt;code&gt;gemini-embedding-001&lt;/code&gt; to 8192 on &lt;code&gt;gemini-embedding-2&lt;/code&gt;. Most of the rest sit at 8192.&lt;/p&gt;

&lt;p&gt;Why it compounds: the ceiling caps your chunk size, chunk size sets your vector count, and vector count multiplied by dimensions is your storage &lt;em&gt;and&lt;/em&gt; your index. Chunking the same corpus against a 512-token ceiling instead of an 8192-token one yields &lt;strong&gt;16x the vectors&lt;/strong&gt;. Your token spend barely moves — it's the same text either way — while everything downstream of the embedding call multiplies.&lt;/p&gt;

&lt;p&gt;To be fair to the small-context models: almost nobody chunks at the ceiling, because retrieval quality usually wants smaller chunks than the maximum anyway. The ceiling doesn't dictate your chunk size. It removes options, and it's the only one of the three fields where the provider makes the decision for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rerank: there is no ladder to write
&lt;/h2&gt;

&lt;p&gt;I wanted to end with the same table for rerankers. It doesn't exist, and the reason is worth more than the table would have been.&lt;/p&gt;

&lt;p&gt;Of the 7 GA rerank models we track, &lt;strong&gt;3 publish a rate&lt;/strong&gt;, and the unit isn't tokens:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Amazon Rerank v1&lt;/td&gt;
&lt;td&gt;Amazon&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$1.00&lt;/strong&gt; per 1,000 searches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rerank 4 Fast&lt;/td&gt;
&lt;td&gt;Cohere&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$2.00&lt;/strong&gt; per 1,000 searches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rerank 4 Pro&lt;/td&gt;
&lt;td&gt;Cohere&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$2.50&lt;/strong&gt; per 1,000 searches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A "search" is not a standard unit, and it is not a token. AWS's price book bills its reranker in &lt;em&gt;search units&lt;/em&gt; — $1 per 1,000 of them — where a unit is a query carrying some bounded number of document chunks, defined in the docs rather than on the price line. Cohere bills per 1,000 searches. Whether those two units mean the same thing for your query shape is your problem, not something either price implies.&lt;/p&gt;

&lt;p&gt;That AWS model is also region-scoped in a way the price book makes plain: the SKU (&lt;code&gt;Z7M6S4MRBXNXJRB4&lt;/code&gt;) is in &lt;code&gt;us-west-2&lt;/code&gt;, and there is no rerank SKU in the &lt;code&gt;us-east-1&lt;/code&gt; price book at all.&lt;/p&gt;

&lt;p&gt;The other four GA rerankers publish no first-party rate we could find. In our data those fields are &lt;code&gt;null&lt;/code&gt;, which is a fact about the provider, not a gap we're papering over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get it as data
&lt;/h2&gt;

&lt;p&gt;All of the above is in a free JSON feed — no key, no signup, CORS open. (If you would rather just look at the 13 rows, they are on &lt;a href="https://aimodelwatch.dev/embeddings" rel="noopener noreferrer"&gt;one page&lt;/a&gt; too.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://aimodelwatch.dev/api/models.json &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.models[]
      | select(.embedding_dimensions != null and .status == "ga")
      | [.price_input_per_mtok, .embedding_dimensions, .context_window, .id]
      | @tsv'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output, run against the live endpoint today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.02    1024    8192    amazon-titan-embed-text-v2
0.02    1536    8192    text-embedding-3-small
0.07    1024    8192    qwen-text-embedding-v4
0.12    1536    128000  embed-v4-0
0.13    3072    8192    text-embedding-3-large
0.135   3072    8192    amazon-nova-2-multimodal-embeddings
0.15    1536    8192    codestral-embed
0.15    3072    2048    gemini-embedding-001
0.2     3072    8192    gemini-embedding-2
        384     512     embed-english-light-v3-0
        384     512     embed-multilingual-light-v3-0
        1024    512     embed-english-v3-0
        1024    512     embed-multilingual-v3-0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The four rows with a blank price are Cohere's v3 embedding family. They're still GA and still documented; Cohere's pricing page currently lists only Embed 4 among its embedding models, so there is no first-party rate to carry. A blank there means "the provider doesn't publish this", not "we didn't look" — every row carries the &lt;code&gt;source_url&lt;/code&gt; it was read from.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One honest note while you're looking at that output.&lt;/strong&gt; The two OpenAI rows read &lt;code&gt;8191&lt;/code&gt; when this was drafted, and I'd written 8192 in the table at the top. Both numbers are first-party: 8191 is the figure OpenAI's 2024 new-embedding-models announcement carried, and the current API reference states &lt;em&gt;"the max input tokens for the model (8192 tokens for all embedding models)"&lt;/em&gt;. The disagreement was reconciled to &lt;strong&gt;8192&lt;/strong&gt; on 2026-08-18 — the reference states the limit as a constraint on the &lt;code&gt;input&lt;/code&gt; parameter, i.e. it carries the field as data, while the model spec pages state no limit at all. It's one token out of eight thousand and it changes nothing in this article. I'm leaving the paragraph in because a catalog that quietly rounds its own disagreements away isn't worth querying — and because you can see the audit trail: the row's &lt;code&gt;notes&lt;/code&gt; field records the old value, the new one, and which surface won.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Data from &lt;a href="https://aimodelwatch.dev" rel="noopener noreferrer"&gt;AI Model Watch&lt;/a&gt; — 231 models, prices and lifecycle dates read from official provider documentation, refreshed daily, with &lt;code&gt;null&lt;/code&gt; where the provider publishes nothing. Free JSON: &lt;a href="https://aimodelwatch.dev/api/models.json" rel="noopener noreferrer"&gt;&lt;code&gt;/api/models.json&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://aimodelwatch.dev/api/deprecations.json" rel="noopener noreferrer"&gt;&lt;code&gt;/api/deprecations.json&lt;/code&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>embeddings</category>
      <category>rag</category>
      <category>api</category>
    </item>
    <item>
      <title>OpenAI Responses API: function calling fiable, estado y trabajos en segundo plano</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Mon, 17 Aug 2026 09:25:11 +0000</pubDate>
      <link>https://dev.to/khavel/openai-responses-api-function-calling-fiable-estado-y-trabajos-en-segundo-plano-3a0g</link>
      <guid>https://dev.to/khavel/openai-responses-api-function-calling-fiable-estado-y-trabajos-en-segundo-plano-3a0g</guid>
      <description>&lt;p&gt;Responses API no convierte una función en fiable por sí sola. Esta guía muestra el bucle correcto de tool calls, validación, estado y trabajos largos para que un agente no confunda una respuesta convincente con una acción segura.&lt;/p&gt;

&lt;p&gt;OpenAI Responses API es la interfaz unificada para generar respuestas, usar herramientas y conservar estado entre turnos. Un tool call no es una orden que el servidor deba obedecer: es una propuesta del modelo que tu backend debe autorizar, validar, ejecutar de forma idempotente y devolver al modelo como &lt;code&gt;function_call_output&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;OpenAI Responses API&lt;/code&gt;. La intención es técnica: un developer que ya puede hacer una llamada básica necesita montar un flujo fiable con function calling, JSON estructurado, streaming, estado conversacional y trabajos que no caben en una petición HTTP corta.&lt;/p&gt;

&lt;p&gt;Mi postura: empieza con Responses API antes de introducir una capa de agentes. Es un contrato explícito que te obliga a entender input, output, tools y estado. Un SDK de agentes puede ahorrar orquestación después; no debería ocultar permisos, validación ni efectos externos.&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué es Responses API y qué no resuelve
&lt;/h3&gt;

&lt;p&gt;Responses API crea un objeto &lt;code&gt;response&lt;/code&gt; a partir de un modelo, una entrada y, opcionalmente, herramientas. La salida no tiene por qué ser texto: puede contener mensajes, llamadas de función, resultados de herramientas alojadas, elementos de razonamiento y eventos de streaming. Leer solo &lt;code&gt;output_text&lt;/code&gt; es correcto para un chat simple, pero insuficiente para un flujo que actúa sobre sistemas reales.&lt;/p&gt;

&lt;p&gt;La API puede encadenar contexto con &lt;code&gt;previous_response_id&lt;/code&gt; o con Conversations. Eso evita reenviar un historial manual enorme, pero no sustituye tu modelo de negocio: tú decides qué conversación pertenece a qué usuario, cuánto vive, qué datos se permiten y cuándo hay que resumir o borrar estado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tampoco decide si una llamada es segura. El modelo puede proponer &lt;code&gt;create_invoice&lt;/code&gt;, &lt;code&gt;send_email&lt;/code&gt; o &lt;code&gt;deploy&lt;/code&gt;. Tu aplicación sigue siendo el control de autoridad: autentica al usuario, limita el recurso, valida argumentos, exige aprobación cuando corresponde y registra el efecto final.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8txhhk48bnrn79gls1o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8txhhk48bnrn79gls1o.png" alt="Diagrama conceptual de un usuario que envía una petición al orquestador de Responses API; el flujo se divide entre una tool validada, salida JSON estructurada y un trabajo asíncrono, con una barrera de autorización, registro de auditoría y estado separado" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El modelo propone pasos; el backend conserva la autoridad. Estado, validación, colas y auditoría son piezas distintas del texto generado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  El bucle correcto de function calling
&lt;/h3&gt;

&lt;p&gt;Function calling tiene cuatro etapas: declaras una tool con un schema; el modelo emite uno o más elementos &lt;code&gt;function_call&lt;/code&gt;; tu servidor valida y ejecuta solo los que autoriza; devuelves un &lt;code&gt;function_call_output&lt;/code&gt; con el &lt;code&gt;call_id&lt;/code&gt; original y pides la siguiente respuesta. Si falta el último paso, el modelo no ve el resultado real de la acción y tenderá a completar la conversación con una suposición.&lt;/p&gt;

&lt;p&gt;No ejecutes argumentos directamente con &lt;code&gt;json.loads&lt;/code&gt; y una llamada a tu SDK interno. El schema reduce salidas mal formadas, pero no prueba que el usuario tenga acceso a &lt;code&gt;project_id&lt;/code&gt;, que una fecha exista ni que la acción sea razonable. Valida tipos, rangos, pertenencia al tenant y política de negocio fuera del modelo.&lt;/p&gt;

&lt;p&gt;Para una operación con efecto, asocia una clave idempotente a la intención de negocio, no al texto del modelo. Un retry HTTP, una reconexión de streaming o una segunda respuesta no debe enviar dos emails o crear dos facturas. Guarda &lt;code&gt;call_id&lt;/code&gt;, usuario, recurso, hash del payload y resultado de la ejecución.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Código: tool estrecha y resultado verificable en Python
&lt;/h3&gt;

&lt;p&gt;Este ejemplo ilustra el bucle. La tool es deliberadamente de lectura y el resultado vuelve como datos, no como instrucciones. En producción, &lt;code&gt;get_release&lt;/code&gt; debería imponer autorización y recuperar solo los campos permitidos para el usuario autenticado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;responses_tools.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;TOOLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;function&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_release&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Returns approved release metadata for one repository.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parameters&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;properties&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;repo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;minLength&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;repo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;additionalProperties&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_release_for_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;allowed_repos_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# authz, not a model prompt
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;read_release_metadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;¿Cuál es el último release de api-gateway?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TOOLS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tool_outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;function_call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_release&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_release_for_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;repo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;tool_outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;function_call_output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;call_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;previous_response_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tool_outputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El detalle importante no es el nombre de la función: es que &lt;code&gt;allowed_repos_for&lt;/code&gt; vive en tu backend. Si el modelo propone otro repo, la autorización falla antes de tocar la fuente de datos. Devuelve un error de dominio breve y deja que el modelo explique el límite al usuario, en vez de darle una excepción cruda o inventar una respuesta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured Outputs: contrato de interfaz, no control de seguridad
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cuando necesitas una salida que otro sistema consuma, usa Structured Outputs con JSON Schema estricto. En Responses API el formato se configura dentro de &lt;code&gt;text.format&lt;/code&gt;; para tools, define &lt;code&gt;strict: true&lt;/code&gt; y limita propiedades. Eso hace que el contrato sea más predecible que pedir «devuelve JSON válido» en un prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;Un schema debe representar una decisión pequeña y verificable. Para triage, por ejemplo: categoría de una allowlist, confianza acotada, evidencia citada y &lt;code&gt;needs_human_review&lt;/code&gt;. Evita un objeto genérico tipo &lt;code&gt;action: string&lt;/code&gt; que luego se convierte en una puerta trasera de comandos para cualquier integración.&lt;/p&gt;

&lt;p&gt;Trata cualquier campo generado como entrada no confiable al cruzar una frontera. &lt;code&gt;strict&lt;/code&gt; evita muchas formas inválidas; no sustituye escape HTML, validación de URLs, autorización, control de concurrencia, límites de tamaño ni saneamiento para SQL o shell. Un JSON impecable puede describir una acción equivocada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estado: previous_response_id frente a Conversations
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;previous_response_id&lt;/code&gt; es útil para enlazar el siguiente turno al anterior con una relación explícita. Es cómodo en una conversación corta o en un workflow donde tu base de datos guarda el último response ID por sesión. Las instrucciones de una llamada anterior no se arrastran automáticamente si pasas instrucciones nuevas: verifica ese comportamiento antes de asumir que una política quedó vigente.&lt;/p&gt;

&lt;p&gt;Conversations es una entidad de estado reutilizable para añadir y recuperar ítems entre respuestas. Encaja cuando necesitas una conversación estable que pueda sobrevivir a distintos dispositivos o workers. Aun así, no conviertas la Conversation en tu única fuente de verdad: conserva en tu base la identidad del usuario, el tenant, el estado de aprobación y referencias de auditoría.&lt;/p&gt;

&lt;p&gt;Mi regla: guarda solo IDs y contexto mínimo de producto; vuelve a resolver permisos, herramientas permitidas y policy en cada petición. El estado puede recordar la conversación, pero no debe heredar autoridad. Un usuario que pierde acceso a un proyecto no debería mantenerlo porque una conversación vieja lo mencionaba.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Streaming y background mode son flujos distintos
&lt;/h3&gt;

&lt;p&gt;Streaming usa eventos server-sent para pintar progreso o texto parcial con baja latencia. Es una decisión de experiencia de usuario; no conviertas cada delta en un registro de negocio ni ejecutes una tool al primer fragmento. Espera al elemento de function call completo y conserva una ruta clara de cancelación del cliente.&lt;/p&gt;

&lt;p&gt;Background mode sirve para respuestas largas que deben continuar aunque la petición web se corte. Creas la respuesta con &lt;code&gt;background=true&lt;/code&gt;, persistes su ID y consultas su estado o recibes el evento webhook correspondiente. El frontend no debería mantener una conexión abierta durante minutos solo para fingir que un job asíncrono es streaming.&lt;/p&gt;

&lt;p&gt;La consecuencia operativa importa: background mode conserva datos para poder hacer polling y no es compatible con Zero Data Retention. Revisa data controls, retención y la región de datos de tu organización antes de activarlo en flujos con información sensible. Para una tarea larga sin datos que deban salir, una cola propia y una llamada normal puede ser una alternativa más controlable.&lt;/p&gt;
&lt;h3&gt;
  
  
  Herramientas alojadas, MCP y límites de datos
&lt;/h3&gt;

&lt;p&gt;Responses API puede combinar funciones de tu aplicación con herramientas alojadas, como web search, file search, code interpreter o image generation, según modelo y disponibilidad. Cada una introduce otra frontera: cuota, tiempo, datos enviados y resultados que pueden estar equivocados o contener instrucciones externas.&lt;/p&gt;

&lt;p&gt;Los servidores MCP remotos son servicios de terceros. No les pases un token o documento solo porque una tool description sea atractiva. Delimita por servidor la URL, identidad, scopes, datos que puede recibir, rate limits y la aprobación para efectos externos. MCP conecta capacidades; no valida automáticamente su confianza.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usa &lt;code&gt;allowed_tools&lt;/code&gt; o un conjunto de tools por tarea cuando sea posible. Un agente de triage no necesita la misma superficie que uno de release. Reducir opciones también mejora la calidad: al modelo le cuesta menos elegir una tool cuando no le ofreces quince acciones parecidas con permisos distintos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitectura mínima que llevaría a producción
&lt;/h2&gt;

&lt;p&gt;Entrada autenticada → policy de tenant → creación de response → parser de output → validador de schema y negocio → executor idempotente → auditoría → &lt;code&gt;function_call_output&lt;/code&gt; → respuesta final. Si hay una acción sensible, añade una transición explícita de propuesta a aprobación: el modelo prepara payload y evidencia; una persona o regla independiente habilita la mutación.&lt;/p&gt;

&lt;p&gt;Mantén los executors fuera del prompt. Una tool debería ser una función estrecha, con nombre que explique el efecto, parámetros mínimos y un resultado redactado. &lt;code&gt;update_customer&lt;/code&gt; es demasiado grande; &lt;code&gt;propose_customer_address_change&lt;/code&gt; y &lt;code&gt;apply_approved_address_change&lt;/code&gt; dejan una frontera revisable.&lt;/p&gt;

&lt;p&gt;Mide más que éxito HTTP: porcentaje de tool calls válidas, denegadas por policy, reintentos idempotentes, aprobaciones, errores por tipo, latencia p50/p95, coste por workflow y tareas resueltas sin escalado. Una respuesta fluida puede ocultar que el modelo llama tres veces a una API o que el 20% de acciones queda bloqueado al final.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Checklist antes de habilitar una tool con efecto
&lt;/h3&gt;

&lt;p&gt;La tool expresa una única capacidad y no acepta campos libres que acaben en SQL, shell o URLs arbitrarias.&lt;/p&gt;

&lt;p&gt;El backend autentica al usuario y comprueba autorización por tenant, recurso y operación; el modelo no decide permisos.&lt;/p&gt;

&lt;p&gt;Los argumentos pasan JSON Schema y validación de negocio antes de llegar a un executor.&lt;/p&gt;

&lt;p&gt;Las mutaciones tienen una clave idempotente y un registro de resultado por operación de negocio.&lt;/p&gt;

&lt;p&gt;Las acciones externas o irreversibles muestran destino, payload, evidencia y riesgo antes de la aprobación.&lt;/p&gt;

&lt;p&gt;Las tools disponibles se reducen por tarea y se revisan al cambiar de modelo, prompt o integración.&lt;/p&gt;

&lt;p&gt;El estado conversacional no concede permisos persistentes y tiene una política de retención explícita.&lt;/p&gt;

&lt;p&gt;Streaming, background jobs y webhooks tienen timeouts, cancelación, reintentos y observabilidad propios.&lt;/p&gt;

&lt;p&gt;Hay evals con entradas ambiguas, argumentos inválidos, recursos de otro tenant y prompt injection indirecta.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Conclusión
&lt;/h3&gt;

&lt;p&gt;Responses API es una buena base cuando quieres control fino: te enseña exactamente cuándo el modelo habló, cuándo pidió una tool y cuándo tu sistema produjo un resultado verificable. Esa claridad vale más que una demo de agente que parece autónoma hasta que intenta escribir en producción.&lt;/p&gt;

&lt;p&gt;Empieza por una tool de lectura, un schema pequeño y una traza completa. Añade estado cuando haya una razón de producto, y background mode cuando el trabajo de verdad sea largo. La autonomía útil no consiste en dar más funciones al modelo: consiste en hacer que cada capacidad tenga una frontera, una evidencia y una forma segura de fallar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es OpenAI Responses API?
&lt;/h3&gt;

&lt;p&gt;Es la API unificada de OpenAI para crear respuestas con input multimodal, herramientas, streaming y estado conversacional. La salida puede incluir texto y elementos de tool calling, no solo una cadena.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Responses API sustituye a OpenAI Agents SDK?
&lt;/h3&gt;

&lt;p&gt;No necesariamente. Responses API ofrece el contrato de bajo nivel; Agents SDK puede ayudar a orquestar agentes. Si necesitas permisos y efectos controlados, debes implementar validación y autorización en cualquiera de las dos capas.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Function calling ejecuta mi función automáticamente?
&lt;/h3&gt;

&lt;p&gt;No. El modelo devuelve una propuesta de llamada; tu aplicación interpreta el output, valida argumentos y permisos, ejecuta si procede y devuelve un &lt;code&gt;function_call_output&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Para qué sirve previous_response_id?
&lt;/h3&gt;

&lt;p&gt;Enlaza una respuesta nueva con el contexto de la respuesta anterior. Es útil para turnos cortos, pero no sustituye una política de identidad, autorización o retención de datos.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuándo uso background mode?
&lt;/h3&gt;

&lt;p&gt;Cuando una respuesta puede durar más que la petición HTTP normal y quieres consultar su estado o recibir un webhook. Revisa antes su efecto en retención de datos y compatibilidad con Zero Data Retention.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Structured Outputs hace segura una acción?
&lt;/h3&gt;

&lt;p&gt;No. Hace más predecible el formato. Todavía debes validar negocio, scopes, tenant, recursos, límites, idempotencia y aprobación humana cuando exista efecto externo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo llevar una tool de Responses API de demo a producción
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Elegir una capacidad de lectura.&lt;/strong&gt; Empieza por una consulta reversible con un recurso claro, como recuperar metadata de un release aprobado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diseñar el schema.&lt;/strong&gt; Declara campos mínimos, tipos, allowlists y &lt;code&gt;additionalProperties: false&lt;/code&gt;; activa modo estricto cuando sea compatible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separar autorización.&lt;/strong&gt; Resuelve usuario, tenant, scopes y recurso en el backend antes de llamar a la fuente de datos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear el primer response.&lt;/strong&gt; Envía el input y solo las tools necesarias para esa tarea; registra el response ID y la versión de policy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interpretar function calls.&lt;/strong&gt; Procesa únicamente elementos completos de tipo function call; no ejecutes texto libre ni deltas de streaming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validar y ejecutar.&lt;/strong&gt; Comprueba schema y reglas de negocio, aplica rate limits e idempotencia y captura un resultado redactado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Devolver function_call_output.&lt;/strong&gt; Usa el call ID original y datos estructurados para que el siguiente response pueda explicar el resultado real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Añadir aprobación.&lt;/strong&gt; Separa propuesta y mutación cuando la acción escriba, envíe, despliegue o transfiera información.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preparar fallos.&lt;/strong&gt; Define errores de autorización, validación, proveedor y timeout; cada uno debe tener una recuperación distinta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medir y evaluar.&lt;/strong&gt; Prueba tenants cruzados, argumentos hostiles y retries; mide tools inválidas, bloqueos, coste, latencia y resolución.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/api-reference/responses" rel="noopener noreferrer"&gt;OpenAI API: Responses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/function-calling" rel="noopener noreferrer"&gt;OpenAI API: function calling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/structured-outputs" rel="noopener noreferrer"&gt;OpenAI API: Structured Outputs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/conversation-state" rel="noopener noreferrer"&gt;OpenAI API: conversation state&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/background" rel="noopener noreferrer"&gt;OpenAI API: background mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/streaming-responses" rel="noopener noreferrer"&gt;OpenAI API: streaming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/tools" rel="noopener noreferrer"&gt;OpenAI API: built-in tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/guides/your-data" rel="noopener noreferrer"&gt;OpenAI API: data controls&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/openai-agents-sdk-mcp-guardrails-tracing/" rel="noopener noreferrer"&gt;OpenAI Agents SDK: MCP, guardrails y tracing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/evaluacion-rag-produccion-metricas-datasets/" rel="noopener noreferrer"&gt;Evaluación RAG en producción&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/opentelemetry-genai-observabilidad-agentes/" rel="noopener noreferrer"&gt;OpenTelemetry GenAI para observar agentes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/prompt-injection-agentes-ia-seguridad-evals/" rel="noopener noreferrer"&gt;Prompt injection en agentes de IA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-produccion-seguridad-permisos-supply-chain/" rel="noopener noreferrer"&gt;MCP en producción: seguridad, permisos y supply chain&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>MCP Registry: cómo publicar y descubrir servidores MCP sin confiar a ciegas</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Thu, 13 Aug 2026 10:48:35 +0000</pubDate>
      <link>https://dev.to/khavel/mcp-registry-como-publicar-y-descubrir-servidores-mcp-sin-confiar-a-ciegas-874</link>
      <guid>https://dev.to/khavel/mcp-registry-como-publicar-y-descubrir-servidores-mcp-sin-confiar-a-ciegas-874</guid>
      <description>&lt;p&gt;El MCP Registry mejora el descubrimiento de servidores, no certifica que sean seguros. Aprende a publicar metadata reproducible y a construir una allowlist interna que trate cada servidor como una dependencia con privilegios.&lt;/p&gt;

&lt;p&gt;Un MCP Registry es un catálogo con una API estándar para describir y descubrir servidores MCP. El registro oficial publica metadata —nombre, versión, repositorio, paquete o endpoint remoto—; no hospeda tu binario ni convierte un servidor listado en seguro o adecuado para tu empresa.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;MCP Registry&lt;/code&gt;. La intención es técnica y práctica: un maintainer quiere publicar un servidor reproducible, y un equipo quiere descubrirlo sin transformar una búsqueda de herramientas en una puerta de entrada a paquetes y credenciales no revisados.&lt;/p&gt;

&lt;p&gt;Mi postura: usa el registro público como inventario y canal de distribución de metadata, no como una lista de confianza. La unidad de confianza sigue siendo una versión concreta de un artefacto, su código, sus tools, su identidad de ejecución y los permisos que le concedes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Qué es MCP Registry y qué problema resuelve
&lt;/h3&gt;

&lt;p&gt;MCP Registry es la especificación y el ecosistema de registros para servidores Model Context Protocol. El Official MCP Registry, en &lt;code&gt;registry.modelcontextprotocol.io&lt;/code&gt;, es un catálogo público de metadata y una API REST sobre la que pueden construirse marketplaces o sub-registros. Su valor es que un cliente no tenga que adivinar cómo encontrar, instalar o actualizar cada integración.&lt;/p&gt;

&lt;p&gt;La frase importante es metadata. Un &lt;code&gt;server.json&lt;/code&gt; puede apuntar a un paquete npm, PyPI, una imagen OCI o un endpoint remoto, junto a los transportes y la configuración de arranque. El registro no ejecuta ese servidor por ti ni inspecciona exhaustivamente lo que hará cuando tenga acceso a tu filesystem, red, OAuth o secretos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Eso separa tres cosas que se confunden con facilidad: descubrimiento (encontrar una ficha), procedencia (saber quién puede publicar un namespace) y confianza operativa (decidir si esta versión recibe permisos en tu entorno). El registro ayuda mucho con las dos primeras; la tercera es una política tuya.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnkm6jjzodhavccrllxhs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnkm6jjzodhavccrllxhs.png" alt="Diagrama conceptual que conecta código y paquete, metadata server.json, registro MCP público, allowlist privada y hosts de desarrollo; debajo aparecen controles de identidad, integridad, sandbox, aprobación y auditoría" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Un registro público resuelve discovery; la allowlist y los controles de ejecución resuelven el riesgo de introducir una nueva dependencia con capacidades de agente.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  El modelo mental correcto: catálogo, no sello de seguridad
&lt;/h3&gt;

&lt;p&gt;Que un servidor aparezca en un registro oficial no significa que sus dependencias sean benignas, que el maintainer siga controlando el paquete, que sus tool descriptions no hayan cambiado o que encaje con tus datos. La propia documentación lo presenta como un repositorio de información autodeclarada y, mientras siga en preview, avisa de posibles cambios incompatibles o resets de datos.&lt;/p&gt;

&lt;p&gt;Trátalo como tratarías npm: una ficha reduce fricción de discovery y aporta campos comparables; no sustituye revisión de código, lockfile, análisis de dependencias, firma, sandbox o permisos mínimos. En MCP el impacto puede ser mayor que en una librería de UI porque el proceso puede recibir secretos y ejecutar operaciones en nombre de un usuario.&lt;/p&gt;

&lt;p&gt;Una política sana empieza con esta pregunta: ¿qué puede leer, escribir, ejecutar o enviar este servidor después de instalarse? Si no puedes responderla para una versión fijada, no está listo para la allowlist, aunque tenga un nombre bonito, muchos installs o una referencia en un marketplace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  server.json: el contrato que publicas
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;server.json&lt;/code&gt; es la ficha versionada del servidor. Como mínimo declara un nombre único, descripción, versión, repositorio y una o más formas de distribución: &lt;code&gt;packages&lt;/code&gt; para artefactos instalables o &lt;code&gt;remotes&lt;/code&gt; para endpoints. Para un paquete también declara su &lt;code&gt;registryType&lt;/code&gt;, identificador, versión y transporte; para un remoto, URL y transporte compatible.&lt;/p&gt;

&lt;p&gt;No copies un ejemplo antiguo sin comprobar el schema que genera tu versión de &lt;code&gt;mcp-publisher&lt;/code&gt;. El formato evoluciona durante preview. La forma menos frágil de empezar es &lt;code&gt;mcp-publisher init&lt;/code&gt;, revisar el JSON resultante y validarlo en CI contra el schema actual antes de publicar. El contrato de registry no es el archivo de configuración con secretos que ejecuta el host.&lt;/p&gt;

&lt;p&gt;Un ejemplo deliberadamente mínimo para un paquete npm por STDIO sería este. Sustituye los nombres, controla la versión desde tu release y no incluyas valores de secretos: la ficha solo puede describir variables requeridas, no contenerlas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;server.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"io.github.acme/release-notes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MCP server for approved release-note data."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.4.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/acme/release-notes-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"packages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"registryType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"identifier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@acme/release-notes-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.4.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"transport"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stdio"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mantén la descripción factual y breve. También es entrada para hosts y modelos: una descripción ambigua, promocional o con instrucciones operativas largas aumenta el riesgo de que un agente elija una capability que no debería tener.&lt;/p&gt;

&lt;h2&gt;
  
  
  Namespace y procedencia: quién puede afirmar ese nombre
&lt;/h2&gt;

&lt;p&gt;El registro oficial asocia la publicación a un namespace. Para &lt;code&gt;io.github.*&lt;/code&gt; usa identidad de GitHub; para dominios propios puede verificar DNS o HTTP. Esa verificación evita que cualquiera publique bajo &lt;code&gt;com.tuempresa.*&lt;/code&gt;, pero no demuestra que todo el código de un repositorio o paquete sea seguro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;Elige un namespace que sobreviva a cambios de equipo. Si tu servidor es producto de una organización, un namespace de dominio verificado suele expresar mejor la propiedad que una cuenta personal. Documenta qué repositorio, pipeline y equipo pueden publicar y elimina permisos cuando alguien deja el proyecto.&lt;/p&gt;

&lt;p&gt;En CI, separa el token que publica el artefacto del mecanismo que publica la metadata. El quickstart del registro ofrece autenticación GitHub/OIDC; úsala para que el pipeline pueda probar origen sin guardar una sesión humana de larga duración. Protege la rama y exige revisión del cambio de &lt;code&gt;server.json&lt;/code&gt;, igual que harías con un workflow de release.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h3&gt;

&lt;p&gt;Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Versionado inmutable: publica un release, no una corrección silenciosa
&lt;/h2&gt;

&lt;p&gt;Cada publicación de un servidor necesita una versión única. Una vez publicada, la metadata de esa versión es inmutable; si debes corregir descripción, repositorio, paquete o endpoint, publica otra versión. El registro intenta ordenar SemVer y marca la versión apropiada como &lt;code&gt;latest&lt;/code&gt;, por lo que usar &lt;code&gt;1.4.0&lt;/code&gt; de forma consistente simplifica a clientes y humanos.&lt;/p&gt;

&lt;p&gt;No uses &lt;code&gt;latest&lt;/code&gt; como versión de paquete en una allowlist. Fija la versión del artefacto y conserva su integridad en un lockfile, digest OCI o checksum cuando aplique. &lt;code&gt;latest&lt;/code&gt; del registry es una conveniencia de discovery, no una orden para actualizar procesos de desarrollo sin revisar qué cambió.&lt;/p&gt;

&lt;p&gt;Cuando solo ajustes metadata, una prerelease de registry puede ser preferible a fingir que el binario cambió. Pero no ocultes una modificación real de tools o permisos detrás de un parche menor: para el consumidor, añadir &lt;code&gt;delete_repository&lt;/code&gt; es un cambio de riesgo aunque tu API siga siendo compatible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Publicar paso a paso desde CI
&lt;/h3&gt;

&lt;p&gt;El orden seguro es: compilar, probar y publicar el artefacto; verificar que es recuperable por su identificador y versión; generar o actualizar &lt;code&gt;server.json&lt;/code&gt;; validar schema y coherencia; autenticar el publisher con identidad de CI; publicar la metadata; y consultar la API para confirmar que la versión concreta aparece. Si publicas la ficha antes que el paquete, invitas a instalaciones rotas.&lt;/p&gt;

&lt;p&gt;Para npm, el registro pide que el paquete se vincule a su nombre MCP mediante &lt;code&gt;mcpName&lt;/code&gt;. Esa comprobación reduce la distancia entre metadata y paquete. Añade además tests que arranquen el paquete exactamente como lo describe el &lt;code&gt;server.json&lt;/code&gt;: comando, transporte, variables declaradas y un &lt;code&gt;initialize&lt;/code&gt; de prueba sin tocar datos reales.&lt;/p&gt;

&lt;p&gt;Un esqueleto de workflow puede ser tan simple como el siguiente. No es una receta para copiar secretos: el token OIDC y los permisos exactos dependen de tu proveedor y del namespace. La parte importante es que publicación sea una consecuencia de artefacto probado, no un comando manual desde un portátil.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;release.sh (esquema)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm ci
npm run build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;test
&lt;/span&gt;npm publish &lt;span class="nt"&gt;--access&lt;/span&gt; public

node scripts/assert-server-json.mjs server.json
mcp-publisher login github-oidc
mcp-publisher publish server.json

curl &lt;span class="nt"&gt;--fail&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt;   &lt;span class="s2"&gt;"https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.acme/release-notes"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Haz que &lt;code&gt;assert-server-json&lt;/code&gt; compare &lt;code&gt;name&lt;/code&gt;, versión, repositorio y paquete contra &lt;code&gt;package.json&lt;/code&gt; y la etiqueta Git. Es una comprobación pequeña que evita el fallo más tonto del ecosistema: publicar metadata de &lt;code&gt;1.4.0&lt;/code&gt; que instala sin querer &lt;code&gt;1.3.2&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Consumir la API sin mezclar discovery y ejecución
&lt;/h3&gt;

&lt;p&gt;La API v0.1 expone una lista de servidores y el detalle de una versión. Permite filtrar por &lt;code&gt;search&lt;/code&gt;, pedir solo &lt;code&gt;latest&lt;/code&gt; o sincronizar incrementalmente con &lt;code&gt;updated_since&lt;/code&gt;. Esto es suficiente para construir una vista de catálogo o un job que detecte cambios; no lo conviertas en un instalador automático para cada resultado nuevo.&lt;/p&gt;

&lt;p&gt;El patrón adecuado es ingestión → normalización → evaluación de política → aprobación → distribución. Tu job puede traer nuevas fichas a una base interna y marcar qué cambió, pero un servidor no pasa a ser ejecutable por un developer hasta que una persona o una regla verificable aprueba su versión, identidad, permisos y distribución.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Guarda la versión y la respuesta original que revisaste. Si el upstream se actualiza, compara el nombre del paquete, transporte, comando, URL, variables, tools observadas y permisos. Un cambio en cualquiera de ellos requiere reevaluación; no basta con que &lt;code&gt;version=latest&lt;/code&gt; avance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sub-registro privado: la capa que una empresa realmente necesita
&lt;/h2&gt;

&lt;p&gt;El registro oficial es para servidores públicamente accesibles; para un servicio interno o una dependencia aprobada solo para tu organización, crea un sub-registro privado o un catálogo compatible. GitHub documenta que una implementación v0.1 necesita endpoints de listado y detalle, además de CORS si un cliente lo consume desde navegador o IDE.&lt;/p&gt;

&lt;p&gt;El sub-registro no tiene que duplicar toda la funcionalidad del público. Empieza con una allowlist inmutable y explícita: ID interno, server name upstream, versión exacta, fuente, owner, clasificación de datos, scopes permitidos, transporte, fecha de revisión y fecha de caducidad. Si falta owner o fecha, el ítem caduca en vez de quedarse como excepción eterna.&lt;/p&gt;

&lt;p&gt;Puedes sincronizar fichas públicas como candidatos, pero no copies automáticamente todas. La ganancia real es cambiar la experiencia por defecto: el developer descubre únicamente servidores aprobados, y el host impide conexiones fuera de política cuando la plataforma lo permita.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Supply chain MCP: controles antes de dar una tool al modelo
&lt;/h3&gt;

&lt;p&gt;Antes de instalar un paquete local, verifica el publisher, repositorio y artefacto; fija versión y lockfile; analiza dependencias; ejecuta el proceso con filesystem, red y variables mínimas; y revisa el comando que el host va a lanzar completo. La recomendación de OWASP es clara: un servidor MCP local puede convertirse en una vía de sandbox escape, exfiltración o ejecución arbitraria si recibe acceso total por comodidad.&lt;/p&gt;

&lt;p&gt;Después de instalar, inspecciona también las tools: nombre, descripción, argumentos, outputs y destino. Las descripciones y schemas son superficie de prompt injection. Conserva un hash de la definición de tools que aprobaste y alerta si cambia; un servidor que hoy solo lee puede sufrir un rug pull mañana sin que cambie el nombre del paquete.&lt;/p&gt;

&lt;p&gt;Para servidores remotos, añade otra capa: validación TLS, URL exacta, OAuth con audiencia y scopes estrechos, egress controlado y rate limits. Una ficha de registry puede hacer visible un endpoint; no concede a ese endpoint derecho a recibir tokens de tu usuario. Para el flujo OAuth completo, consulta nuestra guía de OAuth 2.1 para MCP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  De la ficha al host: consentimiento y aislamiento
&lt;/h3&gt;

&lt;p&gt;El host debe enseñar qué se instala o conecta, qué comando se ejecutará en local, qué variables necesita y qué acciones expone. La aprobación del usuario no puede ser una tarjeta truncada con un botón «Conectar». Si el host no revela el comando completo, los permisos o la procedencia, el equipo pierde la evidencia necesaria para aprobarlo.&lt;/p&gt;

&lt;p&gt;Aísla servidores como dominios de seguridad independientes. Un servidor de documentación no necesita el token de un servidor de deploy ni acceso a todos los archivos del repositorio. Da una credencial por servidor y entorno, monta solo los directorios imprescindibles y bloquea red saliente salvo destinos que puedas justificar.&lt;/p&gt;

&lt;p&gt;Las mutaciones de impacto —escribir código, emitir una orden, cambiar un permiso, enviar datos fuera— deben seguir requiriendo aprobación con parámetros completos. Un registro resuelve cómo encontrar una tool; no decide cuándo un agente puede ejecutar una acción con consecuencias.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observabilidad y renovación de confianza
&lt;/h2&gt;

&lt;p&gt;Registra server name, versión, digest o lockfile, host, usuario o service account, tool, argumentos redactados, resultado, latencia y decisión de aprobación. Sin esa relación no podrás responder qué servidor consultó un dato o cambió un recurso cuando una alerta llegue semanas después.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo que conviene comprobar
&lt;/h3&gt;

&lt;p&gt;Configura dos bucles de revisión. El primero es de cambios: nueva versión, nuevo paquete, endpoint, comando, tool o scope reabre la evaluación. El segundo es temporal: cada entrada aprobada expira en 90 o 180 días y necesita un owner que confirme que sigue mantenida y con el mismo riesgo aceptable.&lt;/p&gt;

&lt;p&gt;Mide también fricción útil: solicitudes de alta, tiempo hasta revisión, instalaciones rechazadas, permisos denegados, tools poco usadas y cambios detectados. Si tu catálogo tarda semanas para un servidor de lectura de bajo riesgo, acabará apareciendo un bypass; si aprueba todo en cinco minutos, solo has creado una lista decorativa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist de publicación y consumo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;El nombre MCP pertenece a un namespace que controlas y la identidad de CI puede probarlo.&lt;/li&gt;
&lt;li&gt;Paquete o endpoint existen antes que la ficha y su versión coincide exactamente con &lt;code&gt;server.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El schema se valida en CI y el proceso se arranca en una prueba de integración sin secretos reales.&lt;/li&gt;
&lt;li&gt;Cada publicación usa una versión única; una corrección se publica como release nuevo, no se reescribe.&lt;/li&gt;
&lt;li&gt;La ficha no incluye secretos ni se confunde con el archivo de configuración runtime del host.&lt;/li&gt;
&lt;li&gt;El registro público entra en el flujo como fuente de discovery, nunca como allowlist automática.&lt;/li&gt;
&lt;li&gt;La allowlist interna fija versión, fuente, owner, datos, scopes, transporte, fecha de revisión y expiración.&lt;/li&gt;
&lt;li&gt;Los paquetes locales se fijan, escanean y ejecutan con sandbox, red, filesystem y credenciales mínimos.&lt;/li&gt;
&lt;li&gt;Las definiciones de tools se inspeccionan y se vuelven a aprobar si cambian.&lt;/li&gt;
&lt;li&gt;Las acciones sensibles muestran parámetros completos y requieren consentimiento o aprobación humana.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Conclusión
&lt;/h3&gt;

&lt;p&gt;MCP Registry es una pieza necesaria para que el ecosistema deje de repartir fragmentos de configuración por README y capturas. Estandariza discovery y metadata, y permite que clientes y empresas hablen el mismo idioma de catálogo. Eso es valioso, pero no es una auditoría de seguridad.&lt;/p&gt;

&lt;p&gt;Publica como maintainer con releases reproducibles, versiones inmutables y CI; consume como equipo con una allowlist, artefactos fijados, sandbox y reevaluación por cambios. Si conviertes un registry en «instalar lo que aparezca», acabas de automatizar la parte peligrosa de tu supply chain. Si lo usas para hacer explícitas procedencia y políticas, reduces fricción sin regalar privilegios.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ¿Qué es MCP Registry?
&lt;/h3&gt;

&lt;p&gt;Es un estándar y catálogo de metadata para descubrir servidores Model Context Protocol. El Official MCP Registry ofrece una API pública para que clientes y sub-registros consulten fichas de servidores.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿El MCP Registry oficial certifica que un servidor sea seguro?
&lt;/h3&gt;

&lt;p&gt;No. Ayuda a descubrir metadata y comprobar propiedad de namespaces, pero no sustituye revisión de código, integridad del artefacto, permisos mínimos, sandbox ni controles de ejecución.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué contiene server.json?
&lt;/h3&gt;

&lt;p&gt;Describe el nombre, versión, repositorio y cómo obtener o conectar el servidor, por ejemplo un paquete con transporte STDIO o un endpoint remoto. No debe almacenar secretos runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Puedo cambiar un servidor ya publicado?
&lt;/h3&gt;

&lt;p&gt;No se reescribe esa versión. Publica una versión nueva de &lt;code&gt;server.json&lt;/code&gt;; las versiones publicadas son inmutables y deben ser únicas.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Necesito un registro privado para mi empresa?
&lt;/h3&gt;

&lt;p&gt;Si quieres publicar servicios internos o aplicar una allowlist de servidores aprobados, sí. Puedes usar una implementación compatible v0.1 o un catálogo interno que fije versiones, owners, permisos y caducidad.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Debo instalar automáticamente los resultados del registry?
&lt;/h3&gt;

&lt;p&gt;No. Úsalo para discovery y somete cada versión a política: publisher, paquete o endpoint, dependencias, tools, scopes, sandbox y aprobación antes de habilitarla.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo publicar y gobernar un servidor con MCP Registry
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Definir el límite.&lt;/strong&gt; Enumera tools, datos, efectos y permisos; elimina capacidades que no pertenecen al primer release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publicar el artefacto.&lt;/strong&gt; Compila, prueba y publica el paquete o endpoint antes de crear la ficha de registry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vincular la procedencia.&lt;/strong&gt; Elige namespace, configura verificación GitHub, DNS o HTTP y limita quién puede publicar desde CI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generar server.json.&lt;/strong&gt; Usa &lt;code&gt;mcp-publisher init&lt;/code&gt;, declara versión exacta, repositorio y transporte sin incluir secretos runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validar en CI.&lt;/strong&gt; Comprueba schema, coherencia con package metadata y un arranque real que complete &lt;code&gt;initialize&lt;/code&gt; en sandbox.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publicar una versión.&lt;/strong&gt; Autentica el publisher con identidad de CI y registra la versión única; no reescribas releases publicados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verificar discovery.&lt;/strong&gt; Consulta el detalle de esa versión en la API y guarda la respuesta revisada como evidencia de release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear allowlist.&lt;/strong&gt; Fija versión, fuente, owner, clasificación de datos, scopes, transporte, revisión y fecha de expiración.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aislar ejecución.&lt;/strong&gt; Usa credenciales por servidor, filesystem y red mínimos, y aprobación humana para acciones sensibles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reevaluar cambios.&lt;/strong&gt; Altera paquete, endpoint, tool, schema o scope y obliga una revisión antes de avanzar a la nueva versión.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fuentes y referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/registry/about" rel="noopener noreferrer"&gt;MCP Registry: about&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/registry/quickstart" rel="noopener noreferrer"&gt;MCP Registry: quickstart para publicar un servidor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/registry/versioning" rel="noopener noreferrer"&gt;MCP Registry: versionado de servidores publicados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/registry/faq" rel="noopener noreferrer"&gt;MCP Registry: FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/modelcontextprotocol/registry/blob/main/docs/reference/api/official-registry-api.md" rel="noopener noreferrer"&gt;Official MCP Registry API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/security_best_practices" rel="noopener noreferrer"&gt;Model Context Protocol: Security Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/administer-copilot/manage-mcp-usage/configure-mcp-registry" rel="noopener noreferrer"&gt;GitHub Docs: configurar un MCP registry empresarial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/MCP_Security_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP MCP Security Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También te puede interesar&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-produccion-seguridad-permisos-supply-chain/" rel="noopener noreferrer"&gt;MCP en producción: seguridad, permisos y supply chain&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/oauth-21-mcp-servidores-remotos/" rel="noopener noreferrer"&gt;OAuth 2.1 para servidores MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/mcp-apps-ui-interactiva-agentes/" rel="noopener noreferrer"&gt;MCP Apps: UI interactiva para tools MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/prompt-injection-agentes-ia-seguridad-evals/" rel="noopener noreferrer"&gt;Prompt injection en agentes de IA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/docker-mcp-toolkit-agentes-locales/" rel="noopener noreferrer"&gt;Docker MCP Toolkit: agentes locales y seguridad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h3&gt;

&lt;p&gt;Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devaisemanal.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=spanish_digest#/portal/signup" rel="noopener noreferrer"&gt;Suscribirme gratis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
