2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
大嶋勇樹氏:ということで、ざっと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の過去バージョンは確認しよう ネット上では公開されていないドキュメントの見つけ方
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術
2024.12.11
大企業への転職前に感じた、「なんか違うかも」の違和感の正体 「親が喜ぶ」「モテそう」ではない、自分の判断基準を持つカギ
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