2026-02-28
#AI #js 
たった3.3Gのメモリでそこそこ文章生成できるGemma3(ジェマスリー)、なんと入力トークンも128KBもいけるので簡単なRAGを実験してみました。(入力トークン上限は ollama show gemma3:4b でチェックできます)

RAGとは、検索拡張生成(Retrieval-augmented generation)の略で、質問時に、学習済みのモデルに質問に合わせた特定の知識を入力に加えて生成させる方法のこと。

質問に合わせた知識の検索にローカルエンベディングが役立ちます。知識を1行ずつまとめたテキストファイルとしておき、事前にベクトル化。質問をエンベディングしたベクトルとの距離が近い順にいくつか取り出し根拠として加えて、下記のようなプロンプトで文章を生成することで、特定の知識を使った回答になります。

あなたは根拠に基づき回答するアシスタントです。 以下の根拠を使って端的に答えてください。 文脈に沿わない根拠は使う必要はありません。 # 質問 ${q} # 根拠 ${top.map((i, idx) => `[${idx + 1}] ${i.text}`).join("\n")} # 回答

実際にやってみます。

$ deno --allow-read --allow-import --allow-net rag.js Wirthで文字列の足し算できる? あなたは根拠に基づき回答するアシスタントです。 以下の根拠を使って端的に答えてください。 文脈に沿わない根拠は使う必要はありません。 # 質問 Wirthで文字列の足し算できる? # 根拠 [1] 文字列の算術演算は「+」のみ使用することができます。 [2] 文字列は、文字の並びを「"」でくくって表します。 [3] 条件分岐文、順次繰返し文、条件繰返し文をまとめて制御文と呼びます。 [4] 比較演算やそれを組み合わせる論理演算は、条件分岐文や条件繰返し文の条件として使うことができます。 [5] 代入文は変数に値を設定します。「<-」(アサイン)の左辺に変数または添字付きの配列を、右辺に代入する値を書きます。 [6] [」「]」と「,」を使用し、要素の値をまとめて代入できます。 # 回答 はい、「+」のみ使用して文字列の足し算ができます。

ちゃんと、根拠に基づき、回答してくれました!
data.txtの書き方を工夫することで、精度はもっともっと高められるでしょう。

いろいろ応用できそうですね!

links
- ローカルAIに問い合わせよう、ask
- MacBookAirで動くローカルAI、gemma3で画像からキーワードを生成しよう、askimg
- ローカルで処理するEmbedding by nomic-embed-text and ollama
- 福井県観光スポットで似たもの探し with Embedding API by OpenAI

クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS