メインコンテンツにスキップ
株式会社ゼットリンカー - Next.js システム開発専門
AI開発

顧客対応履歴をNext.js×AIで検索できる仕組みの設計

Conclusion

顧客対応履歴はベクトル検索で「意味」から探せます。1窓口・直近1年分から始め、個人情報保護とアクセス制御を最初から組み込むのが安全です。

結論、顧客対応履歴の検索は「全文一致」ではなく「意味で探す」設計に切り替えると、過去のやり取りが埋もれなくなります。Next.js×ベクトルDBで顧客対話ログを検索可能にする設計と、社内マニュアル検索との違い、着手範囲の決め方を実務目線で整理します。

14分で読めます
Next.jsNext.jsAI駆動開発中小企業ベクトル検索顧客対応

「あのお客様、去年似たような問い合わせをしていた気がするけど、どの担当者とのやり取りだったか思い出せない」——受託でお客様対応の仕組みをお預かりしていると、こういう相談を年に何度もいただきます。メールとチャットと電話メモが別々の場所にあり、担当者の記憶だけが頼りになっている状態です。

先に、この記事の要点をまとめます。

  • **顧客対応履歴の検索が難しいのは、問い合わせの言い回しが毎回違うから。**キーワードが一語一句一致しないと探せない検索では「先月と同じ内容」の過去ログを取りこぼす
  • ベクトル検索(意味で探す仕組み)を顧客対話ログに適用すると、表現が違っても近い内容の過去のやり取りを拾える。ただし、社内マニュアル検索とはデータの性質が違うため、同じ設計をそのまま流用すると精度が落ちる
  • 着手は「特定の窓口・直近1年分」のような絞った範囲から始め、使いながら対象を広げるのが現実的

ただし、1つ注意点があります。顧客対話ログは社内マニュアルと違って「個人情報を含む」「担当者ごとに書き方の癖がある」「未解決のまま放置された相談も混ざる」という固有の難しさがあります。ここを甘く見て設計すると、検索結果に個人情報が漏れて出てきたり、精度の低い検索になったりします。後半で具体的な対処を説明します。

本記事は2026年8月時点の情報をもとに、Next.js × ベクトルDBで顧客対応履歴を検索可能にする設計を、エンジニアと発注側の両方の目線で整理します。中小企業で複数の担当者が同じお客様に対応する体制を組んでいる情シス担当者の方へ、特に読んでいただきたい内容です。

なぜ顧客対応履歴の検索は難しいのか?

同じ内容の問い合わせでも、聞き方が毎回違うため、キーワードの一致だけを頼りにした検索では過去ログを見つけられないことが多いからです。

たとえば「請求書の宛名を間違えた」という相談は、「請求書 宛名 間違い」と検索して探すことを想定しがちですが、実際のお客様や担当者の記録には次のような表現で残っています。

  • 「発行済みの請求書、会社名の表記を直してほしいとのご要望」
  • 「インボイスの宛先訂正の件で折り返し予定」
  • 「請求先名義変更の対応、経理部に確認中」

言葉としては一致する単語がほとんどありません。人間なら「同じ話だ」とすぐ分かりますが、キーワード検索のシステムはそう判断できません。この結果、「同じような相談が過去にもあったはずなのに、検索しても出てこない」という状態が起き、毎回ゼロから調べ直すことになります。

この問題が実害になるのは、担当者が異動・退職したときです。属人的な記憶に依存していた顧客対応の経緯が、検索できない形でログに埋もれたまま引き継がれなくなります。新しく担当になった人は、同じ質問をお客様に何度もすることになり、「前にも同じことを話したのに」という不満につながります。

ベクトル検索は何を解決するのか?

単語の一致ではなく「意味の近さ」で検索するため、表現が違っても同じ内容のやり取りを見つけられます。

ベクトル検索は、文章を「意味を数値化した座標(ベクトル)」に変換して保存し、検索クエリも同じ方法で座標に変換した上で、近い座標を持つ文章を探す仕組みです。「請求書の宛名を間違えた」と「インボイスの宛先訂正」は、単語こそ違いますが意味的には近い場所に配置されるため、片方で検索してももう片方が見つかります。

顧客対応履歴のベクトル検索基盤が、メール・チャット・電話メモという3つの入力チャネルと、検索・要約・関連案件表示という3つの活用先をつなぐハブになっている構成

この仕組み自体は、社内マニュアルをAIで検索可能にするで扱った社内文書検索と技術的な土台は共通しています。ただし、対象データが「マニュアル」から「顧客対話ログ」に変わることで、設計上の注意点がいくつか変わります。

マニュアル検索と顧客対応履歴検索は何が違うのか?

マニュアルは「正解が1つに定まった静的な文書」なのに対し、顧客対応履歴は「同じお客様の状況が時系列で変化していく動的な記録」だという点が最大の違いです。

マニュアル検索では、最新版の文書さえ正しく索引化されていれば、検索結果の信頼性は保たれます。一方、顧客対応履歴の検索では、次のような違いを意識した設計が必要です。

  • 時系列の重み付けが要る:3年前の相談と先月の相談が同じ重みで検索結果に並ぶと、担当者は混乱します。基本は新しいやり取りを優先し、古いものは参考情報として下位に表示する設計にします
  • 担当者・部署のメタデータが不可欠:「誰が」「いつ」「どの案件で」対応したかが分からない検索結果は、業務では使い物になりません。マニュアル検索以上に、メタデータの設計比重が上がります
  • 未解決・保留中の案件が混在する:マニュアルは公開時点で完結していますが、顧客対応ログには「まだ回答待ち」の相談も混ざります。検索結果にステータス(対応済み/保留中)を表示しないと、解決済みの話だと誤認するリスクがあります
  • 個人情報を含む前提で設計する:氏名・連絡先・場合によっては契約内容の詳細が本文に含まれます。マニュアル検索より一段厳しいアクセス制御が前提になります

ここで一度お知らせ

15分のカジュアル相談

事例・要件未定でもOK/営業はしません/所要時間15分

カジュアルに相談する

個人情報を含むデータで検索を作るときの注意点は?

検索結果に表示する範囲を「役職・部署に応じて絞る」ことと、外部APIに送るデータから個人情報を除去する下処理の両方が必要です。

顧客対話ログをベクトル検索の対象にする際、最初に決めるべきはアクセス制御の設計です。全社員が全顧客の対応履歴を検索できる状態は、多くの企業でセキュリティポリシー上望ましくありません。担当している顧客・部署の範囲に検索結果を絞る仕組みが必要です。これは社内システムの権限設計で説明したRBAC(役割に基づくアクセス制御)の考え方をそのまま応用できます。

もう1つの論点が、外部のAI APIにデータを送る場合の下処理です。ベクトル化や要約生成でAnthropicやOpenAIのAPIを呼ぶ設計にする場合、次のような配慮が実務上求められます。

  • 契約書・利用規約でAPI提供元がデータを学習に使わない条項になっているかを確認する(多くの法人向けAPIプランはデフォルトで学習利用オプトアウトですが、契約内容は必ず確認します)
  • 氏名・電話番号など、検索精度に不要な個人情報はベクトル化前にマスキングする(メタデータとして別テーブルに保持し、表示時だけ突合する設計が安全です)
  • 監査ログを残す:誰がいつどの顧客の対応履歴を検索したかの記録を残しておくと、後から問題が起きた際の追跡ができます

この3点は「検索精度を上げるための工夫」ではなく「作る前提として最初から組み込むべき設計」です。後から追加しようとすると、既存データの再処理が必要になり手戻りが大きくなります。

どこから着手するのが現実的か?

特定の1窓口・直近1年分のデータからスモールスタートし、検索してみた手応えを確認してから対象範囲を広げるのが現実的です。

全部署・全期間のデータを一度にベクトル化しようとすると、次の理由でうまくいかないことが多いです。

  1. データの形式がバラバラ:メールはテキスト、チャットはSaaSのエクスポート形式、電話メモは担当者ごとの手書きメモとフォーマットが違い、統合の下処理だけで想定以上の工数がかかる
  2. 精度検証がしづらい:一度に大量のデータを入れると、検索結果の質が良いのか悪いのか判断する基準が作りづらい
  3. 費用感が見えにくい:ベクトル化・保存・検索のいずれも処理量に応じて費用が発生するため、小さく始めて費用感を掴んでから広げる方が予算計画を立てやすい

実務では、次のような順序で進めるプロジェクトが多い印象です。

  1. 1つの窓口(たとえばカスタマーサポート窓口)に絞り、直近1年分のメール・チャットログだけを対象にする
  2. 検索UIを最小構成で作り、実際の担当者に1〜2週間使ってもらう
  3. 「見つからなかった」フィードバックを集めて、チャンク(文章の分割単位)の粒度やメタデータの設計を調整する
  4. 手応えが確認できたら、対象期間や他の窓口(営業部門の商談ログなど)に広げる

私たちが受託で関わった案件の範囲でも、最初から全社統合検索を目指すよりも、この段階的な進め方の方が結果的に完成までの期間が短くなる傾向があります。範囲を絞ることで、精度の調整サイクルを何度も回せるためです。

なお、検索ではなく「複数のやり取りをまたいで一つの回答に要約させたい」というニーズもあります。たとえば「このお客様、これまでどんな相談をしてきたか」を1つのサマリーとして見たい場合は、検索結果を並べるだけでなく、AI SDKを使った要約生成を組み合わせる設計になります。この使い分けは社内規定を参照して回答するチャットボットで扱った「検索」と「対話・要約」の役割分担と同じ考え方です。

Next.jsではどう構成するか?

顧客対応データの取り込み処理と、検索・表示の画面を分離し、取り込み側はバッチ処理、検索側はServer Componentsで完結させる構成が扱いやすいです。

構成要素を分けて考えると次のようになります。

  • データ取り込み層:メール・チャットのAPI連携やCSVインポートから、対話ログを取得しチャンク分割・ベクトル化してDBに保存する。リアルタイム性は不要なため、日次や数時間おきのバッチ処理で十分なケースがほとんどです
  • 検索・表示層:担当者が検索する画面。Next.jsのServer Componentsで検索クエリを受け取り、ベクトルDBに問い合わせて結果を表示します。アクセス制御はここでRBACの権限情報と突合させます
  • 要約生成層(任意):検索結果をさらに1つの回答にまとめたい場合、AI SDKで生成AIの呼び出しを行う層を別に持たせます

この3層を最初から密結合にせず、取り込み層だけ先に作って手動でデータを流し込み、検索層で精度を確認してから要約生成層を足す、という順番で進めると、途中でどこに問題があるか切り分けやすくなります。取り込み層のデータ品質が悪いまま検索層を作り込んでも、後から手戻りになるだけです。

検索・表示層のRoute Handlerは、次のように「クエリのベクトル化」「検索」「アクセス制御での絞り込み」の3ステップで組むのが基本形です。

// app/api/customer-search/route.ts のイメージ(簡略化)
import { NextResponse } from 'next/server';
import { getSessionUser } from '@/lib/auth';

export async function POST(request: Request) {
  const user = await getSessionUser(request);
  const { query } = await request.json();

  // 1. 検索クエリをベクトル化
  const embedding = await embeddingClient.create({ input: query });

  // 2. ベクトルDBで類似する対話ログを検索
  const results = await vectorDB.query({
    vector: embedding.data[0].embedding,
    topK: 10,
    // 3. RBACの担当範囲でメタデータをあらかじめ絞り込む
    filter: { assignedTeam: { $in: user.accessibleTeams } },
  });

  return NextResponse.json({
    results: results.map((r) => ({
      snippet: r.metadata.snippet,
      customerName: r.metadata.customerName,
      status: r.metadata.status, // 対応済み / 保留中
      updatedAt: r.metadata.updatedAt,
    })),
  });
}

ポイントは、ベクトルDBへの問い合わせと同時に filter でアクセス制御をかけている点です。検索結果を取得してからアプリ側でフィルタリングする実装も見かけますが、それだと権限外のデータが一瞬でもサーバーのメモリに乗ってしまいます。問い合わせの時点で絞り込む設計の方が安全です。

よくある失敗パターン

実際にこの手の仕組みを作る中で、次のような失敗をよく見かけます。

  • チャンクの分割単位が対話ログに合っていない:マニュアル向けの「数百文字ごとに機械的に分割」する方法をそのまま流用すると、1つの相談のやり取りが複数のチャンクにバラバラに分割され、文脈が失われます。対話ログは「1件の問い合わせ=1チャンク」を基本単位にする方が精度が安定します
  • ステータス表示を後回しにする:検索結果に「対応済み」か「保留中」かの表示を付けずにリリースしてしまい、担当者が解決済みだと誤認してお客様への回答が止まってしまうケースがあります。ステータス表示は最初のリリースから含めるべき項目です
  • アクセス制御をUI側だけで実装する:画面上は担当外の顧客データを非表示にしていても、APIのレスポンス自体に権限外データが含まれていると、開発者ツールから閲覧できてしまいます。フィルタリングは必ずサーバー側・DBへの問い合わせ時点で行います

まとめ

この記事で持ち帰れることは、次の3点です。

  • 顧客対応履歴の検索が使われない理由と、ベクトル検索がそれをどう解決するかを説明できる(表現の違いを意味で吸収する仕組みだと理解した上で判断できる)
  • 社内マニュアル検索と顧客対応履歴検索の設計上の違い(時系列の重み・メタデータ・未解決案件の扱い・個人情報保護)を区別して考えられる
  • 着手範囲の決め方(1窓口・直近1年分から始めて広げる進め方)が分かり、いきなり全社統合を目指さなくてよいと判断できる

今日ひとりでできることを1つ挙げるなら、直近1ヶ月分の顧客対応履歴(メールでもチャットログでも構いません)を眺めて、「同じような相談が過去にもあった気がするけれど、探すのに時間がかかった」というケースが実際に何件あったか数えてみてください。この件数が、検索の仕組みに投資する価値があるかどうかの判断材料になります。

ゼットリンカーでは、中小企業向けのNext.jsフルスクラッチ受託で、顧客対応履歴の検索・要約のような業務システムをAI駆動開発(Claude Code)を実装工程に組み込みながら設計しています。「うちの顧客対応ログは検索できる状態にできるのか」「まずどの窓口から着手すべきか」といった個別の判断からで構いませんので、お問い合わせからご相談ください。

よくある質問

Q. ベクトル検索を導入すれば、社内マニュアル検索と同じ仕組みを流用できますか?

技術的な土台(文書をベクトル化して意味で検索する仕組み)は共通していますが、そのまま流用すると精度が落ちます。顧客対応履歴は時系列の重み付け・担当者や部署のメタデータ・未解決案件の扱い・個人情報保護といった、マニュアル検索には無い設計要素が必要になるため、対象データに合わせた調整が必要です。

Q. 顧客対応履歴を外部のAI APIに送っても個人情報の扱いは大丈夫ですか?

多くの法人向けAPIプランはデフォルトで学習利用がオプトアウトされていますが、契約内容の確認は必須です。あわせて、氏名・電話番号などの個人情報はベクトル化前にマスキングし、メタデータとして別に保持して表示時だけ突合する設計にすると、検索精度への影響を抑えながらリスクを下げられます。

Q. どのくらいのデータ量から検索の仕組みを作る意味がありますか?

明確な下限はありませんが、1つの窓口の直近1年分のような、絞った範囲から始めるのが現実的です。全社・全期間のデータを一度に統合しようとすると、データ形式の統一だけで工数がかさみ、検索精度の検証もしづらくなります。小さく始めて手応えを確認し、対象を広げる進め方の方が完成までの期間が短くなる傾向があります。

Q. 検索と要約(チャットボット)、どちらを先に作るべきですか?

