LocalLens
アーキテクチャ

全体パイプライン

フォルダがディスクから根拠付き回答に変わるまでの道のり。

LocalLens はフォルダと質問を受け取り、引用付きの回答を返します。 その 2 点の間にあるのは、小さく固定されたパイプラインだけです。

インデックス用パイプライン

インデックス処理は brain を作成するときに 1 回だけ走ります。

コード上のステップは次のとおりです。

  1. discoverTextDocuments(rootPath)(src/files.ts)はフォルダを 走査し、安全なテキストファイル以外をふるい落として LocalDocument[] を返します。
  2. chunkDocuments(documents, { brainId })(src/rag.ts)は ragChunk を呼んで各ドキュメントを約 220 トークンのチャンクに分割 (40 トークンのオーバーラップ付き)し、TextChunk[] を返します。
  3. QvacGateway.ingestChunks(workspace, chunks)(src/qvac.ts)は 各チャンクを GTE_LARGE_FP16 で embedding に変換し、名前付きの QVAC ワークスペースに書き込みます。
  4. LocalLensStore.saveBrainsaveChunks(src/store.ts)が brain とそのチャンクを .locallens/store.json に保存します。

最初の 3 ステップは入力フォルダを対象に動きます。4 つ目は brain の レコードを残すための処理で、次回アプリを開いたときに再インデックス なしで質問できるようにするためのものです。

質問用パイプライン

すべてのチャット往復は同じ 4 ステップをたどります。

コード上では次のようになります。

  1. QvacGateway.search(workspace, question, 5)(src/qvac.ts)は 質問を embedding にして ragSearch を実行し、上位 5 件の SearchHit[] を返します。
  2. buildGroundedHistory(question, hits)(src/rag.ts)は、 システムルールと番号付き抜粋を含む 2 メッセージ構成の ChatMessage[] を生成します。
  3. QvacGateway.answer(history)(src/qvac.ts)は QVAC の completion()stream: true で呼び出し、各 contentDeltaAsyncGenerator<string> として yield します。
  4. LocalLensApp.askBrain(src/locallens.ts)がストリームを蓄積し、 { answer, citations } を返します。

各ステップの所在

工程モジュール主な呼び出し
ファイル検出src/files.tsdiscoverTextDocuments
チャンク化src/rag.tschunkDocumentsragChunk
Embedding と取り込みsrc/qvac.tsingestChunksragIngest
永続化src/store.tssaveBrain, saveChunks
検索src/qvac.tssearchragSearch
プロンプトsrc/rag.tsbuildGroundedHistory
テキスト生成src/qvac.tsanswercompletion
ワークフローsrc/locallens.tsLocalLensApp.askBrain

このパイプラインに含まれないもの

  • 質問パスでの再取り込みなし。 質問するときにファイルシステムや JSON ストアに触ることはありません。QVAC のワークスペースを読むだけです。
  • 質問ごとに 2 度目のモデル呼び出しはなし。 チャットモデルとの往復は 1 回。検索用の embedding 呼び出しが質問ごとに 1 回。それだけです。
  • 会話状態を保持しない。 各質問は独立した検索ラウンドです。チャット 履歴は毎回ゼロから組み立てられ、その質問に対する検索結果のみを 根拠とします。

最後の性質が、フォローアップの回答を根拠から外させない理由です。 マルチターンの対話が必要なら、buildGroundedHistoryに組み立てて ください。中に入れてはいけません。RAG と LLM の章で理由を説明しています。

次へ

On this page