Claude Code × Medical Application
【Claude Code】社内の BI ダッシュボードを AI ダッシュボードに Part4:公開と運用 — 費用とセキュリティの管理

1. はじめに — 費用と安全は、先に決める
AI ダッシュボードを人に使ってもらうとき、気になるのは費用と安全です。質問のたびに AI を呼ぶので、使われるほど費用がかかります。誰かに機械で連打されたら、どこまで膨らむのか。
Part3 までで、話しかけると動く画面ができました。Part4 は、それを公開して運用する回です。今回は誰でも使える公開のデモなので、社内で使うときより条件は厳しくなります。見る人を選べず、悪意のある使い方も想定しなければなりません。
この回の構成です。
- はじめに(この章)
- 費用を守る — 三重の上限
- ボット対策は入口で1回だけ
- 測ってから直す — スマホの初回表示
- 公開は2段階、人の手を決めておく
- 社内で使うときとの違い
- 今回のハーネス/まとめ
2. 費用を守る — 三重の上限
2-1. 先に天井を決める
公開のデモなので、誰が何回押しても費用が膨らまないことを、作る前に決めました。上限は三重です。
- 入口でボット対策:Cloudflare Turnstile を入口で1回だけ通す(3章)
- 回数制限:1人あたり1時間20回・1日60回。Cloudflare の KV(キーと値の保存先)に記録する
- 月額の上限:Anthropic に専用のワークスペースを作り、月額の上限を設ける
質問文は保存しません。何を聞かれたかを記録しないので、閲覧者の入力を預かる責任も生まれません。
2-2. 1問あたり約0.1円
モデルは Claude Haiku 5.5 で、料金は入力が100万トークンあたり0.10ドル、出力が0.50ドルです(公式の料金ページで確かめました)。1問で AI を1〜3回呼び、入力は約200〜2,000トークン(指示文はキャッシュから読むので少ない)、出力は約450〜650トークンでした。多いほうで計算しても1問あたり約0.0005ドル、約0.1円です。
- 約0.1円1問あたりの AI の費用(実測のトークン数から)
- 20回1人あたり1時間の回数制限(1日60回)
2-3. 止まっても、画面は使える
月額の上限に達して API が止まったときは、使用上限や残高不足のエラーを見分けて「今月は質問機能を停止中です。下の条件から選んで見られます」と出し、質問欄だけを止めます。条件を手で選ぶ部分とほかの画面は、そのまま使えます。
この表示は、本番の設定には触れずに確かめました。手で止めるための設定(ASK_PAUSED=1)をプレビュー環境だけに入れて別の枝にデプロイし、表示を確かめてから消しています。止まったときの姿も、作るものの一部です。
3. ボット対策は入口で1回だけ
3-1. 質問のたびに確認を出さない
最初の版では、質問の入力欄の下に Turnstile(ボット対策の確認)の枠を置いていました。これでは質問のたびに枠が目に入り、使いにくくなります。
そこで、入口のページで「ご利用にあたって」を読んで同意するときに、Turnstile を1回だけ通す形にしました。通った人には、サーバーが24時間の署名つきクッキーを渡します。質問の窓口(/api/ask)は、毎回このクッキーを確かめます。
- クッキーは「期限・乱数・署名(HMAC-SHA256)」の3つをつないだもの。HttpOnly・Secure・SameSite=Lax で、送る先は
/apiだけ - 署名の比較は、かかる時間をそろえる(比べ方の差から鍵を推測されないように)
- テストは11件。期限切れ・書き換え・別の鍵・形のおかしな値をすべて弾くことを確かめた
3-2. 入口とアプリを分ける
最初は、今のページの上に同意の画面を重ねる形にしましたが、入口のページ(/)とアプリの画面(/app)を分ける形に変えました。共有された URL から直接 /app?… に来た人も、まず入口に送り、同意したら元の条件の画面に戻します。
戻り先は /app で始まるものだけに限っています。戻り先を自由に指定できると、外のサイトへ飛ばす踏み台にされるからです。この確かめもテストを7件書いています。
3-3. 切れたら、裏で通し直す
同意はブラウザに30日残りますが、クッキーは24時間で切れます。切れたときに入口へ戻すと、送りかけた質問が消えてしまいます。そこで、質問を送ったときに 401 が返ったら、裏で Turnstile を通し直してクッキーを取り直し、同じ質問を送り直すようにしました。確認の枠が出るのは、本当に確かめが要る人だけです。
Turnstile がトークンを出せないとき、質問欄が止まったままになる弱点も見つかりました。エラーか20秒で、空のトークンのまま送る形にしています。サーバーが「ボット対策の確認ができませんでした」と返し、画面は止まりません。
4. 測ってから直す — スマホの初回表示
4-1. まず測る
社内の BI でも、外出先でスマホから見たい、という声はよく出ます。プレビュー公開のあと、スマホの初回表示を測りました。条件は、遅い4G(1.6Mbps・150ms)と4G(9Mbps・60ms)、CPU を4倍に減速、キャッシュなし、3回の中央値です。
最初の計測では転送量が約1.7MBで、内訳はフォント 654KB、施設の一覧 312KB、JS 277KB(大半が地図の部品)、地図のタイル 226KB でした。Claude Code には、内訳と「効く順の直し案」を出させてから、人が「フォントの軽量化と、施設の一覧の最小化」を選んで頼みました。
4-2. 効いたのは「読む時期」
- 施設の一覧を2つに分ける:初回は最小の列(id・短い名前・都道府県・医療圏・座標・区分)だけ。gzip で 312KB → 136KB。正式名称・病床・リンクは、地図が落ち着いてから読む
- フォントを読む時期を遅らせる:使う太さを3つから2つに減らしても、転送量はほとんど変わりませんでした。効いたのは、最初の画面に要るデータがそろってからフォントを読むことでした。それまでは端末の標準フォントで描きます
- 先読み:データの JSON を HTML の時点で先読みし、地図のタイルと Turnstile のサーバーに事前に接続する
4-3. 測り方の書き分けも直した
直したあとに測り直すと、4G で地図の円まで 2.1秒 → 1.4秒でした。ここで、目標にしていた「4G で4秒以内」は直す前から満たしていたことが分かりました。最初に報告された 9.5秒は遅い4G の値で、条件の書き分けが足りなかったのです。数字を報告させるときは、どの条件で測ったかを必ず一緒に書かせるようにしました。
直す途中で、スマホでは地図が日本全体を収められず、北海道の東と先島が切れていることにも気づきました。地図の中の状態を読むと、最小ズームが4で止まっていました。地図の部品を途中で入れ替えたとき、前の部品の感覚で決めた値が残っていたのです。最小ズームを3に直すと、全国表示の地図タイルも 226KB → 33KB に減り、遅い4G で 4.0秒、4G で 1.2秒になりました。
4-4. 安全のための更新で、少し遅くなった
公開前の総点検で、地図の部品(MapLibre)に既知の脆弱性が見つかり、直った版(4 → 6)に上げました。JS が 286KB → 366KB に増え、測り直すと地図の円まで 4G で約1.5秒、遅い4G で約4.2秒になりました。最初の画面が地図なので、地図の部品を後から読む形にしてもほとんど速くなりません。手間に見合わないと判断し、この値で公開しています。
5. 公開は2段階、人の手を決めておく
5-1. 検索に出ない仮の URL で確かめる
公開は2段階に分けました。
段階1は、Cloudflare Pages の仮の URL(〇〇.pages.dev)への公開です。検索に出ない設定を 3重にしました。robots.txt、ページの meta robots、そしてデータの JSON も含む全ファイルに付ける X-Robots-Tag です。デプロイしたあと、3つとも効いていることを確かめています。本番と同じ設定で動かして、ここまでの章の確かめ(費用・ボット対策・スマホ)をすべて実物で行いました。
段階2は、記事の公開と同じ日です。本番のドメイン(dpc.herzleben.co.jp)を付けて検索に出ない設定を外し、記事を公開します。アプリの入口とフッターには、機能を紹介するためのデモであり、集計や名寄せに不正確な点が含まれる場合があることを、目立つ形で出しています。
5-2. 人にしか任せないこと
Claude Code には、デプロイのコマンドや Pages のプロジェクト・KV の作成まで任せました。一方で、次の3つは人がやると決めていました。
- 秘密の値を入れる:API の鍵、クッキーの署名の鍵、Turnstile の本番の鍵は、人が自分で Cloudflare の Secrets に入れる。Claude Code の会話にも作業ログにも残らない
- ボット対策の確認欄を押す:3章のとおり、AI は代わりに通さない
- 公開に切り替える:本番のドメイン、検索に出ない設定を外すこと、記事の公開
どれも、間違えたときに取り返しがつかないか、AI がやると意味をなくすものです。
5-3. 運用のつまずき
手元での作業にも、小さなつまずきがありました。設定ファイルに KV を足した瞬間、手元で動かしていた開発用のサーバー2つが同時に設定を読み直し、模擬の KV のファイルを取り合って1つが落ちました(SQLITE_BUSY)。古い開発用のサーバーが6つ残っていて、新しいサーバーが404を返したこともあります。手元で何が動いているかを、区切りごとに確かめて止めるようにしました。
6. 社内で使うときとの違い
今回は公開のデモなので、社内で使うときとは前提が違います。違いを整理しておきます。
| 今回(公開のデモ) | 社内で使うとき | |
|---|---|---|
| 見る人 | 誰でも | 社員・関係者 |
| 入口の確かめ | Turnstile と署名つきクッキー | 社内の認証(シングルサインオンなど) |
| 回数制限・月額の上限 | 必須 | あったほうが安心(費用の見通しが立つ) |
| データ | 公表された値だけ | 権限ごとに見せる範囲を分ける |
| 検索に出ない設定 | プレビューの間だけ | 常に(社内の網の中に置く) |
費用の守り方と、止まっても画面が使える作りは、社内でもそのまま使えます。入口の確かめは、社内の認証に置き換わります。
7. 今回のハーネス
| 道具 | このアプリでの実体 | 役割 |
|---|---|---|
| 費用の上限 | 回数制限(KV)・専用ワークスペースの月額上限 | 誰が何回押しても費用に天井がある |
| 入口の確かめ | Turnstile・署名つきクッキー・テスト18件 | 質問のたびに確認を出さずに守る |
| 停止中の表示 | ASK_PAUSED、エラーの見分け |
止まっても画面は使える |
| 計測 | 遅い4G・4G、CPU 4倍、3回の中央値 | 直す前に測り、条件を書き分ける |
| 2段階の公開 | noindex 3重のプレビュー → 本番 | 実物で確かめてから開く |
| 人の手 | 秘密の値・ボット対策・公開の切り替え | 取り返しがつかないこと、AI がやると意味をなくすこと |
8. まとめ
- 費用は、作る前に天井を決めた。ボット対策・回数制限・月額の上限の三重で、1問あたり約0.1円
- ボット対策は入口で1回だけ。24時間の署名つきクッキーで、質問のたびに確認を出さない
- スマホの初回表示は、測ってから直した。効いたのは量より「読む時期」。測った条件を書き分けることも直した
- 公開は2段階。秘密の値・ボット対策・公開の切り替えは人がやると決めておいた
任せる範囲を広げるほど、人がやることをはっきり決めておく必要があります。
連載のおわりに
Part0〜4 で、社内の BI ダッシュボードを「話しかけると動く AI ダッシュボード」に変える過程を、DPC 公開データを題材に紹介しました。
- Part0:全体像と設計 — 何が変わるか、どんな画面か
- Part1:データ整備 — 年度・施設・地域の不一致をそろえる
- Part2:数値の検証 — 照合とレビューで正しさを担保する
- Part3:生成 AI の組み込み — AI に委ねる範囲の設計
- Part4:公開と運用 — 費用とセキュリティの管理(この回)
アプリは dpc.herzleben.co.jp で公開しています。実際に話しかけて、AI がどの条件を選んだかを確かめてみてください。
出典
- Anthropic「Pricing」(Claude Haiku 5.5、2026年10月24日確認)。https://www.anthropic.com/pricing
- Cloudflare, Pages Functions / Workers KV / Turnstile のドキュメント
- 地図:国土地理院「地理院タイル(淡色地図)」
- 本記事の図表・画面は株式会社HerzLebenが作成したものです
