AI Engineering Academy · レッスン

LangSmithによるトレーシング

LangChainアプリケーションにLangSmithのトレーシングを組み込み、すべてのチェーンステップ、LLM呼び出し、トークン数、レイテンシを検索可能なトレースエクスプローラーに記録します。

レッスン 2/413 ステップ

「LangSmithによるトレーシング」はCoddyKit上の無料AI Engineering Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Engineering Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Engineering Academyコースには全4レッスンが含まれています。

LangSmithとは

LangSmithは、LLMアプリケーション専用に構築された可観測性プラットフォームです。LangChainの実行をすべて自動的に取得し、すべてのチェーンステップ、LLM呼び出し、ツール実行、検索、出力パーサーを、検索可能な階層型トレースエクスプローラーに表示します。レイテンシ、コスト、エラーステータス、カスタムメタデータでトレースを絞り込み、任意のトレースを再実行して障害をデバッグできます。

# Install: pip install langsmith
import os

# Set environment variables to enable automatic tracing
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
os.environ['LANGCHAIN_API_KEY'] = 'lsv2_...your_key_here...'
os.environ['LANGCHAIN_PROJECT'] = 'my-rag-app'  # project name in LangSmith UI

# That's all - LangChain now sends traces to LangSmith automatically
# No code changes needed to your chain or agent

コードを変更せずに自動トレーシング

LangSmithの最も魅力的な機能は、3つの環境変数を設定するだけで、追加のコードなしにすべてのLangChain操作が自動的にトレースされることです。すべてのLCELチェーン、すべてのChatOpenAI呼び出し、すべての検索呼び出し、すべてのツール実行について、入力、出力、時間、トークン数が取得されます。環境変数を1つ変更するだけで、LangSmithのトレーシングを本番環境に導入できます。

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# This chain is automatically traced - no extra code needed
llm = ChatOpenAI(model='gpt-4o')
prompt = ChatPromptTemplate.from_template('Answer this question: {question}')
chain = prompt | llm | StrOutputParser()

# This call creates a trace in LangSmith showing:
# - The formatted prompt (with question substituted)
# - The LLM call with model, temperature, token counts
# - The parsed output
# - End-to-end latency and cost
result = chain.invoke({'question': 'What is RAG?'})
print(result)

RAGパイプラインのトレーシング

RAGアプリケーションでは、LangSmithのトレースが特に役立ちます。検索してから生成するパイプライン全体を取得できるためです。取得されたドキュメント、その類似度スコア、プロンプト内でのコンテキストの整形方法、LLMが生成した内容を確認できます。これにより、誤った回答の原因が不適切な検索にあるのか、生成品質の低さにあるのかをすぐに判断できます。

from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain_core.runnables import RunnablePassthrough

embeddings = OpenAIEmbeddings()
vectorstore = Chroma(embedding_function=embeddings)
retriever = vectorstore.as_retriever(search_kwargs={'k': 5})

rag_chain = (
    {'context': retriever, 'question': RunnablePassthrough()}
    | ChatPromptTemplate.from_template('Context: {context}\n\nQuestion: {question}\n\nAnswer:')
    | ChatOpenAI(model='gpt-4o')
    | StrOutputParser()
)

# LangSmith traces EVERY step:
# 1. Retriever: query embedding + vector search + returned documents (with scores)
# 2. Prompt: formatted template with context injected
# 3. LLM: full prompt, response, tokens, latency, cost
# 4. Parser: final string output
answer = rag_chain.invoke('What is the capital of France?')

トレースへのメタデータの追加

デフォルトでは、LangSmithのトレースに各ステップの入力と出力が含まれます。カスタムのメタデータタグを追加して、トレースを拡張することもできます。たとえば、ユーザーID、セッションID、フィーチャーフラグの値、A/Bテストのバリエーションなど、UIでトレースを絞り込み、分析するのに役立つ情報を追加できます。RunnableConfigを使ってメタデータを渡すと、そのリクエストのすべてのトレースに表示されます。

from langchain_core.runnables import RunnableConfig

def handle_user_request(user_id: str, query: str, ab_variant: str):
    config = RunnableConfig(
        tags=['production', ab_variant],
        metadata={
            'user_id': user_id,
            'ab_variant': ab_variant,
            'feature': 'rag_qa'
        }
    )
    
    result = rag_chain.invoke(query, config=config)
    return result

# In LangSmith UI you can now:
# - Filter traces by user_id to debug a specific user's issue
# - Compare latency between ab_variant='A' and ab_variant='B'
# - See all traces tagged 'production' vs 'staging'

