使用Amazon Bedrock和Amazon Location Service的地理生成人工智能

利用Amazon Bedrock和Amazon Location Service创造智能地理生成人工智能

今天,地理空间工作流通常包括加载数据,转换数据,然后生成地图、文本或图表等可视化洞见。生成式人工智能可以通过自主的代理自动化这些任务。在本文中,我们讨论如何使用Amazon Bedrock的基础模型来为代理提供能力以完成地理空间任务。这些代理可以使用像地理编码这样的基于位置的服务来执行各种任务并回答问题,这些服务可以通过Amazon Location Service获得。我们还分享了使用代理将Amazon Bedrock的功能与Amazon Location的能力结合起来的示例代码。此外,我们还讨论了构建它所涉及的设计考虑。

Amazon Bedrock是一个完全托管的服务,提供易于使用的API,用于访问文本、图像和嵌入式的基础模型。Amazon Location提供了地图、地点和路由的API,这些数据由Esri、HERE、Grab和OpenStreetMap等可信第三方提供。如果你需要对基础设施有完全控制,你可以使用Amazon SageMaker JumpStart,它可以让你部署基础模型并访问数百个模型。

解决方案概述

在大型语言模型(LLMs)领域中,代理是一个可以自主推理和完成任务的实体,它们借助LLMs的帮助。这让LLMs能够超越文本生成,进行对话和完成领域特定任务。为了引导这种行为,我们采用推理模式。根据研究论文大型语言模型是零次推理者,尽管具有知识截断,LLMs在高层次推理方面表现出色。

我们选择了Claude 2作为我们从Amazon Bedrock选择的基础模型,旨在创建一个能够处理地理空间任务的地理空间代理。总体概念很简单:像地理空间数据科学家一样思考。该任务涉及编写Python代码来读取数据、转换数据,然后在一个有趣的地图上可视化数据。我们使用了一种称为Plan-and-Solve Prompting的提示模式来实现这个目的。

使用Plan-and-Solve策略允许进行多步推理,并作为第一个任务开发一个高层级计划。这对于我们的加载、转换和可视化工作流非常有效,并且是我们的代理将使用的高层级计划。这些子任务中的每一个都会分别发送给Claude 2来解决。

我们设计了一个示例任务,创建一个纽约Airbnb房源价格热力图。为了规划完成任务的路径,代理需要了解数据集。代理需要了解数据集中的列以及这些列中的数据类型。我们从数据集中生成一个摘要,以便代理能够规划用户提供的任务,即生成热力图。

先决条件

部署演示需要一些先决条件。你需要拥有一个带有访问密钥AWS身份和访问管理(IAM)角色和对Amazon Bedrock和Amazon Location的权限的AWS账户访问。你需要使用Amazon Location控制台创建一个地图、一个地点索引和一个Amazon Location API密钥。你还需要访问一个安装了Docker的本地或虚拟环境。在我们的演示中,我们使用一个在安装了Docker的Amazon Linux上运行的Amazon Elastic Compute Cloud(Amazon EC2)实例。

读取和总结数据

为了提供数据集的背景信息,我们要求Claude 2编写Python代码来读取数据并提供与我们的任务相关的摘要。以下是我们包含的一些提示。完整列表可在项目中的prompts.py文件中找到。

你的角色:你是一个地理空间数据分析师,专门分析任意地理空间数据集的数据模式。
你的任务:你会提供一组文件URL。你需要生成一个符合以下要求的Python函数:
    使用geopandas读取每个文件。每个文件可以是CSV、shape文件或GeoJSON。
    使用内置函数resolved_file_url= get_data_file_url(file_url, session_id)来获取可下载的URL。

基于这些提示,Claude 2生成了以下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('不支持的文件格式')
        
        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)

前缀agent://告诉我们的CLI这个文件存储在会话存储文件夹中。运行CLI时,它将创建一个geospatial-agent-session-storage文件夹以存储本地数据。代理现在识别上传的Airbnb数据及其列名。接下来,让我们向Claude询问一些提示,以使用这些列生成热图。我们将传入以下提示。

你的角色:你是一个地理空间数据分析师,专门分析任意地理空间数据集的数据模式。
你的任务:你会提供一个带有一些行数据的表格。你的任务是生成一个描述表格中数据的摘要,遵循以下要求。
    第一句话应该是从用户行动的角度对表格中的数据进行摘要。
    如果表格中没有几何列,第二句话应该指出可以用于在geopandas中生成几何列的列名。

Claude回复了一个提示

摘要:该表格包含用于房源id、名称、房东id、房东姓名以及地理位置详细信息(如街区、纬度和经度)的列,可以用于生成一个用于绘制图形的几何列。价格列包含可用于生成房源价格热图的房源价格。

计划解决方案

现在我们可以要求Claude 2起草一个高层次的计划。我们可以使用Python中的一个名为NetworkX的图形库来规划解决问题的步骤。

