音声メモを文字起こししてAIで日報を自動作成!Google CloudとGeminiでアプリを作ってみた
・ 読了 約17分

一日の終わりに、商談の内容を思い出して日報を手入力したりするのは面倒です。メモがあっても、顧客ごとに読み返し、「課題」「次にすること」などの項目へ整理し直す手間がかかります。そこで、音声メモの文字起こしから日報への整理まで、AIに任せるアプリをサンプルとして作りました。思いついた順に話した内容や、あとから変更になった予定を、1日分の日報にまとめられます。もちろん、一日の終わりでなくとも都度喋るだけで情報をまとめておくこともできます。なかなか人前で喋るというのは気恥ずかしさがあるものではありますが、文字で入力するより圧倒的に効率がいいことは事実です。
例えば、日報や連絡事項は午前中のメモでは「上長に確認して折り返す」と話していたのに、夕方の電話で「内訳を作り直して再提出する」に変わった。こうした追記や訂正も含めて、1日分の音声を日報にまとめられるか試してみました。
今回、使ったのは、Google Cloudが提供する文字起こしサービスであるSpeech-to-Textと生成AIのGeminiです。顧客ごとの日報に整理し、表形式のファイルとしてCSVを出力できます。日報の項目をクリックすると、元の音声の該当箇所を再生できる画面も作りました。さすがに実際の商談の内容をデータとして使うことはできないので、架空の商談を台本にし、Cloud Text-to-Speechで読み上げた音声を使っています。Text-to-Speechは文字起こしとは逆で、テキストを音声にするサービスです。会社名や人物、取引内容はデモ用の設定です。
処理の順番は「音声を用意する → 文字起こしする → 日報の項目に整理する → 画面やCSVに出す」です。
以下では、この順番に沿って使ったサービスとその結果を紹介します。コードは各処理の抜粋を載せています。文字起こしの段階では、話した順番の文章が作られます。そこから「これは顧客の課題」「この話は午前の商談への追記」と読み取って日報へ整理するのがAIであるGeminiの役割です。Pythonはサービス間でデータを受け渡し、回答を保存してCSVなどに加工します。音声を文字にするのはSpeech-to-Text、その文章を 日報にまとめるのはGeminiという構成で、日報や入力情報をアプリケーション上で整理してみることができるものになっています。

