リーガルテック

法務ツールの実装入門──Python・tkinter・exe化で「現場に配れるツール」を作る

無料ツール 6本まとめ
⚖️
法務向け無料デスクトップツール一覧
契約依頼の一次整理マスキング論点アラート
運用引継ぎメモ稟議一枚化レビュー受付台帳を 完全オフラインで支援。用途別に"最短で選べます"。
✓ 一次整理 ✓ マスキング ✓ 論点アラート ✓ 運用引継ぎ ✓ 稟議一枚化 ✓ 法務依頼受付台帳
+ 無料ツール一覧を見る
✓ インストール不要 ✓ 完全オフライン対応 ✓ すべて無料
法務ツールの実装入門──Python・tkinter・exe化で「現場に配れるツール」を作る|Legal GPT
リーガルエンジニアリング連載 ── 第3回

法務ツールの実装入門
──Python・tkinter・exe化で
「現場に配れるツール」を作る

法務ツール開発で最も難しかったのは、AIモデルの選定ではなかった。
「自分のPCで動く」を「他人に配れる」に変える──その実装の全過程を公開する。

Legal GPT ─ legal-gpt.com カテゴリ:リーガルエンジニアリング

前回の第2回「オフラインAIで作る理由」では、法務がクラウドAIを「選べない」場面が構造的に多いこと、そしてオフラインAIを戦略的に選択する3つの設計原則──データ主権の完全保持、再現性と検証可能性、自社ルールへの完全適合──を解説しました。

第3回となる本稿のテーマは、その設計思想をどう実装に落とすかです。

率直に言います。法務ツールの開発で最も時間を費やし、最も挫折しかけたのは、AIモデルの選定でも、正規表現の設計でもありませんでした。「自分のPCで動くツール」を「他人のPCでも動くexe」にする工程──つまり配布の壁──が、全工程の中で最大のボトルネックでした。

法務ツール開発で難しいのは、AIを呼ぶことではない。現場で使えるUIにし、配布できる形にし、更新・説明・監査に耐える構造にすることである。

本記事は、第1回「要件定義10STEP」のSTEP 4(中核ロジックの選定)・STEP 5(誤検出対応)・STEP 8(設定・辞書の外出し)を掘り下げ、筆者が契約書マスキングツールLegal Gateway稟議一枚化ツール等の開発で得た知見を、非エンジニアの法務担当者が追体験できる粒度で整理します。

本記事の構成は以下の通りです。

第1章
開発順序
「最初からAIを入れない」──法務ツールはどこから作り始めるべきか
第2章
ロジック設計
正規表現・NLP・LLM・人間──処理の性質に応じた4層の役割分担
第3章
GUI設計
CLIで終わらせない──tkinterで「迷わない3ステップUI」を作る
第4章
配布の壁
PyInstallerでexe化する際に「本当に詰まる」ポイントと設計段階での備え
第5章
設定外出し
法務ルールをコードから分離する──YAML/JSON設定ファイル設計
第6章
ログ・版管理
処理ログ・ルール版・入力ハッシュ──監査に耐える証跡設計

法務ツールはどこから作り始めるべきか

法務担当者がツールを自作する際、最大の落とし穴は「最初からAIを入れようとすること」です。

生成AIの話題が先行するあまり、「まずLLMを使った契約書レビューを作ろう」と考えがちですが、これは順序が逆です。最初のバージョンでは、100点の自動化を目指す必要はありません。むしろ、精度より先に、再現性・説明可能性・改修容易性を優先すべきです。

本稿では、Python経験が浅い法務担当者でも、まずは「1つのWordファイルを読み込み、1つの結果を出す」小さなスクリプトから始めることを前提に説明します。最初から巨大な契約審査システムを作る必要はありません。小さく作り、1本通し、配布し、改善する。この順序が最も現実的です。

1定型処理から着手する理由

法務業務には、「定型パターンの抽出」だけで十分に価値が出る処理が数多くあります。たとえば、契約書マスキングツールの場合、メールアドレス・電話番号・口座番号・法人番号──これらはすべて正規表現だけで処理できます。AIを一切使わなくても、確実に検出でき、監査でも説明しやすい。

ここで「AIっぽさ」よりも「監査で説明できること」の強さを意識することが、法務ツール開発の出発点です。

2「最初の1本」に向くテーマの選び方

