展示会の生産性を飛躍的に改善した、HubbleのLLMドリブンな営業成長基盤

[Hubble Advent Calendar 2024](https://qiita.com/advent-calendar/2024/hubble) の16日目[^1] の記事です🤶
[@alstrocrack](https://qiita.com/alstrocrack) さんからバトンを受け取りました！


## はじめに

こんにちは、[@Shogo](https://qiita.com/embokoir) です。

昨年に続き、いわゆる開発サイドではないチームから単騎、この企画に飛び入り参加しています。快く受け入れてくださる開発チームの皆さん、いつもありがとうございます！

さて、私はHubbleで今年からは新規事業開発というミッションに日々取り組んでいるのですが、その傍ら、昨年まで担っていた[Business Analytics & Operations（BAO）](https://note.hubble-docs.com/n/n2eecd1fcf74e)としての責務も持っており、ビジネスチームが接するデータパイプライン周りの企画や実装・可視化、その過程で発生する様々なオペレーションづくりにも励んでいます。

アドベントカレンダーのゴールも見えてきた12月23日、私からはそんな「BAO」の文脈で、我々が「**展示会の活動で獲得した大量の情報を、いかにして効率的に記録できるようにしているか？**」という話を紹介します。


## 前提

当社はセールス・マーケティング活動の一環として、多数の展示会に参加しています。
展示会では、ブースを訪れてくださる方々と数えきれないほど沢山の名刺交換をします。基本的にはその場で何かしらの会話が生まれますし、中には立ち話で終わらずに、ブース内に設けたスペースでより具体的な話を進めていくケースもあります。私自身も現地でそうした立ち回りをすることもあります。

いずれにせよ、そうした**話の内容や名刺に記載された連絡先といった情報は、その後のビジネス活動においてお互いに重要なものであり、的確に抜け漏れなく記録することが求められます**。

## 問題意識

さて、ここで一つのテーマとして、効率の問題があります。

展示会では三桁を超える枚数の名刺を一日で交換をすることもありますし、次から次へと来場者が訪れる中では、一件一件に長い時間をかけて作業をしている暇もありません（厳密にはできるのでしょうが、そこに時間を費やすことは大いな機会損失でもあります）。

つまり最大限の成果をあげるためには、忙しい状況下でも、できるだけ少ない手数で、それでいて正確に情報を記録できていく必要があります。

出展を重ねる中でいつも痛感するのは、ただでさえバタバタしている現場において名刺の文字情報とシステム上のデータを精査するという作業は、タイポや変換ミスといったヒューマンエラーを引き起こしかねないだけでなく、**とにかく時間がかかり致命的なロスになりうる、** ということです。

展示会の現場で、表に立つべきメンバーが長々と書類上の文字を精査する作業はいわゆる「ノンコア」な作業に他なりません。どうにか減らせないかと考えてきた結果、現在では以下のような方策を採っています。

## アンサー

今回でいう名刺、つまり
- **「思い思いのレイアウトで記載された、非構造的なテキスト情報**」を
- **「システムや業務で扱いやすい、構造化されたデータ」** 

へ鮮やかに変換する手段としては、イマドキはやはりLLMが思い浮かびます。
（ちなみに手前味噌ながら、[Hubble mini](https://hubble-docs.com/lp/Hubble-mini/) は契約書においてそれを実現し、かつ契約書管理システムとして日々のビジネス活動に最適化を施しているプロダクトです。）

そこでLLMを軸に、Google Apps Scriptを基盤とし何種類かのAPIも駆使して、下記のような仕組みを構築・運用することで今回の問題を解消しています。
プログラム周りを私が思いのままに実装し、その後マーケティングチームが現場の運用と辻褄が合うようにワークフローやスプレッドシート周りを調整してくれました。

※⑤・⑥は少し毛色が異なるため、本エントリでは詳細には言及していません。また機会があれば書くこととします。

![image.png](https://i.gyazo.com/2757f657a7adf3dd9a248543376f944b.png)

（解説）

①現場での終話直後、会話した担当者が手元のモバイル端末から所定のSlackチャンネルにてSlackワークフローを起動。ワークフロー内のフォームから、話したサービス群・会話内容・今後の方針等、最小限ながらに十分な情報を選択 or 入力して送信。名刺の画像を添付。

②Slackのワークフロー受信をトリガーにSlack APIが発動。Google Apps Scriptへフォーム内容と名刺画像をPOST。

③**OpenAIのGPT-4o等のAPI[^2]を用い、名刺の画像から会社名・氏名・部署・役職・メールアドレスといったデータを抽出**。フォーム送信内容と併せてGoogleスプレッドシートへ記載。

- OpenAI APIへのプロンプトはソースコードへのベタ打ちでなく、スプレッドシート内のセルから取得するため、アウトプットを見ながら適宜チューニングが可能。「こういうパターンもあるのか」とわかったタイミングで、次回以降のプロンプトに即時反映。

※サーバーにはGoogle Apps Scriptを利用

④追加の情報がある場合、Googleスプレッドシート上の該当レコードを編集する形で追記。特にある程度の時間をかけて会話し、担当者が手元のPC等でメモを取ったケースを想定。

⑤当日の会期終了後、④までの情報をSalesforceの取引先責任者としてインポート。Apexで事前に作成したAPIをGASから叩くことで、数百レコードにわたるこの作業も数クリックのみに留める。会社名から法人番号を検索するといった仕組みも含んでおり、法人の重複や表記揺れもこの段階で一定程度防止。

⑥後日、セールスチームの担当者はSalesforceにて情報を確認し、電話や商談を実施。


## 成果

数千件以上にわたってきた名刺交換において、そこに書かれた**文字情報を見ながら精査するという作業がほぼゼロに**なったのはもちろん、結果的には、その周りも含めたほとんどの業務の量と質が従来よりも大幅に改善しました。

実は上記を構築する前にも名刺関連の有償の仕組みが社内に存在していたのですが、OCRの精度に満足がいかずに都度手作業で修正する手間が発生していたり、苦心してその修正を終えたとしても、各メンバーの手元のメモと名刺情報の紐付けが大変で長時間の居残り作業が発生しかねなかったりと、必要以上に「ノンコア」な業務に忙殺されがちな日々でした。

現在では支出を減らすことができただけでなく、そうした業務の大半を削ることができるようになり、**時間も体力もヘルシーに**回すことができています。


## 工夫ポイント

だいぶシステマティックな話に終始していますが、実情を省みれば、実際に活用する面々の波長に合わせた「**細部のちょっとした工夫**（≒遊び）」も、意外と良い成功要因になっているのかなと思ったりします。

- **Slackをインタフェースとしている**
    - フォーム送信に特化したアプリケーションの場合、多くは「送信したら終わり」ですが、コミュニケーションのために設計されたSlack内の機能であれば、必要に応じてその後のスレッドで対話もできますし、後日「この案件について」といった形で参照・引用するのも容易です
- このシステム全体に対する総称として「`ネコパンチ・データ`」という愛称があり、社内用語として浸透が進んでいる
    - ネコがパンチするイメージが、データを瞬時にさばいていく様子とピッタリらしいです（本当に？？）
- Slack上ではBotのUIになっており、そのBotに対してメンションすると、`ネコパンチ・データ`が「ちょっとユーモラスな対話」をしてくれる
    - たまにいじられることもあるとか…


## おわりに

私自身、昔から「もっと上手くできないかなぁ…」と思っていた事柄だっただけに、特にOpenAIのAPIが出てきてからはどう実装していこうかとウズウズしながら構想を練っていました。（今回の仕組み自体取り立てて斬新なものではないですし、同じような思いを抱いている方は沢山いるのではないかと思います！）

とある日に思い立って一気に作り上げ、翌日に展示会を主管する担当者へ見せたところ、さっそく採用してもらえ、今に至ります。今となってはその担当者も、「これがなかった時代にはどうやって回していたんだっけ？（笑）」と、当時を思い出せないくらいのようで、嬉しい限りです。

実際に使ってみたいという方、裏側のソースコードを見てみたいという方、はたまた「ネコパンチ・データ」とちょっと対話してみたいと思った物好きな方、ぜひHubble社の扉をたたいてみてください。心からお待ちしています！

明日は [@power3812](https://qiita.com/power3812) さんです！


[^1]: 平日のみ投稿の企画のため、12/23ですが「16日目」の記事としています。 
[^2]: APIとやりとりするデータがモデルのトレーニングに使われない仕組みを使用。情報保護には最大限の配慮をしています。