Weave Calls Screenshot Weave Calls Screenshot Weave Calls Screenshot
Calls CallsはWeaveの基本的な構成要素です。関数の単一の実行を表し、以下を含みます:
  • 入力(引数)
  • 出力(戻り値)
  • メタデータ(実行時間、例外、LLM使用状況など)
CallsはOpenTelemetryデータモデルのスパンに似ています。Callは以下のことができます:
  • Trace(同じ実行コンテキスト内のCallのコレクション)に属する
  • 親子関係のCallを持ち、ツリー構造を形成する

Callsの作成

Weaveでのcallの作成には主に3つの方法があります:

1. LLMライブラリの自動トラッキング

Weaveは自動的に一般的なLLMライブラリへの呼び出しを追跡します。例えばopenaianthropiccohere、そしてmistralなどです。プログラムの開始時に単にweave.init('project_name')を呼び出すだけです:
Weaveのデフォルトのトラッキング動作はautopatch_settings引数を使用してweave.init制御できます。
showLineNumbers
import weave

from openai import OpenAI
client = OpenAI()

# Initialize Weave Tracing
weave.init('intro-example')

response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        {
            "role": "user",
            "content": "How are you?"
        }
    ],
    temperature=0.8,
    max_tokens=64,
    top_p=1,
)

サマリー

メトリクスやその他の呼び出し後の値をCallのsummarysummary 辞書に保存できます。実行中にcall.summarysummaryを変更すると、追加した値は呼び出しが終了したときにWeaveの計算されたサマリーデータとマージされます。

2. 関数の装飾とラッピング

しかし、LLMアプリケーションには、追跡したい追加のロジック(前処理/後処理、プロンプトなど)がある場合が多いです。
Weaveでは@weave.opデコレータを使用してこれらの呼び出しを手動で追跡できます。例えば:
showLineNumbers
import weave

# Initialize Weave Tracing
weave.init('intro-example')

# Decorate your function
@weave.op
def my_function(name: str):
    return f"Hello, {name}!"

# Call your function -- Weave will automatically track inputs and outputs
print(my_function("World"))
また、クラスのメソッドも追跡できます。

同期および非同期ジェネレータ関数のトレース

Weaveは同期および非同期ジェネレータ関数の両方をトレースすることをサポートしており、深くネストされたパターンも含まれます。
ジェネレータは値を遅延的に生成するため、出力はジェネレータが完全に消費された場合(例えば、リストに変換することによって)にのみログに記録されます。 トレースに出力が確実に記録されるようにするには、ジェネレータを完全に消費してください(例えば、list()を使用するなど)。
showLineNumbers
from typing import Generator
import weave

weave.init("my-project")

# This function uses a simple sync generator.
# Weave will trace the call and its input (`x`), 
# but output values are only captured once the generator is consumed (e.g., via `list()`).
@weave.op
def basic_gen(x: int) -> Generator[int, None, None]:
    yield from range(x)

# A normal sync function used within the generator pipeline.
# Its calls are also traced independently by Weave.
@weave.op
def inner(x: int) -> int:
    return x + 1

# A sync generator that calls another traced function (`inner`).
# Each yielded value comes from a separate traced call to `inner`.
@weave.op
def nested_generator(x: int) -> Generator[int, None, None]:
    for i in range(x):
        yield inner(i)

# A more complex generator that composes the above generator.
# Tracing here produces a hierarchical call tree:
# - `deeply_nested_generator` (parent)
#   - `nested_generator` (child)
#     - `inner` (grandchild)
@weave.op
def deeply_nested_generator(x: int) -> Generator[int, None, None]:
    for i in range(x):
        for j in nested_generator(i):
            yield j

# The generator must be *consumed* for Weave to capture outputs.
# This is true for both sync and async generators.
res = deeply_nested_generator(4)
list(res)  # Triggers tracing of all nested calls and yields
Tracing generator functions in Weave.

実行中にcallオブジェクトのハンドルを取得する

時にはCallCallop.callwith_resultCallCall
showLineNumbers
result, call = my_function.call("World")
その後、callcallオブジェクト
opがクラスのメソッドである場合は、インスタンスを最初の引数としてopに渡す必要があります(以下の例を参照)。
showLineNumbers
# Notice that we pass the `instance` as the first argument.
print(instance.my_method.call(instance, "World"))
showLineNumbers
import weave

# Initialize Weave Tracing
weave.init("intro-example")

class MyClass:
    # Decorate your method
    @weave.op
    def my_method(self, name: str):
        return f"Hello, {name}!"

instance = MyClass()

# Call your method -- Weave will automatically track inputs and outputs
instance.my_method.call(instance, "World")

Call表示名

場合によっては、callの表示名を上書きしたいことがあります。これは次の4つの方法のいずれかで実現できます:
  1. opを呼び出す時に表示名を変更する:
