\n\n\n\n Mi Elección de Marco de Agente: Construyendo Más Allá del PoC - AgntDev \n

Mi Elección de Marco de Agente: Construyendo Más Allá del PoC

📖 12 min read2,295 wordsUpdated Mar 25, 2026

¡Hola a todos! Leo aquí de agntdev.com. Hoy quiero hablar sobre algo que ha estado rondando en mi cabeza durante las últimas semanas, desde que me ensucié las manos con el último grupo de frameworks para agentes. Específicamente, estoy pensando en el aspecto de “construcción”: no solo en construir un agente, sino en cómo los construimos y las implicaciones que a menudo se pasan por alto al elegir un enfoque fundamental sobre otro. Hemos superado la etapa de “prueba de concepto” con los agentes, y ahora se trata de hacerlos fiables, mantenibles y verdaderamente útiles.

El ángulo específico en el que me estoy adentrando hoy es Los Costos Ocultos de los Componentes de Agente Premade: Por Qué Crear el Tuyo Propio Puede Ser a Veces Más Barato.

Ahora, sé lo que algunos de ustedes están pensando: “¿Leo, hablas en serio? Acabamos de conseguir todas estas herramientas y frameworks increíbles que nos dan módulos de memoria, componentes de planificación y ejecutores de herramientas preconstruidos. ¿Por qué demonios querría crear el mío propio?” Y créanme, me he hecho esa misma pregunta muchas veces. Durante mucho tiempo, fui un devoto seguidor del mantra de “usar el framework”. ¿Por qué reinventar la rueda, verdad?

Mi perspectiva comenzó a cambiar durante un proyecto reciente con un cliente. Estábamos construyendo un agente de soporte interno para una empresa SaaS de tamaño mediano. La idea era simple: un agente que pudiera responder consultas comunes de clientes a través de la documentación, verificar estados de base de datos e incluso escalar tickets cuando fuera necesario. Comenzamos con uno de los populares frameworks de agentes en Python; ya saben cuáles, prometen darte un agente en minutos. Y durante los primeros días, se sintió como magia.

Uniendo algunos componentes preconstruidos para memoria (una integración con una base de datos vectorial), planificación (una cadena básica de LLM) y ejecución de herramientas (llamando a algunas APIs internas), la demostración se veía genial. El cliente estaba impresionado. Brindamos con un kombucha de celebración. Pero luego llegó la prueba en el mundo real.

La Ilusión de la Velocidad: Cuando el “Inicio Rápido” se Convierte en “Depuración Lenta”

Los problemas comenzaron de manera sutil. El agente ocasionalmente alucinaba, lo cual es común con los LLMs, pero la manera en que alucinaba era peculiar. No solo inventaba cosas; estaba afirmando con confianza hechos que eran casi correctos, pero ligeramente erróneos, extrayendo de lo que parecía ser un revoltijo de interacciones históricas y contexto actual. Comenzamos a investigar el componente de memoria.

El módulo de memoria de este framework en particular estaba diseñado para un historial de conversación de propósito general. Almacenaba turnos, los resumía y recuperaba fragmentos relevantes basados en la similitud semántica. Suena bien en papel, ¿verdad? Pero nuestro agente necesitaba distinguir entre la consulta actual de un usuario, el contexto histórico del mismo usuario y el conocimiento general de la documentación. El componente preconstruido estaba tratando todo como una gran bolsa de palabras.

Mi equipo pasó días tratando de ajustar los parámetros de este componente de memoria de “caja negra”. Cambiamos los tamaños de fragmentos, probamos diferentes modelos de incrustación, incluso intentamos prefiltrar las entradas antes de que llegaran a la memoria. Nada funcionó del todo. El problema no era la *funcionalidad* del componente; era su *filosofía de diseño* que no se alineaba con nuestro problema específico.

Eventualmente nos dimos cuenta de que para obtener el comportamiento que necesitábamos, tendríamos que escribir un envoltorio elaborado alrededor de la memoria preconstruida (lo que se sentía como pelear contra el framework) o hurgar profundamente en su código fuente y modificarlo (lo que se sentía como inscribirse en una pesadilla de mantenimiento). Aquí es donde el “costo oculto” comenzó a mostrarse.

El Peso de la Abstracción: Cuando la Generalidad se Convierte en una Carga

Los frameworks, por su naturaleza, apuntan a la generalidad. Quieren servir a una audiencia amplia con necesidades diversas. Esto significa que sus componentes a menudo están diseñados para ser flexibles, configurables y algo opuestos a cómo *deberían* funcionar las cosas. Y para el 80% de los casos de uso, ¡eso es fantástico! Realmente acelera el desarrollo.

