Módulo 11: Deep Agents
Proyecto Evolutivo: Versión Deep Agent (v6)
Descripción del proyecto
Has llegado al proyecto final del Módulo 11 y al momento pedagógico más importante de la guía.
En los módulos 6-10, tu AI Research Assistant creció pieza a pieza: búsqueda básica con Functional API (v1), retry y branching (v2), checkpointing y crash recovery (v3), HITL con approvals (v4), y multi-agente con supervisor y especialistas (v5). Aproximadamente 150 líneas de código para un sistema que planifica, busca, analiza, escribe, y se recupera de fallos. Diseñaste cada nodo, cada edge, cada condición de routing. Lo entiendes porque lo construiste.
Ahora vas a reimplementar ese mismo sistema como Deep Agent. ~40 líneas. El mismo resultado funcional — investigación multi-fuente con reporte consolidado — pero con un trade-off fundamental: ganaste velocidad de desarrollo y perdiste control sobre cada decisión del flujo.
El valor de este proyecto no es el código. Es la comparación. Poner la v5 y la v6 lado a lado y poder articular: "gané X, perdí Y, y elegiría Z para este caso de uso." Ese es el criterio que te convierte en AI Engineer. No el que sabe usar un framework — el que sabe elegir el framework correcto.
Objetivo del proyecto
Reimplementar el AI Research Assistant como Deep Agent (v6) y comparar directamente con la versión LangGraph (v5), articulando los trade-offs de cada enfoque.
Al completar este proyecto:
- Crearás un Deep Agent con planning, filesystem, subagent spawning, y memory configurados
- Ejecutarás la misma consulta en v5 (LangGraph) y v6 (Deep Agent) para comparar resultados
- Articularás exactamente qué ganaste (velocidad de desarrollo, simplicidad) y qué perdiste (control, debuggabilidad)
- Tendrás DOS versiones funcionales del Research Assistant en tu portfolio
Antes y después
v5 (Módulo 10): ~150 líneas, control total
research-assistant-v5/
├── agents/
│ ├── researcher.py ← Agente especializado en búsqueda
│ ├── analyst.py ← Agente especializado en análisis
│ ├── writer.py ← Agente especializado en redacción
│ └── supervisor.py ← Coordinador del sistema
├── tools/
│ ├── search_tools.py ← web_search, arxiv_search
│ ├── analysis_tools.py ← compare_sources, detect_patterns
│ └── writing_tools.py ← format_report
├── state/
│ └── multi_agent_state.py ← Estado compartido tipado
├── tracing/
│ ├── agent_logger.py ← Logging por agente
│ └── flow_tracer.py ← Tracing del flujo
└── main.py ← Orquestación + CLI
Tú diseñaste: qué agente hace qué, en qué orden, cuándo hacer retry, cuándo pedir aprobación, cómo loguear, y cómo combinar resultados.
v6 (Este proyecto): ~40 líneas, el framework decide
research-assistant-v6/
├── .env ← API keys
├── requirements.txt ← deep-agents, langchain-openai, python-dotenv
├── agent_memory/ ← Directorio de memoria (auto-generado)
└── main.py ← Todo el agente en un archivo
El framework decide: cómo descomponer la tarea, qué archivos crear, cuándo delegar, y cómo organizar los resultados.
Especificaciones técnicas
| Componente | Versión | Propósito |
|---|---|---|
| Python | 3.11+ | Runtime |
| deep-agents | v0.2+ | Framework de Deep Agents |
| langchain-openai | latest | Proveedor de modelos |
| langchain-community | latest | TavilySearchResults |
| python-dotenv | latest | Variables de entorno |
Instalación
pip install deep-agents langchain-openai langchain-community python-dotenv
Variables de entorno
# .env
OPENAI_API_KEY=sk-...
TAVILY_API_KEY=tvly-...
Paso 1: Definir el Deep Agent con planning
El primer paso es crear el agente con instrucciones que guíen el planning. Las instrucciones son el equivalente a diseñar el workflow en LangGraph — en lugar de nodos y edges, escribes qué quieres que el agente haga.
"""
main.py
Research Assistant v6 — Deep Agent version.
"""
from dotenv import load_dotenv
load_dotenv()
from deep_agents import create_deep_agent
from deep_agents.memory import FilesystemMemoryBackend
from langchain_community.tools import TavilySearchResults
web_search = TavilySearchResults(max_results=5)
memory = FilesystemMemoryBackend(
base_path="./agent_memory",
max_memories=200,
max_memory_age_days=90,
)
agent = create_deep_agent(
"openai:gpt-4.1",
tools=[web_search],
name="Research Assistant v6",
instructions=(
"Eres un asistente de investigación especializado. "
"Para cada tema de investigación: "
"1) Descompone la investigación en pasos claros con write_todos. "
"2) Busca fuentes diversas: web general, artículos técnicos, reportes. "
"3) Escribe los hallazgos de cada búsqueda en archivos separados dentro de research/. "
"4) Si el tema tiene múltiples dimensiones, delega búsquedas a subagentes especializados. "
"5) Analiza y sintetiza todos los hallazgos en analysis/synthesis.md. "
"6) Genera un reporte final estructurado en output/report.md con: "
" - Resumen ejecutivo "
" - Hallazgos principales "
" - Análisis "
" - Conclusiones "
" - Fuentes consultadas "
"Recuerda las preferencias del usuario entre sesiones."
),
memory=memory,
max_iterations=15,
)
Qué pasa cuando el agente recibe una tarea
Al ejecutar agent.run("Investiga el estado de AI agents en producción en 2025"), el agente:
- Lee memorias relevantes — si el usuario investigó antes, recupera preferencias
- Ejecuta write_todos — descompone la tarea:
Todos generados automáticamente:
1. [pending] Definir alcance: AI agents en producción, 2025
2. [pending] Buscar frameworks de agentes principales
3. [pending] Buscar casos de uso en producción documentados
4. [pending] Buscar challenges y limitaciones reportadas
5. [pending] Sintetizar hallazgos
6. [pending] Generar reporte final
- Ejecuta cada paso — buscando, escribiendo archivos, y actualizando todos
- Re-planifica si necesario — si una búsqueda revela una dimensión inesperada, agrega pasos
Comparación con v5
En v5, tú definiste este workflow como un grafo:
builder.add_edge(START, "plan")
builder.add_edge("plan", "researcher")
builder.add_edge("researcher", "analyst")
builder.add_edge("analyst", "writer")
builder.add_conditional_edges("writer", evaluate_quality, ...)
En v6, el equivalente es la sección de instrucciones. El agente traduce tus instrucciones en un plan de ejecución. Menos preciso que edges explícitos, pero más flexible — si la tarea cambia, el plan se adapta sin modificar código.
Paso 2: Configurar el virtual filesystem
El virtual filesystem es el equivalente al estado del grafo en LangGraph. En v5, los hallazgos vivían en state["findings"]. En v6, viven en archivos.
Estructura esperada de archivos
Cuando el agente completa una investigación, el filesystem se ve así:
workspace/
├── research/
│ ├── web_general.md ← Hallazgos de búsqueda web
│ ├── frameworks.md ← Información sobre frameworks específicos
│ └── production_cases.md ← Casos de uso en producción
├── analysis/
│ └── synthesis.md ← Análisis cruzado de todas las fuentes
└── output/
└── report.md ← Reporte final consolidado
Ventaja: context offloading
En v5, todos los hallazgos están en state["findings"] — una lista que crece con cada búsqueda. Si tienes 10 fuentes con 500 tokens cada una, son 5,000 tokens en el context window permanentemente.
En v6, cada hallazgo está en un archivo. El agente lee solo el archivo que necesita para el paso actual. El context window se mantiene lean.
v5 (LangGraph):
Context window: [system prompt] + [state con todos los findings] + [instrucción actual]
Tamaño: crece con cada paso
v6 (Deep Agent):
Context window: [system prompt] + [archivo actual] + [instrucción actual]
Tamaño: constante (~misma cantidad de tokens por paso)
Inspeccionar archivos generados
result = agent.run("Investiga AI agents en producción en 2025")
for path, content in result.files.items():
print(f"\n{'='*60}")
print(f"Archivo: {path}")
print(f"Tamaño: {len(content)} caracteres")
print(f"Preview: {content[:200]}...")
# Output esperado (varía según el modelo):
# ============================================================
# Archivo: research/web_general.md
# Tamaño: 2340 caracteres
# Preview: # Búsqueda Web: AI Agents en Producción
#
# ## Fuentes encontradas
# 1. **LangChain Blog** — "Agents in Production: Lessons Learned"
# Key insight: La mayoría de agentes en producción usan...
#
# ============================================================
# Archivo: research/frameworks.md
# Tamaño: 1890 caracteres
# Preview: # Frameworks de AI Agents
#
# ## Principales frameworks en 2025
# | Framework | Enfoque | Adopción |...
#
# ============================================================
# Archivo: analysis/synthesis.md
# Tamaño: 3100 caracteres
# Preview: # Síntesis: AI Agents en Producción (2025)
#
# ## Patrones identificados
# 1. La mayoría de implementaciones en producción son...
#
# ============================================================
# Archivo: output/report.md
# Tamaño: 4200 caracteres
# Preview: # AI Agents en Producción: Estado Actual (2025)
#
# ## Resumen Ejecutivo
# Los AI agents han transitado de demos a producción...
Paso 3: Habilitar subagent spawning
En v5, los agentes especializados (researcher, analyst, writer) estaban definidos en build time. Tú decidiste qué agente existía y qué hacía.
En v6, el agente principal decide en runtime si necesita delegar. La instrucción "delega búsquedas a subagentes especializados cuando el tema es amplio" le da permiso pero no obligación.
Cómo funciona internamente
Main Agent: "Investigar AI agents en producción"
│
├─ write_todos: 6 pasos
│
├─ Paso 1: Define scope → ejecuta directamente
│
├─ Paso 2: "Buscar frameworks" → decide que es específico
│ └─ spawn: framework_researcher
│ └─ Instrucciones: "Busca los principales frameworks de AI agents en 2025"
│ └─ Tools: [web_search]
│ └─ Retorna: hallazgos sobre LangGraph, CrewAI, AutoGen...
│ └─ Main Agent escribe resultado en research/frameworks.md
│
├─ Paso 3: "Buscar casos de producción" → decide que es diferente de paso 2
│ └─ spawn: production_researcher
│ └─ Instrucciones: "Busca empresas usando AI agents en producción"
│ └─ Tools: [web_search]
│ └─ Retorna: hallazgos sobre casos reales...
│ └─ Main Agent escribe resultado en research/production_cases.md
│
├─ Paso 4-6: Sintetiza y genera reporte → ejecuta directamente
│
└─ Resultado: 6/6 todos completados, 2 subagentes spawned
Control sobre subagentes
agent = create_deep_agent(
"openai:gpt-4.1",
tools=[web_search],
name="Research Assistant v6",
instructions="...",
memory=memory,
max_iterations=15,
max_subagents=3,
subagent_timeout=60,
)
max_subagents=3— máximo 3 subagentes simultáneos (previene explosión de costos)subagent_timeout=60— cada subagente tiene 60 segundos antes de ser terminado
Comparación con v5
| Aspecto | v5 (LangGraph) | v6 (Deep Agent) |
|---|---|---|
| Agentes definidos en | Build time (código) | Runtime (el framework decide) |
| Roles | Fijos: researcher, analyst, writer | Dinámicos: el agente crea lo que necesita |
| Coordinación | Supervisor con edges explícitos | Main agent coordina con write_todos |
| Control | Tú defines quién hace qué | El framework decide, tú guías con instructions |
| Debugging | Log por agente, sabes qué nodo falló | Log de subagent spawning, menos granular |
Paso 4: Configurar long-term memory
La memoria permite que el agente recuerde preferencias entre sesiones. En v5, esto requería un Store con namespaces y lógica de load/save. En v6, es una línea de configuración.
Configuración (ya incluida en Paso 1)
memory = FilesystemMemoryBackend(
base_path="./agent_memory",
max_memories=200,
max_memory_age_days=90,
)
Ejemplo de memoria en acción
Sesión 1:
result = agent.run(
"Investiga RAG techniques. Prefiero fuentes académicas de arxiv y NeurIPS."
)
print(result.output[:200])
# Output esperado (varía según el modelo):
# ## AI Research Report: RAG Techniques
#
# ### Resumen Ejecutivo
# Las técnicas de Retrieval-Augmented Generation han evolucionado...
# (prioriza fuentes de arxiv y NeurIPS como solicitado)
Sesión 2 (días después):
result = agent.run("Investiga AI safety")
print(result.output[:200])
# Output esperado (varía según el modelo):
# ## AI Research Report: AI Safety
#
# ### Resumen Ejecutivo
# El campo de AI safety ha experimentado avances significativos...
# (automáticamente prioriza arxiv y NeurIPS por la memoria de sesión 1)
No le repetiste la preferencia. El agente la recuperó del filesystem backend.
Inspeccionar memorias
import json
import os
memory_dir = "./agent_memory/memories"
if os.path.exists(memory_dir):
for f in os.listdir(memory_dir):
with open(os.path.join(memory_dir, f)) as fh:
mem = json.load(fh)
print(f" [{mem['type']}] {mem['content'][:80]}...")
# Output esperado:
# [preference] El usuario prefiere fuentes académicas de arxiv y NeurIPS...
Paso 5: Código completo (~40 líneas)
Este es el agente completo. Compáralo mentalmente con las ~150 líneas de v5.
"""
main.py
Research Assistant v6 — Deep Agent version.
Reimplementación completa del Research Assistant como Deep Agent.
"""
from dotenv import load_dotenv
load_dotenv()
from deep_agents import create_deep_agent
from deep_agents.memory import FilesystemMemoryBackend
from langchain_community.tools import TavilySearchResults
web_search = TavilySearchResults(max_results=5)
memory = FilesystemMemoryBackend(
base_path="./agent_memory",
max_memories=200,
max_memory_age_days=90,
)
agent = create_deep_agent(
"openai:gpt-4.1",
tools=[web_search],
name="Research Assistant v6",
instructions=(
"Eres un asistente de investigación especializado. "
"Para cada tema de investigación: "
"1) Descompone la investigación en pasos claros con write_todos. "
"2) Busca fuentes diversas: web general, artículos técnicos, reportes. "
"3) Escribe los hallazgos de cada búsqueda en archivos separados dentro de research/. "
"4) Si el tema tiene múltiples dimensiones, delega búsquedas a subagentes especializados. "
"5) Analiza y sintetiza todos los hallazgos en analysis/synthesis.md. "
"6) Genera un reporte final estructurado en output/report.md con: "
" Resumen ejecutivo, Hallazgos principales, Análisis, Conclusiones, Fuentes. "
"Recuerda las preferencias del usuario entre sesiones."
),
memory=memory,
max_iterations=15,
max_subagents=3,
subagent_timeout=60,
)
if __name__ == "__main__":
topic = input("Tema de investigación: ")
result = agent.run(topic)
print(f"\n{'='*60}")
print(f"Investigación completada")
print(f"{'='*60}")
print(f"Archivos generados: {list(result.files.keys())}")
print(f"Todos: {sum(1 for t in result.todos if t['status'] == 'completed')}/{len(result.todos)}")
print(f"Subagentes usados: {len(result.subagents_spawned)}")
print(f"\nReporte final:")
print(result.files.get("output/report.md", "No se generó reporte")[:500])
python main.py
# Input: Investiga el estado de AI agents en producción en 2025
# Output esperado:
# ============================================================
# Investigación completada
# ============================================================
# Archivos generados: ['research/web_general.md', 'research/frameworks.md', 'research/production_cases.md', 'analysis/synthesis.md', 'output/report.md']
# Todos: 6/6
# Subagentes usados: 2
#
# Reporte final:
# # AI Agents en Producción: Estado Actual (2025)
#
# ## Resumen Ejecutivo
# Los AI agents han transitado de prototipos a producción...
40 líneas. Planning, filesystem, subagentes, memoria, y CLI — todo incluido.
Paso 6: Comparación side-by-side
Este es EL momento del módulo. Pon ambas versiones frente a frente.
Líneas de código
v5 (LangGraph):
state/multi_agent_state.py ← 25 líneas
agents/researcher.py ← 35 líneas
agents/analyst.py ← 30 líneas
agents/writer.py ← 25 líneas
agents/supervisor.py ← 40 líneas
tools/*.py ← 45 líneas
tracing/*.py ← 30 líneas
main.py ← 50 líneas
─────────────────────────────────────────
Total: ~280 líneas (con tracing), ~150 sin tracing
v6 (Deep Agent):
main.py ← 40 líneas
─────────────────────────────────────────
Total: ~40 líneas
Tabla de análisis
| Aspecto | v5 (LangGraph) | v6 (Deep Agent) | Ganador |
|---|---|---|---|
| Líneas de código | ~150 (sin tracing) | ~40 | v6 (73% menos código) |
| Tiempo de desarrollo | ~2-4 horas | ~20 minutos | v6 |
| Control sobre el flujo | Total — cada nodo y edge definido | Parcial — instructions guían | v5 |
| Debugging | Excelente — log por agente, estado por nodo | Aceptable — logs de planning | v5 |
| Branching condicional | Sí — route_by_quality, evaluate | No — el framework decide | v5 |
| HITL | Granular — interrupt() en puntos específicos | General — apruebas la tarea | v5 |
| Multi-agente | Roles fijos, coordinación explícita | Dinámico, el framework decide | Depende |
| Persistencia | Checkpointer + Store | Filesystem + memory backend | Empate |
| Escalabilidad | Manual — agregas nodos/edges | Automática — el agente se adapta | v6 |
| Costo por ejecución | Medio (~$0.05-0.10) | Alto (~$0.10-0.30) | v5 |
| Mantenibilidad | Más código = más que mantener | Menos código = menos que mantener | v6 |
| Testing | Unit tests por nodo | Integration tests del resultado | v5 |
Análisis de trade-offs
Lo que ganaste con v6:
- ✅ Velocidad de desarrollo: 20 minutos vs 2-4 horas. Si necesitas un prototipo rápido, v6 gana
- ✅ Simplicidad: 40 líneas que un nuevo developer entiende en 5 minutos
- ✅ Adaptabilidad: si la tarea cambia, solo modificas instructions. En v5, editas nodos, edges, y condiciones
- ✅ Filesystem: los archivos son inspeccionables, no necesitas acceder al estado del grafo
- ✅ Memory built-in: una línea vs ~80 líneas de setup manual
Lo que perdiste con v6:
- ❌ Control fino: no decides "si quality_score < 0.7, busca más fuentes." El framework decide cuándo re-buscar
- ❌ HITL granular: no puedes pedir aprobación antes de que el analyst genere conclusiones. Apruebas la tarea completa o nada
- ❌ Debugging preciso: en v5, sabes que "el analyst recibió 8 hallazgos correctos pero su conclusión fue incorrecta." En v6, ves que "el agente generó un reporte con un error"
- ❌ Testing unitario: en v5, testeas researcher_node() independientemente. En v6, solo testeas el resultado final
- ❌ Costos predecibles: v5 tiene un número fijo de LLM calls (plan + search + analyze + write). v6 tiene un número variable (depende del planning del agente)
- ❌ Modelos por paso: en v5, analyst usa gpt-4.1 y los demás gpt-4.1-mini. En v6, el mismo modelo para todo
Ejecución comparativa
Ejecuta la misma consulta en ambas versiones:
from dotenv import load_dotenv
load_dotenv()
import time
QUERY = "Investiga el estado de AI agents en producción en 2025"
print("=" * 60)
print("v6 (Deep Agent)")
print("=" * 60)
start = time.time()
from deep_agents import create_deep_agent
from deep_agents.memory import FilesystemMemoryBackend
from langchain_community.tools import TavilySearchResults
agent_v6 = create_deep_agent(
"openai:gpt-4.1",
tools=[TavilySearchResults(max_results=5)],
name="Research Assistant v6",
instructions=(
"Investiga temas complejos. Descompone en pasos con write_todos. "
"Escribe hallazgos en archivos. Delega a subagentes cuando sea necesario. "
"Genera un reporte final en output/report.md."
),
memory=FilesystemMemoryBackend(base_path="./memory_v6"),
max_iterations=15,
)
result_v6 = agent_v6.run(QUERY)
time_v6 = time.time() - start
print(f"Tiempo: {time_v6:.1f}s")
print(f"Archivos: {len(result_v6.files)}")
print(f"Todos: {sum(1 for t in result_v6.todos if t['status'] == 'completed')}/{len(result_v6.todos)}")
print(f"Subagentes: {len(result_v6.subagents_spawned)}")
print(f"Reporte: {len(result_v6.files.get('output/report.md', ''))} chars")
# Output esperado (varía):
# Tiempo: ~45-90s
# Archivos: 4-5
# Todos: 5-6/5-6
# Subagentes: 1-3
# Reporte: ~3000-5000 chars
La comparación cuantitativa te da datos concretos para articular los trade-offs.
Criterios de éxito
Tu proyecto está completo cuando puedes responder SÍ a cada pregunta:
- ✅ ¿El Deep Agent genera un reporte de investigación funcional?
- ✅ ¿El agente usa write_todos para descomponer la tarea?
- ✅ ¿Los hallazgos se escriben en archivos separados (no todo en context window)?
- ✅ ¿El agente spawna al menos un subagente para búsquedas especializadas?
- ✅ ¿La memoria persiste preferencias entre sesiones?
- ✅ ¿Puedes articular 3 ventajas y 3 desventajas de v6 vs v5?
- ✅ ¿Tienes ambas versiones (v5 y v6) funcionales?
Escenarios de prueba
Ejecuta estos escenarios para validar que tu agente funciona en diferentes tipos de tareas.
Escenario 1: Investigación simple
result = agent.run("¿Cuál es el estado actual de LangGraph?")
assert len(result.todos) >= 3, "Debe planificar al menos 3 pasos"
assert "output/report.md" in result.files, "Debe generar reporte"
print("✅ Escenario 1 pasó")
Escenario 2: Investigación multi-dimensión
result = agent.run(
"Compara 3 enfoques de RAG: naive RAG, advanced RAG, y modular RAG. "
"Para cada uno, investiga: arquitectura, pros, contras, y casos de uso."
)
assert len(result.files) >= 3, "Debe generar múltiples archivos de investigación"
assert len(result.subagents_spawned) >= 1, "Debe delegar al menos una búsqueda"
print("✅ Escenario 2 pasó")
Escenario 3: Memoria entre sesiones
result1 = agent.run("Investiga AI safety. Prefiero papers de arxiv.")
result2 = agent.run("Investiga AI governance")
report = result2.files.get("output/report.md", "")
print("✅ Escenario 3 pasó" if "arxiv" in report.lower() else "❌ Memoria no funciona")
Escenario 4: Re-planning
result = agent.run(
"Investiga el impacto de AI en educación superior. "
"Si encuentras que hay diferencias significativas entre regiones, "
"investiga Europa y América Latina por separado."
)
assert len(result.todos) > 5, "Debe haber re-planificado con más pasos"
print("✅ Escenario 4 pasó")
Errores comunes
1. El agente no genera archivos — responde directamente
Causa: Las instrucciones no enfatizan suficiente el uso del filesystem.
Solución: Sé explícito en las instrucciones:
instructions=(
"SIEMPRE escribe los hallazgos en archivos. "
"NUNCA pongas toda la investigación en una sola respuesta. "
"Cada fuente → un archivo en research/. "
"El reporte final → output/report.md."
)
2. Demasiados subagentes — costos altos
Causa: No limitaste max_subagents o las instrucciones son muy amplias.
Solución:
agent = create_deep_agent(
...,
max_subagents=3,
subagent_timeout=60,
instructions=(
"Delega a subagentes SOLO cuando el tema tiene dimensiones "
"claramente diferentes que requieren búsquedas especializadas."
),
)
3. La memoria no persiste entre ejecuciones
Causa: Estás creando un nuevo FilesystemMemoryBackend con un path diferente cada vez.
Solución: Usa siempre el mismo base_path:
memory = FilesystemMemoryBackend(base_path="./agent_memory")
4. El plan tiene demasiados pasos — se vuelve lento
Causa: Las instrucciones son demasiado detalladas y el agente crea un paso por cada sub-instrucción.
Solución: Simplifica las instrucciones y limita iteraciones:
agent = create_deep_agent(
...,
max_iterations=10,
instructions=(
"Investiga el tema en 4-5 pasos máximo. "
"No descompongas innecesariamente."
),
)
5. El reporte es superficial comparado con v5
Causa: Un solo modelo maneja todo. En v5, gpt-4.1 hacía análisis profundo.
Solución: Usa gpt-4.1 (no mini) como modelo principal para investigaciones complejas:
agent = create_deep_agent("openai:gpt-4.1", ...)
El trade-off: más caro pero mejor calidad de razonamiento.
6. No puedes comparar con v5 porque no la tienes funcionando
Causa: No completaste el proyecto del Módulo 10.
Solución: La comparación es el punto central de este proyecto. Si no tienes v5, vuelve al Módulo 10 y complétala. La comparación sin ambas versiones pierde todo su valor pedagógico.
7. Los archivos del filesystem se mezclan entre ejecuciones
Causa: No limpias el workspace entre ejecuciones diferentes.
Solución: Usa --output-dir diferente por investigación, o limpia manualmente:
import shutil
if os.path.exists("./workspace"):
shutil.rmtree("./workspace")
8. El agente ignora las instrucciones de formato
Causa: Las instrucciones son demasiado largas y el modelo pierde contexto.
Solución: Prioriza las instrucciones más importantes al inicio del prompt:
instructions=(
"FORMATO: Reporte con Resumen, Hallazgos, Análisis, Conclusiones, Fuentes. "
"SIEMPRE usa write_todos. SIEMPRE escribe en archivos. "
"Luego: busca fuentes diversas, delega cuando sea necesario."
)
Perspectiva de portfolio
Ahora tienes DOS versiones del Research Assistant:
Tu portfolio:
├── Research Assistant v5 (LangGraph)
│ ├── ~150 líneas de código
│ ├── 4 agentes especializados + supervisor
│ ├── Custom workflow con edges y condiciones
│ ├── HITL granular, retry con quality evaluation
│ └── Demuestra: "Sé construir sistemas complejos desde cero"
│
└── Research Assistant v6 (Deep Agent)
├── ~40 líneas de código
├── Planning, filesystem, subagentes, memory
├── Framework decide el flujo
└── Demuestra: "Sé usar herramientas de alto nivel eficientemente"
En una entrevista, puedes decir:
"Construí el mismo Research Assistant de dos formas. La versión LangGraph tiene 150 líneas — diseñé cada nodo, edge, y condición. La versión Deep Agent tiene 40 líneas — el framework maneja planning, filesystem, y subagentes. Puedo articular los trade-offs: LangGraph me da control total sobre debugging, HITL, y flujo. Deep Agents me da velocidad de desarrollo y adaptabilidad. Elijo según el caso de uso."
Eso demuestra criterio, no dependencia de un framework.
Lo que viene: Módulo 12 — LangSmith y Producción
Tu Research Assistant ahora existe en dos versiones. Ambas funcionan. Pero ninguna está lista para producción.
¿Cuánto cuesta una investigación? ¿Cuántos tokens usa cada paso? ¿El reporte es consistentemente bueno o varía? ¿Cómo detectas cuando el agente "alucina" una fuente? ¿Cómo mides si v5 produce mejores reportes que v6?
El Módulo 12 agrega LangSmith: tracing completo de cada llamada al LLM, evaluation automatizada de la calidad de los reportes, token tracking por sesión, rate limiting, y un production checklist. Funciona con ambas versiones — LangGraph y Deep Agent.
M11: Construiste el agente (v5 y v6)
↓
M12: Lo haces observable y deployable
↓
Resultado: un agente en producción que puedes monitorear, evaluar, y mejorar
Es el módulo que transforma tu proyecto de aprendizaje en un sistema que podrías deployar.
Recursos del proyecto
- Deep Agents — Documentation — API reference completa de create_deep_agent
- Deep Agents — Planning — Documentación de write_todos y re-planning
- Deep Agents — Filesystem — Virtual filesystem API y mejores prácticas
- LangGraph vs Deep Agents — Artículo oficial sobre cuándo usar cada abstracción
- Building Effective Agents (Anthropic) — Framework de decisión para complejidad de agentes
- Cognitive Architectures for Language Agents — Paper sobre planning, memory, y tool use en agentes
Módulo 11 — LangChain & LangGraph: From Chains to Agents