法務担当者が初めてツールを作るなら、以下の基準を満たすテーマを選ぶのが賢明です。入力が比較的定型であること、成果が目に見えやすいこと、誤作動時の被害が限定的であること、法務部内で価値を説明しやすいこと──この4条件です。

優先度テーマ例理由
まず作るべき契約書論点アラート、マスキング、更新期限アラート、稟議一枚化の補助入力が定型。正規表現+辞書で8割処理可能。結果が明快で説明しやすい
次に作るべき交渉論点整理、コメントテンプレ自動挿入、引継ぎサマリ生成文脈依存の判断が入る。NLPやローカルLLMの導入が合理的になる段階
後回しにすべき高度な全文意味解析、完全自動レビュー、自動起案の全面実行精度要件が高く、誤判断時のリスクが大きい。人間の介在が不可欠

筆者の場合も、まず契約書論点アラートツールマスキングツールから着手し、正規表現とNLPの手応えを得てから、Legal Gatewayのような文脈依存ツールに進みました。この順序が、結果として最もスムーズでした。


正規表現・NLP・LLM・人間──4層の役割分担

オフライン法務ツールの中核は、「全部をAIにやらせない」設計です。第2回で解説した「ルール+NLP+ローカルLLM+人間確認」の分業設計を、本章ではより具体的に掘り下げます。

1形式が決まった情報は、AIを使わない

電話番号、メールアドレス、口座番号、郵便番号、法人番号、日付、金額──これらは形式が決まっている情報です。正規表現で処理する方が、AIより高速で、高精度で、説明も容易です。

マスキングツールの開発では、まずこれらの定型パターンを正規表現で抽出し、その上にNLPを重ねる設計にしました。この順序が重要です。正規表現で8割を処理し、残りの2割だけをNLPやLLMに委ねることで、全体の精度と説明可能性を両立できます。

Python
# メールアドレスと電話番号を先に正規表現で抽出する
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の強みです。

Python
# 固有表現抽出の最小イメージ(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条項単位ではなく文脈判断が必要契約類型判定、リスク要約
最終承認人間確定判断責任は委任不可出力確認、例外判断
📋 入力文書
契約書・稟議書等
🧹 クリーニング
文字正規化・不要文字除去
🔤 正規表現
定型パターン抽出
🧠 NLP
固有表現抽出
🤖 ローカルLLM
文脈判断(草案)
👤 人間確認
最終判断・承認
図:処理フロー ── クリーニング後、前段のルールベースで8割を処理し、AIには文脈判断だけを担当させる

この分業設計は、第2回で述べた「賢い手抜き」──AIを使いすぎないことで統制と精度を両立する──をそのまま実装に落としたものです。

なお、本稿でいう「法務ツール」は、特に外部送信NGのデータを扱うオフラインAIツールを中心に想定しています。そのため、技術選定も「最も賢いモデル」ではなく「社内に閉じて安定運用できる構成」を優先しています。外部送信が許容される作業(公開情報に基づく法令調査など)については、クラウドAIの方が合理的です。データの機密区分に応じて処理環境を使い分ける設計が重要であることは、第2回で解説した通りです(生成AIの社内ルール整備については「社内ルールと生成AIの法務リスク」を参照)。


CLIで終わらせない──tkinterで「迷わない3ステップUI」を作る

Pythonでロジックを書き、コマンドラインで動作を確認する。ここまでは比較的早く到達できます。しかし、ここで止まると「自分だけが使えるツール」のままです。法務部内の他のメンバーがコマンドプロンプトを開いてPythonを実行する──この前提は、多くの法務部門では成り立ちません。

GUI化は見た目の問題ではなく、運用設計の問題です。「自分以外が使えるかどうか」が、ツールが「個人の作品」にとどまるか「部門の資産」になるかを分けます(属人化の脱却については「属人化を脱却!ChatGPTで法務レビューのワークフローを効率化する方法」も参照)。

1なぜtkinterなのか

GUIの選択肢はいくつかあります。Streamlit、Flask+Webブラウザ、tkinter──それぞれに長短があります。

方式長所短所法務部向け適性
CLI(コマンドライン)開発が速い非エンジニアに不向き低い
tkinter GUIPython標準。配布しやすい。exe化との相性が良い見た目は簡素高い
Webアプリ(Streamlit等)拡張性が高い。見た目が洗練サーバー環境が必要。権限設計が重い中程度

