Difyの会話ログをCSV出力・分析する方法

    こんにちは。横田です。

    Difyで作ったチャットアプリを社内やクライアント様に展開していると、結構よく聞かれるのが「会話ログをエクスポートしたい」「過去の会話を分析したい」というリクエストです。

    Difyの管理画面の「ログ」タブから会話単位での履歴は見られるのですが、残念ながらデフォルトではCSVエクスポート機能がついていません
    1件ずつ目視で確認するだけならいいのですが、件数が増えてきたり、定期的に分析したいとなると、何かしらの方法でログを引っ張り出してくる必要があります。

    本記事では、セルフホスト版Difyを前提に、実案件で実際に試した 4つのアプローチ(公式API / PostgreSQL直クエリ / Langsmith・Langfuse / Pythonスクリプト)を比較し、用途別におすすめの方法を整理してみました。

    📌 対象環境:本記事はセルフホスト版Dify(Docker Composeで構築するOSS版)を前提にしています。Dify Cloud では DB への直接アクセスができないなど一部の方法は使えませんので、ご注意ください。

    管理画面のログ機能の限界

    Difyの管理画面には「ログ」タブがあり、各アプリの会話履歴をブラウザ上で確認できます。1件ずつ会話の流れを追うには便利な機能ですが、運用していると次のような不満が出てきます。

    • CSV / Excel エクスポートがない(個別コピペは現実的ではない)
    • 件数が増えるとUIが重くなる
    • 会話横断での全文検索が弱い(特定キーワードの出現頻度の集計など)
    • 定期的に分析するワークフローに組み込めない

    つまり「ちょっと見るだけ」ならOK、「分析・継続運用」になると別の手段が必要、というのが実情です。

    4つの取得方法 比較表

    先に結論を表でまとめます。詳細は次節以降で解説します。

    方法 難易度 向いている用途
    ① 公式API ★★☆ 単発エクスポート・運用ツール組み込み
    ② PostgreSQL直クエリ ★★★ 大量データの一括取得・集計分析
    ③ Langsmith / Langfuse ★☆☆ 継続監視・デバッグ・トークン分析
    ④ Pythonスクリプト ★★☆ 定期エクスポート・CSV化自動化

    💡 ざっくり結論:手早く取り出すなら「① API」、
    大量データを集計分析するなら「② PostgreSQL直クエリ」、
    運用しながらデバッグや観測もしたいなら「③ Langsmith / Langfuse」、
    定期実行で自動化したいなら「④ Python」がそれぞれ最短ルートです。

    方法① 公式API(一番おすすめ)

    ドキュメントもしっかりしていて、セルフホスト環境のDifyにそのまま使えるので、まずはここから検討するのが無難です。

    APIキーの取得

    Difyアプリの管理画面 → 左メニュー「アプリの API アクセス」を開くと、API Base URL とシークレットキー(APIキー)が表示されます。これを使ってリクエストを投げます。

    会話一覧を取得

    GET /v1/conversations?user={USER_ID}&limit=100
    
    Authorization: Bearer {API_KEY}

    user パラメータには、ChatアプリでメッセージをやりとりするときにDifyに渡したエンドユーザーIDを指定します。limit は最大100、それ以上は last_id でページネーションして取得します。

    各会話のメッセージを取得

    GET /v1/messages?conversation_id={CONV_ID}&user={USER_ID}&limit=100
    
    Authorization: Bearer {API_KEY}

    レスポンスには query(ユーザー発言)、answer(AI回答)、created_atmetadata(トークン消費・遅延など)が含まれます。

    ⚠️ 注意:API は user 単位で会話を取得する仕組みです。「全ユーザーの全会話を一括取得する」エンドポイントは現状ありません。全件まとめて欲しいときは、次に紹介する SQL 直クエリを使うか、Python で user リストを順にループ取得するアプローチが必要になります。

    方法② PostgreSQL を直接SQLで叩く

    セルフホスト環境ならではの方法で、SQLで全件・横断的に取得できるのが圧倒的なメリットです。データ分析や統計を取りたいなら、これが一番素直で速いです。

    DBに接続する

    Docker Compose で立てている場合、以下のコマンドでPostgreSQLコンテナに入れます。

    docker exec -it docker-db-1 psql -U postgres -d dify

    コンテナ名はバージョンによって dify-db-1 等になっているので、docker ps で確認してください。

    主要なテーブル

    会話ログ取得で使うのは主に次の2テーブルです。

    テーブル 主なカラム 内容
    conversations id / app_id / from_end_user_id / name / created_at 会話セッションの単位
    messages id / conversation_id / query / answer / message_tokens / answer_tokens / total_price / created_at 1往復ごとのメッセージ本体

    サンプルクエリ:特定アプリの全会話をCSV化

    \copy (
      SELECT
        c.id            AS conversation_id,
        c.name          AS conversation_name,
        c.from_end_user_id,
        m.created_at,
        m.query         AS user_message,
        m.answer        AS ai_answer,
        m.message_tokens,
        m.answer_tokens,
        m.total_price
      FROM messages m
      JOIN conversations c ON c.id = m.conversation_id
      WHERE c.app_id = 'YOUR_APP_UUID'
      ORDER BY c.created_at, m.created_at
    ) TO '/tmp/dify_logs.csv' WITH CSV HEADER;

    \copy を使うと、psql 内から直接CSVファイルに書き出せます。Dockerコンテナ内の /tmp/ に出力されるので、docker cp でホスト側に取り出すか、ボリュームマウントしているディレクトリに出力するのがラクです。

    ⚠️ 自己責任ゾーン:DBに直接アクセスする方法は、Difyのバージョンアップでスキーマが変わるリスクがあります。本番運用に組み込むより、「分析のために月1回ダンプを取る」くらいの使い方がおすすめです。書き込みは絶対にしないでください。

    方法③ Langsmith / Langfuse などの観測ツール

    Difyは v0.6.12 から、Langsmith(LangChain社のObservabilityサービス)と Langfuse(OSSのLLM観測ツール)の両方に対応しています。これらと連携すると、会話ログだけでなく トークン消費・実行時間・各ノードの中間出力 まで自動で記録してくれます。

    設定はクリック数手順だけ

    1. Langsmith / Langfuse 側でプロジェクトを作成し、API Key を発行
    2. Difyアプリ管理画面 → 左メニュー「監視」 → 「トレースアプリパフォーマンス」
    3. API Key とプロジェクト名を貼り付けて保存

    これだけで、以降のすべての会話が自動で外部ツールに送信され、ダッシュボードで可視化されます。

    こんなときに向いている

    • 会話のどのノードで時間がかかっているのか調べたい
    • 本番運用で月いくらかかっているのか(トークン消費)を可視化したい
    • 失敗した会話やエラー時の挙動をピンポイントで確認したい
    • RAGの retrieval(検索)結果をトレースしたい

    ✅ 個人的なおすすめ:Langfuse はセルフホスト可能でOSSのため、機密データを扱う案件にも導入しやすいです。
    Cloudの無料枠でも結構な量を捌けるので、「観測したいけど予算は抑えたい」場合は Langfuse から試すのがおすすめです。

    ただし、Langsmith / Langfuse は観測・モニタリング目的のツールであり、整ったCSVをスポットでダウンロードする用途には完全には向きません。エクスポート機能はあるものの、「整形して分析資料を作る」フェーズでは結局SQLや次のPythonスクリプトに頼ることになります。

    方法④ Pythonスクリプトで定期エクスポート

    「毎週月曜にCSVを自動生成してSlackに投げたい」みたいな定期的なエクスポートをしたい場合は、公式APIをPythonでラップしてスクリプト化するのが現実的です。Difyサーバーと同じネットワーク内のマシンや、CIサーバー(GitHub Actions等)から実行する構成にしておくと運用がラクになります。

    最小サンプルコード

    import os
    import csv
    import requests
    
    API_BASE = "https://api.dify.ai/v1"  # self-host なら自社ドメインに差し替え
    API_KEY  = os.environ["DIFY_API_KEY"]
    USER_ID  = "your-end-user-id"
    
    HEADERS = {"Authorization": f"Bearer {API_KEY}"}
    
    
    def fetch_conversations(user_id: str) -> list:
        """ユーザー単位で会話一覧を全件取得"""
        convs, last_id = [], None
        while True:
            params = {"user": user_id, "limit": 100}
            if last_id:
                params["last_id"] = last_id
            r = requests.get(f"{API_BASE}/conversations", headers=HEADERS, params=params)
            r.raise_for_status()
            data = r.json()
            convs.extend(data["data"])
            if not data.get("has_more"):
                break
            last_id = data["data"][-1]["id"]
        return convs
    
    
    def fetch_messages(conv_id: str, user_id: str) -> list:
        """会話単位でメッセージを全件取得"""
        r = requests.get(
            f"{API_BASE}/messages",
            headers=HEADERS,
            params={"conversation_id": conv_id, "user": user_id, "limit": 100},
        )
        r.raise_for_status()
        return r.json()["data"]
    
    
    def export_to_csv(user_id: str, out_path: str):
        with open(out_path, "w", encoding="utf-8", newline="") as f:
            w = csv.writer(f)
            w.writerow(["conversation_id", "created_at", "query", "answer"])
            for c in fetch_conversations(user_id):
                for m in fetch_messages(c["id"], user_id):
                    w.writerow([c["id"], m["created_at"], m["query"], m["answer"]])
    
    
    if __name__ == "__main__":
        export_to_csv(USER_ID, "dify_logs.csv")
        print("✅ 完了:dify_logs.csv")

    このスクリプトを cron / launchd / GitHub Actions 等で定期実行すれば、毎日・毎週のエクスポートが自動化できます。あとはお好みで Slack 通知や Google Sheets への投入を組み合わせると、運用ツールとして完成形になります。

    結局どれを選べばいい?

    用途別のおすすめをまとめると、こんな感じです。

    やりたいこと おすすめの方法
    いますぐ手元にログを落としたい(一回きり) ① API を Postman / curl で叩く
    全件・横断的に分析したい ② PostgreSQL に \copy でCSV出力
    本番運用中、性能・コストを継続監視したい ③ Langfuse(無料枠あり)または Langsmith
    毎週CSV自動生成・社内共有したい ④ Python + cron で定期実行
    機密データを社外サービスに出したくない ② SQL or ③ Langfuse セルフホスト

    個人的には、「とりあえずAPIで取れる形にしておいて、分析が大事になってきたらSQLやLangfuseを組み合わせる」という育て方が、後戻りが少なくてよい印象です。

    まとめ

    Difyの会話ログ取得、改めてポイントを整理すると:

    • 管理画面ではCSVエクスポートできない → 別手段が必要
    • 公式APIはドキュメントも整っていて一番安全な選択肢
    • PostgreSQL直クエリはセルフホストならではの強力な手段(書き込みは厳禁)
    • Langsmith / Langfuseは観測・デバッグ用途で強い味方になる(Langfuseはセルフホストも可能)
    • Python + cronで定期エクスポートを自動化すると運用がぐっとラクになる

    「ログが取れないとDifyの活用が広がらない」というご相談はとても多いのですが、上記の組み合わせでだいたい解決できるはずです。社内案件・PoCで困っている方の参考になれば幸いです。

    バイタリフィでは、Difyを活用したAIチャットアプリの設計・構築から、ログ分析基盤の構築まで支援しています。「会話ログを使って改善サイクルを回したい」「BIツールに繋ぎたい」といったご相談があれば、お気軽にお問い合わせください。