TTSで商談メモの音声を用意する
TTSはText-to-Speechの略で、文章を読み上げ音声に変換する技術です。Google CloudではCloud Text-to-Speechというサービスで利用できます。 また余談となりますが、ちょうど新しい音声生成モデル Gemini 3.8 Flash TTSが発表されたところでもあります。TTSでは、商談の台本を読み上げさせ、テスト用の音声を作っています。
入力は2026年9月9日(水)のメモ3本です。A社を「創和星環建設」、B社を「光洋雲庭テック」と架空の企業とし、午前と午後にそれぞれを訪問する設定です。夕方にA社の商談を更新する、という内容にしました。
メモ | 内容 | 音声の長さ |
|---|---|---|
11:05 | A社への訪問。課題、次のアクション、期日など | 78.3秒の音声 |
14:30 | B社への訪問。試用の相談と30万円の見積もり | 107.6秒の音声 |
18:10 | A社の次のアクションを訂正。最後に展示会の用事を追記 | 55.1秒の音声 |
午前11:05のA社のメモでは、次のアクションを「まず上長に確認して折り返す」、回答の期日を「今週金曜日」と話しています。
夕方18:10のメモは、同じA社の担当者から電話があり、工事の内訳を分けた資料を求められた、という設定です。ここで「上長に確認して折り返す、と午前のメモに残しましたが、それは取り消しです。単価内訳を作り直して再提出する、に変更します」と話します。期日は金曜日のままです。この2本を同じ商談としてまとめ、次のアクションを夕方の内容に更新できるか試します。
A社のメモでは金額を話していません。また、夕方のメモの最後には、顧客名を付けずに「あと来週の展示会、パンフの部数だけ確認しておく」と加えました。金額を勝手に補わず、相手が分からない用事をA社やB社に結び付けずに扱えるかも見てみます。
音声を添付できないので若干イメージが湧きづらいかもしれませんが、セールス担当の人が顧客との打ち合わせのあとに重要なことを口頭で報告してると想像してください。
※一部デモの動画を添付しています。
設定項目は、ブラウザで使う管理画面「Google Cloudコンソール」で見ると分かりやすいです。Text-to-Speechの合成画面では、文章を入力し、言語と声を選んで「合成」を押すと試聴できます。利用するプロジェクトでは、あらかじめAPIを有効にし、課金を設定しておきます。
今回の設定を画面の項目に対応させると、次のようになります。
画面で選ぶ項目 | 今回の設定 |
|---|---|
言語 | 日本語( |
音声 |
|
詳細設定の速度 |
|
社名の読みを指定するために使ったのがSSMLです。SSMLとは文章に読み方などの指定を書き添える記法で、<sub alias="そうわせいかんけんせつ">創和星環建設</sub>と書くと、この社名を指定した読みで発音させられます。出力は、パソコンで再生できるWAV形式です。アプリでは音声形式をLINEAR16、サンプルレートを16000に指定しました。サンプルレートは、音を1秒あたり何回のデータとして記録するかを表します。アプリからの呼び出しには、同じ設定をコード側にも指定します。今回はSDKのsynthesize_speechに台本と設定を渡し、返ってきた音声を保存しました。
Speech-to-Textで文字起こしする
さてここが今回の作成したものの中で一番重要なところかもしれません。音声を文章へ変換する処理はSTT(Speech-to-Text)と呼ばれます。ここではGoogle CloudのSpeech-to-Text v2を使い、先ほどの音声を文字に戻しました。
管理画面で試す場合は、「音声文字変換」から新しい文字起こしを作り、音声ファイルを指定します。続く「音声文字変換のオプション」でAPIのバージョンをV2に切り替え、言語とモデルを選びます。STTもプロジェクトでAPIの有効化が必要です。
今回の言語は日本語(ja-JP)、モデルはlongです。モデルは、音声を認識するために学習された仕組みです。処理する地域には東京のasia-northeast1を指定しました。
言語とモデルをPythonで指定したのが次のコードです。auto_decoding_configでWAVの形式を自動検出し、featuresで単語の開始・終了時刻、認識の信頼度(confidence)、句読点の自動挿入を有効にしています。Trueは「有効」を意味します。
from google.cloud import speech_v2 as speech
config = speech.RecognitionConfig(
auto_decoding_config=speech.AutoDetectDecodingConfig(),
language_codes=["ja-JP"],
model="long",
features=speech.RecognitionFeatures(
enable_word_time_offsets=True,
enable_word_confidence=True,
enable_automatic_punctuation=True,
),
)
短い音声はRecognizeへ直接送れます。長い音声は、Cloud Storageに置き、保存場所をBatchRecognizeへ渡します。公式サンプルをもとに、次のように呼び出しました。
request = speech.BatchRecognizeRequest(
recognizer=f"projects/{project}/locations/{location}/recognizers/_",
config=config,
files=[speech.BatchRecognizeFileMetadata(uri=gcs_uri)],
recognition_output_config=speech.RecognitionOutputConfig(
inline_response_config=speech.InlineOutputConfig()
),
)
operation = client.batch_recognize(request=request)
results = operation.result(timeout=600).results[gcs_uri].transcript.results
gcs_uriはgs://バケット名/ファイル名.wavという音声の保存場所です。バケットはファイルを入れる保存先を指します。locationには先ほどの地域が入り、result()で処理の完了を待ちます。直接送れる音声は60秒までなので、デモでは59秒を超えたらCloud Storage経由に切り替えます。午前と午後のメモが該当し、55秒の夕方のメモは直接送りました。
ところが、文字起こしを読むと社名が化けていました。「創和星環建設」が「創和性関係説」、「光洋雲庭テック」が「紅葉 運転 テック」になっています。STTに渡すのは音声だけなので、台本の漢字は伝わりません。「そうわせいかんけんせつ」という音をどの漢字にするかは、認識側で決まります。
そこで、単語を認識のヒントとして登録する語彙適応を試しました。管理画面では「モデル適応」に当たり、フレーズと優先させる強さ(ブースト)を設定できます。アプリでは顧客名や製品名の一覧をCustomClass、認識させたい表現をPhraseSetとして登録し、文字起こしの際に参照させます。
最初の語彙登録で、「創和星環建設」は4回中0回から2回、「星環AGパック」は2回中0回から1回、正しく書かれるようになりました。数字は、文字起こしの空白を除いて台本どおりの表記を数えたものです。その後、顧客名や製品名のboostを20まで上げ、「創和星環建設の山崎部長」のような表現も追加しましたが、正しく書かれた箇所は増えませんでした。「光洋雲庭テック」は直らず、この結果のまま日報作成に進みます。
Geminiで顧客ごとの日報にまとめる
文字起こしができたら、Geminiにその文字起こししたテキストを日報へ整理してもらいます。今回はGoogle Cloud上でAIを利用するための基盤、Vertex AIを経由して呼び出しました。渡すのは、録音時刻順に並べた文字起こしと、日報のひな型です。当然ながら音声を作るために用意した正解の台本は、Geminiには渡していません。
営業用テンプレートには、訪問目的、顧客の課題、次のアクション、金額など8項目を定義しました。顧客名と担当者名を手がかりに、午前と夕方のメモを同じ商談へまとめます。ひな型は、設定をテキストで書くための形式であるYAMLで用意しました。「次のアクション」「金額」といった項目名や、日付の書き方をここにまとめています。AIへの指示文をプロンプトと呼びますが、このプロンプトもひな型の内容を使って組み立てています。
日報の日付と曜日も一緒に渡しています。「今週金曜日」という発話だけでは具体的な日付を決められませんが、今回は9月9日(水)の記録と分かるため、9月11日へ置き換えられます。午前と夕方の順番も付けておくことで、後から訂正した内容を判断する材料になります。
プロンプトには、話していない項目は「未言及」にすること、訂正後の値を現在値にして以前の値を履歴へ残すことを書きました。また、各項目には、どの録音をもとにしたかが分かる番号と、文字起こしからの引用を付けさせています。たとえばA社の金額が空いていても、B社で話した30万円を補ってほしくはありません。データには「値がない」ことを表すnullと、未言及という状態を記録します。値が入る項目には引用も必要です。Python側でも、値と引用がそろっているかを確認しています。
最初の出力を読むと、引用自体は合っているものの、その引用に含まれない事実まで日報の値に混ざってしまうことがありました。そこで「各項目の値は、付けた1つの引用が裏付ける範囲に絞る」という指示を加え、もう一度生成しました。
Geminiの回答はJSONで受け取ります。日報の項目ごとに値を取り出せるので、画面への表示やCSVへの変換に使えます。さらに、必要な項目や値の種類を決めた「スキーマ」を指定しました。次のコードではresponse_schema=schemaがその指定です。promptには、先ほどの指示文と文字起こしが入ります。
from google import genai
from google.genai import types
with genai.Client(
vertexai=True, project=project, location="global"
) as client:
response = client.models.generate_content(
model="gemini-3.8-flash",
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=schema,
temperature=0.0,
),
)
output = schema.model_validate_json(response.text)
このように回答のデータ形式を指定する機能を構造化出力と呼びます。末尾のmodel_validate_jsonでは、受け取ったデータが指定した形式に合うかを確認しています。
プロンプトを直して2回目に生成した日報は、商談2件にまとまりました。A社の結果から一部の項目を抜き出すと、次のようになります。
項目 | 生成された内容 |
|---|---|
顧客名・担当者名 | 創和星環建設・山崎部長 |
次のアクション | 単価内訳を作り直して再提出する。 |
訂正前のアクション | まず上長に確認して折り返す。 |
期日 | 2026-09-11 |
金額 | 未言及 |
午前と夕方のメモが同じ商談にまとまり、夕方に話したアクションが現在の値になっています。午前のアクションも履歴として残りました。話していない金額は空欄の意味を保ったまま「未言及」と表示されます。B社の金額は30万円。「来週月曜日」は9月14日に変換されています。夕方の最後に話した展示会パンフレットの部数確認は、相手が分からないため未分類に入りました。B社名には文字起こしの誤りが残り、「紅葉運転テック」と表示されています。
日報をクリックして、元の発話を聞く
確認画面では、Pythonが保存した日報を読み込み、冒頭の画像のように、左側に日報、右側に文字起こしと音声プレイヤーを並べています。
動画では、右側の「SEG 01」で、登録した音声メモを再生しています。音声で話した内容が、左側の日報では「訪問目的」「話した内容」「顧客の課題」などの項目に整理されています。音声を聞きながら、どのような文章にまとまったかを見比べられるような形です。
画面で日付を選ぶと、その日に生成した日報と元の音声が開きます。顧客ごとに内容を読み、気になった項目をクリックして発話を確認する流れです。音声の再生位置は、Pythonで求めています。Geminiが返した引用を文字起こしの中から探し、該当する単語の開始・終了時刻を取り出します。空白や句読点の違いはそろえてから比較します。ここで、文字起こしのときに取得しておいた単語の時刻が使えます。
A社の次のアクションについて、保存したデータの一部を示します。valueが日報に表示する文章、evidenceがその根拠です。
{
"value": "単価内訳を作り直して再提出する。",
"evidence": {
"segment_id": "SEG_20260909_03",
"start_sec": 17.6,
"quote": "単価内訳を作り直して再提出するに変更します"
}
}
segment_idは元の録音を識別する番号、start_secは再生を始める秒数です。Geminiが文章と引用を返し、Pythonが引用に対応する秒数を加えました。画面はこの情報を読み込んで、指定された録音の位置へ移動します。
A社の現在のアクションをクリックすると、夕方のメモの17.6秒へ移動します。取り消し線が付いた以前のアクションなら、午前のメモの56.84秒から再生します。日報を読みながら、その内容を話した箇所を聞き直せます。
文字起こしでは、単語のconfidenceが0.7未満なら背景に色を付けています。ただ、誤認識したB社名にも0.96前後の値が付いていました。色は聞き直す場所の目安に使うことにしました。
CSVはPythonの標準機能で書き出しています。1商談を1行にし、各列へ現在の値を入れ、訂正があったことも別の列に残します。
今回の営業CSVは2行です。午前と夕方のA社メモが1行にまとまり、別の行にB社が入ります。CSVの列順やファイルへの書き込みはPythonで処理するため、出力形式だけを変えたい場合にGeminiへ再度問い合わせる必要はありません。日報の内容を作る処理と、表示・出力する処理を分けたことで、この部分は手元で繰り返し確認できています。
エンジニアの日報でも試してみる
営業版を動かしたあと、台本・語彙・テンプレートをエンジニアの日報用にも差し替えてみました。約65秒の作業メモから「完了したこと」「進行中」「詰まっていること」「次にすること」の4項目を生成でき、Pythonや画面のコードを変える必要はありませんでした。
台本の内容は、CSV出力を改善する作業の報告です。「ファイル名をそろえる作業を進めている」という話は進行中の項目に、「検証用バケットへの書き込み権限がない」という話は詰まっていることの項目に入りました。続く「管理者に権限を確認してもらう」は、次にすることとして整理されています。
エンジニア版では「備考」が「尾行」と認識され、そのまま日報に残った箇所もありました。合成音声でもこうした誤りは出ます。生成した日報に元の発話を結び付けておくと、気になった表現を見つけたときに、その場で音声を確認できます。
二つの日報を作る中で、業務に合わせて決めたのは「何を1件として扱うか」「どの項目に分けるか」「言及がない項目や訂正をどう残すか」でした。営業では顧客と担当者、作業報告ではタスク名を手がかりに記録をまとめています。
同じ仕組みで、製造現場の点検記録も作れそうです。たとえば「2号機の搬送ベルトに傷があった。保全担当に交換を依頼した」というメモを、設備名・点検で見つかったこと・対応内容に分けます。設備名や部品名を語彙に登録し、設備ごとに記録をまとめるルールを用意する形です。
小売店なら、閉店後の引き継ぎメモが考えられます。「牛乳が夕方に売り切れた。明日は発注数を増やしたい」という報告を、商品名・売り場で起きたこと・翌日の対応案に整理します。翌朝の担当者が一覧を読み、気になる箇所の音声を聞き直す使い方を想定できます。いつもの引き継ぎ表が、テンプレートのたたき台になります。

Resonalエンジニアリング部
Google Cloudや生成AIの導入、プロダクト開発における役立つコンテンツをお届けします。

