2025/01/04

作ってみよう:#17)スマート名刺管理 - GTP4o API リクエストの作成 ①

いよいよ、GPT4o に対して問い合わせを行うプログラムの開発を開始します。


スクリプトライブラリの作成

API 連携機能のコードをまとめて管理するため LotusScript のライブラリを作成します。

名前 lsReadNameCard

まずは、ライブラリ内で普遍的な値を Private 変数に登録し、初期化時点で取得します。このタイミングで、前回作成した 2 つのプロフィール文書を取得しておきます。


Option Declare

Private xns As NotesSession
Private xndb As NotesDatabase
Private xndWAPI As NotesDocument 'OpenAI API 設定
Private xndChat As NotesDocument 'Chat Completion 設定

Sub Initialize
   Set xns = New NotesSession
   Set xndb = xns.CurrentDatabase

   'プロフィール文書 取得
   Set xndWAPI = xndb.GetProfileDocument("fpStdCfg_OpenAI")
   Set xndChat = xndb.GetProfileDocument("fpStdCfg_OpenAI_ChatCompletion")
End Sub


以降の作業では、関数作成前に呼び出し側を記述する場合があります。そのため、デザイナー上で『N012 SUB または FUNCTION の名前ではありません。』エラーが出ます。このエラーについては気にせず作業を進めてください。完成時にはこのエラーはなくなります。


API コールを行うメイン関数

今回作成するメインの関数です。

ライブラリを利用するエージェントからコールされるので、Public 宣言されています。引数は、名刺管理の文書で、名刺画像が添付されている前提です。

Public Function ReadNameCard(vnd As NotesDocument) As Boolean
   Dim jnavRequest As NotesJSONNavigator
   Dim jnavResponce As NotesJSONNavigator
   Dim jnavNameCard As NotesJSONNavigator

   '1. API リクエスト時に送信する JSON を作成
   Set jnavRequest = xMakeRequest(vnd)
   'Call xSetRT(vnd, "JSON_Request", jnavRequest.Stringify)

   '2. API をコールし、結果の JSON を取得
   Set jnavResponce = xCallWebAPI(jnavRequest)
   'Call xSetRT(vnd, "JSON_Responce", jnavResponce.Stringify)

   '3. 結果の JSON 内から名刺情報部分だけの JSON を取得
   Set jnavNameCard = xGetNameCard(jnavResponce)
   'Call xSetRT(vnd, "JSON_NameCard", jnavNameCard.Stringify)

   '4. 名刺情報を文書に保存
   Call xSaveNameCard(jnavNameCard, vnd)
End Function

コメントに記載している通り、処理は大きく 4 つに分かれます。以降、順次作成します。

なお、xSetRT 関数は JSON をリッチテキストに保存する関数です。デバッグ時など値を確認したいときに有効にします。1 の JSON は画像を含むことから非常に大きくなります。フォームを開くのが遅くなるので必要な時以外は出力しないことをお薦めします。


送信する JSON の作成

API リクエスト時に送信する JSON の全体像は次の通りです。

この構造にそって、JSON を作成する関数が xMakeRequest です。ここでは、JSON 全体を作成することが目的で、3 つの各ノードを具体的に作成するのは、それぞれサブ関数が担当しています。

Private Function xMakeRequest(vnd As NotesDocument) As NotesJSONNavigator
   Dim jnav As NotesJSONNavigator

   '送信する JSON(RequestBody)の準備
   Set jnav = xns.CreateJSONNavigator("")

   '1) model
   Call xMakeRequest_Model(jnav)

   '1) messages
   Call xMakeRequest_Message(jnav, vnd)

   '1) response_format
   Call xMakeRequest_ResponseFormat(jnav)

   Set xMakeRequest = jnav
End Function


model ノードの作成

コールする API のモデルを指定する部分です。構造が単純なので関数も簡単です。

Private Function xMakeRequest_Model(vjnav As NotesJSONNavigator) As Boolean
   Dim sModel As String

   'Chat Completion 設定 からモデル指定を取得
   sModel = xndChat.Model(0)
   If sModel = "" Then
      sModel = "gpt-4o-2024-08-06"
   End If

   Call vjnav.AppendElement(sModel, "model")
End Function


messages ノードの作成

画像送信するパターンの messages ノードの指定については、別の連載『つないでみよう』の #16 でまとめています。必要に応じてご確認ください。

このノードの指定は大きく 2 つに分かれます。システムの役割を指定する設定とユーザのリクエストです。今回は、AI の役割は OCR であることを伝え、画像を送信するだけという単純な構造としています。


messages ノードを作成する関数 xMakeRequest_Message は次の通りです。

Private Function xMakeRequest_Message(vjnav As NotesJSONNavigator, vnd As NotesDocument) As Boolean
   Dim jaMsg As NotesJSONArray
   Dim joMsg As NotesJSONObject
   Dim jaCnt As NotesJSONArray
   Dim joCnt As NotesJSONObject
   Dim jo As NotesJSONObject
   Dim s As String
   Dim sSystem As String

   '1) messages
   Set jaMsg = vjnav.AppendArray("messages")

   'OpenAI Chat Completion 設定 から AI の役割を取得
   sSystem = xndChat.SystemRole(0)

   '2) system ロール
   If sSystem <> "" Then
      '指定があれば追加
      Set joMsg = jaMsg.AppendObject()
      Call joMsg.AppendElement("system", "role")
      Call joMsg.AppendElement(sSystem, "content")
   End If

   '2) user ロール
   Set joCnt = jaMsg.AppendObject()
   Call joCnt.AppendElement("user", "role")

   Set jaCnt = joCnt.AppendArray("content")

   '3) image_url 名刺画像
   Set joCnt = jaCnt.AppendObject()
   Call joCnt.AppendElement("image_url", "type")

   Set jo = joCnt.Appendobject("image_url")
   s = "data:image/jpeg;base64,{" & xGetImage_Base64(vnd, "Body") & "}"
   Call jo.AppendElement(s, "url")
End Function

GPT4o に画像を送信する JSON は以下のようなフォーマットで、赤線の部分が画像ファイルを Base64 でエンコードした文字列となります。文書内の添付ファイルからこの文字列を取得する関数が xGetImage_Base64 となります。この関数については次回紹介します。


前回 作ってみよう 次回


0 件のコメント:

コメントを投稿