与上一个提示类似,我们传入一些要求来指导Claude 2:

你的角色:你是一个地理空间数据科学家和熟练的Python开发人员。
你的任务:一系列连续的步骤。
你的回复需满足以下要求:
    创建一个单个的NetworkX图。
    不允许有未连接的组件。
    第一个操作是数据加载。
    使用geopandas处理空间数据。

基于这些提示,Claude 2生成了以下Python代码:

import networkx as nx

G = nx.DiGraph()

# 加载数据
G.add_node("airbnb_data_url", node_type="data", data_path="agent://airbnb_listings_price.csv",
            description="Airbnb房源价格数据的URL")
G.add_node("load_data", node_type="operation", operation_type="load",
           description="加载Airbnb房源价格数据")
G.add_edge("airbnb_data_url", "load_data")

G.add_node("airbnb_df", node_type="data",
            description="包含Airbnb房源价格的Pandas DataFrame")
G.add_edge("load_data", "airbnb_df")

# 转换数据
G.add_node("add_geometry", node_type="operation", operation_type="transform",
           description="使用纬度和经度创建几何列")
G.add_edge("airbnb_df", "add_geometry")

G.add_node("airbnb_gdf", node_type="data",
           description="添加了几何列的GeoDataFrame")
G.add_edge("add_geometry", "airbnb_gdf")

# 可视化数据
G.add_node("plot_heatmap", node_type="operation", operation_type="visualization",
           description="生成房源价格热图")
G.add_edge("airbnb_gdf", "plot_heatmap")

G.add_node("price_heatmap", node_type="data",
            description="显示Airbnb房源价格的热图")
G.add_edge("plot_heatmap", "price_heatmap")

在这个NetworkX图中,Claude 2将过程分解为三个主要部分:

  • 加载数据 – 从给定URL导入Airbnb的房源价格到Pandas DataFrame中
  • 转换数据 – 根据纬度和经度坐标创建一个几何字段
  • 可视化数据 – 生成热图以显示Airbnb房源的定价

这种方法可以清晰而直接地实现手头的地理空间任务。我们可以使用GraphViz来可视化以下工作流程。

Graph

实施计划

既然Claude 2提供了一个计划,现在是时候将其付诸实践了。对于每个步骤,我们提示Claude 2编写相应的代码。为了让Claude 2专注,我们为每个任务提供高级要求。让我们深入了解Claude 2为每个单独阶段生成的代码。

加载数据

为了将Airbnb房源价格数据加载到Pandas DataFrame中,我们创建一个提示并传入一些参数。”Operation_task”中的”Load Airbnb data”是指我们之前创建的图中的”Load Data”节点。

您的角色:您是一个地理空间数据科学家和专业的Python开发人员。Operation_task:您需要生成一个Python函数来执行:加载Airbnb数据。您的回复需要满足以下要求:    函数定义为:    load_data(airbnb_data_url='agent://airbnb_listings_price.csv')。    在进行空间连接时,至少保留一个几何字段。    Point函数需要导入shapely库。

根据这些提示,Claude 2生成了以下Python代码:

import pandas as pddef load_data(airbnb_data_url='agent://airbnb_listings_price.csv'):    """    加载Airbnb房源价格数据    """    file_url = get_data_file_url(airbnb_data_url, session_id, storage_mode)     airbnb_df = pd.read_csv(file_url)    return airbnb_df

转换数据

接下来,Claude 2生成了使用纬度和经度将一个geometry列添加到我们的DataFrame中的代码。对于这个提示,我们传入以下要求:

您的角色:您是一个地理空间数据科学家和专业的Python开发人员。Operation_task:您需要生成一个Python函数来执行:从纬度/经度添加几何列。您的回复需要满足以下要求:    函数定义为:add_geometry(filtered_df)。    函数返回行为:return airbnb_gdf。

根据这些提示,Claude 2生成了以下Python代码:

import geopandas as gpdfrom shapely.geometry import Pointdef add_geometry(airbnb_df):    """    从纬度和经度添加几何列    """    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

可视化数据

最后,Claude 2使用pydeck构建热图可视化,这是一个用于空间渲染的Python库。对于这个提示,我们传入以下要求:

您的角色:您是一个地理空间数据科学家和专业的Python开发人员。Operation_task:您需要生成一个Python函数来执行:生成价格热图。您的回复需要满足以下要求:    函数定义为:generate_heatmap(airbnb_gdf)。    函数返回行为:return airbnb_heatmap。

根据这些提示,Claude 2生成了以下Python代码:

import pandas as pdimport geopandas as gpdimport pydeck as pdk def plot_heatmap(airbnb_gdf):    """    绘制房源价格热图    """    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,            ),        ],    )     # 保存热图HTML    price_heatmap.to_html(get_local_file_path('airbnb_heatmap.html', session_id, task_name))     return price_heatmap

当Claude 2返回响应时,它还包括一些有助于说明每个函数如何满足所提供要求的说明。例如,对于热力图可视化,Claude 2指出了以下内容:

