<?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>Evaluación RAG en producción: métricas, datasets y gates antes de cambiar tu pipeline</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Mon, 06 Jul 2026 09:18:12 +0000</pubDate>
      <link>https://dev.to/khavel/evaluacion-rag-en-produccion-metricas-datasets-y-gates-antes-de-cambiar-tu-pipeline-i3j</link>
      <guid>https://dev.to/khavel/evaluacion-rag-en-produccion-metricas-datasets-y-gates-antes-de-cambiar-tu-pipeline-i3j</guid>
      <description>&lt;p&gt;Un RAG que responde bonito puede estar fallando justo donde importa: recuperar evidencia, citar contexto correcto y no inventar. Esta guía baja la evaluación RAG a ingeniería operable.&lt;/p&gt;

&lt;p&gt;Evaluación RAG en producción significa medir por separado recuperación, generación, groundedness, completitud, coste y regresiones. Si solo miras si la respuesta suena bien, estás evaluando una demo, no un sistema.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;evaluación RAG producción&lt;/code&gt;. La intención de búsqueda en español es práctica: construir un set de pruebas, elegir métricas y poner gates antes de cambiar embeddings, chunking, reranking, prompts o modelos.&lt;/p&gt;

&lt;p&gt;Mi postura: el primer dashboard de RAG no debería ser bonito. Debería decirte qué pregunta falló, qué documentos recuperó, qué evidencia faltó, qué parte inventó el modelo y qué cambio del pipeline lo provocó.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué problema resuelve la evaluación RAG
&lt;/h2&gt;

&lt;p&gt;RAG promete respuestas con fuentes, pero esa promesa se rompe en varias capas. Puede fallar el chunking, el embedding, el filtro por permisos, el reranker, el prompt, el modelo o el formato de citas. La respuesta final puede sonar razonable aunque la evidencia recuperada sea pobre.&lt;/p&gt;

&lt;p&gt;Por eso evaluar RAG como una sola caja negra es cómodo y peligroso. Necesitas separar al menos dos preguntas: &lt;code&gt;¿recuperé el contexto correcto?&lt;/code&gt; y &lt;code&gt;¿el modelo usó ese contexto sin inventar?&lt;/code&gt;. Si mezclas ambas, arreglarás prompts cuando el problema era retrieval, o tocarás embeddings cuando el modelo estaba ignorando fuentes buenas.&lt;/p&gt;

&lt;p&gt;La evaluación seria no intenta demostrar que el RAG funciona. Intenta encontrar dónde deja de funcionar antes que tus usuarios.&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%2Fgj8sj6r3fh1su21z3icn.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%2Fgj8sj6r3fh1su21z3icn.png" alt="Diagrama de evaluación RAG con corpus, dataset de preguntas, retrieval, generación, jueces, gates de CI y monitorización en producción" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;El pipeline sano mide componentes, no solo respuestas: dataset, retrieval, generación, jueces, umbrales, trazas y revisión humana de fallos.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  La arquitectura mental: dataset, pipeline, jueces y gates
&lt;/h2&gt;

&lt;p&gt;Un sistema de evaluación RAG tiene cuatro piezas. Primero, un dataset con preguntas reales, respuestas esperadas y, cuando se pueda, documentos relevantes. Segundo, una forma reproducible de ejecutar el pipeline contra esas preguntas. Tercero, evaluadores que midan retrieval y respuesta. Cuarto, gates que bloqueen cambios cuando hay regresión.&lt;/p&gt;

&lt;p&gt;El dataset no tiene que empezar grande. Prefiero 40 preguntas bien elegidas a 1.000 preguntas sintéticas que nadie revisó. Debe mezclar casos frecuentes, preguntas ambiguas, consultas con permisos, preguntas sin respuesta, cambios recientes y ejemplos donde el RAG haya fallado en producción.&lt;/p&gt;

&lt;p&gt;Los gates no deberían exigir perfección. Deberían exigir que no empeores lo que ya funcionaba y que los fallos importantes queden visibles. Un umbral imperfecto con trazas revisables gana a una promesa manual de que alguien revisará respuestas de vez en cuando.&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;from&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ragas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;evaluate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ragas.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Faithfulness&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AnswerRelevancy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ContextPrecision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ContextRecall&lt;/span&gt;

&lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&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;question&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;¿Cómo se rota una clave de API en producción?&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;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;run_rag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;¿Cómo se rota una clave de API en producción?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contexts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;run_rag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;¿Cómo se rota una clave de API en producción?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;contexts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ground_truth&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;Rotar clave, desplegar secreto nuevo, invalidar el anterior y auditar uso.&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="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&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;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Faithfulness&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;AnswerRelevancy&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;ContextPrecision&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;ContextRecall&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;MIN_SCORES&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;faithfulness&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer_relevancy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context_precision&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context_recall&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="p"&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;metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minimum&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;MIN_SCORES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&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="n"&gt;metric&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;score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;minimum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SystemExit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RAG regression: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &amp;lt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;minimum&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Métricas que sí separan el problema
&lt;/h2&gt;

&lt;p&gt;Context precision pregunta si los chunks recuperados eran útiles para responder. Es la métrica que castiga meter basura en el prompt. Un top-k lleno de documentos vagamente parecidos puede parecer generoso, pero baja precisión y encarece cada respuesta.&lt;/p&gt;

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

&lt;p&gt;Context recall pregunta si recuperaste la evidencia necesaria. Es la métrica que detecta el fallo contrario: el modelo responde mal porque el dato correcto nunca llegó al contexto. Si recall cae, tocar el prompt rara vez arregla el fondo.&lt;/p&gt;

&lt;p&gt;Faithfulness o groundedness mide si la respuesta está soportada por el contexto. Es el antídoto contra la alucinación con fuentes decorativas. Answer relevancy mide si la respuesta contesta la pregunta. Factual correctness o response completeness comparan contra una referencia cuando existe ground truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dataset: empieza pequeño, pero con dientes
&lt;/h2&gt;

&lt;p&gt;Un dataset útil para RAG debe guardar &lt;code&gt;query&lt;/code&gt;, &lt;code&gt;expected_answer&lt;/code&gt;, &lt;code&gt;expected_sources&lt;/code&gt; o qrels, usuario/tenant cuando hay permisos, categoría de pregunta, dificultad y notas de fallo. Si solo guardas pregunta y respuesta, no podrás saber si falló retrieval o generación.&lt;/p&gt;

&lt;p&gt;Incluye preguntas negativas: &lt;code&gt;no lo sé&lt;/code&gt;, documentos inexistentes, términos parecidos, permisos cruzados y datos obsoletos. Un RAG que siempre contesta es más peligroso que uno que sabe negarse.&lt;/p&gt;

&lt;p&gt;Cada incidente real debería producir al menos un caso de evaluación. Si soporte reporta una respuesta falsa, no lo cierres solo cambiando prompt. Añade una prueba que falle antes del fix y pase después. Ese hábito convierte producción en fuente de evals, no en un sitio donde repetir errores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieval: mide ranking, no solo similitud
&lt;/h2&gt;

&lt;p&gt;El retrieval no termina en embeddings. También importan filtros, permisos, búsqueda híbrida, reranking, deduplicación, ventanas de contexto y orden final. Un cambio de &lt;code&gt;top_k=5&lt;/code&gt; a &lt;code&gt;top_k=12&lt;/code&gt; puede mejorar recall y empeorar faithfulness porque mete ruido que el modelo no sabe ignorar.&lt;/p&gt;

&lt;p&gt;Cuando tienes documentos relevantes etiquetados, usa métricas de ranking como recall@k, MRR o NDCG. Cuando no los tienes, usa jueces LLM para estimar relevancia del contexto, pero conserva ejemplos revisables. Un juez sin auditoría puede esconder errores sistemáticos.&lt;/p&gt;

&lt;p&gt;Mi regla práctica: antes de cambiar embeddings o reranker, congela 30 consultas y compara exactamente qué documentos entran en el prompt. Si no puedes explicar diferencias de retrieval, todavía no estás haciendo optimización; estás tocando knobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generación: groundedness no es lo mismo que utilidad
&lt;/h2&gt;

&lt;p&gt;Una respuesta puede ser grounded y mala: cita el contexto correcto, pero no ayuda al usuario. Otra puede ser útil y peligrosa: contesta perfecto, pero añade una afirmación que no estaba en las fuentes. Por eso necesitas varias métricas, no una nota final.&lt;/p&gt;

&lt;p&gt;Groundedness mira precisión contra contexto: no inventar fuera de la evidencia. Completeness mira recall contra una respuesta esperada: no omitir partes críticas. Relevance mira si contestas la pregunta. Correctness mira si el contenido coincide con ground truth.&lt;/p&gt;

&lt;p&gt;Para decisiones de producto, muestra los fallos con trazas: pregunta, chunks, respuesta, score, razón del juez y diff contra versión anterior. Un número agregado sirve para ver tendencia; el ejemplo concreto sirve para arreglar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jueces LLM: útiles, pero no oráculos
&lt;/h2&gt;

&lt;p&gt;Los evaluadores basados en LLM son prácticos porque muchas respuestas no tienen una única cadena exacta. OpenAI Evals, LangSmith, Ragas, LlamaIndex, Microsoft Foundry y DeepEval convergen en la misma idea: define criterios, pasa ejemplos y usa jueces para puntuar dimensiones concretas.&lt;/p&gt;

&lt;p&gt;Pero un juez LLM también es un modelo. Debes fijar modelo, temperatura, prompt del juez, versión del dataset y umbrales. Si cambias el juez al mismo tiempo que cambias el RAG, no sabrás si mejoró el sistema o cambió la regla de medición.&lt;/p&gt;

&lt;p&gt;Reserva revisión humana para muestras de alto impacto: respuestas con baja confianza, discrepancias entre jueces, cambios grandes en ranking y preguntas de seguridad, privacidad o cumplimiento. La automatización reduce volumen; no elimina responsabilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo poner gates sin bloquear todo el equipo
&lt;/h2&gt;

&lt;p&gt;Divide los gates en tres niveles. En PR, ejecuta un subset pequeño y barato: smoke tests, preguntas críticas y regresiones recientes. En nightly, ejecuta dataset completo con métricas y comparación contra baseline. En producción, monitoriza muestras, feedback de usuario, coste y drift de recuperación.&lt;/p&gt;

&lt;p&gt;No uses un único umbral global. Un RAG legal, financiero o de soporte interno puede exigir groundedness muy alta. Un buscador exploratorio puede tolerar más ruido si cita fuentes y deja claro el nivel de confianza.&lt;/p&gt;

&lt;p&gt;Los gates deben fallar con información accionable. &lt;code&gt;faithfulness baja&lt;/code&gt; no basta. El informe debe decir qué pregunta, qué respuesta, qué chunks y qué cambio introdujo la regresión.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coste, latencia y evaluación continua
&lt;/h2&gt;

&lt;p&gt;Evaluar también cuesta. Si cada cambio dispara cien llamadas a un juez caro, el equipo acabará saltándose evals. Usa capas: métricas deterministas para retrieval cuando hay qrels, jueces baratos para smoke tests y jueces más fuertes para releases importantes.&lt;/p&gt;

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

&lt;p&gt;Mide coste por dimensión. Retrieval puede degradar por latencia antes de degradar calidad. Un reranker puede subir relevancia y duplicar coste. Un modelo generador mejor puede ocultar retrieval mediocre durante un tiempo. Sin costes por paso, la optimización queda incompleta.&lt;/p&gt;

&lt;p&gt;En producción, guarda traces suficientes: query normalizada, filtros aplicados, documentos candidatos, documentos finales, prompt, modelo, respuesta, scores y feedback. Sin trazas, cada bug de RAG se convierte en una discusión subjetiva.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errores comunes que veo en equipos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Evaluar solo diez preguntas felices porque son las que salen bien en demo.&lt;/li&gt;
&lt;li&gt;Cambiar chunking, embedding, reranker y prompt en el mismo PR.&lt;/li&gt;
&lt;li&gt;Medir respuesta final sin guardar documentos recuperados.&lt;/li&gt;
&lt;li&gt;Usar un juez LLM sin versionar su prompt ni revisar ejemplos fallidos.&lt;/li&gt;
&lt;li&gt;Optimizar answer relevancy mientras context recall está roto.&lt;/li&gt;
&lt;li&gt;No incluir preguntas sin respuesta, permisos, datos caducados y casos hostiles.&lt;/li&gt;
&lt;li&gt;Tratar las citas como HTML bonito en vez de evidencia verificable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Plan de adopción en cinco días
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Día 1: exporta 40 preguntas reales y clasifícalas por tipo, riesgo y frecuencia.&lt;/li&gt;
&lt;li&gt;Día 2: añade expected answer y fuentes esperadas para los casos donde tengas ground truth.&lt;/li&gt;
&lt;li&gt;Día 3: ejecuta tu pipeline actual y guarda respuesta, chunks, modelo, coste y latencia.&lt;/li&gt;
&lt;li&gt;Día 4: calcula context precision, context recall, faithfulness y answer relevancy; revisa manualmente los diez peores casos.&lt;/li&gt;
&lt;li&gt;Día 5: crea un gate de CI con subset crítico y un informe nightly con dataset completo.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;La evaluación RAG no va de encontrar la métrica perfecta. Va de crear una máquina de aprendizaje técnico: cada fallo produce un caso, cada cambio compara contra baseline y cada release sabe qué ganó y qué perdió.&lt;/p&gt;

&lt;p&gt;Mi recomendación es empezar menos ambicioso y más disciplinado: dataset pequeño, trazas completas, métricas separadas, gates modestos y revisión humana de fallos. Cuando eso funcione, amplía corpus, jueces y monitorización. El orden contrario produce dashboards bonitos y RAG frágil.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  ¿Qué es evaluación RAG?
&lt;/h3&gt;

&lt;p&gt;Evaluación RAG es el proceso de medir si un sistema retrieval-augmented generation recupera evidencia relevante y genera respuestas correctas, completas y fieles al contexto.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué métricas usar para RAG en producción?
&lt;/h3&gt;

&lt;p&gt;Empieza con context precision, context recall, faithfulness o groundedness, answer relevancy, correctness cuando tengas referencia, coste y latencia por paso.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Necesito ground truth para evaluar RAG?
&lt;/h3&gt;

&lt;p&gt;No siempre. Puedes evaluar relevancia y groundedness con query, contexto y respuesta, pero los casos con ground truth permiten medir recall, completitud y regresiones con más precisión.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Ragas, LangSmith, LlamaIndex o DeepEval?
&lt;/h3&gt;

&lt;p&gt;Elige según stack. Lo importante es versionar dataset, criterios, juez y baseline; la herramienta concreta importa menos que la disciplina de evaluación.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cuántas preguntas necesito para empezar?
&lt;/h3&gt;

&lt;p&gt;Con 30-50 preguntas reales y bien etiquetadas puedes detectar fallos importantes. Después amplía con incidentes, logs de búsqueda y casos sintéticos revisados.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿La evaluación automática reemplaza revisión humana?
&lt;/h3&gt;

&lt;p&gt;No. Reduce volumen y detecta regresiones, pero los fallos de alto impacto siguen necesitando revisión humana y trazas auditables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo montar una evaluación RAG mínima en producción
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Inventariar casos.&lt;/strong&gt; Reúne preguntas reales, incidentes, consultas frecuentes, preguntas sin respuesta y casos con permisos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Etiquetar evidencia.&lt;/strong&gt; Añade respuesta esperada y documentos relevantes cuando exista ground truth; marca categoría y riesgo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capturar trazas.&lt;/strong&gt; Guarda query, filtros, chunks candidatos, chunks finales, prompt, modelo, respuesta, coste y latencia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medir retrieval.&lt;/strong&gt; Calcula context precision, context recall y ranking cuando tengas documentos relevantes etiquetados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medir respuesta.&lt;/strong&gt; Evalúa groundedness, answer relevancy, completeness y correctness según el tipo de pregunta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear baseline.&lt;/strong&gt; Fija versión de dataset, prompt, modelo, judge y umbrales antes de optimizar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bloquear regresiones.&lt;/strong&gt; Ejecuta un subset crítico en PR y el dataset completo en nightly o antes de release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cerrar el bucle.&lt;/strong&gt; Convierte cada fallo real en una prueba nueva y revisa manualmente los casos de alto riesgo.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Regla operativa
&lt;/h2&gt;

&lt;p&gt;Activa la automatización donde el comentario pueda cambiar una decisión técnica, no donde solo vaya a producir ruido revisable.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;¿Te sirve esto?&lt;/strong&gt; Cada semana resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos, en español y sin ruido. &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;Suscríbete gratis a DevAI Semanal&lt;/a&gt;.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/" rel="noopener noreferrer"&gt;Ragas: available metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/langsmith/evaluate-rag-tutorial" rel="noopener noreferrer"&gt;LangSmith: evaluate a RAG application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/guides/evals" rel="noopener noreferrer"&gt;OpenAI API: working with evals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.llamaindex.ai/python/framework/module_guides/evaluating/" rel="noopener noreferrer"&gt;LlamaIndex: evaluating&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/foundry/concepts/evaluation-evaluators/rag-evaluators" rel="noopener noreferrer"&gt;Microsoft Foundry: RAG evaluators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deepeval.com/guides/guides-rag-evaluation" rel="noopener noreferrer"&gt;DeepEval: RAG evaluation guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/html/2504.14891v1" rel="noopener noreferrer"&gt;arXiv: Retrieval Augmented Generation Evaluation in the Era of Large Language Models&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>Claude Opus 4.8 vs GPT-5.5 — the actual 2026 price and context numbers</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Sun, 05 Jul 2026 11:43:29 +0000</pubDate>
      <link>https://dev.to/khavel/claude-opus-48-vs-gpt-55-the-actual-2026-price-and-context-numbers-266p</link>
      <guid>https://dev.to/khavel/claude-opus-48-vs-gpt-55-the-actual-2026-price-and-context-numbers-266p</guid>
      <description>&lt;p&gt;"Claude or GPT" is still the first question every team building on an LLM API asks, and the answer usually arrives as vibes. Here are the numbers instead. I maintain a catalog of model prices and lifecycles, so this is the current frontier-flagship comparison, pulled from each provider's own pricing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two flagships, side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;Claude Opus 4.8&lt;/strong&gt; (Anthropic)&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;GPT-5.5&lt;/strong&gt; (OpenAI)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Input / 1M tokens&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$5.00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$5.00&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output / 1M tokens&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$25.00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$30.00&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cached input / 1M&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context window&lt;/td&gt;
&lt;td&gt;1,000,000&lt;/td&gt;
&lt;td&gt;1,050,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Status&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The input price and the cached-input price are &lt;strong&gt;identical&lt;/strong&gt; ($5.00 and $0.50). The context windows are effectively tied at ~1M tokens. The one number that differs is &lt;strong&gt;output: GPT-5.5 charges 20% more&lt;/strong&gt; ($30 vs $25 per 1M).&lt;/p&gt;

