GitHubの検索欄を使う

大嶋勇樹氏:ここまでGitHub上でまずChatOpenAIクラスを探してソースコードを読んでみたわけなんですが、ChatOpenAIクラスの見つけ方自体は、ほかにもいろいろなやり方があります。

今はなんとなくLangChainのリポジトリのトップからたどって、がんばって「なんとなくここかな」と探してきたんですが、ほかの探し方としては、例えばGitHubの検索欄を使う方法が1つあります。

(画面を示して)検索欄に「ChatOpenAI」と入力して検索すると、リポジトリの中からヒットする箇所を見つけてくれます。

ただGitHub上の検索欄を使って検索する方法にはちょっと欠点があって、最新版のソースコードしか検索できないようになっています。

なんとなく「最新版だとここにあるから、自分が使っている過去のバージョンでもここにあるんじゃないかな」と推測する程度に使うことはできるんですが、見つけたものをそのまま読むと、自分の使っているバージョンは実装が違ってハマるようなこともあるので、その点はご注意ください。

目安として見つけたら、もう一度該当のバージョンに戻って、そのディレクトリを見にいくのがいいと思います。

「定義」からソースコードを読む

ほかには、Pythonのプラグインが入っていないといけないかもしれませんが、「Visual Studio Code」や「PyCharm」でChatOpenAIをimport内で使っている箇所を右クリックして「定義へ移動」とすると、ソースコードを開くことができます。

すると、ChatOpenAIのローカルにインストールした、ダウンロードした実体が開かれて読むこともできます。これはローカルの.venvというディレクトリ以下に置いているわけですが、そこのファイルは開かれているわけですね。

ちなみに、ローカルでこんなふうに開いた場合、「なんとなくここの挙動が気になる」と思ったら、printを仕込んであげると、実際に挙動が変わって、内容を表示することもできます。

grepコマンドを使う

あとはgrepコマンドを使うとかですね。例えば「grep -rn ChatOpenAI」としてChatOpenAIというキーワードを、「.venv/lib/python3.11/site-packages/langchain」としてLangChainのパッケージ以下を検索してあげると、ヒットする行が見つかります。

おそらくクラスだから、さらに「| grep class」とかしてあげれば、このクラス、ChatOpenAIがopenai.pyの131行目に定義されていることを、検索して見つけることもできます。

ここまでのポイント ソースコードをGitHubで見る時はバージョン確認が大事

ということで、ここまで最初の例として、ChatOpenAIクラスの2つの呼び出し方を見てきました。ここまでのポイントとしては、まずソースコードをGitHubで見る時は該当バージョンに切り替えるのはけっこう大事というか、特にLangChainのようにアップデートが激しいものについては、確実にやったほうがいいかなと思います。

あとはchat(messages)が、__call__という特殊メソッドの呼び出しであることや、「class ChatOpenAI(BaseChatModel)」が継承であるといったPythonの知識であったり、ローカルでエディタの定義の参照やgrepコマンドを使うのも役立つということを見てきました。

ということで、最初に簡単な例を見てきたんですが、この後もう少し、Chat APIについてLangChainで「ちゃんと」使うには、ということを見ていきます。

質問への回答

いくつか質問をもらっているので、いったん回答します。

1つもらったのが「そもそもの質問ですみません。『OpenAI Python』じゃなくてLangChainを使うメリットは何でしょうか?」ということです。今のサンプルコードであればOpenAI Pythonを使えばいいんですが、LangChainはOpenAI Pythonよりもはるかに多機能で、すごくいろいろなことができるようになっています。

なので、LLMを使ってアプリケーションを作りたい、例えば独自データにQ&Aするものを作りたいとかいろいろあると思いますが、そういう時はLangChainのほうが機能が充実していて、使えるものが多いです。

もう1つ質問をもらったのが、「なぜ同じ操作を行っているのにpredictを使用しているのでしょうか?」ということです。これはすみません、僕が呼び出し方が2つあるのを知って、「きっとこういうつながりになっているんだろうな」と想像してソースコードを見て、(それが)ちょうどこういう勉強会の題材として良かったから採用しただけですね。

あとは、LangChainの中のソースコードをいろいろ読んでいった時に、モデルの呼び出し方が場所によっていろいろ使い分けられたりしていると思うので、そういう時に「いろんな呼び出し方があるんだな」と気づくとかはありますね。質問ありがとうございます。

(次回につづく)