mcpField
L
langsmith-observability

langsmith-observability

github.com/orchestra-researchテスト・品質14.1k952 回インストール19 週間前に更新
リポジトリ

langsmith-observability について

LangSmith は、LLM アプリケーションのデバッグ、評価、監視を行うプラットフォームです。実行トレースを記録し、データセットによる評価、本番環境の監視、回帰テストを支援します。

主な機能

  1. 01LLM 呼び出しのトレース記録
  2. 02データセットを使った評価
  3. 03本番環境の指標・エラー・コストの監視
  4. 04実行へのフィードバック収集
  5. 05CI/CD での回帰評価

活用シーン

  1. 01プロンプト、チェーン、エージェントの問題調査
  2. 02モデル出力の比較と体系的な評価
  3. 03本番アプリケーションのレイテンシとコストの監視
  4. 04CI/CD での AI 機能の回帰テスト

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/orchestra-research/ai-research-skills --skill langsmith-observability

インストール後、Claude Code で/langsmith-observabilityを入力して読み込まれたか確認します。

同梱ファイルreferences/advanced-usage.mdreferences/troubleshooting.md

詳細

LangSmith - LLM オブザーバビリティプラットフォーム

言語モデルと AI アプリケーションのデバッグ、評価、モニタリングのための開発プラットフォームです。

LangSmith を使用するタイミング

次のような場合に LangSmith を使用します:

  • LLM アプリケーションの問題(プロンプト、チェーン、エージェント)をデバッグする場合
  • データセットに対してモデルの出力を体系的に評価する場合
  • 本番環境の LLM システムを監視する場合
  • AI 機能のリグレッションテストを構築する場合
  • レイテンシ、トークン使用量、コストを分析する場合
  • プロンプトエンジニアリングで共同作業する場合

主な機能:

  • トレーシング: すべての LLM 呼び出しの入力、出力、レイテンシを取得します
  • 評価: 組み込みおよびカスタムのエバリュエーターによる体系的なテスト
  • データセット: 本番トレースから、または手動でテストセットを作成します
  • モニタリング: 本番環境でメトリクス、エラー、コストを追跡します
  • インテグレーション: OpenAI、Anthropic、LangChain、LlamaIndex と連携します

代わりに使用できる選択肢:

  • Weights & Biases: 深層学習の実験追跡、モデルのトレーニング
  • MLflow: 汎用的な ML ライフサイクル、モデルレジストリに重点
  • Arize/WhyLabs: ML モニタリング、データドリフトの検出

クイックスタート

インストール
pip install langsmith

# Set environment variables
export LANGSMITH_API_KEY="your-api-key"
export LANGSMITH_TRACING=true
@traceable による基本的なトレーシング
from langsmith import traceable
from openai import OpenAI

client = OpenAI()

@traceable
def generate_response(prompt: str) -> str:
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}]
    )
    return response.choices[0].message.content

# Automatically traced to LangSmith
result = generate_response("What is machine learning?")
OpenAI ラッパー(自動トレーシング)
from langsmith.wrappers import wrap_openai
from openai import OpenAI

# Wrap client for automatic tracing
client = wrap_openai(OpenAI())

# All calls automatically traced
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}]
)

主要な概念

Run とトレース

Run は単一の実行単位(LLM 呼び出し、チェーン、ツール)です。Run は階層的な トレース を形成し、実行フロー全体を示します。

from langsmith import traceable

@traceable(run_type="chain")
def process_query(query: str) -> str:
    # Parent run
    context = retrieve_context(query)  # Child run
    response = generate_answer(query, context)  # Child run
    return response

@traceable(run_type="retriever")
def retrieve_context(query: str) -> list:
    return vector_store.search(query)

@traceable(run_type="llm")
def generate_answer(query: str, context: list) -> str:
    return llm.invoke(f"Context: {context}\n\nQuestion: {query}")
プロジェクト

プロジェクトは関連する Run をまとめます。環境変数またはコードで設定します:

import os
os.environ["LANGSMITH_PROJECT"] = "my-project"

# Or per-function
@traceable(project_name="my-project")
def my_function():
    pass

Client API

from langsmith import Client

client = Client()

# List runs
runs = list(client.list_runs(
    project_name="my-project",
    filter='eq(status, "success")',
    limit=100
))

# Get run details
run = client.read_run(run_id="...")

# Create feedback
client.create_feedback(
    run_id="...",
    key="correctness",
    score=0.9,
    comment="Good answer"
)

データセットと評価

データセットの作成
from langsmith import Client

client = Client()

# Create dataset
dataset = client.create_dataset("qa-test-set", description="QA evaluation")

