IA generativa geoespacial con Amazon Bedrock y Amazon Location Service

Hoy en día, los flujos de trabajo geoespaciales suelen consistir en cargar datos, transformarlos y luego producir información visual como mapas, texto o gráficos. La IA generativa puede automatizar estas tareas a través de sistemas autónomos. agentes. En esta publicación, analizamos cómo utilizar los modelos de cimentación de Roca Amazónica para impulsar a los agentes a completar tareas geoespaciales. Estos agentes pueden realizar diversas tareas y responder preguntas utilizando servicios basados ​​en la ubicación, como la codificación geográfica, disponibles a través de Servicio de localización de Amazon. También compartimos un código de muestra que utiliza un agente para unir las capacidades de Amazon Bedrock con Amazon Location. Además, analizamos las consideraciones de diseño que se tuvieron en cuenta para construirlo.

Amazon Bedrock es un servicio totalmente administrado que ofrece una API fácil de usar para acceder a modelos básicos para texto, imágenes e incrustaciones. Amazon Location ofrece una API para mapas, lugares y rutas con datos proporcionados por terceros confiables como Esri, HERE, Grab y OpenStreetMap. Si necesita control total de su infraestructura, puede utilizar Inicio rápido de Amazon SageMakerque le brinda la capacidad de implementar modelos básicos y tiene acceso a cientos de modelos.

Descripción general de la solución

En el ámbito de los grandes modelos de lenguaje (LLM), un agente es una entidad que puede razonar y completar tareas de forma autónoma con la ayuda de un LLM. Esto permite a los LLM ir más allá de la generación de texto para llevar a cabo conversaciones y completar tareas de dominios específicos. Para guiar este comportamiento, empleamos patrones de razonamiento. Según el trabajo de investigación Los modelos de lenguaje grandes son razonadores de tiro cerolos LLM sobresalen en razonamiento de alto nivel, a pesar de tener un límite de conocimientos.

Seleccionamos claudio 2 como nuestro modelo fundacional de Amazon Bedrock con el objetivo de crear un agente geoespacial capaz de manejar tareas geoespaciales. El concepto general era sencillo: pensar como un científico de datos geoespaciales. La tarea implicó escribir código Python para leer datos, transformarlos y luego visualizarlos en un mapa interesante. Utilizamos un patrón de incitación conocido como Indicaciones para planificar y resolver para este propósito.

El uso de una estrategia de Planificar y Resolver permite un razonamiento de varios pasos y desarrollar un plan de alto nivel como primera tarea. Esto funciona bien para nuestro flujo de trabajo de carga, transformación y visualización, y es el plan de alto nivel que utilizará nuestro agente. Cada una de estas subtareas se envía a Claude 2 para que las resuelva por separado.

Ideamos una tarea de ejemplo para crear un mapa de calor de precios de Anuncios de Airbnb en Nueva York. Para planificar una ruta para completar la tarea, el agente debe comprender el conjunto de datos. El agente necesita conocer las columnas del conjunto de datos y el tipo de datos en esas columnas. Generamos un resumen del conjunto de datos para que el agente pueda planificar la tarea proporcionada por el usuario, en este caso, generando un mapa de calor.

Requisitos previos

Hay algunos requisitos previos para implementar la demostración. Necesitará acceso a una cuenta de AWS con una llave de acceso o Gestión de acceso e identidad de AWS (SOY) role con permisos para Amazon Bedrock y Amazon Location. Necesitará crear un mapaa índice de lugaresy un Clave API de ubicación de Amazon utilizando la consola de ubicación de Amazon. También necesitará acceso a un entorno local o virtual donde esté instalado Docker. En nuestra demostración utilizamos un Nube informática elástica de Amazon Instancia (Amazon EC2) que ejecuta Amazon Linux con Docker instalado.

Leer y resumir los datos.

Para brindarle al agente contexto sobre el conjunto de datos, le solicitamos a Claude 2 que escriba código Python que lea los datos y proporcione un resumen relevante para nuestra tarea. Las siguientes son algunas de las indicaciones que incluimos. La lista completa está disponible en el prompts.py archivo en el proyecto.

