W&B Weave は、同期および非同期のジェネレーター関数のトレースをサポートしており、深くネストしたパターンにも対応しています。
ジェネレーターは値を遅延的に yield するため、Weave が出力をログに記録するのは、ジェネレーターが完全に消費されたときのみです (たとえばリストに変換したとき) 。
Weave がトレース内で出力を取得できるようにするには、ジェネレーターを完全に消費してください (たとえば list() を使う) 。
from typing import Generator
import weave
weave.init("my-project")
# この関数はシンプルな同期ジェネレーターを使用します。
# Weave はこの呼び出しとその入力 (`x`) をトレースしますが、
# 出力値が記録されるのは、ジェネレーターが消費された後のみです(たとえば `list()` を使った場合)。
@weave.op
def basic_gen(x: int) -> Generator[int, None, None]:
yield from range(x)
# ジェネレーターのパイプライン内で使われる通常の同期関数です。
# この関数の呼び出しも Weave によって個別にトレースされます。
@weave.op
def inner(x: int) -> int:
return x + 1
# 別のトレース対象関数 (`inner`) を呼び出す同期ジェネレーターです。
# `yield` されるそれぞれの値は、個別の `inner` 呼び出しのトレースから得られます。
@weave.op
def nested_generator(x: int) -> Generator[int, None, None]:
for i in range(x):
yield inner(i)
# 上記のジェネレーターを合成した、より複雑なジェネレーターです。
# ここでのトレースは階層的な呼び出しツリーを生成します:
# - `deeply_nested_generator`(親)
# - `nested_generator`(子)
# - `inner`(孫)
@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
# Weave が出力を取得するには、ジェネレーターを「消費」する必要があります。
# これは同期ジェネレーターと非同期ジェネレーターの両方に当てはまります。
res = deeply_nested_generator(4)
list(res) # すべてのネストした呼び出しと `yield` をトレースさせる
This feature is not available in the TypeScript SDK yet.
次のスクリーンショットは、前述のコードのトレースを選択した Traces ページを示しています。中央のペインには、選択されたトレースのトレースツリーが表示されています。トレースツリーには、deeply_nested_generator、nested_generator、inner の各 Ops が階層構造で示されています。
Weave は、ジェネレーターを最後まで消費し終えた後にのみ、その出力を取得します。ジェネレーターは、それを反復処理することで消費します (たとえば list()、for ループ、あるいは枯渇するまで next() を使うなど) 。async for や同等の方法で消費する場合も、非同期ジェネレーターについて同じことが当てはまります。
関数やメソッドを @weave.op でデコレートする方法の詳細は、呼び出しの作成 を参照してください。