生成 AI と ArcGIS の連携
近年 ChatGPT のような文章による指示でコンテンツを生成する AI が数多く登場しています。様々な企業が生成 AI のサービスを開発し、多くのユーザーがそれらを業務で活用しています。そんな生成 AI と ArcGIS の連携について過去の記事でも取り上げましたが、今回は Python と ArcPy を使って、ArcGIS Pro 上で生成 AI を利用できるようなスクリプト ツールを作成してみました。
ChatGPT と Azure OpenAI Service について
ChatGPT とは、OpenAI が開発した大規模言語モデル(Large Language Models 以下、LLM)を使って、人間と自然な会話をすることができる AI サービスです。ユーザーは、ChatGPT のサービスにアクセスし、文章の生成を体験することができます。また、過去の記事でも取り上げたように API を使用してサービスにアクセスし、AI による文章生成やデータ作成を体験することができます。 Azure OpenAI Service は、Microsoft と OpenAI が提携して提供するサービスで、API キーを取得することで LLM や画像生成のモデルを利用できます。 今回は、この Azure OpenAI Service を使って、最新の GPT である GPT-4o mini を利用します。なお、Azure OpenAI Service での生成 AI サービスのデプロイについては省略させていただきます。デプロイの詳細については、こちらのリファレンスを参照してください。
ArcGIS Pro で GPT-4o mini に質問するスクリプト ツールの作成
ArcGIS Pro では、Python のライブラリである ArcPy を使って、地理空間データの操作や分析を自動化することができ、スクリプト ツールという形で、カスタムのジオプロセシングツールも作成できます。スクリプト ツールでは、パラメーターを入力して、独自の Python スクリプトを実行することができます。 この ArcPy を使って、API キーなどをパラメーターとして入力し、ArcGIS Pro の操作と ArcPy でのコーディングについて AI に質問できるスクリプト ツールを作成しました。
使用するライブラリ
上記した ArcPy の他に LLM との連携をするために LangChain というライブラリを使用します。 LangChain は、LLM を活用したアプリケーションを開発するためのフレームワークです。今回利用する主な理由としては、この後ご紹介するプロンプト テンプレートを利用するためです。ユーザーにおける生成 AI 利用のハードルの一つとして、タスクの文章化があげられます。それらを簡素化するために今回は LangChain を利用しています。 利用前に必要なライブラリを下記のように pip で導入します。
pip install langchain
pip install -qU langchain-openai
ArcGIS Pro で AI とチャットをしてみよう
今回作成したスクリプトは、ArcGIS Pro 上で動作する Python スクリプト ツールとなります。ArcGIS Pro 上で使える簡易的な AI チャットボットを想像していただければと思います。
ArcPy が受け取るパラメーターと UI の設定
Azure OpenAI Service の生成 AI サービスを API 経由で使うにあたり、必要なパラメーターがいくつかあります。ArcPy 側ではそれらをパラメーターとして入力するための設定をしています。 まず、必要な値としてはサービスのエンドポイントと API キーはもちろん、利用している API のバージョンと利用するサービスのデプロイ名が必要になります。パラメーターについては、こちらのリファレンスも参照してください。 今回は、回答のランダム性も設定できるようにしておきたいので temperature もパラメーターとして持たせてみます。
![Pythonツール.png Pythonツール.png](https://community.esri.com/t5/image/serverpage/image-id/113590iEEB6DA1D9AE80B4B/image-size/large?v=v2&px=999)
ArcGIS Pro で独自のツールを作る際は、ArcGIS Pro の UI を操作して作成するカスタム ツールボックス と Python のスクリプトで作成する Python ツールボックスと二通りの方法がありますが、今回は Python ツールボックスを使用します。これらの差異や作成手順は、過去の記事をご参照ください。Python スクリプト ツールからの作成の場合は ArcPy のメソッドを用いてパラメーターの設定をする必要がありますので、図のようなパラメーターを実装するために下記のように設定します。
import arcpy
params = []
# Azure エンドポイント
endpoint = arcpy.Parameter(
displayName="Azure OpenAI エンドポイント",
name="AzureEndPoint",
datatype="String",
parameterType="Required",
direction="Input",
)
params.append(endpoint)
# Azure デプロイ名
deployname = arcpy.Parameter(
displayName="デプロイ名",
name="deployname",
datatype="String",
parameterType="Required",
direction="Input",
)
params.append(deployname)
# API のバージョン
apiversion = arcpy.Parameter(
displayName="API バージョン",
name="apiversion",
datatype="String",
parameterType="Required",
direction="Input"
)
params.append(apiversion)
# API キー
apikey = arcpy.Parameter(
displayName="API キー",
name="apikey",
datatype="GPStringHidden", # 入力した文字列を隠す
parameterType="Required",
direction="Input",
)
params.append(apikey)
# 質問分類
quetype = arcpy.Parameter(
displayName="質問の種類",
name="quetype",
datatype="String",
parameterType="Required",
direction="Input",
)
quetype.filter.type="Value List"
quetype.filter.list=["コーディング","ArcGIS Pro の操作"]
quetype.value="コーディング"
params.append(quetype)
# 回答のランダム性の制御
temperature = arcpy.Parameter(
displayName="温度設定",
name="temperature",
datatype="GPDouble",
parameterType="Required",
direction="Input",
)
temperature.filter.type="Range"
temperature.filter.list = [0, 1]
temperature.controlCLSID="{C8C46E43-3D27-4485-9B38-A49F3AC588D9}"
temperature.value=0
params.append(temperature)
# 質問
que = arcpy.Parameter(
displayName="GPT への質問",
name="ChatGPTMessages",
datatype="String",
parameterType="Required",
direction="Input",
)
que.controlCLSID="{E5456E51-0C41-4797-9EE4-5269820C6F0E}"
params.append(que)
これらのパラメーターを入力し、実行ボタンを押すと LangChain の AzureChatOpenAI クラスに下記のように渡されます。
from langchain_openai import AzureChatOpenAI
os.environ["AZURE_OPENAI_ENDPOINT"] = parameters[0].valueAsText
os.environ["DEPLOYMENT_NAME"] = parameters[1].valueAsText
os.environ["AZURE_OPENAI_API_VERSION"] = parameters[2].valueAsText
os.environ["AZURE_OPENAI_API_KEY"] = parameters[3].valueAsText
llm = AzureChatOpenAI(
azure_deployment=os.getenv("DEPLOYMENT_NAME"),
api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
temperature=parameters[5].valueAsText,
)
直接 API キーをパラメーターに含めることは Azure OpenAI Service のドキュメントでも非推奨となっているため、今回は os モジュールを使って、環境変数に設定しています。 次は、変数 llm に格納したモデルを使ってユーザーの質問に回答するよう設定します。
LangChain によるプロンプト テンプレートの構成
生成 AI をよく使う方の多くは、プロンプト(命令)を意識しているかと思われます。より快適に利用するなら必須のスキルですが、初めて触る方やあまり触れる機会が少ない方は意識し辛い点でもあるので、思ったような回答が得られないことも多々あるかと思います。 そこで今回は LangChain を利用し、ユーザーが記述した質問に対し、プロンプトを再構成し、極力プロンプトを意識する必要がないようにテンプレートを用意しています。 今回は「コーディング」と「ArcGIS Pro の操作」に焦点をおいて、それぞれにテンプレートを用意しています。特にコーディングにおいては、下記のようにコードを出力するための指示とコード以外の出力は返さないようにしています。
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.chains import SimpleSequentialChain
qa_temp="""
以下の質問は、ArcGIS Pro の ArcPy でのコーディングについてのものです。
Python コードをつけてお答えください。
質問:{question}
"""
summrize_temp="""
入力をコードのみにしてください。
入力:{summarize}
"""
qa_prompt=PromptTemplate(
input_variables=["question"],
template=qa_temp
)
qa_chain=LLMChain(llm=llm,prompt=qa_prompt)
summarize_prompt=PromptTemplate(
input_variables=["summarize"],
template=summarize_temp
)
summarize_chain=LLMChain(llm=llm,prompt=summarize_prompt)
qa_summarize_chain=SimpleSequentialChain(chains=[qa_chain,summarize_chain])
qa_result=qa_summarize_chain(parameters[6].valueAsText)
arcpy.AddMessage(qa_result["output"])
上記のようにプロンプト テンプレートを用意し、シンプルな質問でもより良い回答を出力できるように設定しています。最終的な出力結果は、「詳細の表示」から確認できるよう arcpy.AddMessage を使っています。 最後にこれらの設定により、思った通りの回答が得られるかを試してみます。
スクリプト ツールの実行
上記で作成したスクリプト ツールを実際に使ってみます。 コーディングと ArcGIS Pro での操作についての項目で質問できますが、どちらも同じ質問をして、同等のことができるか確認してみます。今回質問する内容は、「特定のレイヤーで 1km バッファを作成する方法を教えてほしい」とします。
コーディングに関する質問
各パラメーターに適切な値を入力し、質問を入力したら早速実行してみましょう。
![コーディング.png コーディング.png](https://community.esri.com/t5/image/serverpage/image-id/113597i83F502B50B23EF3A/image-size/large?v=v2&px=999)
実際に出力された Python スクリプトは下記のとおりです。
import arcpy
# バッファを作成したいレイヤーのパスを指定
input_layer = "C:/path/to/your/layer.shp" # ここを実際のレイヤーのパスに変更
output_buffer = "C:/path/to/your/output_buffer.shp" # 出力バッファのパス
# バッファの距離を指定(1km)
buffer_distance = "1000 Meters"
# バッファを作成
arcpy.Buffer_analysis(input_layer, output_buffer, buffer_distance)
print("バッファが作成されました。")
特に指定はしていなかったので shp 形式での入力と出力を前提としているようです。 この辺りは、プロンプトでファイル名やパスを指定するなどして調整してみてもいいかもしれません。実際にこれらのスクリプトのパスを変更して実行してみましょう。
![コーディング_buffer.png コーディング_buffer.png](https://community.esri.com/t5/image/serverpage/image-id/113598iF00B7FEEC2ECB261/image-size/large?v=v2&px=999)
エラーなく実行できました。どうやらコードに間違いはなかったようです。 次に「ArcGIS Pro の操作」で試してみましょう。
ArcGIS Pro での操作に関する質問
コーディングに関する質問と同様の手順で質問分類の項目を「ArcGIS Pro の操作」として、実行します。結果はコーディングに関する質問と同様にメッセージ ボックスに出力されます。
![ArcGISPro.png ArcGISPro.png](https://community.esri.com/t5/image/serverpage/image-id/113595iD76B813EF9E4E18A/image-size/large?v=v2&px=999)
実際に出力された説明は下記のとおりです。
1. **ArcGIS Proを起動**し、プロジェクトをロード。
2. **マップを開く**: コンテンツパネルから対象のマップを選択。
3. **レイヤーを選択**: バッファを作成したいレイヤーを右クリック。
4. **ジオプロセシングツールを開く**: メニューから「ジオプロセシング」を選択。
5. **バッファツールを検索**: ツールボックスで「Buffer」を検索し、選択。
6. **バッファツールの設定**: 入力フィーチャにレイヤーを選び、バッファ距離に「1 Kilometer」を入力。出力フィーチャクラスの保存先を指定。
7. **オプションの設定**: 必要に応じて他のオプションを設定。
8. **実行**: 設定後、「実行」ボタンをクリック。
9. **結果の確認**: 出力フィーチャクラスがコンテンツパネルに追加され、マップ上で確認。
10. **保存**: プロジェクトを保存。
いくらか説明が雑になっている箇所がありますが、上記の手順通り実行すると下図のような形でバッファが作成できました。
![ArcGISPro_buffer.png ArcGISPro_buffer.png](https://community.esri.com/t5/image/serverpage/image-id/113596i3977398CB1DDC342/image-size/large?v=v2&px=999)
このようにして ArcGIS Pro の操作を行う上でのサポート ツールとして使うこともできそうです。
さいごに
今回は ArcPy を使って ArcGIS Pro で Azure OpenAI Service の GPT-4o mini を利用する方法について紹介しました。また、LangChain を使ってプロンプト テンプレートを実装することでユーザー側はプロンプトを深く考えずとも GPT-4o mini による適切な回答を受け取ることができました。これらの技術を組み合わせることで、ArcGIS Pro 上でも GPT-4o mini を利用することができます。 ただ、今回記載した内容では、それぞれの機能をすべて発揮できているわけではありません。特に LangChain や Azure OpenAI Service の機能は、今後も研鑽が必要と感じています。 ぜひ、皆様も ArcGIS Pro と生成 AI との連携の可能性について、ご意見やご感想をお寄せください。
参考資料