AIに事実を語らせない設計 — 決定論エンジン+LLMは文章化のみ
手相のVLM抽出・四柱推命の決定論計算・LLMによる文章化を三層に分け、生成文の根拠を機械検証する。Palmia の実装記録
ブラウザ版が公開中です(iOSアプリは近日公開)。
なぜポートフォリオにあるか
「AIが嘘をつくかもしれない」は、生成AIの導入を止める理由として正しい。止めないための方法は、AIを信じないことです。Palmia は、事実の計算をAIの外に出し、AIには文章化だけを任せ、その文章が引用した根拠を機械が検証する構成で組みました。
なぜ作ったか
占いアプリは、生成AIを最も雑に使える領域です。「それらしいことを書けば当たっているように読める」ので、AIが事実を捏造しても誰も気づかない。
だからこそ逆の設計を試す題材として適していました。**当たるかどうかではなく、「アプリが提示した根拠が、そのユーザーのデータに実在するか」は機械的に判定できる。**その判定を通らない文章を世に出さない仕組みを作れるなら、同じ構造は契約書の要約にも、保険や医療の説明文にも、社内規程のQ&Aにも移せます。
いちばん難しかったこと
「AIに嘘をつかせない」は、プロンプトで解決できません。「事実に基づいて答えて」と書いても、モデルは事実に基づいて答えているつもりで存在しない特徴を語ります。
難所は2つありました。
- どこまでをAIの外に出すか。 四柱推命の命式計算は、暦の変換ルールの塊です。ここをAIに任せると、節入り時刻の境界で静かに間違えます。
- 文章化だけを任せたあと、その文章をどう検証するか。 自由な日本語を出力させた時点で、内容の正しさは通常もう追えません。
どう決めたか(と、捨てたもの)
三層に割りました。VLM は手のひらの特徴を構造化して抽出するだけ。四柱推命の命式は決定論エンジンが計算する。LLM に許すのは、それらを日本語の文章にすることだけ。
電卓が答えを出し、AIはその答えを読み上げるだけ。AIに計算はさせません。だから、ありもしない数字が出てきません。
検証のために、生成される各セクションに evidence_refs(根拠の参照)の提示を必須にしました。参照先は lines.heart.tip のような正規の語彙に限られ、実在しない参照を引いた文章は検証に失敗して再生成されます。
捨てたものは表現の自由度です。モデルが「なんとなく良いことを言う」余地を消したので、文章は構造に縛られます。占いとしての面白さより、言っていることの裏が取れることを優先しました。
実際に動いているもの
節気データは1940〜2036年の97年分を分精度で保持し、年柱・月柱の切替を節入りの「時刻」で判定します(立春当日でも、その時刻より前ならまだ前年)。
モデルは役割ごとに使い分けています。手相の特徴抽出に Gemini 3.5 Flash、日々のリーディングに Flash-Lite、有料の詳細レポートに Claude Opus 5。呼び出しは成功・失敗を問わず1件ずつ原価台帳に記録し、**そのときの単価をスナップショットして保存します。**あとからモデルの価格が変わっても、過去の原価が books の上で書き換わらないためです。
財布を守る制御は3層に分けました。IPごと・検証済みユーザーごと・アカウント全体の上限で、IPは詐称や VPN で回避できるという前提に立っています。
手のひら画像はリクエスト中しか存在せず、端末にもサーバにも永続化しません。
コードから数えられる値
2026-07-21 から 07-29 までの86コミット、114,822行(ts / tsx / sql / mjs)。テスト369ファイル、全ワークスペースでカバレッジ100%を閾値強制。データベースは22テーブル・36 RLSポリシーで、さらに3テーブルは意図的にポリシーを一切張らず(=anon / authenticated からは1行も見えない)service_role 専用にしています。RLS の検証は pgTAP のスイート13本。
CIは7ワークフロー。うち1本がセキュリティ専用で、CodeQL・Gitleaks・Secretlint・依存監査・ライセンス許可リスト・SBOM・Trivy・OSV-Scanner を束ねています。
これは、あなたの案件の何を証明するか
「間違った1文が事故になる」領域で生成AIを本番に出すには、この形にする必要があります。事実の計算をAIの外へ出し、AIには文章化だけを任せ、その文章が引用した根拠を機械で検証する。契約書の要約、保険・医療・金融の説明文、社内規程のQ&A — どれも同じ構造に載ります。
景表法・薬機法の表現チェックをCIに載せる仕組みも実装済みで、そのまま持ち込めます(「否定するために迷信を引用する文」を通す実装になっているのが要点です)。
この形の生成AI実装は、モダン・AI開発のサービスとしてお請けしています。音声AIチャットボットを本番運用した受託事例もあわせてご覧ください。
コードから数えられる値
- テスト
- 369ファイル全ワークスペースでカバレッジ100%を閾値として強制。1行でも未テストの行があればCIが落ちる
- RLSポリシー
- 36本全22テーブルで有効化。加えて3テーブルはポリシーを一切張らず service_role 専用にしている
- セキュリティCI
- 7ワークフローCodeQL / Trivy / OSV / SBOM / ライセンス許可リストを含む
- 節気データ
- 97年分1940〜2036年の節入り時刻を国立天文台の値で分単位まで保持
よくある質問
- パルミアは今すぐ使えますか?
- ブラウザ版のスキャン機能は今すぐ利用できます。iOSアプリは近日公開の段階で、まだリリースされていません。
- AIが占いの内容を作り話することはありませんか?
- 構造上できません。四柱推命の事実計算は決定論エンジンが行い、LLMには文章化のみを許可しています。生成された各セクションは根拠の参照(evidence_refs)の提示が必須で、正規の語彙に照合できない根拠を引用した文章は検証に失敗し、再生成されます。
- 手のひらの画像は保存されますか?
- 保存しません。手のひら画像を永続化しない設計にしており、画像はリクエストの処理中にしか存在せず、端末にもサーバにも残りません。
- 四柱推命の計算はどこまで正確ですか?
- 1940年から2036年までの97年分の節入り時刻を、国立天文台の値で分単位まで保持した決定論エンジンで計算しています。立春当日でも、節入りの時刻より前であれば前年として扱います。
- どのAIモデルを使っていますか?
- 手相の特徴抽出に Gemini 3.5 Flash、日々のリーディングに Flash-Lite、有料の詳細レポートに Claude Opus 5 を使い分けています。原価は呼び出し単位で台帳化し、そのときの単価をスナップショットして保存しています。
- テストの水準はどのくらいですか?
- テストは369ファイルあり、全ワークスペースでカバレッジ100%を閾値として強制しています。1行でも未テストの行があればCIが落ちます。セキュリティCIはCodeQL・Trivy・OSV・SBOM・ライセンス許可リストを含む7ワークフロー構成です。
同様の課題、抱えていませんか?
あなたのビジネス課題も、最新の技術で解決できます。 まずは30分の無料技術相談から、状況をお聞かせください。
自社の課題もSaaS化できるか相談するプロジェクト単位(請負)・技術顧問、どちらにも対応可能です