Your Role: You are a geospatial data analyzer designed to analyze data schema from arbitrary geospatial datasets.
Your Task: You are provided a set of file URLs. You need to generate a Python function that meets the following:
    Read each file using geopandas. Each file could be CSV, shape file, or GeoJSON.
    Use built-in function resolved_file_url= get_data_file_url(file_url, session_id) to get downloadable URLs.

A partir de estas indicaciones, Claude 2 generó el siguiente código Python:

import geopandas as gpd
import pandas as pd
import numpy as np
 
def analyze_geospatial_data(file_urls):
    dataframes = []
    for file_url in file_urls:
        resolved_file_url = get_data_file_url(file_url, 'a5b188fe-91f7-4f92-92fe-c4030721a427', 'local')
        if file_url.endswith('.csv'):
            df = pd.read_csv(resolved_file_url)
        elif file_url.endswith('.shp'):
            df = gpd.read_file(resolved_file_url)
        elif file_url.endswith('.parquet'):
            df = pd.read_parquet(resolved_file_url)
        elif file_url.endswith('.geojson'):
            df = gpd.read_file(resolved_file_url)
        else:
            raise ValueError('Unsupported file format')
 
        df = df.sample(n=3, random_state=42)
        dataframes.append({
            'file_url': file_url, 
            'resolved_file_url': resolved_file_url,
            'data_frame': df,
            'column_names': list(df.columns)
        })
    return dataframes
 
file_urls = ['agent://airbnb_listings_price.csv']
dataframes = analyze_geospatial_data(file_urls)

El agent:// El prefijo le dice a nuestra CLI que este archivo está almacenado dentro de la carpeta de almacenamiento de la sesión. Al ejecutar la CLI, creará una carpeta de almacenamiento de sesiones de agente geoespacial para almacenar datos locales. El agente ahora reconoce los datos cargados de Airbnb y los nombres de sus columnas. A continuación, pidámosle a Claude algunos consejos para generar un mapa de calor usando estas columnas. Pasaremos las siguientes indicaciones.

Your Role: You are a geospatial data analyzer designed to analyze data schema from arbitrary geospatial data sets.
Your Task: You are provided with a table with some rows data. Your task is to generate a summary that describes the data in the table following the requirements below.
    The first sentence should be summary of the data in the table from the aspect of the user action.
    If there is no geometry column in the table, the second sentence should note column names that can be used to generate a geometry column in geopandas.

Claude 2 responde con una pista.

Summary: The table contains columns for listing id, name, host id, host name, location details like neighborhood, latitude, and longitude that can be used to generate a geometry column for plotting. Price column contains listing price that can be used to generate a heatmap of listing prices.

Planificar una solución

Ahora podemos pedirle a Claude 2 que redacte un plan de alto nivel. Podemos usar una biblioteca de gráficos para Python llamada RedX para trazar los pasos para resolver nuestro problema.

De manera similar a nuestro último mensaje, pasamos algunos requisitos para guiar a Claude 2:

Your Role: You are a geospatial data scientist and an expert Python developer.
Your Task: A series of consecutive steps.
Your Reply needs to meet these requirements:
    Create a single NetworkX graph.
    No disconnected components allowed.
    First operations are data loading.
    Use geopandas for spatial data.

A partir de estas indicaciones, Claude 2 generó el siguiente código Python:

import networkx as nx
G = nx.DiGraph()
# Load the data
G.add_node("airbnb_data_url", node_type="data", data_path="agent://airbnb_listings_price.csv", 
           description="URL for Airbnb listing price data")
G.add_node("load_data", node_type="operation", operation_type="load",
           description="Load the Airbnb listing price data")
G.add_edge("airbnb_data_url", "load_data")
G.add_node("airbnb_df", node_type="data", 
           description="Pandas DataFrame containing Airbnb listing prices")
