智慧體課程文件

額外單元2:Agent 的可觀測性和評估

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

Ask a Question Open In Colab

額外單元2:Agent 的可觀測性和評估

您可以按照此 Notebook 中的程式碼進行操作,您可以使用 Google Colab 執行它。

在本 Notebook 中,我們將學習如何使用開源可觀測性工具來**監控 AI Agent 的內部步驟(跟蹤)**並**評估其效能**。

觀察和評估 Agent 行為的能力對於以下方面至關重要:

  • 在任務失敗或產生次優結果時除錯問題
  • 即時監控成本和效能
  • 透過持續反饋提高可靠性和安全性

練習前提條件 🏗️

在執行本 Notebook 之前,請確保您已:

🔲 📚 學習了 Agent 簡介

🔲 📚 學習了 smolagents 框架

步驟 0:安裝所需的庫

我們將需要一些庫來執行、監控和評估我們的 Agent

%pip install langfuse 'smolagents[telemetry]' openinference-instrumentation-smolagents datasets 'smolagents[gradio]' gradio --upgrade

步驟 1:整合 Agent

在本 Notebook 中,我們將使用 Langfuse 作為我們的可觀測性工具,但您可以使用**任何其他相容 OpenTelemetry 的服務**。下面的程式碼展示瞭如何為 Langfuse(或任何 OTel 端點)設定環境變數,以及如何整合您的 smolagent。

注意:如果您使用 LlamaIndex 或 LangGraph,您可以在此處此處找到有關如何整合它們的文件。

首先,讓我們將 Langfuse API 金鑰設定為環境變數。透過註冊 Langfuse Cloud自託管 Langfuse 獲取您的 Langfuse API 金鑰。

import os
# Get keys for your project from the project settings page: https://cloud.langfuse.com
os.environ["LANGFUSE_PUBLIC_KEY"] = "pk-lf-..." 
os.environ["LANGFUSE_SECRET_KEY"] = "sk-lf-..." 
os.environ["LANGFUSE_HOST"] = "https://cloud.langfuse.com" # 🇪🇺 EU region
# os.environ["LANGFUSE_HOST"] = "https://us.cloud.langfuse.com" # 🇺🇸 US region

我們還需要為推理呼叫配置我們的 Hugging Face token。

# Set your Hugging Face and other tokens/secrets as environment variable
os.environ["HF_TOKEN"] = "hf_..." 

設定好環境變數後,我們現在可以初始化 Langfuse 客戶端。get_client() 使用環境變數中提供的憑據初始化 Langfuse 客戶端。

from langfuse import get_client
 
langfuse = get_client()
 
# Verify connection
if langfuse.auth_check():
    print("Langfuse client is authenticated and ready!")
else:
    print("Authentication failed. Please check your credentials and host.")

接下來,我們可以設定 SmolagentsInstrumentor() 來整合我們的 smolagent 並將跟蹤傳送到 Langfuse。

from openinference.instrumentation.smolagents import SmolagentsInstrumentor
 
SmolagentsInstrumentor().instrument()

步驟 2:測試您的整合

這是一個來自 smolagents 的簡單 CodeAgent,它計算 1+1。我們執行它以確認整合是否正常工作。如果一切都設定正確,您將在可觀測性儀表板中看到日誌/跟蹤。

from smolagents import InferenceClientModel, CodeAgent

# Create a simple agent to test instrumentation
agent = CodeAgent(
    tools=[],
    model=InferenceClientModel()
)

agent.run("1+1=")

檢查您的Langfuse Traces Dashboard(或您選擇的可觀測性工具)以確認跟蹤和日誌已記錄。

Langfuse 的示例截圖

Example trace in Langfuse

跟蹤連結

步驟 3:觀察和評估更復雜的 Agent

既然您已確認整合正常工作,讓我們嘗試一個更復雜的查詢,以便我們能夠看到如何跟蹤高階指標(token 使用、延遲、成本等)。

from smolagents import (CodeAgent, DuckDuckGoSearchTool, InferenceClientModel)

search_tool = DuckDuckGoSearchTool()
agent = CodeAgent(tools=[search_tool], model=InferenceClientModel())

agent.run("How many Rubik's Cubes could you fit inside the Notre Dame Cathedral?")

跟蹤結構

大多數可觀測性工具記錄的**跟蹤**包含**span**,代表 Agent 邏輯的每個步驟。這裡,跟蹤包含 Agent 的整體執行以及以下子 span:

  • 工具呼叫 (DuckDuckGoSearchTool)
  • LLM 呼叫 (InferenceClientModel)

您可以檢查這些以精確檢視時間花費在哪裡,使用了多少 token 等

Trace tree in Langfuse

跟蹤連結

線上評估

在上一節中,我們學習了線上評估和離線評估的區別。現在,我們將瞭解如何在生產中監控 Agent 並即時評估它。

