実行プログラムと拡張機能

Langfuseでローカルエージェントの遅い処理を見つける

1回の回答にかかった時間をモデル・検索・ツールに分けると、遅い箇所を調べやすくなります。

Langfuseはアプリが明示的に送信したトレースイベントを表示します。ローカルインスタンスとPython SDK v4を使う場合、API1のbase URLをそのインスタンスに設定し、@observeで関数呼び出しを記録します。Langfuseを導入しただけで任意のOllamaリクエストが自動記録されるわけではありません。計測した入出力に個人情報や文書内容が含まれる可能性があるため、記録項目を選び機密値をマスクしてください。

ローカルエージェントのモデル呼び出し・ファイル読み込み・ツール実行のどこで待つか調べるときにLangfuseを使います。Python SDKのイベントから各段階の開始・終了・所要時間を確認できます。以下ではローカルOllamaと合成ファイルを計測し、入力・出力本文は記録しません。

実行条件と要点
  • trace全体の時間にはキュー待機、ツール、モデル準備、生成が含まれる場合があります。
  • 新しい計測ではPython SDK v4の@observeとget_client()を使い、旧trace() APIの例を混在させません。
  • Langfuseの入出力に機密情報が記録されないよう、計測する範囲を自分で決めます。

応答全体の時間を処理段階に分ける

エージェントが遅い原因は、トークン2生成とは限りません。検索、ファイル読み込み、ツール待機、再試行、回答生成が順に発生します。Langfuse traceに各段階を記録すると、同じテスト入力でどの区間が長くなったか確認できます。

書類・表・メールのアイコンからノートPCの横のロボットへ矢印が伸びる作業台
段階ごとの時間を記録すると、リクエスト全体の遅延原因を探しやすくなります。

ローカルインスタンスを起動しSDK計測環境を準備する

リポジトリルートのdocker-compose.ymlで# CHANGEMEが付いた値をすべて置き換えます。Webサービスのportsを127.0.0.1:3000:3000に制限し、NEXTAUTH_URLもhttp://localhost:3000に設定します。docker compose up -dとdocker compose psを実行し、ポートが127.0.0.1:3000->3000/tcpと表示されることを確認します。

docker compose logs -f langfuse-webにReadyと表示されたら、ブラウザーでhttp://localhost:3000を開きます。サインアップ画面で最初のユーザーを作成し、プロジェクトのSettings → API Keysで公開キーとシークレットキーを発行します。

Langfuse Composeリポジトリを準備
git clone https://github.com/langfuse/langfuse.git langfuse-local
cd langfuse-local
# 저장소 루트 docker-compose.yml에서 # CHANGEME 값을 바꾸고 NEXTAUTH_URL을 맞춰요.
リポジトリを準備し、次のポート割り当てをUIサービスに適用します。
UIサービスのloopback専用ポート割り当て
ports:
  - "127.0.0.1:3000:3000"
Composeで3000番ポートを公開するUIサービスの既存ports項目を置き換えます。
Langfuseを起動してポートを確認
docker compose up -d
docker compose ps
docker compose logs -f langfuse-web
PORTS欄に127.0.0.1:3000->3000/tcpが表示されたらhttp://localhost:3000を開きます。
小さなロボット装置がブラウザー・カレンダー・メッセージ画面につながる机
UIと計測SDKが同じローカルインスタンスを指すよう接続先を合わせます。

SDK v4でモデル呼び出しとツール処理を記録する

Python環境にlangfuseとrequestsをインストールし、プロジェクトの公開・秘密APIキー、LANGFUSE_BASE_URL=http://localhost:3000、取得済みのOllamaモデルIDを環境変数に設定します。@observeが親request spanを作り、get_client()のcontext managerがOllama generationとファイル読み込みtoolをその下に記録します。本文は入出力に設定せず、状態と文字数だけをmetadataに残します。