# Add examples
client.create_examples(
    inputs=[
        {"question": "What is Python?"},
        {"question": "What is ML?"}
    ],
    outputs=[
        {"answer": "A programming language"},
        {"answer": "Machine learning"}
    ],
    dataset_id=dataset.id
)
評価の実行
from langsmith import evaluate

def my_model(inputs: dict) -> dict:
    # Your model logic
    return {"answer": generate_answer(inputs["question"])}

def correctness_evaluator(run, example):
    prediction = run.outputs["answer"]
    reference = example.outputs["answer"]
    score = 1.0 if reference.lower() in prediction.lower() else 0.0
    return {"key": "correctness", "score": score}

results = evaluate(
    my_model,
    data="qa-test-set",
    evaluators=[correctness_evaluator],
    experiment_prefix="v1"
)

print(f"Average score: {results.aggregate_metrics['correctness']}")
組み込みエバリュエーター
from langsmith.evaluation import LangChainStringEvaluator

# Use LangChain evaluators
results = evaluate(
    my_model,
    data="qa-test-set",
    evaluators=[
        LangChainStringEvaluator("qa"),
        LangChainStringEvaluator("cot_qa")
    ]
)

高度なトレーシング

トレーシングコンテキスト
from langsmith import tracing_context

with tracing_context(
    project_name="experiment-1",
    tags=["production", "v2"],
    metadata={"version": "2.0"}
):
    # All traceable calls inherit context
    result = my_function()
手動による Run
from langsmith import trace

with trace(
    name="custom_operation",
    run_type="tool",
    inputs={"query": "test"}
) as run:
    result = do_something()
    run.end(outputs={"result": result})
入力/出力の加工
def sanitize_inputs(inputs: dict) -> dict:
    if "password" in inputs:
        inputs["password"] = "***"
    return inputs

@traceable(process_inputs=sanitize_inputs)
def login(username: str, password: str):
    return authenticate(username, password)
サンプリング
import os
os.environ["LANGSMITH_TRACING_SAMPLING_RATE"] = "0.1"  # 10% sampling

LangChain インテグレーション

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# Tracing enabled automatically with LANGSMITH_TRACING=true
llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("user", "{input}")
])

chain = prompt | llm

# All chain runs traced automatically
response = chain.invoke({"input": "Hello!"})

本番環境のモニタリング

Hub プロンプト
from langsmith import Client

client = Client()

# Pull prompt from hub
prompt = client.pull_prompt("my-org/qa-prompt")

# Use in application
result = prompt.invoke({"question": "What is AI?"})
非同期クライアント
from langsmith import AsyncClient

async def main():
    client = AsyncClient()

    runs = []
    async for run in client.list_runs(project_name="my-project"):
        runs.append(run)

    return runs
フィードバックの収集
from langsmith import Client

client = Client()

# Collect user feedback
def record_feedback(run_id: str, user_rating: int, comment: str = None):
    client.create_feedback(
        run_id=run_id,
        key="user_rating",
        score=user_rating / 5.0,  # Normalize to 0-1
        comment=comment
    )

# In your application
record_feedback(run_id="...", user_rating=4, comment="Helpful response")

テストインテグレーション

Pytest インテグレーション
from langsmith import test

@test
def test_qa_accuracy():
    result = my_qa_function("What is Python?")
    assert "programming" in result.lower()
CI/CD での評価
from langsmith import evaluate

def run_evaluation():
    results = evaluate(
        my_model,
        data="regression-test-set",
        evaluators=[accuracy_evaluator]
    )

    # Fail CI if accuracy drops
    assert results.aggregate_metrics["accuracy"] >= 0.9, \
        f"Accuracy {results.aggregate_metrics['accuracy']} below threshold"

ベストプラクティス

  1. 構造化された命名 - プロジェクトや Run の命名規則を一貫して使用します
  2. メタデータの追加 - バージョン、環境、ユーザー情報を含めます
  3. 本番環境でサンプリング - サンプリングレートを使ってデータ量を制御します
  4. データセットの作成 - 注目すべき本番ケースからテストセットを構築します
  5. 評価の自動化 - CI/CD パイプラインで評価を実行します
  6. コストの監視 - トークン使用量とレイテンシの傾向を追跡します

よくある問題

トレースが表示されない:

import os
# Ensure tracing is enabled
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "your-key"

# Verify connection
from langsmith import Client
client = Client()
print(client.list_projects())  # Should work

トレーシングによる高いレイテンシ:

# Enable background batching (default)
from langsmith import Client
client = Client(auto_batch_tracing=True)

# Or use sampling
os.environ["LANGSMITH_TRACING_SAMPLING_RATE"] = "0.1"

大きなペイロード:

# Hide sensitive/large fields
@traceable(
    process_inputs=lambda x: {k: v for k, v in x.items() if k != "large_field"}
)
def my_function(data):
    pass

参考資料

リソース

コメント