{"id":687,"date":"2026-06-26T13:23:59","date_gmt":"2026-06-26T11:23:59","guid":{"rendered":"https:\/\/atlaszn.com\/blog\/?p=687"},"modified":"2026-06-26T14:26:06","modified_gmt":"2026-06-26T12:26:06","slug":"agente-integrando-patrones","status":"publish","type":"post","link":"https:\/\/atlaszn.com\/blog\/agente-integrando-patrones\/","title":{"rendered":"Dise\u00f1o de un agente: Integrando patrones ag\u00e9nticos en un pipeline"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Patrones que se ven bien en teor\u00eda<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Los art\u00edculos anteriores explicaron cinco patrones ag\u00e9nticos por separado: <a href=\"https:\/\/atlaszn.com\/blog\/tool-use\/\">Tool Use<\/a>, <a href=\"https:\/\/atlaszn.com\/blog\/paralelizacion-llm\/\">Parallelization<\/a>, <a href=\"https:\/\/atlaszn.com\/blog\/routing-llm\/\">Routing<\/a>, <a href=\"https:\/\/atlaszn.com\/blog\/prompt-chaining\/\">Prompt Chaining<\/a> y <a href=\"https:\/\/atlaszn.com\/blog\/reflection-llm\/\">Reflection<\/a>. Cada uno funciona bien de forma aislada. Pero la pregunta que nadie contestaba era: \u00bfC\u00f3mo se integran en un sistema coherente sin convertirse en un spaghetti de callbacks?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La respuesta est\u00e1 en la disciplina de dise\u00f1o y en mantener cada patr\u00f3n en su lugar. Cada patr\u00f3n necesita una responsabilidad clara, un punto de entrada definido y un punto de salida predecible. Si no, los patrones se solapan, las dependencias se entrelazan y el sistema se vuelve imposible de mantener.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Construimos un analizador financiero trivial para demostrarlo. No es un sistema de an\u00e1lisis financiero real. Es un sistema donde cada patr\u00f3n es visible, separado y funcional. El dominio financiero es simplemente un veh\u00edculo, tiene datos estructurados, reglas claras y un resultado f\u00e1cil de entender.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Arquitectura general<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El flujo sigue cinco etapas:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Tool Use<\/strong>: Obtener datos de fuentes externas (financials, balance, news).<\/li>\n\n\n\n<li><strong>Parallelization<\/strong>: Ejecutar las tres herramientas concurrentemente.<\/li>\n\n\n\n<li><strong>Routing<\/strong>: Clasificar la empresa seg\u00fan m\u00e9tricas (growth, risk, stable).<\/li>\n\n\n\n<li><strong>Prompt Chaining<\/strong>: Generar el informe paso a paso (resumen \u2192 riesgos \u2192 perspectivas \u2192 informe).<\/li>\n\n\n\n<li><strong>Reflection<\/strong>: Revisar y corregir el informe con un loop Generator-Critic.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Lo que esto no hace es intentar ser inteligente. Lo que intenta es que puedas se\u00f1alar cualquier bloque del c\u00f3digo y decir \u00abesto es Tool Use\u00bb o \u00abesto es Reflection\u00bb. Ese es el objetivo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El c\u00f3digo est\u00e1 disponible en <a href=\"https:\/\/github.com\/FeR12J\/demo_agentic_patterns\/tree\/v.1\">github<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Contexto central: La decisi\u00f3n que simplifica todo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El primer problema que aparece al integrar m\u00faltiples patrones es la gesti\u00f3n de datos. \u00bfC\u00f3mo pasan los datos entre patrones sin convertir el c\u00f3digo en un mapa de metro?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La soluci\u00f3n: un contexto central compartido.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from dataclasses import dataclass, field\nfrom typing import Optional\n\n@dataclass\nclass AnalysisContext:\n    \"\"\"Contexto compartido entre todos los patrones del pipeline.\"\"\"\n\n    # Entrada\n    company: str\n\n    # Datos crudos (Tool Use + Parallelization)\n    financials: dict = field(default_factory=dict)\n    balance: dict = field(default_factory=dict)\n    news: list = field(default_factory=list)\n\n    # Clasificaci\u00f3n (Routing)\n    company_type: Optional&#91;str] = None\n\n    # Generaci\u00f3n (Prompt Chaining)\n    summary: str = \"\"\n    risks: str = \"\"\n    outlook: str = \"\"\n    report_draft: str = \"\"\n\n    # Revisi\u00f3n (Reflection)\n    final_report: str = \"\"\n    reflection_iterations: int = 0\n    critic_feedback: str = \"\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cada patr\u00f3n lee y escribe en el mismo objeto. No hay que pasar 15 variables entre funciones. El c\u00f3digo se mantiene limpio y el flujo es visible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esta decisi\u00f3n tiene un tradeoff: El contexto central es mutable, lo que introduce el riesgo de que un patr\u00f3n modifique datos que otro patr\u00f3n a\u00fan necesita. En este sistema no es problema porque el flujo es secuencial y cada patr\u00f3n escribe en campos distintos. En sistemas m\u00e1s complejos, considerar un patr\u00f3n de eventos o un estado inmutable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00f3dulo 1: Tool Use y Parallelization<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Las herramientas son funciones que obtienen datos. Tres herramientas, tres fuentes independientes:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><code>get_financials()<\/code>: ingresos, crecimiento, margen, EPS.<\/li>\n\n\n\n<li><code>get_balance()<\/code>: efectivo, deuda, activos, pasivos.<\/li>\n\n\n\n<li><code>get_news()<\/code>: noticias recientes sobre la empresa.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La independencia es clave. Ninguna herramienta depende de la otra. Eso las convierte en candidatas ideales para Parallelization.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>async def fetch_data(ctx: AnalysisContext) -&gt; None:\n    \"\"\"Tool Use + Parallelization.\n\n    Tres herramientas independientes se ejecutan concurrentemente.\n    \"\"\"\n    financials, balance, news = await asyncio.gather(\n        asyncio.to_thread(get_financials, ctx.company),\n        asyncio.to_thread(get_balance, ctx.company),\n        asyncio.to_thread(get_news, ctx.company),\n    )\n\n    ctx.financials = financials\n    ctx.balance = balance\n    ctx.news = news<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>asyncio.gather()<\/code> ejecuta las tres herramientas concurrentemente. <code>asyncio.to_thread()<\/code> las mueve a un thread separado porque son llamadas bloqueantes. El tiempo total es el de la herramienta m\u00e1s lenta, no la suma de las tres.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">N\u00f3tese que las herramientas son funciones sincr\u00f3nicas normales. <code>asyncio.to_thread()<\/code> se encarga de ejecutarlas en un thread pool. Esto permite usar cualquier funci\u00f3n existente sin tener que reescribirla como async.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00f3dulo 2: Routing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El router clasifica la empresa seg\u00fan m\u00e9tricas financieras. No necesita LLM: las reglas son claras y reproducibles.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def route_company(ctx: AnalysisContext) -&gt; str:\n    \"\"\"Clasifica la empresa en un tipo basado en m\u00e9tricas financieras.\"\"\"\n    financials = ctx.financials\n    balance = ctx.balance\n\n    revenue_growth = financials.get(\"revenue_growth\", 0)\n    debt = balance.get(\"debt\", 0)\n    equity = balance.get(\"equity\", 1)\n\n    debt_ratio = debt \/ equity if equity &gt; 0 else 0\n\n    if revenue_growth &gt; 0.20:\n        ctx.company_type = \"growth\"\n    elif debt_ratio &gt; 0.6:\n        ctx.company_type = \"risk\"\n    else:\n        ctx.company_type = \"stable\"\n\n    return ctx.company_type<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tres reglas. Tres tipos de empresa. El router determinista es m\u00e1s r\u00e1pido y reproducible que un router basado en LLM. Cuando las categor\u00edas son claras, no necesitas un modelo para decidir.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El tipo de empresa afecta los prompts en Prompt Chaining: una empresa \u00abgrowth\u00bb recibe prompts enfocados en escalabilidad y valoraci\u00f3n. Una empresa \u00abrisk\u00bb recibe prompts enfocados en solvencia y liquidez. El routing personaliza la generaci\u00f3n sin a\u00f1adir complejidad.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00f3dulo 3: Prompt Chaining<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Aqu\u00ed ocurre la generaci\u00f3n real. El patr\u00f3n Prompt Chaining descompone una tarea compleja (generar un informe financiero) en etapas secuenciales m\u00e1s simples y controlables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cuatro pasos. Cada paso recibe el output del paso anterior como input:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Resumen ejecutivo<\/strong>: financials + balance \u2192 <code>ctx.summary<\/code><\/li>\n\n\n\n<li><strong>An\u00e1lisis de riesgos<\/strong>: summary + news \u2192 <code>ctx.risks<\/code><\/li>\n\n\n\n<li><strong>Perspectivas<\/strong>: summary + risks + company_type \u2192 <code>ctx.outlook<\/code><\/li>\n\n\n\n<li><strong>Informe completo<\/strong>: summary + risks + outlook \u2192 <code>ctx.report_draft<\/code><\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>async def run_chaining(ctx: AnalysisContext) -&gt; str:\n    \"\"\"Ejecuta la cadena completa de prompts.\"\"\"\n    await generate_summary(ctx)\n    await generate_risks(ctx)\n    await generate_outlook(ctx)\n    await generate_report(ctx)\n\n    return ctx.report_draft<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cada paso llama al modelo local. La llamada es simple: prompt + temperatura + max tokens.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>async def call_llm(prompt: str, system: str = \"\", temperature: float = 0.3) -&gt; str:\n    \"\"\"Llama al modelo local v\u00eda API OpenAI-compatible.\"\"\"\n    headers = {\"Content-Type\": \"application\/json\"}\n    messages = &#91;]\n\n    if system:\n        messages.append({\"role\": \"system\", \"content\": system})\n\n    messages.append({\"role\": \"user\", \"content\": prompt})\n\n    payload = {\n        \"model\": LLM_MODEL,\n        \"messages\": messages,\n        \"temperature\": temperature,\n        \"max_tokens\": 2048,\n    }\n\n    async with httpx.AsyncClient(timeout=60.0) as client:\n        response = await client.post(\n            f\"{LLM_BASE_URL}\/chat\/completions\",\n            json=payload,\n            headers=headers,\n        )\n        response.raise_for_status()\n        data = response.json()\n        return data&#91;\"choices\"]&#91;0]&#91;\"message\"]&#91;\"content\"]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La temperatura var\u00eda seg\u00fan el paso: 0.3 para resumen y riesgos (necesitan creatividad controlada), 0.2 para el informe final (necesita consistencia). El timeout de 60 segundos cubre la mayor\u00eda de casos con modelos locales de 12B.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">M\u00f3dulo 4: Reflection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El Generator ya produjo un draft del informe. El Critic lo revisa contra los datos originales y proporciona feedback. Si hay problemas, el Generator corrige. Loop hasta <code>OUTPUT_ACCEPTABLE<\/code> o m\u00e1ximo 3 iteraciones.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>async def reflect(ctx: AnalysisContext) -&gt; str:\n    \"\"\"Ejecuta el loop de Reflection.\"\"\"\n    for iteration in range(MAX_ITERATIONS):\n        ctx.reflection_iterations = iteration + 1\n\n        is_acceptable, feedback = await critic_review(ctx)\n\n        if is_acceptable:\n            ctx.final_report = ctx.report_draft\n            return ctx.final_report\n\n        # Feedback no aceptable \u2192 corregir\n        ctx.critic_feedback = feedback\n        await correct_report(ctx)\n\n    # Si llegamos aqu\u00ed, se agotaron las iteraciones\n    ctx.final_report = ctx.report_draft\n    return ctx.final_report<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El Critic eval\u00faa cuatro cosas: coherencia financiera, riesgos omitidos, afirmaciones sin soporte y contradicciones. Usa temperatura 0.1 para consistencia en la evaluaci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por qu\u00e9 3 iteraciones y no 5. Lo que vimos fue que despu\u00e9s de la tercera iteraci\u00f3n, la mejora marginal cae por debajo del 5% en la mayor\u00eda de casos. El coste crece linealmente pero el retorno no. Truncamos el historial despu\u00e9s de la tercera iteraci\u00f3n y el informe final suele ser aceptable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Orquestador: El coraz\u00f3n del sistema<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Todo converge en <code>analyze_company()<\/code>. Cinco pasos, cinco patrones, un contexto compartido.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>async def analyze_company(company: str) -&gt; str:\n    \"\"\"Orquestador principal.\"\"\"\n    # Paso 1: Crear contexto compartido\n    ctx = AnalysisContext(company=company)\n\n    # Paso 2: Tool Use + Parallelization\n    await fetch_data(ctx)\n\n    # Paso 3: Routing\n    company_type = route_company(ctx)\n\n    # Paso 4: Prompt Chaining\n    await run_chaining(ctx)\n\n    # Paso 5: Reflection\n    final_report = await reflect(ctx)\n\n    # Paso 6: Guardar informe\n    save_report(ctx, final_report)\n\n    return final_report<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El c\u00f3digo es limpio porque cada patr\u00f3n tiene una responsabilidad clara. No hay solapamiento. No hay dependencias cruzadas. El flujo es secuencial y predecible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Estructura del proyecto<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Archivo<\/th><th>Patr\u00f3n<\/th><th>Responsabilidad<\/th><\/tr><tr><td><code>main.py<\/code><\/td><td>Orquestador<\/td><td>Integra todos los patrones en un flujo coherente<\/td><\/tr><tr><td><code>models.py<\/code><\/td><td>Contexto<\/td><td>Objeto compartido entre todos los patrones<\/td><\/tr><tr><td><code>tools.py<\/code><\/td><td>Tool Use<\/td><td>Herramientas de datos (financials, balance, news)<\/td><\/tr><tr><td><code>routing.py<\/code><\/td><td>Routing<\/td><td>Clasificaci\u00f3n de empresa seg\u00fan m\u00e9tricas<\/td><\/tr><tr><td><code>chaining.py<\/code><\/td><td>Prompt Chaining<\/td><td>Generaci\u00f3n paso a paso del informe<\/td><\/tr><tr><td><code>reflection.py<\/code><\/td><td>Reflection<\/td><td>Revisi\u00f3n y correcci\u00f3n con Generator-Critic<\/td><\/tr><tr><td><code>prompts.py<\/code><\/td><td>Prompts<\/td><td>Templates de prompts para cada etapa<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Lo que aprendimos construy\u00e9ndolo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El primer bug que encontramos fue silencioso.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El c\u00f3digo estaba configurado con&nbsp;<code>gemma-3-12b<\/code>&nbsp;como modelo, pero el modelo en el servidor era google\/gemma3-12b. El endpoint redirig\u00eda autom\u00e1ticamente a&nbsp;<code>qwen3.6-27b<\/code> como fallback, un modelo de razonamiento que no expon\u00eda la salida en el campo&nbsp;<code>content<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nuestro pipeline le\u00eda \u00fanicamente&nbsp;<code>content<\/code>. El resultado era sistem\u00e1ticamente vac\u00edo en cada etapa del flujo. El sistema no fallaba ni lanzaba excepciones: Produc\u00eda informes con estructura v\u00e1lida en Markdown, pero sin contenido real, solo plantillas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Este es uno de los fallos m\u00e1s peligrosos en sistemas ag\u00e9nticos:&nbsp;<strong>La ejecuci\u00f3n es correcta, pero la sem\u00e1ntica est\u00e1 vac\u00eda<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Segundo problema: Prompts con placeholders interpretados literalmente<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">En el prompt del informe utiliz\u00e1bamos instrucciones del tipo:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>[Desarrolla el resumen con an\u00e1lisis de m\u00e9tricas clave]<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El modelo interpretaba estos bloques como texto literal, no como instrucciones. El resultado era un draft compuesto por instrucciones sin ejecutar.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El problema se amplifica en pipelines multi-etapa: El Critic detecta inconsistencias, pero al reinyectar el estado, el sistema sigue operando sobre una base vac\u00eda. El bucle se vuelve est\u00e9ril.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Tercer problema: Portabilidad del entorno<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">El modelo y el endpoint estaban hardcodeados. En entornos donde el modelo no exist\u00eda, la API devolv\u00eda&nbsp;<code>400 Bad Request<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La soluci\u00f3n fue introducir una capa de auto-detecci\u00f3n:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li>Consulta&nbsp;<code>\/models<\/code>&nbsp;al iniciar<\/li>\n\n\n\n<li>Validaci\u00f3n de disponibilidad del modelo<\/li>\n\n\n\n<li>Fallback autom\u00e1tico a un modelo compatible<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Esto elimina una clase completa de errores de despliegue silencioso.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Lecciones concretas<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">La simplicidad en configuraci\u00f3n es deuda t\u00e9cnica diferida. Variables de entorno y auto-detecci\u00f3n reducen fallos de producci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un modelo de razonamiento no es equivalente a un modelo instructivo. La diferencia no es conceptual, es de interfaz: la salida puede estar en campos distintos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Los placeholders en prompts (<code>[haz esto]<\/code>) degradan la ejecuci\u00f3n del modelo en lugar de guiarla. Deben separarse claramente instrucciones y datos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En pipelines ag\u00e9nticos, los errores silenciosos se propagan. Si el primer nodo produce vac\u00edo, el sistema entero ejecuta correctamente sobre entrada inv\u00e1lida.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Los errores de entorno pueden simular errores de modelo. Siempre hay que validar capa de inferencia antes de depurar prompts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lo importante no son los cinco patrones<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El objetivo del proyecto no era construir un analista financiero. El objetivo era demostrar que los patrones ag\u00e9nticos pueden componerse de forma limpia cuando cada uno tiene una responsabilidad bien definida.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El mismo dise\u00f1o podr\u00eda reutilizarse para:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li>An\u00e1lisis legal.<\/li>\n\n\n\n<li>Investigaci\u00f3n cient\u00edfica.<\/li>\n\n\n\n<li>Auditor\u00eda de c\u00f3digo.<\/li>\n\n\n\n<li>An\u00e1lisis de contratos.<\/li>\n\n\n\n<li>Revisi\u00f3n documental.<\/li>\n\n\n\n<li>Inteligencia competitiva.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Cambiando las herramientas y los prompts, la arquitectura permanece pr\u00e1cticamente igual. No se trata de ense\u00f1ar un analista financiero. Se trata de ense\u00f1ar una forma de dise\u00f1ar agentes. Y esa diferencia es enorme.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusi\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cinco patrones. Un contexto compartido. Un flujo coherente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lo que este proyecto demuestra no es que los patrones agenticos sean complejos. Demuestra que la complejidad no est\u00e1 en los patrones individuales, est\u00e1 en integrarlos sin que se solapen. Cuando cada patr\u00f3n tiene una responsabilidad clara, el sistema se mantiene limpio incluso con cinco componentes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El objetivo nunca fue construir el mejor analista financiero posible. El objetivo era demostrar que los patrones agenticos pueden convivir sin convertirse en un sistema imposible de mantener. Si despu\u00e9s de leer el c\u00f3digo puedes identificar d\u00f3nde empieza y termina cada patr\u00f3n, el experimento ha funcionado.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Implementaci\u00f3n de patrones ag\u00e9nticos integrados en un analizador financiero trivial con Python y modelo local.<\/p>\n","protected":false},"author":1,"featured_media":699,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[135,50,6],"tags":[121,143,85,142,127,140,83,141,131,120,136],"class_list":["post-687","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agentes","category-fundamentos","category-ia-automatizacion","tag-agentic-patterns","tag-gemma12b","tag-llm","tag-modelo-local","tag-parallelization","tag-patrones-agenticos","tag-prompt-chaining","tag-python","tag-reflection","tag-routing","tag-tool-use"],"_links":{"self":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/687","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=687"}],"version-history":[{"count":10,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/687\/revisions"}],"predecessor-version":[{"id":769,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/687\/revisions\/769"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/media\/699"}],"wp:attachment":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/media?parent=687"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/categories?post=687"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/tags?post=687"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}