&lt;h2&gt;
  
  
  Where that 20% actually matters
&lt;/h2&gt;

&lt;p&gt;Output-heavy vs input-heavy workloads land in different places, so a single "which is cheaper" verdict is wrong. Two concrete monthly examples:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input-heavy (RAG / long-context Q&amp;amp;A) — say 10M input + 2M output:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Opus 4.8: (10 × $5) + (2 × $25) = &lt;strong&gt;$100/mo&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;GPT-5.5: (10 × $5) + (2 × $30) = &lt;strong&gt;$110/mo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Output-heavy (agents / code generation) — say 2M input + 8M output:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Opus 4.8: (2 × $5) + (8 × $25) = &lt;strong&gt;$210/mo&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;GPT-5.5: (2 × $5) + (8 × $30) = &lt;strong&gt;$250/mo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So they're within ~10% on retrieval-style traffic, but Claude is ~16% cheaper once your workload is dominated by generated tokens — which is exactly the shape of agentic coding and long-form generation. If you're input-heavy, it's close enough that other factors (tokenizer, tool-use reliability, latency) decide it.&lt;/p&gt;

&lt;h2&gt;
  
  
  One caveat that trips everyone up: tokens aren't a shared unit
&lt;/h2&gt;

&lt;p&gt;Price-per-token comparisons quietly assume both models count tokens the same way. They don't. Anthropic and OpenAI use different tokenizers, so &lt;strong&gt;the same paragraph of English can be a different number of tokens on each&lt;/strong&gt;. A 5–15% difference in token count for the same text is normal, and it moves the real bill in the same direction as the price difference. Treat these figures as the starting point, then measure your own prompts on both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The third option people skip: Google undercuts both
&lt;/h2&gt;

&lt;p&gt;If you're anchored on "Claude vs GPT," you're comparing the two most expensive frontier options and ignoring the cheapest-per-quality tier:&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;Input / 1M&lt;/th&gt;
&lt;th&gt;Output / 1M&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 3.1 Pro&lt;/td&gt;
&lt;td&gt;$2.00&lt;/td&gt;
&lt;td&gt;$12.00&lt;/td&gt;
&lt;td&gt;Preview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 3.5 Flash&lt;/td&gt;
&lt;td&gt;$1.50&lt;/td&gt;
&lt;td&gt;$9.00&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 3.1 Flash-Lite&lt;/td&gt;
&lt;td&gt;$0.25&lt;/td&gt;
&lt;td&gt;$1.50&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On that same input-heavy 10M-in/2M-out workload, &lt;strong&gt;Gemini 3.5 Flash costs ~$33/mo&lt;/strong&gt; — roughly a third of either flagship — and Gemini 3.1 Flash-Lite is ~$5.50/mo. They won't match Opus 4.8 or GPT-5.5 on the hardest reasoning, but for classification, extraction, summarization, and most chat, paying frontier prices is a choice, not a requirement.&lt;/p&gt;

&lt;p&gt;And if raw cost is the only axis, open-weight and Chinese-lab models go lower still — DeepSeek-V4-Flash is ~$0.14/$0.28, Llama 3.1 8B ~$0.02/$0.03.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input-heavy work:&lt;/strong&gt; Opus 4.8 and GPT-5.5 are within ~10% — pick on capability/ergonomics, not price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output-heavy work (agents, code):&lt;/strong&gt; Claude Opus 4.8 is ~16% cheaper thanks to the $25 vs $30 output rate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-sensitive work:&lt;/strong&gt; don't default to either flagship — Gemini Flash is ~3× cheaper, and the value tier below that is another order of magnitude down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always&lt;/strong&gt; re-measure token counts on your own prompts; the per-token price is only half the bill.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I keep the full side-by-side (and every other pair) updated here: &lt;strong&gt;&lt;a href="https://aimodelwatch.dev/compare/claude-opus-4-8-vs-gpt-5-5" rel="noopener noreferrer"&gt;aimodelwatch.dev/compare/claude-opus-4-8-vs-gpt-5-5&lt;/a&gt;&lt;/strong&gt;. Prices change and models get deprecated without much warning — there's a free email alert on the site if you want a heads-up when a model you use changes price or gets a retirement date.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Numbers verified 2026-07-05 against platform.openai.com and ai.google.dev. Spot a figure that's drifted? Tell me — accuracy is the whole point.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>openai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Vercel AI SDK: cómo montar agentes en Next.js con streaming, tools y MCP</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Sat, 04 Jul 2026 09:20:36 +0000</pubDate>
      <link>https://dev.to/khavel/vercel-ai-sdk-como-montar-agentes-en-nextjs-con-streaming-tools-y-mcp-3da0</link>
      <guid>https://dev.to/khavel/vercel-ai-sdk-como-montar-agentes-en-nextjs-con-streaming-tools-y-mcp-3da0</guid>
      <description>&lt;p&gt;Vercel AI SDK no es solo una librería de chat. Bien usado, es la capa TypeScript que conecta UI, streaming, tools, MCP, salida estructurada, agentes y observabilidad sin casarte con un único proveedor de modelos.&lt;/p&gt;

&lt;p&gt;Vercel AI SDK es un toolkit TypeScript para construir productos de IA con streaming, chat UI, tool calling, salida estructurada, agentes y proveedores intercambiables. Su valor real aparece cuando dejas de tratarlo como un wrapper de &lt;code&gt;fetch&lt;/code&gt; y lo usas como contrato entre frontend, backend, tools y observabilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;Vercel AI SDK agentes Next.js&lt;/code&gt;. La intención de búsqueda en español es práctica: montar un chat o agente en Next.js que pueda transmitir tokens, llamar herramientas, validar JSON, integrarse con MCP y medirse en producción.&lt;/p&gt;

&lt;p&gt;Mi postura: AI SDK encaja muy bien si tu producto ya vive en TypeScript/Next.js y necesitas velocidad de iteración. No sustituye una arquitectura de permisos, persistencia ni evaluación; solo hace que la parte LLM tenga menos pegamento accidental.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué es Vercel AI SDK y qué no es
&lt;/h2&gt;

&lt;p&gt;Vercel AI SDK es una capa común para hablar con modelos, producir streams, definir tools, validar entradas y salidas, renderizar mensajes en UI y conectar proveedores. Su promesa no es que el modelo razone mejor, sino que tu aplicación tenga una interfaz estable para cambiar de modelo, añadir herramientas y operar el flujo sin reescribir media app.&lt;/p&gt;

&lt;p&gt;No es una base de datos, no es un sistema de permisos y no es una cola duradera. Si el agente necesita memoria, auditoría, trazabilidad de negocio o jobs largos, debes diseñar esas piezas aparte. El SDK puede orquestar llamadas y streams; la responsabilidad del producto sigue siendo tuya.&lt;/p&gt;

&lt;p&gt;El error habitual es empezar por el chat visual. El orden profesional es distinto: caso de uso, contrato de mensajes, tools permitidas, política de aprobación, límites de coste, persistencia, métricas y solo después UI.&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%2Fvhsrrmpd2igxptijma3w.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%2Fvhsrrmpd2igxptijma3w.png" alt="Diagrama de arquitectura de AI SDK en Next.js con cliente, route handler, agente, tools, MCP, datos y observabilidad" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Arquitectura mínima para llevar Vercel AI SDK de demo a producto: UI de chat, route handler, agente, tools tipadas, MCP, datos y métricas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitectura mínima en Next.js
&lt;/h2&gt;

&lt;p&gt;El patrón base en App Router es sencillo: el cliente usa &lt;code&gt;useChat&lt;/code&gt;, el servidor expone un &lt;code&gt;route.ts&lt;/code&gt;, el handler convierte mensajes de UI a mensajes de modelo, &lt;code&gt;streamText&lt;/code&gt; genera la respuesta y el resultado vuelve como stream compatible con la UI. Esa cadena parece trivial, pero define el contrato de producción.&lt;/p&gt;

&lt;p&gt;En el cliente, no trates &lt;code&gt;messages&lt;/code&gt; como texto plano. AI SDK trabaja con partes: texto, tool calls, aprobaciones, errores y metadatos. Si renderizas solo &lt;code&gt;message.content&lt;/code&gt;, perderás estados importantes. En aplicaciones reales, la UI debe saber si una herramienta está esperando aprobación, si falló o si produjo salida utilizable.&lt;/p&gt;

&lt;p&gt;En el servidor, la frontera importante es el route handler. Ahí defines modelo, system prompt, tools, límites de pasos, timeouts, abort signals, logging y tags de coste. Si esa lógica queda repartida entre componentes, server actions y helpers ocultos, luego no podrás auditar por qué el agente hizo algo.&lt;/p&gt;

&lt;p&gt;app/api/chat/route.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { convertToModelMessages, streamText, stepCountIs, tool } from "ai";
import { z } from "zod";

const tools = {
  buscarDocs: tool({
    description: "Busca documentación interna del producto",
    inputSchema: z.object({ query: z.string().min(3) }),
    outputSchema: z.object({ resumen: z.string(), fuentes: z.array(z.string()) }),
    execute: async ({ query }) =&amp;gt; searchDocs(query),
  }),
};

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: "openai/gpt-4.1",
    system: "Responde como asistente técnico. Cita fuentes internas cuando uses tools.",
    messages: await convertToModelMessages(messages),
    tools,
    stopWhen: stepCountIs(5),
  });

  return result.toUIMessageStreamResponse();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Salida estructurada con Zod&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { generateText, Output } from "ai";
import { z } from "zod";