G.add_edge("load_data", "airbnb_df")
# Transform the data
G.add_node("add_geometry", node_type="operation", operation_type="transform",
           description="Create a geometry column using latitude and longitude")
G.add_edge("airbnb_df", "add_geometry")
G.add_node("airbnb_gdf", node_type="data",
           description="GeoDataFrame with geometry column added")
G.add_edge("add_geometry", "airbnb_gdf")
# Visualize the data
G.add_node("plot_heatmap", node_type="operation", operation_type="visualization",
           description="Generate a heatmap of listing prices")
G.add_edge("airbnb_gdf", "plot_heatmap")
G.add_node("price_heatmap", node_type="data", 
           description="The heatmap plot showing Airbnb listing prices")
G.add_edge("plot_heatmap", "price_heatmap")

En este gráfico de NetworkX, Claude 2 divide el proceso en tres segmentos principales:

  • Cargando datos – Importar los precios de listado de Airbnb desde una URL determinada a un Pandas DataFrame
  • Transformando datos – Crear una columna de geometría basada en las coordenadas de latitud y longitud.
  • Visualizando datos – Generar un mapa de calor para mostrar los precios de los listados de Airbnb

Este enfoque permite una implementación clara y directa de la tarea geoespacial en cuestión. Podemos usar GraphViz para visualizar el siguiente flujo de trabajo.

implementar el plan

Ahora que Claude 2 nos ha proporcionado un plan, es hora de darle vida. Para cada paso, le pedimos a Claude 2 que escriba el código correspondiente. Para mantener a Claude 2 enfocado, proporcionamos requisitos de alto nivel para cada tarea. Profundicemos en el código que Claude 2 generó para cada fase individual.

Cargar los datos

Para cargar los datos de precios de listado de Airbnb en un Pandas DataFrame, creamos un mensaje y pasamos algunos parámetros. “Cargar datos de Airbnb” en Operation_task hace referencia al nodo Cargar datos en nuestro gráfico que creamos anteriormente.

Your Role: You are a geospatial data scientist and an expert Python developer.
Operation_task: You need to generate a Python function to do: Load Airbnb data.
Your Reply needs to meet these requirements:
    The function definition is: 
    load_data(airbnb_data_url="agent://airbnb_listings_price.csv").
    When doing spatial joins, retain at least 1 geometry column.
    Point function requires importing shapely library.

A partir de estas indicaciones, Claude 2 generó el siguiente código Python:

import pandas as pd
def load_data(airbnb_data_url="agent://airbnb_listings_price.csv"):
    """
    Load Airbnb listing price data
    """
    file_url = get_data_file_url(airbnb_data_url, session_id, storage_mode) 
    airbnb_df = pd.read_csv(file_url)
    return airbnb_df

Transformar los datos

A continuación, Claude 2 genera el código para agregar un geometry columna a nuestro DataFrame usando latitude y longitude. Para este mensaje, pasamos los siguientes requisitos:

Your Role: You are a geospatial data scientist and an expert Python developer.
Operation_task: You need to generate a Python function to do: 
    Add geometry column from latitude/longitude.
    Your Reply needs to meet these requirements:
    The function definition is: add_geometry(filtered_df).
    The function return line is: return airbnb_gdf.

A partir de estas indicaciones, Claude 2 generó el siguiente código Python:

import geopandas as gpd
from shapely.geometry import Point
def add_geometry(airbnb_df):
    """
    Add geometry column from latitude and longitude
    """
    airbnb_df['geometry'] = airbnb_df.apply(lambda row: Point(row['longitude'], row['latitude']), axis=1)
    airbnb_gdf = gpd.GeoDataFrame(airbnb_df, geometry='geometry')
 
    return airbnb_gdf

Visualiza los datos

Finalmente, Claude 2 crea una visualización de mapa de calor usando pydeck, que es una biblioteca de Python para representación espacial. Para este mensaje, pasamos los siguientes requisitos:

Your Role: You are a geospatial data scientist and an expert Python developer.
Operation_task: You need to generate a Python function to do: Generate heatmap from price.
Your Reply needs to meet these requirements:
    The function definition is: generate_heatmap(airbnb_gdf).
    The function return line is: return airbnb_heatmap.

A partir de estas indicaciones, Claude 2 generó el siguiente código Python:

import pandas as pd
import geopandas as gpd
import pydeck as pdk
 
def plot_heatmap(airbnb_gdf):
    """
    Plot heatmap of listing prices
    """
    price_heatmap = pdk.Deck(
        map_style=location_map_style(),
        initial_view_state=pdk.ViewState(
            latitude=airbnb_gdf['latitude'].mean(),
            longitude=airbnb_gdf['longitude'].mean(),
            zoom=11,
            pitch=50,
        ),
        layers=[
            pdk.Layer(
                'HexagonLayer',
                data=airbnb_gdf,
                get_position=['longitude', 'latitude'],
                radius=100,
                elevation_scale=4,
                elevation_range=[0, 1000],
                pickable=True,
                extruded=True,
            ),
            pdk.Layer(
                'ScatterplotLayer',
                data=airbnb_gdf,
                get_position=['longitude', 'latitude'],
                get_color="[200, 30, 0, 160]",
                get_radius=200,
            ),
        ],
    )
 
    # Save heatmap HTML
    price_heatmap.to_html(get_local_file_path('airbnb_heatmap.html', session_id, task_name))
 
    return price_heatmap

Cuando Claude 2 devuelve una respuesta, también incluye algunas notas útiles que explican cómo cada función cumple con los requisitos proporcionados. Por ejemplo, para la visualización del mapa de calor, Claude 2 observó lo siguiente:

"This function generates a heatmap of Airbnb listing prices using pydeck and saves the resulting HTML locally. It fulfills the requirements specified in the prompt."

Ensamblar el código generado

Ahora que Claude 2 ha creado los bloques de construcción individuales, es hora de juntarlos todos. El agente reúne automáticamente todos estos fragmentos en un único archivo Python. Este script llama a cada una de nuestras funciones en secuencia, agilizando todo el proceso.

El paso final se parece al siguiente código:

session_id = "a5b188fe-91f7-4f92-92fe-c4030721a427"
task_name = "1694813661_airbnb_listings_price_heatmap"
storage_mode = "local"
# Sequentially invoke the functions
airbnb_df = load_data(airbnb_data_url="agent://airbnb_listings_price.csv")
airbnb_gdf = add_geometry(airbnb_df)
price_heatmap = plot_heatmap(airbnb_gdf)

Una vez completado el script, podemos ver que Claude 2 ha creado un archivo HTML con el código para visualizar nuestro mapa de calor. La siguiente imagen muestra Nueva York en un mapa base de ubicaciones de Amazon con un mapa de calor que visualiza los precios de listado de Airbnb.

Visualización del mapa de calor

Utilice la ubicación de Amazon con Amazon Bedrock

Aunque nuestro agente Planificar y resolver puede manejar esta tarea geoespacial, debemos adoptar un enfoque ligeramente diferente para tareas como geocodificar una dirección. Para ello podemos utilizar una estrategia llamada Reaccionardonde combinamos el razonamiento y la acción con nuestro LLM.

En el patrón ReAct, el agente razona y actúa basándose en la información del cliente y en la herramientas a su disposición. Para equipar a este agente impulsado por Claude 2 con la capacidad de geocodificar, desarrollamos una herramienta de geocodificación. Esta herramienta utiliza la API de Amazon Location Places, específicamente la SearchPlaceIndexForText método, para convertir una dirección en sus coordenadas geográficas.

Agent: Hi! I'm Agent Smith, your conversational geospatial assistant. How can I assist you today?
You: >? Hello, can you give me the coordinates for 112 E 11th St, Austin, TX 78701?
Agent: The coordinates for 112 E 11th St, Austin, TX 78701 are longitude -97.740590981087 and latitude 30.274118017533.

