以下のページでは、Weaveトレースに関するよくある質問への回答を提供しています。

Weaveは関数に関してどのような情報を取得しますか?

関数は、デコレータを通じて手動で、または有効化された統合の一部として自動的にWeave Op として指定できます。Opが実行されると、Weaveは分析をサポートするための詳細情報を取得します。Weaveはデフォルトとは異なるものをログに記録したい場合に備えて、何をログに記録するかを細かく制御できます。設定例については以下をご覧ください。
  • コードキャプチャ - Weaveは、Opのソースコードの表現を取得します。これにはインラインコメントだけでなく、変数の値や呼び出されたOp以外の関数のソースを再帰的に取得することも含まれます。コードキャプチャにより、変更がソース管理システムに保存されていなくても、関数が何をしていたかを確認できます。コードキャプチャはOpのバージョン管理の一部として使用され、時間の経過に伴うコードの評価を理解できます。コードキャプチャが無効になっている場合は、代わりにハッシュ値が使用されます。
  • 関数名、入力、および出力 - 関数の名前は取得されますが、オーバーライドされた。入力と出力のJSON形式の表現が記録されます。入力については、値に加えて引数名も記録されます。Weaveではログのカスタマイズが可能です - 関数を指定して、記録される内容の追加/削除/変更ができます。
  • Op呼び出し階層 - あるOpが別のOpの実行コンテキスト内で呼び出された場合、中間に非Op関数が実行されている場合でも、この関係は記録されます。Op呼び出し間のこの関係は「トレースツリー」を提供するために使用されます。
  • 実行ステータスと例外 - Weaveは関数が実行中か、完了したか、エラーが発生したかを追跡します。実行中に例外が発生した場合、エラーメッセージとスタックトレースが記録されます。
  • システム情報 - Weaveはクライアントが実行されているオペレーティングシステムに関する情報(詳細なバージョン情報を含む)を記録することがあります。
  • クライアント情報 - Weaveは使用されているプログラミング言語やその言語とWeaveクライアントライブラリの詳細なバージョン情報など、Weaveクライアント自体に関する情報を記録することがあります。
  • タイミング - 実行の開始時間と終了時間が記録され、レイテンシ計算にも使用されます。
  • トークン使用量 - 一部のインテグレーションではLLMトークン使用量が自動的に記録されることがあります。
  • ユーザーとランコンテキスト - ログはW&Bユーザーアカウントに関連付けられます。これはwandb Runコンテキストとともに記録されます。
  • 派生情報 - Weaveは記録された生データから派生情報を計算することがあります。例えば、トークン使用量と使用されたモデルの知識に基づいてコスト見積もりが計算されることがあります。Weaveは呼び出し全体にわたって一部の情報を集計します。
  • あなたが選択する追加情報 - あなたはカスタムメタデータをweave.attributes呼び出しの一部として記録したり、フィードバックを呼び出しに添付したりすることができます。

コードキャプチャを無効にするにはどうすればよいですか?

Weaveクライアントの初期化時にコードキャプチャを無効にできます:weave.init("entity/project", settings={"capture_code": False})。 また、環境変数 WEAVE_CAPTURE_CODE=falseを使用することもできます。

システム情報のキャプチャを無効にするにはどうすればよいですか?

Weaveクライアントの初期化時にシステム情報のキャプチャを無効にできます:weave.init("entity/project", settings={"capture_system_info": False})

クライアント情報のキャプチャを無効にするにはどうすればよいですか?

Weaveクライアントの初期化時にクライアント情報のキャプチャを無効にできます:weave.init("entity/project", settings={"capture_client_info": False})

UIでPythonのdatetime値をレンダリングするにはどうすればよいですか?

Pythonのdatetime.datetime(タイムゾーン情報付き)を使用し、weave.publish(...)を使用してオブジェクトを公開します。Weaveはこの型を認識し、タイムスタンプとしてレンダリングします。

UIでMarkdownをレンダリングするにはどうすればよいですか?

文字列をweave.Markdown(...)でラップしてから保存し、weave.publish(...)を使用して保存します。Weaveはオブジェクトの型に基づいてレンダリング方法を決定し、weave.Markdownは既知のUIレンダラーにマッピングされます。値はUI上でフォーマットされたMarkdownオブジェクトとして表示されます。完全なコードサンプルについては、呼び出しの表示を参照してください。

Weaveは関数の実行速度に影響しますか?