const { output } = await generateText({
  model: "openai/gpt-4.1",
  output: Output.object({
    schema: z.object({
      riesgo: z.enum(["bajo", "medio", "alto"]),
      motivo: z.string(),
      acciones: z.array(z.string()),
    }),
  }),
  prompt: "Evalua este cambio antes de permitir que el agente lo aplique...",
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Streaming: dónde se gana y dónde se rompe
&lt;/h2&gt;

&lt;h2&gt;
  
  
  ¿Te está sirviendo? Hay una dosis cada semana
&lt;/h2&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;El streaming mejora percepción de velocidad, pero también cambia cómo piensas estados. Un endpoint clásico falla o responde. Un stream puede empezar bien, llamar una tool, pedir aprobación, emitir texto parcial, fallar en una tool y aun así dejar una conversación recuperable.&lt;/p&gt;

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

&lt;p&gt;Para un chat de soporte interno, streaming de texto basta. Para un agente que ejecuta herramientas, necesitas mostrar estados de tool, no solo palabras. El usuario debe entender si el agente está buscando, esperando permiso, ejecutando una acción o resumiendo resultados.&lt;/p&gt;

&lt;p&gt;Mi regla: cualquier tool que tarde más de dos segundos debe producir estado visible. Cualquier tool que cambie datos debe dejar rastro. Cualquier salida que se use en automatización debe validarse con schema antes de aceptarla.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools: contratos pequeños, permisos explícitos
&lt;/h2&gt;

&lt;p&gt;Las tools son la frontera de seguridad del agente. En AI SDK se definen con &lt;code&gt;inputSchema&lt;/code&gt; y, cuando tiene sentido, &lt;code&gt;outputSchema&lt;/code&gt;. Eso obliga a describir qué puede pedir el modelo y qué devuelve tu sistema. Si una tool acepta &lt;code&gt;string&lt;/code&gt; libre para ejecutar acciones, no tienes una tool: tienes un agujero con buena DX.&lt;/p&gt;

&lt;p&gt;Empieza con tools de lectura: buscar documentación, consultar tickets, recuperar métricas. Después añade mutaciones pequeñas: crear borrador, abrir issue, proponer patch. Las acciones irreversibles necesitan aprobación humana o una política automática muy estrecha.&lt;/p&gt;

&lt;p&gt;Las herramientas deben ser aburridas. Una tool buena hace una cosa, valida input, aplica permisos del usuario real, registra llamada, devuelve salida acotada y falla con errores interpretables. El modelo no debería decidir permisos por contexto conversacional.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP sin convertirlo en barra libre
&lt;/h2&gt;

&lt;p&gt;AI SDK puede consumir tools de servidores MCP, lo cual es útil si ya tienes conectores estandarizados. Pero MCP no elimina el problema de confianza. Un servidor remoto puede exponer muchas capacidades y el agente puede combinarlas de formas que no habías previsto.&lt;/p&gt;

&lt;p&gt;Para producción prefiero allowlists de tools, scopes por entorno y separación entre lectura y escritura. Un agente que resume documentación no necesita la misma superficie que un agente que abre pull requests o toca datos de cliente.&lt;/p&gt;

&lt;p&gt;La buena arquitectura trata MCP como un catálogo de capacidades, no como permiso universal. Descubrir herramientas dinámicamente es cómodo; aprobar cuáles entran en producción sigue siendo una decisión de ingeniería.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agentes: ToolLoopAgent no arregla un mal proceso
&lt;/h2&gt;

&lt;p&gt;El salto de &lt;code&gt;streamText&lt;/code&gt; a un agente aparece cuando quieres varios pasos: pensar, llamar tools, observar resultados, decidir si continuar y terminar. En AI SDK, el patrón de agente evita que escribas tú el bucle manual, pero no decide por ti cuándo parar ni qué acciones son seguras.&lt;/p&gt;

&lt;p&gt;Define &lt;code&gt;stopWhen&lt;/code&gt; con intención. Un límite de pasos demasiado alto puede consumir coste y tiempo sin mejorar respuesta. Un límite demasiado bajo corta workflows legítimos. Para empezar, usa pocos pasos, mide trayectorias reales y sube solo si hay evidencia.&lt;/p&gt;

&lt;p&gt;No llames agente a cualquier chat con tools. Un agente de producto debe tener objetivo, herramientas, estado observable, política de error, evaluación y dueño. Si no puedes explicar esos puntos, lo que tienes es una demo con autonomía estética.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured output: cuándo validar JSON
&lt;/h2&gt;

&lt;p&gt;Salida estructurada es la pieza que más rápido mejora calidad cuando el resultado alimenta otro sistema. Si el modelo decide prioridad, riesgo, campos de una tarea, clasificación o acciones siguientes, no aceptes markdown: pide objeto validado con schema.&lt;/p&gt;

&lt;p&gt;Esto no garantiza verdad, pero sí garantiza forma. La verdad se verifica con datos, tests o revisión. La forma se valida con Zod y tipos. Mezclar ambas cosas es una fuente clásica de bugs: un JSON válido puede ser una decisión equivocada.&lt;/p&gt;

&lt;p&gt;Úsalo para contratos internos: &lt;code&gt;decision&lt;/code&gt;, &lt;code&gt;confidence&lt;/code&gt;, &lt;code&gt;citations&lt;/code&gt;, &lt;code&gt;next\_actions&lt;/code&gt;, &lt;code&gt;requires\_approval&lt;/code&gt;. Si el objeto no pasa schema, la app debe pedir aclaración o degradar, no inventar campos.&lt;/p&gt;

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

&lt;p&gt;El valor de AI SDK en producción aumenta cuando lo conectas con métricas: modelo, tokens, latencia, tool calls, pasos, errores, finish reason, usuario, feature y coste estimado. Sin eso, solo sabrás que el chat 'a veces va lento' o que la factura subió.&lt;/p&gt;

&lt;p&gt;Vercel AI Gateway puede ayudar con routing, visibilidad y control de proveedores si tu despliegue ya está en Vercel. LiteLLM o gateways propios encajan mejor cuando necesitas una capa multi-cloud o políticas internas más fuertes. La decisión no es religiosa: elige el punto donde puedes medir y gobernar mejor.&lt;/p&gt;

&lt;p&gt;La métrica de negocio no es tokens por respuesta. Es tareas resueltas con intervención aceptable. Un agente barato que obliga a revisar todo puede salir caro. Un agente caro que elimina una hora semanal de trabajo repetitivo puede ser rentable.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Define una keyword técnica interna para cada flujo: soporte, análisis, extracción, copilot interno o agente de operaciones.&lt;/li&gt;
&lt;li&gt;Separa rutas de chat humano, generación estructurada y ejecución de acciones.&lt;/li&gt;
&lt;li&gt;Usa schemas para tool input, tool output y objetos que consumirá otro sistema.&lt;/li&gt;
&lt;li&gt;Aplica permisos fuera del prompt: usuario, tenant, recurso y acción.&lt;/li&gt;
&lt;li&gt;Añade aprobación para tools de escritura, pagos, despliegues, borrados o datos sensibles.&lt;/li&gt;
&lt;li&gt;Registra modelo, coste, latencia, pasos, tools, errores y usuario.&lt;/li&gt;
&lt;li&gt;Persistencia: guarda mensajes y eventos importantes, no solo el texto visible.&lt;/li&gt;
&lt;li&gt;Evalúa conversaciones reales antes de subir límites de pasos o tools.&lt;/li&gt;
&lt;li&gt;Documenta fallback: modelo alternativo, modo lectura, respuesta parcial o escalado humano.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cuándo elegir AI SDK frente a OpenAI Agents SDK, LangGraph o Cloudflare Agents SDK
&lt;/h2&gt;

&lt;p&gt;Elige Vercel AI SDK si tu producto está en TypeScript/Next.js y quieres integrar UI, streaming, tools y proveedores con baja fricción. Es especialmente fuerte cuando el frontend y el backend del producto se mueven juntos.&lt;/p&gt;

&lt;p&gt;Elige OpenAI Agents SDK si priorizas un stack centrado en OpenAI con tracing, guardrails y handoffs muy integrados. Elige LangGraph si necesitas orquestación explícita de grafos, checkpoints y workflows complejos en Python. Elige Cloudflare Agents SDK si el problema principal es runtime stateful con Durable Objects, WebSockets y scheduling cerca de la edge.&lt;/p&gt;

&lt;p&gt;La comparación honesta: AI SDK es probablemente la vía más directa para productos web TypeScript. No es necesariamente la mejor para workflows duraderos, agentes con estado complejo o entornos donde el frontend no importa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan de adopción en cinco días
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Día 1: monta un chat mínimo con &lt;code&gt;useChat&lt;/code&gt; y un route handler, sin tools. Mide latencia y errores.&lt;/li&gt;
&lt;li&gt;Día 2: añade una sola tool de lectura con &lt;code&gt;inputSchema&lt;/code&gt;, permisos y logging.&lt;/li&gt;
&lt;li&gt;Día 3: introduce salida estructurada para una decisión que hoy parseas desde texto.&lt;/li&gt;
&lt;li&gt;Día 4: añade una tool con &lt;code&gt;needsApproval&lt;/code&gt; y diseña la UI de aprobación.&lt;/li&gt;
&lt;li&gt;Día 5: conecta métricas de coste, pasos y errores; decide si necesitas MCP, gateway o agente multi-step.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Vercel AI SDK merece atención porque resuelve una parte concreta del problema: unir aplicaciones TypeScript con modelos, streams, tools y UI sin escribir pegamento distinto para cada proveedor. Eso es mucho, pero no es todo.&lt;/p&gt;

&lt;p&gt;La guía corta es esta: usa AI SDK para acelerar la capa de interacción con modelos; diseña tú la seguridad, persistencia, observabilidad y evaluación. Si esas cuatro piezas no existen, el SDK solo hará que llegues más rápido a una demo difícil de operar.&lt;/p&gt;

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

&lt;p&gt;¿Qué es Vercel AI SDK?&lt;/p&gt;

&lt;p&gt;Vercel AI SDK es un toolkit TypeScript para construir aplicaciones y agentes de IA con generación de texto, streaming, chat UI, tool calling, salida estructurada y múltiples proveedores de modelos.&lt;/p&gt;

&lt;p&gt;¿Vercel AI SDK sirve solo para Next.js?&lt;/p&gt;

&lt;p&gt;No. Tiene integración muy buena con Next.js, pero el core puede usarse en otros entornos TypeScript y frameworks compatibles.&lt;/p&gt;

&lt;p&gt;¿Cuándo usar &lt;code&gt;streamText&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Usa &lt;code&gt;streamText&lt;/code&gt; para experiencias interactivas donde el usuario necesita ver progreso, chat o respuesta incremental, especialmente en UI web.&lt;/p&gt;

&lt;p&gt;¿Cuándo usar salida estructurada?&lt;/p&gt;

&lt;p&gt;Usa salida estructurada cuando otro sistema vaya a consumir el resultado: clasificaciones, decisiones, extracción de datos, acciones siguientes o contratos de automatización.&lt;/p&gt;

&lt;p&gt;¿AI SDK reemplaza a MCP?&lt;/p&gt;

&lt;p&gt;No. MCP expone herramientas y contexto; AI SDK puede consumir esas tools y conectarlas al flujo de la app, pero sigues necesitando permisos, allowlists y observabilidad.&lt;/p&gt;

&lt;p&gt;¿Necesito AI Gateway?&lt;/p&gt;

&lt;p&gt;No siempre. Es útil si quieres routing, observabilidad y control de proveedores en Vercel. Si ya tienes gateway propio, evalúa si añade valor o duplica capas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo llevar Vercel AI SDK a producción en Next.js
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Elegir el flujo.&lt;/strong&gt; Decide si estás construyendo chat, extracción estructurada, agente multi-step o automatización con aprobación humana.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear el route handler.&lt;/strong&gt; Centraliza modelo, mensajes, tools, límites de pasos, timeouts y logging en un endpoint revisable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diseñar tools pequeñas.&lt;/strong&gt; Define &lt;code&gt;inputSchema&lt;/code&gt;, &lt;code&gt;outputSchema&lt;/code&gt;, permisos reales y errores interpretables para cada tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Añadir streaming UI.&lt;/strong&gt; Renderiza partes de mensaje, estados de tool y aprobaciones; no trates la respuesta como texto plano.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validar contratos.&lt;/strong&gt; Usa salida estructurada para decisiones que alimentan código, base de datos o workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrar MCP con allowlist.&lt;/strong&gt; Conecta solo tools necesarias y separa lectura de escritura por entorno y permiso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medir operación.&lt;/strong&gt; Registra coste, latencia, pasos, tool calls, errores y resultado de negocio antes de ampliar autonomía.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Regla operativa
&lt;/h2&gt;

&lt;p&gt;Activa la automatización donde el comentario pueda cambiar una decisión técnica, no donde solo vaya a producir ruido revisable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ai-sdk.dev/docs/introduction" rel="noopener noreferrer"&gt;AI SDK documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai-sdk.dev/docs/getting-started/nextjs-app-router" rel="noopener noreferrer"&gt;AI SDK Next.js App Router&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling" rel="noopener noreferrer"&gt;AI SDK tools and tool calling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai-sdk.dev/docs/ai-sdk-core/generating-structured-data" rel="noopener noreferrer"&gt;AI SDK structured data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai-sdk.dev/docs/agents" rel="noopener noreferrer"&gt;AI SDK agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai-sdk.dev/docs/ai-sdk-ui/chatbot" rel="noopener noreferrer"&gt;AI SDK UI chatbot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai-sdk.dev/docs/ai-sdk-core/mcp-tools" rel="noopener noreferrer"&gt;AI SDK MCP tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vercel.com/docs/ai-gateway" rel="noopener noreferrer"&gt;Vercel AI Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vercel/ai" rel="noopener noreferrer"&gt;vercel/ai GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&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;a href="https://devaisemanal.com/mcp-outputschema-structuredcontent-agentes/" rel="noopener noreferrer"&gt;MCP outputSchema y structuredContent&lt;/a&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;a href="https://devaisemanal.com/cloudflare-agents-sdk-durable-objects/" rel="noopener noreferrer"&gt;Cloudflare Agents SDK: agentes stateful&lt;/a&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;/p&gt;

&lt;h2&gt;
  
  
  Recibe una lectura semanal de herramientas IA para devs
&lt;/h2&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>Cursor Background Agents: cómo preparar entornos remotos sin regalar tu repo</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Fri, 03 Jul 2026 09:17:29 +0000</pubDate>
      <link>https://dev.to/khavel/cursor-background-agents-como-preparar-entornos-remotos-sin-regalar-tu-repo-3n4m</link>
      <guid>https://dev.to/khavel/cursor-background-agents-como-preparar-entornos-remotos-sin-regalar-tu-repo-3n4m</guid>
      <description>&lt;p&gt;Cursor Background Agents cambia el flujo de trabajo: agentes remotos, ramas propias y comandos automáticos. La parte difícil es diseñar permisos, entorno y revisión.&lt;/p&gt;

&lt;p&gt;Cursor Background Agents no es solo una función cómoda para lanzar tareas mientras haces otra cosa. Es un cambio de arquitectura: el agente trabaja en una máquina remota, clona un repositorio, ejecuta comandos, empuja una rama y deja un cambio revisable. Eso puede ahorrar contexto humano, pero también mueve permisos, secretos y ejecución fuera del portátil del desarrollador.&lt;/p&gt;

&lt;h2&gt;
  
  
  La idea duradera
&lt;/h2&gt;

&lt;p&gt;La lectura evergreen es clara: cualquier equipo que adopte agentes remotos necesita tratar el entorno como CI/CD con capacidad de edición, no como un chat más del editor. Si el agente tiene acceso a GitHub, internet y terminal auto-run, el control real no está en escribir mejores prompts. Está en configurar el repositorio, el entorno, los permisos y el proceso de revisión.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué hace distinto a un background agent
&lt;/h2&gt;

&lt;p&gt;Según la documentación de Cursor, los Background Agents crean agentes asíncronos que editan y ejecutan código en un entorno remoto. El flujo normal es conectar GitHub, elegir repositorio y rama base, lanzar una tarea y revisar después la rama o el PR resultante. También hay entrada desde web, móvil y API, lo que abre casos de uso de automatización más allá del editor de escritorio.&lt;/p&gt;

&lt;p&gt;Ese patrón cambia tres supuestos. Primero, el agente no depende de que tu portátil tenga todas las dependencias instaladas. Segundo, puede iterar con comandos de terminal sin pedir aprobación para cada paso como ocurre en algunos flujos foreground. Tercero, el trabajo queda preparado para handoff, revisión y colaboración.&lt;/p&gt;

&lt;p&gt;La contrapartida es que ya no basta con confiar en el entorno local. Tienes que decidir qué repos puede clonar la app, qué comandos puede lanzar el entorno, qué secretos llegan a la máquina y quién revisa el diff antes de mezclarlo.&lt;/p&gt;

&lt;h2&gt;
  
  
  El archivo environment.json como contrato
&lt;/h2&gt;

&lt;p&gt;Cursor documenta &lt;code&gt;.cursor/environment.json&lt;/code&gt; como la pieza que describe cómo preparar la máquina: comando de instalación, procesos persistentes y terminales que deben estar vivos durante la sesión. Es tentador meter ahí todo lo que hace funcionar el proyecto, pero conviene verlo como un contrato reproducible y mínimo.&lt;/p&gt;

&lt;p&gt;El comando &lt;code&gt;install&lt;/code&gt; debe ser idempotente. Si cada ejecución instala dependencias de forma distinta o depende de estado manual, el agente producirá bugs difíciles de reproducir. Los &lt;code&gt;terminals&lt;/code&gt; deben levantar servicios necesarios para validar cambios, no procesos auxiliares con acceso amplio a datos internos. Si necesitas Docker, Cursor permite preparar ese arranque, pero no conviene convertir la máquina en una réplica completa de producción.&lt;/p&gt;

&lt;p&gt;Un buen &lt;code&gt;environment.json&lt;/code&gt; se parece más a una receta de CI que a las notas personales de un desarrollador. Debe instalar lo necesario, arrancar lo justo y evitar pasos que descarguen binarios o scripts no fijados por versión sin revisión.&lt;/p&gt;

&lt;h2&gt;
  
  
  Permisos de GitHub: empieza pequeño
&lt;/h2&gt;

&lt;p&gt;Background Agents necesitan permisos de lectura y escritura sobre los repositorios donde van a trabajar. Ese permiso es potente: permite clonar, crear ramas y empujar cambios. La decisión correcta no es conectar toda la organización por comodidad, sino empezar con repositorios concretos y tareas acotadas.&lt;/p&gt;

&lt;p&gt;Para un piloto, limita el agente a repos de bajo riesgo o a mirrors sin secretos. Usa ramas base específicas, reglas de protección, revisiones obligatorias y checks de CI. Si el agente abre un PR, el merge debe seguir el mismo estándar que un cambio humano: tests, linters, revisión de seguridad y dueño técnico.&lt;/p&gt;

&lt;p&gt;El acceso a dependencias privadas y submódulos merece revisión aparte. Dar acceso a un monorepo puede implicar acceso transitivo a más código del que la tarea necesita. Si el objetivo es arreglar documentación, no debería requerir permisos sobre servicios críticos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto-run no es magia, es superficie de ataque
&lt;/h2&gt;

&lt;p&gt;La documentación de Cursor advierte que los background agents ejecutan comandos de terminal automáticamente para iterar sobre tests, y que eso introduce riesgo de exfiltración si una instrucción maliciosa consigue influir en el agente. Este punto es el centro de la guía: el problema no es que el agente pueda equivocarse, sino que un README, issue, fixture, log o dependencia puede intentar darle instrucciones hostiles.&lt;/p&gt;

&lt;p&gt;El mitigante práctico es reducir lo que un comando puede ver y enviar. No inyectes secretos de producción en el entorno. Usa tokens efímeros y con scope mínimo. Evita que tests de agente dependan de bases de datos reales. Bloquea publicación de artefactos sensibles en logs. Y trata cualquier salida generada por fuentes no confiables como datos, no como instrucciones.&lt;/p&gt;

&lt;p&gt;Si necesitas que el agente ejecute comandos peligrosos, el diseño debe cambiar: crea una tarea manual, exige aprobación humana o mueve esa validación a CI con credenciales controladas. Auto-run debe validar, no desplegar producción.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacidad y retención
&lt;/h2&gt;

&lt;p&gt;Cursor indica que Background Agents están disponibles con Privacy Mode, pero también que el código se conserva temporalmente para ejecutar el agente y que la ejecución ocurre en infraestructura remota. Eso no es necesariamente incompatible con un equipo serio, pero sí requiere una decisión explícita de privacidad.&lt;/p&gt;

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

&lt;p&gt;El checklist mínimo debería preguntar: qué repositorios pueden salir al entorno remoto, cuánto tiempo queda accesible la máquina, qué prompts y resúmenes se guardan, qué secretos se pasan, qué canales externos reciben notificaciones y qué ocurre si se desactiva Privacy Mode al iniciar una ejecución.&lt;/p&gt;

&lt;p&gt;La regla operativa es sencilla: no uses background agents para repositorios donde no puedas explicar el ciclo de vida del código y los secretos durante la ejecución. Si legal, seguridad o compliance no entienden el flujo, todavía no es un flujo listo para datos sensibles.&lt;/p&gt;

&lt;h2&gt;
  
  
  API y automatización
&lt;/h2&gt;

&lt;p&gt;La API de Background Agents permite crear y gestionar agentes programáticamente. Esto encaja con flujos como responder feedback, corregir bugs pequeños, actualizar documentación o generar PRs repetitivos. También abre el riesgo de crear una fábrica de cambios de baja calidad si no hay cola, límites y owners.&lt;/p&gt;

&lt;p&gt;Antes de automatizar, define qué tareas son aptas para agente remoto: issues con reproducción clara, cambios de documentación, refactors mecánicos, tests faltantes o migraciones pequeñas. No metas de entrada incidentes, seguridad crítica, cambios de billing o migraciones de datos.&lt;/p&gt;

&lt;p&gt;La API debe vivir detrás de presupuestos: número máximo de agentes activos, repos permitidos, etiquetas de issue admitidas, modelos autorizados, coste por tarea y revisión obligatoria. Si cualquier webhook puede lanzar un agente caro sobre cualquier repo, el problema no tardará en aparecer.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Crea un repositorio piloto sin secretos de producción.&lt;/li&gt;
&lt;li&gt;Conecta solo el repo necesario y revisa permisos de la app de GitHub.&lt;/li&gt;
&lt;li&gt;Define &lt;code&gt;.cursor/environment.json&lt;/code&gt; como receta mínima, reproducible e idempotente.&lt;/li&gt;
&lt;li&gt;Usa ramas protegidas y exige PR antes de mezclar cualquier cambio.&lt;/li&gt;
&lt;li&gt;Prohíbe secretos largos o de producción en el entorno del agente.&lt;/li&gt;
&lt;li&gt;Separa validación automática de despliegue real.&lt;/li&gt;
&lt;li&gt;Revisa logs para detectar comandos inesperados, descargas raras o salidas sensibles.&lt;/li&gt;
&lt;li&gt;Documenta qué fuentes del repo son instrucciones confiables y cuáles son datos.&lt;/li&gt;
&lt;li&gt;Mide coste por tarea, tasa de PR aceptado, tiempo de revisión y fallos de CI.&lt;/li&gt;
&lt;li&gt;Aumenta permisos solo cuando el piloto demuestre valor y control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cuándo no usarlo
&lt;/h2&gt;

&lt;p&gt;No usaría Background Agents para tareas donde el agente necesite explorar datos de clientes, secretos de producción o incidentes activos sin supervisión. Tampoco lo pondría a ejecutar migraciones destructivas, cambios de infraestructura o rotación de credenciales directamente desde el entorno remoto.&lt;/p&gt;

&lt;p&gt;El patrón sí encaja para tareas con frontera clara: arreglar tests rotos, preparar upgrades pequeños, actualizar docs, crear casos de prueba, refactorizar módulos aislados o investigar bugs reproducibles. Cuanto más claro sea el input y más barato sea revertir, mejor encaja el flujo.&lt;/p&gt;

&lt;p&gt;Si la tarea requiere juicio de producto, negociación con stakeholders o entender contexto no escrito, el background agent puede preparar evidencia, pero no debería cerrar la decisión.&lt;/p&gt;

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

&lt;p&gt;Cursor Background Agents es una pieza útil porque convierte trabajo de agente en ramas revisables y entornos remotos reproducibles. Pero esa utilidad aparece cuando el equipo lo trata como automatización de ingeniería, no como un permiso ilimitado para que el editor haga cosas en segundo plano.&lt;/p&gt;

&lt;p&gt;La secuencia responsable es simple: repo piloto, permisos mínimos, entorno reproducible, cero secretos de producción, PR obligatorio y medición. Después puedes abrir más casos de uso. Si empiezas conectando toda la organización y confiando en que los prompts sean suficientes, estás confundiendo productividad con ausencia de controles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regla operativa
&lt;/h2&gt;

&lt;p&gt;Activa la automatización donde el comentario pueda cambiar una decisión técnica, no donde solo vaya a producir ruido revisable.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.cursor.com/background-agent" rel="noopener noreferrer"&gt;Cursor Docs: Background Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.cursor.com/background-agent/api/overview" rel="noopener noreferrer"&gt;Cursor Docs: Background Agents API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.cursor.com/account/agent-security" rel="noopener noreferrer"&gt;Cursor Docs: Agent Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.cursor.com/background-agent/web-and-mobile" rel="noopener noreferrer"&gt;Cursor Docs: Web &amp;amp; Mobile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/codex/cloud/internet-access#risks-of-agent-internet-access" rel="noopener noreferrer"&gt;OpenAI: riesgos de prompt injection en agentes con internet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://labs.cloudsecurityalliance.org/wp-content/uploads/2026/04/CSA_research_note_teampcp-ai-tooling-supply-chain_20260409-csa-styled.pdf" rel="noopener noreferrer"&gt;Cloud Security Alliance: TeamPCP supply chain attacks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Recibe una lectura semanal de herramientas IA para devs.&lt;/strong&gt; Cada martes: Claude Code, Cursor, Copilot, MCP, agentes y herramientas nuevas. En espanol y sin ruido. &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;Suscribete gratis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Publicado originalmente en &lt;a href="https://devaisemanal.com/cursor-background-agents-entornos-remotos-seguridad/" rel="noopener noreferrer"&gt;devaisemanal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>15 AI models hit end-of-life in the next 90 days — the full table</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Thu, 02 Jul 2026 15:59:44 +0000</pubDate>
      <link>https://dev.to/khavel/15-ai-models-hit-end-of-life-in-the-next-90-days-the-full-table-33l0</link>
      <guid>https://dev.to/khavel/15-ai-models-hit-end-of-life-in-the-next-90-days-the-full-table-33l0</guid>
      <description>&lt;p&gt;If you build on hosted LLM APIs, model retirements are the quiet breakage: a model ID keeps working right up until the day it returns a 404, and the deprecation notice was a line in a changelog you didn't read.&lt;/p&gt;

&lt;p&gt;I maintain a catalog of model lifecycles, so here's a concrete, dated snapshot: &lt;strong&gt;15 models across 6 providers are scheduled to hit end-of-life within the next 90 days&lt;/strong&gt; (by 2026-09-30). Dates and replacements are from each provider's own docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Retires&lt;/th&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Model (API id)&lt;/th&gt;
&lt;th&gt;Official replacement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2026-07-23&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;o3-deep-research&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpt-5.5-pro&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-07-23&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;computer-use-preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpt-5.4-mini&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-07-23&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpt-5-codex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpt-5.5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-07-24&lt;/td&gt;
&lt;td&gt;DeepSeek&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;deepseek-chat&lt;/code&gt; (legacy alias)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deepseek-v4-flash&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-07-24&lt;/td&gt;
&lt;td&gt;DeepSeek&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;deepseek-reasoner&lt;/code&gt; (legacy alias)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deepseek-v4-flash&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-07-31&lt;/td&gt;
&lt;td&gt;Mistral&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mistral-small-3-2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mistral-small-2603&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-07-31&lt;/td&gt;
&lt;td&gt;Mistral&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mistral-nemo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ministral-3-8b-latest&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-08-05&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude-opus-4-1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude-opus-4-8&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-08-31&lt;/td&gt;
&lt;td&gt;Mistral&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mistral-medium-3-1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mistral-medium-latest&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-09-08&lt;/td&gt;
&lt;td&gt;Alibaba&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3-max&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3.7-max&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-09-08&lt;/td&gt;
&lt;td&gt;Alibaba&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3-max-preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3.7-max&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-09-08&lt;/td&gt;
&lt;td&gt;Alibaba&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3-6-max-preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3.7-max&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-09-14&lt;/td&gt;
&lt;td&gt;Amazon&lt;/td&gt;
&lt;td&gt;&lt;code&gt;amazon-nova-premier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;amazon.nova-2-lite-v1:0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-09-24&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sora-2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;— (no drop-in successor)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-09-24&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sora-2-pro&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;— (no drop-in successor)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  A few things worth flagging
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The DeepSeek ones are aliases, not models.&lt;/strong&gt; &lt;code&gt;deepseek-chat&lt;/code&gt; and &lt;code&gt;deepseek-reasoner&lt;/code&gt; are pointers; after 2026-07-24 they resolve to &lt;code&gt;deepseek-v4-flash&lt;/code&gt;. If you pinned the alias expecting stable behavior, the behavior changes under you — pin the concrete snapshot instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;claude-opus-4-1&lt;/code&gt; → &lt;code&gt;claude-opus-4-8&lt;/code&gt; is not a free swap.&lt;/strong&gt; The 4.7-generation tokenizer counts roughly 30–35% more tokens for the same text, so your per-request cost and context math shift even if the price-per-token looks similar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sora 2 / Sora 2 Pro have no listed drop-in replacement.&lt;/strong&gt; If a video pipeline depends on them, that's a migration to scope now, not in September.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to not get surprised by this
&lt;/h2&gt;

&lt;p&gt;The durable fix is to treat model lifecycle as a dependency you monitor, the same way you watch for CVEs or deprecated framework APIs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pin concrete model snapshots, never floating aliases, in anything you can't hotfix fast.&lt;/li&gt;
&lt;li&gt;Keep a list of the model IDs you actually call in production, and check their retirement dates on a schedule.&lt;/li&gt;
&lt;li&gt;Test the named replacement &lt;em&gt;before&lt;/em&gt; the retirement date — pricing, tokenizer, and output format can all move.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I keep the full, dated deprecation list (all providers, not just the next 90 days) updated here: &lt;strong&gt;&lt;a href="https://aimodelwatch.dev/deprecations" rel="noopener noreferrer"&gt;aimodelwatch.dev/deprecations&lt;/a&gt;&lt;/strong&gt;. If you want a heads-up when a model you use gets a retirement date, there's a free email alert on the site.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Data pulled 2026-07-02 from provider docs. If you spot a date that's drifted, tell me — accuracy is the whole point.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>machinelearning</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Cloudflare Agents SDK: cómo crear agentes con estado en Durable Objects</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Thu, 02 Jul 2026 09:11:24 +0000</pubDate>
      <link>https://dev.to/khavel/cloudflare-agents-sdk-como-crear-agentes-con-estado-en-durable-objects-2g56</link>
      <guid>https://dev.to/khavel/cloudflare-agents-sdk-como-crear-agentes-con-estado-en-durable-objects-2g56</guid>
      <description>&lt;p&gt;Cloudflare Agents SDK no es otro wrapper de prompts. Es un runtime TypeScript para agentes persistentes: cada instancia vive en un Durable Object con SQL, estado sincronizado, WebSockets, tareas programadas y herramientas MCP.&lt;/p&gt;

&lt;p&gt;Cloudflare Agents SDK es un runtime TypeScript para crear agentes de IA persistentes sobre Cloudflare Workers y Durable Objects. La diferencia importante frente a un endpoint serverless normal es que cada agente tiene identidad duradera, SQL local, estado sincronizado, conexiones WebSocket, tareas programadas y una ruta natural hacia MCP, Workflows y herramientas del ecosistema Cloudflare.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plan de despliegue.&lt;/strong&gt; TL;DR La keyword principal es &lt;code&gt;Cloudflare Agents SDK&lt;/code&gt;. La intención de búsqueda en español es práctica: entender qué es, cuándo usarlo frente a un backend propio o un framework de agentes Python, y cómo diseñar una arquitectura mínima sin convertir el agente en un servicio opaco. Mi postura: merece la pena cuando el producto necesita sesiones vivas, memoria por usuario o equipo, eventos, WebSockets, scheduling y acciones largas. Para una llamada aislada al modelo, es demasiada plataforma; usa una API directa y guarda la complejidad para cuando el agente tenga ciclo de vida real.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Qué es Cloudflare Agents SDK y qué no es
&lt;/h2&gt;

&lt;p&gt;Una definición citable: Cloudflare Agents SDK es una capa de runtime para agentes stateful donde una clase &lt;code&gt;Agent&lt;/code&gt; encapsula estado, conexiones, métodos invocables, llamadas a modelos, herramientas, errores y tareas programadas, ejecutándose sobre Durable Objects.&lt;/p&gt;

&lt;p&gt;No es un modelo, no es un prompt mágico y no reemplaza la disciplina de producto. El SDK te da primitivas para que un agente recuerde, despierte, reciba eventos, coordine trabajo y hable con clientes en tiempo real. La calidad sigue dependiendo de tus tools, permisos, evals, límites y diseño del workflow.&lt;/p&gt;

&lt;p&gt;La lectura práctica es esta: Cloudflare intenta convertir el problema de &lt;code&gt;dónde vive mi agente&lt;/code&gt; en infraestructura gestionada. En lugar de reconstruir sesión, memoria, WebSocket, cola y cron en piezas separadas, puedes colgarlo de una instancia direccionable por nombre.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Briefing.&lt;/strong&gt; El modelo mental: agente como micro-servidor duradero Cada instancia de agente se parece más a un pequeño servidor con identidad que a una función stateless. Si el agente representa a un usuario, una sala, un ticket, un repositorio o un tenant, el mismo identificador devuelve la misma instancia. Eso elimina mucho pegamento: no tienes que sincronizar manualmente memoria conversacional entre Lambda, Redis, base de datos y WebSocket gateway. El coste conceptual es que debes diseñar fronteras de instancia. Un agente por usuario facilita privacidad y preferencias. Un agente por equipo facilita colaboración. Un agente por repositorio facilita automatización de desarrollo. Mezclar todo en un agente global suele acabar en permisos borrosos y estado difícil de auditar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La pregunta buena no es &lt;code&gt;¿puedo hacer un chatbot?&lt;/code&gt;. La pregunta buena es: ¿qué entidad del producto necesita recordar, recibir eventos, ejecutar tareas y mantener conexiones? Esa entidad debería mapearse a una instancia de agente.&lt;/p&gt;

&lt;p&gt;La idea sana: el modelo razona dentro de un runtime con identidad, estado y límites; no dentro de un endpoint que olvida todo al devolver la respuesta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitectura mínima que sí desplegaría
&lt;/h2&gt;

&lt;p&gt;La versión mínima seria tiene seis piezas. Primero, una clase &lt;code&gt;Agent&amp;lt;Env, State&amp;gt;&lt;/code&gt; con un estado pequeño y serializable. Segundo, &lt;code&gt;routeAgentRequest&lt;/code&gt; para enrutar peticiones a instancias por nombre. Tercero, una política explícita de nombres: usuario, equipo, sala, ticket o repositorio. Cuarto, SQL local solo para datos que pertenecen a esa instancia. Quinto, WebSockets o SSE solo cuando el usuario necesita ver progreso. Sexto, observabilidad y límites antes de tools mutantes.&lt;/p&gt;

&lt;p&gt;No empezaría conectando Browser, MCP, pagos, email y Workflows el día uno. Empezaría con una tarea de lectura, una tool controlada y un estado mínimo. Cuando eso sea observable, añadiría scheduling. Cuando scheduling no baste para trabajo largo con reintentos, movería esa parte a Workflows.&lt;/p&gt;

&lt;p&gt;La arquitectura debe dejar claro qué vive en el agente y qué vive fuera. Preferencias, progreso y memoria local encajan en el agente. Datos de negocio compartidos, billing, permisos corporativos y auditoría de largo plazo suelen pertenecer a sistemas externos que el agente consulta con credenciales limitadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Código mínimo: estado, routing y RPC
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;routeAgentRequest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;agents&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;lastTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepoAgent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;lastTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;callable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;summarizeRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Aqui llamarias a un modelo y a tools de lectura con permisos limitados.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Resumen pendiente para: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;routeAgentRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;ExportedHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Env&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;El detalle que importa no es la sintaxis del contador. Es el contrato: estado pequeño, método invocable, actualización explícita y routing que devuelve siempre la misma instancia cuando el nombre coincide. Eso hace posible reanudar trabajo sin inventarte otro session store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurar Durable Objects sin olvidar migraciones
&lt;/h2&gt;

&lt;p&gt;Agents SDK depende de Durable Objects. En &lt;code&gt;wrangler.jsonc&lt;/code&gt;, cada clase de agente necesita binding y migración SQLite. Si cambias el nombre de la clase o creas otro tipo de agente, trátalo como cambio de infraestructura, no como refactor inocente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&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;"durable_objects"&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;"bindings"&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;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;"RepoAgent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"class_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;"RepoAgent"&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;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"migrations"&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;span class="nl"&gt;"tag"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"new_sqlite_classes"&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="s2"&gt;"RepoAgent"&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;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;Mi regla: versiona la configuración junto al agente y revisa migraciones en PR. Un agente con memoria persistente no se comporta como una función desechable; si rompes identidad o esquema, rompes continuidad para usuarios reales.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estado: cuándo usar &lt;code&gt;setState&lt;/code&gt; y cuándo usar SQL
&lt;/h2&gt;

&lt;p&gt;Usa &lt;code&gt;setState&lt;/code&gt; para el estado pequeño que el cliente necesita ver sincronizado: fase actual, progreso, última acción, preferencias simples o bandera de aprobación. Es persistente, se guarda en SQLite y se sincroniza en tiempo real con clientes conectados.&lt;/p&gt;

&lt;p&gt;Usa &lt;code&gt;this.sql&lt;/code&gt; para historial, filas consultables, eventos, resultados intermedios o datos que no quieres enviar enteros a cada cliente. La tentación de meter todo en &lt;code&gt;state&lt;/code&gt; es fuerte porque funciona rápido; también es la forma más fácil de crear payloads enormes y acoplar UI con almacenamiento interno.&lt;/p&gt;

&lt;p&gt;Estado de agente no es memoria infinita para el LLM. Si usas estado como contexto del modelo, resume y selecciona. Poner transcripciones completas en cada turno dispara coste, latencia y riesgo de prompt injection acumulada.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Briefing.&lt;/strong&gt; Scheduling: agentes que despiertan sin usuario El scheduling es una de las razones reales para usar este runtime. Puedes programar una tarea con retraso, fecha concreta, cron o intervalo, y la tarea sobrevive reinicios porque queda persistida. Por debajo, Cloudflare usa Durable Object alarms para despertar la instancia.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DigestAgent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;onRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 8 * * *&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dailyDigest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev-team&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Digest scheduled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;dailyDigest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runs&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// Generar resumen, consultar fuentes y enviar notificacion. } }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No usaría scheduling para procesos de horas con reintentos complejos y compensaciones. Ahí entran Workflows. Scheduling es ideal para recordatorios, polling prudente, reintentos simples, digest diarios y mantenimiento de una instancia concreta.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lectura práctica.&lt;/strong&gt; Workflows: cuándo sacar trabajo del turno interactivo Un turno de chat debería mantenerse explicable. Si el agente necesita investigar durante minutos, coordinar pasos con reintentos o garantizar ejecución aunque se corte la conexión, separa el trabajo en Workflows. El agente puede iniciar el workflow, persistir estado visible y recibir resultado o progreso. La diferencia mental: el agente conserva identidad y conversación; Workflows ejecuta procesos duraderos. Juntos sirven para casos como análisis de repositorios, informes programados, procesamiento de tickets, migraciones asistidas o tareas que deben sobrevivir despliegues. El error frecuente es meter todo en el método &lt;code&gt;onChatMessage&lt;/code&gt;. Eso produce demos espectaculares y producción frágil. Si una operación tiene fases, presupuesto y retry policy, dale forma de workflow o de tarea programada, no de respuesta improvisada.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  MCP: conectar herramientas sin abrir toda la cuenta
&lt;/h2&gt;

&lt;p&gt;Cloudflare Agents puede consumir MCP y también servir herramientas mediante MCP. Eso encaja muy bien con agentes internos: el agente mantiene sesión y permisos locales, mientras MCP expone capacidades concretas a modelos o clientes compatibles.&lt;/p&gt;

&lt;p&gt;Pero MCP no es una licencia para conectar toda tu infraestructura. Usa OAuth o credenciales por ámbito, separa lectura de escritura, registra tool calls y limita qué servidores puede usar cada tipo de agente. Si el agente opera sobre Cloudflare, GitHub o sistemas internos, el blast radius lo define tu política de tools, no el SDK.&lt;/p&gt;

&lt;p&gt;Para DevAI, la pauta sería: MCP para capacidades bien acotadas, output estructurado para resultados auditables y revisión humana para acciones irreversibles. Sin esas tres cosas, solo has creado una consola de administración con lenguaje natural.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSockets y cliente React: progreso sin polling torpe
&lt;/h2&gt;

&lt;p&gt;El cliente puede conectarse al agente con &lt;code&gt;useAgent&lt;/code&gt; o &lt;code&gt;useAgentChat&lt;/code&gt;. Eso permite leer estado sincronizado, invocar métodos y mostrar progreso sin montar un gateway WebSocket separado. Para UIs de chat, &lt;code&gt;AIChatAgent&lt;/code&gt; y &lt;code&gt;useAgentChat&lt;/code&gt; añaden persistencia de mensajes y recuperación de streams.&lt;/p&gt;

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

&lt;p&gt;No pondría todo el producto dentro del hook. La UI debe tratar el agente como runtime de interacción, no como base de datos global. El patrón limpio es: estado visible en el agente, datos de negocio en APIs normales, y eventos largos como progreso o milestones.&lt;/p&gt;

&lt;p&gt;Si el usuario cierra la pestaña o se cae la conexión, la promesa del runtime es que pueda volver a la misma instancia. Diseña la UI para esa realidad: muestra última fase, último error, siguiente acción disponible y si hay aprobación humana pendiente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seguridad y permisos: el agente no es el perímetro
&lt;/h2&gt;

&lt;p&gt;Cloudflare te da identidad duradera del agente, pero eso no equivale a autorización de negocio. Comprueba usuario, tenant y permisos en cada acción sensible. El nombre de instancia ayuda a enrutar; no debería ser el único control de acceso.&lt;/p&gt;

&lt;p&gt;Separa secrets por entorno, scope y tool. Un agente de soporte no necesita credenciales de despliegue. Un agente de repositorio no necesita escribir en billing. Un agente que genera resúmenes no necesita ejecutar acciones mutantes. Lo aburrido sigue siendo lo correcto: mínimo privilegio, allowlists, logs y revisión humana.&lt;/p&gt;

&lt;p&gt;También vigilaría prompt injection persistente. Un agente que recuerda instrucciones, páginas visitadas o resultados de tools puede acumular datos hostiles. Resume, etiqueta procedencia y evita que contenido recuperado se convierta en instrucciones del sistema.&lt;/p&gt;

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

&lt;p&gt;Mide por instancia y por tipo de trabajo: turnos, tools, modelo, tokens, duración, reintentos, errores, tareas programadas y workflows iniciados. Si usas AI Gateway, aprovecha caching, rate limits, fallback y logs para ver consumo real en vez de adivinarlo por factura.&lt;/p&gt;

&lt;p&gt;La métrica que más me interesa no es &lt;code&gt;mensajes respondidos&lt;/code&gt;. Es &lt;code&gt;decisiones útiles completadas sin intervención peligrosa&lt;/code&gt;. Un agente que contesta mucho pero dispara workflows innecesarios, llama tools caras o requiere revisión manual constante no está ahorrando tiempo.&lt;/p&gt;

&lt;p&gt;Para producción pondría presupuestos por agente, por usuario y por acción. Cuando un agente cruza umbral, debe degradar: modelo más barato, menos contexto, cola asíncrona o pedir aprobación. Sin degradación, el primer incidente será coste o permisos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Briefing.&lt;/strong&gt; Cuándo elegir Cloudflare Agents SDK frente a LangGraph, ADK u OpenAI Agents SDK Elige Cloudflare Agents SDK si el problema principal es runtime: identidad duradera, WebSockets, estado por instancia, scheduling, Workers, Durable Objects, Workflows y herramientas cerca de la edge. Encaja especialmente en productos web que necesitan agentes vivos por usuario, equipo, canal o recurso. Elige LangGraph si el núcleo del problema es orquestación explícita de estados y grafos complejos en Python. Elige Google ADK si tu stack está en Google Cloud y quieres sesiones, evals y despliegue dentro de ese ecosistema. Elige OpenAI Agents SDK si priorizas handoffs, guardrails y tracing alrededor de modelos OpenAI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La comparación honesta: Cloudflare no gana por tener el mejor loop de razonamiento. Gana cuando quieres dejar de fabricar infraestructura alrededor del loop. Si tu equipo ya tiene backend robusto, colas, WebSockets y cron bien resueltos, el valor incremental baja.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lectura práctica.&lt;/strong&gt; Checklist de producción Define la entidad que representa cada instancia de agente: usuario, equipo, sala, ticket, repo o proceso. Mantén &lt;code&gt;state&lt;/code&gt; pequeño, serializable y visible; usa SQL para historial y eventos consultables. Configura Durable Object bindings y migraciones como parte revisada del despliegue. Separa tools de lectura y escritura; aplica credenciales de mínimo privilegio. Usa scheduling para tareas simples y Workflows para procesos largos con reintentos. Instrumenta turnos, tools, tokens, latencia, errores, tareas y workflows por instancia. Añade revisión humana para acciones irreversibles o con coste relevante. Protege el agente contra prompt injection persistente: procedencia, resumen y límites de contexto. Prueba reconexión, hibernación, despliegue y recuperación antes de anunciarlo como producción.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Plan de adopción en cinco días
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Día 1: elige una entidad clara, por ejemplo &lt;code&gt;repo-agent/&amp;lt;owner&amp;gt;/&amp;lt;repo&amp;gt;&lt;/code&gt; o &lt;code&gt;support-agent/&amp;lt;ticket-id&amp;gt;&lt;/code&gt;, y crea un agente sin tools mutantes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Día 2: añade estado mínimo, SQL para eventos y una UI que muestre fase, último error y progreso.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Día 3: conecta un modelo y una sola tool de lectura. Mide tokens, latencia y errores por instancia.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Día 4: añade scheduling para una tarea real, como digest diario, revisión de cola o reintento con backoff.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Día 5: decide si necesitas MCP, Workflows o ambos. Si no puedes explicar permisos y recuperación, no añadas más herramientas todavía.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Cloudflare Agents SDK es interesante porque ataca una parte poco glamourosa de los agentes: dónde viven, cómo recuerdan, cómo se reconectan, cómo despiertan y cómo ejecutan trabajo duradero. Eso no convierte cualquier chatbot en producto, pero sí reduce mucha infraestructura accidental.&lt;/p&gt;

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

&lt;p&gt;Mi recomendación es usarlo cuando el agente tenga vida propia: sesiones, estado, eventos, scheduling, progreso y tools. Si solo necesitas transformar un input en JSON, no lo compliques. Pero si estás construyendo un agente que acompaña a un usuario o equipo durante horas o días, Durable Objects como runtime empiezan a tener mucho sentido.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;¿Qué es Cloudflare Agents SDK?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cloudflare Agents SDK es un SDK TypeScript para crear agentes de IA persistentes sobre Workers y Durable Objects, con estado, SQL local, WebSockets, scheduling, Workflows y soporte MCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cloudflare Agents SDK requiere Durable Objects?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sí. El modelo de identidad, estado persistente, SQL y conexiones del agente se apoya en Durable Objects y sus bindings de configuración.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Puedo usar OpenAI o Anthropic con Cloudflare Agents SDK?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sí. El runtime puede usar Workers AI o proveedores externos como OpenAI, Anthropic y Gemini; la elección del modelo no es lo mismo que la elección del runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cuándo usar scheduling y cuándo Workflows?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usa scheduling para tareas simples en una instancia: retrasos, cron, intervalos y reintentos ligeros. Usa Workflows para procesos largos, multi-paso, con reintentos y garantías más fuertes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cloudflare Agents SDK reemplaza a MCP?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. MCP es una interfaz de herramientas y contexto. Agents SDK puede consumir o servir MCP, pero sigues necesitando permisos, allowlists y observabilidad.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Es mejor que LangGraph o Google ADK?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No universalmente. Cloudflare Agents SDK destaca como runtime stateful para productos web; LangGraph destaca en grafos de ejecución; Google ADK encaja en el ecosistema Google; OpenAI Agents SDK encaja en orquestación OpenAI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo llevar un agente Cloudflare Agents SDK a producción
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Elegir la entidad de instancia.&lt;/strong&gt; Decide si cada agente representa un usuario, equipo, sala, ticket, repositorio o proceso programado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Crear la clase Agent.&lt;/strong&gt; Define &lt;code&gt;Agent&amp;lt;Env, State&amp;gt;&lt;/code&gt; con estado pequeño, métodos invocables y una política clara de nombres.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configurar Durable Objects.&lt;/strong&gt; Añade bindings y migraciones SQLite en &lt;code&gt;wrangler.jsonc&lt;/code&gt; y revísalos como infraestructura.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separar estado y datos.&lt;/strong&gt; Usa &lt;code&gt;setState&lt;/code&gt; para estado visible y SQL o APIs externas para historial y datos compartidos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Añadir tools con permisos mínimos.&lt;/strong&gt; Empieza por lectura, registra llamadas y exige aprobación humana para acciones irreversibles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Programar trabajo duradero.&lt;/strong&gt; Usa &lt;code&gt;schedule&lt;/code&gt; para tareas simples y Workflows para procesos largos con reintentos y recuperación.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verificar recuperación.&lt;/strong&gt; Prueba reconexión WebSocket, hibernación, despliegue, errores de modelo y reanudación antes de exponerlo a usuarios.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cierre editorial.&lt;/strong&gt; Regla operativa Activa la automatización donde el comentario pueda cambiar una decisión técnica, no donde solo vaya a producir ruido revisable.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/agents/" rel="noopener noreferrer"&gt;Cloudflare Agents overview&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/agents/runtime/agents-api/" rel="noopener noreferrer"&gt;Cloudflare Agents API&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/agents/runtime/lifecycle/state/" rel="noopener noreferrer"&gt;Cloudflare Agents state&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/agents/runtime/communication/routing/" rel="noopener noreferrer"&gt;Cloudflare Agents routing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/agents/runtime/execution/schedule-tasks/" rel="noopener noreferrer"&gt;Cloudflare Agents schedule tasks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/agents/runtime/execution/run-workflows/" rel="noopener noreferrer"&gt;Cloudflare Agents Workflows&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/agents/model-context-protocol/" rel="noopener noreferrer"&gt;Cloudflare Agents MCP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/changelog/product/agents/" rel="noopener noreferrer"&gt;Cloudflare Agents changelog&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/cloudflare/agents" rel="noopener noreferrer"&gt;cloudflare/agents GitHub repository&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.cloudflare.com/workflows/get-started/durable-agents/" rel="noopener noreferrer"&gt;Cloudflare Workflows durable AI agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;¿Te sirve esto? Cada semana resumo herramientas de IA para devs (agentes, MCP, seguridad, workflows) en un email de 5 minutos, en español. &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;Suscríbete gratis&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Publicado originalmente en &lt;a href="https://devaisemanal.com/cloudflare-agents-sdk-durable-objects/" rel="noopener noreferrer"&gt;devaisemanal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>Claude Code para .NET y C#: guía práctica para developers (2026)</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Tue, 30 Jun 2026 09:15:17 +0000</pubDate>
      <link>https://dev.to/khavel/claude-code-para-net-y-c-guia-practica-para-developers-2026-hjc</link>
      <guid>https://dev.to/khavel/claude-code-para-net-y-c-guia-practica-para-developers-2026-hjc</guid>
      <description>&lt;p&gt;Claude Code es un agente de IA que trabaja desde la terminal sobre tu repositorio. Para quien programa en C# y .NET encaja sorprendentemente bien, pero conviene configurarlo con criterio antes de soltarlo sobre una solución grande.&lt;/p&gt;

&lt;p&gt;Claude Code es la herramienta de línea de comandos de Anthropic: un agente que vive en tu terminal, lee tu repositorio, ejecuta comandos y propone cambios revisables como un diff. No es un autocompletado dentro del editor; es un compañero que razona sobre el proyecto entero y trabaja por tareas.&lt;/p&gt;

&lt;h2&gt;
  
  
  La versión corta
&lt;/h2&gt;

&lt;p&gt;Para quien programa en C# y .NET la pregunta no es si funciona, sino cómo configurarlo para que entienda una solución con varios proyectos, dependencias y convenciones propias. Bien preparado, Claude Code es muy eficaz en .NET; mal preparado, se pierde entre archivos y propone cambios que no compilan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por qué Claude Code encaja bien con .NET
&lt;/h2&gt;

&lt;p&gt;El ecosistema .NET es muy estructurado: una solución (.sln) que agrupa proyectos (.csproj), convenciones claras de nombres, tipado fuerte y un compilador estricto. Esa estructura es justo lo que un agente de código aprovecha: hay señales fuertes para entender qué hace cada parte y un compilador que verifica de inmediato si un cambio es válido.&lt;/p&gt;

&lt;p&gt;El tipado fuerte de C# y el feedback rápido de &lt;code&gt;dotnet build&lt;/code&gt; y &lt;code&gt;dotnet test&lt;/code&gt; cierran el bucle entre propuesta y verificación. Claude Code puede editar, compilar, leer el error y corregir sin que tú intervengas en cada paso. En lenguajes dinámicos ese bucle es más frágil; en .NET el compilador hace de red de seguridad.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Funciona Claude Code en Windows?
&lt;/h2&gt;

&lt;p&gt;Sí. Claude Code funciona en Windows, y la vía más cómoda para la mayoría de developers .NET es ejecutarlo dentro de WSL (Windows Subsystem for Linux), aunque también puede usarse en PowerShell. El SDK de .NET, &lt;code&gt;dotnet&lt;/code&gt;, MSBuild y las herramientas de test funcionan igual; Claude Code solo necesita poder ejecutar esos comandos en tu terminal.&lt;/p&gt;

&lt;p&gt;Si trabajas con Visual Studio, lo habitual es mantener Visual Studio para depurar y diseñar, y usar Claude Code en una terminal paralela para tareas de agente: refactors, generación de tests, migraciones mecánicas o exploración de un módulo desconocido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo configurar Claude Code para una solución C
&lt;/h2&gt;

&lt;p&gt;Instala el SDK de .NET y comprueba que &lt;code&gt;dotnet build&lt;/code&gt; y &lt;code&gt;dotnet test&lt;/code&gt; funcionan en tu solución antes de abrir Claude Code.&lt;/p&gt;

&lt;p&gt;Crea un archivo CLAUDE.md en la raíz del repo con lo esencial: estructura de la solución, proyectos principales, comando de build, comando de test y convenciones que no son obvias.&lt;/p&gt;

&lt;p&gt;Indica las restricciones reales: versión de .NET objetivo, nullable habilitado, analizadores activos y reglas de estilo que deben respetarse.&lt;/p&gt;

&lt;p&gt;Limita el alcance al principio: trabaja en una rama, no le des permisos amplios sobre el sistema y revisa cada diff antes de integrarlo.&lt;/p&gt;

&lt;p&gt;Añade los servidores MCP que de verdad aporten valor (por ejemplo acceso a documentación o a tu issue tracker) en lugar de conectarlo todo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo es el flujo de trabajo en la práctica
&lt;/h2&gt;

&lt;p&gt;El patrón que mejor funciona es por tareas concretas y verificables. En vez de pedir "mejora el proyecto", pides algo acotado: "añade validación al endpoint X y un test que lo cubra". Claude Code lee el contexto, propone el cambio, ejecuta &lt;code&gt;dotnet test&lt;/code&gt; y te entrega un diff.&lt;/p&gt;

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

&lt;p&gt;Para una migración mecánica (por ejemplo, mover de un patrón antiguo a uno nuevo en varios archivos), describe el cambio una vez, deja que lo aplique en bucle y revisa el resultado compilado. La clave es que el compilador y los tests sean la fuente de verdad, no la confianza en el modelo.&lt;/p&gt;

&lt;p&gt;Para explorar un módulo que no conoces, pídele primero un resumen de cómo está organizado y dónde vive cada responsabilidad antes de tocar nada. Eso evita cambios a ciegas en código que aún no entiendes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code vs Cursor vs GitHub Copilot para .NET
&lt;/h2&gt;

&lt;p&gt;GitHub Copilot brilla como autocompletado y asistente dentro del editor, integrado de forma nativa en Visual Studio y VS Code. Es lo más cómodo para escribir código línea a línea y resolver dudas sin salir del IDE.&lt;/p&gt;

&lt;p&gt;Cursor es un editor completo centrado en IA, con un buen equilibrio entre edición asistida y agentes; encaja si quieres un IDE moderno orientado a IA como herramienta principal.&lt;/p&gt;

&lt;p&gt;Claude Code es la opción más "agente de terminal": razona sobre el repositorio entero y trabaja por tareas largas con verificación mediante build y tests. Muchos equipos .NET acaban combinando los tres: Copilot para el día a día en el editor, Claude Code para tareas de agente y revisión humana obligatoria para lo que toca seguridad o datos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuánto cuesta
&lt;/h2&gt;

&lt;p&gt;Claude Code se factura por uso de modelo a través de la API de Anthropic o mediante los planes de suscripción de Claude que incluyen Claude Code. El coste real depende de cuántas tareas largas ejecutes, qué modelo uses y cuánto contexto arrastre cada sesión.&lt;/p&gt;

&lt;p&gt;Para controlar el gasto, aplica la misma disciplina que con cualquier herramienta de IA para devs: tareas acotadas, contexto justo, y revisar el consumo tras un par de semanas. Si te interesa el detalle de costes de herramientas de IA, lo tratamos a fondo en nuestras guías sobre AI credits y comparativas de asistentes.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;¿Claude Code funciona en Windows con .NET?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sí. Funciona en Windows, normalmente vía WSL aunque también en PowerShell. El SDK de .NET, dotnet, MSBuild y las herramientas de test se ejecutan igual; Claude Code solo necesita poder lanzar esos comandos desde la terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Hace falta abandonar Visual Studio para usar Claude Code?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Lo habitual es mantener Visual Studio para depurar y diseñar, y usar Claude Code en una terminal paralela para tareas de agente como refactors, generación de tests o migraciones mecánicas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Por qué Claude Code encaja bien con C#?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Porque .NET es muy estructurado y C# tiene tipado fuerte: la estructura de la solución da señales claras al agente y el compilador verifica de inmediato cada cambio, cerrando el bucle entre propuesta y verificación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo controlo lo que puede hacer en mi repositorio?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Trabaja en una rama, no le des permisos amplios sobre el sistema, revisa cada diff antes de integrarlo y exige revisión humana en los cambios que tocan seguridad, autenticación o datos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo poner a punto Claude Code en un proyecto .NET
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verificar el entorno .NET.&lt;/strong&gt; comprueba que dotnet build y dotnet test funcionan en tu solución antes de abrir Claude Code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escribir un CLAUDE.md.&lt;/strong&gt; documenta estructura de la solución, proyectos clave, comando de build, comando de test y convenciones no obvias.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarar restricciones.&lt;/strong&gt; indica versión de .NET, nullable, analizadores y reglas de estilo que deben respetarse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Empezar acotado.&lt;/strong&gt; trabaja en una rama, pide tareas concretas y verificables, y revisa el diff antes de integrar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cerrar el bucle con tests.&lt;/strong&gt; deja que el agente ejecute dotnet test y corrija a partir del error en lugar de confiar a ciegas en la salida.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Claude Code es una de las mejores formas de aplicar un agente de código a proyectos .NET, precisamente porque C# y el compilador le dan la estructura y la verificación que necesita. La diferencia entre que sea útil o caótico está casi siempre en la preparación: un CLAUDE.md honesto, tareas acotadas y revisión humana donde importa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Medida útil
&lt;/h2&gt;

&lt;p&gt;La compactación funciona si conserva la decisión técnica que tomaría una persona con el log completo delante.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.claude.com/en/docs/claude-code/overview" rel="noopener noreferrer"&gt;Claude Code overview (Anthropic)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.claude.com/en/docs/claude-code/memory" rel="noopener noreferrer"&gt;Claude Code: configuración y CLAUDE.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/dotnet/core/tools/" rel="noopener noreferrer"&gt;.NET CLI docs (Microsoft)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Cada semana resumo herramientas de IA para developers (agentes, MCP, seguridad, workflows) en un email de 5 minutos, en español y sin ruido.&lt;/em&gt; &lt;strong&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;Suscríbete gratis a DevAI Semanal&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>LangGraph: cómo crear agentes Python con estado, checkpoints y revisión humana</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Mon, 29 Jun 2026 09:12:07 +0000</pubDate>
      <link>https://dev.to/khavel/langgraph-como-crear-agentes-python-con-estado-checkpoints-y-revision-humana-1ei4</link>
      <guid>https://dev.to/khavel/langgraph-como-crear-agentes-python-con-estado-checkpoints-y-revision-humana-1ei4</guid>
      <description>&lt;p&gt;LangGraph no es otra capa bonita para llamar a un LLM. Su valor aparece cuando un agente necesita estado duradero, rutas explícitas, checkpoints, interrupciones humanas y una forma razonable de depurar ejecuciones largas.&lt;/p&gt;

&lt;p&gt;LangGraph es un framework de orquestación para agentes con estado. La idea central no es escribir prompts más largos, sino declarar un grafo de ejecución donde cada nodo lee y devuelve estado, las aristas deciden el siguiente paso y un checkpointer permite pausar, reanudar y auditar runs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Plan de despliegue&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resumen práctico
&lt;/h3&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;LangGraph agentes Python&lt;/code&gt;. La intención de búsqueda en español es práctica: entender qué es LangGraph, cuándo usarlo frente a una llamada directa al modelo o un SDK de agentes, y cómo montarlo sin convertir producción en una demo imposible de depurar.&lt;/p&gt;

&lt;p&gt;Mi postura: LangGraph merece la pena cuando el workflow tiene estado, bifurcaciones, herramientas, aprobación humana o duración larga. Para un chatbot simple o una única llamada con structured output, probablemente es demasiada maquinaria.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Checklist&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Qué problema resuelve LangGraph
&lt;/h3&gt;

&lt;p&gt;Un agente real no falla solo porque el modelo responda mal. Falla porque pierde estado entre pasos, llama tools en orden incorrecto, no se sabe qué decidió antes de actuar, reintenta sin criterio o necesita una persona justo cuando la ejecución ya está a medias.&lt;/p&gt;

&lt;p&gt;LangGraph ataca ese problema bajando el agente a una estructura explícita: &lt;code&gt;StateGraph&lt;/code&gt;, nodos, edges, estado tipado, checkpointers, streaming e interrupciones humanas. Eso no hace que el modelo sea más listo; hace que el sistema sea más observable y recuperable.&lt;/p&gt;

&lt;p&gt;La diferencia importante frente a un script lineal es que el grafo conserva intención. Puedes decir: primero clasifica, luego busca, después decide si llama una tool o pide revisión humana, y finalmente responde o ejecuta. Esa forma se puede razonar, probar y explicar en revisión.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Briefing&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conceptos que debes entender antes de copiar código
&lt;/h3&gt;

&lt;p&gt;State: contrato compartido de la run. Normalmente contiene mensajes, datos recuperados, decisiones, errores, contadores y cualquier campo que necesites para decidir el siguiente paso.&lt;/p&gt;

&lt;p&gt;Node: función que recibe estado y devuelve un parche de estado. Un nodo debería tener una responsabilidad concreta: recuperar contexto, decidir tool, validar salida, pedir aprobación o sintetizar respuesta.&lt;/p&gt;

&lt;p&gt;Edge: transición entre nodos. Puede ser fija o condicional. Las aristas condicionales son donde aparece la lógica de workflow: si hay tool call, ejecuta tool; si hay riesgo, pausa; si la respuesta está completa, termina.&lt;/p&gt;

&lt;p&gt;Checkpointer: capa que guarda snapshots por &lt;code&gt;thread_id&lt;/code&gt;. Sin esto, human-in-the-loop y durable execution son frágiles. En desarrollo puedes usar memoria; en producción necesitas almacenamiento externo.&lt;/p&gt;

&lt;p&gt;Interrupt: mecanismo para pausar la ejecución y esperar input humano. Es útil para aprobar queries, cambios en repos, emails salientes, acciones sobre infraestructura o cualquier operación que no quieras delegar ciegamente.&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%2Fd9rpwqxqc09lzfvh3nji.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%2Fd9rpwqxqc09lzfvh3nji.png" alt="Diagrama de arquitectura de un agente LangGraph con entrada, estado, StateGraph, tools, checkpoint persistente, revisión humana y runtime con logs" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La frontera sana: el LLM decide dentro de un grafo, pero el equipo controla estado, persistencia, revisión humana y runtime observable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Código mínimo con StateGraph
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing_extensions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.checkpoint.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;InMemorySaver&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;needs_review&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;draft&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;Plan para: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task&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;needs_review&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;human_gate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&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="c1"&gt;# En produccion, aqui usarias interrupt() o una cola de aprobacion.
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;route_after_plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&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;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;human_gate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;needs_review&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;human_gate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;human_gate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;route_after_plan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;human_gate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;InMemorySaver&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="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&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;task&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;preparar un PR de documentacion&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;draft&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="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;needs_review&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;configurable&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;thread_id&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;demo-1&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este ejemplo no pretende ser producción. Sirve para ver la forma mental: estado explícito, nodos pequeños, routing condicional y un &lt;code&gt;thread_id&lt;/code&gt; que permite asociar checkpoints a una ejecución. La parte seria empieza cuando sustituyes memoria local por un checkpointer persistente y defines qué acciones requieren aprobación.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dónde está la decisión de arquitectura
&lt;/h2&gt;

&lt;p&gt;La decisión no es &lt;code&gt;LangGraph sí o no&lt;/code&gt;. La decisión real es cuánto control necesitas sobre la trayectoria del agente. Si tu flujo solo genera una respuesta tipada, Pydantic AI u OpenAI Agents SDK pueden bastar. Si necesitas bucles, pausa humana, recuperación tras error y una ruta auditable, LangGraph empieza a justificar su complejidad.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Puntos a revisar&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Tampoco usaría LangGraph para esconder lógica de negocio dentro de prompts. Justo al revés: lo usaría para sacar decisiones del prompt y convertirlas en nodos, edges, validadores y checkpoints que el equipo pueda revisar.&lt;/p&gt;

&lt;p&gt;Un buen diseño de LangGraph se parece más a un workflow de software que a un chat: entradas claras, estado versionable, pasos nombrados, errores manejables y criterios de salida. Si el grafo solo llama al modelo cinco veces sin contratos, no has ganado arquitectura; has ganado una forma más larga de tener una demo.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Checklist&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Checkpoints: desarrollo no es producción
&lt;/h3&gt;

&lt;p&gt;El error normal es quedarse con &lt;code&gt;InMemorySaver&lt;/code&gt; porque el tutorial funciona. En memoria está bien para notebooks, tests y ejemplos locales. En producción, si el proceso muere, pierdes la run; si necesitas escalar workers, no compartes estado; si debes auditar, no tienes una historia fiable.&lt;/p&gt;

&lt;p&gt;Para producción necesitas un checkpointer externo: Postgres, Redis, DynamoDB u otra capa que encaje con tu infraestructura. Lo importante no es el proveedor, sino las propiedades: persistencia, concurrencia, retención, cifrado, backups y capacidad de buscar por thread o usuario.&lt;/p&gt;

&lt;p&gt;AWS publicó un patrón de checkpointing con DynamoDB precisamente porque el checkpointer pasa a ser infraestructura. Esa es la lectura correcta: en agentes duraderos, el estado ya no es un detalle interno del código; es parte de la superficie operativa.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Checklist&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Human-in-the-loop sin teatro
&lt;/h3&gt;

&lt;p&gt;Human-in-the-loop no significa que una persona lea todo. Significa que el sistema sabe cuándo debe detenerse. Una aprobación humana útil aparece antes de acciones irreversibles: enviar un email externo, ejecutar una query destructiva, abrir un PR grande, tocar infraestructura, gastar presupuesto o publicar contenido.&lt;/p&gt;

&lt;p&gt;La mala versión es pedir aprobación para cada paso y convertir al agente en un formulario lento. La buena versión es clasificar riesgo: lectura sin aprobación, escritura reversible con logs, escritura sensible con interrupción y acciones críticas fuera del alcance del agente.&lt;/p&gt;

&lt;p&gt;En LangGraph, &lt;code&gt;interrupt()&lt;/code&gt; tiene sentido cuando el estado ya contiene suficiente contexto para que la persona decida. Si el humano tiene que reconstruir toda la run, el grafo no está explicando su propio trabajo.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Briefing&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Para evaluar un agente LangGraph, no midas solo la respuesta final. Mide trayectoria: nodos visitados, tools llamadas, argumentos, reintentos, interrupciones, duración, coste, errores y cambios entre versiones de prompt o modelo.&lt;/p&gt;

&lt;p&gt;Una batería mínima debería incluir casos felices, inputs ambiguos, datos hostiles, fallo de tool, timeout, salida inválida, aprobación humana y reanudación desde checkpoint. Si solo pruebas el happy path, justo estás ignorando la razón por la que LangGraph existe.&lt;/p&gt;

&lt;p&gt;El logging debe conservar &lt;code&gt;thread_id&lt;/code&gt;, versión del grafo, versión de prompts, modelo, tools disponibles y resultado de cada nodo. Sin esa evidencia, depurar un agente duradero se convierte en leer una novela escrita por un modelo con mala memoria.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lectura práctica&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Plan de adopción en cinco días
&lt;/h3&gt;

&lt;p&gt;Día 1: elige un caso con estado real, como triage de tickets, revisión de PRs, generación de reportes o asistente interno con tools.&lt;/p&gt;

&lt;p&gt;Día 2: define el &lt;code&gt;State&lt;/code&gt; antes de escribir prompts. Si no sabes qué estado existe, no sabes qué estás orquestando.&lt;/p&gt;

&lt;p&gt;Día 3: crea un grafo con tres o cuatro nodos y un checkpointer local. Añade logging por nodo desde el principio.&lt;/p&gt;

&lt;p&gt;Día 4: cambia a checkpointer persistente y añade un punto de interrupción humana para la acción más sensible.&lt;/p&gt;

&lt;p&gt;Día 5: crea evals de trayectoria y prueba reanudación tras fallo. Si no puedes explicar una run fallida, todavía no lo despliegues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errores que veo venir
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Meter toda la lógica en un nodo gigante llamado &lt;code&gt;agent&lt;/code&gt;. Si todo ocurre dentro de un prompt, LangGraph no te está ayudando a operar el sistema.&lt;/li&gt;
&lt;li&gt;Persistir estado sin política de retención. Los checkpoints pueden contener datos sensibles, prompts, resultados de tools y decisiones intermedias.&lt;/li&gt;
&lt;li&gt;Confundir memory del agente con memoria de usuario. El estado de ejecución no es necesariamente una preferencia duradera del usuario.&lt;/li&gt;
&lt;li&gt;Abrir todas las tools desde el primer día. Empieza con lectura, observa trayectorias y añade mutaciones con aprobación.&lt;/li&gt;
&lt;li&gt;Desplegar sin versionar prompts y grafo. Cambiar el routing o el prompt principal sin evals hace que los checkpoints antiguos sean más difíciles de interpretar.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cuándo no usaría LangGraph
&lt;/h2&gt;

&lt;p&gt;No lo usaría para un endpoint simple que recibe input, llama al modelo una vez y devuelve JSON validado. Ahí una llamada estructurada o un SDK más directo será más barato de mantener.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Puntos a revisar&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;No lo usaría si el equipo no tiene todavía tests, logs ni dueño técnico del workflow. Un framework de orquestación no arregla una operación inmadura; la hace más visible.&lt;/p&gt;

&lt;p&gt;Tampoco lo usaría para simular autonomía donde en realidad quieres una automatización determinista. Si el proceso se puede escribir como reglas normales, escribe reglas normales y reserva el LLM para partes ambiguas.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Checklist&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;LangGraph es valioso cuando aceptas una premisa incómoda: un agente de producción es un sistema distribuido pequeño, no un prompt con marketing. Tiene estado, fallos parciales, decisiones intermedias, permisos, observabilidad y usuarios esperando una respuesta explicable.&lt;/p&gt;

&lt;p&gt;Mi recomendación es empezar con un grafo pequeño, estado explícito, checkpointer persistente, una sola interrupción humana y evals de trayectoria. Si eso funciona, amplía. Si no funciona, el problema no era falta de nodos; era falta de diseño.&lt;/p&gt;

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

&lt;p&gt;¿Qué es LangGraph?&lt;/p&gt;

&lt;p&gt;LangGraph es un framework para construir agentes y workflows con estado usando grafos: defines estado, nodos, edges, persistencia, streaming e interrupciones humanas.&lt;/p&gt;

&lt;p&gt;¿LangGraph reemplaza a LangChain?&lt;/p&gt;

&lt;p&gt;No. LangGraph forma parte del ecosistema LangChain, pero se centra en orquestación de agentes stateful y workflows duraderos.&lt;/p&gt;

&lt;p&gt;¿Cuándo conviene usar LangGraph?&lt;/p&gt;

&lt;p&gt;Conviene cuando el agente necesita varios pasos, routing condicional, tools, checkpoints, recuperación, human-in-the-loop u observabilidad de trayectoria.&lt;/p&gt;

&lt;p&gt;¿InMemorySaver sirve para producción?&lt;/p&gt;

&lt;p&gt;No como base seria. Es útil para desarrollo y pruebas, pero producción necesita un checkpointer persistente y operable.&lt;/p&gt;

&lt;p&gt;¿LangGraph es mejor que Pydantic AI o Google ADK?&lt;/p&gt;

&lt;p&gt;No universalmente. LangGraph destaca en control de workflow y estado; Pydantic AI destaca en contratos Python tipados; Google ADK encaja mejor si priorizas el stack Google.&lt;/p&gt;

&lt;p&gt;¿Qué debo medir en un agente LangGraph?&lt;/p&gt;

&lt;p&gt;Mide respuesta final, nodos visitados, tool calls, argumentos, reintentos, interrupciones humanas, latencia, coste y éxito de reanudación desde checkpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo llevar un agente LangGraph a producción
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Definir el estado.&lt;/strong&gt; Escribe el contrato de &lt;code&gt;State&lt;/code&gt; con mensajes, contexto, decisiones, errores y metadatos mínimos antes de crear nodos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separar nodos.&lt;/strong&gt; Divide planificación, recuperación, decisión, tool calls, validación y síntesis en nodos pequeños y observables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistir checkpoints.&lt;/strong&gt; Sustituye memoria local por un checkpointer externo con retención, cifrado, backups y búsqueda por thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Añadir revisión humana.&lt;/strong&gt; Usa interrupciones solo para acciones sensibles y entrega al humano un estado suficiente para decidir rápido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluar trayectorias.&lt;/strong&gt; Crea casos que verifiquen nodos recorridos, tools llamadas, errores, reintentos y reanudación tras fallo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desplegar con límites.&lt;/strong&gt; Publica el runtime con logging, límites de coste, timeouts, versionado de prompts y rollback claro.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Cierre editorial&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Regla operativa
&lt;/h3&gt;

&lt;p&gt;Activa la automatización donde el comentario pueda cambiar una decisión técnica, no donde solo vaya a producir ruido revisable.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/oss/python/langgraph/overview" rel="noopener noreferrer"&gt;LangGraph overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/oss/python/langgraph/thinking-in-langgraph" rel="noopener noreferrer"&gt;LangGraph thinking in LangGraph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/oss/python/langgraph/checkpointers" rel="noopener noreferrer"&gt;LangGraph checkpointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.langchain.com/oss/python/langgraph/human-in-the-loop" rel="noopener noreferrer"&gt;LangGraph human-in-the-loop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/langchain-ai/langgraph" rel="noopener noreferrer"&gt;LangGraph GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://changelog.langchain.com/announcements/langgraph-v1-0-alpha-is-here" rel="noopener noreferrer"&gt;LangChain: LangGraph v1.0 alpha&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/database/build-durable-ai-agents-with-langgraph-and-amazon-dynamodb/" rel="noopener noreferrer"&gt;AWS: durable AI agents with LangGraph and DynamoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/machine-learning/build-highly-scalable-serverless-langgraph-multi-agent-systems-in-aws-with-amazon-bedrock-agentcore/" rel="noopener noreferrer"&gt;AWS: serverless LangGraph multi-agent systems with AgentCore&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/pydantic-ai-agentes-python-produccion/" rel="noopener noreferrer"&gt;Pydantic AI: agentes Python tipados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/google-adk-agentes-python-produccion/" rel="noopener noreferrer"&gt;Google ADK: agentes Python con tools y evals&lt;/a&gt;&lt;/li&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/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;p&gt;&lt;em&gt;Cada semana resumo herramientas de IA para developers (agentes, MCP, seguridad, workflows) en un email corto en español. &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;Suscríbete gratis&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Publicado originalmente en &lt;a href="https://devaisemanal.com/langgraph-agentes-python-estado-produccion/" rel="noopener noreferrer"&gt;devaisemanal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>Tabnine vs Cursor: privacidad enterprise frente a editor agéntico</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Sun, 28 Jun 2026 13:55:22 +0000</pubDate>
      <link>https://dev.to/khavel/tabnine-vs-cursor-privacidad-enterprise-frente-a-editor-agentico-1i3b</link>
      <guid>https://dev.to/khavel/tabnine-vs-cursor-privacidad-enterprise-frente-a-editor-agentico-1i3b</guid>
      <description>&lt;p&gt;Cursor y Tabnine pertenecen a la misma conversación de IA para programar, pero resuelven problemas distintos: uno rediseña el editor; el otro prioriza control enterprise.&lt;/p&gt;

&lt;p&gt;Tabnine vs Cursor parece una comparación directa entre asistentes de código, pero el producto base es distinto. Cursor es un editor centrado en IA, diseñado para chat, edición multiarchivo, contexto de repo y flujos agénticos dentro de una experiencia propia. Tabnine se integra en IDEs existentes y vende más fuerte privacidad, control y adopción enterprise.&lt;/p&gt;

&lt;h3&gt;
  
  
  No compiten igual
&lt;/h3&gt;

&lt;p&gt;Si tu pregunta es qué herramienta cambia más mi forma de programar, Cursor suele tener ventaja. Si la pregunta es qué herramienta puedo desplegar con más control en una organización sensible, Tabnine gana puntos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Experiencia de desarrollo
&lt;/h3&gt;

&lt;p&gt;Cursor funciona mejor cuando aceptas vivir dentro de su editor. Su valor está en Composer, contexto de proyecto, ediciones amplias y una interacción muy directa con el código abierto en pantalla.&lt;/p&gt;

&lt;p&gt;Tabnine encaja cuando no quieres cambiar el editor del equipo o cuando hay una mezcla de VS Code, JetBrains, Visual Studio y otros entornos. La adopción puede ser menos disruptiva porque se suma al IDE existente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacidad y datos
&lt;/h3&gt;

&lt;p&gt;Cursor ofrece privacy mode y opciones de zero data retention para proveedores de modelos, pero el equipo debe configurar y entender bien esas opciones. Como en cualquier herramienta agéntica, cuanto más contexto le das, más importante es la política de datos.&lt;/p&gt;

&lt;p&gt;Tabnine ha construido gran parte de su mensaje alrededor de privacidad, zero data retention, modelos privados y despliegue controlado. Para equipos con compliance fuerte, esa narrativa no es marketing secundario: puede ser el criterio de compra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agentes y contexto
&lt;/h3&gt;

&lt;p&gt;Cursor suele sentirse más potente en tareas agénticas interactivas: editar varios archivos, iterar con el modelo y moverse rápido por una base de código desde el editor.&lt;/p&gt;

&lt;p&gt;Tabnine Agent acerca Tabnine a esa categoría, pero su ventaja natural sigue siendo dar asistencia gobernable en entornos existentes. Para equipos que temen que un agente toque demasiado, eso puede ser una virtud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuándo elegir Cursor
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Quieres un editor centrado en IA y aceptas cambiar el flujo de trabajo.&lt;/li&gt;
&lt;li&gt;Haces muchas ediciones multiarchivo y tareas exploratorias.&lt;/li&gt;
&lt;li&gt;Tu equipo prioriza velocidad de iteración y experiencia de producto.&lt;/li&gt;
&lt;li&gt;Puedes gobernar privacidad y contexto con políticas claras.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cuándo elegir Tabnine
&lt;/h3&gt;

&lt;p&gt;No quieres cambiar de IDE o tienes varios IDEs en la organización.&lt;/p&gt;

&lt;p&gt;Privacidad, despliegue y administración pesan más que la experiencia agéntica más agresiva.&lt;/p&gt;

&lt;p&gt;Tu equipo quiere empezar por completions, chat y tareas controladas.&lt;/p&gt;

&lt;p&gt;Necesitas una historia clara para seguridad, legal o compliance.&lt;/p&gt;

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

&lt;p&gt;Cursor es más transformador como entorno de trabajo. Tabnine es más conservador y gobernable como plataforma de asistencia. Ninguno gana siempre.&lt;/p&gt;

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

&lt;p&gt;La decisión depende del riesgo que puedas aceptar. Para un equipo pequeño que quiere moverse rápido, Cursor puede ser mejor. Para una empresa que necesita control antes que velocidad máxima, Tabnine merece prioridad.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criterio final
&lt;/h3&gt;

&lt;p&gt;Si no puedes medir consumo, limitar funciones avanzadas y revisar excepciones, todavía no estás listo para tratarlo como coste controlado.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.tabnine.com/" rel="noopener noreferrer"&gt;Tabnine Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.tabnine.com/main/getting-started/tabnine-agent" rel="noopener noreferrer"&gt;Tabnine Agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tabnine.com/code-privacy/" rel="noopener noreferrer"&gt;Tabnine code privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cursor.com/en-US/data-use" rel="noopener noreferrer"&gt;Cursor data use and privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cursor.com/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/tabnine-autocompletado-codigo-ia/" rel="noopener noreferrer"&gt;Tabnine: autocompletado de código con IA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/cursor-ai-que-es-guia-completa/" rel="noopener noreferrer"&gt;Cursor AI: guía completa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devaisemanal.com/windsurf-ide-editor-ia/" rel="noopener noreferrer"&gt;Windsurf IDE: editor con IA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;¿Te ha sido útil?&lt;/strong&gt; Recibe una lectura semanal de herramientas IA para devs (Claude Code, Cursor, Copilot, MCP, agentes) — en español y sin ruido. &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;Suscríbete gratis a DevAI Semanal&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
    <item>
      <title>Google ADK: cómo crear agentes Python con tools, MCP y evals sin quedarte en demo</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Sat, 27 Jun 2026 09:06:12 +0000</pubDate>
      <link>https://dev.to/khavel/google-adk-como-crear-agentes-python-con-tools-mcp-y-evals-sin-quedarte-en-demo-6oa</link>
      <guid>https://dev.to/khavel/google-adk-como-crear-agentes-python-con-tools-mcp-y-evals-sin-quedarte-en-demo-6oa</guid>
      <description>&lt;p&gt;Google ADK no es solo otra forma de llamar a Gemini. Su valor está en darte una estructura de ingeniería para agentes: orquestación, tools, MCP, sesiones, evaluación y despliegue sin esconder todo en un prompt gigante.&lt;/p&gt;

&lt;p&gt;Google ADK, Agent Development Kit, es un framework code-first para construir, evaluar y desplegar agentes de IA. Está optimizado para Gemini y Google Cloud, pero su idea importante no es el proveedor: es tratar el agente como una aplicación con runner, tools, estado, evals y runtime.&lt;/p&gt;

&lt;p&gt;Plan de despliegue&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;p&gt;La keyword principal es &lt;code&gt;Google ADK agentes&lt;/code&gt;; la intención de búsqueda en español es práctica: entender qué es ADK, cómo crear un agente Python, cómo conectar tools y MCP, cómo evaluar trayectorias y cuándo desplegarlo en Cloud Run o Agent Engine.&lt;/p&gt;

&lt;p&gt;Mi postura: ADK merece atención si tu equipo ya vive cerca de Google Cloud o necesita workflows de agente más explícitos que un chat con functions. No lo usaría para un bot trivial; sí para agentes que tocan APIs, documentación interna, BigQuery, tareas asíncronas o pipelines con evaluación.&lt;/p&gt;

&lt;p&gt;Checklist&lt;/p&gt;

&lt;p&gt;Qué es Google ADK en una frase citable&lt;/p&gt;

&lt;p&gt;Google ADK es un framework para crear agentes de IA como software: defines agentes, instrucciones, modelos, tools, workflows, sesiones, evaluación y despliegue con código en vez de confiar en prompts sueltos.&lt;/p&gt;

&lt;p&gt;La diferencia frente a una llamada directa al modelo es la arquitectura. En una llamada normal tienes prompt, modelo y respuesta. En ADK tienes un runtime que puede gestionar eventos, estado, tools, subagentes, callbacks, evals y canales de despliegue.&lt;/p&gt;

&lt;p&gt;Eso importa porque los agentes reales no fallan solo por el modelo. Fallan por permisos demasiado amplios, tools vagas, estado implícito, rutas de ejecución imposibles de reproducir y cambios de prompt que nadie evalúa antes de publicar.&lt;/p&gt;

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

&lt;p&gt;Si quieres seguir frameworks de agentes como Google ADK, Pydantic AI, OpenAI Agents SDK, Claude Agent SDK y MCP sin tragarte cada changelog, 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;p&gt;Lectura práctica&lt;/p&gt;

&lt;p&gt;La arquitectura mínima de un agente ADK serio&lt;/p&gt;

&lt;p&gt;Piensa en ADK como cinco capas. Primero, el agente o workflow que decide el flujo. Segundo, las tools que exponen capacidades concretas. Tercero, session y memory para no depender de contexto pegado a mano. Cuarto, evaluación para comparar comportamiento. Quinto, despliegue en un runtime que puedas observar y limitar.&lt;/p&gt;

&lt;p&gt;La parte peligrosa es confundir flexibilidad con barra libre. Un agente con acceso a Google Search, BigQuery, repos internos y herramientas mutantes necesita límites más parecidos a un servicio backend que a un prompt de playground.&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%2Fv7zk1dpu37yj779z6acb.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%2Fv7zk1dpu37yj779z6acb.png" alt="Diagrama de un flujo Google ADK con cliente, runner, agent workflow, tools, sistemas externos, session memory, observabilidad, evals y deployment" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La frontera útil: ADK orquesta el flujo, pero el equipo define tools estrechas, estado explícito, evals y permisos antes del despliegue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Primer ejemplo: un agente Python pequeño
&lt;/h2&gt;

&lt;p&gt;La forma más sana de empezar no es un sistema multiagente. Es un agente con una instrucción concreta y una tool de lectura. Si esto no es reproducible y medible, añadir subagentes solo amplifica el ruido.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from google.adk.agents import Agent
from google.adk.tools import google_search

root_agent = Agent(
    name="research_assistant",
    model="gemini-flash-latest",
    instruction=(
        "Busca informacion tecnica actual, cita fuentes y di cuando "
        "no tengas evidencia suficiente. No ejecutes acciones mutantes."
    ),
    tools=[google_search],
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checklist&lt;/p&gt;

&lt;p&gt;Tools: el contrato importa más que la lista&lt;/p&gt;

&lt;p&gt;ADK permite conectar tools propias, herramientas integradas, OpenAPI y MCP. La tentación es enchufar todo lo que el agente podría necesitar. Mala idea. Una tool debe tener nombre claro, argumentos mínimos, output predecible y permisos acordes al riesgo.&lt;/p&gt;

&lt;p&gt;Regla práctica: tools de lectura primero; tools mutantes solo con scopes estrechos, logging y aprobación humana cuando afecten repos, datos de cliente, facturación, infraestructura o producción.&lt;/p&gt;

&lt;p&gt;La documentación de ADK incluye &lt;code&gt;McpToolset&lt;/code&gt; para conectar servidores MCP por transportes locales o remotos. Eso es potente, pero MCP no sustituye el diseño de permisos. Si un servidor MCP expone demasiadas acciones, ADK solo será el sitio donde ese riesgo se vuelve fácil de invocar.&lt;/p&gt;

&lt;p&gt;Briefing&lt;/p&gt;

&lt;p&gt;MCP en ADK: cuándo tiene sentido&lt;/p&gt;

&lt;p&gt;Usa MCP cuando la capacidad vive fuera de tu aplicación: documentación viva, repositorios, observabilidad, catálogos internos, data warehouses o herramientas SaaS. No uses MCP para esconder una API mal modelada detrás de una tool genérica.&lt;/p&gt;

&lt;p&gt;El patrón que sí usaría: un agente ADK con una tool MCP de lectura para recuperar contexto, una tool propia para validar o normalizar resultados y una salida final que el producto pueda auditar. El patrón que evitaría: un agente con diez servidores MCP y ninguna política de allowlist.&lt;/p&gt;

&lt;p&gt;Lectura práctica&lt;/p&gt;

&lt;p&gt;Segundo ejemplo: conectar un servidor MCP por HTTP&lt;/p&gt;

&lt;p&gt;Este ejemplo es deliberadamente estrecho: una sola fuente de documentación por MCP remoto, cabecera explícita y una instrucción que limita el uso a búsqueda técnica. En producción, la clave viviría en Secret Manager o en el entorno del runtime, nunca pegada al repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os

from google.adk.agents import Agent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import (
    StreamableHTTPConnectionParams,
)

docs_mcp = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://developerknowledge.googleapis.com/mcp",
        headers={"X-Goog-Api-Key": os.environ["DEVELOPER_KNOWLEDGE_API_KEY"]},
    )
)

root_agent = Agent(
    name="google_docs_agent",
    model="gemini-flash-latest",
    instruction=(
        "Responde preguntas de implementacion usando documentacion oficial. "
        "Cita la pagina consultada y marca incertidumbre."
    ),
    tools=[docs_mcp],
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Workflow agents: cuándo salir del agente único
&lt;/h2&gt;

&lt;p&gt;ADK cubre agentes de workflow como &lt;code&gt;SequentialAgent&lt;/code&gt;, &lt;code&gt;ParallelAgent&lt;/code&gt; y &lt;code&gt;LoopAgent&lt;/code&gt;. La señal para usarlos no es que suenen sofisticados; es que tu proceso ya tiene fases claras.&lt;/p&gt;

&lt;p&gt;Puntos a revisar&lt;/p&gt;

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

&lt;p&gt;Un &lt;code&gt;SequentialAgent&lt;/code&gt; encaja en pipelines como investigar, sintetizar y validar. Un &lt;code&gt;ParallelAgent&lt;/code&gt; encaja cuando puedes separar tareas independientes, por ejemplo comprobar documentación, changelog y repositorio. Un &lt;code&gt;LoopAgent&lt;/code&gt; solo debería existir con condición de parada clara, presupuesto y salida observable.&lt;/p&gt;

&lt;p&gt;La ruta mala es meter routing dinámico desde el día uno. Primero escribe el flujo determinista que un humano seguiría. Luego permite adaptación donde de verdad haya incertidumbre.&lt;/p&gt;

&lt;p&gt;Checklist&lt;/p&gt;

&lt;p&gt;Sesiones y memoria: no todo contexto merece entrar al prompt&lt;/p&gt;

&lt;p&gt;ADK separa conversación, eventos, estado y memoria. Esa separación ayuda a evitar el clásico prompt gigante que mezcla preferencias, datos vivos, resultados intermedios y reglas de seguridad.&lt;/p&gt;

&lt;p&gt;Para un agente interno, guardaría en sesión lo necesario para continuar una ejecución; en memoria, preferencias o hechos reutilizables; y fuera del prompt, cualquier dato sensible que solo debería consultarse bajo tool controlada.&lt;/p&gt;

&lt;p&gt;Si no puedes explicar qué parte del contexto viene de sesión, memoria o tool call, no estás listo para auditar el agente cuando se equivoque.&lt;/p&gt;

&lt;p&gt;Checklist&lt;/p&gt;

&lt;p&gt;Evaluación: el punto donde ADK deja de ser demo&lt;/p&gt;

&lt;p&gt;ADK incluye evaluación de respuestas y trayectorias. La parte clave es la trayectoria: no basta con que la respuesta final suene bien; importa qué tools llamó, en qué orden, con qué argumentos y si ignoró instrucciones críticas.&lt;/p&gt;

&lt;p&gt;Una batería mínima debería tener casos normales, ambiguos y hostiles. Para agentes con MCP, añade casos donde la tool devuelve datos incompletos, una fuente irrelevante, un error de permisos y una respuesta que debería terminar en revisión humana.&lt;/p&gt;

&lt;p&gt;Mide al menos: exactitud, uso correcto de tools, coste, latencia, número de llamadas, refusals útiles, errores de permisos y cambios entre modelos. Cambiar de &lt;code&gt;gemini-flash&lt;/code&gt; a un modelo más capaz sin evals es una apuesta, no ingeniería.&lt;/p&gt;

&lt;p&gt;Briefing&lt;/p&gt;

&lt;p&gt;Despliegue: Cloud Run, Agent Engine o nada todavía&lt;/p&gt;

&lt;p&gt;ADK puede desplegar agentes en opciones como Cloud Run y Agent Engine. La elección práctica depende del ciclo de vida. Cloud Run encaja si quieres un servicio HTTP controlado por tu equipo. Agent Engine encaja si quieres apoyarte más en el runtime de Vertex AI para agentes.&lt;/p&gt;

&lt;p&gt;Antes de desplegar, exigiría cuatro evidencias: un conjunto de evals que pasa, logs de tool calls, límites de coste y permisos revisados. Si falta cualquiera, deja el agente como herramienta interna o CLI hasta que madure.&lt;/p&gt;

&lt;p&gt;Lectura práctica&lt;/p&gt;

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

&lt;p&gt;Define una instrucción corta y verificable antes de añadir tools.&lt;/p&gt;

&lt;p&gt;Registra solo tools necesarias para la tarea principal.&lt;/p&gt;

&lt;p&gt;Separa tools de lectura y acciones mutantes.&lt;/p&gt;

&lt;p&gt;Usa MCP con allowlist y credenciales de mínimo privilegio.&lt;/p&gt;

&lt;p&gt;Guarda secretos en el entorno o Secret Manager, nunca en el prompt.&lt;/p&gt;

&lt;p&gt;Crea evals de respuesta final y de trayectoria.&lt;/p&gt;

&lt;p&gt;Registra modelo, tokens, tool calls, latencia, errores y coste.&lt;/p&gt;

&lt;p&gt;Añade fallback humano para acciones irreversibles.&lt;/p&gt;

&lt;p&gt;Versiona prompts, tools y datasets de evaluación junto al código.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;El primero es vender ADK como garantía de calidad por estar cerca de Google. Un framework no convierte tools vagas en decisiones buenas.&lt;/li&gt;
&lt;li&gt;El segundo es conectar MCP sin política. Si el agente puede descubrir o ejecutar demasiadas cosas, el problema ya no es el modelo: es tu superficie de permisos.&lt;/li&gt;
&lt;li&gt;El tercero es usar workflow agents para impresionar. Si el flujo no está claro en una pizarra, tampoco estará claro cuando lo ejecute un LLM.&lt;/li&gt;
&lt;li&gt;El cuarto es desplegar antes de evaluar trayectorias. Una respuesta correcta con tool calls incorrectas es una incidencia esperando fecha.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cuándo elegir ADK frente a OpenAI Agents SDK o Pydantic AI
&lt;/h2&gt;

&lt;p&gt;Elige ADK si tu stack está en Google Cloud, usas Gemini/Vertex AI, quieres una ruta clara a Cloud Run o Agent Engine y necesitas orquestación con tools, sesiones y evals dentro del ecosistema Google.&lt;/p&gt;

&lt;p&gt;Puntos a revisar&lt;/p&gt;

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

&lt;p&gt;Elige OpenAI Agents SDK si tu producto depende de la superficie OpenAI, tracing y handoffs propios del SDK. Elige Pydantic AI si tu equipo Python prioriza tipos, output estructurado y portabilidad entre proveedores.&lt;/p&gt;

&lt;p&gt;La decisión no debería ser religiosa. Haz una prueba con el mismo caso, las mismas tools y las mismas evals. El framework que haga más fácil auditar el fallo gana.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan de adopción en cinco días
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Día 1: elige una tarea de lectura con impacto real, como responder dudas de documentación interna o preparar un briefing técnico.&lt;/li&gt;
&lt;li&gt;Día 2: crea un agente ADK con una sola tool y logs básicos. Nada de acciones mutantes.&lt;/li&gt;
&lt;li&gt;Día 3: añade session state y diez evals: cinco normales, tres ambiguas y dos hostiles.&lt;/li&gt;
&lt;li&gt;Día 4: prueba MCP solo para una fuente concreta y mide si mejora la respuesta o solo añade coste.&lt;/li&gt;
&lt;li&gt;Día 5: decide runtime. Si las evals no son estables, no despliegues; deja el agente como CLI interna.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Checklist&lt;/p&gt;

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

&lt;p&gt;Google ADK es interesante porque empuja los agentes hacia una forma más operable: runner, tools, workflows, sesiones, evaluación y despliegue. Esa estructura no elimina el riesgo, pero lo hace visible.&lt;/p&gt;

&lt;p&gt;Mi recomendación es usar ADK como disciplina, no como excusa para meter más IA en producción. Empieza estrecho, mide trayectorias, limita MCP, audita permisos y despliega solo cuando puedas reproducir una run mala sin leer la mente del modelo.&lt;/p&gt;

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

&lt;p&gt;¿Qué es Google ADK?&lt;/p&gt;

&lt;p&gt;Google ADK, Agent Development Kit, es un framework code-first para construir, evaluar y desplegar agentes de IA con modelos, tools, workflows, sesiones y runtimes.&lt;/p&gt;

&lt;p&gt;¿Google ADK solo sirve con Gemini?&lt;/p&gt;

&lt;p&gt;Está optimizado para Gemini y Google Cloud, pero la idea del framework es modular y puede integrarse con tools, MCP y distintos patrones de despliegue.&lt;/p&gt;

&lt;p&gt;¿ADK soporta MCP?&lt;/p&gt;

&lt;p&gt;Sí. ADK puede conectar servidores MCP mediante &lt;code&gt;McpToolset&lt;/code&gt;, incluyendo transportes locales y remotos, para exponer capacidades externas como tools del agente.&lt;/p&gt;

&lt;p&gt;¿Cuándo usar workflow agents en ADK?&lt;/p&gt;

&lt;p&gt;Úsalos cuando el proceso tenga fases claras: secuencial para pipelines, paralelo para tareas independientes y loop solo con condición de parada y presupuesto.&lt;/p&gt;

&lt;p&gt;¿Qué debo evaluar en un agente ADK?&lt;/p&gt;

&lt;p&gt;Evalúa respuesta final, trayectoria, llamadas a tools, argumentos, latencia, coste, errores, refusals útiles y comportamiento ante datos ambiguos o hostiles.&lt;/p&gt;

&lt;p&gt;¿ADK reemplaza a OpenAI Agents SDK o Pydantic AI?&lt;/p&gt;

&lt;p&gt;No. ADK compite como framework de agentes, pero conviene elegir según stack, proveedor, despliegue, tipado, observabilidad y facilidad de evaluación.&lt;/p&gt;

&lt;p&gt;Cierre editorial&lt;/p&gt;

&lt;p&gt;Regla operativa&lt;/p&gt;

&lt;p&gt;Activa la automatización donde el comentario pueda cambiar una decisión técnica, no donde solo vaya a producir ruido revisable.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/" rel="noopener noreferrer"&gt;Google ADK documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/agents/" rel="noopener noreferrer"&gt;Google ADK agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/agents/workflow-agents/" rel="noopener noreferrer"&gt;Google ADK workflow agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/tools/" rel="noopener noreferrer"&gt;Google ADK tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/tools/mcp-tools/" rel="noopener noreferrer"&gt;Google ADK MCP tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/sessions/" rel="noopener noreferrer"&gt;Google ADK sessions and memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/evaluate/" rel="noopener noreferrer"&gt;Google ADK evaluate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/adk-docs/deploy/" rel="noopener noreferrer"&gt;Google ADK deploy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/google/adk-python" rel="noopener noreferrer"&gt;google/adk-python GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview" rel="noopener noreferrer"&gt;Google Cloud Agent Engine overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&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;a href="https://devaisemanal.com/pydantic-ai-agentes-python-produccion/" rel="noopener noreferrer"&gt;Pydantic AI: agentes Python tipados&lt;/a&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;a href="https://devaisemanal.com/docker-mcp-toolkit-agentes-locales/" rel="noopener noreferrer"&gt;Docker MCP Toolkit para agentes locales&lt;/a&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;/p&gt;

&lt;p&gt;Recibe una lectura semanal de herramientas IA para devs&lt;/p&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>español</category>
      <category>automation</category>
    </item>
    <item>
      <title>Tabnine vs GitHub Copilot: privacidad, autocompletado y control enterprise</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Thu, 25 Jun 2026 09:10:47 +0000</pubDate>
      <link>https://dev.to/khavel/tabnine-vs-github-copilot-privacidad-autocompletado-y-control-enterprise-2h82</link>
      <guid>https://dev.to/khavel/tabnine-vs-github-copilot-privacidad-autocompletado-y-control-enterprise-2h82</guid>
      <description>&lt;p&gt;Tabnine y GitHub Copilot compiten como asistentes de código, pero no empujan exactamente el mismo ángulo: Copilot gana por ecosistema; Tabnine por control y privacidad.&lt;/p&gt;

&lt;p&gt;Tabnine vs GitHub Copilot no es solo una comparación de calidad de sugerencias. Es una comparación de filosofía de producto. Copilot está profundamente integrado con GitHub, Microsoft y el ecosistema de modelos premium. Tabnine empuja más fuerte la idea de control: privacidad, despliegue enterprise, modelos gobernados y una plataforma que una organización puede limitar mejor.&lt;/p&gt;

&lt;h2&gt;
  
  
  La diferencia principal
&lt;/h2&gt;

&lt;p&gt;Para un desarrollador individual, Copilot suele ser la opción más obvia por popularidad, ecosistema y experiencia general. Para equipos regulados, consultoras o empresas que quieren aislar contexto y controlar políticas, Tabnine merece una lectura más seria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autocompletado y flujo diario
&lt;/h2&gt;

&lt;p&gt;Copilot se percibe como referencia porque su autocompletado está muy extendido y su experiencia en VS Code/GitHub es fluida. Funciona bien para código común, tests, boilerplate, explicación y chat.&lt;/p&gt;

&lt;p&gt;Tabnine también cubre completado, chat y asistencia en IDEs, pero su propuesta se vuelve más interesante cuando la organización valora consistencia, privacidad y administración. No intenta ganar solo por espectacularidad; intenta ser aceptable para equipos que no pueden abrir todo el contexto a cualquier proveedor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacidad y entrenamiento
&lt;/h2&gt;

&lt;p&gt;Aquí está la diferencia que más pesa para empresas. Tabnine comunica con fuerza zero data retention, cifrado y opciones de despliegue privado o air-gapped según plan. También diferencia modelos propios y modelos de terceros, algo importante porque las garantías pueden cambiar según el modelo activado.&lt;/p&gt;

&lt;p&gt;Copilot ofrece controles y planes enterprise, pero para usuarios Free/Pro/Pro+ conviene revisar ajustes de uso de datos y entrenamiento. En organizaciones, la pregunta práctica no es quién promete más, sino qué cuenta se usa, qué plan aplica y qué datos puede procesar el asistente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agentes y funciones avanzadas
&lt;/h2&gt;

&lt;p&gt;Copilot ha avanzado hacia agent mode, code review, integración con GitHub y flujos de PR. Eso lo vuelve potente para equipos que ya viven dentro de GitHub y quieren que la IA participe en el ciclo completo de desarrollo.&lt;/p&gt;

&lt;p&gt;Tabnine también ha añadido Tabnine Agent y CLI, moviéndose más allá del autocompletado clásico. Aun así, su posición diferencial sigue siendo la gobernanza. Si quieres máxima integración con GitHub, Copilot tiene ventaja. Si quieres despliegue controlado y límites enterprise, Tabnine compite mejor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuándo elegir Tabnine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tu empresa prioriza privacidad, cumplimiento o despliegue controlado.&lt;/li&gt;
&lt;li&gt;Necesitas políticas centralizadas para modelos y contexto.&lt;/li&gt;
&lt;li&gt;Trabajas en repos propietarios donde no quieres depender de configuraciones individuales.&lt;/li&gt;
&lt;li&gt;Prefieres productividad incremental y gobernable a agentes muy autónomos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cuándo elegir Copilot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tu equipo ya vive en GitHub y Microsoft.&lt;/li&gt;
&lt;li&gt;Quieres la experiencia más popular y con más integraciones.&lt;/li&gt;
&lt;li&gt;Te interesan code review, agent mode y flujos de PR dentro de GitHub.&lt;/li&gt;
&lt;li&gt;El riesgo de datos está cubierto por plan Business/Enterprise y políticas claras.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Copilot es la opción más natural para muchos desarrolladores. Tabnine es la opción que conviene mirar cuando seguridad, control y despliegue pesan más que la inercia del ecosistema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lo que conviene comprobar:&lt;/strong&gt; la decisión correcta no es cuál completa mejor una función en una demo. Es qué asistente puedes permitir en tu organización sin que privacidad, coste y gobernanza dependan de preferencias locales de cada desarrollador.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criterio final:&lt;/strong&gt; si no puedes medir consumo, limitar funciones avanzadas y revisar excepciones, todavía no estás listo para tratarlo como coste controlado.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.tabnine.com/" rel="noopener noreferrer"&gt;Tabnine Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.tabnine.com/main/welcome/readme/privacy" rel="noopener noreferrer"&gt;Tabnine privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tabnine.com/code-privacy/" rel="noopener noreferrer"&gt;Tabnine code privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/features/copilot/trust" rel="noopener noreferrer"&gt;GitHub Copilot Trust Center&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Publicado originalmente en &lt;a href="https://devaisemanal.com/tabnine-vs-github-copilot/" rel="noopener noreferrer"&gt;devaisemanal.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Te sirve este tipo de análisis?&lt;/strong&gt; Cada martes envío una lectura de herramientas IA para devs — Claude Code, Cursor, Copilot, MCP, agentes — en español y sin ruido. &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;Suscríbete gratis&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>español</category>
      <category>automation</category>
    </item>
    <item>
      <title>GitHub Agent Finder: cómo descubrir agentes, MCP y skills sin convertir Copilot en una caja negra</title>
      <dc:creator>Khavel</dc:creator>
      <pubDate>Wed, 24 Jun 2026 09:59:06 +0000</pubDate>
      <link>https://dev.to/khavel/github-agent-finder-como-descubrir-agentes-mcp-y-skills-sin-convertir-copilot-en-una-caja-negra-4pbg</link>
      <guid>https://dev.to/khavel/github-agent-finder-como-descubrir-agentes-mcp-y-skills-sin-convertir-copilot-en-una-caja-negra-4pbg</guid>
      <description>&lt;p&gt;GitHub Agent Finder apunta a un problema real: los agentes no pueden cargar todos los MCP servers, skills y herramientas por si acaso. La mejora no es descubrir más cosas; es descubrir solo lo permitido, con ranking, política y decisión humana.&lt;/p&gt;

&lt;p&gt;GitHub Agent Finder es una capa de descubrimiento para Copilot que busca capacidades relevantes para una tarea - MCP servers, tools, skills, agentes o canvases - en un registro permitido y devuelve matches ordenados para usarlos bajo demanda.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Plan de despliegue TL;DR La keyword principal es &lt;code&gt;GitHub Agent Finder&lt;/code&gt;; la intención de búsqueda en español es entender qué es, cómo encaja con ARD/MCP registries y qué controles necesita un equipo antes de permitir discovery dinámica de herramientas. Mi postura: Agent Finder es una buena dirección porque reduce contexto basura y configuración manual. Pero si lo tratas como una tienda de plugins, vas a crear el mismo problema de permisos que ya tenías con MCP, solo con mejor UX.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Qué problema resuelve GitHub Agent Finder
&lt;/h2&gt;

&lt;p&gt;Una definición citable: GitHub Agent Finder es un servicio de discovery para Copilot que consulta catálogos compatibles con Agentic Resource Discovery (ARD) y ayuda a encontrar capacidades adecuadas para una tarea sin preconfigurar todas las integraciones en cada agente.&lt;/p&gt;

&lt;p&gt;El problema es familiar para cualquier equipo que haya probado MCP o agentes custom. Empiezas con un servidor de GitHub, añades uno de documentación, luego CI, navegador, base de datos, cloud, tickets y un par de skills. En poco tiempo el agente tiene demasiado contexto, demasiadas tools y una frontera de permisos que nadie sabe explicar.&lt;/p&gt;

&lt;p&gt;Agent Finder cambia el centro de gravedad: en vez de cargar todo por defecto, Copilot puede buscar en un índice de recursos y proponer capacidades relevantes. Eso es útil solo si el índice está gobernado. La discovery sin política es shadow IT con ranking.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lectura práctica ARD en una frase: catálogo, registro y ranking ARD no es otro framework de agentes. Es una especificación de discovery: define cómo publicar, describir, buscar y verificar recursos agentic, desde MCP servers hasta skills, agentes y herramientas tradicionales. La distinción importante es entre catálogo y registro. Un catálogo publica recursos y metadatos; un registro o discovery service los indexa y responde búsquedas. Agent Finder se apoya en ese modelo para que Copilot no dependa de una lista estática pegada en un JSON o en un perfil de agente. Para equipos, la pregunta correcta no es &lt;code&gt;qué puede descubrir Copilot&lt;/code&gt;. La pregunta correcta es &lt;code&gt;qué catálogos puede consultar Copilot, quién aprueba esos recursos, qué scopes tienen y cómo revocamos acceso&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modelo recomendado: Agent Finder descubre y rankea capacidades, pero la ejecución real debe quedar separada por scopes, allowlists, logs y aprobación humana cuando haya acciones mutantes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué descubre realmente
&lt;/h2&gt;

&lt;p&gt;La documentación de GitHub describe Agent Finder como una forma de encontrar capacidades como MCP servers, tools, agents y skills en tiempo de ejecución. El anuncio añade canvases dentro del conjunto de recursos que puede considerar.&lt;/p&gt;

&lt;p&gt;Eso importa porque &lt;code&gt;capacidad&lt;/code&gt; no significa siempre lo mismo. Un MCP server puede exponer una tool mutante sobre GitHub. Una skill puede ser una guía operativa en Markdown. Un custom agent puede traer instrucciones, herramientas y comportamiento especializado. Un canvas puede ser una superficie de trabajo compartida.&lt;/p&gt;

&lt;p&gt;Mezclarlos bajo discovery común tiene sentido para UX, pero no para riesgo. Un skill de solo lectura y un MCP server con permisos de escritura en producción no merecen el mismo proceso de aprobación.&lt;/p&gt;

&lt;h2&gt;
  
  
  La promesa buena: menos contexto muerto
&lt;/h2&gt;

&lt;p&gt;El beneficio más claro es reducir contexto muerto. Hoy muchos setups cargan todos los servidores MCP o todas las instrucciones por si acaso. Eso ensucia el prompt, aumenta coste, introduce ambigüedad y abre más caminos para prompt injection indirecta.&lt;/p&gt;

&lt;p&gt;Si Agent Finder funciona bien, el agente no necesita arrastrar cada tool en cada sesión. Describe la tarea, consulta recursos relevantes, obtiene matches rankeados y solo entonces decide qué incorporar.&lt;/p&gt;

&lt;p&gt;Ese patrón es mejor que la configuración estática infinita. Pero no elimina la revisión: un ranking no es una autorización. Ranking responde &lt;code&gt;qué parece útil&lt;/code&gt;; política responde &lt;code&gt;qué se puede usar&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  La promesa peligrosa: discovery como sustituto de gobierno
&lt;/h2&gt;

&lt;p&gt;El fallo fácil sería vender Agent Finder como automatización mágica: el agente encuentra lo que necesita y listo. Eso es exactamente lo que no debes permitir en repos privados, datos de clientes, billing, cloud o CI/CD.&lt;/p&gt;

&lt;p&gt;GitHub insiste en tres límites sanos: puedes apuntar a registros públicos o privados, los recursos descubiertos se acotan por settings gestionados y Agent Finder no instala ni conecta silenciosamente nada. Esos tres detalles son la diferencia entre discovery útil y permiso implícito.&lt;/p&gt;

&lt;p&gt;En un equipo serio, Agent Finder debería devolver opciones, no conceder autoridad. La persona o política del entorno decide si una capacidad entra en la sesión y con qué alcance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Briefing Cómo lo usaría en un equipo dev Primero, separaría registros. Un registro público para exploración y aprendizaje. Un registro privado para recursos internos aprobados. Nada de mezclar servidores de demo con herramientas que tocan repos, issues, secrets, observabilidad o bases de datos. Segundo, modelaría recursos por intención. &lt;code&gt;leer documentación&lt;/code&gt;, &lt;code&gt;triage de issues&lt;/code&gt;, &lt;code&gt;depurar CI&lt;/code&gt;, &lt;code&gt;proponer PR&lt;/code&gt;, &lt;code&gt;consultar métricas&lt;/code&gt; y &lt;code&gt;mutar infraestructura&lt;/code&gt; son categorías distintas. La categoría debería determinar scopes, logs y aprobación.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tercero, publicaría skills y agentes custom como código revisable. Un &lt;code&gt;SKILL.md&lt;/code&gt; o un perfil de agente no es documentación inocente: puede guiar decisiones de producción. Debe pasar por PR, ownership y versionado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lectura práctica MCP registry no es lo mismo que barra libre de MCP GitHub ya documenta políticas para gestionar uso de MCP en organizaciones y empresas: bloquear MCP, restringirlo a registros definidos y aplicar settings en superficies soportadas como IDEs y Copilot CLI. Agent Finder se apoya en esa misma lógica de registro: descubre dentro de las fuentes que permites. Si el registro está mal curado, el resultado estará mal curado. Si el registro separa lectura, escritura, producción y sandbox, la discovery empieza a ser operable. Mi regla: ningún recurso descubierto dinámicamente debería tener más permisos que una integración configurada a mano. La discovery debe reducir fricción, no subir privilegios por comodidad.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Skills y custom agents: el riesgo no está solo en las APIs
&lt;/h2&gt;

&lt;p&gt;La documentación de GitHub para agent skills usa &lt;code&gt;SKILL.md&lt;/code&gt; con frontmatter e instrucciones, y permite ubicaciones de proyecto, personales y compartidas. Los custom agents usan perfiles Markdown con identidad, descripción, tools y configuración de MCP.&lt;/p&gt;

&lt;p&gt;Eso es potente porque convierte conocimiento de equipo en componentes reutilizables. También es delicado: una skill puede enseñar al agente a ignorar señales, ejecutar comandos demasiado amplios o confiar en fuentes no revisadas.&lt;/p&gt;

&lt;p&gt;Por eso trataría skills, agents y MCP servers como dependencias. Tienen owners, versión, changelog, scope y tests de comportamiento. Si no sabes quién mantiene una capacidad, no debería aparecer en el registro interno.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Define si Agent Finder usará catálogo público, registro privado o ambos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separa recursos exploratorios de recursos aprobados para trabajo real.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clasifica capacidades por lectura, inspección, escritura y mutación crítica.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Haz que skills y custom agents internos vivan en repos revisables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No permitas auto-instalación ni auto-conexión de capacidades mutantes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registra qué recurso descubrió Copilot, por qué tarea y quién lo autorizó.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Empieza con recursos de documentación y CI de solo lectura.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exige scopes mínimos para MCP servers y revocación sencilla.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prueba custom agents en privado antes de liberarlos a toda la organización.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mide si baja el contexto cargado y los errores de herramienta, no solo si parece más cómodo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;El primero es confundir discovery con confianza. Que Agent Finder encuentre una capacidad no significa que sea correcta para tu repo, tus datos o tu compliance.&lt;/p&gt;

&lt;p&gt;El segundo es crear un registro privado que acaba siendo un cajón desastre. Si todo entra, el registro no gobierna; solo maquilla el desorden.&lt;/p&gt;

&lt;p&gt;El tercero es no revisar las instrucciones. En agentes, el riesgo puede estar en una API, pero también en una frase de &lt;code&gt;SKILL.md&lt;/code&gt; que empuja al modelo a actuar fuera del procedimiento esperado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementación mínima razonable
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Paso 1: inventaria tus capacidades actuales: MCP servers, skills, custom agents, scripts y herramientas que ya usa el equipo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paso 2: elimina duplicados y clasifica cada capacidad por intención, datos accesibles, acciones posibles y owner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paso 3: crea un registro privado pequeño con recursos de bajo riesgo y documentación interna.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paso 4: prueba Agent Finder con tareas reales pero no críticas, observando qué matches devuelve y qué contexto evita cargar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paso 5: añade capacidades mutantes solo cuando puedas limitar scopes, auditar uso y exigir aprobación humana.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Briefing Conclusión GitHub Agent Finder es una respuesta sensata a un problema que MCP hizo visible: no puedes escalar agentes si cada sesión arrastra todas las tools, todos los skills y todos los agentes por si acaso. La parte importante no es que Copilot descubra más recursos. Es que descubra menos recursos, mejores, permitidos y relevantes. Si tu adopción termina con un catálogo más ordenado, menos contexto cargado y permisos más estrechos, Agent Finder aporta. Si termina con otro marketplace sin ownership, solo has cambiado el nombre del desorden.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;&lt;strong&gt;¿Qué es GitHub Agent Finder?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub Agent Finder es una capacidad de Copilot para descubrir recursos de IA, como MCP servers, tools, skills y agentes, consultando registros compatibles con ARD y devolviendo matches relevantes para una tarea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué es ARD?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agentic Resource Discovery es una especificación abierta para publicar, descubrir y verificar capacidades agentic en la web o en registros privados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Agent Finder instala herramientas automáticamente?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Según GitHub, Agent Finder encuentra opciones y devuelve matches, pero no conecta ni instala silenciosamente recursos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿En qué se diferencia de configurar MCP servers a mano?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La configuración manual enumera recursos por adelantado; Agent Finder permite buscar capacidades en tiempo de ejecución dentro de registros permitidos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Es seguro usar Agent Finder en una empresa?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Puede serlo si usas registros privados, settings gestionados, scopes mínimos, logs y aprobación humana para acciones mutantes. No debería usarse como permiso implícito.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué debería meter primero en un registro privado?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recursos de bajo riesgo: documentación interna, skills de diagnóstico, herramientas de lectura y agentes custom probados en repos no críticos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cierre editorial Regla operativa Activa la automatización donde el comentario pueda cambiar una decisión técnica, no donde solo vaya a producir ruido revisable.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.blog/changelog/2026-06-17-agent-finder-for-github-copilot-now-available/" rel="noopener noreferrer"&gt;GitHub Changelog: Agent finder for GitHub Copilot now available&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/copilot/concepts/mcp-management" rel="noopener noreferrer"&gt;GitHub Docs: MCP server usage in your company&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://agenticresourcediscovery.org/connect/github-copilot/" rel="noopener noreferrer"&gt;Agentic Resource Discovery: GitHub Copilot connection guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.googleblog.com/announcing-the-agentic-resource-discovery-specification/" rel="noopener noreferrer"&gt;Google Developers Blog: Announcing Agentic Resource Discovery&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://agenticresourcediscovery.org/" rel="noopener noreferrer"&gt;Agentic Resource Discovery Specification&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/add-skills" rel="noopener noreferrer"&gt;GitHub Docs: Adding agent skills for GitHub Copilot&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents" rel="noopener noreferrer"&gt;GitHub Docs: Creating custom agents for Copilot cloud agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/test-custom-agents" rel="noopener noreferrer"&gt;GitHub Docs: Testing and releasing custom agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/copilot/concepts/agents/enterprise-management" rel="noopener noreferrer"&gt;GitHub Docs: Agent management for enterprises&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Publicado originalmente en &lt;a href="https://devaisemanal.com/github-agent-finder-ard-copilot/" rel="noopener noreferrer"&gt;devaisemanal.com&lt;/a&gt;. Si te sirve este tipo de análisis, &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;suscríbete gratis a DevAI Semanal&lt;/a&gt; — herramientas de IA para devs, agentes, MCP y seguridad, resumidas cada semana en español.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>espanol</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
