Notes開発者のためのXPagesデザインレシピ

簡単でCoolなXPagesアプリケーションを作るための情報を発信していきます

Notesクライアント 生成AI

NotesクライアントからChatGPTに質問してみよう(番外編3)

追加のパラメータを実装してみる

 番外編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が存在しない世界にはもう戻れないと思うので皆さんもいろいろ実験してみて下さい。