過去の対応履歴を「探す」ニーズが主なら検索を、複数のやり取りをまたいで「1つの回答にまとめたい」ニーズが主なら要約生成を優先します。多くの現場では検索の精度を先に固めてから、必要に応じて要約生成層を追加する順番が扱いやすいです。

本記事は Next.js 16.x 時点の情報です

最終更新:2026年8月11日

Share this article

要件整理から始める無料相談

1時間/準備不要/見積もりまでご案内します

無料相談を申し込む

次に読む記事

ALL ARTICLES →

プライバシーポリシー

株式会社ゼットリンカー(以下、「当社」といいます。)は、お客様の個人情報の重要性を認識し、 その保護の徹底を図るため、以下のプライバシーポリシー(以下、「本ポリシー」といいます。)を定めます。

1. 個人情報の定義

本ポリシーにおいて「個人情報」とは、生存する個人に関する情報であって、 当該情報に含まれる氏名、生年月日その他の記述等により特定の個人を識別することができるもの、 及び他の情報と容易に照合することができ、それにより特定の個人を識別することができることとなるものを指します。

2. 個人情報の収集

当社は、お客様が当社のサービスをご利用になる際、お客様の個人情報を収集することがあります。収集する個人情報は以下の通りです:

  • 氏名
  • メールアドレス
  • 電話番号
  • 会社名・組織名
  • 住所
  • その他当社が定める入力フォームにお客様が入力する情報

3. 個人情報の利用目的

当社は、お客様からご提供いただいた個人情報を、以下の目的で利用します:

  • お客様への連絡やサービスの提供
  • お客様からのお問い合わせへの対応
  • 当社サービスの改善や新サービスの開発
  • メールマガジンの配信(お客様の同意がある場合)
  • 契約や法令等に基づく権利の行使や義務の履行
  • その他、上記利用目的に付随する目的

4. 個人情報の第三者提供

当社は、以下の場合を除き、お客様の同意なく個人情報を第三者に提供することはありません:

  • 法令に基づく場合
  • 人の生命、身体または財産の保護のために必要がある場合であって、本人の同意を得ることが困難である場合
  • 公衆衛生の向上または児童の健全な育成の推進のために特に必要がある場合
  • 国の機関もしくは地方公共団体またはその委託を受けた者が法令の定める事務を遂行することに対して協力する必要がある場合

5. 個人情報の管理

当社は、お客様の個人情報を正確かつ最新の状態に保ち、個人情報への不正アクセス、 個人情報の紛失、破損、改ざん及び漏洩などを防止するため、 セキュリティシステムの維持・管理体制の整備等の必要な措置を講じ、安全対策を実施し個人情報の厳重な管理を行います。

6. 個人情報の開示・訂正・削除

お客様は、当社に対してご自身の個人情報の開示を求めることができます。 また、開示の結果、個人情報の内容が事実でないことが判明した場合には、 速やかに訂正または削除に応じます。

7. 導入事例の公開について

当社は、お客様から依頼いただいたプロジェクトを導入事例として記事にさせていただく場合があります。導入事例として公開する場合は、以下の点に配慮いたします:

  • 機密情報や個人情報は公開いたしません
  • 社名を公開する場合は、公開内容について事前にお客様に確認いただきます
  • 社名を非公開とする場合でも、お客様のご要望に応じて公開内容を確認いただくことが可能です

8. Cookie(クッキー)の使用について

当社のウェブサイトでは、お客様により良いサービスを提供するため、Cookie を使用することがあります。 Cookie により個人を識別できる情報を収集することはありません。 お客様はブラウザの設定により Cookie の受信を拒否することができます。

9. SSL(Secure Socket Layer)について

当社のウェブサイトはSSLに対応しており、ウェブブラウザとウェブサーバーとの通信を暗号化しています。 お客様が入力する個人情報は自動的に暗号化されて送受信されるため、 万が一、第三者が傍受した場合でも内容を解読することは困難です。

10. プライバシーポリシーの変更

当社は、必要に応じて、本ポリシーの内容を変更することがあります。 変更後のプライバシーポリシーについては、当社ウェブサイトに掲載したときから効力を生じるものとします。

