はじめに
あっなったっの アーイドル〜♪
ナイスなstapyでした! nikkieです。
最近触っているLangChain、触るたびにこれはすごいライブラリだと実感します。
小さい箇所ですが、langchain.verbose = True
と指定するだけで、プロンプトが出力され、何が起こっているかの理解にとても役立ちます1。
このlangchain.verbose
とはなんなのか、ソースコードを少し追ってみました。
目次
langchain.verbose
はモジュールの属性
最新のv0.0.231を見ていきます。
https://github.com/hwchase17/langchain/blob/v0.0.231/langchain/__init__.py#L64
verbose: bool = False
langchain.verbose
の使われ方
LangChainでは「Chain」という概念2が肝だと思います。
モデルとプロンプトをつないだChainを作ったり、複数のChainをつないだりできます。
このChainを初期化する際にlangchain.verbose
の値が参照されます!
すべてのChainのベースクラス(と現時点で理解してます)
https://github.com/hwchase17/langchain/blob/v0.0.231/langchain/chains/base.py#L33
読み取り
同じモジュールの中に、langchain.verbose
を読み取る関数があります。
https://github.com/hwchase17/langchain/blob/v0.0.231/langchain/chains/base.py#L29-L30
def _get_verbosity() -> bool: return langchain.verbose
動作を確認するため、ここで紹介した要素だけを抜き出したスクリプトを用意します。
# my_langchain.py verbose: bool = False def _get_verbosity() -> bool: return verbose
# verbose_value.py import my_langchain print(f"{my_langchain._get_verbosity()=}") print("---- Set verbose True ----") my_langchain.verbose = True print(f"{my_langchain._get_verbosity()=}")
my_langchain.verbose = True
と値を書き換えると、_get_verbosity
関数の返り値も対応して変わります。
% python verbose_value.py my_langchain._get_verbosity()=False ---- Set verbose True ---- my_langchain._get_verbosity()=True
読み取った値を指定する
LangChainはPyDantic(v0.0.231時点ではPyDantic 1系3)を使っています。
ChainはPyDanticのBaseModelを継承したクラス!
https://github.com/hwchase17/langchain/blob/v0.0.231/langchain/chains/base.py#L33
# SerializableがBaseModelを継承しています # https://github.com/hwchase17/langchain/blob/v0.0.231/langchain/load/serializable.py#L33 class Chain(Serializable, ABC):
Chainクラスのインスタンスはverbose属性を持ちます。
ここはPyDanticの書き方で、default_factory
に上記の_get_verbosity
関数を指定しています。
https://github.com/hwchase17/langchain/blob/v0.0.231/langchain/chains/base.py#L71
class Chain(Serializable, ABC): # ... 省略 ... verbose: bool = Field(default_factory=_get_verbosity)
PyDanticのField
のdefault_factory
はこちら
https://docs.pydantic.dev/latest/usage/fields/#default-values
You can also use default_factory to define a callable that will be called to generate a default value.
フィールドのデフォルト値を生成するために呼び出されるcallable(関数など)を定義してdefault_factory
引数に指定できるようです。
というわけで、以上の要素によってlangchain.verbose = True
という設定がChainに渡ります。
(これによりChainの扱うプロンプトが標準出力に表示される仕組みはまたの機会としたいと思います)
再現させる実装をして検証
動作環境
上記のコードも含めて、以下の環境で動作確認しました。
Python 3.11.4
pip install 'pydantic<2'
で以下がインストールされています。
pydantic==1.10.11 typing_extensions==4.7.1
verboseを指定しないときの設定値(Falseのまま)
# my_langchain.py verbose: bool = False def _get_verbosity() -> bool: return verbose from pydantic import BaseModel, Field class Chain(BaseModel): verbose: bool = Field(default_factory=_get_verbosity)
# false_example.py import my_langchain chain = my_langchain.Chain() print(repr(chain))
% python false_example.py Chain(verbose=False)
設定しないときはChainインスタンスのverbose属性はFalse
ですね
verboseをTrueに指定したときの設定値(Trueになる)
# true_example.py import my_langchain my_langchain.verbose = True chain = my_langchain.Chain() print(repr(chain))
% python true_example.py Chain(verbose=True)
my_langchain.verbose = True
と指定すると(※langchain.verbose = True
のイメージ)、Chainインスタンスのverbose属性はTrue
です!!
my_langchain.verbose = True
という簡単な方法で、LangChainの肝のChainインスタンス(複数)のverbose
属性の値が全部設定できちゃうわけですね!
終わりに
LangChainのlangchain.verbose = True
により、Chainインスタンスの属性がTrue
に設定されることを見てきました。
- ライブラリのユーザが
langchain.verbose = True
と指定する - Chainを初期化する際、
langchain.verbose
の値がverbose属性に設定されるlangchain.verbose
を読み取る_get_verbosity
関数- PyDanticの
Field
のdefault_factory
引数に_get_verbosity
関数を指定
langchain.verbose = True
でプロンプトが出力されるのは魔法のように感じていましたが、扱うコードの一端を知り「こんな実装ができるのか!」と感動しました。
引き続きソースコードを追っていきます。
- StudyCoさんの勉強会で知って、素振りのたびに活用しています! ↩
- https://python.langchain.com/docs/modules/chains/↩
- PyDanticは最近2系がリリースされましたが、LangChainは1系に依存しています。 https://github.com/hwchase17/langchain/blob/v0.0.231/pyproject.toml#L15↩