giftee Tech Blog

ギフティの開発を支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信しています。

面接官への面接フィードバックを自動生成する仕組みをAI+GASで作った

面接フィードバックを自動生成する仕組みをAI+GASで作った

ギフティのVPoEの大曽根です。

以下の以前のエントリーで AI で価値創造の取り組みの現在地をご紹介しましたが、今回はその中の1つのテーマについて、具体の取り組みを紹介します。

tech.giftee.co.jp

ちなみにこれからご紹介する仕組みの構築はエンジニアのサポートは無く、Non-dev である自分が Claude Code を使って実装しています。

背景

面接官に「深掘りが足りなかった」「アトラクトの意識が薄かった」と伝えることは、面接の質を上げるうえで重要です。

ただ、面接の場は候補者と面接官というクローズドな環境であるため、第三者が面接内容を把握して面接官にフィードバックするのは難しいという側面があります。

一方で、Google Meet には文字起こし機能があり、面接内容はテキストとして残すことができます。 フィードバック観点を言語化して、それらを AI にコンテキストとしてインプットすれば、フィードバックレポートを作れると思い、仕組みを実装しました。


何を作ったか

ひとことで言えば、面接の文字起こしから、面接官ごとのフィードバックレポートを自動生成し、Slack に通知する仕組みです。

Google Meet で面接
    ↓ 文字起こしが自動保存
Google Docs(共有アイテムに出現)
    ↓ 5分ごとに検知
Google Apps Script
    ↓ Claude API でレポート生成
Slack に通知(面接官にメンション)

面接が終わると、数分後には Slack にこんな通知が届きます。

📋 面接フィードバックレポート生成完了

📅 面接日時: 2025年12月04日
👤 候補者: 山田太郎
🎤 面接官: @tanaka, @suzuki
    └── 面接フィードバックレポート_tanaka.md
    └── 面接フィードバックレポート_suzuki.md
    └── 面接サマリ_山田太郎.md

技術構成

要素 採用技術
実行環境 Google Apps Script
AI Claude API(分類: Haiku、生成: Sonnet)
通知 Slack API
設定管理 Google Drive 上の Markdown ファイル

GAS を選んだ理由はシンプルで、Google Meet の文字起こしが Google Docs として保存されるからです。 同じ Google Workspace 内で完結するのは都合がいいです。

評価ガイドラインやレポートの雛形は Google Drive 上の Markdown ファイルとして管理しています。 「コードを触らずに評価基準を更新したい」という運用要件を満たすためです。人事担当者がエンジニアに依頼せずとも、評価観点を追加・修正できます。


作っていて詰まったところ

「面談」で引っかかる社内ミーティング問題

ファイル名に「面接」「面談」を含むドキュメントを対象にしたところ、「振り返り面談」「評価面談」といった社内ミーティングまで拾ってしまいました。

対策として、レポート生成の前に Claude Haiku で内容を分類するステップを挟みました。

採用面接 / カジュアル面談 → 処理続行
振り返り面談 / 社内MTG → スキップ(ログのみ記録)

Haiku は軽量で速いので、事前フィルタリングに向いています。「高いモデルを呼ぶ前に、安いモデルで門前払いする」ようにしてコストを意識した設計にしました。


Google Docs の「タブ」という罠

Gemini の文字起こし機能が生成する Google Docs には、「メモ」と「文字起こし」の2つのタブがあります。最初は気づかず「文字起こし」タブだけを読んでいたため、参加者情報(名前)が取得できませんでした。

Google Docs API でタブ一覧を取得し、全タブの内容を結合することで解決しました。

const url = `https://docs.googleapis.com/v1/documents/${fileId}?fields=tabs(tabProperties)`;

ドキュメントにタブがあることは認識していたものの、タブを意識する必要があることに気づくのに少し時間がかかりました。


Slack メンションの地味に深い沼

「面接官に Slack でメンションしたい」という要件、一見シンプルですが、意外と厄介でした。

問題1: メールアドレスがない

文字起こしファイルには参加者の名前しか記載されておらず、メールアドレスがありません。Slack の users.lookupByEmail API が使えない。

解決策: users.list で全ユーザーを取得し、名前でマッチング。

// "Jun Ozone" → "junozone" に正規化して比較
const normalizedName = name.toLowerCase().replace(/\s+/g, '');