showLineNumbers
result = my_function("World", __weave={"display_name": "My Custom Display Name"})
この__weavemetadata
  1. call単位で表示名を変更します。これはOp.callwith_resultCallCallCall.set_display_nameset_display_name
showLineNumbers
result, call = my_function.call("World")
call.set_display_name("My Custom Display Name")
  1. 特定のOpのすべてのCallの表示名を変更する:
showLineNumbers
@weave.op(call_display_name="My Custom Display Name")
def my_function(name: str):
    return f"Hello, {name}!"
  1. このcall_display_namedisplay_nameCallCallCallCall
  2. 一般的なユースケースの1つは、関数名にタイムスタンプを追加するだけです。
    from datetime import datetime
    
    @weave.op(call_display_name=lambda call: f"{call.func_name}__{datetime.now()}")
    def func():
        return ...
    
  3. また、.attributes
    def custom_attribute_name(call):
        model = call.attributes["model"]
        revision = call.attributes["revision"]
        now = call.attributes["date"]
    
        return f"{model}__{revision}__{now}"
    
    @weave.op(call_display_name=custom_attribute_name)
    def func():
        return ...
    
    with weave.attributes(
        {
            "model": "finetuned-llama-3.1-8b",
            "revision": "v0.1.2",
            "date": "2024-08-01",
        }
    ):
        func()  # the display name will be "finetuned-llama-3.1-8b__v0.1.2__2024-08-01"
    
        with weave.attributes(
            {
                "model": "finetuned-gpt-4o",
                "revision": "v0.1.3",
                "date": "2024-08-02",
            }
        ):
            func()  # the display name will be "finetuned-gpt-4o__v0.1.3__2024-08-02"
    
技術的注意:「Calls」は「Ops」によって生成されます。Opは@weave.opweave.opでデコレートされた関数またはメソッドです。 デフォルトでは、Opの名前は関数名であり、関連するcallも同じ表示名を持ちます。上記の例は、特定のOpのすべてのCallの表示名を上書きする方法を示しています。時々、ユーザーはOp自体の名前を上書きしたいと思うことがあります。これは次の2つの方法のいずれかで実現できます:
  1. 任意のcallがログに記録される前に、Opのnamename
showLineNumbers
my_function.name = "My Custom Op Name"
  1. opデコレータでnamename