Weaveログ記録のオーバーヘッドは、通常LLMへの呼び出しと比較して無視できるほど小さいです。 Opの実行速度へのWeaveの影響を最小限に抑えるため、ネットワークアクティビティはバックグラウンドスレッドで行われます。 プログラムが終了するとき、残りのキューに入れられたデータがログに記録される間、一時停止しているように見えることがあります。

Weaveのデータ取り込みはどのように計算されますか?

取り込まれたバイトとは、受信、処理、保存されるバイトと定義しています。これにはトレースメタデータ、LLM入力/出力、およびWeaveに明示的に記録されるその他の情報が含まれますが、通信オーバーヘッド(HTTPヘッダーなど)や長期保存されないその他のデータは含まれません。バイトは受信して保存された時点で一度だけ「取り込まれた」としてカウントされます。

ペアワイズ評価とは何ですか?どのように行いますか?

Weaveのスコアリングモデルを評価する際、絶対値メトリクス(例:モデルAの場合は9/10、モデルBの場合は8/10)は、相対的なもの(例:モデルAはモデルBよりも優れている)よりも割り当てるのが通常難しいです。ペアワイズ評価では、2つのモデルの出力を相対的にランク付けして比較することができます。このアプローチは、テキスト生成、要約、質問応答などの主観的なタスクにおいて、どのモデルがより良いパフォーマンスを発揮するかを判断したい場合に特に有用です。ペアワイズ評価により、特定の入力に対してどのモデルが最適かを示す相対的な優先順位ランキングを得ることができます。
このアプローチは回避策であり、将来のリリースで変更される可能性があります。私たちはペアワイズ評価をサポートするためのより堅牢なAPIに積極的に取り組んでいます。今後の更新にご期待ください!
以下のコードサンプルは、クラスベースのスコアラーと呼ばれるPreferenceScorerを作成することで、Weaveでペアワイズ評価を実装する方法を示しています。PreferenceScorerは2つのモデル、ModelAModelBを比較し、入力テキスト内の明示的なヒントに基づいてモデル出力の相対的なスコアを返します。
from weave import Model, Evaluation, Scorer, Dataset
from weave.flow.model import ApplyModelError, apply_model_async

class ModelA(Model):
    @weave.op
    def predict(self, input_text: str):
        if "Prefer model A" in input_text:
            return {"response": "This is a great answer from Model A"}
        return {"response": "Meh, whatever"}

class ModelB(Model):
    @weave.op
    def predict(self, input_text: str):
        if "Prefer model B" in input_text:
            return {"response": "This is a thoughtful answer from Model B"}
        return {"response": "I don't know"}

class PreferenceScorer(Scorer):
    @weave.op
    async def _get_other_model_output(self, example: dict) -> Any:
        """Get output from the other model for comparison.
        Args:
            example: The input example data to run through the other model
        Returns:
            The output from the other model
        """

        other_model_result = await apply_model_async(
            self.other_model,
            example,
            None,
        )

        if isinstance(other_model_result, ApplyModelError):
            return None

        return other_model_result.model_output

    @weave.op
    async def score(self, output: dict, input_text: str) -> dict:
        """Compare the output of the primary model with the other model.
        Args:
            output (dict): The output from the primary model.
            input_text (str): The input text used to generate the outputs.
        Returns:
            dict: A flat dictionary containing the comparison result and reason.
        """
        other_output = await self._get_other_model_output(
            {"input_text": input_text}
        )
        if other_output is None:
            return {"primary_is_better": False, "reason": "Other model failed"}

        if "Prefer model A" in input_text:
            primary_is_better = True
            reason = "Model A gave a great answer"
        else:
            primary_is_better = False
            reason = "Model B is preferred for this type of question"

        return {"primary_is_better": primary_is_better, "reason": reason}

dataset = Dataset(
    rows=[
        {"input_text": "Prefer model A: Question 1"},  # Model A wins
        {"input_text": "Prefer model A: Question 2"},  # Model A wins
        {"input_text": "Prefer model B: Question 3"},  # Model B wins
        {"input_text": "Prefer model B: Question 4"},  # Model B wins
    ]
)

model_a = ModelA()
model_b = ModelB()
pref_scorer = PreferenceScorer(other_model=model_b)
evaluation = Evaluation(dataset=dataset, scorers=[pref_scorer])
evaluation.evaluate(model_a)