スマホで手のひらを撮って結果を読む——手軽な体験の裏では、ビジョンモデルと説明文生成のつなぎ方、そして「何を約束しないか」の境界設計が重要です。本稿では公開されている日本語の説明を手がかりに、Palm Reader のような娯楽向けパイプラインを組むときのメモを残します。手相は娯楽・自己振り返り用であり、医療・金融・法律・人間関係の専門助言ではありません。 コードはすべて説明用のサンプルです。
公開フローから見える処理段
日本語版の案内は次の3段です。
- 鮮明な手のひら写真をアップロード
- 名前と誕生日を入力(面倒な登録なし、と説明)
- 生命線・知能線・感情線・運命線などの解説を読む(保存可)
結果には総合スコアやパーソナルテーマなどもあります。実装に落とすと、(A) 画像前処理と線の検出候補、(B) 構造化特徴、(C) 読みやすい日本語説明、の三段になります。「約1分」「読みやすい」「プライバシーに配慮」といった公開コピーは、そのままSLO・文面トーン・保持ポリシーの受け入れ条件になります。
画像入力のバリデーション
暗い写真や指が閉じた写真では線が取れません。クライアントで完璧を求めず、サーバでも弾くのが安全です。公開Tips(自然光・指を軽く開く・背景をシンプルに)は、エラーメッセージの文案そのものに使えます。
type PalmUpload = {
imageBytes: Buffer;
mime: 'image/jpeg' | 'image/png' | 'image/webp';
name: string;
birthDate: string; // YYYY-MM-DD
};
function validatePhotoMeta(width: number, height: number, brightness: number) {
if (width < 640 || height < 640) {
return { ok: false as const, reason: '手のひら全体が写る解像度にしてください' };
}
if (brightness < 0.25) {
return { ok: false as const, reason: 'もう少し明るい場所で撮ってください' };
}
return { ok: true as const };
}
撮影ガイドをUIの前段に置き、失敗時だけ詳細を出すと離脱が減ります。手以外が大きく写っている・複数人が写っている場合の扱いも、早めに仕様化しておくとよいです。
構造化してから文章を書く
ビジョンの生ログをそのままLLMに渡すと、毎回トーンがぶれたり、根拠のない断定が増えたりします。先に特徴をJSON化し、説明はテンプレ+言い換えに限定します。「一般的な星座占いの定型文ではない」とあるので、誕生日はトーンの調整やテーマの補助に使い、手の特徴と矛盾する断定を出さないガードが必要です。
type PalmFeatures = {
overallScore: number; // 0-100 表示用
lines: {
life?: { strength: number; notes: string[] };
head?: { strength: number; notes: string[] };
heart?: { strength: number; notes: string[] };
fate?: { strength: number; notes: string[] };
};
themeHint: string; // 例: exploration / stability
};
const DISCLAIMER =
'本結果は娯楽・自己振り返り用です。医療・金融・法律・人間関係の助言ではありません。';
function toExplainPrompt(f: PalmFeatures, name: string) {
return [
'Write gentle Japanese explanations for entertainment only.',
'Do not give medical, financial, or legal advice.',
`Name: ${name}`,
`Features JSON: ${JSON.stringify(f)}`,
'Cover the four main lines briefly, then one personal theme.',
`End with: ${DISCLAIMER}`,
].join('\n');
}
総合スコアは「正しさの証明」ではなく、画面上で全体像をつかむための要約値です。内部の特徴量をそのまま100点満点の科学指標のように見せない方が、娯楽プロダクトとしての期待値コントロールになります。
結果の保存と共有
公開文には、診断結果の保存・ダウンロード・共有が案内されています。実装では「テキスト結果」「特徴JSON」「原画像」を別ライフサイクルにすると安全です。共有リンクには画像を含めず、短文結果と免責だけを載せるのが無難です。
type PalmReport = {
id: string;
userKey?: string; // ログイン無しならブラウザ側キー
features: PalmFeatures;
narrative: string; // 生成済み本文(免責込み)
createdAt: Date;
imageDeletedAt?: Date; // 原画像削除時刻
};
function publicSharePayload(r: PalmReport) {
return {
id: r.id,
narrative: r.narrative,
overallScore: r.features.overallScore,
// imageUrl は載せない
};
}
プライバシーと保持
手の画像は生体に近いセンシティブデータです。最低限でも次を決めます。
- 解析後に原画像をいつ削除するか(即時/短期)
- 結果テキストだけを保存するか、特徴JSONも残すか
- 共有リンクに画像を含めない
- ログに顔や他の人物が写り込んでいないか
- サポート用に一時保持する場合のアクセス権限
「プライバシーに配慮」と書くなら、保持期間と削除の方針をプロダクト仕様に含めるのが一貫します。解析ワーカーの一時ディスクからも、ジョブ完了後に確実に消す必要があります。
フロントの役割とやらないこと
- やる: 撮影ガイド、アップロード進捗、結果の読みやすいレイアウト、保存/再表示、免責の常時表示
- やらない: 「当たる」「治る」「成功する」系の断定コピー、医療・投資・恋愛成就の保証、原画像の無期限CDN公開
娯楽ドメインでも、コピーとAPIの両方が同じ境界を守っているかが信頼の要点です。
レイテンシとユーザー期待
「約1分」はマーケティング文言であると同時に、キュー設計の制約です。ビジョン推論と説明生成を直列にすると外れ値が出やすいので、次のようにすると安定します。
- アップロード完了時点でジョブIDを返す(同期はここまで)
- 前処理・特徴抽出をワーカーで実行
- 説明文生成は特徴JSONが揃ってから
- 完了後に結果ページを更新(ポーリングまたはSSE)
途中経過(「手の線を探しています」「文章をまとめています」)を出すと、体感待ちが短くなります。失敗時は撮影ガイドへ戻す導線を優先し、同じ暗い写真で無限リトライさせない方が良いです。
スコアとコピーの倫理
総合スコアや「最も強いサイン」は、娯楽UIとしては分かりやすい一方、科学的根拠があるように読めすぎると誤解を生みます。表示上は「傾向の要約」である旨を近くに置き、数値の差が小さいときは差を煽らないラウンド表示にする、といった細部も効きます。LLM側には「断定禁止・助言禁止・必ず免責」をシステムプロンプトと出力検証の両方で二重に掛けます。出力検証では、医療・投資・法律キーワードの簡易検出だけでも事故率は下がります。
まとめ
娯楽向け手相AIは、精度アピールより 入力品質・構造化・免責・画像保持 の設計が本体です。主要な線の見せ方や注意書きの置き方は Palm Reader で確認できます。断定を避け、ユーザーが「振り返りのきっかけ」として使える言葉に落とす——それがこの系統のプロダクトではいちばん長い寿命を持ちます。


