{"id":640,"date":"2026-06-15T20:49:19","date_gmt":"2026-06-15T18:49:19","guid":{"rendered":"https:\/\/atlaszn.com\/blog\/?p=640"},"modified":"2026-06-15T21:04:10","modified_gmt":"2026-06-15T19:04:10","slug":"routing-con-llms-toma-de-decisiones-dinamicas-en-sistemas-agenticos","status":"publish","type":"post","link":"https:\/\/atlaszn.com\/blog\/2026\/06\/15\/routing-con-llms-toma-de-decisiones-dinamicas-en-sistemas-agenticos\/","title":{"rendered":"Routing con LLMs: toma de decisiones din\u00e1micas en sistemas ag\u00e9nticos"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">El problema que Routing resuelve<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un pipeline lineal funciona bien cuando sabes qu\u00e9 va a pasar:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"> Entrada \u2192 paso 1 \u2192 paso 2 \u2192 salida. Predecible, f\u00e1cil de testear, barato de mantener.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La realidad es que los inputs de un sistema con LLMs rara vez siguen un guion. En un chatbot de soporte, un usuario puede preguntar por el estado de un pedido, pedir cancelar una suscripci\u00f3n, o simplemente insultar al bot. Un pipeline lineal procesa los tres casos igual y produce resultados mediocres o directamente err\u00f3neos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Routing es la respuesta. Introduce l\u00f3gica condicional en el flujo del agente: eval\u00faa el input, clasifica la intenci\u00f3n, y dirige la ejecuci\u00f3n al handler correcto. No es un reemplazo de Prompt Chaining, es su complemento. Chaining maneja el <em>qu\u00e9<\/em> hacer dentro de un flujo; Routing decide <em>cu\u00e1l<\/em> flujo activar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Arquitectura b\u00e1sica<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El patr\u00f3n tiene tres componentes:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Router<\/strong>: El punto de decisi\u00f3n. Recibe el input y produce una clasificaci\u00f3n.<\/li>\n\n\n\n<li><strong>Handlers<\/strong>: Los flujos especializados. Cada uno maneja un tipo de input espec\u00edfico.<\/li>\n\n\n\n<li><strong>Fallback<\/strong>: La ruta por defecto. Maneja lo que el router no clasific\u00f3.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La estructura es esencialmente un switch-case, pero en lugar de reglas est\u00e1ticas, la decisi\u00f3n puede tomarla un modelo de lenguaje, un clasificador ML, o l\u00f3gica determinista.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized is-style-default\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_routing-1024x683.webp\" alt=\"\" class=\"wp-image-644\" style=\"aspect-ratio:1.4993329419926358;width:718px;height:auto\" srcset=\"https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_routing-1024x683.webp 1024w, https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_routing-300x200.webp 300w, https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_routing-768x512.webp 768w, https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_routing.webp 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El router puede estar en la entrada del sistema, clasificando la solicitud primaria, o en cualquier punto intermedio. De hecho, uno de los usos m\u00e1s efectivos es el <em>mid-chain routing<\/em>: un pipeline avanza normalmente hasta que un resultado intermedio requiere una decisi\u00f3n. Por ejemplo, un sistema de an\u00e1lisis financiero extrae datos, y dependiendo de si detecta anomal\u00edas, deriva a un flujo de alerta o a uno de reporte est\u00e1ndar.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ejemplo: estructura de un router<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Un router funcional en Python se reduce a esto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Router:\n    def __init__(self, llm_router, rule_patterns, handlers):\n        self.llm_router = llm_router\n        self.rule_patterns = rule_patterns  # &#91;(regex, categoria), ...]\n        self.handlers = handlers            # {categoria: handler_func}\n\n    def classify(self, input_text: str) -&gt; str:\n        # 1. Intenta rule-based primero\n        for pattern, category in self.rule_patterns:\n            if pattern.search(input_text):\n                return category\n\n        # 2. Fallback a LLM-based\n        return self.llm_router.route(input_text)\n\n    def execute(self, input_text: str) -&gt; str:\n        category = self.classify(input_text)\n        handler = self.handlers.get(category, self.handlers&#91;\"default\"])\n        return handler(input_text)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tres capas: regla r\u00e1pida, LLM como red de seguridad, fallback como \u00faltimo recurso. Es el patr\u00f3n que m\u00e1s se repite en producci\u00f3n porque suele resolver la mayor\u00eda de los casos sin costo de tokens y deja que el modelo maneje lo impredecible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Los cuatro m\u00e9todos de routing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En la literatura sobre sistemas LLM, suelen distinguirse cuatro mecanismos principales de routing. Cada uno tiene un perfil de latencia, costo y precisi\u00f3n distinto. Elegir mal aqu\u00ed no rompe el sistema, lo hace ineficiente.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LLM-based routing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">El modelo mismo clasifica el input mediante un prompt estructurado y devuelve una etiqueta. Es el m\u00e1s flexible: entiende contexto, intenci\u00f3n impl\u00edcita, y generaliza a inputs no vistos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El problema es que cuesta. Cada decisi\u00f3n de routing es una llamada completa al modelo. En sistemas de alto volumen, eso se acumula r\u00e1pido. La mitigaci\u00f3n est\u00e1ndar es usar un modelo peque\u00f1o y r\u00e1pido exclusivamente para el router (un modelo de 1-3B par\u00e1metros suele ser suficiente para clasificaci\u00f3n de intenci\u00f3n). No necesitas GPT-5 para decidir si algo es una queja o una consulta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En LangChain se implementa con <code>RunnableBranch<\/code>. En LangGraph, las aristas condicionales del grafo son esencialmente routing basado en estado.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from langchain.chat_models import init_chat_model\nfrom langchain_core.runnables import RunnableBranch\n\nmodel = init_chat_model(\"qwen2.5-3b\", provider=\"ollama\")\n\nrouter = RunnableBranch(\n    (\n        lambda x: \"precio\" in x&#91;\"input\"].lower() or \"costo\" in x&#91;\"input\"].lower(),\n        lambda x: f\"Consultando precios: {x&#91;'input']}\",  # handler precios\n    ),\n    (\n        lambda x: \"soporte\" in x&#91;\"input\"].lower() or \"problema\" in x&#91;\"input\"].lower(),\n        lambda x: f\"Derivando a soporte: {x&#91;'input']}\",  # handler soporte\n    ),\n    # Fallback: LLM clasifica lo que las reglas no atraparon\n    model.bind(\n        response_format={\"type\": \"json_schema\", \"json_schema\": {...}}\n    ).pipe(lambda x: x.json()&#91;\"categoria\"]),\n)\n\nresult = router.invoke({\"input\": \"Mi suscripci\u00f3n no funciona\"})<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">N\u00f3tese que las ramas con lambda son reglas simples, solo la rama por defecto llama al modelo. Eso ya es el patr\u00f3n h\u00edbrido en practica: rule-based como filtro, LLM como catch-all.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Embedding-based routing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">El input se vectoriza y se compara contra embeddings pre-calculados de cada ruta. La ruta con mayor similitud sem\u00e1ntica gana.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esto funciona bien cuando las rutas son estables y conocidas de antemano. Si tienes 5 categor\u00edas de soporte, calculas sus embeddings una vez y el routing se reduce a una operaci\u00f3n de similitud coseno, b\u00e1sicamente instant\u00e1nea y gratuita.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El problema aparece cuando las categor\u00edas son sem\u00e1nticamente cercanas o ambiguas. \u00abMi cuenta est\u00e1 bloqueada\u00bb vs \u00abno puedo iniciar sesi\u00f3n\u00bb, dos frases que comparten contexto pero requieren acciones distintas. La similitud coseno tiende a confundirlas; un LLM-based router distingue mejor los matices porque entiende intenci\u00f3n, no solo proximidad vectorial.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import numpy as np\n\ndef cosine_similarity(a, b):\n    return np.dot(a, b) \/ (np.linalg.norm(a) * np.linalg.norm(b))\n\n# Embeddings pre-calculados de cada ruta\nroute_embeddings = {\n    \"precios\":    embed(\"precios, tarifas, planes, costo, factura\"),\n    \"soporte\":    embed(\"error, problema, no funciona, ayuda, bug\"),\n    \"ventas\":     embed(\"demo, prueba, comprar, contactar, empresa\"),\n}\n\ndef route_by_embedding(input_text: str) -&gt; str:\n    input_vec = embed(input_text)\n    scores = {\n        route: cosine_similarity(input_vec, vec)\n        for route, vec in route_embeddings.items()\n    }\n    return max(scores, key=scores.get)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La funcion <code>embed<\/code> puede ser cualquier modelo de embeddings, sentence-transformers, Ollama con nomic-embed, o incluso el API de OpenAI. Una vez calculados los embeddings de las rutas, el routing en si no requiere llamadas al modelo.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule-based routing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">if\/else, regex, match de keywords. Determinista, r\u00e1pido, barato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y fr\u00e1gil. Un input que no coincide con ninguna regla cae al fallback. Si las reglas son exhaustivas, funciona perfecto pero \u00abexhaustivo\u00bb es una palabra peligrosa en producci\u00f3n. Los usuarios siempre encuentran formas de preguntar que no anticipaste.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El uso correcto de rule-based routing no es como mecanismo principal, sino como primer filtro. Intercepta los casos obvios; \u00abprecio\u00bb, \u00abfactura\u00bb, \u00abcontrato\u00bb  y deja que el LLM-based router maneje lo que sobra. Esa combinaci\u00f3n reduce el costo total significativamente.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import re\n\nRULES = &#91;\n    (re.compile(r\"\\b(precio|costo|tarifa|factura|cobro)\\b\", re.I), \"precios\"),\n    (re.compile(r\"\\b(error|problema|falla|no funciona|bug)\\b\", re.I), \"soporte\"),\n    (re.compile(r\"\\b(demo|prueba gratuita|empresa|contactar)\\b\", re.I), \"ventas\"),\n    (re.compile(r\"\\b(hola|buenos d&#91;\u00edi]as|saludos)\\b\", re.I), \"saludo\"),\n]\n\ndef rule_route(text: str) -&gt; str | None:\n    for pattern, category in RULES:\n        if pattern.search(text):\n            return category\n    return None  # fallback necesario\n\nresult = rule_route(\"Tengo un error con mi factura\")  # \u2192 \"soporte\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">ML model-based routing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Un clasificador discriminativo fine-tuned toma la decisi\u00f3n. No genera texto, eval\u00faa par\u00e1metros y devuelve una categor\u00eda. Es m\u00e1s barato que llamar a un LLM general-purpose y m\u00e1s preciso que embeddings simples.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pero requiere datos de entrenamiento y mantenimiento. Si las categor\u00edas de routing cambian con frecuencia, algo com\u00fan en productos en crecimiento, fine-tunar un clasificador cada vez que a\u00f1ades una ruta se vuelve costoso en ingenier\u00eda. Tiene m\u00e1s sentido en sistemas maduros donde el espacio de clasificaci\u00f3n es estable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Comparativa<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>M\u00e9todo<\/th><th>Latencia<\/th><th>Costo<\/th><th>Precisi\u00f3n<\/th><th>Flexibilidad<\/th><th>Mantenimiento<\/th><\/tr><\/thead><tbody><tr><td>LLM-based<\/td><td>Media-Alta<\/td><td>Alto (tokens)<\/td><td>Alta-Muy alta<\/td><td>Muy alta<\/td><td>Bajo (cambiar prompt)<\/td><\/tr><tr><td>Embedding-based<\/td><td>Baja<\/td><td>Bajo<\/td><td>Media<\/td><td>Media<\/td><td>Medio (recalcular embeddings)<\/td><\/tr><tr><td>Rule-based<\/td><td>M\u00ednima<\/td><td>Cero<\/td><td>Muy alta (casos previstos)<\/td><td>Baja<\/td><td>Alto (mantener reglas)<\/td><\/tr><tr><td>ML model-based<\/td><td>Baja<\/td><td>Medio (fine-tuning)<\/td><td>Alta<\/td><td>Media-Alta<\/td><td>Alto (reentrenar)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Routing en la pr\u00e1ctica: d\u00f3nde colocarlo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La posici\u00f3n del router en el flujo determina qu\u00e9 tipo de decisi\u00f3n toma. Hay tres ubicaciones comunes:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Entry-point routing<\/strong>: Clasifica la solicitud del usuario antes de cualquier procesamiento. Es el patr\u00f3n m\u00e1s visible: un chatbot que deriva entre \u00abventas\u00bb, \u00absoporte\u00bb y \u00abt\u00e9cnico\u00bb desde el primer mensaje.<\/li>\n\n\n\n<li><strong>Mid-chain routing<\/strong>: Aparece despu\u00e9s de uno o m\u00e1s pasos de procesamiento. Un pipeline de an\u00e1lisis primero extrae datos, y dependiendo de lo que encuentre, activa rutas distintas. Aqu\u00ed es donde Routing gana sobre Chaining puro: el pipeline se adapta a los datos en lugar de seguir un guion fijo.<\/li>\n\n\n\n<li><strong>Subroutine routing<\/strong>: Elige entre herramientas o sub-agentes. Function calling puede verse como una forma de subroutine routing donde el modelo selecciona una herramienta espec\u00edfica. La diferencia con Routing como patr\u00f3n es que subroutine routing suele ser una decisi\u00f3n puntual dentro de un flujo mayor, no el mecanismo principal de decisi\u00f3n.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">He visto sistemas que ponen routing en las tres capas simult\u00e1neamente, entry-point para la intenci\u00f3n general, mid-chain para decisiones basadas en datos, y subroutine para selecci\u00f3n de herramientas. Funciona, pero cada capa a\u00f1ade latencia. En producci\u00f3n, el overhead de tres decisiones secuenciales puede superar el beneficio de la especializaci\u00f3n.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3mo medir si tu routing funciona<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un router en producci\u00f3n sin m\u00e9tricas es una caja negra. No sabes si est\u00e1 tomando las decisiones correctas hasta que un usuario se queja. Estos son los indicadores m\u00ednimos:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Porcentaje de requests por ruta<\/strong>: La distribuci\u00f3n te dice si las categor\u00edas est\u00e1n equilibradas. Si el 70% de todo el tr\u00e1fico cae en una sola ruta, probablemente est\u00e1s subutilizando los handlers especializados o las descripciones de ruta est\u00e1n mal definidas.<\/li>\n\n\n\n<li><strong>Tasa de fallback<\/strong>: El porcentaje de inputs que el router no clasific\u00f3. Como regla pr\u00e1ctica, una tasa de fallback persistentemente alta suele indicar que las categor\u00edas o reglas necesitan revisi\u00f3n. Si el fallback crece con el tiempo, el espacio de clasificaci\u00f3n est\u00e1 cambiando y no lo est\u00e1s siguiendo.<\/li>\n\n\n\n<li><strong>Confianza media del router<\/strong>: En embedding-based, la puntuaci\u00f3n de similitud coseno. Cuando el proveedor lo expone, los log-probs de la etiqueta elegida o alguna puntuaci\u00f3n de confianza derivada del modelo. Una confianza media baja significa que el router opera en zona gris, clasifica, pero inseguro. Es se\u00f1al de que las rutas necesitan redefinici\u00f3n.<\/li>\n\n\n\n<li><strong>Rutas m\u00e1s confundidas<\/strong>: Cuando dos categor\u00edas compiten consistentemente por el mismo input, las descripciones de ruta se superponen. Revisar los pares de rutas con mayor tasa de clasificaci\u00f3n incorrecta (si tienes ground truth) es la forma m\u00e1s directa de encontrar ambig\u00fcedades.<\/li>\n\n\n\n<li><strong>Coste por decisi\u00f3n<\/strong>: En un router h\u00edbrido, esto te dice cu\u00e1ntos requests alcanzaron la capa LLM. Si el rule-based filtro intercepta el 80%, el coste real es una fracci\u00f3n del peor caso. Monitorear esto con el tiempo detecta si la distribuci\u00f3n de inputs est\u00e1 cambiando.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">No necesitas un dashboard completo. Un log estructurado con <code>{input_hash, ruta, metodo, confianza, timestamp}<\/code> y un resumen diario es suficiente para mantener el router bajo control. Lo que importa es detectar la deriva antes de que se convierta en un problema visible para el usuario.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Anti-patrones que rompen el routing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Los errores aqu\u00ed no son t\u00e9cnicos, son de dise\u00f1o. El c\u00f3digo de routing rara vez falla; falla la decisi\u00f3n de <em>qu\u00e9<\/em> enrutar y <em>cu\u00e1ndo<\/em>.<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Todo por un agente monol\u00edtico<\/strong>: Si un solo agente maneja reservas, consultas, quejas y debugging, el contexto se contamina y el modelo produce resultados mediocres en todo. Routing existe para evitar esto.<\/li>\n\n\n\n<li><strong>Sin fallback<\/strong>: Inputs no clasificados causan fallos silenciosos o respuestas gen\u00e9ricas que frustran al usuario. La ruta por defecto no es opcional.<\/li>\n\n\n\n<li><strong>Rutas superpuestas<\/strong>: Si dos rutas describen \u00absoporte t\u00e9cnico\u00bb y \u00abproblemas con el producto\u00bb, el router oscila entre ellas. Las descripciones de ruta deben ser mutuamente excluyentes.<\/li>\n\n\n\n<li><strong>Over-routing<\/strong>: A\u00f1adir capas de routing donde un pipeline lineal resuelve el problema. Cada decisi\u00f3n de routing a\u00f1ade latencia. Si el flujo es predecible, Chaining es m\u00e1s barato y m\u00e1s r\u00e1pido.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Cu\u00e1ndo NO usar Routing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Routing es soluci\u00f3n a un problema espec\u00edfico: inputs impredecibles que requieren flujos distintos. Si tu sistema procesa un tipo conocido de input en una secuencia fija, Routing a\u00f1ade complejidad sin retorno.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ejemplos concretos donde Routing sobra:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li>Un pipeline de extracci\u00f3n de datos de PDFs siempre sigue los mismos pasos.<\/li>\n\n\n\n<li>Un sistema que genera res\u00famenes desde texto, no necesita decidir entre flujos.<\/li>\n\n\n\n<li>Un classificador binario (spam\/no spam), es routing de dos ramas, pero un modelo directo es m\u00e1s eficiente que un router + dos handlers.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La regla pr\u00e1ctica: si puedes describir el flujo como \u00absiempre haz A, luego B, luego C\u00bb, no necesitas Routing. \u00dasalo cuando la pregunta real es \u00ab\u00bfcu\u00e1l de estos caminos tomar?\u00bb.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Routing y Prompt Chaining: no son rivales<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El primer art\u00edculo de esta serie cubri\u00f3 <a href=\"https:\/\/atlaszn.com\/blog\/2026\/05\/24\/prompt-chaining-llms-pipelines\/\" data-type=\"page\" data-id=\"581\">Prompt Chaining<\/a>. Routing no lo reemplaza, lo complementa. De hecho, la combinaci\u00f3n m\u00e1s com\u00fan en producci\u00f3n es:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Routing \u2192 Prompt Chaining<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El router decide el flujo, y dentro de cada flujo, un pipeline de chaining ejecuta los pasos especializados. En LangChain, <code>RunnableBranch<\/code> encapsula exactamente esto: cada rama es una cadena independiente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Muchos sistemas llamados \u00abagentes\u00bb en producci\u00f3n son realmente esta combinaci\u00f3n: un router en la entrada y pipelines chaining en cada rama. El branding ag\u00e9ntico oculta una arquitectura bastante convencional.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfCu\u00e1ndo debo usar Routing en lugar de un solo pipeline?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando el flujo de ejecuci\u00f3n depende de las caracter\u00edsticas del input. Si un usuario puede pedir informaci\u00f3n, hacer una reserva, o reportar un error, Routing clasifica la intenci\u00f3n y dirige cada caso a su handler especializado. Un pipeline \u00fanico intentar\u00eda cubrir todos los casos y terminar\u00eda siendo mediocre en cada uno.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfQu\u00e9 tipo de routing es m\u00e1s r\u00e1pido?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Rule-based routing es el m\u00e1s r\u00e1pido y determinista. Funciona con if-else, regex o match de keywords. El trade-off es que no generaliza a inputs no previstos. Para categor\u00edas bien definidas y alto volumen, es la opci\u00f3n correcta. Embedding-based queda en segundo lugar, la operaci\u00f3n de similitud coseno es pr\u00e1cticamente instant\u00e1nea.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfPuedo combinar varios tipos de routing?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed. Un patr\u00f3n com\u00fan y efectivo es usar rule-based como primer filtro para casos obvios y LLM-based como fallback para inputs que no encajan en las reglas. Esto reduce costos y latencia sin perder cobertura. Esencialmente, pagas con tokens solo lo que las reglas no resuelven.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfEs necesario un fallback en Routing?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed. Los inputs no clasificados rompen el sistema. Siempre define una ruta por defecto que maneje casos ambiguos, ya sea pidiendo clarificaci\u00f3n al usuario o derivando a un handler gen\u00e9rico. Un router sin fallback es una bomba de tiempo.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfQu\u00e9 es Auto-Flow en Google ADK?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Es el mecanismo de Google ADK para delegaci\u00f3n autom\u00e1tica basada en LLM. El agente principal eval\u00faa la solicitud y decide cu\u00e1l sub-agente especializado debe manejarla. No necesitas escribir l\u00f3gica de branching expl\u00edcita, el modelo mismo gestiona la delegaci\u00f3n. Es \u00fatil, pero pierde transparencia: no ves f\u00e1cilmente por qu\u00e9 el agente eligi\u00f3 una ruta sobre otra.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfCu\u00e1ndo Routing introduce m\u00e1s problemas que beneficios?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando el flujo es predecible y lineal. Si siempre ejecutas los mismos pasos en el mismo orden, Routing a\u00f1ade latencia y complejidad innecesaria. Un Prompt Chaining simple es m\u00e1s barato, m\u00e1s r\u00e1pido y m\u00e1s f\u00e1cil de debuggear.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusi\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Routing no hace m\u00e1s inteligente al modelo. Hace m\u00e1s direccional al sistema. La diferencia importa: un pipeline mal dirigido produce output correcto en el camino equivocado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En la pr\u00e1ctica, la mayor\u00eda de implementaciones \u00fatiles de Routing combinan rule-based como filtro r\u00e1pido con LLM-based como red de seguridad. El router perfecto no existe, pero uno bien dise\u00f1ado reduce el ruido entre la intenci\u00f3n del usuario y la acci\u00f3n del sistema.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Routing para sistemas con LLMs: c\u00f3mo clasificar inputs y dirigirlos al flujo correcto con LLM-based, embedding-based, rule-based y ML routing.<\/p>\n","protected":false},"author":1,"featured_media":641,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[125,121,123,122,82,86,85,120,124],"class_list":["post-640","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ia-automatizacion","tag-agentes-ia","tag-agentic-patterns","tag-google-adk","tag-intent-classification","tag-langchain","tag-langgraph","tag-llm","tag-routing","tag-runnablebranch"],"_links":{"self":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/640","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/comments?post=640"}],"version-history":[{"count":6,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/640\/revisions"}],"predecessor-version":[{"id":648,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/640\/revisions\/648"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/media\/641"}],"wp:attachment":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/media?parent=640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/categories?post=640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/tags?post=640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}