11. お問い合わせ

本ポリシーに関するお問い合わせは、以下の窓口までお願いいたします。

株式会社ゼットリンカー

〒160-0023

東京都新宿区西新宿3丁目3番13号西新宿水間ビル2F

代表取締役: 金原隆利

お問い合わせ先: info@zetlinker.com

制定日:2024年1月1日

最終改訂日:2026/8/11

利用規約

この利用規約(以下、「本規約」といいます。)は、株式会社ゼットリンカー(以下、「当社」といいます。)が 提供するウェブサイトおよびサービス(以下、「本サービス」といいます。)の利用条件を定めるものです。 お客様は、本規約に同意した上で、本サービスをご利用ください。

第1条(適用)

1. 本規約は、お客様と当社との間の本サービスの利用に関わる一切の関係に適用されるものとします。

2. 当社は本サービスに関し、本規約のほか、ご利用にあたってのルール等、各種の定め(以下、「個別規定」といいます。)を することがあります。これら個別規定はその名称のいかんに関わらず、本規約の一部を構成するものとします。

3. 本規約の規定と個別規定の規定が異なる場合は、個別規定において特段の定めなき限り、個別規定の規定が優先されるものとします。

第2条(定義)

本規約において使用する以下の用語は、各々以下に定める意味を有するものとします。

  • 「利用契約」とは、本規約を契約条件として当社とお客様との間で締結される、本サービスの利用契約
  • 「知的財産権」とは、著作権、特許権、実用新案権、意匠権、商標権その他の知的財産権(それらの権利を取得し、またはそれらの権利につき登録等を出願する権利を含みます。)
  • 「投稿データ」とは、お客様が本サービスを利用して投稿その他送信するコンテンツ(文章、画像、動画その他のデータを含みますがこれらに限りません。)

第3条(本サービスの提供)

1. お客様は、本規約に同意の上、当社の定める方法によって利用登録を申請し、当社がこれを承認することによって、本サービスを利用することができるようになります。

2. 当社は、お客様に以下のいずれかの事由があると判断した場合、利用登録の申請を承認しないことがあり、その理由については一切の開示義務を負わないものとします。

  • 利用登録の申請に際して虚偽の事項を届け出た場合
  • 本規約に違反したことがある者からの申請である場合
  • その他、当社が利用登録を相当でないと判断した場合

第4条(ユーザーIDおよびパスワードの管理)

1. お客様は、自己の責任において、本サービスのユーザーIDおよびパスワードを適切に管理するものとします。

2. お客様は、いかなる場合にも、ユーザーIDおよびパスワードを第三者に譲渡または貸与し、もしくは第三者と共用することはできません。

3. 当社は、ユーザーIDとパスワードの組み合わせが登録情報と一致してログインされた場合には、そのユーザーIDを登録しているお客様自身による利用とみなします。

第5条(禁止事項)

お客様は、本サービスの利用にあたり、以下の行為をしてはなりません。

  • 法令または公序良俗に違反する行為
  • 犯罪行為に関連する行為
  • 本サービスの内容等、本サービスに含まれる著作権、商標権ほか知的財産権を侵害する行為
  • 当社、ほかのお客様、またはその他第三者のサーバーまたはネットワークの機能を破壊したり、妨害したりする行為
  • 本サービスによって得られた情報を商業的に利用する行為
  • 当社のサービスの運営を妨害するおそれのある行為
  • 不正アクセスをし、またはこれを試みる行為
  • 他のお客様に関する個人情報等を収集または蓄積する行為
  • 不正な目的を持って本サービスを利用する行為
  • 本サービスの他のお客様またはその他の第三者に不利益、損害、不快感を与える行為
  • 他のお客様に成りすます行為
  • 当社が許諾しない本サービス上での宣伝、広告、勧誘、または営業行為
  • 面識のない異性との出会いを目的とした行為
  • 当社のサービスに関連して、反社会的勢力に対して直接または間接に利益を供与する行為
  • その他、当社が不適切と判断する行為

制定日:2024年1月1日

最終改訂日:2026/8/11