LangChainに関する私の基本的な記事では、LangSmith のトピックについて簡単に触れただけでした。この記事では、他の Large Language Model ( LLM ) フレームワークとも連携して動作するこのプラットフォームについて詳しく見ていきます。
ラングスミスの定義
LangSmithは、一言で言えば、LLM アプリケーションとインテリジェント エージェントをプロトタイプの状態から運用環境にトレース、評価、移行するためのツールです。
または、 LangSmith のドキュメントには次のように記載されています。「LangSmith は、実稼働対応の LLM アプリケーションを構築するためのプラットフォームです。これにより、LLM フレームワーク上に構築されたチェーンとインテリジェント エージェントをデバッグ、テスト、評価、監視できるようになります。 LangSmith は、主要なオープンソースフレームワークである LangChain とシームレスに統合できます。」
この記事でこれがどのように機能するかを正確に知ることができます。注: 現在、LangChain はPython 、JavaScript、Go の 3 つの実装で利用できます。前述のすべての例で最初の例を使用します。
LangChain で LangSmith を使用する
LangSmith アカウントを設定し、API キーを作成し、 pip
を使用して LangChain インストールを更新し、シェル環境変数を設定した後、Python クイックスタート アプリケーションを実行できます。
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI()
llm.predict("Hello, world!")
結果を見る前に、LangSmith ハブを見てみましょう。
次のタブには、デフォルト プロジェクトのトレース リストが表示されます。
それに応じて OpenAI API 料金を調整または構成した後でのみ、Python プログラムが最後まで実行されました。結果を見てみましょう:
関連するメタデータ タブを見ると、「Hello, World!」プロンプトがサンプリング温度 0.7 のgpt-3.5-turbo
モデルで実行されていることがわかりました。ここでのスケールは 0 から 1 までで、1 は最も任意の設定で、0 はモデルに温度を自動的に設定するように要求します。
ラングスミスの仕組み
LangSmith は、LangChain またはその他の LLM プログラム内のすべての LLM、チェーン、エージェント、ツール、およびレトリーバー呼び出しをログに記録します。これはあなたに役立ちます
-
予期しない最終結果をデバッグする、
-
エージェントが「ループ」する理由を特定する
-
チェーンが予想よりも遅い理由を調べ、
-
エージェントが使用したトークンの数を確認します。
LangSmith は、すべての LLM 呼び出しの正確な入力と出力を簡単に視覚化します。入力側は簡単だと思うなら、それは間違いです。LLM 呼び出しでは、入力変数 (プロンプト) に加えて、テンプレートが使用され、多くの場合、言語モデルのコンテキストを設定する補助関数も使用されます。 Web またはファイルのアップロード。
一般に、LangChain を使用するすべての作業では LangSmith をオンにしておくことが推奨されます。ログは、関連する場合にのみ表示する必要があります。プロンプトで望ましい結果が得られない場合は、「プレイグラウンド」にプロンプトを送信するオプションがあります。
対応する「シークレットと API キー」ボタンを使用して API キーを追加することを忘れないでください。
LangSmith LLMChain の例
LangChain の紹介では、ChatOpenAI 呼び出しと単純なカンマ区切りリスト パーサーを組み合わせた LLMChain の例を使用しました。この Python コードの LangSmith ログを見ると、プログラムで何が起こっているかを理解するのに役立ちます。
パーサーはBaseOutputParser
のサブクラスです。 ChatOpenAI 呼び出しのシステム メッセージ テンプレートは、比較的単純なプロンプト エンジニアリングです。
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.chains import LLMChain
from langchain.schema import BaseOutputParser
class CommaSeparatedListOutputParser(BaseOutputParser):
"""Parse the output of an LLM call to a comma-separated list."""
def parse(self, text: str):
"""Parse the output of an LLM call."""
return text.strip().split(", ")
template = """You are a helpful assistant who generates comma separated lists.
A user will pass in a category, and you should generate 5 objects in that category in a comma separated list.
ONLY return a comma separated list, and nothing more."""
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
chain = LLMChain(
llm=ChatOpenAI(),
prompt=chat_prompt,
output_parser=CommaSeparatedListOutputParser()
)
chain.run("colors")
ラングスミスで評価する
このクイックスタート ウォークスルーでは、サンプル データ セットを使用してチェーンを評価します。データセットが作成されると、評価用の LLM、チェーン、またはエージェントが定義されます。プロセスが完了すると、LangSmith 内でトレースとフィードバックがレビューされます。
from langsmith import Client
example_inputs = [
"a rap battle between Atticus Finch and Cicero",
"a rap battle between Barbie and Oppenheimer",
"a Pythonic rap battle between two swallows: one European and one African",
"a rap battle between Aubrey Plaza and Stephen Colbert",
]
client = Client()
dataset_name = "Rap Battle Dataset"
# Storing inputs in a dataset lets us
# run chains and LLMs over a shared set of examples.
dataset = client.create_dataset(
dataset_name=dataset_name, description="Rap battle prompts.",
)
for input_prompt in example_inputs:
# Each example must be unique and have inputs defined.
# Outputs are optional
client.create_example(
inputs={"question": input_prompt},
outputs=None,
dataset_id=dataset.id,
)
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
# Since chains and agents can be stateful (they can have memory),
# create a constructor to pass in to the run_on_dataset method.
def create_chain():
llm = ChatOpenAI(temperature=0)
return LLMChain.from_string(llm, "Spit some bars about {input}.")
from langchain.smith import RunEvalConfig, run_on_dataset
eval_config = RunEvalConfig(
evaluators=[
# You can specify an evaluator by name/enum.
# In this case, the default criterion is "helpfulness"
"criteria",
# Or you can configure the evaluator
RunEvalConfig.Criteria("harmfulness"),
RunEvalConfig.Criteria(
{"cliche": "Are the lyrics cliche?"
" Respond Y if they are, N if they're entirely unique."}
)
]
)
run_on_dataset(
client=client,
dataset_name=dataset_name,
llm_or_chain_factory=create_chain,
evaluation=eval_config,
verbose=True,
project_name="llmchain-test-1",
)
この例では、考慮すべきことがさらにたくさんあります。上記のコードはデータ セットを取得し、データ セットからの 4 つのプロンプトに対してモデルを実行し、生成されたラップ バトルの結果ごとに複数の評価を実行します。
実行中に端末経由で出力された関連統計は次のとおりです。
Eval quantiles:
0.25 0.5 0.75 mean mode
harmfulness 0.00 0.0 0.0 0.00 0.0
helpfulness 0.75 1.0 1.0 0.75 1.0
cliche 1.00 1.0 1.0 1.00 1.0
以下の記録が示すように、ラップ バトルのプロンプトの設定を楽しんでいた人がいます。
コードでは独自のプロジェクト名 ( llmchain-test-1
) が使用されているため、結果もそこに表示されます。
以下は、 gpt-3.5-turbo
によって生成された「バービー vs オッペンハイマー」のラップ バトルです。
ラングスミス クックブック
LangSmith の標準ドキュメントでは、プラットフォームの基本をすべてカバーしています。ただし、 LangSmith クックブックを使用すると、現実世界の一般的なパターンやユース ケースを詳しく知ることができます (コードを実行するには、リポジトリをクローンまたはフォークする必要があります)。
クックブックは次の分野をカバーしています。
-
LangChain によるコード トレース。
-
プロンプトを発見して LangChain Hub と共有します。
-
LLM システムのテストとベンチマーク。
-
ユーザーのフィードバックを活用してアプリケーションを最適化、監視し、パーソナライズします。
-
微調整を目的としてデータをエクスポートします。
-
探索的なデータ分析。