法務ツールの実装入門──Python・tkinter・exe化で「現場に配れるツール」を作る
法務ツールの実装入門
──Python・tkinter・exe化で
「現場に配れるツール」を作る
法務ツール開発で最も難しかったのは、AIモデルの選定ではなかった。
「自分のPCで動く」を「他人に配れる」に変える──その実装の全過程を公開する。
前回の第2回「オフラインAIで作る理由」では、法務がクラウドAIを「選べない」場面が構造的に多いこと、そしてオフラインAIを戦略的に選択する3つの設計原則──データ主権の完全保持、再現性と検証可能性、自社ルールへの完全適合──を解説しました。
第3回となる本稿のテーマは、その設計思想をどう実装に落とすかです。
率直に言います。法務ツールの開発で最も時間を費やし、最も挫折しかけたのは、AIモデルの選定でも、正規表現の設計でもありませんでした。「自分のPCで動くツール」を「他人のPCでも動くexe」にする工程──つまり配布の壁──が、全工程の中で最大のボトルネックでした。
本記事は、第1回「要件定義10STEP」のSTEP 4(中核ロジックの選定)・STEP 5(誤検出対応)・STEP 8(設定・辞書の外出し)を掘り下げ、筆者が契約書マスキングツール、Legal Gateway、稟議一枚化ツール等の開発で得た知見を、非エンジニアの法務担当者が追体験できる粒度で整理します。
本記事の構成は以下の通りです。
開発順序
ロジック設計
GUI設計
配布の壁
設定外出し
ログ・版管理
第1章 ── 開発順序
法務ツールはどこから作り始めるべきか
法務担当者がツールを自作する際、最大の落とし穴は「最初からAIを入れようとすること」です。
生成AIの話題が先行するあまり、「まずLLMを使った契約書レビューを作ろう」と考えがちですが、これは順序が逆です。最初のバージョンでは、100点の自動化を目指す必要はありません。むしろ、精度より先に、再現性・説明可能性・改修容易性を優先すべきです。
本稿では、Python経験が浅い法務担当者でも、まずは「1つのWordファイルを読み込み、1つの結果を出す」小さなスクリプトから始めることを前提に説明します。最初から巨大な契約審査システムを作る必要はありません。小さく作り、1本通し、配布し、改善する。この順序が最も現実的です。
1定型処理から着手する理由
法務業務には、「定型パターンの抽出」だけで十分に価値が出る処理が数多くあります。たとえば、契約書マスキングツールの場合、メールアドレス・電話番号・口座番号・法人番号──これらはすべて正規表現だけで処理できます。AIを一切使わなくても、確実に検出でき、監査でも説明しやすい。
ここで「AIっぽさ」よりも「監査で説明できること」の強さを意識することが、法務ツール開発の出発点です。
2「最初の1本」に向くテーマの選び方
法務担当者が初めてツールを作るなら、以下の基準を満たすテーマを選ぶのが賢明です。入力が比較的定型であること、成果が目に見えやすいこと、誤作動時の被害が限定的であること、法務部内で価値を説明しやすいこと──この4条件です。
| 優先度 | テーマ例 | 理由 |
|---|---|---|
| まず作るべき | 契約書論点アラート、マスキング、更新期限アラート、稟議一枚化の補助 | 入力が定型。正規表現+辞書で8割処理可能。結果が明快で説明しやすい |
| 次に作るべき | 交渉論点整理、コメントテンプレ自動挿入、引継ぎサマリ生成 | 文脈依存の判断が入る。NLPやローカルLLMの導入が合理的になる段階 |
| 後回しにすべき | 高度な全文意味解析、完全自動レビュー、自動起案の全面実行 | 精度要件が高く、誤判断時のリスクが大きい。人間の介在が不可欠 |
筆者の場合も、まず契約書論点アラートツールやマスキングツールから着手し、正規表現とNLPの手応えを得てから、Legal Gatewayのような文脈依存ツールに進みました。この順序が、結果として最もスムーズでした。
第2章 ── ロジック設計
正規表現・NLP・LLM・人間──4層の役割分担
オフライン法務ツールの中核は、「全部をAIにやらせない」設計です。第2回で解説した「ルール+NLP+ローカルLLM+人間確認」の分業設計を、本章ではより具体的に掘り下げます。
1形式が決まった情報は、AIを使わない
電話番号、メールアドレス、口座番号、郵便番号、法人番号、日付、金額──これらは形式が決まっている情報です。正規表現で処理する方が、AIより高速で、高精度で、説明も容易です。
マスキングツールの開発では、まずこれらの定型パターンを正規表現で抽出し、その上にNLPを重ねる設計にしました。この順序が重要です。正規表現で8割を処理し、残りの2割だけをNLPやLLMに委ねることで、全体の精度と説明可能性を両立できます。
# メールアドレスと電話番号を先に正規表現で抽出する import re text = "連絡先は test@example.com、電話は 03-1234-5678 です。" email_pattern = r'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}' phone_pattern = r'0\d{1,4}-\d{1,4}-\d{3,4}' emails = re.findall(email_pattern, text) phones = re.findall(phone_pattern, text)
このような定型情報は、NLPやLLMに渡す前に正規表現で抜いてしまう方が、速度・精度・説明可能性のすべてで有利です。
2固有名詞・表記揺れはNLPで補完する
一方で、正規表現だけでは限界がある処理もあります。典型的なのが、人名・組織名・住所といった固有名詞の抽出です。
たとえば「株式会社ABC」「ABC株式会社」「(株)ABC」「エービーシー株式会社」──これらはすべて同一の組織を指しますが、正規表現で網羅的にマッチさせるのは現実的ではありません。ここでGiNZA等のローカルNLPライブラリを使った固有表現抽出が威力を発揮します。辞書マッチだけでは取りこぼす表記揺れを、文脈から判定できるのがNLPの強みです。
# 固有表現抽出の最小イメージ(spaCy / GiNZA系) import spacy nlp = spacy.load("ja_ginza") doc = nlp("株式会社ABCは東京都千代田区に本店を置く。代表者は山田太郎。") for ent in doc.ents: print(ent.text, ent.label_)
実務では、この結果をそのまま信用するのではなく、会社名辞書や除外語リストと組み合わせて誤検出を落としていきます。NLPは単独で使うより、辞書・ルールと重ねた方が安定します。
「正規表現 vs NLP」ではなく、補完関係
重要なのは、正規表現とNLPを対立させないことです。電話番号は正規表現が圧倒的に強い。人名はNLPが強い。両者は得意領域が異なるため、2段構えで使い分けるのが最も実務的です。正規表現で「型」を抜き、NLPで「意味」を抜く──この分業が安定した精度を生みます。
3解析前のクリーニング層──「壊れた入力」への備え
正規表現やNLPの前に、もうひとつ重要な工程があります。入力データのクリーニング(サニタイズ)です。
法務が扱う文書は、外字、機種依存文字、PDFからコピペした際の壊れた改行、全角半角の混在など、「予期せぬ入力」が日常的に紛れ込む地雷原です。これらを放置すると、正規表現が想定通りに動かず、GUIが原因不明のエラーで停止する──しかもエラーの原因が「入力データの文字コード」にあるとは気づきにくいため、デバッグに時間を奪われます。
対策として、解析処理の前に文字コードの正規化(NFKC変換等)・不要な制御文字の除去・全角半角の統一を行うクリーニング関数を1つ挟むだけで、後工程の安定性が大きく向上します。
4文脈依存の判断だけ、ローカルLLMに渡す
契約類型の判定、リスク要約の草案生成、条項間の整合性チェック──これらは条項単位ではなく文書全体の文脈を踏まえた判断が必要です。ここで初めて、ローカルLLM(量子化済み小型モデル)の出番が来ます。
ただし、ローカルLLMの出力は「草案」であって「確定」ではない点を設計に組み込むことが不可欠です。LLMが「リスク高」と判定した理由が説明できなければ、事業部への説明も上長への報告もできません(AIレビューの品質改善については「Claudeで契約書チェックしたら見落としが95%減った話」も参考になります)。
5最終判断は、常に人間が確定する
法務における判断責任は、委任できません。ツールの出力は必ず人間が確認し、承認するワークフローを前提に設計します。この「Human in the Loop」の設計は、第1回のSTEP 3(自動化の範囲と人間の役割)で定義した考え方そのものです。
処理の棚卸し表──手法の選択基準
| 処理対象 | 第一選択 | 選択理由 | 典型例 |
|---|---|---|---|
| 形式が決まっている情報 | 正規表現 | 高速・高精度・説明容易 | メール、電話番号、口座番号、法人番号 |
| 固有名詞・表記揺れ | ローカルNLP(GiNZA等) | 辞書だけでは取り切れない | 氏名、会社名、住所 |
| 文脈依存の判定 | ルール+ローカルLLM | 条項単位ではなく文脈判断が必要 | 契約類型判定、リスク要約 |
| 最終承認 | 人間確定 | 判断責任は委任不可 | 出力確認、例外判断 |
契約書・稟議書等
文字正規化・不要文字除去
定型パターン抽出
固有表現抽出
文脈判断(草案)
最終判断・承認
この分業設計は、第2回で述べた「賢い手抜き」──AIを使いすぎないことで統制と精度を両立する──をそのまま実装に落としたものです。
なお、本稿でいう「法務ツール」は、特に外部送信NGのデータを扱うオフラインAIツールを中心に想定しています。そのため、技術選定も「最も賢いモデル」ではなく「社内に閉じて安定運用できる構成」を優先しています。外部送信が許容される作業(公開情報に基づく法令調査など)については、クラウドAIの方が合理的です。データの機密区分に応じて処理環境を使い分ける設計が重要であることは、第2回で解説した通りです(生成AIの社内ルール整備については「社内ルールと生成AIの法務リスク」を参照)。
第3章 ── GUI設計
CLIで終わらせない──tkinterで「迷わない3ステップUI」を作る
Pythonでロジックを書き、コマンドラインで動作を確認する。ここまでは比較的早く到達できます。しかし、ここで止まると「自分だけが使えるツール」のままです。法務部内の他のメンバーがコマンドプロンプトを開いてPythonを実行する──この前提は、多くの法務部門では成り立ちません。
GUI化は見た目の問題ではなく、運用設計の問題です。「自分以外が使えるかどうか」が、ツールが「個人の作品」にとどまるか「部門の資産」になるかを分けます(属人化の脱却については「属人化を脱却!ChatGPTで法務レビューのワークフローを効率化する方法」も参照)。
1なぜtkinterなのか
GUIの選択肢はいくつかあります。Streamlit、Flask+Webブラウザ、tkinter──それぞれに長短があります。
| 方式 | 長所 | 短所 | 法務部向け適性 |
|---|---|---|---|
| CLI(コマンドライン) | 開発が速い | 非エンジニアに不向き | 低い |
| tkinter GUI | Python標準。配布しやすい。exe化との相性が良い | 見た目は簡素 | 高い |
| Webアプリ(Streamlit等) | 拡張性が高い。見た目が洗練 | サーバー環境が必要。権限設計が重い | 中程度 |
法務部向けの単機能ツールであれば、tkinterで十分です。Python標準ライブラリに含まれるため追加のインストールが不要であり、PyInstallerとの相性も良好です。「Streamlitの方がきれいでは?」と思うかもしれませんが、Streamlitはブラウザ経由のアクセスになるため、サーバーの立ち上げや社内ネットワークの設定が追加の障壁になります。オフラインツールの設計思想とも相容れません。
2「3ステップ」に収める画面設計
法務ツールのGUI設計で最も重要な原則は、操作を3ステップに収めることです。
入力ファイル選択
オプション確認
チェック開始・出力
tkinterであれば、この導線は驚くほど少ないコードで実現できます。
# ファイル選択→チェック開始の最小GUI import tkinter as tk from tkinter import filedialog, messagebox def select_file(): path = filedialog.askopenfilename(filetypes=[("Word files", "*.docx")]) entry.delete(0, tk.END) entry.insert(0, path) def run_check(): if not entry.get(): messagebox.showwarning("確認", "ファイルを選択してください。") return messagebox.showinfo("完了", "チェックを開始します。") root = tk.Tk() root.title("契約書チェックツール") entry = tk.Entry(root, width=50) entry.pack(padx=12, pady=8) tk.Button(root, text="ファイル選択", command=select_file).pack(pady=4) tk.Button(root, text="チェック開始", command=run_check).pack(pady=4) root.mainloop()
ここで地味ながら重要なのが、ボタン名やメッセージの言葉選びです。技術用語を法務の言葉に翻訳することで、心理的な障壁が大きく下がります。
| 技術者的な表現 | 法務向け表現 | 理由 |
|---|---|---|
| Execute | チェック開始 | 法務の業務文脈に合致 |
| Export | Wordで出力 | 出力形式を明示する方が安心感がある |
| FileNotFoundError | 選択したファイルが見つかりません。 保存先またはファイル名をご確認ください | 技術用語を出さない |
| Processing… | 処理中です(約30秒) | 待ち時間の見通しを示す |
筆者が開発したLegal Gatewayやマスキングツールでは、この「ダブルクリックで起動→ファイル選択→結果出力」の導線を徹底したことで、初回説明15分で運用開始できる状態を実現しています。
第4章 ── 配布の壁
実装で最も難しかったのはAIではなく配布だった
正直に書きます。法務ツールの開発全工程の中で、最も挫折しかけたのがこの章の内容──PyInstallerによるexe化です。
Pythonスクリプトとしては問題なく動く。tkinterのGUIも期待通りに表示される。しかし、PyInstallerでexeに固めた瞬間、一つ直すとまた別のエラーが出る──この連鎖が続きました。AIモデルの精度を上げる作業よりも、exe化のトラブルシューティングに費やした時間の方がはるかに長かった、というのが偽らざる実感です。
1なぜexe化が必要なのか
法務部門のPCには、原則としてPython環境がインストールされていません。「Pythonをインストールしてください」と言った瞬間に、社内ITのセキュリティ審査が発生し、導入ハードルは数週間単位で跳ね上がります。
exe化は「あると便利」な機能ではなく、法務ツールを社内展開するための必須条件です。ダブルクリックで起動する──この一点を実現するために、PyInstallerでの.exe生成が必要になります。
2PyInstallerで問題が「連鎖する」理由
PyInstallerは、Pythonスクリプトとその依存ライブラリを1つの実行ファイルにまとめるツールです。仕組みとしてはシンプルに見えますが、法務ツールのような「NLPモデル+設定ファイル+テンプレート+辞書」を同梱するケースでは、構造的に問題が連鎖しやすくなります。
なぜ連鎖するのか。その理由を整理します。
| 詰まりポイント | 何が起きるか | なぜ連鎖するか |
|---|---|---|
| hidden-import | spaCy/GiNZA等の動的インポートをPyInstallerが検出できず、exe起動時にModuleNotFoundErrorが発生 | 1つ直すと、そのモジュールがさらに別のモジュールを動的に呼んでおり、追加のhidden-importが必要になる |
| データファイルの同梱 | YAML設定、辞書ファイル、NLPモデル、テンプレdocx等がexeに含まれず、FileNotFoundErrorが発生 | –add-dataで同梱しても、コード側の読み込みパスがexe環境と一致しない(後述のパス問題に波及) |
| パス解決の崩壊 | 開発時は相対パスで動くが、exe化すると一時展開フォルダ(_MEIxxxxxx)にファイルが配置されるため、パスがすべて変わる | 1ファイルのパスを直しても、別のファイルのパスが同じ問題を抱えている |
| exeサイズの肥大化 | NLPモデルを含めると数百MBになり、起動時間も長くなる | 軽量化のためにモデルを分離すると、今度は「モデルファイルの配布・更新」という別の運用課題が発生 |
| ウイルス対策ソフトの誤検知 | Windows Defenderや社内セキュリティ製品がexeをブロック | 回避のためにexeの構成を変えると、それが他の同梱設定に影響する |
| 依存ライブラリの変動 | pip installで最新版を入れたら、前回のビルド構成と互換性が崩れる | バージョンを固定していないと、ビルドのたびに異なるexeが生成される |
問題の本質は、個々のエラーが独立していないことです。hidden-importの追加→データファイル同梱の見直し→パスの書き換え→テスト→新たなModuleNotFoundError──この「モグラ叩き」が、exe化を法務ツール開発最大のボトルネックにしている原因です。PyInstallerでのビルドは、何十人もの関係者が関わるM&Aのクロージングに似ています。1箇所の定義を書き換えただけで、無関係に見えた別の工程が突如として破綻する。だからこそ、依存関係という名の「契約関係」は、最初から完全に固定しておく必要があるのです。
筆者が最も苦しんだのは、「昨日ビルドしたexeは動いたのに、NLPモデルのバージョンを上げたら動かなくなった」というパターンでした。ライブラリの依存関係がバージョンアップで変わり、hidden-importの指定もデータファイルの構成も変更が必要になる。しかし、どこが変わったのかがエラーメッセージからは特定しにくい。
この経験から得た教訓は、「exe化で動くことを確認してからライブラリを更新する」のではなく、「ライブラリの構成を固定してからexe化する」という順序の重要性です。仮想環境(venv)でライブラリバージョンを完全に固定し、requirements.txtで依存構成を記録したうえで、その環境でのみexeをビルドする──この原則を守ることで、連鎖的なトラブルは大幅に減りました。「いつビルドしても同じ構成になる」ことが、再現可能なexeの前提条件です。
3設計段階で先に整理すべき4つのこと
この経験を踏まえ、設計段階──コードを書き始める前──に整理しておくべきことを4つ挙げます。
① パス解決の方針を最初から決める
exe化後のファイル読み込みでは、PyInstallerが生成する一時フォルダのパスを取得する仕組みが必要です。開発環境とexe環境でパスの取得方法を分岐させるユーティリティ関数を最初に1つ書いておくことで、後からすべてのファイル読み込み箇所を修正する羽目になる事態を防げます。
# 開発環境と exe 環境で共通に使うパス解決関数 import os import sys def resource_path(relative_path): if hasattr(sys, "_MEIPASS"): base_path = sys._MEIPASS else: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) rules_path = resource_path("config/rules.yaml") template_path = resource_path("templates/ringi.docx")
この関数を最初に用意しておけば、後から全ファイルの読み込み箇所を修正する手戻りをかなり防げます。exe化で苦しんだ経験上、これは早めに決めておくべき実装上の基本線です。
② 同梱ファイルの一覧を管理し、.specファイルを育てる
YAML設定、辞書ファイル、NLPモデル、テンプレートdocx、ライセンス表記ファイル──exe化時に同梱すべきファイルは意外に多くなります。これらをREADMEや管理シートで一覧化しておくことで、--add-data指定の漏れを防げます。.specファイル(PyInstallerのビルド設定ファイル)を早い段階から管理し、ビルド構成を再現可能にしておくことも重要です。
# PyInstaller .spec ファイルの断片例 a = Analysis( ['main.py'], datas=[ ('config/rules.yaml', 'config'), ('templates/ringi.docx', 'templates'), ('dict/company_names.csv', 'dict') ], hiddenimports=[ 'ginza', 'spacy.lang.ja' ], )
③ 「exeの差し替え」と「設定ファイルの差し替え」を分離する
更新時に「exe自体を差し替える」のか「設定ファイルだけ差し替えればよいのか」を設計段階で決めておきます。業務ルールの変更(閾値、キーワード、対象条項等)は設定ファイルの差し替えで済むように設計し、exe自体の再配布はロジックやUIの変更時のみとする──この分離が、運用の負担を大幅に下げます(詳細は第5章で解説)。
④ IT部門との「根回しエンジニアリング」
見落とされやすいのが、社内IT部門との事前調整です。大企業のPCでは、デジタル署名(Code Signing)のないexeは実行自体がブロックされる設定になっていることが珍しくありません。
対策は2つあります。1つは、exeにコード署名を付与すること。もう1つは、IT部門にexeのハッシュ値を事前に渡してホワイトリストに登録してもらうことです。いずれにせよ、exeが完成してから「実行できない」と気づくのでは遅いため、開発初期の段階でIT部門に「こういうexeを配布する予定がある」と伝えておくことが重要です。法務ならではの「根回しエンジニアリング」──技術とは無関係に見えますが、これを怠ると配布計画そのものが頓挫します。
こうした配布・運用の壁を越えて初めて、Legal Gatewayや稟議一枚化ツールは、「自分のPCで動く試作品」ではなく「他人が使える社内ツール」になりました。配布後も、社内のウイルス対策ソフトとの相性、Windows Update後の動作確認、新しいPCへの展開──運用課題は続きます。だからこそ、exe化の前に設計を固めることが、長期的な運用コストを下げる最も確実な方法です。
第5章 ── 設定外出し
法務ルールをコードから分離する──YAML/JSON設定ファイル設計
法務ツールは、法改正・社内規程変更・承認条件変更が頻発する環境で使われます。このとき、業務ルールをコードに埋め込む設計は必ず破綻します。
「損害賠償の上限条項がない場合のアラート閾値を変えたい」「禁止語リストにA社の商号を追加したい」──こうした変更のたびにPythonコードを書き換え、exeを再ビルドし、全員に再配布する運用は、現実的ではありません。
だから、業務ルールは設定ファイル(YAML/JSON)に外出しします。
1外出しすべきもの、コードに残すべきもの
| 分類 | 外出ししやすいもの(YAML/JSON) | コード側に残すべきもの |
|---|---|---|
| 定数・リスト | 禁止語、例外語、対象条項名、会社名辞書、マスキング対象語、閾値 | 読み込み・正規化・重複除去などの処理手順 |
| 判定ルール | キーワード→アラート対応表、金額閾値ごとの承認者分岐、対象類型の定義 | スコア計算、優先順位付け、複数条件の統合ロジック |
| 正規表現 | 単純な抽出パターン、差し替え前提の検索パターン | 前後文脈の判定、後処理を伴う複雑な抽出ロジック |
| テンプレート | 稟議書文面、交渉カードの定型文、コメントテンプレート | テンプレ挿入の順序や条件分岐 |
| 版管理情報 | ルールセットのバージョン番号、適用開始日、更新メモ | 版管理の仕組みそのもの |
この設計の恩恵は明確です。
| 比較軸 | コード固定 | YAML/JSON外出し |
|---|---|---|
| 閾値変更 | 開発者対応が必要 | 法務主導で変更しやすい |
| 監査説明 | ソースコード確認が必要 | 設定ファイルの差分で説明しやすい |
| 誤修正リスク | 高い(コードを触る) | 限定しやすい(設定値のみ変更) |
| 更新配布 | exe再配布が必要 | 設定ファイル差替えで済む場合あり |
2YAMLとJSONの使い分け
設定ファイルのフォーマットとしては、YAMLとJSONが一般的です。筆者の使い分けの基準はシンプルです。人間が直接編集する設定にはYAML(コメントが書ける、インデントで構造が見やすい)、プログラム間のデータ受け渡しにはJSON(パースが速い、ログ出力に向く)を使います。
法務担当者がメモ帳で書き換える可能性がある設定──禁止語リスト、閾値、対象条項名など──は、YAMLの方が事故が起きにくいです。一方、処理ログや実行結果の記録にはJSONの方が扱いやすい。このように、「誰がそのファイルを触るか」で選択するのが実務的です。
ruleset_version: "2026.03" risk_thresholds: high: 80 medium: 50 alert_keywords: - "損害賠償" - "解除" - "反社会的勢力" approval_routes: high: "法務部長承認" medium: "法務担当レビュー" low: "セルフチェックのみ"
この程度の設定であっても、コード内に埋め込まず外出ししておくことで、閾値変更やキーワード追加を「exe再配布なし」で回せる場面が増えます。
Legal Gatewayの内部統制アシュアランス機能では、リスクスコアの閾値や承認ルールをYAML設定ファイルで管理しています。このため、「なぜこの閾値なのか」「いつ変更されたのか」を設定ファイルの差分で説明できます。コードの中に閾値を埋め込んでいたら、監査時にソースコードを提示して説明する必要があり、非エンジニアの監査担当者に伝わりません。設定の外出しは、技術的な便宜ではなく、説明責任の設計です。
第6章 ── ログ・版管理
監査に耐える証跡設計──ログ・版管理・再現性
第1回 STEP 10で解説した通り、法務ツールのログは単なるデバッグ用ではありません。説明責任のための証跡です。「半年前にこの契約書をチェックした結果はどうだったか」を後から検証できることが、法務ツールに求められる水準です。
1記録すべきログ項目
法務ツールが1回の処理で記録すべき項目は、以下の通りです。
| カテゴリ | 記録項目 | 目的 |
|---|---|---|
| 実行情報 | 実行日時、実行者(PC名/ユーザー名) | 「誰が、いつ実行したか」の特定 |
| 入力情報 | 入力ファイル名、入力ファイルのハッシュ値(SHA-256等) | 入力の同一性の検証。改ざん検知 |
| ルール情報 | ルールセットのバージョン番号、適用設定ファイル名 | 「どのルールで処理したか」の再現 |
| 処理結果 | 検出件数、リスクスコア、判定結果のサマリ | 処理結果の証跡 |
| 例外情報 | エラー内容、手修正の有無、逸脱理由 | 「なぜ通常と異なる結果になったか」の説明 |
2再現性の確保──「同じ入力で同じ結果」を保証する
入力ファイルのハッシュ値とルールセットのバージョンをログに記録することで、「同じ入力に同じルールを適用すれば同じ結果が出る」ことを証明できます。これは第2回の設計原則2「再現性と検証可能性」を、実装レベルで担保する仕組みです。
クラウドAIでは、モデルのバージョンアップにより同じプロンプトでも結果が変わり得るため、この再現性を保証することが構造的に困難です。ローカルに保持したモデルファイルとルールセットのバージョンを固定できることこそ、オフラインAI設計の強みであり、法務の証跡保全に耐える根拠になります。
ログの出力形式は、機械可読性と後続処理のしやすさからJSONを基本とし、監査担当者が直接確認する場面ではCSVエクスポートも用意しておくと、運用の幅が広がります。
実装アーキテクチャの全体像
ここまでの各章の内容を、1つのアーキテクチャ図として整理します。法務ツールの実装は、以下の5層構造で考えると見通しが良くなります。
「ファイル選択→オプション確認→チェック開始」の3ステップ導線
閾値、辞書、テンプレート、ルールセットバージョンの一元管理
外字・壊れた改行・機種依存文字を解析前に処理
前段ルールベースで8割処理、AIは文脈依存のみ担当
「いつ・誰が・どのルールで・何を処理し・何が出たか」を完全記録
この5層のどこにどの技術が対応するかを意識しておくと、開発の途中で迷ったときに立ち返る指針になります。そして、この5層のすべてが社内に閉じていることが、オフラインAI設計の構造的な強みです。
私の開発順序──どの段階で何を学んだか
最後に、筆者がこれまでに開発してきたツールの順序と、各段階で得た教訓を整理します。
「外に出せないデータ」からの出発
説明可能性の重要性に気づく
設定ファイル設計の確立
「統制されたミニシステム」への進化
| 開発フェーズ | ツール | 学んだこと |
|---|---|---|
| 試作期 | マスキングツール | 正規表現で8割は処理できる。NLPは固有名詞にだけ使えば十分。クラウドAPI版は情シス審査を通らない |
| 導線設計期 | Legal Gateway | 法務が求めるのは精度ではなく説明可能性。「なぜそう判定したか」が説明できなければ使えない |
| 配布・運用期 | 稟議一枚化、論点アラート | exe化が最大のボトルネック。設定ファイルの外出しで保守コスト激減。パス解決を最初に設計すべきだった |
| 統制設計期 | 引継ぎ支援、アシュアランス機能 | 法務ツールは「AI導入」ではなく「統制可能な業務システム設計」。ログ・版管理・承認フローこそが品質を決める |
振り返ると、この進化は一直線ではなく、試行錯誤の連続でした。CLIで十分だと思ったが他の人は使えなかった。だからGUIにした。Python環境がないのでexe化した。設定変更のたびにexeを再ビルドするのが辛くなり、ルールを外出しした。モデルの賢さに時間を使いすぎて配布設計が遅れた。──この「設計→配布→運用→再設計」のサイクルを回した回数が、ツールの品質を決めたというのが実感です。
まとめ:法務ツールは「部門の資産」にするために作る
本記事を通じて伝えたかったことを整理します。
第一に、最初からAIを入れない。 定型処理は正規表現で十分に高精度であり、監査でも説明しやすい。AIは文脈依存の判断にだけ使えばよい。
第二に、GUIとexe化こそが普及のボトルネック。 CLIで動くだけでは「自分の作品」にとどまる。ダブルクリックで起動し、3ステップで完結するUI設計にして初めて「部門の資産」になる。
第三に、業務ルールはコードから分離する。 YAML/JSON設定ファイルの外出しにより、法改正や社内規程変更への対応を、開発者不在でも可能にする。
第四に、ログと版管理は「あれば嬉しい」ではなく、監査対応の前提。 入力ハッシュ、ルール版、処理結果の記録が、法務ツールの信頼性を担保する。
第五に、最も難しかったのはAIではなく配布だった。 PyInstallerによるexe化は、一つ直すとまた別のエラーが出る「連鎖」が発生しやすく、設計段階でのパス解決方針・同梱ファイル管理・依存バージョン固定・IT部門との事前調整が不可欠。
開発フェーズ別チェックリスト
これからツールを作り始める方のために、フェーズ別の優先事項を一覧にします。
| フェーズ | 優先事項 | やらなくてよいこと |
|---|---|---|
| 試作 | とにかく1件の契約書を通す。正規表現だけでよい | GUI化、exe化、AI導入 |
| 初回配布 | tkinterでGUI化。README整備。初回説明資料の作成 | 高度なUI。ローカルLLMの組み込み |
| 横展開 | PyInstallerでexe化。設定ファイルの外出し。パス解決の統一。IT部門との事前調整 | 不要機能の追加。完璧な自動化 |
| 安定運用 | ログ設計。版管理。差分運用。監査対応の仕組み化。依存バージョンの固定 | 最新AIモデルへの追従(安定性を優先) |
次のステップ
本記事の実装思想を体現したツールを、すべて無料で公開中です。いずれも完全オフライン動作・ログ保存・設定外部化を前提に設計しています。
オフライン設計と併用する──「外部送信OK」な業務はAIプロンプトで加速する
本記事で解説したオフライン設計は「外部送信NGのデータ」に対する解です。一方、法令調査や一般的なレビュー方針の検討など、外部送信が許容される業務では、クラウドAIの活用が合理的です。以下のプロンプト集は、そうした場面で法務実務を加速させるために設計されています。
自社の法務業務の中で、「正規表現だけで処理できそうな定型作業」を1つ特定してみてください。メールアドレスの検出、契約期間の抽出、特定キーワードの有無チェック──まずはそこから、最初の1本を始められます。
次回予定:「ローカルLLMを法務ツールに組み込む──CPU環境で動く量子化モデルの選定と実装」
次回は、本記事の第2章で触れた「ローカルLLM」の具体的な組み込み方をテーマに、llama-cpp-pythonの導入、量子化モデルの選定基準、CPU環境での実用的な速度感、「正規表現で条項を切り出し→ローカルLLMで要約だけ生成」というオーケストレーション設計まで整理する予定です。
🔍 関連ガイドへ進む
この記事と関連度の高い実務ガイドをまとめています。次に読むならこちら。
