Prompt API を使うサンプル
はじめに
Prompt API は、 Chrome 148 でサポートされたローカル LLM です。
次の条件を満たした場合に使用できます。
22GB 以上の空き容量、
4GB 以上の VRAM を持つ GPU、
または 16GB RAM 4コア以上の CPU で利用できます。
もちろん、Chrome 以外のブラウザ(Firefox 等)では利用できません。ただし、今後どうなるかはわかりません。また、Edge 等の Chromium 系ブラウザでは flags の設定等で動作するようになる場合があるようです。
Chrome では、対象端末には設定不要で強制的に導入されたため、一時期 4GB のクソデカダウンロードを強要することが話題になりました。
サンプル
仕様
- AI への入力をサーバーに転送しません
- ローカル LLM であるため、対象端末の CPU/GPU を使用して動作します。
- ブラウザの設定しだいでは、
- Chat形式で動作します
- 日本語の入力・出力を想定しています。
- 逐次出力します。
- 過去の入力・出力を保持します。
- コンテキストウィンドウが溢れた場合、エラー停止します。
個人的な考察等
CPU/GPU 使用率が極めて高くなる。ユーザー環境が際立って高性能でもない限り、実行中の他機能への影響が大きい。そのため、裏でこっそり利用するような使い方は殆どできない。
翻訳や要約等の簡易な処理に限定したとしても要求マシンパワーやスマホ等の実行不可能環境を加味すれば、外部APIを叩いたほうが現実的に思える。
現状ではユーザーが暗黙的に実行を許可するような環境下でしか利用できないと考える。
今後の展望として、簡易AIアプリの実装等に利用できるのではないか?
例えば、次のような使い方が考えられる。
- 簡易チャット風AI
- キャラクターとの会話
- 要約・翻訳
- Chrome 拡張機能でポップアップでページ要約を表示する
- 適当な文章を「ビジネス文章」「SNS投稿用文章」に変換する
- 利用規約や法律文章等の機密性高い対象の簡易解析
- オフラインや通信不安定環境での補助機能
- ウェブページの自動操作(現状では難しい)
サンプルコード
const input = document.getElementById('input');
const output = document.getElementById('output');
let session = null;
let isGenerating = false;
// モデルの取得
async function getSession() {
if (session) { return session; }
const availability = await LanguageModel.availability({
expectedInputs: [{type:'text', languages:['ja']}],
expectedOutputs:[{type:'text', languages:['ja']}]
});
if (availability === 'unavailable') {
throw new Error('この環境では Prompt API を利用できません。');
}
session = await LanguageModel.create({
expectedInputs: [{type:'text', languages:['ja']}],
expectedOutputs:[{type:'text', languages:['ja']}],
monitor(monitor) {
monitor.addEventListener('downloadprogress', (event) => {
//const percent = Math.round(event.loaded * 100);
//output.textContent = 'モデルを準備しています: '+percent+'%';
});
}
});
return session;
};
// プロンプトの実行
async function executePrompt(prompt) {
if (isGenerating) { return; }
isGenerating = true;
input.disabled = true;
if (session) {
output.textContent += '----------------------------------------\n\n';
}
output.textContent += 'あなたの質問:\n'+prompt+'\n\n';
output.textContent += 'AI の回答:\n';
try {
const currentSession = await getSession();
const stream = currentSession.promptStreaming(prompt);
for await (const chunk of stream) {
output.textContent += chunk;
}
output.textContent += '\n';
} catch (error) {
console.error(error);
output.textContent += '\n\nエラー: '+error.message+'\n\n';
} finally {
input.disabled = false;
input.focus();
isGenerating = false;
}
};
// Enter 入力時に実行する(Shift+Enterで改行する)
input.addEventListener('keydown', (event) => {
if (event.key !== "Enter" || event.shiftKey || event.isComposing) {
return;
}
// textarea に改行が入力されるのを防止
event.preventDefault();
const prompt = input.value.trim();
if (prompt) {
input.value = '';
executePrompt(prompt);
}
});