はじめに
この記事はブラウザ上でローカルLLMと対話したい#2|ローカルHTTPサーバーの続き
今回はローカルのOllamaサーバーにAPIリクエストを送り、その結果を表示する部分を実装する
javascriptを別ファイルに書き出す
#1の時点では、1個のhtmlファイルにjavascriptも書いていたが、ここからは別でtest.jsというファイルをjsディレクトリ配下に作成し、作業していく
そこで、htmlファイルは以下のように書く
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LLM Chat</title>
</head>
<body>
<input type="text" id="inputmsg"> <!--入力ボックス-->
<button type="button" id="send">送信</button><!--送信ボタン-->
<div id="messages"><!--メッセージ領域-->
</div>
<script src="js/test.js" charset="utf-8"></script>
</body>
</html>
<script src=”js/test.js” charset=”utf-8″></script>の部分がjavascriptを呼び出す部分
jsファイルを相対パスで指定している
ソースコード
全体像
今回はchat関数の追加が主な変更点
async function chat(message) {
const url = 'http://127.0.0.1:11434/api/chat';
const data = {
model: "Llama-3.1-Swallow-8B-Instruct-v0.1_Q4_K_M",
messages: [{ role: "user", content: message }],
stream: false
};
// 非同期なHTTPリクエストを送信
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
const result = await response.json();
return result.message;
}
const inputMsg = document.getElementById('inputmsg');
const sendBtn = document.getElementById('send');
const messagesDiv = document.getElementById('messages');
sendBtn.addEventListener('click', async () => {
const message = inputMsg.value.trim();
// messagesに送信メッセージを追加
const userMessageEl = document.createElement('div');
userMessageEl.textContent = message;
messagesDiv.appendChild(userMessageEl);
// 入力をクリア
inputMsg.value = '';
// messagesに返信メッセージを追加
// chat関数が完了するまで待つ
const result = await chat(message);
const systemMessageEl = document.createElement('div');
systemMessageEl.textContent = result.content;
messagesDiv.appendChild(systemMessageEl);
});
chat関数
入力メッセージを受け取り、返信メッセージを返す非同期関数
async function chat(message) {
const url = 'http://127.0.0.1:11434/api/chat';
const data = {
model: "Llama-3.1-Swallow-8B-Instruct-v0.2_Q4_K_M",
messages: [{ role: "user", content: message }],
stream: false
};
// 非同期なHTTPリクエストを送信
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
const result = await response.json();
return result.message;
}
dataは辞書型の変数、modelでLLMのモデルを指定する
指定したモデルはLlama 3.1 SwallowをOllamaで使えるようにする|ローカルLLMで追加したモデルの現時点での最新バージョン
ここはOllamaに入っている各自のモデルを指定すればよい
fetchで非同期なHTTPメソッドを送信する
これの前にawaitをつけることで、処理が完了するまで先へ進まないようにしている
responseはサーバーからの応答をjson形式で受け取る
これも非同期処理なので、awaitで応答を待つ(処理が完了するまでは、reultにはPromiseが格納される)
もし待たなければ、最後のresult.messageでエラーが起こる
実行画面
ローカルサーバーを立ててブラウザでファイルを開く方法については前回の記事を参照
$ npx http-server
Ollamaのサーバーも別のターミナルを開いて立てる
$ ollama serve
(参考)OllamaのPythonライブラリを使ってローカルLLMを利用する
ローカルホストのページをブラウザで開いて、メッセージを送信する
これで、超簡易的ではあるが、ローカルLLMとメッセージのやりとりがブラウザ上でできるようになった
なお、会話履歴はLLMに送っていないので、応答は前のメッセージの内容を反映していない
今後の予定
さらに改善するための例を一部挙げる
- 会話履歴を反映した会話
- 表示画面などのUI改善
- Enterキーで送信する機能の追加