2025.11 — 現在

発音チェック

韓国語を学ぶ日本人と、日本語を学ぶ韓国人のための発音矯正サービスです。録音がイントネーション曲線の描かれた「フィードバックカード」になり、ネイティブの先生が直接添削して返します。ベータ運営中です。

2日
PoC制作 → 運営陣を説得
573ms → 20ms
キャッシュを外したセッション照会
26件 → 2件
レビュー243件 · 開始点のずれ
サービス

韓国語は、文字が読めることと自然に聞こえることの間に大きな距離がある言語です。連音(リエゾン)や濃音化のように表記と音がずれる規則が多く、文章が読めてもイントネーションがぎこちないと、すぐに伝わりにくくなります。そしてそのぎこちなさは、自分の耳ではなかなか聞き取れません。日本語を学ぶ韓国人にとっての、ピッチアクセントや無声化も同じです。

発音チェックはこのイントネーションを目に見える形にします。毎週金曜日に3文のミッションが届き、水曜日までに提出した録音はピッチ曲線の描かれた「フィードバックカード」になります。ネイティブの先生がその上に描き込みと動画で添削して返します。「通じる発音」から「ネイティブっぽい」と言われる発音へ。韓国語を学ぶ日本人と日本語を学ぶ韓国人、双方向で運営しています。

差別化

AIを排除するのではなく、機械が得意なことと人にしかできないことを分けるサービスです。イントネーションを抽出して曲線に描く繰り返し作業は技術が引き受けて先生は添削に集中し、人の耳でしか捉えられない「言語の質感」はネイティブの先生が担当します。

学習者はスコアや統計ではなく、フィードバックカードという目に見える形で自分の発音の変化を追い続けられます。音声処理はブラウザ内で完結し、先生が見たカードと学習者が受け取るカードが同じ絵であることもテストで保証しています。

PoC → ベータ運営

2日で動くPoCを作るところから始めました。添削ワークフローの実演と、サーバーコストがほぼかからない運営構造を見せて日韓のネイティブ運営メンバーを説得。クローズドベータ → SNS・コミュニティでのテスター募集を経て、現在ベータサービスとして運営中です。

運営メンバーと共にサービス全体を日韓2言語で作り、両国のユーザーとテストを重ねました。運営メンバーのQAメモがバグ再現 → 原因追跡 → 修正PRへそのままつながるパイプラインも整えています。

社内レビューツール Into

サービスとは別に、イントネーションカードの制作を自動化できるか検証する社内レビューツール「Into」を作りました。音声と文章を入れるとブラウザでピッチを抽出し、音節(韓国語)/モーラ(拍、日本語)単位のチャートを自動生成します。核心の実験は、STT(Whisper)の単語タイムスタンプをアライメントのシードにして、音節と時間のずれをどこまで補正できるか。自動は下書き、先生のドラッグが完成版です。

先生のドラッグ補正データを正解に昇格させ、アライメントアルゴリズムの変更をms単位で採点するハーネス(修正のたびに正解と比べて自動で点数を出す採点装置)を作成。日韓の先生と243件のレビューを重ね、開始点ずれを26件から2件に、アライメント誤差p90を34%削減しました。

レビューページ自体も、レビュアーが速く正確に判断できるよう簡素化しました。自由記述ではなく問題タイプのタグで指摘を残す方式にして、レビュー結果がそのまま集計できる指標になるようにしています。

構成

全体をCloudflare上で運営しています。画面とAPIはWorker 1つ(web-beta)が担当し、毎日動くバッチと通知は別のWorker(agent-service)とDurable Objectが処理します。データはD1とR2に、添削動画はStreamに置き、ログインはソーシャルOAuthで処理しています。

発音チェックのサービス構成図
性能の実測

初期はスピードを優先してAIと共に素早く作り、運営が始まってからはそのコードを実測しながらひとつずつ整えました。「D1が遅いからAWSへ移すべきでは」という話が出たとき、wallTimeとcpuTimeを突き合わせてみると、実際に遅かったのはセッションを速くするために入れていたKVキャッシュでした。キャッシュを外すとセッション照会は573msから20msに、使わないデータまで運んでいたギャラリーの応答は6.6MBから186KBになりました。

キャッシュを外したセッション照会の経路
通知の重複

Discord通知が二重に届く障害もありました。2つの環境にcronが重複登録されていたのが原因でしたが、ワークフローはどちらも「正常完了」でエラーログが残らないため、実行記録の時刻を突き合わせてようやく見つけました。同じことが起きないようルールとして残しています。

cronが2つの環境に重複登録された通知の経路
トラフィックの正体

運営メンバーからの質問にも測定で答えました。「使う人がいない時間にトラフィックが出る」の正体は、60秒ごとにランディングページを丸ごとレンダリングさせていたアップタイムボット(1日1,440回)。早朝のトラフィックは、登校前に集中する学生の課題提出でした。提出はリクエスト1件ではなく、文の数だけ音声がアップロードされ、その後にWorkflowと通知が続く処理なので、数人が同じ時間に提出すると数十から数百のリクエストになります。「カードに韓国語が抜けるのでは」という心配は、キャンバスに描かれたピクセルを直接数えて問題ないことを確認しました。

課題提出1件が生むリクエスト
Stack
Next.js·React·tRPC·Drizzle·Turborepo·Cloudflare Workers·D1·R2·Stream·Workflows·Durable Objects
©2026 Imjurney · All Rights Reserved8 Posts | 4 Projects