法務部向けの単機能ツールであれば、tkinterで十分です。Python標準ライブラリに含まれるため追加のインストールが不要であり、PyInstallerとの相性も良好です。「Streamlitの方がきれいでは?」と思うかもしれませんが、Streamlitはブラウザ経由のアクセスになるため、サーバーの立ち上げや社内ネットワークの設定が追加の障壁になります。オフラインツールの設計思想とも相容れません。

2「3ステップ」に収める画面設計

法務ツールのGUI設計で最も重要な原則は、操作を3ステップに収めることです。

📂 STEP 1
入力ファイル選択
⚙ STEP 2
オプション確認
💾 STEP 3
チェック開始・出力
図:法務ツールGUIの基本導線 ── ダブルクリックで起動、3ステップで完結

tkinterであれば、この導線は驚くほど少ないコードで実現できます。

Python
# ファイル選択→チェック開始の最小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チェック開始法務の業務文脈に合致
ExportWordで出力出力形式を明示する方が安心感がある
FileNotFoundError選択したファイルが見つかりません。
保存先またはファイル名をご確認ください
技術用語を出さない
Processing…処理中です(約30秒)待ち時間の見通しを示す

筆者が開発したLegal Gatewayやマスキングツールでは、この「ダブルクリックで起動→ファイル選択→結果出力」の導線を徹底したことで、初回説明15分で運用開始できる状態を実現しています。


実装で最も難しかったのは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-importspaCy/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がまた動かなくなる」無限ループ

筆者が最も苦しんだのは、「昨日ビルドしたexeは動いたのに、NLPモデルのバージョンを上げたら動かなくなった」というパターンでした。ライブラリの依存関係がバージョンアップで変わり、hidden-importの指定もデータファイルの構成も変更が必要になる。しかし、どこが変わったのかがエラーメッセージからは特定しにくい。

この経験から得た教訓は、「exe化で動くことを確認してからライブラリを更新する」のではなく、「ライブラリの構成を固定してからexe化する」という順序の重要性です。仮想環境(venv)でライブラリバージョンを完全に固定し、requirements.txtで依存構成を記録したうえで、その環境でのみexeをビルドする──この原則を守ることで、連鎖的なトラブルは大幅に減りました。「いつビルドしても同じ構成になる」ことが、再現可能なexeの前提条件です。

3設計段階で先に整理すべき4つのこと

この経験を踏まえ、設計段階──コードを書き始める前──に整理しておくべきことを4つ挙げます。

① パス解決の方針を最初から決める

exe化後のファイル読み込みでは、PyInstallerが生成する一時フォルダのパスを取得する仕組みが必要です。開発環境とexe環境でパスの取得方法を分岐させるユーティリティ関数を最初に1つ書いておくことで、後からすべてのファイル読み込み箇所を修正する羽目になる事態を防げます。

Python
# 開発環境と 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のビルド設定ファイル)を早い段階から管理し、ビルド構成を再現可能にしておくことも重要です。

Spec
# 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を配布する予定がある」と伝えておくことが重要です。法務ならではの「根回しエンジニアリング」──技術とは無関係に見えますが、これを怠ると配布計画そのものが頓挫します。

exe化は「動けば終わり」ではない。他人のPCで再現できて初めて完了である。

こうした配布・運用の壁を越えて初めて、Legal Gateway稟議一枚化ツールは、「自分のPCで動く試作品」ではなく「他人が使える社内ツール」になりました。配布後も、社内のウイルス対策ソフトとの相性、Windows Update後の動作確認、新しいPCへの展開──運用課題は続きます。だからこそ、exe化の前に設計を固めることが、長期的な運用コストを下げる最も確実な方法です。


法務ルールをコードから分離する──YAML/JSON設定ファイル設計

法務ツールは、法改正・社内規程変更・承認条件変更が頻発する環境で使われます。このとき、業務ルールをコードに埋め込む設計は必ず破綻します

「損害賠償の上限条項がない場合のアラート閾値を変えたい」「禁止語リストにA社の商号を追加したい」──こうした変更のたびにPythonコードを書き換え、exeを再ビルドし、全員に再配布する運用は、現実的ではありません。

だから、業務ルールは設定ファイル(YAML/JSON)に外出しします。

1外出しすべきもの、コードに残すべきもの

