Tutorial de introducción a Deep Agents
Deep Agents es un marco de desarrollo de agentes listo para usar (Batteries Included) lanzado oficialmente por LangChain, diseñado específicamente para tareas complejas, ejecución de flujos largos, planificación de múltiples pasos y escenarios de colaboración multiagente.
En comparación con los agentes tradicionales, que requieren que el desarrollador combine componentes como Prompt, Tool, Memory y Workflow, Deep Agents ya incorpora capacidades principales como planificación de tareas, sistema de archivos, orquestación de subagentes, compresión de contexto y gestión de memoria, lo que permite a los desarrolladores dedicar más esfuerzo a la lógica de negocio en lugar de a la construcción de la arquitectura subyacente.
Este tutorial está dirigido a desarrolladores sin conocimientos previos; te guía desde la instalación y configuración para que comprendas gradualmente el mecanismo central de funcionamiento de Deep Agents y crees un proyecto de agente de IA real y ejecutable con la API de DeepSeek.
¿Qué es Deep Agents?
Deep Agents puede entenderse como un marco de agente avanzado (Agent Harness) orientado a entornos de producción.
Oficialmente se define como: un marco de ejecución de agentes con infraestructura completa, y no solo un simple bucle de llamadas LLM + Tool.
Una vez completada la instalación, se obtienen directamente las siguientes capacidades, sin necesidad de desarrollo adicional:
- Planificación automática de tareas (Planning)
- Lectura y escritura del sistema de archivos (Filesystem)
- Colaboración de subagentes (Sub Agents)
- Compresión y gestión del contexto (Context Management)
- Ejecución de tareas largas (Long Running Tasks)
- Aprobación humana (Human-in-the-Loop)
- Memoria persistente (Memory)
- Salida en streaming (Streaming)
Objetivos de diseño de Deep Agents
Los agentes tradicionales suelen adoptar el patrón ReAct: entrada del usuario → razonamiento del LLM → llamada a herramienta → razonamiento del LLM → llamada a herramienta → salida del resultado.
Cuando la escala de la tarea es pequeña, este patrón funciona bien. Sin embargo, a medida que aumenta la complejidad de la tarea (por ejemplo, generar automáticamente informes de investigación de mercado, analizar los informes financieros de varias empresas o escribir el código completo de un proyecto), aparecen gradualmente los siguientes problemas:
- La ventana de contexto se expande rápidamente y supera los límites del modelo
- Las cadenas de razonamiento demasiado largas provocan una disminución del rendimiento
- El agente tiende a olvidar el trabajo realizado anteriormente
- Falta de aislamiento entre múltiples tareas, que interfieren entre sí
- La lógica de llamada a herramientas se vuelve cada vez más compleja y difícil de mantener
El objetivo principal de Deep Agents es resolver estos problemas de ingeniería en escenarios de tareas complejas.
Relación con LangChain y LangGraph
Muchos principiantes confunden fácilmente el posicionamiento de estos tres proyectos; en realidad se encuentran en diferentes niveles de abstracción.
| Marco | Nivel de posicionamiento | Responsabilidad principal | Escenarios aplicables |
|---|---|---|---|
| LangChain | Capa de componentes base | Proporciona componentes base de IA como Model, Prompt, Tool, Retriever y Output Parser | Capacidades base para construir un agente individual o una aplicación de IA |
| LangGraph | Capa de tiempo de ejecución | Proporciona gestión de estado, orquestación de flujos de trabajo, nodos y aristas, y persistencia de checkpoints | Escenarios complejos que requieren estructuras de grafo y flujos de ejecución personalizados |
| Deep Agents | Capa de marco de aplicación | Encapsula sobre LangGraph capacidades de nivel producción como planificación, sistema de archivos, subagentes, memoria y compresión de contexto | Construcción rápida de agentes complejos de múltiples pasos sin necesidad de diseñar la arquitectura desde cero |