手動でのスパン作成

LangChainを経由しないコード(カスタムAPI呼び出し、データベースクエリ、前処理ステップなど)については、LangSmithクライアントを直接使って手動スパンを作成できます。これにより、LangChain以外のステップもLangChainのステップと同じトレースに記録され、各リクエストの実行経路を完全に把握できます。

from langsmith import Client, traceable

client = Client()

# Decorate functions to auto-trace them
@traceable(name='preprocess_query')
def preprocess_query(raw_query: str) -> str:
    # This step is now traced even though it doesn't use LangChain
    cleaned = raw_query.strip().lower()
    cleaned = ' '.join(cleaned.split())  # normalize whitespace
    return cleaned

@traceable(name='fetch_user_history')
def fetch_user_history(user_id: str) -> list[str]:
    # Database call - also traced
    return db.query('SELECT message FROM chat_history WHERE user_id = ? ORDER BY timestamp DESC LIMIT 5', user_id)

# All three steps appear in the same trace
def handle_request(user_id: str, raw_query: str):
    query = preprocess_query(raw_query)         # traced
    history = fetch_user_history(user_id)       # traced
    result = rag_chain.invoke({'query': query, 'history': history})  # traced by LangChain
    return result

LangSmithでのトレース評価

LangSmithには、トレースのデータセットに対して評価器を実行できる評価フレームワークが含まれています。トレースされた例を選択し、自動評価器(正確性や関連性を評価するLLM-as-judgeスコアラーを含む)を実行して、異なるパイプラインバージョン間で結果を比較できます。これにより、本番環境のトレースをアプリケーション改善のフィードバックループとして活用できます。

from langsmith.evaluation import evaluate, LangChainStringEvaluator

# Create an evaluator that uses an LLM to judge correctness
correctness_evaluator = LangChainStringEvaluator(
    'qa',
    config={'llm': ChatOpenAI(model='gpt-4o')}
)

# Run evaluation against a dataset of traced examples
results = evaluate(
    rag_chain,
    data='my-rag-test-set',      # name of dataset in LangSmith
    evaluators=[correctness_evaluator],
    experiment_prefix='rag-v2-chunking-test'
)

print('Evaluation results:')
print(f'Correctness: {results.results["correctness"].mean():.2f}')
print(f'Average latency: {results.results["latency"].mean():.2f}s')

トレースからのテストデータセット作成

LangSmithの最も強力な機能の1つは、本番環境のトレースから直接テストデータセットを作成できることです。興味深いトレース(失敗例、エッジケース、優れた例など)を見つけたら、1回のクリックでデータセットに追加できます。時間が経つにつれて、合成例ではなく実際のユーザークエリから、包括的なリグレッションテストスイートを構築できます。

from langsmith import Client

client = Client()

# Create a dataset from existing traces
dataset = client.create_dataset('rag-regression-tests')

# Add examples from production traces (by trace ID)
for trace_id in failed_trace_ids:
    run = client.read_run(trace_id)
    client.create_example(
        inputs=run.inputs,
        outputs={'answer': run.outputs.get('output', '')},
        dataset_id=dataset.id,
        metadata={'source': 'production_failure', 'date': run.start_time.isoformat()}
    )

print(f'Added {len(failed_trace_ids)} examples to regression test dataset')

トレースのフィルタリングと検索

本番環境では、数千件のトレースを扱うことになります。LangSmithのUIとAPIは、柔軟なフィルタリングと検索に対応しています。たとえば、しきい値を超えるレイテンシ、特定のエラータイプ、特定のユーザー、出力に特定のキーワードを含むトレース、または補完トークン数が上限を超えるトレースを検索できます。これにより、特定の障害カテゴリを調査したり、特定のユーザーの挙動を監視したりすることが容易になります。

from langsmith import Client

client = Client()

# Find slow traces (useful for performance investigation)
slow_runs = client.list_runs(
    project_name='my-rag-app',
    filter='gt(latency, 5)',  # latency > 5 seconds
    limit=20
)

# Find error traces
error_runs = client.list_runs(
    project_name='my-rag-app',
    filter='eq(error, true)',
    limit=50
)

# Find traces from a specific user
user_runs = client.list_runs(
    project_name='my-rag-app',
    filter='has(metadata, user_id="user_abc123")',
    limit=100
)

for run in slow_runs:
    print(f'Slow run: {run.id}, latency: {run.end_time - run.start_time}')

LangSmithでの実験比較

LangSmithは実験の比較に対応しています。同じテストデータセットをパイプラインの2つのバージョン(例:チャンクサイズ500とチャンクサイズ1000)に通し、レイテンシ、コスト、品質の指標を横並びで比較できます。これにより、パイプラインの変更を本番環境にデプロイする前に、それがリグレッションではなく改善であることを簡単に検証できます。

from langsmith.evaluation import evaluate

test_dataset = 'my-rag-eval-set'

# Run experiment A: chunk size 500
results_a = evaluate(
    rag_pipeline_v1,
    data=test_dataset,
    evaluators=[correctness_evaluator, relevance_evaluator],
    experiment_prefix='chunk-500'
)

# Run experiment B: chunk size 1000
results_b = evaluate(
    rag_pipeline_v2,
    data=test_dataset,
    evaluators=[correctness_evaluator, relevance_evaluator],
    experiment_prefix='chunk-1000'
)

# Compare in LangSmith UI: Experiments tab shows A vs B side by side
# Or compare programmatically:
print(f'Correctness - v1: {results_a.results["correctness"].mean():.2f}, v2: {results_b.results["correctness"].mean():.2f}')

本番環境でのLangSmith

LangSmithはsmith.langchain.comでホスト型SaaSとして利用できるほか、セルフホスト型のオプションもあります。本番環境では、クリティカルパスにレイテンシを追加しないよう、トレーシングを非同期(ノンブロッキング)にできます。また、トレースをサンプリングして(たとえば、高トラフィックの本番環境でリクエストの10%だけをトレースして)コストを抑えながら可視性を維持することもできます。ダッシュボードには、リクエスト量、レイテンシ、コスト、エラー率のリアルタイムグラフが表示されます。

import os

# Production configuration
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'
os.environ['LANGCHAIN_PROJECT'] = 'production'

# Enable async tracing (non-blocking - does not add latency to requests)
os.environ['LANGCHAIN_CALLBACKS_BACKGROUND'] = 'true'

# Optional: sample 10% of traces to reduce cost in high-traffic scenarios
import random

def should_trace() -> bool:
    return random.random() < 0.10  # 10% sampling rate

def handle_request(query):
    config = RunnableConfig()
    if not should_trace():
        config = RunnableConfig(callbacks=[])  # disable tracing for this request
    return rag_chain.invoke(query, config=config)

LangSmithとカスタムロギングの比較

独自のトレースログシステムを構築することもできますし、ユースケースによってはそれが適切な選択となる場合もあります。カスタムログと比べたLangSmithの利点は、コード変更なしでLangChainと統合できること、LLMトレースの調査に特化したUIを備えていること(汎用的なKibana/Grafanaダッシュボードではありません)、評価と実験比較をネイティブにサポートしていること、そしてトークン数とコストを自動的に追跡できることです。一方で、規模が大きくなるとベンダー依存とコストが課題になります。

クイックチェック

このレッスンで学んだLangSmithによるトレーシングについて、理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、次のことを学びました。LangSmithでは、3つの環境変数を設定するだけでコードを変更せずに、LangChainアプリケーションをエンドツーエンドで自動トレーシングできます。@traceableデコレーターを使うと、データベース呼び出しや前処理など、LangChain以外のステップにもトレーシングを拡張できます。また、実験比較により、デプロイ前にテストデータセットを使ってパイプラインの改善を検証できます。次は、モデルに依存しないオブザーバビリティの選択肢としてLangfuseを見ていきます。

無料で開始

AI チューターと学ぶ Python — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
30
レッスン
120

よくある質問

「LangSmithによるトレーシング」レッスンは無料ですか?

はい。「LangSmithによるトレーシング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Engineering Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Engineering Academyコースには全4レッスンが含まれています。

「LangSmithによるトレーシング」で何を学びますか?

LangChainアプリケーションにLangSmithのトレーシングを組み込み、すべてのチェーンステップ、LLM呼び出し、トークン数、レイテンシを検索可能なトレースエクスプローラーに記録します。 ブラウザで直接実行するハンズオンコードでAI Engineering Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

AI Engineering Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAI Engineering Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「LangSmithによるトレーシング」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAI Engineering Academyレッスンでコードを書いて実行できますか?

はい。すべてのAI Engineering Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. LLMアプリのデバッグが難しい理由
  2. LangSmithによるトレーシング
  3. モデルに依存しない可観測性のためのLangfuse
  4. レイテンシ、コスト、品質低下へのアラート
← AI Engineering Academyに戻る