En este breve intercambio, el agente descifra su intención de geocodificar una dirección, activa la herramienta de geocodificación y devuelve la latitud y longitud.

Ya sea trazando un mapa de calor o codificando geográficamente una dirección, Claude 2 combinado con agentes como ReAct y Plan and Solve puede simplificar los flujos de trabajo geoespaciales.

Implementar la demostración

Para comenzar, complete los siguientes pasos:

  1. Clone el siguiente repositorio en su máquina local o en una instancia EC2. Es posible que necesites correr aws configure --profile <profilename> y establecer una Región predeterminada; esta aplicación fue probada usando us-east-1.
git clone https://github.com/aws-samples/amazon-location-geospatial-agent/

Ahora que tenemos el repositorio clonado, configuramos nuestras variables de entorno.

  1. Cambie los directorios a la carpeta del proyecto clonado:
cd amazon-location-geospatial-agent

  1. Editar el .env archivo usando su editor de texto preferido:
  1. Agregue el nombre de su mapa, el nombre del índice del lugar y la clave API:
API_KEY_NAME=AgentAPIKey
MAP_NAME=AgentMap
PLACE_INDEX_NAME=AgentPlaceIndex

  1. Ejecute el siguiente comando para construir su contenedor:
  1. Ejecute el siguiente comando para ejecutar y conectarse a su contenedor Docker:
docker run --rm -it -v ~/.aws:/root/.aws --entrypoint bash agent

  1. Tome el conjunto de datos de Airbnb:
apt install -y wget
wget http://data.insideairbnb.com/united-states/ny/new-york-city/2023-10-01/visualisations/listings.csv
cp listings.csv data/listings.csv

  1. Ejecute el siguiente comando para crear una sesión. Usamos sesiones para aislar entornos de chat únicos.
SESSION_ID="3c18d48c-9c9b-488f-8229-e2e8016fa851" FILE_NAME="listings.csv" make create-session

Ahora estás listo para iniciar la aplicación.

  1. Ejecute el siguiente comando para iniciar la aplicación de chat:
poetry run agent --session-id 3c18d48c-9c9b-488f-8229-e2e8016fa851 --profile <profilename>

Serás recibido con un mensaje de chat.

  1. Puedes comenzar haciendo la siguiente pregunta:
I've uploaded the file listings.csv. Draw a heatmap of Airbnb listing price.

El agente agarra el Airbnb_listings_price.csv archivo que hemos descargado en el /data carpeta y la analiza en un DataFrame geoespacial. Luego genera el código para transformar los datos así como el código para la visualización. Finalmente, crea un archivo HTML que se escribirá en el /data carpeta, que puede abrir para visualizar el mapa de calor en un navegador.

Otro ejemplo utiliza la API de Amazon Location Places para geocodificar una dirección. Si le pedimos al agente que geocodifique la dirección 112 E 11th St, Austin, TX 78701, obtendremos una respuesta como se muestra en la siguiente imagen.

Ejemplo de interacción

Conclusión

En esta publicación, brindamos una breve descripción general de Amazon Bedrock y Amazon Location, y cómo puede usarlos juntos para analizar y visualizar datos geoespaciales. También analizamos Plan-and-Solve y ReAct y cómo los usamos en nuestro agente.

Nuestro ejemplo sólo roza la superficie. Intente descargar nuestro código de muestra y agregue sus propios agentes y herramientas para sus tareas geoespaciales.


Sobre los autores

Jeff Demuth es un arquitecto de soluciones que se unió a Amazon Web Services (AWS) en 2016. Se enfoca en la comunidad geoespacial y le apasionan los sistemas de información geográfica (SIG) y la tecnología. Fuera del trabajo, a Jeff le gusta viajar, crear aplicaciones de Internet de las cosas (IoT) y jugar con los últimos dispositivos.

Swagata Prateek es un ingeniero de software senior que trabaja en Amazon Location Service en Amazon Web Services (AWS), donde se enfoca en IA generativa y geoespacial.