"该函数使用pydeck生成Airbnb列表价格的热力图,并将结果保存为本地HTML。它满足了提示中指定的要求。"

组装生成的代码

现在,Claude 2已经创建了各个构建模块,是时候把它们放在一起了。该代理自动将所有这些代码片段组装成一个单独的Python文件。该脚本按顺序调用我们的每个函数,简化了整个过程。

最后一步的代码如下:

session_id = "a5b188fe-91f7-4f92-92fe-c4030721a427"task_name = "1694813661_airbnb_listings_price_heatmap"storage_mode = "local"# 按顺序调用函数airbnb_df = load_data(airbnb_data_url='agent://airbnb_listings_price.csv')airbnb_gdf = add_geometry(airbnb_df)price_heatmap = plot_heatmap(airbnb_gdf)

脚本完成后,我们可以看到Claude 2已经创建了一个包含可视化热力图代码的HTML文件。下面的图片显示了将纽约显示在亚马逊位置地图上,并使用热力图可视化Airbnb列表价格。

热力图可视化

使用亚马逊位置和亚马逊基岩

尽管我们的Plan-and-Solve代理可以处理这个地理空间任务,但对于地理编码地址等任务,我们需要采用稍微不同的方法。为此,我们可以使用一种名为ReAct的策略,在其中将推理、行动与LLM相结合。

在ReAct模式中,代理根据客户输入和其可用的工具进行推理和行动。为了使这个由Claude 2驱动的代理具备地理编码的能力,我们开发了一个地理编码工具。该工具使用亚马逊位置Places API,具体使用SearchPlaceIndexForText方法,将地址转换为其地理坐标。

Agent: 你好!我是Smith助手,您的对话式地理空间助手。我今天如何帮您?您: >? 嗨,你能给我112 E 11th St,Austin,TX 78701的坐标吗?代理: 112 E 11th St,Austin,TX 78701的经度为-97.740590981087,纬度为30.274118017533。

在这个简短的交流中,代理解析出您地理编码地址的意图,激活了地理编码工具,并返回了纬度和经度。

无论是绘制热力图还是地理编码地址,Claude 2与ReAct和Plan and Solve等代理结合使用,可以简化地理空间工作流程。

部署演示

要开始,请完成以下步骤:

  1. 将以下存储库克隆到本地机器或EC2实例上。您可能需要运行aws configure --profile <profilename>并设置默认区域;此应用程序已经在us-east-1上进行了测试。
git clone https://github.com/aws-samples/amazon-location-geospatial-agent/

现在我们已经克隆了存储库,我们来配置环境变量。

  1. 进入克隆的项目文件夹:
cd amazon-location-geospatial-agent
  1. 使用您喜欢的文本编辑器编辑.env文件:
vim .env
  1. 添加您的地图名称、地点索引名称和API密钥:
API_KEY_NAME=AgentAPIKeyMAP_NAME=AgentMapPLACE_INDEX_NAME=AgentPlaceIndex
  1. 运行以下命令构建容器:
docker build -t agent .
  1. 运行以下命令以运行并连接到您的Docker容器:
docker run --rm -it -v ~/.aws:/root/.aws --entrypoint bash agent
  1. 获取Airbnb数据集:
apt install -y wgetwget http://data.insideairbnb.com/united-states/ny/new-york-city/2023-10-01/visualisations/listings.csvcp listings.csv data/listings.csv
  1. 运行以下命令创建会话。我们使用会话来隔离唯一的聊天环境。
SESSION_ID="3c18d48c-9c9b-488f-8229-e2e8016fa851" FILE_NAME="listings.csv" make create-session

现在您已经准备好启动应用程序了。

  1. 运行以下命令开始聊天应用程序:
poetry run agent --session-id 3c18d48c-9c9b-488f-8229-e2e8016fa851 --profile <profilename>

您将受到聊天提示。

  1. 您可以从以下问题开始:
我已上传文件listings.csv。绘制Airbnb列表价格的热图。

代理程序会获取我们已下载到“/data”文件夹中的“Ai rbnb_listings_price.csv”文件,并将其解析为地理空间数据帧。然后,它会生成转换数据的代码以及可视化的代码。最后,它会创建一个HTML文件,该文件将被写入“/data”文件夹中,您可以在浏览器中打开以可视化热图。

另一个示例使用Amazon Location Places API对地址进行地理编码。如果我们要求代理对地址“112 E 11th St, Austin, TX 78701”进行地理编码,我们将获得以下图像中显示的响应。

Example Interaction

结论

在本文中,我们简要介绍了Amazon Bedrock和Amazon Location,以及如何将它们结合使用来分析和可视化地理空间数据。我们还介绍了Plan-and-Solve和ReAct,并展示了如何在我们的代理中使用它们。

我们的示例仅涉及表面。尝试下载我们的示例代码,并添加您自己的代理和工具,以完成您的地理空间任务。