分類外出ししやすいもの(YAML/JSON)コード側に残すべきもの
定数・リスト禁止語、例外語、対象条項名、会社名辞書、マスキング対象語、閾値読み込み・正規化・重複除去などの処理手順
判定ルールキーワード→アラート対応表、金額閾値ごとの承認者分岐、対象類型の定義スコア計算、優先順位付け、複数条件の統合ロジック
正規表現単純な抽出パターン、差し替え前提の検索パターン前後文脈の判定、後処理を伴う複雑な抽出ロジック
テンプレート稟議書文面、交渉カードの定型文、コメントテンプレートテンプレ挿入の順序や条件分岐
版管理情報ルールセットのバージョン番号、適用開始日、更新メモ版管理の仕組みそのもの

この設計の恩恵は明確です。

比較軸コード固定YAML/JSON外出し
閾値変更開発者対応が必要法務主導で変更しやすい
監査説明ソースコード確認が必要設定ファイルの差分で説明しやすい
誤修正リスク高い(コードを触る)限定しやすい(設定値のみ変更)
更新配布exe再配布が必要設定ファイル差替えで済む場合あり

2YAMLとJSONの使い分け

設定ファイルのフォーマットとしては、YAMLとJSONが一般的です。筆者の使い分けの基準はシンプルです。人間が直接編集する設定にはYAML(コメントが書ける、インデントで構造が見やすい)、プログラム間のデータ受け渡しにはJSON(パースが速い、ログ出力に向く)を使います。

法務担当者がメモ帳で書き換える可能性がある設定──禁止語リスト、閾値、対象条項名など──は、YAMLの方が事故が起きにくいです。一方、処理ログや実行結果の記録にはJSONの方が扱いやすい。このように、「誰がそのファイルを触るか」で選択するのが実務的です。

YAML
ruleset_version: "2026.03"

risk_thresholds:
  high: 80
  medium: 50

alert_keywords:
  - "損害賠償"
  - "解除"
  - "反社会的勢力"

approval_routes:
  high: "法務部長承認"
  medium: "法務担当レビュー"
  low: "セルフチェックのみ"

この程度の設定であっても、コード内に埋め込まず外出ししておくことで、閾値変更やキーワード追加を「exe再配布なし」で回せる場面が増えます。

設定外出しが「監査対応」になった実例

Legal Gatewayの内部統制アシュアランス機能では、リスクスコアの閾値や承認ルールをYAML設定ファイルで管理しています。このため、「なぜこの閾値なのか」「いつ変更されたのか」を設定ファイルの差分で説明できます。コードの中に閾値を埋め込んでいたら、監査時にソースコードを提示して説明する必要があり、非エンジニアの監査担当者に伝わりません。設定の外出しは、技術的な便宜ではなく、説明責任の設計です。


監査に耐える証跡設計──ログ・版管理・再現性

第1回 STEP 10で解説した通り、法務ツールのログは単なるデバッグ用ではありません。説明責任のための証跡です。「半年前にこの契約書をチェックした結果はどうだったか」を後から検証できることが、法務ツールに求められる水準です。

1記録すべきログ項目

法務ツールが1回の処理で記録すべき項目は、以下の通りです。

カテゴリ記録項目目的
実行情報実行日時、実行者(PC名/ユーザー名)「誰が、いつ実行したか」の特定
入力情報入力ファイル名、入力ファイルのハッシュ値(SHA-256等)入力の同一性の検証。改ざん検知
ルール情報ルールセットのバージョン番号、適用設定ファイル名「どのルールで処理したか」の再現
処理結果検出件数、リスクスコア、判定結果のサマリ処理結果の証跡
例外情報エラー内容、手修正の有無、逸脱理由「なぜ通常と異なる結果になったか」の説明

2再現性の確保──「同じ入力で同じ結果」を保証する

入力ファイルのハッシュ値とルールセットのバージョンをログに記録することで、「同じ入力に同じルールを適用すれば同じ結果が出る」ことを証明できます。これは第2回の設計原則2「再現性と検証可能性」を、実装レベルで担保する仕組みです。

クラウドAIでは、モデルのバージョンアップにより同じプロンプトでも結果が変わり得るため、この再現性を保証することが構造的に困難です。ローカルに保持したモデルファイルとルールセットのバージョンを固定できることこそ、オフラインAI設計の強みであり、法務の証跡保全に耐える根拠になります。

ログの出力形式は、機械可読性と後続処理のしやすさからJSONを基本とし、監査担当者が直接確認する場面ではCSVエクスポートも用意しておくと、運用の幅が広がります。


