WindowsでJavaScript版LangChainを動かす

「ChatGPT使って何かやりたい」的なふわっとした要望のもと、OpenAI APIの検証をすることになった。

APIを素で叩くのはちょっと辛いなあと思っていたので調べると、LangChainを使うのがよさそうに思えたが、チーム内でPython使えるのが自分しかいない。

他のプログラミング言語で扱えないかと思ったところ、JavaScript版であるLangChain.jsがnpmパッケージとして提供されており、TypeScriptもサポートされているため、そちらを使うことにした。

Windowsで環境構築する場合、いくつか注意点があったのでメモ。

環境

Windows 10 Pro 21H2, Node.js 16.15.1, Yarn 1.22.19, Python 3.10.10, Git 2.39.2 にて、2023/3/13に確認。

OpenAIのAPIキーは取得済み。

サンプルプロジェクトのダウンロード

ゼロベースで環境構築するのは、画面作成などが面倒。

LangChainブログのTypeScriptサポート記事で、Next.js製のサンプルプロジェクトが紹介されていたので、そちらを利用する。

github.com

yarn create next-app langchain-example \
  -e https://github.com/sullivan-sean/chat-langchainjs

サンプルプロジェクトの設定

以降、READMEに沿って設定していく。コマンド実行にはGit Bashを使用。

READMEではパッケージマネージャーとしてYarnが使われているためそれに倣うが、npmなど他のパッケージマネージャーでも問題ないと思われる。

.env ファイルの作成

.env.example ファイルが用意されているので、これを .env としてコピー。

cp .env.example .env

2023/3/13 時点で .env ファイルの内容は OPENAI_API_KEY="" のみのため、ここにOpenAIのAPIキーを設定しておく。

npmパッケージのインストール

yarn install を実行すると、以下のエラーが発生。

gyp ERR! find Python
gyp ERR! find Python Python is not set from command line or npm configuration
gyp ERR! find Python Python is not set from environment variable PYTHON
gyp ERR! find Python checking if "python3" can be used
gyp ERR! find Python - "python3" is not in PATH or produced an error
gyp ERR! find Python checking if "python" can be used
gyp ERR! find Python - "python" is not in PATH or produced an error

LangChain.jsのREADMEにあるように、Python版のLangChainを使用しているため、Pythonのインストールが必要。仕事用PC、一度初期化してからPython入れていなかった。

任意の方法でPythonをインストールし、PATHを通すなどで実行可能にしておく。現時点のWindows 10では、Pythonがインストールされていない状態でコマンドプロンプトから python を実行すると、Microsoft StoreのPython 3.10のページが開くので、今回はそこからPython 3.1010をインストールした。

再度 yarn install すると、別のエラー。

error <PROJECT_DIR>\node_modules\hnswlib-node: Command failed.
Exit code: 1
Command: node-gyp rebuild
Arguments:
Directory: <PROJECT_DIR>\node_modules\hnswlib-node
Output:
<PROJECT_DIR>\node_modules\hnswlib-node>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules
\node-gyp\bin\node-gyp.js" rebuild )  else (node "" rebuild )
gyp info it worked if it ends with ok
gyp info using node-gyp@9.0.0
gyp info using node@16.15.1 | win32 | x64
gyp info find Python using Python version 3.10.10 found at "<AppData>\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\python.exe"
gyp ERR! find VS
gyp ERR! find VS msvs_version not set from command line or npm config
gyp ERR! find VS VCINSTALLDIR not set, not running in VS Command Prompt
gyp ERR! find VS could not use PowerShell to find Visual Studio 2017 or newer, try re-running with '--loglevel silly' for more details
gyp ERR! find VS looking for Visual Studio 2015
gyp ERR! find VS - not found
gyp ERR! find VS not looking for VS2013 as it is only supported up to Node.js 8
gyp ERR! find VS
gyp ERR! find VS **************************************************************
gyp ERR! find VS You need to install the latest version of Visual Studio
gyp ERR! find VS including the "Desktop development with C++" workload.
gyp ERR! find VS For more information consult the documentation at:
gyp ERR! find VS https://github.com/nodejs/node-gyp#on-windows
gyp ERR! find VS **************************************************************
gyp ERR! find VS
gyp ERR! configure error

URL付きで説明してくれているが、node-gypによるビルドにVisual C++ build toolsが必要。これまた初期化してからインストールしていなかった。

今回は、Chocolateyにパッケージがあったので、管理者権限で実行したコマンドプロンプトから、 cinst -y visualcpp-build-tools でインストール。

また、 npm config set msvs_version 2017 しておく必要があるとのこと。プロジェクト単位で設定したいので、 echo 'msvs_version=2017' > .npmrc.npmrc に記述する。