生產中常見的跟蹤指標

  1. **成本** — smolagents 的整合捕獲 token 使用量,您可以透過為每個 token 分配價格將其轉換為近似成本。
  2. **延遲** — 觀察完成每個步驟或整個執行所需的時間。
  3. **使用者反饋** — 使用者可以提供直接反饋(贊/踩)以幫助完善或糾正 Agent。
  4. **LLM 作為判斷者** — 使用單獨的 LLM 幾乎即時地評估 Agent 的輸出(例如,檢查毒性或正確性)。

下面,我們展示了這些指標的示例。

1. 成本

下面是顯示 Qwen2.5-Coder-32B-Instruct 呼叫使用情況的截圖。這有助於檢視耗時的步驟並最佳化您的 Agent。

Costs

跟蹤連結

2. 延遲

我們還可以看到完成每個步驟所需的時間。在下面的示例中,整個對話花費了 32 秒,您可以按步驟細分。這有助於您識別瓶頸並最佳化您的 Agent。

Latency

跟蹤連結

3. 額外屬性

您還可以將其他屬性傳遞給您的 span。這些屬性可以包括 user_idtagssession_id 和自定義元資料。使用這些詳細資訊豐富跟蹤對於分析、除錯和監控應用程式在不同使用者或會話中的行為非常重要。

from smolagents import (CodeAgent, DuckDuckGoSearchTool, InferenceClientModel)

search_tool = DuckDuckGoSearchTool()
agent = CodeAgent(
    tools=[search_tool],
    model=InferenceClientModel()
)

with langfuse.start_as_current_span(
    name="Smolagent-Trace",
    ) as span:
    
    # Run your application here
    response = agent.run("What is the capital of Germany?")
 
    # Pass additional attributes to the span
    span.update_trace(
        input="What is the capital of Germany?",
        output=response,
        user_id="smolagent-user-123",
        session_id="smolagent-session-123456789",
        tags=["city-question", "testing-agents"],
        metadata={"email": "user@langfuse.com"},
        )
 
# Flush events in short-lived applications
langfuse.flush()

Enhancing agent runs with additional metrics

4. 使用者反饋

如果您的 Agent 嵌入在使用者介面中,您可以記錄直接的使用者反饋(例如聊天介面中的點贊/點踩)。下面是一個使用 Gradio 嵌入帶有簡單反饋機制的聊天的示例。

在下面的程式碼片段中,當用戶傳送聊天訊息時,我們會在 Langfuse 中捕獲跟蹤。如果使用者喜歡/不喜歡最後一個答案,我們會將分數附加到跟蹤中。

import gradio as gr
from smolagents import (CodeAgent, InferenceClientModel)
from langfuse import get_client

langfuse = get_client()

model = InferenceClientModel()
agent = CodeAgent(tools=[], model=model, add_base_tools=True)

trace_id = None

def respond(prompt, history):
    with langfuse.start_as_current_span(
        name="Smolagent-Trace"):
        
        # Run your application here
        output = agent.run(prompt)

        global trace_id
        trace_id = langfuse.get_current_trace_id()

    history.append({"role": "assistant", "content": str(output)})
    return history

def handle_like(data: gr.LikeData):
    # For demonstration, we map user feedback to a 1 (like) or 0 (dislike)
    if data.liked:
        langfuse.create_score(
            value=1,
            name="user-feedback",
            trace_id=trace_id
        )
    else:
        langfuse.create_score(
            value=0,
            name="user-feedback",
            trace_id=trace_id
        )

with gr.Blocks() as demo:
    chatbot = gr.Chatbot(label="Chat", type="messages")
    prompt_box = gr.Textbox(placeholder="Type your message...", label="Your message")

    # When the user presses 'Enter' on the prompt, we run 'respond'
    prompt_box.submit(
        fn=respond,
        inputs=[prompt_box, chatbot],
        outputs=chatbot
    )

    # When the user clicks a 'like' button on a message, we run 'handle_like'
    chatbot.like(handle_like, None, None)

demo.launch()

使用者反饋隨後會被捕獲在您的可觀測性工具中

User feedback is being captured in Langfuse

5. LLM 作為判斷者

LLM 作為判斷者是自動評估 Agent 輸出的另一種方式。您可以設定一個單獨的 LLM 呼叫來衡量輸出的正確性、毒性、風格或您關心的任何其他標準。

工作流程:

  1. 您定義一個**評估模板**,例如“檢查文字是否有毒。”
  2. 每次您的 Agent 生成輸出時,您都會將該輸出與模板一起傳遞給您的“判斷者”LLM。
  3. 判斷者 LLM 會回覆一個評級或標籤,您將其記錄到您的可觀測性工具中。

Langfuse 的示例

LLM-as-a-Judge Evaluation Template LLM-as-a-Judge Evaluator

# Example: Checking if the agent’s output is toxic or not.
from smolagents import (CodeAgent, DuckDuckGoSearchTool, InferenceClientModel)

