Curso
Kit de Desarrollo de Agentes de Google (ADK): Una guía con proyecto de demostración
En este blog, te explicaré cómo crear un asistente de viajes multiagente basado en IA utilizando el nuevo kit de desarrollo de agentes (ADK) de código abierto de Google. Kit de Desarrollo de Agentes (ADK) y la tecnología A2A (Agente a Agente) de Google.
Utilizaremos varios agentes para gestionar vuelos, hoteles y recomendaciones de actividades, que se comunicarán mediante API REST y servidores FastAPI. Al final, lo envolveremos todo con un frontend Streamlit limpio para una experiencia de usuario intuitiva.
Mantenemos a nuestros lectores al día de lo último en IA enviándoles The Median, nuestro boletín gratuito de los viernes que desglosa las noticias clave de la semana. Suscríbete y mantente alerta en sólo unos minutos a la semana:
¿Qué es el Kit de Desarrollo de Agentes de Google (ADK)?
El ADK de Google es un marco modular, listo para la producción, para construir agentes potenciados por LLM. Es el mismo conjunto de herramientas que impulsa a los agentes dentro de los productos de Google, como Agentspace y Customer Engagement Suite. Ahora de código abiertoayuda a los desarrolladores a crear aplicaciones multiagente potentes, flexibles e interoperables.
¿Por qué utilizar el Kit de Desarrollo de Agentes (ADK)?
ADK proporciona la flexibilidad de Python con estructuras integradas para la gestión de estados, devoluciones de llamada, streaming y entrada/salida estructurada. Veamos sus principales características:
- Multiagente por diseño: ADK puede componer agentes en flujos de trabajo paralelos, secuenciales o jerárquicos.
- Modelo agnóstico: Funciona con Gemini, GPT-4o, Claude, Mistral y otros a través de
LiteLlm
. - Modular y escalable: El usuario puede definir agentes especializados y delegar de forma inteligente utilizando la orquestación incorporada.
- Preparado para streaming: Admite la interacción en tiempo real, incluido el audio/vídeo bidireccional.
- Herramientas incorporadas: Admite CLI local e interfaz de usuario web para depuración y evaluación.
- Admite el despliegue: ADK contenedoriza y despliega fácilmente agentes en distintos entornos.
¿Qué es el protocolo Agent2Agent (A2A) de Google?
El protocolo Agent2Agent (A2A) es un estándar abierto e independiente del proveedor desarrollado por Google para facilitar la comunicación y la colaboración entre agentes de IA en diversas plataformas y marcos de trabajo.
Los agentes ADK exponen un punto final HTTP estándar /run
y metadatos a través de .well-known/agent.json
. Esto permite descubrir agentes y facilitar la comunicación entre ellos (o incluso con orquestadores externos como LangGraph o CrewAI).
Aunque es opcional, añadir el archivo de metadatos A2A hace que tus agentes sean interoperables con el ecosistema más amplio de herramientas y orquestadores de agentes.
Resumen del proyecto: Planificador de viajes basado en IA con ADK y A2A
Este proyecto construye un planificador de viajes que:
- Toma como entrada el destino, las fechas y el presupuesto.
- Llama a tres agentes distintos:
flight_agent
: Recomienda opciones de vuelo.stay_agent
: Encuentra hoteles dentro de tu presupuesto.activities_agent
: Sugiere actividades atractivas.- Después, utiliza un
host_agent
central para orquestar todas las peticiones. - Por último, utiliza una interfaz de usuario Streamlit para la interacción con el usuario.
Todos los agentes están alojados como servidores FastAPI independientes y exponen un punto final /run
. La comunicación se realiza a través del cliente compartido compatible con A2A.
Nota: Este proyecto se ejecuta completamente en tu máquina local por simplicidad, pero puedes desplegar fácilmente cada agente y la interfaz de usuario en plataformas en la nube como Render, Railway o Google Cloud Run para un acceso escalable.
Paso 1: Requisitos previos
Empecemos por instalar las siguientes bibliotecas:
pip install google-adk litellm fastapi uvicorn httpx pydantic openai streamlit
A continuación, configura tu clave de la API de OpenAI; no dudes en utilizar otro proveedor de modelos. Para aprender a configurar tu clave API de OpenAI, te recomiendo este tutorial introductorio sobre la API GPT-4o.
export OPENAI_API_KEY="your_key_here"
Paso 2: Esquema compartido y utilidades
Antes de poder construir agentes inteligentes, tenemos que definir un lenguaje común para que puedan hablar entre ellos. En nuestra configuración, esto se hace utilizando
- Un esquema compartido para la entrada (definido a través de Pydantic)
- Una utilidad cliente REST para llamar a los agentes
- Una envoltura de servidor REST para estandarizar el punto final
/run
en todos los agentes
Se colocan en las carpetas shared/
y common/
para mantener el código modular. Veamos cada una de ellas.
Crear una shared/schemas.py
archivo
Definimos un esquema TravelRequest
utilizando Pydantic. Esto garantiza que todos los agentes estén de acuerdo en la estructura de las solicitudes entrantes, que incluye el destino, las fechas del viaje y el presupuesto del usuario.
from pydantic import BaseModel
class TravelRequest(BaseModel):
destination: str
start_date: str
end_date: str
budget: float
Esta clase ayuda en:
- Mantener la coherencia de las entradas para todos los agentes.
- Añadir validación automática con FastAPI.
- Simplificar la reutilización del código.
Crear una common/a2a_client.py
archivo
Esta ligera utilidad asíncrona permite a cualquier agente (especialmente al anfitrión) invocar a otro agente mediante el protocolo A2A llamando al punto final /run
.
import httpx
async def call_agent(url, payload):
async with httpx.AsyncClient() as client:
response = await client.post(url, json=payload, timeout=60.0)
response.raise_for_status()
return response.json()
Esta utilidad envía asíncronamente una solicitud POST al endpoint /run
de otro agente utilizando httpx
. Devuelve la respuesta JSON analizada y genera un error si la solicitud falla.
Utilizaremos esta utilidad en nuestro agente anfitrión para llamar a las páginas flight_agent
, stay_agent
, y activities_agent
.
Crear una common/a2a_server.py
archivo
En lugar de escribir una ruta FastAPI personalizada para cada agente, la generalizamos utilizando la función create_app(agent)
, que maneja:
- Servir al agente en
/run
- Recibir una solicitud de viaje
- Devolver una respuesta estructurada
from fastapi import FastAPI
import uvicorn
def create_app(agent):
app = FastAPI()
@app.post("/run")
async def run(payload: dict):
return await agent.execute(payload)
return app
Esta utilidad crea una aplicación FastAPI con una ruta estándar /run
que delega la ejecución en el agente proporcionado. Garantiza una interfaz agente-agente (A2A) coherente para todos los servicios que utilicen una entrada JSON estructurada.
Juntos, estos componentes compartidos hacen que nuestro sistema multiagente sea más mantenible, reutilizable y alineado con la filosofía A2A de Google de mensajería interagente sencilla y estructurada.
Paso 3: Construir el sistema multiagente con ADK y A2A
Ahora que ya tenemos los contratos compartidos y las utilidades, empecemos a construir los agentes individuales. Para transformar esto en un sistema verdaderamente modular y multiagente, utilizaremos el protocolo A2A de Google, una sencilla interfaz basada en HTTP que permite a los agentes comunicarse de forma coherente e interoperable.
A2A (Agente-a-Agente) permite la coordinación plug-and-play entre agentes, tanto si son funciones Python locales como si están alojados en redes. Cada agente expone un punto final /run
con un esquema común y actúa como un servicio.
En nuestra demostración, tenemos cuatro agentes:
host_agent
: Orquesta a todos los demás agentesflight_agent
: Encuentra vuelos adecuadosstay_agent
: Sugiere alojamientoactivities_agent
: Recomienda participar en actividades locales
Todos los agentes tienen una estructura similar, con 3 archivos y una subcarpeta:
agents/
├── host_agent/
│ │ ├── agent.py # Optional if host logic is minimal
│ │ ├── task_manager.py # Calls other agents and aggregates responses
│ │ ├── __main__.py # Starts FastAPI app via common/a2a_server.py
│ │ └── .well-known/
│ │ └── agent.json # A2A Agent Card metadata
├── flight_agent/
├── stay_agent/
└── activities_agent/
Cada agente utiliza google.adk.agents.Agent
, una envoltura del modelo LiteLlm
, y Runner
para la ejecución. Empieza creando los siguientes archivos dentro de la carpeta activities_agent
y repite lo mismo para flight_agent
y stay_agent
.
Crear una agent.py
archivo
Definamos ahora la lógica de nuestro activities_agent
, que se encargará de generar experiencias locales atractivas basadas en el itinerario de viaje del usuario.
Paso 1: Importaciones
Comenzamos importando los módulos esenciales para configurar y ejecutar nuestro agente.
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
import json
Este agente utiliza componentes de Google ADK como Agent, '
Runner, ' y LiteLlm
y gestiona el estado mediante InMemorySessionService.
. La biblioteca Types
se utiliza para construir avisos estructurados.
Paso 2: Agente de actividades
Ahora, instanciamos el propio agente utilizando la clase Agente del ADK.
activities_agent = Agent(
name="activities_agent",
model=LiteLlm("openai/gpt-4o"),
description="Suggests interesting activities for the user at a destination.",
instruction=(
"Given a destination, dates, and budget, suggest 2-3 engaging tourist or cultural activities. "
"For each activity, provide a name, a short description, price estimate, and duration in hours. "
"Respond in plain English. Keep it concise and well-formatted."
)
)
El parámetro instrucción define la instrucción del sistema que guía el comportamiento de la LLM. Aunque en este ejemplo se utiliza el inglés llano, puedes ajustar la instrucción para que devuelva JSON estructurado para facilitar el análisis sintáctico.
Paso 3: Gestión de la sesión
A continuación, para realizar un seguimiento de las interacciones de los usuarios, configuramos un Corredor junto con la información de la sesión.
session_service = InMemorySessionService()
runner = Runner(
agent=activities_agent,
app_name="activities_app",
session_service=session_service
)
USER_ID = "user_activities"
SESSION_ID = "session_activities"
El Runner
gestiona la ejecución del agente para una sesión de aplicación concreta. Mientras que la clase InMemorySessionService
almacena el contexto en la memoria. A continuación, definimos los identificadores de usuario y de sesión. Sin embargo, en producción, podrían ser dinámicas o específicas del usuario. Esto garantiza que existe una sesión ADK nueva antes de enviar cualquier consulta al agente LLM.
Paso 4: Ejecutar la lógica del agente
La función execute()
gestiona las peticiones entrantes, construye una solicitud, invoca el modelo y analiza la salida.
async def execute(request):
session_service.create_session(
app_name="activities_app",
user_id=USER_ID,
session_id=SESSION_ID
)
prompt = (
f"User is flying to {request['destination']} from {request['start_date']} to {request['end_date']}, "
f"with a budget of {request['budget']}. Suggest 2-3 activities, each with name, description, price estimate, and duration. "
f"Respond in JSON format using the key 'activities' with a list of activity objects."
)
message = types.Content(role="user", parts=[types.Part(text=prompt)])
async for event in runner.run_async(user_id=USER_ID, session_id=SESSION_ID, new_message=message):
if event.is_final_response():
response_text = event.content.parts[0].text
try:
parsed = json.loads(response_text)
if "activities" in parsed and isinstance(parsed["activities"], list):
return {"activities": parsed["activities"]}
else:
print("'activities' key missing or not a list in response JSON")
return {"activities": response_text} # fallback to raw text
except json.JSONDecodeError as e:
print("JSON parsing failed:", e)
print("Response content:", response_text)
return {"activities": response_text} # fallback to raw text
La función execute()
construye dinámicamente una solicitud utilizando los parámetros de la solicitud entrante, como el destino, las fechas y el presupuesto. Esto es lo que ocurre bajo el capó:
- La solicitud indica al modelo que devuelva un objeto JSON estructurado que contenga una lista de actividades.
- Se construye un objeto
Content
y se pasa al ADK Runner, que espera asíncronamente la respuesta final del modelo utilizando un generador de flujo. - Una vez recibida la respuesta final, el agente extrae la salida de texto sin procesar e intenta parsearla como JSON.
- Si el análisis sintáctico tiene éxito y existe la clave de actividades esperada, se devuelven los datos estructurados.
- Si falta la clave o está malformada, la opción alternativa es devolver la respuesta de texto sin formato, de modo que la interfaz de usuario siga teniendo una salida utilizable.
- Este enfoque de doble manejo garantiza una degradación gradual cuando el LLM devuelve texto plano en lugar de JSON estructurado.
Esta estrategia mejora la solidez y la experiencia del usuario, sobre todo cuando los resultados del modelo varían ligeramente debido a la temperatura o a la interpretación puntual.
Crear una task_manager.py
archivo
Tras definir la lógica de execute()
en agent.py
, ahora la conectamos a la configuración del servidor compatible con ADK mediante task_manager.py
.
from .agent import execute
async def run(payload):
return await execute(payload)
Este archivo actúa como una fina envoltura alrededor de la función execute()
definida anteriormente. Pone el método run()
a disposición de módulos externos, especialmente el script del servidor en __main__.py
.
Crear una __main__.py
archivo
El archivo __main__.py
lanza un servidor FastAPI en el puerto 8003, que sirve al agente en el punto final /run
.
from common.a2a_server import create_app
from .task_manager import run
app = create_app(agent=type("Agent", (), {"execute": run}))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, port=8003)
Esto es lo que ocurre:
- El
create_app()
(de common/a2a_server.py) envuelve nuestro agente en una interfaz FastAPI estándar compatible con A2A. - Construimos dinámicamente un objeto con un método
execute()
para que el ADK pueda invocar correctamente arun()
. - Esta separación nos permite mantener interfaces API sin estado mientras reutilizamos la lógica central del agente.
Crear una .well-known/agent.json
archivo
Utilizamos este archivo JSON para describir la identidad y la finalidad del agente según el protocolo A2A (Agente a Agente).
{
"name": "activity_agent",
"description": "Agent providing activity details."
}
Nota: Aunque el archivo .well-known/agent.json
no es utilizado directamente por nuestros agentes en este proyecto, se adhiere a la especificación A2A y es importante para el descubrimiento, la introspección y la compatibilidad futura con orquestadores como LangGraph, CrewAI o el registro de agentes de Google.
También se utiliza una lógica similar para flight_agent
y stay_agent
.
Paso 4: Coordinación con host_agent
El host_agent
actúa como planificador central de la demo. La página host_agent
ejemplifica el modelo de controlador en los sistemas multiagente. Separa la toma de decisiones y la ejecución, permitiendo que cada agente posterior se centre en su nicho mientras centraliza la lógica de coordinación. Esto no sólo simplifica las pruebas y el escalado, sino que también refleja la arquitectura de microservicios del mundo real en los sistemas distribuidos.
Envía la misma carga útil a los tres agentes utilizando sus API expuestas /run
y fusiona los resultados. Vamos a añadir los siguientes archivos a la carpeta host_agent
.
Crear una agent.py
archivo
Empecemos con las importaciones básicas.
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
Este bloque de importación aporta todos los componentes básicos necesarios para definir y ejecutar un agente basado en LLM utilizando Google ADK: clase Agent
, envoltorio LLM ligero, Runner
para gestionar la ejecución y gestión de sesiones en memoria.
host_agent = Agent(
name="host_agent",
model=LiteLlm("openai/gpt-4o"),
description="Coordinates travel planning by calling flight, stay, and activity agents.",
instruction="You are the host agent responsible for orchestrating trip planning tasks. "
"You call external agents to gather flights, stays, and activities, then return a final result."
)
session_service = InMemorySessionService()
runner = Runner(
agent=host_agent,
app_name="host_app",
session_service=session_service
)
USER_ID = "user_host"
SESSION_ID = "session_host"
El código anterior define un agente ADK de nivel superior responsable de coordinar el plan de viaje completo. Aunque en esta implementación no invocamos subagentes del LLM, la indicación del sistema establece el papel para una futura ampliación en la que el LLM podría encargarse potencialmente del uso de herramientas y del meta-razonamiento.
async def execute(request):
# Ensure session exists
session_service.create_session(
app_name="host_app",
user_id=USER_ID,
session_id=SESSION_ID
)
prompt = (
f"Plan a trip to {request['destination']} from {request['start_date']} to {request['end_date']} "
f"within a total budget of {request['budget']}. Call the flights, stays, and activities agents for results."
)
message = types.Content(role="user", parts=[types.Part(text=prompt)])
async for event in runner.run_async(user_id=USER_ID, session_id=SESSION_ID, new_message=message):
if event.is_final_response():
return {"summary": event.content.parts[0].text}
Esta función execute()
sirve como punto de entrada principal al LLM del agente anfitrión. Ello:
- Inicializa una sesión (para soporte de memoria si es necesario)
- Construye dinámicamente una consulta de usuario
- Lo envía al modelo mediante runner.run_async( de ADK)
method
- Por último, espera y extrae la respuesta final
Crear una task_manager.py
archivo
El gestor de tareas ejecuta la lógica de orquestación llamando a agentes remotos y gestionando todo el flujo de trabajo de planificación del viaje. Para su aplicación práctica, definimos las URL de servicio para cada agente hijo. Estos puntos finales se ajustan al esquema JSON A2A /run protocol and expect a shared
TravelRequest`.
from common.a2a_client import call_agent
FLIGHT_URL = "http://localhost:8001/run"
STAY_URL = "http://localhost:8002/run"
ACTIVITIES_URL = "http://localhost:8003/run"
Ahora definimos la carga útil.
async def run(payload):
#Print what the host agent is sending
print("Incoming payload:", payload)
flights = await call_agent(FLIGHT_URL, payload)
stay = await call_agent(STAY_URL, payload)
activities = await call_agent(ACTIVITIES_URL, payload)
# Log outputs
print("flights:", flights)
print("stay:", stay)
print("activities:", activities)
# Ensure all are dicts before access
flights = flights if isinstance(flights, dict) else {}
stay = stay if isinstance(stay, dict) else {}
activities = activities if isinstance(activities, dict) else {}
return {
"flights": flights.get("flights", "No flights returned."),
"stay": stay.get("stays", "No stay options returned."),
"activities": activities.get("activities", "No activities found.")
}
Esta función utiliza la función de ayuda call_agent()
para enviar la carga útil a cada servicio descendente y registra las entradas y salidas para que sean visibles durante el desarrollo. Este archivo es esencialmente donde vive la verdadera lógica de orquestación.
Crear una __main__.py
archivo
El archivo __main__.py
sirve como punto de entrada para el servidor FastAPI que envuelve al agente anfitrión.
from common.a2a_server import create_app
from .task_manager import run
app = create_app(agent=type("Agent", (), {"execute": run}))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, port=8000)
El archivo principal hace lo siguiente:
- Utiliza
create_app()
decommon/a2a_server.py
para generar una aplicación FastAPI con un punto final estandarizado/run
. - A continuación, pasa un objeto simple similar a un agente con un método
execute()
que delega internamente en la funcióntask_manager.run()
. - Por último, inicia el servidor FastAPI utilizando
uvicorn
en un puerto especificado (normalmente 8000).
Esto alinea la interfaz del agente anfitrión con otros agentes posteriores, manteniendo la coherencia en todo el sistema.
Crear una .well-known/agent.json
archivo
Este archivo actúa como un patrón multiagente clásico en el que un nodo central delega y compone tareas.
{
"name": "host_agent",
"description": "Coordinates travel planning among specialized agents."
}
Aunque es opcional, es una buena práctica incluirlo en todos los directorios de agentes, como se ha explicado anteriormente.
Paso 5: Construir la interfaz de usuario con Streamlit
Por último, creemos una aplicación sencilla en la que los usuarios puedan introducir sus preferencias y recibir un itinerario estructurado. Empieza creando un archivo travel_ui.py
en el directorio raíz y añádele el siguiente código.
import streamlit as st
import requests
Importamos bibliotecas básicas como Streamlit y solicitudes de apoyo a la interfaz de usuario.
st.set_page_config(page_title="ADK-Powered Travel Planner", page_icon="✈️")
st.title("🌍 ADK-Powered Travel Planner")
origin = st.text_input("Where are you flying from?", placeholder="e.g., New York")
destination = st.text_input("Destination", placeholder="e.g., Paris")
start_date = st.date_input("Start Date")
end_date = st.date_input("End Date")
budget = st.number_input("Budget (in USD)", min_value=100, step=50)
if st.button("Plan My Trip ✨"):
if not all([origin, destination, start_date, end_date, budget]):
st.warning("Please fill in all the details.")
else:
payload = {
"origin": origin,
"destination": destination,
"start_date": str(start_date),
"end_date": str(end_date),
"budget": budget
}
response = requests.post("http://localhost:8000/run", json=payload)
if response.ok:
data = response.json()
st.subheader("✈️ Flights")
st.markdown(data["flights"])
st.subheader("🏨 Stays")
st.markdown(data["stay"])
st.subheader("🗺️ Activities")
st.markdown(data["activities"])
else:
st.error("Failed to fetch travel plan. Please try again.")
La aplicación Streamlit proporciona una interfaz de usuario fácil de usar para interactuar con el planificador de viajes multiagente creado con ADK. He aquí algunas cosas que tocamos en el código anterior.
- Utiliza
text_input
,date_input
, ynumber_input
para recoger origen, destino, fechas y presupuesto. - Al hacer clic en "Planificar mi viaje", valida la entrada para asegurarse de que no queda ningún campo en blanco.
- Si es válido, construye una carga útil JSON y envía una solicitud POST a la dirección
host_agent
enhttp://localhost:8000/run.
- El
host_agent
invoca a todos los agentes hijos (vuelo, estancia, actividad), agrega sus respuestas y devuelve un plan de viaje unificado. - La respuesta se analiza y se muestra utilizando el método
st.markdown()
en cabeceras separadas para vuelos, estancias y actividades. - Si falla el backend, se mostrará un mensaje de error alternativo utilizando
st.error()
.
Ahora, ejecuta el siguiente comando en tu terminal local:
uvicorn agents.host_agent.__main__:app --port 8000 &
uvicorn agents.flight_agent.__main__:app --port 8001 &
uvicorn agents.stay_agent.__main__:app --port 8002 &
uvicorn agents.activities_agent.__main__:app --port 8003 &
streamlit run travel_ui.py
Cuando un usuario hace clic en "Planificar mi viaje", el agente anfitrión toma el control, activa los agentes y muestra los resultados en la interfaz de usuario:
Tu estructura general de archivos sería algo así:
ADK_demo/
├── agents/
│ ├── host_agent/
│ │ ├── agent.py
│ │ ├── task_manager.py
│ │ ├── __main__.py
│ │ └── .well-known/
│ │ └── agent.json
│ │
│ ├── flight_agent/
│ │ ├── agent.py
│ │ ├── task_manager.py
│ │ ├── __main__.py
│ │ └── .well-known/
│ │ └── agent.json
│ │
│ ├── stay_agent/
│ │ ├── agent.py
│ │ ├── task_manager.py
│ │ ├── __main__.py
│ │ └── .well-known/
│ │ └── agent.json
│ │
│ └── activities_agent/
│ ├── agent.py
│ ├── task_manager.py
│ ├── __main__.py
│ └── .well-known/
│ └── agent.json
│
├── common/
│ ├── a2a_client.py # Utility to send requests to other agents
│ └── a2a_server.py # Shared FastAPI A2A-compatible server template
│
├── shared/
│ └── schemas.py # Shared Pydantic schema
│
├── streamlit_app.py # Frontend UI for user input and response rendering
├── requirements.txt
└── README.md
Y ya está. He reunido todo lo que hemos construido en este proyecto GitHub.
Conclusión
Con sólo unas pocas aplicaciones FastAPI y agentes ADK, hemos construido un planificador de viajes colaborativo que:
- Se comunica mediante el protocolo A2A
- Utiliza agentes LLM para vuelos, estancias y actividades
- Agrega y muestra los resultados en una limpia interfaz de usuario Streamlit
Aunque todos los agentes utilizan el mismo modelo bajo el capó, este sistema tiene un comportamiento multiagente, es decir, los agentes tienen funciones distintas, responsabilidades aisladas y una comunicación estructurada.
Aquí tienes algunos recursos para empezar:

Soy una Google Developers Expert en ML(Gen AI), una Kaggle 3x Expert y una Women Techmakers Ambassador con más de 3 años de experiencia en tecnología. Cofundé una startup de tecnología sanitaria en 2020 y estoy cursando un máster en informática en Georgia Tech, especializándome en aprendizaje automático.
Aprende IA con estos cursos
Curso
Developing AI Systems with the OpenAI API
Curso
Retrieval Augmented Generation (RAG) with LangChain

blog
Cinco proyectos que puedes crear con modelos de IA generativa (con ejemplos)

blog
7 proyectos de IA para todos los niveles

Tutorial
Tutorial de la API de OpenAI Assistants
Tutorial
Construir agentes LangChain para automatizar tareas en Python
Tutorial
Guía para principiantes sobre la ingeniería de avisos ChatGPT

Tutorial