なぜ QVAC か
ほとんどの仕事をこなしている 5 つの SDK 呼び出しと、それが 1 つのパッケージにまとまっている理由。
QVAC は LocalLens のローカル AI ループを 動かしている SDK です。この規模のプロジェクトで興味深いのは、本来なら 5 つの別ライブラリを引っ張ってくることになる 5 つの仕事を、1 パッケージで 扱える点です。
使っている 5 つの SDK 呼び出し
import {
loadModel,
ragChunk,
ragIngest,
ragSearch,
completion,
// and the lifecycle helpers:
ragCloseWorkspace,
ragDeleteWorkspace,
close,
} from "@qvac/sdk";| 呼び出し | 使用箇所 | 役割 |
|---|---|---|
loadModel | src/qvac.ts → ensureReady | 埋め込みモデル(GTE_LARGE_FP16)とチャットモデル(QWEN3_1_7B_INST_Q4、600M フォールバックあり)を読み込む。 |
ragChunk | src/rag.ts → chunkDocument | ドキュメントテキストを約 220 トークン幅、40 トークンのオーバーラップで分割する。 |
ragIngest | src/qvac.ts → ingestChunks | チャンクを embedding にし、名前付きワークスペースに保存する。 |
ragSearch | src/qvac.ts → search | クエリを embedding にし、上位 K 件のチャンクを返す。 |
completion | src/qvac.ts → answer | 読み込み済みモデルからチャット出力をストリーミングする。 |
ragCloseWorkspace | src/qvac.ts → closeWorkspace | ディスク上のワークスペースを閉じる(必要なら削除する)。 |
close | src/qvac.ts → close | アプリ終了時に QVAC ランタイムを片付ける。 |
LocalLens が使っているのはこれで全部です。手動の embedding ループも、 別建てのベクトルデータベースも、独自のトークン分割器もありません。
モデルのライフサイクル
QVAC のモデルは遅延的に、最初に使われたタイミングで読み込まれます。
private async ensureReady(): Promise<void> {
if (this.chatModelId && this.embeddingModelId) return;
this.readyPromise ??= this.loadModels().finally(() => {
this.readyPromise = undefined;
});
await this.readyPromise;
}知っておくと役立つ帰結が 2 つあります。
- コールドスタートのコストは最初の質問にかかり、起動時にはかかりません。
これで
bun run devの起動が速く保たれ、UI 側で「モデルを読み込み中…」の 表示をかけるきっかけが明確になります。 - 同時呼び出しは 1 つの読み込みを共有します。 全ての呼び出し元は同じ
readyPromiseを await します。同じティックに 2 つのリクエストが 届いても、同じソースに対してloadModelが二重に走ることはありません。
フォールバックモデルがある理由
デフォルトのチャットモデルは QWEN3_1_7B_INST_Q4 です。古いマシンや
小さいマシンでは読み込みに失敗することがあります。ゲートウェイは
それを捕捉して QWEN3_600M_INST_Q4 にフォールバックします。
try {
this.chatModelId = await loadModel({ modelSrc: QWEN3_1_7B_INST_Q4, modelConfig });
} catch {
this.chatModelId = await loadModel({ modelSrc: QWEN3_600M_INST_Q4, modelConfig });
}フォールバックは呼び出し元からは見えません。QvacGateway.answer は
どちらの場合でも同じストリーミングシグネチャを返します。
なぜ 1 つの SDK に集約するのか?
LocalLens は embedding に @xenova/transformers、ベクトルに chromadb や
qdrant、テキスト生成に llama.cpp を使うこともできました。それぞれ
単独では良い選択肢です。3 つ全部を使う場合のコストは、それらを統合する
グルーコード、つまりモデルのライフサイクル、ワークスペースの
ライフサイクル、エラーマッピング、非同期イテレーションを自分で書くこと
です。QVAC はそれらを最初から提供します。このアプリが 8 ファイルに
収まっている理由の大半はそこにあります。
関連する上流のページ
- QVAC RAG リファレンス —
ragChunk、ragIngest、ragSearch。 - QVAC completion リファレンス — ストリーミング、KV キャッシュ、thinking のキャプチャ。
- QVAC モデルカタログ — 対応モデル ID。