Cómo Construir un Agente con LangGraph y AWS CDK - Pt. 1

La creación de agentes ha cobrado gran relevancia durante estos últimos años. En esta serie de artículos aprenderás a construir uno utilizando LangGraph y AWS CDK. Iremos desde lo mas básico hasta ver temas como la gestión de memoria e integración con MCP’s (Model Context Protocol).
LangGraph
LangGraph es una herramienta versátil que permite crear y gestionar flujos de trabajo de procesamiento de lenguaje natural (NLP) utilizando grafos. Proporciona una API sencilla para implementar diferentes modelos de lenguaje y conectarlos de manera eficaz, permitiendo así la creación de agentes conversacionales y sistemas de recomendación. Puedes aprender más sobre LangGraph aquí.
AWS CDK
AWS Cloud Development Kit (CDK) es un framework que permite a los desarrolladores definir su infraestructura en la nube utilizando lenguajes de programación familiares, como TypeScript, Python y Java. AWS CDK hace que la provisión de recursos en AWS sea más accesible y modular. Si quieres saber más sobre AWS CDK, puedes dirigirte a su documentación oficial.
¿Que vamos a construir?
Vamos a avanzar paso a paso en la construcción de un agente inteligente que tendrá la capacidad de recibir la URL de cualquier artículo en línea. Este agente no solo generará un resumen del contenido del artículo, sino que también nos enviará dicho resumen directamente a nuestro correo electrónico. Además, el agente será lo suficientemente sofisticado para recordar y almacenar nuestras preferencias personales en cuanto al tono y la estructura del resumen que deseamos recibir. Por ejemplo, si preferimos un resumen más formal o uno más casual, o si queremos que el resumen sea conciso o detallado, el agente ajustará su salida en consecuencia. Esta funcionalidad personalizada garantizará que los resúmenes sean útiles y alineados con nuestras expectativas.
Requisitos Previos
Antes de empezar, asegúrate de tener instalado lo siguiente en tu máquina:
Node JS (versión 22.x o superior)
AWS CLI configurado con tus credenciales de AWS.
AWS CDK instalado globalmente:
npm install -g aws-cdk
Empezemos! 🚀
Estructura del Proyecto
Primero, iniciemos creando un nuevo proyecto de CDK:
mkdir article-summarizer-agent-cdk-langgraph && cd article-summarizer-agent-cdk-langgraph cdk init app --language=typescriptAhora, dentro de nuestro directorio del proyecto instalamos las dependencias que necesitaremos:
npm install @langchain/core @langchain/langgraph @langchain/openai dotenv esbuildInstalamos algunos tipos para usarlos dentro de nuestras lambdas:
npm install -D @types/aws-lambdaLa estructura del proyecto será la siguiente:
article-summarizer-agent-cdk-langgraph/ ├── bin │ └── article-summarizer-agent-cdk-langgraph.ts ├── lib │ ├── config │ └── article-summarizer-agent-cdk-langgraph-stack.ts ├── src │ ├── agent │ │ ├── agent.ts │ │ ├── instructions.ts │ │ └── tools │ └── handlers ├── cdk.json ├── package.json └── tsconfig.json
Desarrollo del Agente
Implementar lógica básica del agente
Vamos a empezar creando la lógica de nuestro agente, es decir, como recibirá el input y como nos dará la respuesta. Para ello agregaremos el siguiente código en el archivo src/agent/agent.ts:
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
export class Agent {
private agent: ReturnType<typeof createReactAgent>;
constructor(model: ChatOpenAI) {
this.agent = createReactAgent({
llm: model,
tools: [],
prompt: "",
});
}
async run(input: string): Promise<string> {
const response = await this.agent.invoke({
messages: [{ role: "user", content: input }],
});
return response.messages[response.messages.length - 1].content;
}
}
Para nuestro agente vamos a usar un modelo de OpenAI, pero si gustas puedes cambiarlo por el modelo de tu preferencia (esta es una de las grandes ventajas de LangGraph 🔥). Por ejemplo, para utilizar Anthropic primero debemos instalar el paquete @langchain/anthropic y luego modificar la clase Agent para que se vea así:
import { ChatAnthropic } from "@langchain/anthropic";
...
export class Agent {
private agent: ReturnType<typeof createReactAgent>;
constructor(model: ChatAnthropic) {
this.agent = createReactAgent({
llm: model,
tools: [],
prompt: "",
});
}
...
}
Puedes revisar la lista de modelos disponibles aquí.
Crear función Lambda para interactuar con el agente
Una vez tengamos la lógica básica de nuestro agente, el siguiente paso es definir una función Lambda que se encargará de procesar las solicitudes y respuestas desde una API implementada en API Gateway. Abre el archivo lib/article-summarizer-agent-cdk-langgraph-stack.ts y añade lo siguiente:
import { StackProps, Stack, Duration } from "aws-cdk-lib";
import { HttpApi, HttpMethod } from "aws-cdk-lib/aws-apigatewayv2";
import { HttpLambdaIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
import { Construct } from "constructs";
import { getConfig } from "./config";
export class ArticleSummarizerAgentCdkLanggraphStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const config = getConfig();
// Definimos la API para interactuar con el agente
const httpApi = new HttpApi(this, "ArticleSummarizerAgentApi", {
apiName: "article-summarizer-agent-api",
description: "API for Article Summarizer Agent",
});
// Definimos la función Lambda que ejecutará el agente
const agentExecutorLambdaFunction = new NodejsFunction(
this,
"AgentExecutorLambdaFunction",
{
functionName: "agent-executor-handler",
entry: "src/handlers/agent-executor/handler.ts",
handler: "handler",
memorySize: 1024,
timeout: Duration.seconds(30),
environment: {
OPENAI_API_KEY: config.OPENAI_API_KEY,
},
}
);
// Agregamos un endpoint POST /message a la API que invoca la función Lambda
httpApi.addRoutes({
path: "/message",
methods: [HttpMethod.POST],
integration: new HttpLambdaIntegration(
"AgentExecutorIntegration",
agentExecutorLambdaFunction
),
});
}
}
Llamar al agente desde nuestra lambda
Ahora, necesitamos llamar a nuestro agente desde la lambda que acabamos de agregar. Para ello creamos un nuevo directorio llamado agent-executor dentro de la carpeta handlers y agregamos un archivo llamado handler.ts con el siguiente código:
import { APIGatewayProxyEventV2, APIGatewayProxyResultV2 } from "aws-lambda";
import { Agent } from "../../agent/agent";
import { ChatOpenAI } from "@langchain/openai";
// Creamos una instancia del modelo de lenguaje
const openAiModel = new ChatOpenAI({
model: "gpt-4o-mini",
});
export const main = async (
event: APIGatewayProxyEventV2
): Promise<APIGatewayProxyResultV2> => {
// Extraemos el mensaje del cuerpo de la solicitud
// Si no hay cuerpo, usamos un objeto vacío
// El mensaje se encuentra en la propiedad "message"
const body = JSON.parse(event.body || "{}") as { message?: string };
// Creamos una instancia del agente
const agent = new Agent(openAiModel);
// Ejecutamos el agente con el mensaje recibido
const responseFromAgent = await agent.run(body.message || "");
// Devolvemos la respuesta del agente en el cuerpo de la respuesta HTTP
return {
statusCode: 200,
body: JSON.stringify({
message: responseFromAgent,
}),
};
};
export const handler = main;
Agregar variables de entorno
Antes de desplegar nuestro proyecto debemos configurar algunas variables de entorno para poder usar nuestro modelo de OpenAI. Para ello agregamos un nuevo directorio llamado config dentro de la carpeta lib y agregamos un archivo index.ts con el siguiente contenido:
import * as dotenv from "dotenv";
dotenv.config();
export type Config = {
OPENAI_API_KEY: string;
};
export const getConfig = (): Config => {
return {
OPENAI_API_KEY: process.env.OPENAI_API_KEY!,
};
};
Creamos un archivo .env dentro del directorio raiz y agregamos la variable OPENAI_API_KEY
OPENAI_API_KEY=<your_open_ai_key>
Desplegar el proyecto y probar
Una vez que tengamos todos estos componentes ya estamos listos para desplegar nuestro proyecto y probarlo para ver como funciona. Para ello nos vamos a nuestra terminal y ejecutamos el siguiente comando
cdk deploy --profile <your_aws_profile>
cdk bootstrap —profile <your_aws_profile> donde your_aws_profile debe ser reemplazado por el perfil que hayas configurado para utilizar aws cliSi nos aparece un mensaje similar a este: Do you wish to deploy these changes (y/n)? simplemente escribimos la letra “y” y presionamos Enter.
Cuando veamos algo similar a esto en nuestra terminal, significa que nuestro proyecto a sido desplegado con éxito 🔥🚀.

Para probar nuestro agente debemos dirigirnos a la consola de AWS y buscar el servicio de API Gateway, ahi encontraremos nuestra API llamada article-summarizer-agent-api, le damos clic y en los detalles encontraremos la url que debemos llamar dentro de la opcion Invoke URL (URL de invocación).

Con esto ya podremos ir a Postman o hacer una petición desde nuestra terminal hacia el endpoint /message y ver que nos responde nuestro agente.
curl -X POST https://<invoke_url>/message \
-H "Content-Type: application/json" \
-d '{"message": "Hola como estas?"}'
🎯 En el próximo artículo veremos cómo ampliar nuestro agente añadiendo instrucciones personalizadas sobre su funcionamiento. Le daremos nuevas herramientas (tools) y una memoria para almacenar las preferencias de los usuarios sobre cómo quieren sus resúmenes.
📰 Si no quieres perderte la continuación, puedes suscribirte a la newsletter aquí.