問題2: 名前の揺らぎ

「Jun Ozone」と「jun ozone」、「田中 太郎」と「田中太郎」など、表記揺れへの対応が必要でした。正規化(小文字化、スペース除去)で吸収。

問題3: 誤マッチ

部分一致で検索したところ、空の display_name が全員にマッチするバグが発生。

// "anystring".includes("") は常に true になる

最低3文字以上の一致を必須条件にして回避。

問題4: チャンネル外へのメンション

面接官がSlackユーザーとして存在しても、通知先チャンネルに参加していなければメンションしても届きません。conversations.members でチャンネルメンバーを確認し、非メンバーはメンションせず太字表示にフォールバック。

チャンネルメンバー → @tanaka(メンション)
非メンバー → *suzuki*(太字、メンションなし)

「メンションしたのに通知が届かない」というユーザー体験の悪さを避けるための対応です。


日本語ファイル名の文字化け

設定ファイルを「評価ガイドライン.md」のような日本語名にしていたところ、GAS から検索できない問題が発生。エンコーディングの差異が原因でした。

解決策は単純で、英語ファイル名に変更。

evaluationguideline.md
template.md
feedbackprompt.md

地味ですが、GAS と Google Drive API の間での日本語ファイル名の扱いには注意が必要です。


必要な権限まわり

Slack App のスコープ

files:write       - ファイルアップロード
chat:write        - メッセージ投稿
users:read        - ユーザー一覧取得
users:read.email  - メールでユーザー検索
channels:read     - publicチャンネルのメンバー確認
groups:read       - privateチャンネルのメンバー確認

スコープを後から追加した場合、「Reinstall to Workspace」を忘れると反映されません。これで30分ほど溶かしました。

GAS の OAuth スコープ

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/documents",
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

コスト感

項目 コスト
GAS 無料
Claude Haiku(分類) 約 $0.001/回
Claude Sonnet(生成) 約 $0.05〜0.10/回
Slack API 無料

1面接あたり $0.05〜0.15 程度。月に50件の面接があっても $10 以下です。


運用の工夫

評価基準の外部ファイル化

評価ガイドラインは Google Drive 上の Markdown ファイル。人事担当者がコード変更なしに基準を更新できます。

処理ログの可視化

スプレッドシートに処理結果を記録。

ステータス 意味
SUCCESS 正常処理
SKIPPED 採用面接以外(振り返り面談等)
FAILED エラー

再処理したい場合は、該当行を削除するだけ。

本番/テストコードの分離

Code.gs(本番用)と Test.gs(確認用)にファイルを分割。トリガーは main 関数のみを対象にし、テスト関数が誤って定期実行されることを防いでいます。


振り返り

うまくいったこと

  • 文字起こし → フィードバックの自動化という当初の目的は達成
  • 評価基準の外部ファイル化により、非エンジニアでも運用可能に
  • 分類ステップの追加で、不要な処理を事前に除外

想定より手間がかかったこと

  • Slack メンションの細かい UX 対応(名前検索、チャンネルメンバー確認)
  • Google Docs のタブ構造という想定外の仕様
  • GAS 特有の制約(ファイル名エンコーディング、実行時間制限)

今後やりたいこと

  • ATS(採用管理システム)との連携
  • 過去の面接のフィードバックなどもふまえた傾向分析・より深いフィードバック

おわりに

やれそうかもというアイディアから Claude Code と壁打ちをしながら実装計画を作成し、それをもとに AI に実装させ、躓いたら都度 AI に聞きながら進めることで Non-dev でも本番運用に乗る仕組みを作ることができました。

「面接の文字起こしから自動でフィードバックを生成する」というアイデア自体はシンプルですが、実際に組んでみると細かい課題が出てきます。

特に Slack メンションのような「動けばいいだけなら簡単だが、ちゃんとやろうとすると面倒」な部分は、ユーザー体験に直結するので手を抜けません。

また、本番でうまく回るようにするために現行の運用も含めて変えていく必要があるので採用側との密な連携が必要になります。

とはいえ、一度仕組みを作ってしまえば、あとは自動で動いてくれます。

面接のたびにフィードバックが届く状態を、ほぼゼロコストで維持できます。

これは地味ながら、じわじわ効いてくる類の仕組み化だと思っています。

同じような課題を抱えている方の参考になれば幸いです。