フォーム読み込み中
システムエンジニアの成瀬です。
日々刻々と進化を続けているAIやクラウドサービスを検証したり、AIを活用したアプリを作ったりしています。
テキスト生成AIで利用されている大規模言語モデル(基盤モデル)は、色々なことを良く知っていて、流暢な言葉で質問に答えてくれます。
その一方で、以下のような困った回答に出くわすこともしばしばあります。
そもそも、生成AIモデルの知識はトレーニング時点の学習データに基づいているため、学習データに含まれていない情報や、最新情報については答えることができません。
また、生成AIモデルの学習データの大部分は、インターネットなどから入手可能な公開情報を利用しているために、不正確・不完全・非中立・非公正な情報が含まれていることが多々あります。
そのような玉石混交の知識の中から、質問に関係のありそうなことを答えているだけで、正しいかどうかを判断しているわけではありません。
また、知識が膨大であるだけに、質問の内容が漠然としているほど回答も発散してしまい、精度も下がってしまいます。
以上のことから、生成AIをQ&Aに利用するにあたって(特に最新情報や非公開情報について)、望ましい回答を引き出すことは、簡単ではないことがわかっていただけたかと思います。
では、どうすればよいでしょうか?
世の中のことは良く知っているけど、業務のことはよくわかっていない...
生成AIモデルって、なんだか新入社員と良く似ていませんか?
ここでは、新入社員の教育係になったつもりで対策を考えてみましょう。
1. 知らないことは教えてあげる(知識を与える)
新入社員は色々な資料を読んで仕事に必要な知識を身につけます。
生成AIモデルにも質問を受けた時に参照すべき情報を教えてあげましょう。
2. 間違った回答をしないように導いてあげる(指示を明確にする)
知識があるからといって、正しい回答ができるとは限りません。
回答の作法や禁句など、指示を明確にすることによって、与えられた知識からどのように回答すればいいのか導いてあげましょう。
では、今回の対策の「知識を与える」と「指示を明確にする」のそれぞれの具体的な方法について、これから見ていきましょう。
生成AIモデルに知識を与える方法としては、主に以下の3つが挙げられます。
事前学習は、ゼロから生成AIモデルをトレーニングする方法で、膨大なコンピューティングリソースを使いながら、大量のトレーニングデータでモデルに学習させます。
これにより、生成AIモデルは言語的素養や世の中に関する知識を身につけます。
トレーニングにかかる費用は莫大で、あるモデル(1800億パラメータ)では55日間で、24億円かかったそうです。
ファインチューニングは、事前学習によってトレーニングされた生成AIモデルに対して、性能改善や、特定の分野の課題に適応させるために、独自のデータでさらにトレーニングします。
ファインチューニングされたモデルはカスタムモデルなどと呼ばれます。
ほとんどのクラウドサービスでも利用可能ですが、基盤モデルが限定されています。
グラウンディングは、プロンプトを経由して外部の情報を与えることで、生成AIモデルの知識を一時的に補強します。
外部から知識を与えることが可能になるために、回答の情報源を明らかにすることができます。
以下にそれぞれの方法のポジティブな点・ネガティブな点について、簡単にまとめてみました。
| 方法 | ポジティブな点 | ネガティブな点 |
|---|---|---|
| 事前学習 | どんなモデルでも作れる | トレーニングが必要 コストが莫大 AIの専門知識が必要 |
| ファインチューニング | プロンプトが小さくてすむ | 対象モデルが限定される トレーニングが必要 |
| グラウンディング | トレーニング不要 情報源を明らかにできる | プロンプトが大きくなる |
それでは、生成AIモデルに知識を与える方法として、最も手軽なグラウンディングを利用してみたいと思います。
実際にプロンプトを試してみながら、よりよい回答を引き出す方法について考えていきましょう。
※ 生成AIの回答はモデルのバージョンやリクエストパラメータによって異なる可能性があります。常に例と同じ結果になるわけではないことに注意してください。
入力されたプロンプトからテキストを生成します。
GENERATE_TEXT(PROMPT)
PROMPT:プロンプトです。
GENERATE_TEXT( "日本の内閣総理大臣は誰ですか?" )
生成テキスト
今回使用するテキスト生成APIの基盤モデルは、日本語にも対応している PaLM2 for Text の最新版を使用します。
| モデル名 | バージョン | 最大入力トークン数 | 最大出力トークン数 |
|---|---|---|---|
| text-bison | 最新版 | 8192 | 2048 |
| text-bison@002 | 安定版 | 8192 | 1024 |
※1トークンは英数字で約4文字、漢字で約 1 文字に相当します。
POST https://us-central1-aiplatform.googleapis.com/v1/projects/{プロジェクトID}/locations/us-central1/publishers/google/models/text-bison:predict
| 名称 | 値 | 説明 |
|---|---|---|
Content-Type | "application/json" | リクエストデータの種類(JSON) |
Authorization | "Bearer {アクセストークン}" | サービス認証に必要 BASE64でエンコードする |
※ アクセストークンは別途APIで取得する必要があります。取得方法については、前編の「アクセストークンの取得方法」を参照してください。
| フィールド名 | データ型 | 説明 | |
|---|---|---|---|
instances | オブジェクトの配列 | 入力プロンプト情報 (複数は不可) | |
prompt | テキスト | モデルが応答を生成するための入力テキスト | |
| parameters | オブジェクト | 調整パラメータ | |
| candidateCount | 整数 (1~8) | 回答のバリエーションの数 デフォルト: 1 | |
| maxOutputTokens | 整数 (1~2048) | 生成する最大トークン数 デフォルト: 1024 | |
| temperature | 実数 (0.0~1.0) | 生成結果の多様性 0.0は低い、1.0は高い デフォルト 0.0 | |
| topK | 整数 (1~40) | 予測確率上位のサンプリング数 デフォルト: 40 | |
| topP | 実数 (0.0~1.0) | 予測確率上位のサンプリング割合 デフォルト: 0.95 | |
| stopSequence | テキストの配列 | 応答内でいずれかの文字列が見つかった場合にテキストの生成を停止するようにモデルに指示するテキストのリストを指定。大文字と小文字は区別。 デフォルト: [] | |
{
instances: {
prompt: "日本の内閣総理大臣は誰ですか?"
},
parameters: {
candidateCount: 1,
maxOutputTokens: 1024,
temperature: 0.0,
topP: 0.1,
topK: 1,
opt_out: true,
}
}
| フィールド名 | データ型 | 説明 | |||
|---|---|---|---|---|---|
predictions | オブジェクトの配列 | 生成結果 リクエストデータのparameters.candidateCountに対応する件数の生成結果が格納されます | |||
content | テキスト | 生成テキスト | |||
safetyAttributes | オブジェクト | 安全属性情報 | |||
categories | テキストの配列 | 生成されたコンテンツに関連付けられた安全属性カテゴリの表示名 順序はスコアと一致します | |||
blocked | ブーリアン | モデルの入力または出力がブロックされたかどうか | |||
scores | 数値の配列 | 各カテゴリの信頼度スコア 値が大きいほど信頼度が高いことを意味します。 | |||
| metadata | オブジェクト | メタデータ | |||
| tokenMetadata | オブジェクト | トークン情報 | |||
| input_token_count | オブジェクト | 入力トークン情報 | |||
| total_tokens | 整数 | 合計トークン数 | |||
| output_token_count | オブジェクト | 出力トークン情報 | |||
| total_tokens | 整数 | 合計トークン数 | |||
{
predictions: [
{
content: '私の知識は2021年1月までの情報に基づいているため、現在の内閣総理大臣は菅義偉氏です。ただし、この情報は古くなっている可能性があるため、最新の情報を取得するには、内閣府のウェブサイトや他の信頼できる情報源を確認することをお勧めします。'
},
],
metadata: {
tokenMetadata: {
inputTokenCount: {
totalTokens: 10
},
outputTokenCount: {
totalTokens: 63
}
}
}
}
上のサンプルの場合、カスタム関数の戻り値として返すためには、レスポンスデータの predictions[0].content をセットすればよいことになります。
なお、Vertex AI APIのリクエストは、デフォルトで1分あたり30回の利用制限があります。利用制限を超過した場合、以下のエラーレスポンスが返ってきます。
{
code: 429,
message: 'Quota exceeded for aiplatform.googleapis.com/online_prediction_requests_per_base_model with base model: textembedding-gecko. Please submit a quota increase request. https://cloud.google.com/vertex-ai/docs/quotas.',
status: 'RESOURCE_EXHAUSTED'
}
※ これから登録するコードは、前編で作成したAppsScriptのプロジェクトを前提にしています。
前編と同様にカスタム関数をスクリプトエディタから登録します。
/**
* 生成AI APIを使用して、テキストを生成します。
*
* @param {"トイレはどこですか"} PROMPT プロンプト {文字列}
* プロンプトのテキストです。
* @return {string}
*
* @customfunction
* copyright (c) 2024 SoftBank Corp.
*/
function GENERATE_TEXT(PROMPT, MODEL = "text-bison") {
let access_info;
try {
access_info = get_access_token_(GCP_CREDS.client_email, GCP_CREDS.private_key)
}
catch (e) {
console.error(e)
throw "内部エラーが発生しました"
}
const access_token = access_info.access_token
const headers = {
"Authorization": "Bearer " + access_token
}
const API_ENDPOINT = "us-central1-aiplatform.googleapis.com"
const url = `https://${API_ENDPOINT}/v1/projects/${GCP_CREDS.project_id}/locations/us-central1/publishers/google/models/${MODEL}:predict`
const payload = {
instances: [
{
prompt: PROMPT
},
],
parameters: {
"candidateCount": 1,
"maxOutputTokens": 1024,
"temperature": 0.0,
"topP": 0.1,
"topK": 1,
"opt_out": true,
}
}
const params = {
method: "post",
contentType: "application/json",
headers: headers,
payload: JSON.stringify(payload),
muteHttpExceptions: true,
}
const res = UrlFetchApp.fetch(url, params)
if (res.getResponseCode() != 200) {
console.error(res.getContentText())
throw "内部エラー"
}
const res_json = JSON.parse(res.getContentText())
return res_json.predictions[0].content
}
それでは、スプレッドシートからカスタム関数を実行してみましょう。
セルA1に以下の式を入力して、エンターキーを押します。
=GENERATE_TEXT("日本の内閣総理大臣は誰ですか?")
情報の鮮度はさておき、以下のような答えが返ってくれば成功です。
もしも、以下のようなエラーが発生した場合は少し時間を空けてからもう一度実行してみてください。
2,3回リトライしてみても改善しなければ、そのまま次に進んでください。
テキスト生成AIの応答は時間がかかることがよくあります。
原因としては、入力・出力時のトークンの長さ、モデルの種類やバージョン、サービスの環境や利用状況などが考えられます。
実は、Google スプレッドシート上で実行するカスタム関数は30秒以内に完了しないと、上のようなエラー( Exceeded maximum execution time ) が発生して、強制的に処理を中断させられてしまいます。
そこで、エラーを気にせず試せるように、カスタム関数をUIから実行できるようにコードを追加します。
/**
* スプレッドシートを開いたときにカスタムメニューを表示します。
*
* copyright (c) 2024 SoftBank Corp.
*/
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu("プロンプト実験室")
.addItem('開く', 'show_prompt_labo_')
.addToUi();
}
/**
* サイドバーを表示します。
*
* copyright (c) 2024 SoftBank Corp.
*/
function show_prompt_labo_() {
const html = HtmlService.createHtmlOutputFromFile('PROMPT_LABO')
.setTitle('プロンプト実験室');
SpreadsheetApp.getUi()
.showSidebar(html);
}
/**
* 生成AI APIを使用して、テキストを生成します。
*
* @param {"トイレはどこですか"} PROMPT プロンプト {文字列}
* プロンプトのテキストです。
* @return {string}
*
* @customfunction
* copyright (c) 2024 SoftBank Corp.
*/
function GENERATE_TEXT(PROMPT, MODEL = "text-bison") {
let access_info;
try {
access_info = get_access_token_(GCP_CREDS.client_email, GCP_CREDS.private_key)
}
catch (e) {
console.error(e)
throw "内部エラーが発生しました"
}
const access_token = access_info.access_token
const headers = {
"Authorization": "Bearer " + access_token
}
const API_ENDPOINT = "us-central1-aiplatform.googleapis.com"
const url = `https://${API_ENDPOINT}/v1/projects/${GCP_CREDS.project_id}/locations/us-central1/publishers/google/models/${MODEL}:predict`
const payload = {
instances: [
{
prompt: PROMPT
},
],
parameters: {
"candidateCount": 1,
"maxOutputTokens": 1024,
"temperature": 0.0,
"topP": 0.1,
"topK": 1,
"opt_out": true,
}
}
const params = {
method: "post",
contentType: "application/json",
headers: headers,
payload: JSON.stringify(payload),
muteHttpExceptions: true,
}
const res = UrlFetchApp.fetch(url, params)
if (res.getResponseCode() != 200) {
console.error(res.getContentText())
throw "内部エラー"
}
const res_json = JSON.parse(res.getContentText())
return res_json.predictions[0].content
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/purecss@3.0.0/build/pure-min.css"
integrity="sha384-X38yfunGUhNzHpBaEBsWLO+A0HDYOQi8ufWDkZ0k9e0eXz/tH3II7uKZ9msv++Ls" crossorigin="anonymous">
</head>
<body>
<form class="pure-form-stacked">
<h3>プロンプト</h3>
<textarea style="width:98%;" rows="10" id="prompt" class="pure-input-1" ></textarea>
<button id="run" class="pure-button pure-button-primary" onclick="generate()">実行</button>
</form>
<br>
<form class="pure-form-stacked">
<h3>回答</h3>
<p id="answer"></p>
</form>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script>
function generate() {
$("#answer").html("ただいま生成中です")
let prompt = $("#prompt").val()
google.script.run
.withSuccessHandler( function(res) {
$("#answer").text(res)
})
.GENERATE_TEXT(prompt)
}
</script>
</body>
</html>
それでは、UIからプロンプトを実験してみましょう。
まず、プロンプト実験室を開きます。
※ もしも、ここで認証ダイアログが表示された場合は、以下のa~dの手順を実施します。
a. 認証ダイアログで「OK」をクリックします。
b. 許可するアカウントを選択します。
c. 許可ボタンをクリックします。
d. もう一度、メニューの「プロンプト実験室」をクリックして、「開く」を選択します。
実験の準備ができたところで、まだ世の中に出ていない情報(永遠に発売未定の全自動掃除機「おそうじボット」)について、質問してみましょう。
おそうじボットの電源の入れ方を教えて
知っているはずのないことを、あたかも知っているかのように答えてしまっています。
これがハルシネーション(幻覚)と呼ばれる症状ですね。
では、「おそうじボット」の架空の取扱説明書に記載されている、電源のオン・オフについての情報(コンテキスト)をプロンプトに追加してみましょう。
プロンプトは以下の通りです。
# 電源のオン・オフ
## 電源をオンにする。
おそうじボットの電源ボタンを押すと電源がオンになり、おそうじボットの両目(LED)が点灯します。
## 電源をオフにする。
おそうじボットの電源ボタンを30秒以上押すと電源がオフになり、おそうじボットの両目(LED)が消灯します。
質問: おそうじボットの電源の入れ方を教えて
回答:
実行すると、以下のように正しい回答が返ってきました。
プロンプトに追加されたコンテキストを認識できているようですね。
では、コンテキストと関係のない質問として、アラームの設定方法を聞いてみましょう。
# 電源のオン・オフ
## 電源をオンにする。
おそうじボットの電源ボタンを押すと電源がオンになり、おそうじボットの両目(LED)が点灯します。
## 電源をオフにする。
おそうじボットの電源ボタンを30秒以上押すと電源がオフになり、おそうじボットの両目(LED)が消灯します。
質問: おそうじボットのアラームの設定方法を教えて
回答:
実行すると、以下のように回答が返ってきました。
またまた、ハルシネーションが起きてしまいました。
コンテキストの内容に質問と関連する情報がなかった場合でも、嘘の回答は困りますね。
その場合、どうすればいいでしょうか?
それでは、コンテキストの前に生成AIモデルへの指示を追加して、回答に使用する情報をコンテキストだけに限定させてみましょう。
以下の情報だけを使用して、質問に回答してください。
# 電源のオン・オフ
## 電源をオンにする。
おそうじボットの電源ボタンを押すと電源がオンになり、おそうじボットの両目(LED)が点灯します。
## 電源をオフにする。
おそうじボットの電源ボタンを30秒以上押すと電源がオフになり、おそうじボットの両目(LED)が消灯します。
質問: おそうじボットのアラームの設定方法を教えて
回答:
回答は以下の通りです。
これで嘘は言わなくなりましたね。
ただ、内部的な事情をそのまま質問者に伝えてしまっては、あまり都合が良くないですね。
コンテキストに関連する情報が含まれていなかった場合の回答として、質問者向けには「わかりません」とだけ答えてもらうようにしましょう。
では、指示を追加した以下のプロンプトで実行してみましょう。
以下の情報だけを使用して、質問に回答してください。
回答が見つからない場合は「わかりません」とだけ答えてください。
# 電源のオン・オフ
## 電源をオンにする。
おそうじボットの電源ボタンを押すと電源がオンになり、おそうじボットの両目(LED)が点灯します。
## 電源をオフにする。
おそうじボットの電源ボタンを30秒以上押すと電源がオフになり、おそうじボットの両目(LED)が消灯します。
質問: おそうじボットのアラームの設定方法を教えて
回答:
結果は以下の通り、「わかりません」とだけ回答してくれました。
生成AIモデルに質問する場合、ただ質問文を与えるだけでなく、プロンプトの組み立て方によって以下の効果があることがわかっていただけたかと思います。
プロンプト実験室では、質問内容に関連する情報をあらかじめ想定して、コンテキストに与えていました。
では、取扱説明書の中から質問に関連する情報をどうやって抽出すればよいでしょうか?
ちょっと長くなってしまったので、今回はここまでにしたいと思います。
次回の後編では、プロンプト実験室で題材にした「おそうじボット」について、一問一答型のアプリを作ってみたいと思います。
「活用のためのアイデア」でも触れた通り、Q&Aの精度を上げるためには色々な試行錯誤が必要です。また、データセットが大規模になるほど、精度を維持することも難しくなります。
そこで、生成AI導入やシステム構築に不安がある方向けに「Vertex AI DIYプラン」をご紹介します。
Vertex AI DIYプランでは、Vertex AI Search による、 社内文書などのエンタープライズ検索の構築をエンジニアがサポートしてくれます。
興味のある方は、一度相談してみてはいかがでしょうか?
詳細については、関連サービスの「Vertex AI DIYプラン」からご確認ください。
Vertex AI Search を使って社内文書を検索する生成AIを構築してみませんか?
ソフトバンクのエンジニアが構築をサポートします。
Google の生成AIの導入を考えている方はもちろん、どのようなものか確認したいという方でもご活用いただけます。
Google スプレッドシート、Gmail、Google カレンダー、Google Chat、Google ドライブ、Google Meet などのさまざまなサービスがあらゆる働き方に対応する業務効率化を実現します。
Google サービスを支える、信頼性に富んだクラウドサービスです。お客さまのニーズにあわせて利用可能なコンピューティングサービスに始まり、データから価値を導き出す情報分析や、最先端の機械学習技術が搭載されています。
条件に該当するページがございません