¿Pero qué pasa con el otro 20%? ¿Qué pasa cuando tu agente necesita un tipo muy específico de memoria que distingue entre el contexto de conversación efímero, preferencias de usuario a largo plazo y conocimiento estático? ¿O cuando su lógica de planificación necesita estar estrechamente integrada con el estado de un sistema externo complejo, en lugar de simplemente enhebrar llamadas a herramientas genéricas?

Ahí es cuando la abstracción comienza a pesarte. No solo estás usando un componente; estás heredando sus suposiciones, sus limitaciones y sus sesgos inherentes. Y tratar de forzar una cuña cuadrada en un agujero redondo, incluso con mucho martillo, generalmente lleva a una cuña rota o a un agujero deformado.

En nuestro escenario de agente de soporte, el componente de memoria preconstruido estaba diseñado para un flujo de conversación donde todo el contexto histórico es más o menos igual. Sin embargo, nuestro agente necesitaba priorizar una consulta nueva contra una base de datos de preguntas frecuentes, solo incorporando el historial de conversación si la consulta era ambigua o se refería claramente a una interacción previa. El componente del framework simplemente no estaba diseñado para esa distinción matizada sin una personalización pesada.

Cuando Crear el Tuyo Propio Tiene Sentido: Control y Claridad

Después de mucha deliberación (y algunas sesiones nocturnas de pizza), decidimos desechar el módulo de memoria preconstruido e implementar el nuestro. Inicialmente, se sintió como un paso atrás, pero la claridad que trajo fue inmediata.

Diseñamos un sistema de memoria específicamente para nuestras necesidades:

  1. Búfer de Conversación Efímero: Una simple deque (cola de doble extremo) para los últimos N turnos de la conversación actual. Se borra después de X minutos de inactividad o cuando llega una nueva consulta distinta.
  2. Almacenamiento de Perfil de Usuario: Una base de datos ligera (Redis, en nuestro caso) que almacena preferencias específicas de usuario, tickets recientes y preguntas frecuentes para ese usuario. Esto persiste a través de sesiones.
  3. Índice de Base de Conocimiento: Nuestra tienda vectorial de elección, específicamente para la documentación y preguntas frecuentes.

La lógica de recuperación fue entonces personalizada:

  • Primero, intenta emparejar la consulta directamente contra la Base de Conocimiento.
  • Si no hay suficiente confianza, revisa el Almacenamiento del Perfil de Usuario para interacciones o preferencias pasadas relevantes.
  • Como último recurso, o para agregar fluidez conversacional, extrae contexto del Búfer Efímero.

Aquí hay un bosquejo simplificado en Python de cómo podría verse nuestra recuperación de memoria personalizada, solo para darles una idea:


class CustomAgentMemory:
 def __init__(self, user_id, knowledge_base_client, user_profile_store):
 self.user_id = user_id
 self.kb_client = knowledge_base_client
 self.profile_store = user_profile_store
 self.conversation_history = collections.deque(maxlen=10) # Búfer efímero

 def add_to_history(self, role, message):
 self.conversation_history.append({"role": role, "content": message})

 def get_context(self, current_query: str) -> list[str]:
 context_chunks = []

 # 1. Priorizar Base de Conocimiento para respuestas directas
 kb_results = self.kb_client.search(current_query, top_k=3)
 if kb_results:
 context_chunks.extend([res["text"] for res in kb_results])
 # Si hay una coincidencia muy fuerte, tal vez no necesitamos mucho más por ahora
 if any(res["score"] > 0.8 for res in kb_results): 
 return context_chunks

 # 2. Revisar Perfil de Usuario para contexto personalizado
 user_prefs = self.profile_store.get_user_preferences(self.user_id)
 if user_prefs:
 context_chunks.append(f"Preferencias del usuario: {user_prefs}")
 
 recent_user_issues = self.profile_store.get_recent_issues(self.user_id, current_query)
 if recent_user_issues:
 context_chunks.extend(recent_user_issues)

 # 3. Agregar historial reciente de conversación para fluidez, pero de menor prioridad
 # Podríamos resumir esto o filtrarlo por relevancia para evitar ruido
 if self.conversation_history:
 # Enfoque simple: solo agregar turnos recientes. Más avanzado: resumir o filtrar LLM.
 for item in list(self.conversation_history):
 context_chunks.append(f"{item['role']}: {item['content']}")

 return context_chunks

# Ejemplo de Uso (simplificado por brevedad)
# kb_client = MyVectorDBClient()
# profile_store = MyRedisProfileStore()
# memory = CustomAgentMemory("user123", kb_client, profile_store)
# memory.add_to_history("user", "Mi impresora no está funcionando.")
# memory.add_to_history("agent", "¿Qué modelo es?")
# context = memory.get_context("¿Cómo puedo solucionar el atasco de papel en mi HP OfficeJet 3000?")
# print(context)

