> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# オンラインモニタリング

> W&B Weave を使用して本番環境の LLM アプリケーションのオンラインモニタリングを設定し、パフォーマンスと品質のメトリクスをトラッキングします。

<Note>
  これはインタラクティブなノートブックです。ローカルで実行するか、以下のリンクから利用できます。

  * [Google Colab で開く](https://colab.research.google.com/github/wandb/docs/blob/main/weave/cookbooks/source/online_monitoring.ipynb)
  * [GitHub でソースを表示](https://github.com/wandb/docs/blob/main/weave/cookbooks/source/online_monitoring.ipynb)
</Note>

<h2 id="integrate-with-weave-production-dashboard">
  Weave との統合: 本番ダッシュボード
</h2>

このノートブックでは、Weave の Traces ビューを拡張する本番モニタリング用のカスタムダッシュボードを、Weave の API と関数を使用して作成する方法を紹介します。このガイドは、本番環境で LLM アプリケーションを運用し、デフォルトの Traces ビューでは得られない、パフォーマンス、コスト、ユーザーのフィードバックに関する独自の情報を把握したい開発者や ML エンジニアを対象としています。このノートブックでは、次の内容を扱います。

* Weave からトレース、コスト、フィードバック、その他のメトリクスを取得します。
* ユーザーのフィードバックとコスト分布の集計ビューを作成します。
* トークン使用量とレイテンシーの経時変化を可視化します。

このノートブックを完了すると、Weave プロジェクトのトレースデータ、コスト、フィードバックを単一のビューに集約する、動作可能なカスタムダッシュボードが完成します。`streamlit` をインストールして[本番ダッシュボードのスクリプト](https://github.com/NiWaRe/agent-dev-collection)を実行すると、自分の Weave プロジェクトでダッシュボードを試すことができます。

<img src="https://github.com/NiWaRe/knowledge-worker-weave/blob/master/screenshots/dashboard_weave_preview.jpg?raw=true" width="1000" alt="Weave での本番ダッシュボードの例" />

<h2 id="setup">
  セットアップ
</h2>

まず、次のパッケージをインストールします。

```python lines theme={"system"}
!pip install streamlit pandas plotly weave
```

<h2 id="implementation">
  Implementation
</h2>

以下のセクションでは、Weave クライアントの初期化、Call データの取得、およびダッシュボード用の可視化の生成について説明します。

<h3 id="initialize-the-weave-client-and-define-costs">
  Weave クライアントを初期化し、コストを定義する
</h3>

まず、Weave クライアントを初期化し、各モデルのコストを追加する関数を設定します。このステップは、後続のコストクエリで各呼び出しにトークンあたりの料金を割り当てるために必須です。

W\&B には多くの標準モデルの標準コストが含まれており、独自のカスタムコストやカスタムモデルも追加できます。次の例では、いくつかのモデルにカスタムコストを追加し、残りのモデルには標準コストを使用する方法を示します。
コストは、Weave で各呼び出しについて追跡されたトークンに基づいて計算されます。多くの LLM ベンダーのライブラリでは、Weave がトークン使用量を自動的にトラッキングしますが、任意の呼び出しでカスタムのトークン数を返すこともできます。カスタムモデルのトークン数とコスト計算の定義について詳しくは、[カスタムコストのクックブック](/ja/products/wandb/weave/cookbooks/custom_model_cost#setting-up-a-model-with-weave)を参照してください。

```python lines theme={"system"}
PROJECT_NAME = "wandb-smle/weave-cookboook-demo"
python
import weave

MODEL_NAMES = [
    # モデル名、プロンプトのコスト、生成のコスト
    ("gpt-4o-2024-05-13", 0.03, 0.06),
    ("gpt-4o-mini-2024-07-18", 0.03, 0.06),
    ("gemini/gemini-1.5-flash", 0.00025, 0.0005),
    ("gpt-4o-mini", 0.03, 0.06),
    ("gpt-4-turbo", 0.03, 0.06),
    ("claude-3-haiku-20240307", 0.01, 0.03),
    ("gpt-4o", 0.03, 0.06),
]

def init_weave_client(project_name):
    try:
        client = weave.init(project_name)
        for model, prompt_cost, completion_cost in MODEL_NAMES:
            client.add_cost(
                llm_id=model,
                prompt_token_cost=prompt_cost,
                completion_token_cost=completion_cost,
            )
    except Exception as e:
        print(f"Failed to initialize Weave client for project '{project_name}': {e}")
        return None
    else:
        return client

client = init_weave_client(PROJECT_NAME)
```

<h3 id="fetch-calls-data-from-weave">
  Weave から Call データをフェッチする
</h3>

クライアントの初期化とコストの設定が完了したら、次のステップは Weave から Call データをプルすることです。Call データをフェッチするためのオプションは 2 つあります。

* データを Call ごとにフェッチする。
* 高レベル API を使用する。

以下のセクションで各オプションについて説明します。

<h4 id="fetch-data-call-by-call">
  Call ごとにデータを取得する
</h4>

Weave からデータにアクセスする 1 つ目の方法は、フィルター処理した Call の一覧を取得し、必要なデータを Call ごとに抽出する方法です。そのためには、`calls_query_stream` API を使用して Weave から Call データを取得します。

* `calls_query_stream` API: Weave から Call データを取得する API です。
* `filter` 辞書: Call データの取得に使用するフィルターパラメーターを格納する辞書です。詳細については、[CallSchema リファレンス](/ja/products/wandb/weave/reference/python-sdk/trace_server/trace_server_interface#class-callschema)を参照してください。
* `expand_columns` リスト: Call データ内で展開する列を格納するリストです。
* `sort_by` リスト: Call データの並べ替えパラメーターを格納するリストです。
* `include_costs` ブール値: Call データにコストを含めるかどうかを指定するブール値です。
* `include_feedback` ブール値: Call データにフィードバックを含めるかどうかを指定するブール値です。

```python lines theme={"system"}
import itertools
from datetime import datetime, timedelta

import pandas as pd

def fetch_calls(client, project_id, start_time, trace_roots_only, limit):
    filter_params = {
        "project_id": project_id,
        "filter": {"started_at": start_time, "trace_roots_only": trace_roots_only},
        "expand_columns": ["inputs.example", "inputs.model"],
        "sort_by": [{"field": "started_at", "direction": "desc"}],
        "include_costs": True,
        "include_feedback": True,
    }
    try:
        calls_stream = client.server.calls_query_stream(filter_params)
        calls = list(
            itertools.islice(calls_stream, limit)
        )  # Call が多すぎる場合は、取得する件数を制限します
        print(f"Fetched {len(calls)} calls.")
    except Exception as e:
        print(f"Error fetching calls: {e}")
        return []
    else:
        return calls

calls = fetch_calls(client, PROJECT_NAME, datetime.now() - timedelta(days=1), True, 100)
python
# 生データは Call オブジェクトのリストです
pd.DataFrame([call.dict() for call in calls]).head(3)
```

Weave から返された値を使用して Call を処理します。必要な情報を抽出し、辞書のリストに格納します。その後、辞書のリストを pandas DataFrame に変換して返します。

```python lines theme={"system"}
import json
from datetime import datetime

import pandas as pd

def process_calls(calls):
    records = []
    for call in calls:
        feedback = call.summary.get("weave", {}).get("feedback", [])
        thumbs_up = sum(
            1
            for item in feedback
            if isinstance(item, dict) and item.get("payload", {}).get("emoji") == "👍"
        )
        thumbs_down = sum(
            1
            for item in feedback
            if isinstance(item, dict) and item.get("payload", {}).get("emoji") == "👎"
        )
        latency = call.summary.get("weave", {}).get("latency_ms", 0)

        records.append(
            {
                "Call ID": call.id,
                "Trace ID": call.trace_id,  # トレースの一意の ID です。トレースの取得に使用できます
                "Display Name": call.display_name,  # UI またはプログラムから設定できる任意の名前です
                "Latency (ms)": latency,
                "Thumbs Up": thumbs_up,
                "Thumbs Down": thumbs_down,
                "Started At": pd.to_datetime(getattr(call, "started_at", datetime.min)),
                "Inputs": json.dumps(call.inputs, default=str),
                "Outputs": json.dumps(call.output, default=str),
            }
        )
    return pd.DataFrame(records)
python
df_calls = process_calls(calls)
df_calls.head(3)
```

<h4 id="use-high-level-apis">
  高レベル API を使用する
</h4>

Weave には、すべての Call を 1 つずつ確認しなくても、モデルのコスト、フィードバック、その他のメトリクスに直接アクセスできる高レベル API も用意されています。
たとえばコストの場合は、`query_costs` API を使用して、project 内で使用されているすべての LLM のコストを取得します。

```python lines theme={"system"}
# コスト API を使用してコストを取得します
costs = client.query_costs()
df_costs = pd.DataFrame([cost.dict() for cost in costs])
df_costs["total_cost"] = (
    df_costs["prompt_token_cost"] + df_costs["completion_token_cost"]
)

# 一意の llm_id ごとに先頭行のみを表示します
df_costs
```

<h3 id="gather-inputs-and-generate-visualizations">
  入力の収集と可視化の生成
</h3>

call のデータとコストがデータフレームとして利用可能であれば、plotly を使用して可視化を生成できます。これはお好みでカスタマイズできるスターターダッシュボードです。より高度な例については、[knowledge-worker-weave リポジトリ内の Streamlit の例](https://github.com/NiWaRe/knowledge-worker-weave/blob/master/prod_dashboard.py) をご確認ください。

```python lines theme={"system"}
import plotly.express as px
import plotly.graph_objects as go

def plot_feedback_pie_chart(thumbs_up, thumbs_down):
    fig = go.Figure(
        data=[
            go.Pie(
                labels=["Thumbs Up", "Thumbs Down"],
                values=[thumbs_up, thumbs_down],
                marker={"colors": ["#66b3ff", "#ff9999"]},
                hole=0.3,
            )
        ]
    )
    fig.update_traces(textinfo="percent+label", hoverinfo="label+percent")
    fig.update_layout(showlegend=False, title="Feedback Summary")
    return fig

def plot_model_cost_distribution(df):
    fig = px.bar(
        df,
        x="llm_id",
        y="total_cost",
        color="llm_id",
        title="Cost Distribution by Model",
    )
    fig.update_layout(xaxis_title="Model", yaxis_title="Cost (USD)")
    return fig

# すべてのプロットのソースコードを参照してください
python
plot_feedback_pie_chart(df_calls["Thumbs Up"].sum(), df_calls["Thumbs Down"].sum())
python
plot_model_cost_distribution(df_costs)
```

<h2 id="conclusion">
  まとめ
</h2>

このクックブックでは、Weave の API と関数を使用して、カスタムの本番モニタリングダッシュボードを作成する方法を紹介しました。Weave は、データをスムーズに取り込み、カスタムプロセス向けにデータを抽出できる、手軽なインテグレーションを重視しています。

* **データ入力:**
  * [`@weave-op()`](/ja/products/wandb/weave/quickstart#2-log-a-trace-to-a-new-project) デコレーターによるフレームワークに依存しないトレースと、CSV から Call をインポートするオプション (関連する[インポートのクックブック](/ja/products/wandb/weave/cookbooks/import_from_csv)を参照してください) 。
  * さまざまなプログラミングフレームワークや言語から Weave にログするためのサービス API エンドポイント。詳細については、[サービス API リファレンス](/ja/products/wandb/weave/reference/service-api/calls/call-start)を参照してください。
* **データ出力:**
  * CSV、TSV、JSONL、または JSON 形式でデータをダウンロードできます。詳細については、[サービス API リファレンス](/ja/products/wandb/weave/reference/service-api)を参照してください。
  * プログラムからデータにアクセスしてエクスポートできます。このクックブックで説明したとおり、エクスポートパネルの「Use Python」セクションを参照してください。詳細については、[Call のクエリとエクスポート](/ja/products/wandb/weave/guides/tracking/tracing#querying-and-exporting-calls)を参照してください。

このカスタムダッシュボードは、Weave 標準の Traces ビューを拡張し、本番環境の LLM アプリケーションをニーズに合わせてモニタリングできるようにします。より複雑なダッシュボードについては、[agent-dev-collection リポジトリの Streamlit の例](https://github.com/NiWaRe/agent-dev-collection)をご覧ください。独自の Weave プロジェクトの URL を追加して利用できます。
