AI拡張アプリのモジュールをフロントから使用する
これは a-blog cms Advent Calendar 2024 6日目の記事です。
内容は、現在制作中のAI拡張アプリについてです。
AI拡張アプリについては、過去に a-blog cms Live や、a-blog cms 勉強会 in 名古屋 で触れてきました。社内の先輩や a-blog cms ユーザーさんに意見をいただき、少しずつ実用的になってきました。そこで、AI拡張アプリの仕様について触れたいと思います。
AI拡張アプリとは
AI拡張アプリについて簡単に触れておきます。この拡張アプリは OpenAI API を使って実装したものです。現時点で提供予定の機能は、「ユニットの本文を元にタイトルの生成」「ユニットの本文を元にタグの生成」「ユニットをプロンプトで校正」の3つの機能です。「ユニットの本文を元にタイトルの生成」「ユニットの本文を元にタグの生成」については、a-blog cms Live で触れていますので動画をご覧ください。「ユニットをプロンプトで校正」は、少しずつ改良して、現時点ではモーダルウィンドウからプロンプトを入力して、校正文が返ってくるしようとなっております。
AI拡張アプリの仕様
AI拡張アプリは OpenAI API を元に作成していて、a-blog cms のモジュールは PHP で動作しているので curl を PHP で再現しています。
POSTモジュールの名前は、ACMS_POST_AI_Chat
です。このモジュールは、特定のデータを含めてPOSTしてあげると以下の json形式でレスポンスを返してくれます。これは、OpenAI API のシステムロールで指示をしていることと、API からのレスポンスデータを解析して配列の形式になっているかを確認しているからです。
[
{
"content": "response1"
},
{
"content": "response2"
},
{
"content": "response3"
}
]
POSTしてみる
以下のコードは、Javascript を使用して実際にPOSTモジュールへアクセスしてレスポンスを求めるコードです。
const postRequest = async (url, data, exec, formToken) => {
const formData = new FormData();
formData.append('prompt', JSON.stringify(data.prompt))
formData.append('mode', data.mode)
formData.append(exec, 'exec')
formData.append('formToken', formToken)
const response = await fetch(url, {
method: 'POST',
body: formData,
});
if(!response.ok) {
return null;
}
return response.json();
};
const postPrompt = async () => {
const postData = {
prompt: [
{
role: "user",
content: `明日の天気を教えてください。`
}
]
mode: 'ai'
}
try {
const result = await postRequest(
window.ACMS.Config.root,
postData,
'ACMS_POST_AI_Chat',
window.csrfToken
);
if(!result) return null;
if(result.errorCode && result.errorCode === 500) return null;
return JSON.parse(result);
}
catch (e) {
return null;
}
};
const getAI = async () => {
const result = await postPrompt();
if(!result) {
console.error('取得に失敗しました。');
return null;
}
if(!result[0].content) {
console.error('生成に失敗しました。');
return null;
}
return result[0].content
}
実際に送信しているのは postRequest関数で、引数にとっている値がポイントになります。
- url
- アクセスする URL です。POST が発火する URL であればいいので root でいいです。
- postData
- 実際にOpenAI API に送信するデータです。prompt と mode を送信する必要があります。prompt は OpenAI API のリファレンスに沿って指定ができます。prompt の content についてはベストプラクティスがあるので、次の章でご紹介します。mode は、現在は tag が指定されている場合のみ意味を持つのですが、tag の場合は、a-blog cms 内の既存のタグを取得する処理が行われています。その他にも mode によって、個別の処理が必要になった場合に使えるよう指定を必要としています。
- exec
- ポストモジュール名です。
- formToken
- a-blog cms の仕様で、formToken を送信する必要があります。window.csrfToken を postPrompt関数内で渡してあげているのですが、これは外部経由からのリクエストを判断するためのトークンです。普段 formなどで POST する時に気にしなくていいのは、a-blog cms が自動でつけているからです。今回は Javascript で送信しているのでつけてあげる必要があります。
prompt のベストプラクティス
ベストプラクティスについては、公式が明言しています。
ただ一つ a-blog cms の仕様として注意事項があり、それは「AI拡張アプリの仕様」の章で紹介した json の レスポンス形式を守ることです。POSTモジュールで形式チェックを行なっているので、間違った形式だとエラーが返ってきてしまいます。ですので、もしレスポンスの形式を独自で指定する場合は、以下のような形式を望ましい形式としてprompt を投げてください。
// 配列で囲い、オブジェクトで "content" を含めます。
[
{
"content": {
"name": "",
"role": "",
},
{
"content": {
"name": "",
"role": "",
}
]
最後に
リリース日がまだ未定で申し訳ないです。できれば本年でリリースしたかったのですが、少し難しいかもしれないです...