Los tres no se reemplazan mutuamente, sino que pueden usarse de forma coordinada: LangChain proporciona los bloques, LangGraph es el marco de ingeniería que organiza los bloques, y Deep Agents es la capa de aplicación avanzada lista para usar construida sobre ellos. Cualquier LangGraph
CompiledStateGraphpuede pasarse como subagente a Deep Agents; las tres capas se pueden combinar de forma flexible.
Resumen de capacidades principales
Deep Agents incluye integrados los siguientes middlewares, listos para usar sin configuración adicional:
| Capacidad | Descripción | Componente principal |
|---|---|---|
| Planificación de tareas | Con herramientas integradaswrite_todoslas herramientas descomponen tareas complejas en pasos ordenados | TodoListMiddleware |
| Sistema de archivos virtual | Lee y escribe archivos, descarga salidas grandes de herramientas al disco para ahorrar ventana de contexto | FilesystemMiddleware |
| Subagente | Delega subtareas a subagentes dedicados con ventanas de contexto independientes | SubAgentMiddleware |
| Compresión de contexto | Resume automáticamente los mensajes históricos para evitar exceder los límites de contexto del modelo | SummarizationMiddleware |
| Human-in-the-loop | Se pausa antes de las llamadas a herramientas críticas y espera la aprobación humana | HumanInTheLoopMiddleware |
| Memoria a largo plazo | Memoria persistente entre sesiones, basada en LangGraph Store | MemoryMiddleware |
| Skills | Carga bajo demanda conocimientos de dominio reutilizables y conjuntos de instrucciones | SkillsMiddleware |
Instalación
Deep Agents se publica en PyPI, con el nombre de paquetedeepagents。
Se recomienda usaruvpara instalar, es más rápido; también se puede usar el tradicionalpip。
Instalación con uv (recomendado)
uv init uv add deepagents tavily-python uv sync
Instalación con pip
pip install deepagents tavily-python
Instalación junto con la API de DeepSeek
DeepSeek es compatible con la interfaz de OpenAI, por lo que también es necesario instalarlangchain-openai。
pip install deepagents langchain-openai
El único requisito de Deep Agents para el modelo es que este admitatool calling (llamada a herramientas)DeepSeek V3 y la serie DeepSeek R1 son compatibles, por lo que puede usarlos con confianza.
Notas de configuración
create_deep_agentEs la función principal para crear agentes y admite la siguiente configuración de parámetros.
| Parámetro | Tipo | ¿Obligatorio? | Descripción | Valor predeterminado |
|---|---|---|---|---|
model | str o instancia de modelo | no | Cadena del modelo, con el formatoprovider:model-nameo pasar directamente el objeto de modelo ya inicializado | anthropic:claude-sonnet-4-6 |
tools | Lista | no | Lista de funciones de herramienta personalizadas u objetos Tool de LangChain | None |
system_prompt | str o SystemMessage | no | Mensaje de sistema personalizado para definir el rol y el comportamiento del agente | None |
backend | BackendProtocol | no | Backend del sistema de archivos virtual, determina la ubicación de almacenamiento de archivos | StateBackend |
subagents | Lista | no | Lista de definiciones de subagentes, utilizada para delegar tareas | None |
memory | Lista | no | Lista de rutas de archivos AGENTS.md para cargar al inicio | None |
skills | Lista | no | Lista de rutas de directorios de Skills para cargar bajo demanda | None |
permissions | Lista | no | Reglas de control de permisos de acceso a nivel de rutas del sistema de archivos | None |
interrupt_on | dict | no | Especifica qué llamadas a herramientas requieren aprobación humana; debe usarse junto con el checkpointer. | None |
checkpointer | Checkpointer | no | Punto de control de persistencia de estado; debe configurarse en diálogos multiturno o HITL. | None |
store | BaseStore | no | Backend de almacenamiento a largo plazo entre sesiones. | None |
response_format | ResponseFormat | no | Definición del Schema para salida estructurada. | None |
middleware | Lista. | no | Middleware personalizado que se agrega al final de la pila de middleware predeterminada. | () |
debug | bool | no | Activa el modo de depuración y genera registros detallados. | False |
Comparación de backends del sistema de archivos
Deep Agents ofrece múltiples backends para controlar cómo el Agent lee y escribe archivos.
| Backend. | Ubicación de almacenamiento. | Persistencia entre sesiones. | Escenarios aplicables. |
|---|---|---|---|
| StateBackend | Dentro del estado del grafo de LangGraph. | No (válido dentro del mismo hilo). | Predeterminado, desarrollo local y escenarios simples. |
| FilesystemBackend | Disco local. | Sí | Requiere lectura/escritura real de archivos locales; úsese con precaución. |
| StoreBackend | LangGraph Store | Sí | Persistencia de diálogos multiturno, uso compartido entre hilos. |
| LocalShellBackend | Disco local + Shell. | Sí | Requiere ejecutar comandos Shell; solo en entornos de confianza. |
| CompositeBackend | Enrutar a múltiples backends. | Depende del subbackend. | Control fino de las estrategias de almacenamiento para diferentes directorios. |
Los principiantes pueden usar directamente el predeterminadoStateBackendy listo.FilesystemBackendyLocalShellBackendHará que el Agent opere directamente sobre tu sistema de archivos local; debes configurar los permisos estrictamente antes de usarlo.
Inicio rápido
Esta sección demuestra cómo crear un Deep Agent ejecutable con el mínimo código.
Configurar la clave API de DeepSeek
DeepSeek es compatible con el formato de interfaz de OpenAI; es necesario configurar tanto la API Key como la Base URL.
export OPENAI_API_KEY="sk-your-deepseek-api-key" export OPENAI_BASE_URL="https://api.deepseek.com" export TAVILY_API_KEY="your-tavily-api-key"
La API Key de DeepSeek se puede solicitar enplatform.deepseek.comla solicitud. Apunta la variable de entorno
OPENAI_BASE_URLa la dirección de DeepSeek; LangChain reenviará las solicitudes automáticamente.TAVILY_API_KEY debe solicitarse en el sitio web oficial de Tavilyhttps://www.tavily.com/ para generar una clave con formato tvly-xxxxxxxx.
Ejemplo mínimo: agente Hello World
Crea un Agent con una herramienta personalizada y envía el primer mensaje a DeepSeek.
Ejemplo
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
# Usa ChatOpenAI y apunta base_url a DeepSeek; esta es la forma más directa de integración
model = ChatOpenAI(
model="deepseek-v4-flash", # Obligatorio: nombre del modelo
api_key=os.environ["OPENAI_API_KEY"], # Obligatorio: clave de API de DeepSeek
base_url="https://api.deepseek.com", # Obligatorio: endpoint compatible con OpenAI de DeepSeek
)
# Define una herramienta personalizada simple; el docstring de la función es la descripción de la herramienta
def get_weather(city: str) -> str:
"""Consulta el clima de una ciudad especificada."""
# En un proyecto real, aquí se llamaría a una API de clima real
return f"{city} hoy está soleado, 25°C, adecuado para salir."
# Crea el Agent, pasando la instancia del modelo y la lista de herramientas
agent = create_deep_agent(
model=model,
tools=[get_weather],
system_prompt="Eres un asistente amigable que puede consultar información meteorológica.",
)
# Llama al Agent; messages acepta el formato de mensajes estilo OpenAI
result = agent.invoke({
"messages": [{"role": "user", "content": "¿Cómo está el clima hoy en Beijing?"}]
})
# Imprime la respuesta final del Agent
print(result["messages"][-1].content)
# 运行脚本 python hello_agent.pyContenido de salida:
Hoy en Beijing **soleado**, temperatura **25°C**, muy adecuado para salir. ☀️
Nota: el Agent devuelve una lista completa de mensajes (
messages), la respuesta final está al final de la lista, es decir,result["messages"][-1].content。
Uso detallado
Esta sección muestra paso a paso las capacidades principales de Deep Agents a través de varios escenarios reales.
Uso de DeepSeek R1 para tareas de razonamiento
DeepSeek R1 es un modelo potenciado para razonamiento, adecuado para tareas que requieren análisis complejo.
Ejemplo
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
# DeepSeek R1: modelo diseñado específicamente para razonamiento complejo
model = ChatOpenAI(
model="deepseek-v4-pro", # Modelo de pensamiento de DeepSeek
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# Ejemplo de herramienta de cálculo matemático
def calculate(expression: str) -> str:
"""Evalúa de forma segura una expresión matemática y devuelve el resultado del cálculo."""
try:
# Nota: en producción debe usarse una biblioteca de evaluación de expresiones más segura
result = eval(expression, {"__builtins__": {}}, {})
return f"Resultado del cálculo: {expression} = {result}"
except Exception as e:
return f"Error de cálculo: {str(e)}"
agent = create_deep_agent(
model=model,
tools=[calculate],
system_prompt="Eres un experto en análisis matemático, bueno para descomponer problemas complejos y resolverlos paso a paso.",
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Calcula la suma de todos los números impares del 1 al 100 y verifica el resultado."}]
})
print(result["messages"][-1].content)
Salida de ejecución:
再换一种方法做交叉验证:
- 1 到 100 所有整数之和:\( \frac{100 \times 101}{2} = 5050 \)
- 1 到 100 的偶数之和:\( 2 + 4 + \cdots + 100 = 2 \times \frac{50 \times 51}{2} = 2550 \)
- 奇数之和:\( 5050 - 2550 = 2500 \)
两种方法结果一致。
---
**结论**:1 到 100 的所有奇数之和为 **2500**。
**推导回顾**:
- 奇数序列首项 1,末项 99,项数 \( \frac{99-1}{2}+1 = 50 \)
- 等差数列求和:\( S = \frac{n(a_1 + a_n)}{2} = \frac{50 \times (1+99)}{2} = 2500 \)
Personalización del mensaje de sistema
A través desystem_promptlos parámetros se definen el rol, los objetivos de la tarea y las normas de comportamiento del Agent.
Ejemplo
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# Prompt del sistema personalizado: define la identidad, responsabilidades y criterios de comportamiento del Agent
code_review_instructions = """Eres un ingeniero senior de Python, especializado en revisión de código.
Tus responsabilidades:
- Revisar legibilidad, rendimiento y seguridad del código
- Señalar posibles bugs y sugerencias de mejora
- Proporcionar ejemplos concretos de modificación
Formato de respuesta:
1. Puntuación global (1-10)
2. Lista de problemas principales
3. Sugerencias de mejora específicas (con fragmentos de código modificados)
"""
agent = create_deep_agent(
model=model,
system_prompt=code_review_instructions,
)
# Envía un fragmento de código para revisión
code_to_review = """
def find_user(users, name):
for i in range(len(users)):
if users[i]['name'] == name:
return users[i]
return None
"""
result = agent.invoke({
"messages": [{"role": "user", "content": f"Por favor revisa el siguiente código:\n```python{code_to_review}```"}]
})
print(result["messages"][-1].content)
Salida en streaming
Para escenarios que requieren mostrar el progreso en tiempo real, se puede usar elstreammétodo para recibir la salida del Agent por bloques.
Ejemplo
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
agent = create_deep_agent(
model=model,
system_prompt="Eres un experto en redacción técnica, hábil para escribir documentación técnica clara y comprensible.",
)
# El método stream devuelve un generador; cada vez produce un bloque de evento
for chunk in agent.stream({
"messages": [{"role": "user", "content": "Escribe una breve introducción sobre los decoradores de Python."}]
}):
# chunk es un diccionario que contiene mensajes incrementales
if "messages" in chunk:
for msg in chunk["messages"]:
if hasattr(msg, "content") and msg.content:
print(msg.content, end="", flush=True)
print() # Salto de línea final
Conversación de múltiples turnos (con checkpoints)
Junto conMemorySaverel checkpoint, se pueden implementar conversaciones con estado entre turnos.
Ejemplo
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver # Checkpoint en memoria; los datos se pierden tras reiniciar
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# MemorySaver guarda el estado de la conversación en memoria; se pierde al finalizar el proceso
# En producción se recomienda usar SqliteSaver o PostgresSaver
checkpointer = MemorySaver()
agent = create_deep_agent(
model=model,
system_prompt="Eres un asistente de programación servicial.",
checkpointer=checkpointer, # Es obligatorio pasarlo; de lo contrario, el diálogo multiturno no puede recordar el contexto
)
# thread_id es el identificador único del hilo de conversación; el mismo thread_id comparte el mismo contexto
config = {"configurable": {"thread_id": "ejemplo-session-001"}}
# Primer turno
result1 = agent.invoke(
{"messages": [{"role": "user", "content": "Me llamo EJEMPLO, estoy aprendiendo Python."}]},
config=config,
)
print("Respuesta del primer turno:", result1["messages"][-1].content)
# Segundo turno: el Agent puede recordar la información del turno anterior
result2 = agent.invoke(
{"messages": [{"role": "user", "content": "¿Cómo me llamo? ¿Qué estoy aprendiendo?"}]},
config=config,
)
print("Respuesta del segundo turno:", result2["messages"][-1].content)
Primera respuesta:你好,EJEMPLO!很高兴认识你,Python 是一门非常适合初学者的语言... Segunda respuesta:你叫 EJEMPLO,你正在学习 Python!...
Función de thread_id:Todas las llamadas bajo el mismo
thread_idcomparten el mismo historial de conversación. Diferentesthread_idestán aislados entre sí y no se interfieren. Puede entenderse como el "número de sala de conversación".
Demo integral: agente de informes de investigación
Esta sección presenta un Agent completo de informes de investigación, usando DeepSeek V3 como modelo principal, integrando herramientas de búsqueda personalizadas y demostrando el uso de subagentes.
Descripción del escenario
Construiremos un Agent que recibe el tema de investigación del usuario, descompone automáticamente la tarea, llama a herramientas de búsqueda para recopilar información y finalmente produce un informe estructurado.
Ejemplo
# Demo: crea un Agent de informes de investigación usando DeepSeek API + Deep Agents
# Instalación de dependencias: pip install deepagents langchain-openai requests
import os
import json
from tavily import TavilyClient
from typing import Literal
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver
# ──────────────────────────────────────────
# 1. Inicializar el modelo DeepSeek
# ──────────────────────────────────────────
main_model = ChatOpenAI(
model="deepseek-v4-flash", # Fuerte capacidad integral, adecuado para planificación y redacción
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
temperature=0.3, # Opcional: reducir la aleatoriedad para hacer el informe más riguroso
)
# Inicializar el cliente de Tavily (para la herramienta de búsqueda)
tavily_client = TavilyClient(
api_key=os.environ["TAVILY_API_KEY"]
)
# ──────────────────────────────────────────
# 2. Definir la herramienta de búsqueda Tavily
# ──────────────────────────────────────────
def web_search(
query: str,
max_results: int = 5,
) -> str:
"""Buscar información en internet con Tavily"""
try:
response = tavily_client.search(
query=query,
max_results=max_results,
search_depth="advanced",
include_answer=True,
include_raw_content=False,
)
lines = []
# Resumen de la respuesta de IA
if response.get("answer"):
lines.append(f"Resumen: {response['answer']}\n")
# Resultados de búsqueda
for idx, item in enumerate(response.get("results", []), start=1):
lines.append(
f"""
[{idx}] {item.get('title', '')}
URL: {item.get('url', '')}
Contenido: {item.get('content', '')}
""".strip()
)
return "\n\n".join(lines)
def format_report(title: str, sections: str) -> str:
"""Organizar el contenido de la investigación en un informe en formato Markdown.
Args:
title: Título del informe
sections: Contenido de cada sección, representado como cadena JSON, formato: {"nombre de sección": "contenido"}
"""
try:
data = json.loads(sections)
lines = [f"# {title}\n"]
for section_name, content in data.items():
lines.append(f"## {section_name}\n")
lines.append(f"{content}\n")
return "\n".join(lines)
except Exception as e:
return f"Error de formato: {str(e)}"
# ──────────────────────────────────────────
# 3. Definir un subagente especializado (experto en integración de información)
# El subagente tiene una ventana de contexto independiente, evitando la expansión del contexto del agente principal.
# ──────────────────────────────────────────
report_writer_subagent = {
"name": "report-writer", # Obligatorio: nombre único del subagente
"description": "Asistente profesional de redacción de informes, responsable de integrar los materiales de investigación en un informe claramente estructurado.", # Obligatorio: el agente principal usa esta descripción para decidir cuándo delegar tareas
"system_prompt": "Eres un experto profesional en redacción de informes. Tras recibir los materiales de investigación, organízalos en un informe que incluya resumen, contenido principal y conclusiones, con un lenguaje claro y conciso.",
"tools": [format_report], # Opcional: herramientas específicas del subagente
# Si no se especifica model, hereda el modelo del agente principal
}
# ──────────────────────────────────────────
# 4. Configurar y crear el Deep Agent
# ──────────────────────────────────────────
checkpointer = MemorySaver()
research_instructions = """Eres un asistente de investigación profesional, experto en investigación profunda y redacción de informes.
Cuando el usuario proporcione un tema de investigación, debes:
1. Usar la herramienta web_search para buscar información relevante (buscar al menos 2-3 veces, cubriendo diferentes perspectivas)
2. Organizar y resumir los materiales recopilados
3. Delegar en el subagente report-writer la redacción del informe final
4. Entregar el informe completo al usuario
Nota: utiliza palabras clave diferentes en cada búsqueda para obtener información más completa.
"""
agent = create_deep_agent(
model=main_model,
tools=[web_search], # Herramientas disponibles para el agente principal
system_prompt=research_instructions,
subagents=[report_writer_subagent], # Registrar subagente
checkpointer=checkpointer,
)
# ──────────────────────────────────────────
# 5. Ejecutar el agente
# ──────────────────────────────────────────
print("Investigando, espere por favor...\n")
result = agent.invoke(
{
"messages": [{
"role": "user",
"content": "Por favor, ayúdame a investigar qué es LangGraph y cuáles son sus principales casos de uso."
}]
},
config={"configurable": {"thread_id": "ejemplo-research-001"}}
)
print("=" * 60)
print("Informe de investigación")
print("=" * 60)
print(result["messages"][-1].content)
正在研究中,请稍候... ============================================================ 研究报告 ============================================================ # LangGraph 研究报告 ## 摘要 LangGraph 是 LangChain 团队推出的一个用于构建有状态、多角色 LLM 应用的框架... ## 主要内容 ### 核心概念 LangGraph 将 Agent 的执行流程建模为一张有向图... ### 主要应用场景 1. 多步骤推理任务 2. 人机协作(Human-in-the-loop)工作流 3. 多 Agent 协作系统 ... ## 结论 LangGraph 是构建生产级 Agent 应用的重要工具...
Ejemplo de human-in-the-loop
Para operaciones sensibles (por ejemplo, eliminar archivos, enviar correos electrónicos), se puede configurar al agente para que pause y espere confirmación humana antes de ejecutar.
Ejemplo
# Human-in-the-loop: hacer que el agente solicite aprobación humana antes de ejecutar operaciones peligrosas
import os
from langchain.tools import tool
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import Command
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# Usar el decorador @tool para definir herramientas (requiere el paquete langchain)
@tool
def delete_file(path: str) -> str:
"""Elimina el archivo en la ruta especificada."""
# En un proyecto real, aquí se llamaría a os.remove(path)
return f"El archivo {path} ha sido eliminado."
@tool
def read_file(path: str) -> str:
"""Lee el contenido del archivo en la ruta especificada."""
return f"Contenido del archivo {path}: (contenido de ejemplo)"
# interrupt_on configura qué herramientas requieren aprobación humana
# True indica permitir: aprobar, editar parámetros, rechazar, enviar respuesta personalizada
# False indica que no se requiere aprobación
# dict permite controlar con precisión los tipos de operaciones permitidas
checkpointer = MemorySaver() # HITL debe usarse junto con checkpointer
agent = create_deep_agent(
model=model,
tools=[delete_file, read_file],
interrupt_on={
"delete_file": True, # Operación de eliminación: requiere flujo de aprobación completo
"read_file": False, # Operación de lectura: no requiere aprobación
},
checkpointer=checkpointer,
)
config = {"configurable": {"thread_id": "ejemplo-hitl-001"}}
# Primera llamada: el agente se pausa al llegar a delete_file
print("Iniciando agente...")
result = agent.invoke(
{"messages": [{"role": "user", "content": "Por favor, elimina el archivo /tmp/test.txt."}]},
config=config,
)
# Comprobar si hay una interrupción pendiente de aprobación
for msg in result.get("messages", []):
print(f"Mensaje del agente: {msg.content if hasattr(msg, 'content') else msg}")
# Reanudar ejecución: pasar la decisión de aprobación
# "approve" indica aprobar la ejecución de esa herramienta
# "reject" indica rechazar, el agente no ejecutará esa herramienta
print("\nAprobación del usuario: operación de eliminación aprobada")
final_result = agent.invoke(
Command(resume={"decision": "approve"}),
config=config,
)
print("Resultado final:", final_result["messages"][-1].content)
Cómo funciona interrupt_on:Cuando el agente está a punto de llamar a una herramienta marcada, LangGraph activa un
interrupt, la ejecución del agente se pausa. Puedes, a través deCommand(resume=...)pasar el resultado de la aprobación para reanudar la ejecución.
Preguntas frecuentes
A continuación se presentan las dudas y consideraciones habituales al usar Deep Agents.
¿Cómo decidir entre usar Deep Agents o usar LangChain/LangGraph directamente?
| Escenario | Elección recomendada | Razón |
|---|---|---|
| Necesita planificación, lectura/escritura de archivos, subagentes, compresión de contexto | Deep Agents | Estas capacidades están listas para usar, sin necesidad de ensamblarlas manualmente |
| Necesita una encapsulación ligera, solo el bucle de llamada a herramientas | LangChain create_agent | Más ligero que Deep Agents, sin middleware integrado |
| Necesita una estructura de grafo personalizada, el bucle no es el bucle estándar de llamada a herramientas | LangGraph | Personalizar completamente la lógica de nodos y aristas del grafo |
| LangGraph CompiledStateGraph como subagente | Uso combinado | Puedes pasar un grafo personalizado como subagente a Deep Agents |
Recomendaciones para elegir modelos DeepSeek
| Modelo | Cadena model | Características | Escenarios adecuados |
|---|---|---|---|
| deepseek-v4-flash | deepseek-v4-flash | Fuerte capacidad integral, rápida velocidad, bajo precio | Tareas generales, conversación cotidiana, escritura |
| deepseek-v4-pro | deepseek-v4-pro | Fuerte capacidad de razonamiento, cadena de pensamiento integrada | Matemáticas, código, razonamiento lógico complejo |
¿Qué hacer si el agente no devuelve resultados tras llamar a una herramienta?
El valor de retorno de la función de herramienta debe ser una cadena o un tipo serializable a cadena.
Si la herramienta devuelve objetos complejos (como diccionarios, listas), se recomienda usarjson.dumps(result, ensure_ascii=False)convertirlo antes de devolverlo.
¿Cómo lograr que el agente solo pueda acceder a archivos específicos a la vez?
UsarpermissionsEl parámetro configura los permisos de acceso al sistema de archivos, lo que permite controlar con precisión que el agente solo pueda leer y escribir en rutas especificadas.
Ejemplo
from deepagents.permissions import FilesystemPermission
from langchain_openai import ChatOpenAI
import os
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
agent = create_deep_agent(
model=model,
permissions=[
FilesystemPermission(path="/workspace/", read=True, write=True), # Permitir lectura y escritura en el directorio de trabajo
FilesystemPermission(path="/secrets/", read=False, write=False), # Prohibir acceso a directorios sensibles
],
)
¿Cómo se combinan el mensaje de sistema predeterminado del agente y mi propio mensaje?
El mensaje de Deep Agents se compone de cuatro partes concatenadas en un orden fijo:
USER(tu system_prompt) →BASE(mensaje predeterminado del SDK) →SUFFIX(ajustes específicos del proveedor del modelo)
Tu mensaje siempre estará al principio y no se sobrescribirá. El mensaje predeterminado del SDK le indica al modelo cómo usar las herramientas de planificación y archivos, por lo que en la mayoría de los casos no es necesario reescribirlo.
Errores comunes de los principiantes
Error común 1:Olvidar pasar
checkpointer. Al usar Human-in-the-loop (interrupt_on) o conversaciones de múltiples turnos,es obligatoriopasar el checkpointer; de lo contrario, el estado no se puede guardar y el agente dará un error.
Error común 2:La función de herramienta no tiene docstring. Deep Agents usa el docstring de la función como descripción de la herramienta, para que el modelo sepa cuándo llamarla. Una herramienta sin docstring puede hacer que el modelo no sepa cuándo llamarla o incluso se niegue a usarla.
Error común 3:Modificar directamente en el middleware
self. Los subagentes del agente y las operaciones concurrentes pueden ejecutarse simultáneamente; modificar directamente los atributos de la instancia del middleware provoca condiciones de carrera (race condition). Cuando necesites guardar estado, debes pasarlo a través del state del grafo, no mediante variables de instancia del middleware.
Más recursos
Para más contenido, consulta la siguiente documentación:
| Nombre | Dirección |
|---|---|
| Documentación oficial de Deep Agents (página principal) | https://docs.langchain.com/deepagents |
| Repositorio de Deep Agents en GitHub (código fuente) | https://github.com/langchain-ai/deepagents |
| Documentación de Python de Deep Agents (guía de desarrollo en Python) | https://docs.langchain.com/oss/python/deepagents/overview |
| Documentación de JavaScript de Deep Agents (guía de desarrollo JS/TS) | https://docs.langchain.com/oss/javascript/deepagents/overview |
| Manual de referencia de la API de Python de Deep Agents | https://reference.langchain.com/python/deepagents/deepagents |
| Manual de referencia de la API de JavaScript de Deep Agents | https://reference.langchain.com/javascript/modules/deepagents.html |
| Documentación oficial de LangChain (biblioteca de componentes básicos) | https://docs.langchain.com/langchain |
| Documentación oficial de LangGraph (Runtime del agente) | https://docs.langchain.com/langgraph |
| Repositorio de LangGraph en GitHub (Código fuente) | https://github.com/langchain-ai/langgraph |
| Repositorio de LangChain en GitHub (Código fuente) | https://github.com/langchain-ai/langchain |
| Sitio web oficial de LangSmith (Depuración y monitoreo de agentes) | https://www.langchain.com/langsmith |
| Documentación oficial de LangSmith | https://docs.smith.langchain.com |
| Sitio web oficial de Tavily (Herramienta de búsqueda) | https://tavily.com |
| Documentación de la API de Tavily | https://docs.tavily.com |
| Plataforma abierta de DeepSeek (Servicios de modelos) | https://platform.deepseek.com |
| Documentación de la API de DeepSeek | https://api-docs.deepseek.com |