La construcción de agentes autónomos basados en inteligencia artificial requiere una arquitectura sólida que permita tomar decisiones, ejecutar tareas y aprender del entorno. Más allá de un simple prompt, estos sistemas implementan patrones de diseño que les otorgan autonomía controlada. A continuación, se explican cuatro patrones fundamentales: supervisor-worker, reflexión, uso de herramientas y memoria, con ejemplos concretos de implementación.
Patrón supervisor-worker: delegación jerárquica
El patrón supervisor-worker organiza los agentes en una estructura jerárquica. Un agente supervisor recibe una tarea compleja, la divide en subtareas y las asigna a workers especializados. Cada worker ejecuta su parte y devuelve resultados al supervisor, que los integra o resuelve conflictos.
Ejemplo de implementación en Python usando LangChain:
`python
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_openai import ChatOpenAI
# Worker especializado en análisis de texto
text_worker = create_openai_functions_agent(
llm=ChatOpenAI(model="gpt-4", temperature=0),
tools=[analyze_sentiment_tool],
prompt=text_worker_prompt
)
text_executor = AgentExecutor(agent=text_worker, tools=[analyze_sentiment_tool])
# Supervisor que asigna según el tipo de tarea
def supervisor(task: str):
if "sentimiento" in task.lower():
return text_executor.invoke({"input": task})
elif "numérico" in task.lower():
return math_worker_executor.invoke({"input": task})
else:
return {"output": "Tarea no reconocida"}
`
En producción, este patrón permite escalar la capacidad del sistema: el supervisor decide qué worker usar y, si falla, puede reasignar la tarea a otro worker similar.
Patrón de reflexión: auto-evaluación y mejora continua
Un agente con capacidad de reflexión evalúa sus propias acciones antes o después de ejecutarlas. Este patrón se implementa en dos fases: primero, el agente genera una respuesta; segundo, analiza esa respuesta y la refina si es necesario. La reflexión puede ser interna (usando el mismo LLM) o externa (usando un evaluador aparte).
Ejemplo con un bucle de reflexión simple:
`python
def reflect_and_act(agent, task, max_iterations=3):
result = agent.run(task)
for i in range(max_iterations):
reflection = agent.run(
f"Revisa la siguiente respuesta y dime si tiene errores lógicos o de contenido. Respuesta: {result}"
)
if "ningún error" in reflection.lower():
break
result = agent.run(
f"Corrige la respuesta basándote en esta retroalimentación: {reflection}. Tarea original: {task}"
)
return result
`
Este patrón es útil en sistemas donde la precisión es crítica, como en asistentes legales o financieros. La reflexión también puede incluir verificación factual usando bases de conocimiento externas.
Uso de herramientas: extensión del agente mediante APIs
Un agente autónomo no está limitado al conocimiento de su modelo; puede llamar herramientas externas como APIs, bases de datos, calculadoras o servicios web. El patrón de tool use define una interfaz uniforme: el agente solicita una herramienta, el sistema la ejecuta y devuelve el resultado.
Implementación con funciones decoradas:
`python
from langchain.tools import tool
@tool
def get_weather(city: str) -> str:
"""Obtiene el clima actual de una ciudad usando OpenWeatherMap."""
import requests
api_key = "tu_api_key"
url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"
response = requests.get(url).json()
return f"Temperatura: {response['main']['temp'] - 273.15:.1f}°C"
# Agente con acceso a la herramienta
tools = [get_weather, calculator_tool, search_tool]
agent = create_openai_functions_agent(llm, tools, prompt)
`
El agente decide cuándo invocar get_weather y pasa los parámetros adecuados. Las herramientas pueden ser de lectura (como APIs de noticias) o de escritura (como envío de correos), pero siempre bajo restricciones de seguridad. Una buena práctica es cachear resultados de herramientas costosas para evitar llamadas repetidas.
Memoria: persistencia del contexto a corto y largo plazo
Sin memoria, un agente trata cada interacción como un evento aislado. El patrón de memoria añade persistencia: la memoria a corto plazo guarda el historial de la conversación actual; la memoria a largo plazo almacena información relevante de sesiones anteriores, como preferencias del usuario o hechos aprendidos.
Ejemplo con memoria en LangChain:
`python
from langchain.memory import ConversationSummaryMemory, VectorStoreRetrieverMemory
from langchain_community.vectorstores import FAISS
import faiss
# Memoria corta: resumen de la conversación
short_memory = ConversationSummaryMemory(llm=llm, memory_key="conversation_summary")
# Memoria larga: recuperación vectorial
retriever = FAISS.from_texts(
["Usuario: soy alérgico al maní", "Fecha de nacimiento: 1990-01-15"],
embedding_model
).as_retriever(search_kwargs={"k": 3})
long_memory = VectorStoreRetrieverMemory(retriever=retriever, memory_key="facts")
# Combinar ambas en el prompt
prompt = f"""
Contexto corto: {short_memory.buffer}
Hechos recordados: {long_memory.load_memory_variables({})["facts"]}
Consulta del usuario: {{input}}
"""
`
La memoria a largo plazo se implementa típicamente con bases vectoriales (FAISS, Chroma, Pinecone). La clave es indexar fragmentos de información que el agente pueda recuperar de forma relevante. Por ejemplo, un agente de atención al cliente recordaría la última compra del usuario y su historial de tickets.
Conclusión
Los patrones de arquitectura para agentes autónomos no son mutuamente excluyentes; un sistema robusto combina supervisor-worker para división de tareas, reflexión para auto-mejora, tool use para acceder al mundo exterior y memoria para mantener contexto. En la práctica, frameworks como LangChain, AutoGPT o CrewAI ya implementan estos patrones como primitivas, pero entenderlos permite personalizarlos según la necesidad. La elección del patrón adecuado depende del dominio: en sistemas críticos priorizamos reflexión; en entornos dinámicos, mejor tool use y memoria larga. La clave está en diseñar agentes que no solo respondan, sino que aprendan y se adapten.