<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Feedback on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/feedback/</link><description>Recent content in Feedback on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Fri, 22 May 2026 07:45:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/feedback/index.xml" rel="self" type="application/rss+xml"/><item><title>Retrain: cerrar el bucle entre el incidente en producción y el adapter que lo arregla</title><link>https://blog.lo0.es/posts/retrain-cerrar-el-bucle-feedback-dataset-adapter/</link><pubDate>Fri, 22 May 2026 07:45:00 +0200</pubDate><guid>https://blog.lo0.es/posts/retrain-cerrar-el-bucle-feedback-dataset-adapter/</guid><description>&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>La etapa &lt;strong>Retrain&lt;/strong> del &lt;a href="https://blog.lo0.es/posts/pipeline-llmops-seis-etapas/">pipeline LLMOps de seis etapas&lt;/a> es la que cierra el ciclo. Sin ella, el sistema desplegado es un proyecto que termina; con ella, es una práctica viva que mejora cada trimestre. La mecánica a primer nivel encaja en cinco sub-procesos secuenciales: &lt;strong>capturar feedback&lt;/strong> (explícito vía thumbs + implícito vía latencia, abandonment, retries), &lt;strong>triajar incidentes&lt;/strong> por causa raíz (model issue, retrieval issue, prompt issue, infra issue), &lt;strong>enriquecer el dataset&lt;/strong> con los casos donde el sistema falló y la respuesta correcta etiquetada por humano, &lt;strong>decidir cadencia&lt;/strong> (scheduled trimestral por defecto + incident-driven cuando un patrón supera threshold), y &lt;strong>promocionar&lt;/strong> el candidato pasándolo por Tune → Eval → Deploy con gates contra el modelo en producción. Las herramientas que el mercado ha consolidado en 2026: Langfuse para feedback collection en la UI, Argilla y Label Studio para anotación humana del dataset enriquecido, MLflow stages para promotion. La trampa más letal —y la más común— es el &lt;strong>bucle abierto&lt;/strong>: tener todas las piezas pero sin canal estructurado que las conecte, con lo que la etapa Retrain se reduce a &amp;ldquo;ya retrenamos cuando haga falta&amp;rdquo; y por tanto nunca.&lt;/p>
&lt;h2 id="estás-aquí-retrain-cierra-el-ciclo-hacia-data">Estás aquí: Retrain (cierra el ciclo hacia Data)&lt;/h2>
&lt;p>Este post entra al detalle de la &lt;strong>etapa 6&lt;/strong> del pipeline LLMOps. Lo que sigue desmonta los cinco sub-procesos de Retrain a primer nivel completo, sin bajar a la mecánica interna de Tune (cubierta en el &lt;a href="https://blog.lo0.es/posts/fine-tuning-continuo-produccion/">post de fine-tuning continuo&lt;/a>) ni a la implementación de las suites de eval (cubierta en el &lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">post de evals&lt;/a>).&lt;/p>
&lt;div class="diagram" style="max-width:780px;margin:1rem auto;">
&lt;svg viewBox="0 0 780 90" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="estás aquí: Retrain">
&lt;style>.box{stroke:#444;stroke-width:1.4;rx:6}.active{fill:#ffd24a;stroke-width:3}.idle{fill:#f4f4f4}.lbl{font:600 12px sans-serif;fill:#222}.arr{stroke:#666;stroke-width:1.4;fill:none;marker-end:url(#rtm)}.cyc{stroke:#c66;stroke-width:2;fill:none;stroke-dasharray:4 2;marker-end:url(#rtm)}&lt;/style>
&lt;defs>&lt;marker id="rtm" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="#c66"/>&lt;/marker>&lt;/defs>
&lt;text x="390" y="20" text-anchor="middle" class="lbl">Estás aquí: RETRAIN · cierra el ciclo de Observe a Data&lt;/text>
&lt;rect x="30" y="35" width="110" height="35" class="box idle"/>&lt;text x="85" y="58" text-anchor="middle" class="lbl">1 · Data&lt;/text>
&lt;rect x="155" y="35" width="110" height="35" class="box idle"/>&lt;text x="210" y="58" text-anchor="middle" class="lbl">2 · Tune&lt;/text>
&lt;rect x="280" y="35" width="110" height="35" class="box idle"/>&lt;text x="335" y="58" text-anchor="middle" class="lbl">3 · Eval&lt;/text>
&lt;rect x="405" y="35" width="110" height="35" class="box idle"/>&lt;text x="460" y="58" text-anchor="middle" class="lbl">4 · Deploy&lt;/text>
&lt;rect x="530" y="35" width="110" height="35" class="box idle"/>&lt;text x="585" y="58" text-anchor="middle" class="lbl">5 · Observe&lt;/text>
&lt;rect x="655" y="35" width="110" height="35" class="box active"/>&lt;text x="710" y="58" text-anchor="middle" class="lbl">6 · Retrain&lt;/text>
&lt;path class="arr" d="M140,52 L155,52"/>&lt;path class="arr" d="M265,52 L280,52"/>&lt;path class="arr" d="M390,52 L405,52"/>&lt;path class="arr" d="M515,52 L530,52"/>&lt;path class="arr" d="M640,52 L655,52"/>
&lt;path class="cyc" d="M710,72 L710,82 L85,82 L85,72"/>
&lt;/svg>
&lt;/div>
&lt;h2 id="la-analogía-maestra-el-comité-de-mortalidad-del-hospital">La analogía maestra: el comité de mortalidad del hospital&lt;/h2>
&lt;p>Un hospital serio celebra reuniones periódicas de &lt;strong>morbidity &amp;amp; mortality&lt;/strong> (M&amp;amp;M): los médicos revisan, sin culpa pero sin omitir nada, los casos donde un paciente murió o tuvo una complicación grave. Buscan causa raíz, identifican patrones, ajustan protocolos, y dejan registro. El comité no se reúne cuando &amp;ldquo;se acuerdan&amp;rdquo;; está calendarizado y es obligatorio. Y cuando hay un incidente catastrófico fuera de ciclo, se convoca M&amp;amp;M extraordinario en 48 h.&lt;/p>
&lt;p>La etapa &lt;strong>Retrain&lt;/strong> es exactamente eso para un sistema LLM:&lt;/p>
&lt;ul>
&lt;li>El &lt;strong>morbidity&lt;/strong> son los incidentes leves: respuestas que el usuario marcó con thumbs-down, sesiones donde reintentó la misma pregunta tres veces, ejemplos donde el eval score bajó pero no por debajo del threshold de alerta.&lt;/li>
&lt;li>El &lt;strong>mortality&lt;/strong> son los incidentes graves: el sistema dio una respuesta peligrosa, un cliente clave canceló por una serie de errores, el agente ejecutó una tool que no debía.&lt;/li>
&lt;li>Las &lt;strong>reuniones periódicas&lt;/strong> son el &lt;strong>scheduled retrain&lt;/strong> trimestral: se mira la acumulación de feedback, se prioriza, se decide qué entra al dataset enriquecido para el próximo entrenamiento.&lt;/li>
&lt;li>Los &lt;strong>M&amp;amp;M extraordinarios&lt;/strong> son los &lt;strong>incident-driven retrain&lt;/strong>: ante un patrón problemático que supera threshold, se dispara un mini-ciclo fuera de cadencia.&lt;/li>
&lt;/ul>
&lt;p>Sin esta disciplina, los incidentes son anécdotas que se olvidan y el sistema no aprende.&lt;/p>
&lt;h2 id="sub-proceso-1--captura-de-feedback">Sub-proceso 1 — Captura de feedback&lt;/h2>
&lt;p>El primer eslabón del bucle es &lt;strong>observar lo que el sistema hace mal&lt;/strong>. Hay dos familias de feedback, complementarias.&lt;/p>
&lt;h3 id="feedback-explícito">Feedback explícito&lt;/h3>
&lt;p>El usuario te dice directamente que la respuesta fue mala. Mecanismos:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Thumbs up/down&lt;/strong> en la UI: el clásico, baja latencia (1 click). Cobertura: 1-5 % del tráfico típicamente. Sesgo: los usuarios votan más cuando están molestos que cuando están contentos.&lt;/li>
&lt;li>&lt;strong>Anotación por usuarios power&lt;/strong>: clientes internos o expertos que dejan comentarios estructurados (&amp;ldquo;la respuesta es correcta pero el formato no respeta nuestra guía de estilo&amp;rdquo;). Cobertura mucho menor pero calidad alta.&lt;/li>
&lt;li>&lt;strong>Formularios de &amp;ldquo;¿qué falló?&amp;rdquo;&lt;/strong> cuando el thumbs-down se clica: opciones predefinidas (alucinación, formato, tono, incompleta, fuera de tema) + texto libre opcional. Permite triaging automatizado.&lt;/li>
&lt;li>&lt;strong>Re-edición&lt;/strong>: si el sistema escribe un borrador (correo, código) y el usuario lo edita antes de enviarlo, esa edición es feedback rico. Diff entre lo generado y lo enviado = señal explícita del fallo.&lt;/li>
&lt;/ul>
&lt;p>Todos los feedbacks explícitos viajan etiquetados con &lt;code>trace_id&lt;/code>, &lt;code>prompt_version&lt;/code>, &lt;code>model&lt;/code>, &lt;code>user_id&lt;/code> (anonimizado si toca), &lt;code>timestamp&lt;/code>, y entran al store de feedback. Langfuse, Phoenix y LangSmith tienen UI built-in para esto; lo importante es que &lt;strong>cada thumbs-down se materialice como una fila en una tabla&lt;/strong>, no como un evento que se pierde.&lt;/p>
&lt;h3 id="feedback-implícito">Feedback implícito&lt;/h3>
&lt;p>El usuario no te dice nada pero su comportamiento delata el problema. Señales típicas:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Latencia anómala&lt;/strong>: el TTFT del sistema fue 8 s cuando la media es 800 ms. Indica overload, retrieval pesado, prefill grande inesperado. Cubierto a primer nivel en &lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">evals&lt;/a> y &lt;a href="https://blog.lo0.es/posts/ebpf-on-device-inference-drift/">ebpf+drift&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Abandonment rate&lt;/strong>: el usuario abandona la sesión antes de leer la respuesta completa. Si el ratio sube de 5 % a 15 % en un segmento, algo va mal.&lt;/li>
&lt;li>&lt;strong>Retries del usuario&lt;/strong>: el usuario hace la misma pregunta (o muy similar) 2-3 veces. Indica que la primera respuesta no le sirvió.&lt;/li>
&lt;li>&lt;strong>Sesiones abortadas&lt;/strong>: el usuario cierra el chat antes de que el modelo termine de generar. En streaming, ratio elevado de aborts es indicador fuerte.&lt;/li>
&lt;li>&lt;strong>Salida del workflow&lt;/strong>: en un agente, el usuario cancela el plan antes de la ejecución. La trayectoria del agente no convenció.&lt;/li>
&lt;li>&lt;strong>Drift estadístico&lt;/strong> en distribución de inputs o outputs (KS test, PSI, embedding-space shift). Cubierto a primer nivel en &lt;a href="https://blog.lo0.es/posts/ebpf-on-device-inference-drift/">eBPF + drift&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>Las señales implícitas son más ruidosas pero &lt;strong>cubren el 100 % del tráfico&lt;/strong>, no el 1-5 % del feedback explícito. Combinarlas con el feedback explícito da el panorama completo.&lt;/p>
&lt;h3 id="patrón-típico-de-almacenamiento">Patrón típico de almacenamiento&lt;/h3>
&lt;p>Todo el feedback —explícito e implícito— acaba en una tabla común con schema mínimo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TABLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">feedback_signals&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">signal_id&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">UUID&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">PRIMARY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">KEY&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">trace_id&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">UUID&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NULL&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">request_id&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">UUID&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NULL&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">signal_type&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">VARCHAR&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NULL&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">-- &amp;#39;thumbs&amp;#39;, &amp;#39;retry&amp;#39;, &amp;#39;abandon&amp;#39;, &amp;#39;drift&amp;#39;, ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">signal_value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">JSONB&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">-- payload del feedback (texto del thumbs-down, latency, etc.)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">prompt_id&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">VARCHAR&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">prompt_version&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">INT&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">VARCHAR&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">user_segment&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">VARCHAR&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">-- tenant, plan, geo
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">occurred_at&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">TIMESTAMPTZ&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NULL&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">triaged&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">BOOLEAN&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">DEFAULT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FALSE&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">triage_label&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">VARCHAR&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">-- llenado en sub-proceso 2
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Postgres es más que suficiente para volúmenes razonables (millones de filas al mes). Langfuse usa Postgres por debajo. Para volúmenes altos puedes derivar a ClickHouse o BigQuery, pero rara vez merece la pena complicar.&lt;/p>
&lt;h2 id="sub-proceso-2--triage-por-causa-raíz">Sub-proceso 2 — Triage por causa raíz&lt;/h2>
&lt;p>Tener feedback no es suficiente. Hay que &lt;strong>categorizar cada incidente&lt;/strong> por su causa raíz antes de decidir qué hacer con él. Sin triage, el dataset enriquecido es un cajón desastre y el siguiente retrain no arregla nada en concreto.&lt;/p>
&lt;p>Las cuatro categorías canónicas:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Categoría&lt;/th>
&lt;th>Significa&lt;/th>
&lt;th>Acción típica&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Model issue&lt;/strong>&lt;/td>
&lt;td>El modelo respondió mal a algo que sí estaba en su capacidad teórica.&lt;/td>
&lt;td>Caso candidato a dataset enriquecido para el siguiente Tune.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Retrieval issue&lt;/strong>&lt;/td>
&lt;td>El RAG no recuperó el contexto correcto. El modelo respondió razonablemente a partir de contexto pobre.&lt;/td>
&lt;td>Ajustar reranker, chunking, indexing — etapa Data, no Tune.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Prompt issue&lt;/strong>&lt;/td>
&lt;td>El system prompt no cubre el caso o lo cubre mal.&lt;/td>
&lt;td>Nueva versión del prompt (etapa transversal de &lt;a href="https://blog.lo0.es/posts/prompt-versioning-langfuse-mlflow/">prompt versioning&lt;/a>).&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Infra issue&lt;/strong>&lt;/td>
&lt;td>Latencia, timeout, error 5xx, overload.&lt;/td>
&lt;td>Ajustar capacidad / autoscaler — etapa Deploy.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>El triage puede hacerse:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Manual&lt;/strong>: un humano (typically: el equipo MLE / data scientist) revisa el feedback en la UI de Langfuse / Phoenix / LangSmith, mira el trace completo, etiqueta. Coste: 2-5 min por incidente. Sostenible hasta unos 50-100 incidentes/semana por persona.&lt;/li>
&lt;li>&lt;strong>Asistido por LLM-as-classifier&lt;/strong>: un LLM clasifica el incidente en una de las cuatro categorías con un prompt estructurado. Cobertura del 80-90 % automatizada, el resto se escala a humano. Estado del arte 2026: GPT-5, Claude 4, Llama 3 70B-instruct con prompt cuidado dan F1 &amp;gt; 0.85 sobre rúbricas internas calibradas.&lt;/li>
&lt;li>&lt;strong>Reglas heurísticas para los obvios&lt;/strong>: error 5xx siempre es infra; latencia &amp;gt; 5σ siempre es infra; thumbs-down sobre RAG con &lt;code>context_relevance &amp;lt; 0.3&lt;/code> es retrieval. Captura el 30-50 % del volumen con coste cero.&lt;/li>
&lt;/ul>
&lt;p>El patrón productivo es: &lt;strong>reglas → LLM classifier → humano&lt;/strong>, en cascada, escalando sólo lo que el nivel anterior no resuelve con confianza.&lt;/p>
&lt;pre tabindex="0">&lt;code>Feedback nuevo
│
▼
[reglas heurísticas]
│
├── confianza alta → etiqueta automática
│
▼ (resto)
[LLM-as-classifier]
│
├── confianza alta → etiqueta sugerida
│
▼ (resto, o discrepancia con reglas)
[revisión humana]
│
└── etiqueta final → feedback_signals.triage_label
&lt;/code>&lt;/pre>&lt;h2 id="sub-proceso-3--dataset-enrichment">Sub-proceso 3 — Dataset enrichment&lt;/h2>
&lt;p>Una vez triajeados los incidentes con etiqueta &lt;code>model issue&lt;/code>, esos casos son candidatos a entrar al &lt;strong>dataset enriquecido&lt;/strong> que alimentará el siguiente Tune. Pero no entran tal cual: hace falta &lt;strong>la respuesta correcta etiquetada por humano&lt;/strong>.&lt;/p>
&lt;h3 id="cómo-se-construye-un-caso-enriquecido">Cómo se construye un caso enriquecido&lt;/h3>
&lt;p>Cada caso enriquecido es una tupla mínima:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">case_id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">enrich-2026-05-22-0142&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">source_trace_id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">trace-xyz&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">prompt_input&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">system&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Eres un asistente de soporte...&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">user&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Cancelé mi pedido el martes pero sigo viendo el cargo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">prompt_version_at_failure&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">customer_support_v3@v2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">model_at_failure&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">llama-3-70b-instruct&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">failure_response&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Lamento las molestias. El cargo debería revertirse en 5-7 días hábiles.&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">human_corrected_response&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Lamento las molestias. He verificado tu cuenta y veo que el reembolso se procesó el miércoles. Aparecerá en tu cuenta en 24-48 h adicionales según tu banco. Aquí está el ID del reembolso: ABC123.&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">labeler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;agente_soporte_M3&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">labeled_at&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;2026-05-22T09:30:00Z&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">quality_score&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">4&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># 1-5, eval por segundo humano antes de promover al dataset&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">notes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;El modelo dio respuesta genérica sin consultar el estado real del reembolso. Necesita el tool de account_lookup.&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Lo importante es que el caso enriquecido tiene &lt;strong>suficiente contexto para reproducirse&lt;/strong>: prompt original, prompt version, modelo, respuesta fallada, respuesta correcta. Sin esto, el caso es un dato suelto inútil para entrenar.&lt;/p>
&lt;h3 id="herramientas-de-anotación">Herramientas de anotación&lt;/h3>
&lt;p>Tres opciones dominantes en 2026:&lt;/p>
&lt;p>&lt;strong>&lt;a href="https://argilla.io/">Argilla&lt;/a>&lt;/strong> (OSS, mantenido por Hugging Face desde 2024). Diseñado específicamente para datasets de LLM: anotación de pares (input, output), preference data (DPO/RLHF), instruction tuning. UI Python-friendly. Integración nativa con datasets de HuggingFace y con MLflow.&lt;/p>
&lt;p>&lt;strong>&lt;a href="https://labelstud.io/">Label Studio&lt;/a>&lt;/strong> (OSS de Heartex). Más generalista, también sirve para LLM. UI rica, configurable, multi-modal. Mejor cuando el equipo ya lo usa para otras tareas.&lt;/p>
&lt;p>&lt;strong>Langfuse UI built-in&lt;/strong>. Permite anotar traces existentes directamente con thumbs + texto + categorical labels. Útil para feedback ligero; para construir datasets serios de preference o instruction tuning, Argilla y Label Studio son más adecuados.&lt;/p>
&lt;p>Patrón típico: &lt;strong>Langfuse para feedback de tráfico&lt;/strong> + &lt;strong>Argilla para construir el dataset enriquecido formal&lt;/strong> que va al pipeline de Tune. Los traces marcados como candidates en Langfuse se exportan periódicamente a Argilla, donde un humano produce la respuesta correcta y valida calidad.&lt;/p>
&lt;h3 id="validación-de-calidad-antes-de-promover">Validación de calidad antes de promover&lt;/h3>
&lt;p>No todo caso anotado entra al dataset. Una buena disciplina exige:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Doble anotación&lt;/strong> en al menos el 10-20 % de los casos críticos (dos anotadores independientes; si discrepan, un tercero resuelve).&lt;/li>
&lt;li>&lt;strong>Quality score&lt;/strong> por caso (1-5 o equivalente) — sólo casos con score ≥ 4 entran al dataset.&lt;/li>
&lt;li>&lt;strong>Versionado del dataset&lt;/strong> con &lt;a href="https://blog.lo0.es/posts/data-versioning-dvc-lakefs/">DVC + lakeFS&lt;/a> o equivalente, igual que el resto de datasets de la etapa Data.&lt;/li>
&lt;li>&lt;strong>Holdout reservado&lt;/strong>: una porción del dataset enriquecido se aparta para evaluar el adapter retraído, &lt;strong>sin que entre al training&lt;/strong>. Si el dataset se enriquece con casos donde el modelo falló y el mismo dataset se usa para evaluar, se mide memorización, no aprendizaje.&lt;/li>
&lt;/ul>
&lt;h2 id="sub-proceso-4--cadencias-scheduled-vs-incident-driven">Sub-proceso 4 — Cadencias: scheduled vs incident-driven&lt;/h2>
&lt;p>Una vez se acumula dataset enriquecido, queda decidir &lt;strong>cuándo se lanza el retrain&lt;/strong>. Hay dos cadencias complementarias.&lt;/p>
&lt;h3 id="scheduled-retrain-trimestral-por-defecto">Scheduled retrain (trimestral por defecto)&lt;/h3>
&lt;p>Un proceso establecido en el calendario. Cada trimestre, en una semana específica, el equipo:&lt;/p>
&lt;ol>
&lt;li>Cierra el ciclo de captura de feedback acumulado.&lt;/li>
&lt;li>Cuenta los casos enriquecidos disponibles (típicamente decenas a cientos por trimestre).&lt;/li>
&lt;li>Lanza el pipeline de fine-tuning con el dataset agregado (golden dataset + casos enriquecidos del trimestre).&lt;/li>
&lt;li>Evalúa el candidato contra suite completa + holdout enriquecido.&lt;/li>
&lt;li>Promociona si pasa eval gates.&lt;/li>
&lt;/ol>
&lt;p>Ventajas: capacity planning predecible, presupuesto cerrado, riesgo controlado, equipo no quemado. El default.&lt;/p>
&lt;h3 id="incident-driven-retrain">Incident-driven retrain&lt;/h3>
&lt;p>Cuando un incidente serio supera threshold, se dispara un mini-ciclo fuera de cadencia. Triggers típicos:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Drift detectado&lt;/strong> en distribución de inputs/outputs sobre threshold (KS p-value &amp;lt; 0.01, PSI &amp;gt; 0.25, embedding-space shift &amp;gt; 2σ).&lt;/li>
&lt;li>&lt;strong>Segmento que falla&lt;/strong>: un cluster de usuarios o un tipo de pregunta muestra tasa de error 3× sobre baseline durante &amp;gt; 48 h.&lt;/li>
&lt;li>&lt;strong>Ataque de prompt injection o jailbreak&lt;/strong> con éxito que supera severity threshold (cubierto en &lt;a href="https://blog.lo0.es/posts/guardrails-safety-llm/">guardrails&lt;/a>).&lt;/li>
&lt;li>&lt;strong>Cambio de dominio externo&lt;/strong>: el cliente cambia política, sale una nueva regulación, etc. El modelo entrenado contra la versión vieja deja de ser válido.&lt;/li>
&lt;/ul>
&lt;p>Mini-ciclo típico: feedback de los últimos 7-14 días, dataset focalizado en el segmento problemático, fine-tuning rápido sobre el adapter existente (no full retrain), eval gate específico al segmento, despliegue canary, promoción si pasa.&lt;/p>
&lt;p>Coste: ~3-7 días de trabajo del equipo según severidad. &lt;strong>No es opcional para casos críticos&lt;/strong>: si el segmento que falla es regulatorio o reputacional, el coste de no responder rápido es mucho mayor que el del mini-ciclo.&lt;/p>
&lt;h3 id="anti-patrón-ya-retrenamos-cuando-haga-falta">Anti-patrón: &amp;ldquo;ya retrenamos cuando haga falta&amp;rdquo;&lt;/h3>
&lt;p>La frase más letal en LLMOps. Sin calendarización explícita, el scheduled nunca llega; sin thresholds explícitos, el incident-driven tampoco se dispara. El sistema acumula deuda silenciosa hasta que un incidente catastrófico fuerza el retrain ya tarde.&lt;/p>
&lt;p>La disciplina mínima: &lt;strong>fecha en calendario para el próximo scheduled + 3-5 thresholds de incident-driven explícitos por escrito&lt;/strong>. Sin esto, la etapa Retrain es teatro.&lt;/p>
&lt;h2 id="sub-proceso-5--promotion-el-candidato-entra-a-producción">Sub-proceso 5 — Promotion: el candidato entra a producción&lt;/h2>
&lt;p>Una vez el adapter candidato existe, no entra a producción directamente. Pasa por &lt;strong>el mismo flow que cualquier release&lt;/strong>: Tune → Eval → Deploy con gates.&lt;/p>
&lt;pre tabindex="0">&lt;code>Adapter candidato (de Tune)
│
▼
[Eval suite completa]
- golden dataset histórico
- holdout enriquecido del trimestre
- regression vs producción
│
pasa? → no → bloqueo + alerta
│
sí
▼
[Eval gate de no-regresión]
- asegurar que no degrada
segmentos que ya funcionaban
│
pasa? → no → bloqueo + alerta
│
sí
▼
[Despliegue canary]
- 5-10% del tráfico al adapter
nuevo durante 24-72 h
- métricas online vs producción
│
métricas OK? → no → rollback
│
sí
▼
[Promotion full]
- mover label en model registry
- MLflow stages: Staging → Production
- El anterior pasa a Archived (preserva
reproducibilidad histórica)
&lt;/code>&lt;/pre>&lt;p>Las herramientas del registry:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>MLflow Model Registry stages&lt;/strong> (Staging, Production, Archived) es el patrón canónico. La promotion es una llamada API: &lt;code>mlflow.models.transition_stage(name, version, &amp;quot;Production&amp;quot;)&lt;/code>. Auditado, revertible.&lt;/li>
&lt;li>&lt;strong>Hugging Face Hub privado&lt;/strong> con repo per adapter es el equivalente &amp;ldquo;Git for models&amp;rdquo; — versionado por commit hash, branches para staging/production, deploy via PR.&lt;/li>
&lt;li>&lt;strong>vLLM multi-LoRA hot-swap&lt;/strong> (descrito en &lt;a href="https://blog.lo0.es/posts/fine-tuning-continuo-produccion/">fine-tuning continuo&lt;/a>) carga el adapter nuevo sin reiniciar el servidor — la promotion física dura segundos.&lt;/li>
&lt;/ul>
&lt;h2 id="aplicado-a-hardware-on-premise-típico">Aplicado a hardware on-premise típico&lt;/h2>
&lt;p>Retrain como etapa &lt;strong>no necesita hardware grande&lt;/strong>. El cálculo:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Feedback collection&lt;/strong>: una pequeña tabla en Postgres. Trivial en cualquier nodo.&lt;/li>
&lt;li>&lt;strong>Triage manual / asistido&lt;/strong>: el LLM-as-classifier corre en el mismo motor de inferencia que sirve producción, en horas de baja demanda, con prioridad spot. Decenas de miles de incidentes al mes consumen del orden de minutos de GPU por día.&lt;/li>
&lt;li>&lt;strong>Dataset enrichment&lt;/strong>: anotación humana, sin coste GPU. Storage despreciable.&lt;/li>
&lt;li>&lt;strong>Tune (mini-ciclo o trimestral)&lt;/strong>: aquí sí hay coste. Fine-tuning de un adapter LoRA sobre Llama 3 70B con un dataset de pocos miles de ejemplos cuesta del orden de 2-8 horas en una H100 single. Sobre 4 H100 con tensor parallel: 30-90 min. Cabe holgadamente en cualquier ventana nocturna de baja demanda.&lt;/li>
&lt;li>&lt;strong>Eval suite completa&lt;/strong>: minutos en un motor con prefix caching activo (cubierto en &lt;a href="https://blog.lo0.es/posts/pagedattention-deep-dive/">pagedattention deep-dive&lt;/a>).&lt;/li>
&lt;li>&lt;strong>Despliegue canary&lt;/strong>: cero coste adicional — el adapter nuevo convive en el mismo motor vía multi-LoRA hot-swap.&lt;/li>
&lt;/ul>
&lt;p>Para una &lt;strong>RTX 4090&lt;/strong> sirviendo Llama 3 8B con equipo pequeño: scheduled retrain mensual o trimestral en una noche, dataset enriquecido con 50-100 casos por ciclo, anotación con Argilla autohospedado en el mismo nodo. Bastante.&lt;/p>
&lt;p>Para un &lt;strong>cluster 4×H100 SXM&lt;/strong> sirviendo a varios tenants: dataset enriquecido segregado por tenant (cada uno con su propio holdout y eval suite), pipeline de retrain orquestado con Argo Workflows o equivalente, MLflow registry centralizado, multi-LoRA hot-swap por tenant.&lt;/p>
&lt;h2 id="trampas-operativas-comunes">Trampas operativas comunes&lt;/h2>
&lt;p>&lt;strong>El bucle abierto.&lt;/strong> El sistema captura feedback, lo guarda en una tabla, y ahí muere. Nadie triajea, nadie enriquece, nadie retrena. El modelo deployed envejece silenciosamente. &lt;strong>Solución&lt;/strong>: SLO interno explícito (por ejemplo, &amp;ldquo;todo feedback &amp;gt;1 semana sin triajear se reporta en standup&amp;rdquo;), dueño asignado.&lt;/p>
&lt;p>&lt;strong>Feedback humano que se pierde.&lt;/strong> Thumbs-down sin captura estructurada (el evento se loggea pero el motivo no), o el motivo se loggea pero nadie lo indexa para queries. &lt;strong>Solución&lt;/strong>: schema explícito como el de arriba, dashboard semanal de &amp;ldquo;top motivos de thumbs-down&amp;rdquo;.&lt;/p>
&lt;p>&lt;strong>Cadence sin definir.&lt;/strong> &amp;ldquo;Ya retrenamos cuando haga falta&amp;rdquo; — nunca. &lt;strong>Solución&lt;/strong>: fecha en calendario + 3-5 thresholds escritos.&lt;/p>
&lt;p>&lt;strong>Sin holdout test set.&lt;/strong> El dataset enriquecido se mezcla con el golden dataset para entrenar Y para evaluar. El adapter parece haber mejorado porque &amp;ldquo;memorizó&amp;rdquo; los casos enriquecidos, pero generaliza mal a nuevos casos similares. &lt;strong>Solución&lt;/strong>: holdout reservado &lt;strong>antes&lt;/strong> de entrenar, eval contra holdout es la métrica que decide promotion.&lt;/p>
&lt;p>&lt;strong>Triage ad-hoc por persona.&lt;/strong> El data scientist senior triajea cuando puede; en vacaciones se acumula; vuelve y abandona porque hay 400 incidentes esperando. &lt;strong>Solución&lt;/strong>: automatizar con LLM-as-classifier el 70-80 %, dejar humano sólo lo difícil; rotar el &amp;ldquo;oncall de triage&amp;rdquo; para no saturar a una persona.&lt;/p>
&lt;p>&lt;strong>Promotion sin canary.&lt;/strong> El adapter pasa eval offline y se despliega al 100 % directamente. Una regresión en producción tarda en detectarse hasta que las métricas online lo evidencian — para entonces el daño está hecho. &lt;strong>Solución&lt;/strong>: canary 5-10 % durante 24-72 h obligatorio.&lt;/p>
&lt;p>&lt;strong>Sin reproducibilidad del incidente original.&lt;/strong> El equipo va a investigar por qué el modelo falló en el incidente del 22 de mayo y descubre que el prompt era distinto (se cambió hace dos semanas), el modelo también, y los logs no guardaron el contexto RAG. &lt;strong>Solución&lt;/strong>: trazabilidad fuerte (cubierta en &lt;a href="https://blog.lo0.es/posts/prompt-versioning-langfuse-mlflow/">prompt versioning&lt;/a> y &lt;a href="https://blog.lo0.es/posts/mcp-observability-otel/">MCP observability&lt;/a>). Sin reproducibilidad, retrain es adivinanza.&lt;/p>
&lt;p>&lt;strong>El dataset enriquecido contamina los datos de Eval.&lt;/strong> El equipo confunde &amp;ldquo;casos donde falló&amp;rdquo; (que entran al training enriquecido) con &amp;ldquo;golden dataset de regresión&amp;rdquo; (que tiene que permanecer estable para detectar drift). Mezclarlos invalida el eval. &lt;strong>Solución&lt;/strong>: dos datasets distintos, dos rutas distintas.&lt;/p>
&lt;h2 id="patrón-operativo-recomendado-el-ciclo-trimestral-en-una-pantalla">Patrón operativo recomendado: el ciclo trimestral en una pantalla&lt;/h2>
&lt;p>Un equipo serio con Retrain bien implementado tiene este flujo cada 3 meses:&lt;/p>
&lt;p>&lt;strong>Semana 1 (cierre de ciclo)&lt;/strong>: bloqueo de captura nueva para el ciclo, snapshot de feedback acumulado. Reporte automatizado: cuántos thumbs-down, cuántos incidentes triajeados, distribución por categoría, top patrones.&lt;/p>
&lt;p>&lt;strong>Semana 2 (triage y anotación)&lt;/strong>: el equipo MLE+anotadores procesa los casos &lt;code>model issue&lt;/code> no triajeados. Anotación humana en Argilla. Validación cruzada en muestras.&lt;/p>
&lt;p>&lt;strong>Semana 3 (training y eval)&lt;/strong>: pipeline lanzado con dataset = golden + enriquecido_de_este_trimestre - holdout. Fine-tuning del adapter en una noche. Eval contra suite completa + holdout. Si pasa gates, candidato &lt;code>v_new&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Semana 4 (canary y promotion)&lt;/strong>: deploy del candidato como adapter alternativo en vLLM, routing del 5-10 % del tráfico al candidato durante 48-72 h. Métricas online: latencia, tasa de queja, eval implícito en producción. Si todo OK, promotion full; si no, rollback y análisis.&lt;/p>
&lt;p>&lt;strong>Semana 5+ (siguiente ciclo)&lt;/strong>: el adapter &lt;code>v_new&lt;/code> ahora es &lt;code>production&lt;/code>. Empieza la captura de feedback del próximo trimestre. El anterior &lt;code>v_old&lt;/code> pasa a &lt;code>Archived&lt;/code> pero queda accesible para reproducibilidad histórica.&lt;/p>
&lt;p>Trimestralmente, ese ciclo más los mini-ciclos incident-driven que aparezcan en medio. Operacional, predecible, auditable.&lt;/p>
&lt;h2 id="lo-que-no-hemos-cubierto-próximos-posts">Lo que no hemos cubierto (próximos posts)&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Online DPO y aprendizaje continuo on-policy&lt;/strong>: cómo se acorta el ciclo a horas o días (Fast-Slow Chasing, RLOO iterativo). Estado del arte 2026 — todavía emergente en producción.&lt;/li>
&lt;li>&lt;strong>Machine unlearning para GDPR&lt;/strong>: cuando un usuario ejerce derecho al olvido y sus interacciones formaron parte del dataset enriquecido de un adapter en producción. Negative LoRA, retrain selectivo.&lt;/li>
&lt;li>&lt;strong>Constitutional AI runtime&lt;/strong>: alignment continuo que sustituye o complementa retrain periódico.&lt;/li>
&lt;li>&lt;strong>Eval gates con metamorphic testing&lt;/strong>: evaluación de robustez frente a perturbaciones del input (typos, paraphrasing, idioma) como parte del gate de promotion.&lt;/li>
&lt;/ul>
&lt;h2 id="ver-también">Ver también&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.lo0.es/posts/pipeline-llmops-seis-etapas/">El pipeline LLMOps de seis etapas&lt;/a> — el mapa maestro donde Retrain es la etapa 6. Este post entra al detalle de esa caja.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/fine-tuning-continuo-produccion/">Fine-tuning continuo en producción&lt;/a> — la mecánica de Tune que ejecuta el adapter nuevo del ciclo descrito aquí.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">Evals: la capa después del tracing&lt;/a> — las suites de eval que sirven de gate en el sub-proceso 5 de promotion.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/prompt-versioning-langfuse-mlflow/">Prompt versioning con Langfuse y MLflow Prompts&lt;/a> — el componente transversal que asegura reproducibilidad del incidente original cuando se va a triajear.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/data-versioning-dvc-lakefs/">Data versioning para LLMOps: DVC, lakeFS y golden dataset reproducible&lt;/a> — el sub-proceso 3 de Retrain enriquece un dataset; este post entra al detalle de cómo versionarlo, su schema y su lineage.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/ebpf-on-device-inference-drift/">eBPF en inferencia local y detección estadística de drift&lt;/a> — las señales de drift que disparan el incident-driven retrain.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/guardrails-safety-llm/">Guardrails y safety en LLMs&lt;/a> — los incidentes de safety / jailbreak que también disparan incident-driven retrain.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/mcp-observability-otel/">MCP por dentro y su observabilidad profunda&lt;/a> — el tracing OTel &lt;code>gen_ai.*&lt;/code> que liga cada feedback con su trace completo, condición necesaria para triagear bien.&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>Argilla documentation, &lt;em>Building Datasets for LLM Fine-Tuning&lt;/em>: &lt;a href="https://argilla.io/docs">https://argilla.io/docs&lt;/a>.&lt;/li>
&lt;li>Label Studio documentation, &lt;em>LLM Annotation&lt;/em>: &lt;a href="https://labelstud.io/templates/llm">https://labelstud.io/templates/llm&lt;/a>.&lt;/li>
&lt;li>Langfuse documentation, &lt;em>User Feedback and Dataset Management&lt;/em>: &lt;a href="https://langfuse.com/docs/scores/user-feedback">https://langfuse.com/docs/scores/user-feedback&lt;/a>.&lt;/li>
&lt;li>MLflow Model Registry stages: &lt;a href="https://mlflow.org/docs/latest/model-registry.html">https://mlflow.org/docs/latest/model-registry.html&lt;/a>.&lt;/li>
&lt;li>Ethayarajh et al., &lt;em>KTO: Model Alignment as Prospect Theoretic Optimization&lt;/em> (2024) — referencia para el ciclo de feedback como señal de alineamiento.&lt;/li>
&lt;li>Google Cloud, &lt;em>Continuous Training and MLOps for GenAI&lt;/em> (2025).&lt;/li>
&lt;li>DataRobot, &lt;em>MLOps Best Practices: Closing the Loop&lt;/em> (2025).&lt;/li>
&lt;li>Eugene Yan, &lt;em>Feedback Loops in LLM Systems&lt;/em> (blog, 2025).&lt;/li>
&lt;/ul></description></item></channel></rss>