---
title: カスタマーサポートチャットボット
sidebarTitle: サポートチャットボット
description: 顧客に直接向き合うサポートチャットボットを段階的に展開する例です。過去チケットを使ったオフラインのテストから、社内での下書き運用、そして顧客への直接応答までを扱います。
translatedAt: 2026-08-19
---

# カスタマーサポートチャットボット

  これは [Langfuse Academy](/academy/japan) の概念を説明するための例です。

## 背景

ある SaaS 企業が、カスタマーサポートのチャットを自動化したいと考えています。
現在はサポートチームがすべての会話に応答しており、チケットシステムには何年分もの解決済みチケットが蓄積されています。
ボットは会社の名前で顧客に話すことになるため、悪い回答は 1 件の会話にとどまらない損害を与えます。顧客はサポート全体への信頼を失うからです。

このリスクがあるため、いきなり顧客向けにリリースする選択肢はありません。
代わりに、3 つのフェーズに分けて展開し、それぞれのフェーズで次に進むための確信を積み上げます。

| フェーズ      | 稼働しているもの                                           | 次のフェーズへのゲート                                                                                                     |
| ------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| 1. オフライン | なし。エージェントは開発中                                 | サポートチームが使いたいと思える水準の下書きができること                                                                   |
| 2. 社内       | エージェントが返信を下書きし、サポートチームが編集して送信 | 下書きと実際に送信された返信の差が、チケットのカテゴリを通じて小さいままであり、サポートチームからの定性的な評価も良いこと |
| 3. 顧客向け   | ボットが顧客に直接応答する                                 | なし。ここが最終目標であり、このフェーズではエージェントを継続的に改善し続ける                                             |

この段階的なアプローチによって、多くのリスクを抑えながら、本番のシグナルを早い段階で得られます。

## フェーズ 1: 最初のエージェントを作る

サポートチームに社内向けエージェントを実際に使ってもらうには、最初のバージョンの時点で彼らにとって有用である必要があります。
そこに到達するために、すでに手元にある解決済みチケットの豊富な過去データを活用できます。合成データの生成は不要です。

**AI エンジニアリング・ループ**

- **トレース** — まだ本番稼働していない
- **モニタリング** — まだ本番稼働していない
- **データセット構築** — 解決済みチケットから
- **実験** — プロンプトとリトリーバルのバリアント
- **評価** — 人間の返信と比較する

サポートチケットシステムの過去データにどんなパターンがあるかを AI で把握し、繰り返し現れる挙動ごとにいくつかのデータセットへまとめられます。

**データセット: howto-questions**

プロダクトの機能の使い方についての質問。返信では手順を説明し、該当するヘルプ記事へリンクします。

| 入力 | 期待される出力 |
| --- | --- |
| 繰り返しタスクはどう設定しますか? | 「繰り返しタスク」のヘルプ記事を参照する。タスクメニューで繰り返しスケジュールを設定するよう案内する。 |
| データを CSV にエクスポートできますか? | 「データのエクスポート」の記事を参照する。CSV エクスポートは Pro プランで利用できると伝える。 |

**データセット: account-changes**

顧客のプラン、シート数、権限に関わる依頼。返信では適切な設定画面と、誰が変更できるのかを示します。

| 入力 | 期待される出力 |
| --- | --- |
| 同僚をワークスペースに追加できません。招待時に 'seat limit reached' と表示されます。 | シート管理のドキュメントを参照する。退職したメンバーを無効化するか、Billing でシートを追加するよう案内する。 |
| ワークスペースのオーナー権限はどう移譲しますか? | 「ワークスペースの権限」のドキュメントを参照する。Settings → Members から移譲でき、管理者権限が必要だと案内する。 |

**データセット: troubleshooting**

顧客の期待どおりに動かないケース。返信では問題を切り分けるか、切り分けに必要な情報を尋ねます。

