追加のパラメータを実装してみる
番外編2で質問の中に人格、役割を含めることによって、回答に変化を付けることができました。APIリファレンスによると送信するJSONに追加の属性を指定することで明示的に役割を指定したり、回答する情報の精度を指定することができるようです。
今回は「system」「temperature」属性を実装してみます。属性の詳細を知りたい方は公式HPを参照して下さい。
API Reference – OpenAI API
system属性の実装
system属性は人格や役割、語尾の指定などを指定できます。送信フォーマットはmessage属性にリストとして追加します。最終的には設定フォームを作って外部に設定できるようにする方が良いですが、今回はサンプルなので定数として属性を定義します。
【問合せJSONフォーマット】
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "あなたはティーンエージャーです。語尾に「ぺこ」をつけて会話します。"
},
{
"role": "user",
"content": "滋賀のおいしいイタリアンを5店舗リストアップしてください。"
}
]
}
【LotusScriptコード】
Sub Click(Source As Button)
'---------- ---------- ---------- ---------- ----------
'OpenAI APIから取得したレスポンスを書込み
'
'---------- ---------- ---------- ---------- ----------
Const APIURL = "https://api.openai.com/v1/chat/completions"
Const APIKEY = "(取得したAPIKEY)"
Const MODEL = "gpt-3.5-turbo"
Const SYSTEM = "語尾に「ぺこ」をつけて会話します。"
'クラス・変数宣言
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Dim session As New NotesSession
Dim jsonNav As NotesJSONNavigator
Dim vXml As Variant 'XMLオブジェクト
Dim sRequest As String '入力した質問
Dim sBodyJson As String '送信するJSON文字列
Dim sContent As String '回答本文
Dim sCarryOver As String '前回の質問引き継ぎフラグ
Dim vRequestList As Variant '質問履歴(リスト)
Dim sSystemJson As String 'system属性JSON
'クラス・変数セット
Set uidoc = ws.CurrentDocument
Set doc = uidoc.Document
sSystemJson = |{"role":"system","content":"| & SYSTEM & |"},|
'入力チェック
sRequest = doc.Request(0)
If sRequest = "" Then
Msgbox "質問を入力して下さい。",64,"確認"
Exit Sub
End If
'継続質問フラグ確認と送信JSONの作成
sCarryOver = doc.CarryOver(0) '質問引き継ぎフラグ取得
sRequest = Replace(sRequest, Chr(13) & Chr(10), "\n") '質問の改行を「\n」に変換(改行はエラーになる)
'ソースコード送信対策
sRequest = Replace(sRequest, """", "\""") 'ダブルコートをエスケープ
sRequest = Replace(sRequest, Chr(9), " ") 'TABを半角スペースに変換
If sCarryOver = "1" Then
vRequestList = doc.RequestList '質問履歴フィールド取得
sBodyJson = |{"model":"| & MODEL & |", "messages":[|&_
sSystemJson &_
|{"role":"user", "content":"| & Join(vRequestList,"\n") & "\n" & sRequest & |"} ] }|
Else
sBodyJson = |{"model":"| & MODEL & |", "messages":[| &_
sSystemJson &_
|{"role":"user", "content":"| & sRequest & |"} ] }|
End If
'Msgbox sBodyJson '< for debug>
'Getリクエストを実行し、結果を取得
Set vXml = CreateObject("MSXML2.XMLHTTP")
vXml.Open "POST", APIURL, False
vXml.setRequestHeader "Content-Type", "application/json"
vXml.setRequestHeader "Authorization", "Bearer " & APIKEY
vXml.send sBodyJson
'エラーレスポンスチェック
If vXml.Status <> 200 Then
Msgbox vXml.responseText, 16, "Error : " & Cstr(vXml.Status)
Exit Sub
End If
'レスポンスから回答を抽出
Set jsonNav = session.CreateJSONNavigator(vXml.responseText)
sContent = jsonNav.GetElementByPointer("/choices/0/message/content").Value
'回答をフォームに書込み
doc.HttpStatus = vXml.Status
doc.Response = sContent
End Sub
system属性を変えて同じ質問をしてみる
属性を変えて回答結果がどのように変わるのか?実験してみます。質問内容は「トヨタ自動車の社長は誰ですか?」です。結果を見てわかる通り、設定の仕方によって正確な回答が得られたり、得られなくなったりします。生成AIは人格もシミュレーションし、再現してくれると言うことです。
【あなたはティーンエージャーです。】
複数回実行すると読み方を間違えたりしました。
【あなたはティーンエージャーです。語尾に「ぺこ」を付けて会話します。】
何度実行しても正しい結果は得られませんでした。
【語尾に「ぺこ」を付けて会話します。】
複数回実行してもほぼ同じ結果ですが、よみがなが「とよだ」「とよた」の2種類がありました。
temperature属性の実装
temperature属性は情報の精度を設定する属性です。0~1の範囲で設定でき、0だと最も確実な情報、1だと不確実な情報を含む回答になります。不確実な情報は要らねえよと言う方もいると思いますが、不確実性を上げることで今までになかったアイディア、新しい発想にたどり着く可能性があります。
【問合せJSONフォーマット】
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "user",
"content": "滋賀のおいしいイタリアンを5店舗リストアップしてください。"
}
],
"temperature":0.2
}
【LotusScriptコード】
Sub Click(Source As Button)
'---------- ---------- ---------- ---------- ----------
'OpenAI APIから取得したレスポンスを書込み
'
'---------- ---------- ---------- ---------- ----------
Const APIURL = "https://api.openai.com/v1/chat/completions"
Const APIKEY = "(取得したAPIKEY)"
Const MODEL = "gpt-3.5-turbo"
Const TEMPERATURE = 1
'クラス・変数宣言
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Dim session As New NotesSession
Dim jsonNav As NotesJSONNavigator
Dim vXml As Variant 'XMLオブジェクト
Dim sRequest As String '入力した質問
Dim sBodyJson As String '送信するJSON文字列
Dim sContent As String '回答本文
Dim sCarryOver As String '前回の質問引き継ぎフラグ
Dim vRequestList As Variant '質問履歴(リスト)
Dim sTempJson As String 'Temperature属性JSON
'クラス・変数セット
Set uidoc = ws.CurrentDocument
Set doc = uidoc.Document
sTempJson = |,"temperature":| & Format$(TEMPERATURE, "0.0#")
'入力チェック
sRequest = doc.Request(0)
If sRequest = "" Then
Msgbox "質問を入力して下さい。",64,"確認"
Exit Sub
End If
'継続質問フラグ確認と送信JSONの作成
sCarryOver = doc.CarryOver(0) '質問引き継ぎフラグ取得
sRequest = Replace(sRequest, Chr(13) & Chr(10), "\n") '質問の改行を「\n」に変換(改行はエラーになる)
'ソースコード送信対策
sRequest = Replace(sRequest, """", "\""") 'ダブルコートをエスケープ
sRequest = Replace(sRequest, Chr(9), " ") 'TABを半角スペースに変換
If sCarryOver = "1" Then
vRequestList = doc.RequestList '質問履歴フィールド取得
sBodyJson = |{"model":"| & MODEL & |", "messages":[ {"role":"user", "content":"| & Join(vRequestList,"\n") & "\n" & sRequest & |"} ]| &_
sTempJson &_
| }|
Else
sBodyJson = |{"model":"| & MODEL & |", "messages":[ {"role":"user", "content":"| & sRequest & |"} ]| &_
sTempJson &_
| }|
End If
'Msgbox sBodyJson '< for debug>
'Getリクエストを実行し、結果を取得
Set vXml = CreateObject("MSXML2.XMLHTTP")
vXml.Open "POST", APIURL, False
vXml.setRequestHeader "Content-Type", "application/json"
vXml.setRequestHeader "Authorization", "Bearer " & APIKEY
vXml.send sBodyJson
'エラーレスポンスチェック
If vXml.Status <> 200 Then
Msgbox vXml.responseText, 16, "Error : " & Cstr(vXml.Status)
Exit Sub
End If
'レスポンスから回答を抽出
Set jsonNav = session.CreateJSONNavigator(vXml.responseText)
sContent = jsonNav.GetElementByPointer("/choices/0/message/content").Value
'回答をフォームに書込み
doc.HttpStatus = vXml.Status
doc.Response = sContent
End Sub
temperature属性を変えて同じ質問をしてみる
temperature属性を変えて、先ほどと同じ「トヨタ自動車の社長は誰ですか?」という質問をしてみます。
【temperature=0】
複数回実行しても同じ結果が得られました。
【temperature=1】
複数回実行すると年やよみがなが変化するようです。
さいごに
属性をいろいろ変えてテストしてみると、生成AIが何者か?何が得意で何が苦手なのか?が見えてきます。生成AIが存在しない世界にはもう戻れないと思うので皆さんもいろいろ実験してみて下さい。