「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製のサンプルプロジェクトが紹介されていたので、そちらを利用する。
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が古いため対応していない模様。
該当のソースコードは 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.