構造化スタジオ
ベータ版見積書などの紙の業務文書をLLMで構造化し、算術検算を通過したデータだけを蓄積するWindowsデスクトップツール
公開日

対象ユーザー
- 紙の見積書・帳票の転記に時間を取られている人
- LLMの出力を業務データとして信頼させる設計に関心がある開発者
構造化スタジオは、紙やPDFの見積書などの業務文書をLLMで構造化し、算術の検算を通過したデータだけをSQLiteに蓄積するWindowsデスクトップツールです。BenriWorksの社内業務のために開発したもので、一般向けの提供は行っていません。それでもここで紹介するのは、「LLMの出力を業務データとしてどう信用するか」という問いへの、このツールなりの答えを記録しておきたいからです。
解決する課題
相見積を取ると、各社の見積書から品目名、数量、単価を表計算やシステムへ写す作業が発生します。件数が増えるほど時間を取られ、急いで写せば間違いも混ざります。
この転記自体は、LLMに文書を読ませればすぐに済みます。見積書を渡せば、それらしいJSONが返ってきます。問題はその先です。返ってきた数字が正しいという保証はどこにもなく、流暢に間違えた値を貯めてしまえば、後で集計に使うときに全件を疑い直すことになります。
構造化スタジオは、この問題を見積書という文書の性質で解きます。見積書には「数量×単価=金額」「明細の合計=小計」という算術的な冗長性があり、数字のどこかを読み間違えると、この計算が合わなくなりやすいのです。抽出結果をこの計算の突き合わせ(検算)に掛け、全て通過したデータだけを蓄積の対象にするのが中心の設計です。
主な機能
文書の読み方は構造化フレームという単位で再利用します。スキーマ、フィールド別の抽出指示、入力と期待出力のペア(Golden Sample)、検算ルールをひとまとめにしたもので、期待出力がスキーマ検証と検算を通らないフレームは保存自体ができません。動く定義だけが残る仕組みです。
現行版の構造化には、あえてLLMのAPIを使いません。アプリがフレームからプロンプトを生成し、利用者はそれを自分のMicrosoft Copilotに貼り付け、原本ファイルを添付して実行します。返ってきたJSONをアプリに貼り戻すと、スキーマ検証と検算が走り、違反したフィールドがエディタ上でハイライトされます。人手を挟む割り切りですが、API利用の承認を待たずに即日運用を始められます。
検算を全て通過したデータは、案件に紐付けて確定データへ昇格できます。ただし、検算が裏を取れるのは算術に現れる値だけで、品目名や日付の読み間違いは計算に現れません。そこでエディタは左に原本のページ画像、右に構造化案を並べた対比表示になっており、最後の確認は人が目で行う前提です。
昇格したデータの出口として、CSV出力(親子2ファイル形式とフラット形式)と、相見積2文書の突合比較があります。品目名の表記揺れを吸収する名寄せ辞書と品目ごとの単価履歴ビューも備え、貯めたデータを次の見積が高いか安いかの判断材料に使えます。
開発の背景
仕様書が最初に掲げるのは、機能ではなく「データ入力を目的化しない」という設計原則です。過去に案件データベースが入力負担の悪循環に陥った経験を踏まえたもので、転記や相見積の照合という、どうせやる業務の副産物としてデータが貯まる構造を求めています。転記時間の削減は価値の入り口にすぎず、その先に照合の統制、単価履歴というデータ資産、フレーム配布による読み方の標準化まで積み上げる構想です。
APIを後回しにした順番も、意図した判断です。生成AIのAPI利用に組織の承認が要る環境では、承認を待ってから作り始めると運用がいつまでも始まりません。承認の要らない手動経路でまず実績を作り、その実績と処理量の記録を、API承認を申請するときの材料にする。仕様書はこの順番を決定事項として明記しています。
技術と設計
本体はPython 3.11とpywebviewによるデスクトップアプリで、画面はReact 18とTypeScript、ビルドにViteを使っています。
通信面には特徴があります。WebのUIを使うデスクトップアプリでは内部にローカルHTTPサーバを立てる構成がよく採られますが、構造化スタジオはこれを避け、pywebviewのjs_apiブリッジでPythonとJavaScriptを直結しています。ポートを一切開かないため、外部との通信がないことを構成のレベルで説明できます。受け入れテストは外向きのsocket接続を禁止した環境で全件実行され、この性質はpytestで機械的に検証されます。
データはSQLiteファイル1個と添付フォルダで完結し、フォルダごとコピーすればバックアップになります。原本のPDFは取込時に表示用のページ画像へ変換するだけで、アプリ自身はOCRも内容解析も持ちません。文書を読むのはLLM側の役割、読み取り結果を検証して蓄積するのがアプリの役割という分担です。
検算ルールの式(例えば sum(lines.金額) == header.小計)は、Pythonのevalを使わず、許可した構文だけを通すホワイトリスト式のAST評価器で計算します。使えるのは四則演算とフィールド参照、sumやroundなど5つの関数に限られ、丸めは銀行丸めではない四捨五入に固定しています。円単位の端数処理の揺れに備えて、ルールごとに許容差(既定は±1)を指定できます。
現在の状態と既知の課題
社内利用のベータ版として運用しており、一般向けの提供や配布は予定していません。
仕様書はv0.95のドラフトのままですが、実装は仕様を追い越しており、当初はv1.5として計画していた名寄せ辞書と単価履歴ビューまで動いています。名寄せ辞書は電気工事分野を対象にしたパイロットとして整備を進めており、辞書データと調査報告の成果物があります。
既知の課題は二つあります。一つは手動経路のスループットで、プロンプトのコピーと応答の貼り戻しを人が担うため、処理量には上限があります。設計上の快適圏は月数十件の想定で、これを超える状態が続くこと自体を、API経路(次の版で計画)を申請する定量的な材料にする位置づけです。もう一つは品目の名寄せの難しさで、サイズや規格が品目名に直結した表記は辞書の一般規則では扱いきれず、人手で同一品目を確定する機能に委ねています。確定した結果は、辞書を育てる種として蓄積されます。
分野・使用技術
- 分野
- 使用技術