実装アーキテクチャの全体像

ここまでの各章の内容を、1つのアーキテクチャ図として整理します。法務ツールの実装は、以下の5層構造で考えると見通しが良くなります。

Interfaceユーザーとの接点
tkinter GUI → PyInstallerでexe化 → ダブルクリック起動
「ファイル選択→オプション確認→チェック開始」の3ステップ導線
Controller設定と交通整理
YAML/JSON設定ファイル → 業務ルールの外出し → 版管理
閾値、辞書、テンプレート、ルールセットバージョンの一元管理
Sanitizer入力クリーニング
文字正規化(NFKC)+ 制御文字除去 + 全角半角統一
外字・壊れた改行・機種依存文字を解析前に処理
Engineテキスト解析・加工
正規表現(定型パターン)+ NLP(固有表現)+ ローカルLLM(文脈判断)
前段ルールベースで8割処理、AIは文脈依存のみ担当
Evidence証跡と再現性
処理ログ(JSON)+ 入力ハッシュ + ルール版 + 差分記録
「いつ・誰が・どのルールで・何を処理し・何が出たか」を完全記録

この5層のどこにどの技術が対応するかを意識しておくと、開発の途中で迷ったときに立ち返る指針になります。そして、この5層のすべてが社内に閉じていることが、オフラインAI設計の構造的な強みです。


私の開発順序──どの段階で何を学んだか

最後に、筆者がこれまでに開発してきたツールの順序と、各段階で得た教訓を整理します。

PHASE 1
マスキングツール
正規表現+NLPの分業。
「外に出せないデータ」からの出発
PHASE 2
Legal Gateway
業務導線全体の支援。
説明可能性の重要性に気づく
PHASE 3
稟議一枚化ツール
テンプレートの外出し。
設定ファイル設計の確立
PHASE 4
論点アラート・引継ぎ支援
ログ・版管理・統制設計。
「統制されたミニシステム」への進化
開発フェーズツール学んだこと
試作期マスキングツール正規表現で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部門との事前調整が不可欠。

法務担当者が最初に学ぶべきなのは、AIモデルの比較ではない。「どの処理をルールで固定し、どこだけをNLPやLLMに任せ、どう配布し、どう更新し、どう説明可能にするか」という設計である。そこまで作れて初めて、ツールは”個人の作品”ではなく”部門の資産”になる。


開発フェーズ別チェックリスト

これからツールを作り始める方のために、フェーズ別の優先事項を一覧にします。

フェーズ優先事項やらなくてよいこと
試作とにかく1件の契約書を通す。正規表現だけでよいGUI化、exe化、AI導入
初回配布tkinterでGUI化。README整備。初回説明資料の作成高度なUI。ローカルLLMの組み込み
横展開PyInstallerでexe化。設定ファイルの外出し。パス解決の統一。IT部門との事前調整不要機能の追加。完璧な自動化
安定運用ログ設計。版管理。差分運用。監査対応の仕組み化。依存バージョンの固定最新AIモデルへの追従(安定性を優先)

次のステップ

本記事の実装思想を体現したツールを、すべて無料で公開中です。いずれも完全オフライン動作・ログ保存・設定外部化を前提に設計しています。

有料プロンプト集

オフライン設計と併用する──「外部送信OK」な業務はAIプロンプトで加速する

本記事で解説したオフライン設計は「外部送信NGのデータ」に対する解です。一方、法令調査や一般的なレビュー方針の検討など、外部送信が許容される業務では、クラウドAIの活用が合理的です。以下のプロンプト集は、そうした場面で法務実務を加速させるために設計されています。

📝 今日やること(1つだけ)

自社の法務業務の中で、「正規表現だけで処理できそうな定型作業」を1つ特定してみてください。メールアドレスの検出、契約期間の抽出、特定キーワードの有無チェック──まずはそこから、最初の1本を始められます。

次回予定:「ローカルLLMを法務ツールに組み込む──CPU環境で動く量子化モデルの選定と実装」

次回は、本記事の第2章で触れた「ローカルLLM」の具体的な組み込み方をテーマに、llama-cpp-pythonの導入、量子化モデルの選定基準、CPU環境での実用的な速度感、「正規表現で条項を切り出し→ローカルLLMで要約だけ生成」というオーケストレーション設計まで整理する予定です。


COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA