← 一覧に戻る
🏛️
ビジネス(開発部)

hojokin-risk-audit-ai

補助金・助成金の**公募要領**(PDFまたは貼り付けテキスト)から応募要件を自動で抽出し、**事業計画書**に書かれた数値・属性と機械的に突合して、要件ごとに「適合 / 不適合の可能性 / 要確認 / 判定不能(情報不足)」を並べるWebアプリ。画面は1枚で、①公募要領を登録 → ②事業計画書を登録 → ③監査を実行、の3ステップ。 このアプリの中心は突合そのものではなく、**その手前にある「根拠の実在確認」**にある。抽出された要件には必ず「公募要領のどこに書いてあるか」という引用が付くが、その引用が**原文中に本当に存在する文字列かどうかを機械的に照合**し、見つからないものは監査対象から自動的に外す。外したことも画面に件数と条件名つきで表示する。 なお、このアプリは**採択・不採択を判定しない。** 画面の先頭に「本ツールは補助ツールであり、採択・不採択の最終判断や専門家(中小企業診断士・行政書士等)への相談を代替するものではありません」「『適合』と表示された項目についても、採択を保証するものではありません」と明記されており、この2文は消せる設定にしていない。

実際のアプリを開く ↗

💻 `C:\Users\utsus\Desktop\AIの作業場\hojokin-risk-audit-ai` で `npm run dev -- -p 3403` を実行してください。起動後 http://localhost:3403 でアクセスできます。初回は `npm install` と `npx prisma generate` が必要です(SQLiteドライバ better-sqlite3 はネイティブ拡張のため、Node.js 24ではビルド済みバイナリが配布されておらず、Node.js 20/22系での実行を推奨します)。

保存場所: C:\Users\utsus\Desktop\AIの作業場\hojokin-risk-audit-ai

なぜ作ったか

補助金の申請支援にAIを使うとき、いちばん危ないのはAIが「それらしい要件」を作ってしまうことだった。

要件の読み違いや作り話が、そのまま「この計画なら大丈夫です」という形で申請者に伝わると、被害は「AIが間違えた」では済まない。不採択で数か月が無駄になり、採択後に要件不適合が判明すれば補助金の返還が発生する。しかも補助金の要件は法令・要綱に紐づく行政の判断であって、ツールが結論を出してよい領域ではない。

そこで設計の中心を、AIの出力を人が信じるかどうかに委ねず、機械で棄却できるようにすることに置いた。守り方は4つ。

#やらないことどう作ってあるか
1存在しない引用を根拠にしない抽出された引用が原文の部分文字列として実在するかをサーバー側で毎回照合する。判定はLLMではなく単純な文字列比較(src/lib/verify/quoteGuard.ts)
2実在確認できない条件で合否を出さない監査APIが quoteVerified === true の条件だけを通す。落ちた条件は判定に一切使われず、「除外しました」と件数つきで別枠に出る
3値が無いものを「満たしている」に丸めない事業計画書にその項目の記入が無ければ「判定不能(情報不足)」を返す。空欄を通過扱いにする分岐が存在しない
4読み取れない文を推測で読まない「〜を除く」「〜でない者」のような除外の言い回しを含む条文は、意味を反転させて解釈せず抽出そのものを見送る。自信を持って間違えるより、拾わない方を選んでいる

3番目と4番目は「見逃し(拾えなかった)」を許して「言い切って間違える」を潰す方向に倒しているので、画面の注意書きでも「抽出条件の見逃し(偽陰性)が残る可能性があります」と正直に書いている。

どういう場面で使うか

補助金の申請書を書き終えたあと、出す前に一度、要件と自社の数字を突き合わせて確認する場面で使う。

公募要領のPDFを入れ、自社の従業員数・資本金・売上高・業種・所在都道府県・設立からの年数を入れて「監査を実行」を押すと、条件ごとに満たす/満たさない/判定できないが根拠の引用つきで並ぶ。

「不適合の可能性」が出たら、それは修正ではなく確認の入口として扱う。原文のどこを見ればよいかがページ番号つきで示されるので、その1か所だけを読み直して、最終的な可否は申請者本人か専門家が判断する。逆に全部「適合」でも出せる保証にはならない、というのが画面上に明示されている。

PDFはテキスト層のあるものだけを受け付ける。スキャン画像のPDFを入れると、空のテキストを黙って通さずに「テキストを検出できませんでした。OCRに対応していないため、テキスト層を持つPDFかテキストの直接貼り付けでご利用ください」と理由つきで止まる。

自動化されているポイント

  • 要件の自動抽出 — 公募要領の本文から、従業員数・資本金・売上高・対象業種・対象地域・設立年数の上限下限を自動で拾い、比較可能な条件(項目・演算子・値)に変換する
  • 引用の実在確認を自動で全件実行 — 抽出結果を保存する前に、引用が原文にあるかを毎回照合する。自前の抽出器が出した引用も例外にしていない
  • 捏造された根拠の自動除外 — 照合に落ちた条件は監査対象から自動的に外れる。データとしては消さずに残し、除外した件数と条件名を画面に出す
  • 除外条文の自動スキップ — 「〜を除く」を含む条文は条件化せず自動で見送る
  • 未記入項目の自動判別 — 事業計画書に値が無い項目は「判定不能」として自動で分離され、適合にも不適合にも数えられない
  • スキャンPDFの自動検出 — 1ページあたりの平均文字数からテキスト層の有無を判定し、OCR非対応であることを明示して止める
  • 監査時点の根拠の自動保存 — 監査結果には、その時点の実在確認フラグを複製して保存する。あとで抽出条件が変わっても、過去の監査が何を根拠に出た結論かを追える