この状態で yarn install すると成功。

関連パッケージの更新

2023/3/13時点で、プロジェクトに設定されたLangChainおよびOpenAIパッケージのバージョンが古くなっている。

設定されているのはLangChainが0.0.15、OpenAIが3.1.0だが、最新はLangChainが0.0.29、OpenAIが3.2.1のため、 yarn add langchain@0.0.29 openai@3.2.1 でそれぞれ更新する。

すると、 pages/api/util.tsコンパイルエラーが発生。該当部分は、 const docChain の宣言時の callbackManager の部分。

callbackManager: {
  handleNewToken: onTokenStream,
}

import { CallbackManager } from 'langchain/callbacks' を追加し、 callbackManager を以下のように変更することで解消した。

callbackManager: onTokenStream
  ? CallbackManager.fromHandlers({
      handleLLMNewToken: async (token) => onTokenStream(token),
    })
  : undefined,

dataディレクトリ配下の情報の更新

この状態でも yarn dev すれば動くが、dataディレクトリに保存されているLangChainのドキュメント情報が古いため、更新を行う。

Langchain docsのダウンロード

プロジェクト直下の download.sh を実行すればいいが、 wget を使用しているため、ChocolateyなりScoopなり、バイナリをダウンロードなり、任意の方法でインストールしておく。

wget が実行可能な状態であれば、 download.sh を実行すると、Python版LangChainのドキュメントlangchain.readthedocs.io ディレクトリにダウンロードされる。

解析処理の実行

yarn ingest を実行すると、 langchain.readthedocs.io ディレクトリ配下のHTMLを解析し、結果が data ディレクトリ配下に保存されるはずだが、実行するとエラー。

Error: Wrong space name, expected "l2" or "ip".
    at Function.getHierarchicalNSW (<PROJECT_DIR>\node_modules\langchain\src\vectorstores\hnswlib.ts:53:12)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at HNSWLib.initIndex (<PROJECT_DIR>\node_modules\langchain\src\vectorstores\hnswlib.ts:61:20)
    at HNSWLib.addVectors (<PROJECT_DIR>\node_modules\langchain\src\vectorstores\hnswlib.ts:85:5)
    at Function.fromDocuments (<PROJECT_DIR>\node_modules\langchain\src\vectorstores\hnswlib.ts:195:5)
    at run (<PROJECT_DIR>\ingest.ts:77:23)
    at <anonymous> (<PROJECT_DIR>\ingest.ts:82:3)
error Command failed with exit code 1.

hnswlibがサポートするDistanceに cosine が追加されたが、hnswlib-nodeが古いため対応していない模様。

github.com

該当のソースコードnode_modules/langchain/dist/vectorstores/hnswlib.js 。0.0.15では ip が指定されていたが、0.0.29では cosine に変更されていた。

2023/3/13時点で、最新のhnswlib-nodeは1.4.2のため、 yarn add hnswlib-node@1.4.2 で更新すると、 yarn ingest が成功するようになった。

注意点として、解析中に fetch が実行されるため、Node.js v18未満の場合、 NODE_OPTIONS='--experimental-fetch' yarn ingest のように、 --experimental-fetch オプションをつけて実行する必要がある。

サンプルプロジェクトの実行

yarn dev し、 localhost:3000 を開く。

メッセージとして Hi there! How can I help? が表示されていれば成功。画面下の入力欄から質問をすることが可能。

自己紹介をさせてみた

pages/api/util.ts にプロンプトが記載されている。回答は Answer in Markdown: のため、Markdown形式となる。

なお、モデルとしては、 OpenAIインスタンス生成時に modelName を指定していないため、デフォルトの text-davinci-003 が使用される。

振り返り

Python版LangChainのビルドにもろもろ準備が必要だが、それ以外はスムーズに環境構築できた。

wget でダウンロードするURLを変更し、 ingest.ts での解析対象のディレクトリ名を変えて yarn ingest を実行、 pages/api/util.ts のプロンプトを変更してやるだけで、それっぽいふるまいをするようになる。

なんというか、すごい時代になったなぁ...

余談

LangChainの質問を投げていると、URL付きで自信満々っぽく回答してくれるが、回答内容が間違っていたり、URLも404だったりして笑う。

一度、存在しないメソッドの説明をしてくれたこともあった。

プロンプトで以下のように指定されているが、効いてないんだろうか。

You should only use hyperlinks that are explicitly listed as a source in the context. Do NOT make up a hyperlink that is not listed.
If you don't know the answer, just say "Hmm, I'm not sure." Don't try to make up an answer.