ブラウザ上でローカルLLMと対話したい#5|class属性を追加する

3 アクセス

はじめに

この記事はブラウザ上でローカルLLMと対話したい#4|対話履歴の追加のつづき
前回でテキスト対話システム部分はたぶんほぼ完成なので、今回から見た目を整えていく

class属性とは

class属性とは、HTMLタグに追加できる属性の1種

  • cssやjavascriptの要素選択に使用
  • 1つの要素に複数のクラスを割り当てられる
  • 1つのクラスを複数の要素で共有できる

今回は、メッセージがユーザから発せられたのか、システム側から発せられたのかを区別するために使用する

class属性を追加

下記は、ユーザの入力メッセージを処理する部分の一部
(全体のソースコードはこの記事の最後に記載)

const message = inputMsg.value.trim();

// messagesに送信メッセージを追加
const userMessageEl = document.createElement('div');
// 送信メッセージにuser-messageクラス属性を追加
userMessageEl.classList.add('user-message');
userMessageEl.textContent = message;
messagesDiv.appendChild(userMessageEl);

// dialogueに送信メッセージを追加
dialogue.push({ role: "user", content: message});

今回追加したのは5,6行目の部分
要素にclass属性を追加するには、classList.add(クラス名)とする
今回はクラス名を’user-message’とした

システム側のメッセージにも同様に、’system-message’ class属性を追加しておく

cssでレイアウト

cssの書き方についてはこれから勉強が必要なので今回は簡単に、ユーザメッセージを右、システムメッセージを左にするように配置を指定するのみにした

jsファイル同様に、cssファイルを別で書くこともできるが、今回はhtmlのhead部分に追加した
記述するには<style>タグで囲った部分

クラス属性から要素を指定するには、.(ドット)クラス名とする
(例).user-message

サンプルコード

.user-message {
    text-align: right;
    margin-bottom: 10px;
}
.system-message {
    text-align: left;
    margin-bottom: 10px;
}

text-alignでテキストを右詰めか左詰めかを指定している
margin-bottomは余白の調整用

実行例

ユーザの入力が右、システムの返信が左に表示されていることがわかる
(LLMの発言内容はとんでもない間違いだが、正しい知識がなければ信じそうになるのが怖い)

おわりに

もっとcssデザインにこだわるポイントはありそう

ソースコード

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>LLM Chat</title>
    <style>
        .user-message {
            text-align: right;
            margin-bottom: 10px;
        }
        .system-message {
            text-align: left;
            margin-bottom: 10px;
        }
    </style>
</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>
// npx http-server
// ollama serve
// をあらかじめ実行

async function chat(dialogue) {
    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: dialogue,
        stream: false
    };
    console.log(data)

    // 非同期な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');

// 対話履歴を保持する配列
const dialogue = [];

sendBtn.addEventListener('click', async () => {
    const message = inputMsg.value.trim();

    // messagesに送信メッセージを追加
    const userMessageEl = document.createElement('div');
    // 送信メッセージにuser-messageクラス属性を追加
    userMessageEl.classList.add('user-message');
    userMessageEl.textContent = message;
    messagesDiv.appendChild(userMessageEl);

    // dialogueに送信メッセージを追加
    dialogue.push({ role: "user", content: message});

    // 入力をクリア
    inputMsg.value = '';

    // messagesに返信メッセージを追加
    // chat関数が完了するまで待つ
    const result = await chat(dialogue);
    
    const systemMessageEl = document.createElement('div');
    // 受信メッセージにsystem-messageクラス属性を追加
    systemMessageEl.classList.add('system-message');
    systemMessageEl.textContent = result.content;
    messagesDiv.appendChild(systemMessageEl);

    // dialogueに返信メッセージを追加
    dialogue.push({ role: "assistant", content: message});

});

Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です