使い方(画面の流れ)

①公募要領を貼り付けるか、PDFを入れて登録すると、その場で条件が抽出され、1件ずつ実在確認の結果が付く。

公募要領と事業計画書の登録画面(架空データ)

画面の先頭にあるのは説明文ではなく注意書きで、「採択・不採択の最終判断を代替しない」「『適合』でも採択を保証しない」の2点が常に見える位置にある。左が公募要領、右が事業計画書の登録。事業計画書は自由記述だけでなく、従業員数・資本金・売上高・設立からの年数・業種・所在都道府県を数値/文字として別に入れる。突合は文章同士ではなくこの項目に対して行う。

②抽出された条件は「実在確認済み ○件」と、条件ごとの ✓ / ✗ で表示される。

抽出条件の実在確認一覧(架空データ)

✓が付いた6件は、引用が公募要領の原文にそのまま存在することを機械が確認したもの。✗の2件は、引用が原文中に見つからなかったもので、この時点で既に監査には使えない状態になっている(スクリーンショットでは、LLMが根拠を捏造した場合に何が起きるかを写すため、原文に無い引用を持つ条件を2件混ぜている。現在の正規表現ベースの抽出器は原文から文字列を切り出す作りなので、原理上この状態を自力では作れない)。

なお、公募要領に書いた「常時使用する従業員の数が5人以下の小規模事業者を除く」という除外条文は、条件として抽出されていない。反転して解釈すると意味が逆になるため、意図的に見送っている。

③監査を実行すると、条件ごとの判定が根拠の引用つきで並ぶ。

監査結果画面(架空データ)

適合(緑)・不適合の可能性(赤)・判定不能(灰)が同じ粒度で並び、どれにも「根拠: 「公募要領の原文」」が付く。所在都道府県を空欄にした計画では、地域要件が**適合にも不適合にもならず「判定不能(情報不足)」**になっている——ここを勝手に通過扱いにしないことがこのアプリの肝になっている。いちばん下には「引用が原文中に見つからず、監査対象から自動的に除外された抽出条件(2件)」が、条件名つきで出ている。

④スマートフォンでも同じ判定がそのまま読める。

スマートフォンで見た監査結果(架空データ)

判定・説明・根拠の引用が縦に積まれる。ただし現時点ではPC画面をそのまま縮めた状態で、モバイル専用のレイアウトは作っていない。

訴求ポイント

  • 「AIが作り話をしていないか」を人の目視ではなく機械で潰している — 引用の実在確認はLLMに判定させず、空白を正規化した上での単純な部分文字列比較で行う。AIの出力をAIに検算させる構成にしていないので、検算側が一緒に間違えることがない
  • 断定しないことが、文言ではなくコードの分岐になっている — 「採択を保証しない」は注意書きに書くだけなら誰でもできる。このアプリは、実在確認に落ちた条件が判定に混ざる経路そのものを塞いであり、未記入項目を適合に丸める分岐が存在しない
  • 不適合を出しても、次に見る場所が1か所に決まる — すべての判定に原文の引用とページ番号が付くので、「AIがそう言っている」ではなく「公募要領のこの行と、御社のこの数字が合わない」という形で確認に移れる
  • 抽出エンジンを差し替えられる形にしてある — 抽出は LLMProvider インターフェース越しに呼ばれ、どの実装が抽出したかを1件ずつDBに記録している。現在は外部APIを一切呼ばない正規表現ベースの実装で動いており、APIキーが無くてもそのまま使える
  • 見逃しを認めている — 「全部拾えます」と言わず、拾えないパターンがあることを画面に書いている。行政の判断が絡む領域で、この正直さは信用の条件になる

現時点でやっていないこと

  • 採否の予測・スコアリング(意図的にやらない。要件との突合までが範囲で、採択可能性の点数化はしない)
  • LLMによる要件抽出(差し替え用のインターフェースと型は用意してあるが、実装は正規表現ベースのものだけ。対応するのは従業員数・資本金・売上高・業種・地域・設立年数の典型的な言い回しに限られる)
  • スキャンPDFの読み取り(OCR非対応。黙って空で通さず、理由を出して止める)
  • ログイン・利用者ごとのデータ分離(現状は誰でも登録・閲覧できる。社内・手元での利用を前提にしている)
  • スマートフォン専用レイアウト(PC画面をそのまま縮めているため、幅375pxでは選択欄が横にはみ出す)
  • 本番デプロイ(データベースがSQLiteのファイル1つのため、現時点ではローカル起動のみ)
README原文を見る →