| 入力 | 期待される出力 |
| --- | --- |
| CSV エクスポートに、追加したカスタムフィールドが含まれていません。 | エクスポート設定のドキュメントを参照する。エクスポートダイアログで 'Export with custom fields' を選ぶよう案内する。 |
| 今朝からカレンダー連携の同期が止まっています。 | 連携名と最後に同期が成功した時刻を尋ね、ステータスページへのリンクを示す。 |

  複数のデータセットに分けるか、1 つにまとめるかは
  [トレードオフ](/academy/japan/datasets#what-makes-a-good-dataset) です。
  分けておくとユースケースごとに性能を測れ、必要なときに一部だけ実行できます。
  1 つの大きなデータセットが妥当な場合もあります。特に、最適な分け方がまだ見えていない初期はそうです。

ここから、[各バージョンをこれらのデータセットに対して実行しながら](/academy/japan/experiments#how-experiments-are-used) プロンプトを反復し、サポートチームが実際に有用だと感じる水準に下書きが届くまで進めます。
各実行は次の方法で採点します。

**評価者**

- `resolution_match` — LLM-as-a-Judge, 二値。データセットアイテムごと
  - 下書きは、人間の返信と同じ情報源を参照し、同じことを推奨しているか?
  - [参照あり](/academy/japan/evaluate#reference-based-vs-reference-free) の評価器です。期待出力が、人間の返信に含まれる情報源と推奨内容を比較対象として与えます。コードによるチェックではなく LLM-as-a-Judge でなければならないのは、2 つの返信がまったく違う言葉で同じことを推奨しうるからです。実行には期待出力が必要なので、これらのデータセットに対する実験は採点できますが、本番トラフィックには使えません。
- `links_valid` — コードベース, 二値。データセットアイテムごと
  - 下書きがリンクしているヘルプ記事が、すべてヘルプセンターに存在するか
  - 手動レビューで、存在しないヘルプ記事にリンクしている下書きが見つかったため追加しました。記事が存在するかどうかはヘルプ記事インデックスを引くだけなので、 [コードベース評価器で厳密に決着が付きます](/academy/japan/evaluate/writing-evaluators#make-it-verifiable) 。ミリ秒で終わり、コストもかかりません。期待出力も不要なので、後のフェーズでは本番の返信に対しても同じチェックを回し続けられます。
- `manual review` — 人手
  - 下書きのサンプルに対する感触の確認

ここでトーンを自動で判定していないことに注目してください。
これは意図的です。下書きの語り口が許容範囲かどうかは、いくつかの [手動チェック](/academy/japan/evaluate#how-evaluation-typically-evolves) で十分確認でき、トーンを完全に合わせ込むのはフェーズ 2 で行うからです。

評価器のスコアが十分に良く、手動レビューの結果も良ければ、エージェントをサポートチケットシステムに載せます。

次のセクションに進む前に、このときのトレースがどう見えるかを示します。

**draft-support-reply トレースの中にあるオブザベーション**

- [Trace] `draft-support-reply` (データセットアイテム: account-changes, 3.1s)
  - 入力: 「同僚をワークスペースに追加できません。招待時に 'seat limit reached' と表示されます。」
  - 出力: 「佐藤様、ご利用のプランのシート 10 件すべてが使用中です。Settings → Members から退職したメンバーを無効化するか、Billing でシートを追加していただけます。」
  - [Retriever] `find-similar-tickets` (0.5s)
    - 入力: チケット本文
    - 出力: 解決済みチケット 3 件: T-3107、T-2954、T-2381 (シート上限、メンバー追加)
  - [Retriever] `search-help-articles` (0.4s)
    - 入力: 「シート上限、シート追加」
    - 出力: 「シート管理」・「請求設定」
  - [Tool] `fetch-account-details` (0.3s)
    - 入力: ワークスペース W-2209
    - 出力: プラン: Team · シート: 10/10 使用中
  - [Gen] `draft-reply` (gpt-4.1, 1.4k tok, $0.01, 1.9s)
    - 入力: チケット本文 · アカウント情報 · ヘルプ記事 2 件 · 解決済みチケット 3 件
    - 出力: 「佐藤様、ご利用のプランのシート 10 件すべてが使用中です。Settings → Members から退職したメンバーを無効化するか、Billing でシートを追加していただけます。」

## フェーズ 2: 社内展開

このフェーズでは、届いたチケットごとにエージェントが返信を下書きし、サポートチームのメンバーがそれを使い、送信前に編集できます。
エージェントの下書きと、メンバーが実際に送信した内容の差分は、非常に信頼できる [ユーザーシグナル](/academy/japan/monitoring#user-feedback) として使えます。

もう 1 つ、より明示的なユーザーシグナルとして、下書きに対する良い・悪いのボタンがあります。チームはそこに書き込みのフィードバックを残すこともできます。

**AI エンジニアリング・ループ**

- **トレース** — すべての下書きをトレースする
- **モニタリング** — すべてのトレースに edit_type
- **データセット構築** — 大きく編集された下書きが新しいアイテムに
- **実験** — 繰り返される編集パターンへの対処
- **評価** — リリース前にデータセットを回し直す

どちらのシグナルも、下書きの [トレース](/academy/japan/tracing#anatomy-of-a-trace) に [スコア](/docs/evaluation/scores/overview) として記録されます。

**評価者**

- `edit_type` — LLM-as-a-Judge, カテゴリ。トレースに付与
  - 人手による編集を `none`、`tone`、 `corrected`、`added` に分類します
  - 下書きと送信された返信を比較する判定器です。`tone` はメンバーが言い回しを変えたが内容は保った場合、 `corrected` は誤りが削除または修正された場合、 `added` は下書きは残したうえで不足していた情報が追加された場合を指します。 言い換えと内容の変更を見分けるには両方のテキストを読む必要があるため、 判定器でなければなりません。他の判定器と同じく、これも最初は未検証の状態です。下書きと送信された返信のサンプルに手でラベルを付け、 [判定器が自分と同じように分類するかを確認](/academy/japan/evaluate/writing-evaluators#validate-the-judge) してください。
- `human_feedback` — 人手, 二値とコメント。トレースに付与
  - 下書きへの良い・悪いのボタン。任意で書き込みのフィードバック
  - チケットシステムのボタンから直接記録され、評価器は不要です。クリックそのものがスコアを書き込みます。書き込まれたコメントは、差分だけでは得られない文脈を与えてくれます。

スコアの悪いトレースは、その後に確認し、改善し、まだカバーされていなければデータセットに追加できます。
その進め方の 1 つが [エラー分析](/academy/japan/monitoring/error-analysis) のプロセスです。

ループを 1 周する例はこうなります。
[モニタリング](/academy/japan/monitoring#metrics-and-signals) で、`troubleshooting` カテゴリの `corrected` 下書きが急増していることが見えます。
トレースを見ると、ヘルプ記事のインデックスが古いために、エージェントが古いエクスポートダイアログを参照し続けていると分かります。
インデックスを更新し、`troubleshooting` データセットを回し直して修正を確認すると、`corrected` 下書きの割合が下がります。
ここから新しい評価器は生まれません。インデックスが古いことは [一度きりの修正](/academy/japan/evaluate/choosing-what-to-evaluate#fix-first) であって、追跡し続ける失敗モードではないからです。

編集される下書きの割合は、時間とともに下がっていくはずです。
すべてのチケットカテゴリで下書きがほぼ手を入れられずに送られるようになれば、エージェントは顧客に向き合う準備ができています。

## フェーズ 3: 顧客向けの展開

ボットが顧客に直接応答するようになると、フェーズ 2 を駆動していたシグナルは消えます。顧客が見る前に誰も返信を編集しないからです。
代わりに、学習と改善を続けるための暗黙的なユーザーシグナルをいくつか導入します。

  いきなり全面的に自動化するのではなく、フェーズ 2 のゲートを通過した依頼
  カテゴリだけを自動化し、残りはもうしばらくサポートチームを通す、という
  やり方もあります。

**AI エンジニアリング・ループ**

- **トレース** — すべての顧客との会話
- **モニタリング** — ユーザーシグナルとリスクの監視
- **データセット構築** — 良くなかった会話が新しいアイテムに
- **実験** — モニタリングで見えたものへの対処
- **評価** — リリース前にデータセットを回し直す

顧客がサポートチャットを評価してくれることはまれなので、主眼は暗黙的なユーザーシグナルを集めることに置きます。

**評価者**

- `handoff_requested` — LLM-as-a-Judge, 二値。トレースに付与
  - 顧客が有人対応を求めたことを検出します
  - 顧客は自由な文章で有人対応を求めるため、コードベース評価器が一致を取れる対象がありません。トレースを採点することで、顧客がボットを見限ったまさにそのターンに印が付きます。
- `question_repeated` — LLM-as-a-Judge, 二値。トレースに付与
  - 顧客が同じ質問を言い換えていることを検出します
  - [暗黙的フィードバック](/academy/japan/monitoring#user-feedback) の一種です。顧客が同じことを繰り返すのは、前の回答が届かなかったことを意味します。言い換えと追加の質問を見分けられるのは、会話を読む判定器だけです。
- `session_outcome` — LLM-as-a-Judge, カテゴリ。セッションに付与
  - 会話がどう終わったかを分類します
  - 会話が終了したときに実行され、`resolved`、 `abandoned`、`handed_off` のいずれかに分類します。3 つの終わり方はボットの性能にとってそれぞれ別の意味を持ち、かつ互いに排他的なので、 [重なり合う二値評価器を複数用意するのではなく、カテゴリ評価器を 1 つ](/academy/japan/evaluate/writing-evaluators#binary-verdicts) にしています。結果は会話全体に属するものなので、トレースではなくセッションに対して採点します。

人手がループから外れたので、評判を損ないうる挙動がないかをすべての返信について監視します。
この 2 つの評価器は、観測された失敗ではなく [絶対条件](/academy/japan/evaluate/choosing-what-to-evaluate#goals-and-hard-constraints) から来ています。どちらも一度も検知したことがありませんが、初日から存在します。
これらは何かをブロックするものではありません。送信済みの返信に印を付け、チームが顧客へすばやくフォローアップできるようにするものです。

**評価者**

- `data_leak` — LLM-as-a-Judge, 二値。トレースに付与
  - 返信が、この顧客以外に関するデータを明かしていないか?
  - [参照なし](/academy/japan/evaluate#reference-based-vs-reference-free) なので、期待出力なしで本番のすべての返信に対して実行できます。どんな言い回しであれ個人データを認識するには言語理解が必要なため、 LLM-as-a-Judge を使います。
- `out_of_scope_help` — LLM-as-a-Judge, 二値。トレースに付与
  - 返信が、引き継ぎではなく返金・割引・約束を提示していないか?
  - これも参照なしで、本番のすべての返信に対して実行します。キーワードチェックではなく判定器を使うのは、約束の言い方が無数にあるからです。 「来月には対応します」には禁止語が 1 つも含まれていません。

これらのシグナルがそろえば、エージェントを継続的に改善する良い体制になります。
良くなかった会話が表に出て、改善され、データセットアイテムになり、構造的にテストできるようになります。
チームはこの体制を使って、より新しい/安い/速いモデルを安全に試し、デプロイするかどうかを根拠を持って判断することもできます。

## まとめ

顧客に直接向き合う自動化は、リスクの高さゆえに立ち上がらないことがよくあります。
この例は、それを現実的に実現するためのベストプラクティスを、継続的な学習と改善を前提に整理したものです。

[他の例](/academy/japan/examples) や [Academy](/academy/japan) も参照してみてください。

<!-- agent-instructions -->

---

## Agent Instructions

This page is part of the [Langfuse](https://langfuse.com) documentation, published as plain Markdown for AI agents. Every page is available as Markdown by appending `.md` to its URL, or by sending an `Accept: text/markdown` header. This page: `https://langfuse.com/academy/japan/examples/customer-support-chatbot.md`.

### Querying these docs

If the answer is not on this page, query the documentation instead of guessing:

- **Semantic search** across all Langfuse docs, returning an answer with the relevant pages and excerpts. Ask a specific, self-contained question:

  ```bash
  curl -sG "https://langfuse.com/api/search-docs" --data-urlencode "query=How do I trace a LangGraph agent?"
  ```

- **Index of every page**: <https://langfuse.com/llms.txt>, with per-section indexes [llms-docs.txt](https://langfuse.com/llms-docs.txt), [llms-integrations.txt](https://langfuse.com/llms-integrations.txt), and [llms-self-hosting.txt](https://langfuse.com/llms-self-hosting.txt).

### Before writing Langfuse code

- **Install the [Langfuse Agent Skill](https://langfuse.com/docs/api-and-data-platform/features/agent-skill).** It encodes Langfuse's own best practices for instrumentation, prompt management, and evaluation, and materially improves results.
- **Read [What does a good trace look like?](https://langfuse.com/docs/observability/best-practices.md)** before instrumenting an application.
- **Verify endpoints, parameters, and response fields** against the [API reference](https://api.reference.langfuse.com) instead of inferring them from code examples.
- **Use the [Langfuse CLI](https://langfuse.com/docs/api-and-data-platform/features/cli)** (`npx langfuse-cli api <resource> <action>`) to read or write traces, prompts, datasets, and scores from the terminal.

Found an error in these docs? Please open an issue at <https://github.com/langfuse/langfuse-docs/issues>.
