> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-feature-automate-reference-docs-generation.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Online monitoring

<Note>
  이것은 대화형 노트북입니다. 로컬에서 실행하거나 아래 링크를 사용할 수 있습니다:

  * [Open in Google Colab](https://colab.research.google.com/github/wandb/weave/blob/master/docs/notebooks/online_monitoring.ipynb)
  * [View source on GitHub](https://github.com/wandb/weave/blob/master/docs/notebooks/online_monitoring.ipynb)
</Note>

# Weave와 통합: 프로덕션 대시보드

GenAI 도구 환경은 빠르게 진화하고 있습니다 - 새로운 프레임워크, 도구 및 애플리케이션이 계속해서 등장하고 있습니다. Weave는 모든 GenAI 모니터링 및 평가 요구 사항을 위한 원스톱 솔루션이 되는 것을 목표로 합니다. 이는 때로는 기존 플랫폼과 통합하거나 프로젝트 또는 조직의 특정 요구 사항에 맞게 Weave를 확장해야 할 필요가 있음을 의미합니다.

이 쿡북에서는 Weave의 강력한 API와 함수를 활용하여 Weave의 Traces 뷰를 확장하는 프로덕션 모니터링을 위한 커스텀 대시보드를 만드는 방법을 보여드리겠습니다. 다음 사항에 중점을 둘 것입니다:

* Weave에서 트레이스, 비용, 피드백 및 기타 메트릭 가져오기
* 사용자 피드백 및 비용 분포에 대한 집계 뷰 생성
* 시간에 따른 토큰 사용량 및 지연 시간에 대한 시각화 생성

streamlit을 설치하고 다음을 실행하여 자신의 Weave 프로젝트로 대시보드를 시도해 볼 수 있습니다 [이 프로덕션 대시보드 스크립트](https://github.com/NiWaRe/agent-dev-collection)!

<img src="https://github.com/NiWaRe/knowledge-worker-weave/blob/master/screenshots/dashboard_weave_preview.jpg?raw=true" width="1000" alt="Example Production Dashboard with Weave" />

# 1. 설정

이 튜토리얼을 따라하기 위해서는 다음 패키지만 설치하면 됩니다:

```python
!pip install streamlit pandas plotly weave
```

# 2. 구현

## 2.1 Weave 클라이언트 초기화 및 비용 정의

먼저, Weave 클라이언트를 초기화하고 각 모델에 대한 비용을 추가하는 함수를 설정하겠습니다.

* 많은 표준 모델에 대한 표준 비용을 포함했지만 자체 커스텀 비용과 커스텀 모델을 쉽게 추가할 수 있도록 했습니다. 다음에서는 몇 가지 모델에 대한 커스텀 비용을 추가하고 나머지는 표준 비용을 사용하는 방법을 보여드리겠습니다.
* 비용은 Weave에서 각 호출에 대해 추적된 토큰을 기반으로 계산됩니다. 많은 LLM 벤더 라이브러리의 경우, 토큰 사용량을 자동으로 추적하지만 모든 호출에 대해 커스텀 토큰 수를 반환하는 것도 가능합니다. 커스텀 모델에 대한 토큰 수 및 비용 계산을 정의하는 방법에 대한 이 쿡북을 참조하세요 - [커스텀 비용 쿡북](https://weave-docs.wandb.ai/cookbooks/custom_model_cost#setting-up-a-model-with-weave).

```python
PROJECT_NAME = "wandb-smle/weave-cookboook-demo"
python
import weave

MODEL_NAMES = [
    # model name, prompt cost, completion cost
    ("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)
```

## 2.2 Weave에서 호출 데이터 가져오기

Weave에서 호출 데이터를 가져오기 위해 두 가지 옵션이 있습니다:

1. 호출별 데이터 가져오기
2. 고수준 API 사용하기

### 2.2.1 호출별 데이터 가져오기

Weave에서 데이터에 접근하는 첫 번째 옵션은 필터링된 호출 목록을 검색하고 호출별로 원하는 데이터를 추출하는 것입니다. 이를 위해 `calls_query_stream` API를 사용하여 Weave에서 호출 데이터를 가져올 수 있습니다:

* `calls_query_stream` API: This API allows us to fetch the calls data from Weave.
* `filter` dictionary: This dictionary contains the filter parameters to fetch the calls data - see [여기](https://weave-docs.wandb.ai/reference/python-sdk/weave/trace_server/weave.trace_server.trace_server_interface/#class-callschema)에서 자세한 내용을 확인하세요.
* `expand_columns` list: This list contains the columns to expand in the calls data.
* `sort_by` list: This list contains the sorting parameters for the calls data.
* `include_costs` boolean: This boolean indicates whether to include the costs in the calls data.
* `include_feedback` boolean: This boolean indicates whether to include the feedback in the calls data.

```python
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)
        )  # limit the number of calls to fetch if too many
        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
# the raw data is a list of Call objects
pd.DataFrame([call.dict() for call in calls]).head(3)
```

Weave의 반환값으로 호출을 처리하는 것은 매우 쉽습니다 - 관련 정보를 추출하여 딕셔너리 목록에 저장할 것입니다. 그런 다음 딕셔너리 목록을 pandas DataFrame으로 변환하여 반환합니다.

```python
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,  # this is a unique ID for the trace that can be used to retrieve it
                "Display Name": call.display_name,  # this is an optional name you can set in the UI or programatically
                "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)
```

### 2.2.2 고수준 API 사용하기

모든 호출을 일일이 살펴보는 대신 Weave는 모델 비용, 피드백 및 기타 메트릭에 직접 접근할 수 있는 고수준 API를 제공합니다.
예를 들어, 비용의 경우 `query_costs` API를 사용하여 프로젝트에서 사용된 모든 LLM의 비용을 가져옵니다:

```python
# Use cost API to get costs
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"]
)

# only show the first row for every unqiue llm_id
df_costs
```

## 2.4 입력 수집 및 시각화 생성

다음으로, plotly를 사용하여 시각화를 생성할 수 있습니다. 이것은 가장 기본적인 대시보드이지만 원하는 대로 커스터마이즈할 수 있습니다! 더 복잡한 예제는 Streamlit 예제를 [여기](https://github.com/NiWaRe/knowledge-worker-weave/blob/master/prod_dashboard.py)에서 확인하세요.

```python
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

# See the source code for all the plots
python
plot_feedback_pie_chart(df_calls["Thumbs Up"].sum(), df_calls["Thumbs Down"].sum())
python
plot_model_cost_distribution(df_costs)
```

# 결론

이 쿡북에서는 Weave의 API와 함수를 사용하여 커스텀 프로덕션 모니터링 대시보드를 만드는 방법을 보여드렸습니다. Weave는 현재 데이터의 쉬운 입력과 커스텀 프로세스를 위한 데이터 추출을 위한 빠른 통합에 중점을 두고 있습니다.

* **데이터 입력:**
  * 프레임워크에 구애받지 않는 트레이싱 [@weave-op()](https://weave-docs.wandb.ai/quickstart#2-log-a-trace-to-a-new-project) 데코레이터와 CSV에서 호출을 가져올 수 있는 가능성 (관련 [가져오기 쿡북](https://weave-docs.wandb.ai/cookbooks/import_from_csv) 참조)
  * 다양한 프로그래밍 프레임워크 및 언어에서 Weave에 로깅하기 위한 서비스 API 엔드포인트, [여기](https://weave-docs.wandb.ai/reference/service-api/call-start-call-start-post)에서 자세한 내용을 확인하세요.
* **데이터 출력:**
  * CSV, TSV, JSONL, JSON 형식으로 데이터를 쉽게 다운로드 - [여기](https://weave-docs.wandb.ai/guides/tracking/tracing#querying--exporting-calls)에서 자세한 내용을 확인하세요.
  * 데이터에 대한 프로그래밍 방식의 접근을 사용한 쉬운 내보내기 - 이 쿡북에서 설명한 대로 내보내기 패널의 "Use Python" 섹션을 참조하세요. [여기](https://weave-docs.wandb.ai/guides/tracking/tracing#querying--exporting-calls)에서 자세한 내용을 확인하세요.

이 커스텀 대시보드는 Weave의 기본 Traces 뷰를 확장하여 프로덕션 환경에서 LLM 애플리케이션의 맞춤형 모니터링을 가능하게 합니다. 더 복잡한 대시보드를 보고 싶다면, 자신의 Weave 프로젝트 URL을 추가할 수 있는 Streamlit 예제를 [이 저장소에서](https://github.com/NiWaRe/agent-dev-collection) 확인하세요.