showLineNumbers
@weave.op(name="My Custom Op Name)

属性

追跡された関数を呼び出す際、weave.attributesweave.attributesenvexample'production'value
showLineNumbers
# ... continued from above ...

# Add additional attributes to the call
with weave.attributes({'env': 'production'}):
    print(my_function.call("World"))
call.attributesattributesはcallが開始されると変更できません。このコンテキストマネージャを使用して、opを呼び出す前に任意のメタデータを設定してください。

並列(マルチスレッド)関数呼び出しのトレース

デフォルトでは、並列呼び出しはすべてWeaveで別々のルート呼び出しとして表示されます。同じ親opCallThreadPoolExecutorweave.trace_context以下のコードサンプルはThreadPoolExecutorweave.trace_contextの使用方法を示しています。 最初の関数funcincrementopweave.opxxx+1x + 1outerincrement_allopweave.opouterincrement_allThreadPoolExecutorweave.trace_contextexc.map(func, inputs)concurrent.futuresfuncincrement
import weave

@weave.op
def func(x):
    return x+1

@weave.op
def outer(inputs):
    with weave.ThreadPoolExecutor() as exc:
        exc.map(func, inputs)

# Update your Weave project name  
client = weave.init('my-weave-project')
outer([1,2,3,4,5])
Weave UIでは、これにより5つのネストされた子呼び出しを持つ単一の親呼び出しが生成されるため、インクリメントが並列で実行されていても完全に階層的なトレースが得られます。The Trace UI, showing a single parent call for outer, with five nested child calls.

3. 手動Call追跡

APIを直接使用してCallを手動で作成することもできます。
showLineNumbers
import weave

# Initialize Weave Tracing
client = weave.init('intro-example')

def my_function(name: str):
    # Start a call
    call = client.create_call(op="my_function", inputs={"name": name})

    # ... your function code ...

    # End a call
    client.finish_call(call, output="Hello, World!")

# Call your function
print(my_function("World"))

4. クラスとオブジェクトメソッドを追跡する

クラスとオブジェクトメソッドも追跡できます。
クラス上の任意のメソッドを追跡するには weave.op.
showLineNumbers
import weave

# Initialize Weave Tracing
weave.init("intro-example")

class MyClass:
    # Decorate your method
    @weave.op
    def my_method(self, name: str):
        return f"Hello, {name}!"

instance = MyClass()

# Call your method -- Weave will automatically track inputs and outputs
print(instance.my_method("World"))

コールの表示

Webアプリでコールを表示するには:
  1. プロジェクトの「Traces」タブに移動します
  2. リストから表示したいコールを見つけます
  3. コールをクリックして詳細ページを開きます
詳細ページには、コールの入力、出力、実行時間、およびその他のメタデータが表示されます。View Call in Web App

コールの更新

コールは作成後はほとんど不変ですが、いくつかの変更がサポートされています: これらの変更はすべて、コール詳細ページに移動してUIから実行できます: Update Call in Web App

表示名の設定

コールの表示名を設定するには、Call.set_display_name メソッドを使用できます。
showLineNumbers
import weave

# Initialize the client
client = weave.init("your-project-name")

# Get a specific call by its ID
call = client.get_call("call-uuid-here")

# Set the display name of the call
call.set_display_name("My Custom Display Name")

フィードバックの追加

詳細については、フィードバックドキュメントを参照してください。

コールの削除

Python APIを使用してコールを削除するには、Call.delete メソッドを使用できます。
showLineNumbers
import weave

# Initialize the client
client = weave.init("your-project-name")

# Get a specific call by its ID
call = client.get_call("call-uuid-here")

# Delete the call
call.delete()

複数のコールの削除

Python APIを使用してコールのバッチを削除するには、コールIDのリストを delete_calls()に渡します。
showLineNumbers
import weave

# Initialize the client
client = weave.init("my-project")

# Get all calls from client 
all_calls = client.get_calls()

# Get list of first 1000 Call objects
first_1000_calls = all_calls[:1000]

# Get list of first 1000 Call IDs
first_1000_calls_ids = [c.id for c in first_1000_calls]

# Delete first 1000 Call objects by ID
client.delete_calls(call_ids=first_1000_calls_ids)

コールのクエリとエクスポート

Screenshot of many calls プロジェクトの /calls ページ(「Traces」タブ)には、プロジェクト内のすべてのコールのテーブルビューが含まれています。そこから、以下のことができます:
  • ソート
  • フィルタリング
  • エクスポート
Calls Table View エクスポートモーダル(上図)では、データを様々な形式でエクスポートできるだけでなく、選択したコールのPythonとCURLの同等のコードも表示されます! 始めるには、UIでビューを構築し、生成されたコードスニペットからエクスポートAPIについて詳しく学ぶのが最も簡単な方法です。
Python APIを使用してコールを取得するには、client.get_calls method:
import weave

# Initialize the client
client = weave.init("your-project-name")

# Fetch calls
calls = client.get_calls(filter=...)

コールスキーマ

フィールドの完全なリストについては、スキーマを参照してください。
プロパティ説明
idstring (uuid)コールの一意の識別子
project_idstring (オプション)関連するプロジェクト識別子
op_namestring操作の名前(参照の場合あり)
display_namestring (オプション)コールのユーザーフレンドリーな名前
trace_idstring (uuid)このコールが属するトレースの識別子
parent_idstring (uuid)親コールの識別子
started_atdatetimeコールが開始されたタイムスタンプ
attributesDict[str, Any]コールに関するユーザー定義のメタデータ (実行中は読み取り専用)
inputsDict[str, Any]コールの入力パラメータ
ended_atdatetime (オプション)コールが終了したタイムスタンプ
exceptionstring (オプション)コールが失敗した場合のエラーメッセージ
outputAny (オプション)コールの結果
summaryOptional[SummaryMap]実行後の要約情報。実行中にこれを変更してカスタムメトリクスを記録できます。
wb_user_idOptional[str]関連する Weights & Biases ユーザーID
wb_run_idOptional[str]関連する Weights & Biases 実行ID
deleted_atdatetime (optional)該当する場合、コール削除のタイムスタンプ
上記の表はWeaveにおけるCallの主要なプロパティを概説しています。各プロパティは関数呼び出しの追跡と管理において重要な役割を果たします:
  • The id, trace_id, and parent_id フィールドは、システム内でコールを整理し関連付けるのに役立ちます。
  • タイミング情報(started_at, ended_at)はパフォーマンス分析を可能にします。
  • The attributes and inputs フィールドはコールのコンテキストを提供します。属性はコールが開始されると固定されるため、weave.attributes で呼び出し前に設定してください。output and summary は結果をキャプチャし、summary は実行中に更新して追加のメトリクスを記録できます。
  • Weights & Biasesとの統合は wb_user_id and wb_run_id を通じて実現されます。
このプロパティの包括的なセットにより、プロジェクト全体を通じて関数呼び出しの詳細な追跡と分析が可能になります。 計算フィールド:
  • コスト
  • 所要時間
  • ステータス

保存されたビュー

トレーステーブルの構成、フィルター、並べ替えを saved views として保存し、お好みの設定に素早くアクセスできます。UIとPython SDKを通じて保存されたビューを設定およびアクセスできます。詳細については、Saved Views をご覧ください。

トレーステーブルでW&B実行を表示する

Weaveを使用すると、コード内の関数呼び出しを追跡し、それらを実行された W&B runs に直接リンクできます。 @weave.op()で関数をトレースし、wandb.init()コンテキスト内で呼び出すと、WeaveはトレースをW&B実行に自動的に関連付けます。 関連する実行へのリンクはトレーステーブルに表示されます。

Python例

以下のPythonコードは、トレースされた操作が wandb.init() コンテキスト内で実行されるとW&B実行にリンクされる方法を示しています。これらのトレースはWeave UIに表示され、対応する実行に関連付けられます。
import wandb
import weave

def example_wandb(projname):
    # Split projname into entity and project
    entity, project = projname.split("/", 1)

    # Initialize Weave context for tracing
    weave.init(projname)

    # Define a traceable operation
    @weave.op()
    def say(message: str) -> str:
        return f"I said: {message}"

    # First W&B run
    with wandb.init(
        entity=entity,
        project=project,
        notes="Experiment 1",
        tags=["baseline", "paper1"],
    ) as run:
        say("Hello, world!")
        say("How are you!")
        run.log({"messages": 2})

    # Second W&B run
    with wandb.init(
        entity=entity,
        project=project,
        notes="Experiment 2",
        tags=["baseline", "paper1"],
    ) as run:
        say("Hello, world from experiment 2!")
        say("How are you!")
        run.log({"messages": 2})

if __name__ == "__main__":
    # Replace this with your actual W&B username/project
    example_wandb("your-username/your-project")
コードサンプルを使用するには:
  1. ターミナルで依存関係をインストールします:
    pip install wandb weave
    
  2. W&Bにログインします:
    wandb login
    
  3. スクリプトで、your-username/your-project を実際のW&Bエンティティ/プロジェクトに置き換えます。
  4. スクリプトを実行します:
    python weave_trace_with_wandb.py
    
  5. Visit https://weave.wandb.ai にアクセスしてプロジェクトを選択します。
  6. Traces タブで、トレース出力を表示します。関連する実行へのリンクはトレーステーブルに表示されます。

自動パッチの設定

デフォルトでは、Weaveは openai, anthropic, cohere, and mistral などの一般的なLLMライブラリへの呼び出しを自動的にパッチし追跡します。 この動作は autopatch_settings 引数を weave.init で使用して制御できます。

すべての自動パッチを無効にする

showLineNumbers
weave.init(..., autopatch_settings={"disable_autopatch": True})

特定の統合を無効にする

showLineNumbers
weave.init(..., autopatch_settings={"openai": {"enabled": False}})

入力と出力の後処理

自動パッチング中に入力と出力(例:PII データ)を後処理する方法をカスタマイズすることもできます:
showLineNumbers
def redact_inputs(inputs: dict) -> dict:
    if "email" in inputs:
        inputs["email"] = "[REDACTED]"
    return inputs

weave.init(
    ...,
    autopatch_settings={
        "openai": {
            "op_settings": {
                "postprocess_inputs": redact_inputs,
            }
        }
    }
)
詳細については、How to use Weave with PII data をご覧ください。

よくある質問

大きなトレースが切り捨てられないようにするにはどうすればよいですか?

詳細については、Trace data is truncatedTroubleshooting guide でご覧ください。

トレースを無効にするにはどうすればよいですか?

環境変数

プログラム全体のトレースを無条件に無効にしたい場合は、環境変数 WEAVE_DISABLED=true を設定できます。

クライアント初期化

特定の条件に基づいて特定の初期化のトレースを条件付きで有効にしたい場合があります。この場合、初期設定で disabled フラグを使用してクライアントを初期化できます。
import weave

# Initialize the client
client = weave.init(..., settings={"disabled": True})

コンテキストマネージャー

最後に、アプリケーションロジックに基づいて単一の関数のトレースを条件付きで無効にしたい場合があります。この場合、コンテキストマネージャー with set_tracing_enabled(False) を使用できます。これは weave.trace.context.call_context からインポートできます。
import weave
from weave.trace.context.call_context import set_tracing_enabled

client = weave.init(...)

@weave.op
def my_op():
    ...

with set_tracing_enabled(False):
    my_op()

Callに関する情報をキャプチャするにはどうすればよいですか?

通常、opを直接呼び出します:
@weave.op
def my_op():
    ...

my_op()
ただし、opの call メソッドを呼び出すことで、コールオブジェクトに直接アクセスすることもできます:
@weave.op
def my_op():
    ...

output, call = my_op.call()
ここから、call オブジェクトには、入力、出力、その他のメタデータを含むコールに関するすべての情報が含まれます。