
2025.02.12
職員一人あたり52時間の残業削減に成功 kintone導入がもたらした富士吉田市の自治体DX“変革”ハウツー
リンクをコピー
記事をブックマーク
大嶋勇樹氏:ということで、ざっとOpenAIのChat APIについて復習してきましたが、ここからはLangChainでのOpenAIのChat APIの使い方の基本を見ていきます。
まずそもそものLangChainについて簡単に紹介すると、LangChainは大規模言語モデルを使ったアプリケーション開発のフレームワークです。実装としてはPythonとJavaScript、TypeScriptの2つがあります。機械学習関連分野によくあることですが、Pythonのほうがやはり開発は活発です。
今日もPythonを使って、3日前(登壇時点)のリリースのバージョンを使っていきます。LangChainはほぼ毎日新しいバージョンがリリースされているので、今はたぶん(バージョン)218とかまで出ているんじゃないかと思いますが、3日前のバージョンを使わせてもらいます。
LangChainは要約やチャットボット、ドキュメントへのQ&Aなど、LLMを使ったさまざまなアプリケーションで活用できるフレームワークとなっています。
そんなLangChainですが、モジュールがいろいろ整理されています。現在だとLanguage modelsやPrompt templates、Chain、Data connection、Memory、Agentsと、大きなモジュールの整理があって、その中にたくさんクラスが存在するように実装されています。
そして、このLangChainで先ほど紹介したOpenAIのChat APIを使う時は、ChatOpenAIというクラスを使います。
このあたりはドキュメントを見ていくともちろん載っていることではありますが、LangChainでChatOpenAIを使う時は、実装方法が2つあります。
スライドだと見にくいかもしれないので、コードを実際に見てみようと思います。(画面を示して)これがLangChainでChatOpenAIというクラスを使ってgpt-3.5-turboのモデルを呼び出す、使う例です。
下の部分はいったんコメントアウトします。
messagesとして、リストの形式でHumanMessage、つまり人間側のメッセージとして「content="Hello!"」「Hello!」と言います。それをchat(messages)のように、APIを呼び出して結果を表示しています。これを実行してみようと思います。
このコードを実行すると……。実行結果は毎回多少違う可能性はありますが、gpt-3.5-turboからの応答が返ってきますね。「Hello!」に対して、「Hello! How can I assist you today?」ということで、こんな応答が返ってきます。これがLangChainでgpt-3.5-turboを呼び出す、すごくシンプルなコードです。
実は呼び出し方はほかにもあります。このほかにも、下に書いてあるように、「chat = ChatOpenAI」に対してchat(messages)と呼ぶ代わりに、chat.predictのように呼び出すこともできます。上側をコメントアウトして、呼び出せることをもう一度実行して確認してみようと思います。
たまたまtemperatureが0というのもあって同じような応答が返ってきましたが、この「.predict」という呼びだし方もできるんですね。chat(messages)でもchat.predictでも、このChatOpenAIは呼び出せます。
実はこれが同じような挙動になっているということを、LangChainのソースコードリーディングのまあまあ簡単ではありますが、1つの例として見ていこうと思います。
(画面を示して)まず、コードが2種類使えるということを見て思うことは、上の「HumanMessage(content="Hello!")」については、おそらく内部で「"role": "user", "content": "Hello!"」みたいに組み立てられて実行されています。
一方で下のpredictについては、HumanMessageのような……。このメッセージが人間のメッセージなのか……。HumanMessage以外にAIMessageでも使えるんですが、そういうのを指定せずに呼んでいます。なので、たぶん内部で勝手にHumanMessageと解釈されて、上と同じような呼び出しになっているんじゃないかと想像できるかと思います。
本当にそうなっているかを、ソースコード上で見ていこうと思います。比較的簡単なテーマではありますが、ソースコードを読むにあたってChat APIの形式がわかっていると、なんとなくこの呼び出し方は疑問に思います。もしもどういうことをやろうとしているかイメージがつかないなどあれば、Q&Aなどに質問をもらえれば、少し補足します。
いったんこのテーマでLangChainのソースコードを読んでみようと思います。ここからは資料はなく、実際に画面にLangChainのソースコードを映しながらやっていきます。
(画面を示して)ソースコードを読む時に、やり方はいろいろありますが、まずはGoolge検索で「LangChain GitHub」と検索してみることにします。公式のLangChain……。公式というか、LangChainの「GitHub」のリポジトリが見つかりますね。
ソースコードを読む時にローカルで読むか、GitHubで読むか。人によってやり方はいろいろありますが、GitHub上で見ていくのも楽なので、まずはGitHub上で見ていこうと思います。
今質問をもらっていますが、急ぎじゃなくてもよさそうな内容だと思うので、いったん進めて、いいタイミングで回答できればと思います。
まずGitHub上でこのChatOpenAIクラスの呼び出し方を見ていこうと思いますが、この時どうするか。最初の一歩をどうするかは、いろいろなやり方があると思います。例えばGitHubの検索欄で検索するとか、ソースコードのツリーを見ていくとか、いろいろあると思いますが、特にLangChainのようなアップデートの激しいものを扱う上で僕がお勧めしたいのは、まずはバージョンを合わせることですね。
まずバージョンを合わせるのが一番ポイントだと思います。(今回は)0.0.219ですね。4時間前に最新版がリリースされて、今(画面に)表示されているのは0.0.219か、さらに新しいバージョンです。0.0.219のリリースのところが表示されているので、まずはGitHubのReleasesから、少し過去のバージョンをたどっていきます。
先ほどのサンプルコードで使っているのは0.0.215なので、0.0.215のタグマークをクリックすると、GitHubのトップページ的な、ソースツリーのトップになります。
ここがv0.0.215、URLもv0.0.215となって、その時点のソースコードのツリーの表示になっています。この状態でChatOpenAIクラスの呼び出し方を見ていきます。いったん確認してみると、このChatOpenAIクラスは「from langchain.chat_models」とimportしています。
importしているパスにもヒントになることがけっこうあったりしますね。実際にLangChainのソースツリーのトップを見ると、重要なソースコードは、おそらくlangchain以下にありそうだなと(わかります)。ここを見ていきます。
するといろいろなモジュール、ディレクトリに括られているわけですが、chat_modelsというディレクトリが見つかるので、これを見てみます。
エディタなどのように左側にも出ていますね。langchain以下のchat_models以下を開いてみました。
この中に、ChatOpenAIクラスがあるんじゃないかと当たりをつけて見ていこうと思います。(画面を示して)これを見ると、openai.pyにあるんじゃないかとなんとなく思えると思います。もっと確実に検索したりして、ちゃんと探す方法も後で説明しようと思いますが、僕は「なんとなくここにありそうだな」という当たりをつけて見ていくこともよくあります。
openai.pyを開くと、右側にどんなクラスがあるかとか……。最近のGitHubはこのあたりをわかりやすく出してくれるんですが、ChatOpenAIクラスがあることが出ていますね。
実際に下側を見ていくか右をクリックすると、openai.pyにChatOpenAIというクラスがあることがわかりました。(画面を示して)こんなふうに、ChatOpenAIクラスを見つけられました。
今の目標は、このchat(messages)とchat.predictがどんな対応にあるかを見ていきたいわけですが、まずchat(messages)から見ていこうと思います。
このchat(messages)は、文法的にPythonの何なのかが1個の大事な要素です。これはPythonの実践入門みたいな本とかを読んだことがあれば知っていることだと思うんですが、chat.__call__というものと同じですね。
このchat(messages)は、call、特殊メソッドといったりしますが、これを呼び出しているわけです。これが省略されているようなものです。(画面を示して)実際にこうやって書いてあげても動くはずです。同じような応答が返ってきますね。
このChatOpenAIのインスタンスに対するchat(messages)という呼び出しは、実は__call__というメソッドの呼び出しでした。なので、ChatOpenAIの__call__というメソッドを探していきたいわけです。そうすれば、実装が見つかるはずです。
GitHubの設定次第だったかもしれませんが、GitHubを使っていると、シンボルの一覧みたいなものが右側に出て、ChatOpenAIクラスに定義されているメソッド、defで定義されている関数を見ることができますが、__call__は見当たりません。
これはなぜかというと、ChatOpenAIはBaseChatModelを継承しているからです。BaseChatModelを継承、拡張して、ChatOpenAIになっているからですね。
なので、ここではBaseChatModelという親のクラスを見にいきます。(画面を示して)最近のGitHubは、選択すると右側の定義に移動するようなリンクが表示されるので、これでBaseChatModelを見ていきます。
隣のタブで開きました。(画面を示して)こんなふうに「class BaseChatModel」が「langchain/chat_models/base.py」というファイルにあることがわかりました。
このBaseChatModelに探していた__call__というメソッドがあるかを見ると……。ありますね。定義されています。
List[BaseMessage]のBaseMessageは、HumanMessageやAIMessageなどが含まれるものですが、__call__はmessagesや、(その他にも)必要に応じていろいろ追加で受け取って、いろいろ実行されていきます。
その中ではgenerateという別のメソッドを呼び出したりしていて、さらにgenerateを深掘りしていくと、「このgenerateの中で実際の文書の生成のAPIを呼んでいそうだな」ということがなんとなく推測できます。
ということで、chat(messages)は__call__という特殊メソッドの呼び出しで、親クラスに(あることを)見つけられました。今度は、これと比較したい、もう1つの呼び出し方のpredictを見ていきます。
predictについても、まずはChatOpenAIクラスの中にpredictというメソッドがあるか見ようとすると、やはりこれもないんですね。
predictについても実は親クラスのほうにあるんじゃないかなと思って、ChatOpenAIの親クラスのBaseChatModelをもう一度見にいきます。BaseChatModelのメソッドを探してみると、predictがありますね。
このpredictが、textという引数を文字列型で受け取るように、こんなふうにタイプヒントが書かれていますね。
そしてその中で処理しています。「self([HumanMessage(content=text)], stop=_stop, **kwargs)」となっていますね。このself()はself.__call__と同じですね。これは__call__という特殊メソッドの呼び出しです。
つまり、chat.predictは、中でchat(messages)をやっていることが、ソースコードで読み取れました。
確かに受け取った文字列をHumanMessageに詰め込んで、__call__のほうの特殊メソッドを呼んでいる挙動になっていますね。
ということで、最初の一歩として比較的シンプルな例ですけれども、ChatOpenAIクラスの2つの呼び出し方がちゃんと中の実装で互換性があるというか、もう一方の呼び出しに対応しているのを見てきました。
(次回につづく)
関連タグ:
大嶋勇樹氏が解説する「OpenAIの文書生成API」の基本 モデルの種類、APIの種類と違い、今使うべきもの
「chat(messages)」と「chat.predict」は同じ挙動を示すのか? ChatOpenAIクラスの2つの呼び出し方の互換性
「GitHub検索欄を使う」「定義から見る」「grepコマンドを使う」 「ソースコードを読む」以外のChatOpenAIクラスの見つけ方
LangChainの「Chain」や「Agent」を使う時は注意が必要 「Chat APIの形式を活かした実装かどうか」の確認方法
時間を溶かさないためにもLangChainの過去バージョンは確認しよう ネット上では公開されていないドキュメントの見つけ方
2025.02.06
すかいらーく創業者が、社長を辞めて75歳で再起業したわけ “あえて長居させるコーヒー店”の経営に込めるこだわり
PR | 2025.02.07
プロジェクトマネージャーは「無理ゲーを攻略するプレイヤー」 仕事を任せられない管理職のためのマネジメントの秘訣
2025.02.04
日本企業にありがちな「生産性の低さ」の原因 メーカーの「ちょっとした改善」で勝負が決まる仕組みの落とし穴
2025.02.05
「納得しないと動けない部下」を変える3つのステップとは マネージャーの悩みを解消する会話のテクニック
2025.02.06
落合陽一氏や松尾豊氏の研究は社会に届いているか? ひろゆき氏が語るアカデミアの課題と展望
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.02.05
エンジニアとして成功するための秘訣とは? ひろゆき氏が語る、自由な働き方を叶えるアプリ開発とキャリア戦略
2025.02.03
手帳に書くだけで心が整うメンタルケアのコツ イライラ、モヤモヤ、落ち込んだ時の手帳の使い方
2025.02.03
「昔は富豪的プログラミングなんてできなかった」 21歳で「2ちゃんねる」を生んだひろゆき氏が語る開発の裏側
2025.02.10
A4用紙を持ち歩いて殴り書きでアウトプット コクヨのワークスタイルコンサルタントが語る、2種類のメモ術
【手放すTALK LIVE#45】人と組織のポテンシャルが継承されるソース原理 ~人と組織のポテンシャルが花開く「ソース原理」とは~
2024.12.09 - 2024.12.09
【著者来館】『成果を上げるプレイングマネジャーは「これ」をやらない』出版記念イベント!
2025.01.10 - 2025.01.10
片付けパパ対談【特別編】 整理術×行動術×メモ術で、仕事も人生も自在にデザイン!
2024.12.16 - 2024.12.16
日本を変える 中小企業リーダーズサミット2025
2025.01.30 - 2025.02.12
【必見】納得しない部下を動かす!マネジメントの裏技とは?
2024.12.16 - 2024.12.16