近年、LLM(Large Language Models)に外部データを読み込ませて、学習していない内容についても回答を生成させるRAG(Retrieval Augmented Generation)技術が注目を集めています。
Azure OpenAIのOn Your Dataを利用することで、RAGを容易に構築できる一方で、データソースはAzure Blob Storageやユーザーがアップロードしたファイルに限られます。
この記事では、RAGのデータソースとしてSharePoint Online(SPO)を使用するための準備段階として、SPOからコンテンツをGraph APIを通じて取得する方法を解説します。
準備
今回はSPOのコンテンツをGraph APIで取得するため、Microsoft Entra IDにアプリケーションを登録する必要があります。
以下サイトを参考にアプリケーションの登録を行ってください。
アプリケーションを登録したら、クライアント シークレットとAPIのアクセス許可の設定を行います。
クライアント シークレットの作成
登録したアプリーケーションの「証明書とシークレット」タブから新しくシークレットを作成します。期間は任意です。
ここで生成されたシークレット値は再度表示することはできないので、必ずコピーして保管してください。
APIのアクセス許可
SPOにアクセスするためにアプリケーションのアクセス許可を設定します。「API のアクセス許可」タブから「Files.Read.All」と「Sites.Read.All」権限を付与してください。
Pythonの準備
使用するPythonのバージョンは3.10です。また、Graph APIを使うためにmsal · PyPIのバージョン1.24.0をインストールしておきます。
今回使用するライブラリと関数
ライブラリ
以下のライブラリをインポートして使用します。
import json import requests import msal import io
関数
必要な変数を先に定義しておきます。
- tenant_id:ディレクトリ (テナント) ID
- client_id:登録したアプリケーションのクライアントID
- secret:作成したシークレットの値
# Load parameters tenant_id = "" authority = f"https://login.microsoftonline.com/{tenant_id}" client_id = "" secret = "" scope = ["https://graph.microsoft.com/.default"] # msalのインスタンス化 app = msal.ConfidentialClientApplication(client_id, authority=authority, client_credential=secret)
アクセストークンの取得
Graph APIにリクエストを送信する際に必要な認証情報を取得する関数です。
def get_access_token() -> dict: # アクセストークンの取得 result = app.acquire_token_silent(scope, account=None) # アクセストークンが取得できなかった場合は、ADDから取得 if not result: result = app.acquire_token_for_client(scopes=scope) return result
Graph APIへのリクエスト
この関数を使用してGraph APIにリクエストを送信してSPOからコンテンツを取得します。
def request_graph_api(endpoint: str): # アクセストークンの取得 access_token = get_access_token() if "access_token" in access_token: graph_data = requests.get( endpoint, headers={'Authorization': 'Bearer ' + access_token['access_token']} ) return graph_data else: print(access_token.get("error")) print(access_token.get("error_description")) print(access_token.get("correlation_id")) raise Exception("===Failed to call MS Graph API. See stderr for details.===")
SharePoint Onlineのコンテンツ取得
SPOからコンテンツを取得する手順を解説します。ここでは、「ドキュメント」、「リスト」、「ページ」の取得について解説します。
サイトIDの取得
コンテンツを取得する前に、SPOのサイトIDを把握する必要があります。
以下のリクエストを送信すると、responseにテナント内のサイト情報が返ってきます。
endpoint = "https://graph.microsoft.com/v1.0/sites"
response = request_graph_api(endpoint).json()
ドキュメントの取得
ドキュメントを取得するために、ドキュメントIDの一覧を取得します。
上記で取得したサイトIDを指定してサイト内のドキュメントを取得できます。
site_id = "" endpoint = f"https://graph.microsoft.com/v1.0/sites/{site_id}/drive/items/root/children" response = request_graph_api(endpoint).json()
そして、取得したいドキュメントのIDを以下のように指定することで、ドキュメントのバイナリデータを取得することができます。
site_id = "" doc_id = "" endpoint = f"https://graph.microsoft.com/v1.0/sites/{site_id}/drive/items/{doc_id}/content" response = request_graph_api(endpoint).content data = io.BytesIO(response)
リストの取得
リスト内のアイテムを取得するために、リストIDの一覧を取得します。
上記で取得したサイトIDを指定してサイト内のリストを取得できます。
site_id = "" endpoint = f"https://graph.microsoft.com/v1.0/sites/{site_id}/lists" response = request_graph_api(endpoint).json()
そして、取得したリストIDを使用してリスト内のアイテム一覧を取得します。
site_id = "" list_id = "" endpoint = f"https://graph.microsoft.com/v1.0/sites/{site_id}/lists/{list_id}/items" response = request_graph_api(endpoint).json()
最後に、取得したいアイテムIDを指定することで、リストのアイテムを取得することができます。
site_id = "" list_id = "" item_id = "" endpoint = f"https://graph.microsoft.com/v1.0/sites/{site_id}/lists/{list_id}/items/{item_id}" response = request_graph_api(endpoint).json()
ページの取得
ページの内容を取得するために、ページIDの一覧を取得します。ページの取得にはbeta版のGraph APIを使用する必要がある点に注意が必要です。
site_id = "" endpoint = f"https://graph.microsoft.com/beta/sites/{site_id}/pages" response = request_graph_api(endpoint).json()
そして、取得したページIDを使用してページの内容を取得します。 クエリとして、「expand=canvasLayout」を指定することでページ内コンテンツを取得します。
site_id = "" page_id = "" endpoint = f"https://graph.microsoft.com/beta/sites/{site_id}/pages/{page_id}/microsoft.graph.sitePage?expand=canvasLayout" response = request_graph_api(endpoint).json()
おわりに
本記事では、Graph APIを使用してSPOからコンテンツを取得する手順について解説しました。
今回はPythonを使用しましたが、他の言語でも同じようにリクエストを送信することでSPOのコンテンツを取得することが可能です。
SPOからコンテンツを取得することができたので、次にAzure AI Searchなどの検索プラットフォームにデータを挿入することで、RAGのデータソースとして使用することが可能となります。