search_tool = DuckDuckGoSearchTool()
agent = CodeAgent(tools=[search_tool], model=InferenceClientModel())

agent.run("Can eating carrots improve your vision?")

您可以看到此示例的答案被判定為“無毒”。

LLM-as-a-Judge Evaluation Score

6. 可觀測性指標概述

所有這些指標都可以在儀表板中一起視覺化。這使您能夠快速檢視 Agent 在多個會話中的表現,並幫助您跟蹤隨時間變化的質量指標。

Observability metrics overview

離線評估

線上評估對於即時反饋至關重要,但您還需要**離線評估**——在開發之前或期間進行系統檢查。這有助於在將更改推廣到生產之前保持質量和可靠性。

資料集評估

在離線評估中,您通常:

  1. 擁有一個基準資料集(包含提示和預期輸出對)
  2. 在該資料集上執行您的 Agent
  3. 將輸出與預期結果進行比較,或使用額外的評分機制

下面,我們將透過 GSM8K 資料集演示此方法,該資料集包含數學問題和解決方案。

import pandas as pd
from datasets import load_dataset

# Fetch GSM8K from Hugging Face
dataset = load_dataset("openai/gsm8k", 'main', split='train')
df = pd.DataFrame(dataset)
print("First few rows of GSM8K dataset:")
print(df.head())

接下來,我們在 Langfuse 中建立一個數據集實體以跟蹤執行。然後,我們將資料集中的每個專案新增到系統中。(如果您不使用 Langfuse,您只需將這些專案儲存在自己的資料庫或本地檔案中進行分析。)

from langfuse import get_client
langfuse = get_client()

langfuse_dataset_name = "gsm8k_dataset_huggingface"

# Create a dataset in Langfuse
langfuse.create_dataset(
    name=langfuse_dataset_name,
    description="GSM8K benchmark dataset uploaded from Huggingface",
    metadata={
        "date": "2025-03-10", 
        "type": "benchmark"
    }
)
for idx, row in df.iterrows():
    langfuse.create_dataset_item(
        dataset_name=langfuse_dataset_name,
        input={"text": row["question"]},
        expected_output={"text": row["answer"]},
        metadata={"source_index": idx}
    )
    if idx >= 9: # Upload only the first 10 items for demonstration
        break

Dataset items in Langfuse

在資料集上執行 Agent

我們定義了一個輔助函式 run_smolagent(),它:

  1. 啟動 Langfuse span
  2. 在提示上執行我們的 Agent
  3. 在 Langfuse 中記錄跟蹤 ID

然後,我們遍歷每個資料集項,執行 Agent,並將跟蹤連結到資料集項。如果需要,我們還可以附加一個快速評估分數。

from opentelemetry.trace import format_trace_id
from smolagents import (CodeAgent, InferenceClientModel, LiteLLMModel)
from langfuse import get_client
 
langfuse = get_client()


# Example: using InferenceClientModel or LiteLLMModel to access openai, anthropic, gemini, etc. models:
model = InferenceClientModel()

agent = CodeAgent(
    tools=[],
    model=model,
    add_base_tools=True
)

dataset_name = "gsm8k_dataset_huggingface"
current_run_name = "smolagent-notebook-run-01" # Identifies this specific evaluation run
 
# Assume 'run_smolagent' is your instrumented application function
def run_smolagent(question):
    with langfuse.start_as_current_generation(name="qna-llm-call") as generation:
        # Simulate LLM call
        result = agent.run(question)
 
        # Update the trace with the input and output
        generation.update_trace(
            input= question,
            output=result,
        )
 
        return result
 
dataset = langfuse.get_dataset(name=dataset_name) # Fetch your pre-populated dataset
 
for item in dataset.items:
 
    # Use the item.run() context manager
    with item.run(
        run_name=current_run_name,
        run_metadata={"model_provider": "Hugging Face", "temperature_setting": 0.7},
        run_description="Evaluation run for GSM8K dataset"
    ) as root_span: # root_span is the root span of the new trace for this item and run.
        # All subsequent langfuse operations within this block are part of this trace.
 
        # Call your application logic
        generated_answer = run_smolagent(question=item.input["text"])
 
        print(item.input)

您可以重複此過程,使用不同的:

  • 模型(OpenAI GPT、本地 LLM 等)
  • 工具(搜尋與不搜尋)
  • 提示(不同的系統訊息)

然後,在您的可觀測性工具中並排比較它們

Dataset run overview Dataset run comparison

總結

在本 Notebook 中,我們介紹瞭如何:

  1. **設定可觀測性**:使用 smolagents + OpenTelemetry 匯出器
  2. **檢查整合**:透過執行一個簡單的 Agent
  3. **捕獲詳細指標**:透過可觀測性工具(成本、延遲等)
  4. **收集使用者反饋**:透過 Gradio 介面
  5. **使用 LLM 作為判斷者**:自動評估輸出
  6. **執行離線評估**:使用基準資料集

🤗 祝您編碼愉快!

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.