Este enfoque nos dio un control total. El LLM recibió exactamente el contexto que queríamos, en el orden que deseábamos, con el nivel adecuado de persistencia. La depuración se volvió sencilla porque conocíamos cada línea de código. No estábamos adivinando qué estaba haciendo la caja negra interna del framework.

Cuando los Componentes Premade Aún Brillan: La Regla del 80%

Ahora, no estoy diciendo que desheches todos los frameworks y componentes preconstruidos. ¡Para nada! Para muchos, muchos proyectos de agentes, son absolutamente la opción correcta. Si las necesidades de tu agente se alinean bien con las suposiciones del framework, ahorrarás una tremenda cantidad de tiempo.

Por ejemplo, si estás construyendo un chatbot simple que solo necesita responder preguntas de una única fuente de conocimiento y mantener un flujo conversacional básico, los componentes de memoria preconstruidos y generación aumentada de recuperación (RAG) de un framework son perfectos. Obtienes velocidad, valores predeterminados razonables y una base bien probada.

Otra área donde los marcos destacan es la orquestación de herramientas. Tener una manera estandarizada de definir herramientas, pasar argumentos y manejar sus salidas es increíblemente valioso. Incluso en nuestro escenario de memoria personalizada, todavía utilizamos el componente ejecutor de herramientas del marco, porque su diseño se ajustaba perfectamente a nuestras necesidades. No necesitábamos reinventar cómo un LLM decide qué API llamar; solo necesitábamos darle el contexto correcto para tomar esa decisión.

La clave es entender los compromisos. Es la clásica decisión de “comprar versus construir”, pero con un giro de agente. Comprar (usar un componente preconstruido) te da velocidad y, a menudo, un costo inicial de desarrollo más bajo. Construir (crear el tuyo propio) te da control, especificidad y, a menudo, costos de mantenimiento a largo plazo más bajos para agentes altamente especializados.

Conclusiones Accionables para Tu Próyecto de Agente

  1. Entiende Profundamente el Problema Central de Tu Agente: Antes de mirar los marcos, mapea exactamente lo que tu agente necesita hacer. ¿Qué tipo de información necesita recordar? ¿Cómo toma decisiones? ¿Con qué sistemas externos interactúa? Cuanto más específico puedas ser, mejor.

  2. Evalúa Críticamente los Componentes del Marco: No elijas un marco solo porque es popular. Para cada componente crítico (memoria, planificación, ejecución de herramientas), pregúntate:

    • ¿La filosofía de diseño de este componente se alinea con los requisitos únicos de mi agente?
    • ¿Cuánta configuración o envoltura necesitaría hacer para que encaje?
    • ¿Cuáles son sus supuestos subyacentes? (por ejemplo, ¿su memoria trata todo el contexto por igual?)
    • ¿Qué tan fácil es depurar si algo sale mal dentro de este componente? ¿Puedo inspeccionar fácilmente su estado interno?
  3. No Tengas Miedo de Mezclar y Combinar: No tienes que comprometerte por completo con un marco o crear completamente el tuyo. Puedes usar un marco por su excelente orquestación de herramientas, pero implementar tu propia memoria personalizada. O utilizar su módulo de planificación pero proporcionarle herramientas personalizadas. La modularidad es tu amiga.

  4. Prioriza la Claridad sobre la Astucia (Especialmente para la Lógica Central): Cuando estás construyendo un sistema que depende de un LLM para interpretar el contexto y tomar decisiones, la ambigüedad es tu enemiga. Si hacer tu propio componente te da control cristalino sobre la entrada al LLM o el estado de tu agente, esa claridad a menudo merece el tiempo de desarrollo extra.

  5. Considera el Costo de Mantenimiento: Si personalizas en gran medida un componente preconstruido o lo envuelves en capas de abstracción, podrías estar firmando para más dolores de cabeza de mantenimiento que si simplemente lo hubieras construido desde cero para empezar. Las actualizaciones al marco subyacente podrían romper tu lógica personalizada, lo que llevaría a más refactorización.

Mi experiencia con el proyecto de agente de soporte realmente reforzó la idea de que “más rápido” no siempre es “más barato” a largo plazo. A veces, tomarse el tiempo para construir una pieza central de tu sistema de agentes por ti mismo, adaptada precisamente a tus necesidades únicas, te ahorrará interminables depuraciones, frustraciones y eventual refactorización más adelante. Te da propiedad y una comprensión más profunda del cerebro de tu agente.

Así que, la próxima vez que estés empezando un proyecto de agente, detente antes de alcanzar ciegamente el componente preconstruido más conveniente. Piensa en lo que realmente diferencia a tu agente y considera si una solución personalizada podría ser la opción más económica al final. ¡Feliz construcción!

Artículos Relacionados

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: Agent Frameworks | Architecture | Dev Tools | Performance | Tutorials
Scroll to Top