SDKと環境変数を準備
python -m venv .venv
source .venv/bin/activate
python -m pip install -U langfuse requests
export LANGFUSE_PUBLIC_KEY='pk-lf-project-key'
export LANGFUSE_SECRET_KEY='sk-lf-project-secret'
export LANGFUSE_BASE_URL='http://localhost:3000'
export OLLAMA_MODEL='YOUR_INSTALLED_MODEL_ID'
キーはプロジェクト設定からコピーし、ollama listに表示されたモデルIDを指定します。

環境変数を設定してから以下をrun_trace.pyに保存します。固定プロンプト3でOllamaを1回呼び、合成テキストファイルを読みます。traceには2段階の所要時間と状態だけを残します。

run_trace.py: Ollamaと合成ファイル読み込みを計測
import os
from pathlib import Path
import requests
from langfuse import get_client, observe, propagate_attributes

MODEL = os.environ['OLLAMA_MODEL']
langfuse = get_client()

@observe(name='local-agent-request', as_type='span', capture_input=False, capture_output=False)
def run_trace():
    with propagate_attributes(trace_name='local-agent-toy', session_id='toy-session-1'):
        with langfuse.start_as_current_observation(as_type='generation', name='ollama-chat', model=MODEL) as generation:
            response = requests.post('http://127.0.0.1:11434/api/chat', json={'model': MODEL, 'stream': False, 'messages': [{'role': 'user', 'content': 'Reply with exactly: local trace test'}]}, timeout=120)
            response.raise_for_status()
            generation.update(metadata={'http_status': response.status_code})
        with langfuse.start_as_current_observation(as_type='tool', name='read-toy-file') as tool:
            text = Path('fixture.txt').read_text(encoding='utf-8')
            tool.update(metadata={'file': 'fixture.txt', 'characters': len(text)})
        print('Ollama status:', response.status_code, '| fixture characters:', len(text))

run_trace()
langfuse.flush()
このコードをrun_trace.pyとして保存します。fixture.txtには合成文だけを入れ、プロンプト・応答本文ではなくモデル名・HTTP状態・文字数だけを記録します。
合成ファイルを作りtraceを送信
printf '%s\n' 'Synthetic fixture for a local tracing example.' > fixture.txt && python run_trace.py
成功するとHTTP 200と文字数が表示され、Langfuseにlocal-agent-toy traceが作成されます。

機密性のない固定入力でtraceを確認する

Tracesにlocal-agent-toyが表示されたら開き、親span、その子のollama-chat generationとread-toy-file tool、各所要時間と記録されたmetadataを確認します。

最初に401/403が出たら、公開・秘密キーが同じプロジェクトのものか、API URLがhttp://localhost:3000か確認します。接続エラーではサービス状態とdocker compose psのPORTSを、Ollamaエラーではcurl http://127.0.0.1:11434/api/tagsの応答を確認します。

合成プロンプトとfixtureだけを使い、文書本文やモデル応答をtraceの入出力には設定しません。

色付きブロックの入った開いた棚、ゴミ箱、チェックリストのノートと並べたブロック
1つのtraceの段階別時間を比べ、モデル処理とツール待機を区別します。

用語の注釈

  1. API — 別のコードからプログラムの機能を呼び出すための決められたインターフェースです。

    本文に戻る
  2. トークン — モデルが入力や出力を分けて処理する単位です。

    本文に戻る
  3. プロンプト — モデルに送る入力文です。生成モデルでは作りたい結果を説明する文になり、出力の構成や内容を大きく左右します。

    本文に戻る

よくある質問

この記事で最初に確認すべきことは何ですか?
Langfuseはアプリが明示的に送信したトレースイベントを表示します。ローカルインスタンスとPython SDK v4を使う場合、APIのbase URLをそのインスタンスに設定し、`@observe`で関数呼び出しを記録します。Langfuseを導入しただけで任意のOllamaリクエストが自動記録されるわけではありません。計測した入出力に個人情報や文書内容が含まれる可能性があるため、記録項目を選び機密値をマスクしてください。