就業規則の何条に書いてあるかをAIに聞くと、それらしい条番号と条文が返ってくる。読んで納得してしまうが、条番号だけ違っていたり、条文の数字が1つ変わっていたりする。
原文をこちらが持っているのだから、引用を突き合わせれば確かめられる。引用を原文の文字列に対して検索して、無ければ作られた文だ。実際に試したら、数字を1つ変えた40件も、語を1つ変えた40件も、全部「原文になかった」と出た。
以下の計測は、2026年9月22日にPython 3.11で行った。原文には厚生労働省のモデル就業規則(令和7年12月版)と、e-Gov法令検索から取った労働基準法の条文を使っている。
94ページの規程でも、照合そのものは一瞬で終わる
モデル就業規則の令和7年12月版は94ページあった。テキストにして空白を除くと68,914文字。労働基準法の条文のほうは63,749文字で、条に切ると132条に分かれた。
この大きさなら、いまのAIには1回で渡せる。ただし渡せることと、正しく引けることは別の話だ。渡したあとに確かめる手順が要る。
照合は文字列の検索なので、6万字でも一瞬で終わる。突き合わせる前に両方を正規化しておく。
def norm(s):
return re.sub(r"\s+", "", unicodedata.normalize("NFKC", s))
NFKCで全角の英数字とカタカナを半角にそろえ、空白と改行を全部落とす。PDFから取り出した原文は行の途中で改行が入るので、これをやらないと一致しない。
数字を1つ変えた40件が、全部引っかかった
原文から実際にある文を抜いて、細工してから照合した。40件ずつ4種類で試している。
そのまま抜いた40件は、40件とも原文で見つかった。空振りはない。
数字を1つ変えた40件は、40件とも「見つからない」と出た。「5日」を「7日」に変えたようなものだ。条文の数字は実務でそのまま使うので、ここが拾えるかどうかが一番大きい。
語を1つ変えた40件も、40件とも見つからなかった。「しなければならない」を「しなくてはならない」に変えたり、「及び」を「または」にしたりしたものだ。意味が変わる言い換えも、変わらない言い換えも、文字列としては別物になる。
全角の数字を半角に直した40件は、40件とも見つかった。正規化で吸収されるので、表記のゆれでは引っかからない。ここは引っかかってほしくない側なので、狙いどおりだ。
引用は10文字以上でないと、まぐれで当たる
短い引用は、原文になくてもたまたま一致する。どれくらい起きるかを数えた。
原文から文字列を切り出して1文字だけ別の字に替え、それが原文のどこかにあるかを3,000回ずつ試した。4文字だと1.40%が当たった。6文字で0.13%、8文字で0.10%。10文字以上では3,000回とも当たらなかった。
だから「照合できた」と言えるのは10文字からだ。配ったスクリプトは20文字未満を「短すぎる」として別に数えている。4文字の引用が100件あれば1件か2件は通ってしまう計算なので、余裕を取った。
依頼文の側でも、引用は20文字以上と決めておく。「労働条件」のような語だけを引用されると、確かめようがない。
PDFから起こした原文は、7割の行が文の途中で切れている
照合するには、原文をテキストにしておく必要がある。PDFから取り出すと、見た目の行でそのまま改行が入る。
モデル就業規則のPDFを起こしたら、79,631文字の中に改行が4,166か所、半角の空白が6,551か所あった。本文の行3,352行のうち、句点で終わらない行が2,419行。7割の行が文の途中で切れている。
この状態で「使用者は、労働時間が六時間を超える場合においては」を探しても当たらない。途中に改行が入っているからだ。だから照合の前に、両側から空白と改行を全部落とす。
import pymupdf, io
d = pymupdf.open("規程.pdf")
io.open("規程.txt", "w", encoding="utf-8").write(
"".join(p.get_text() for p in d))
Wordの規程なら、そのまま「名前を付けて保存」でテキストにできる。文字コードはUTF-8にする。Shift_JISのままだとスクリプト側で開けない。
もうひとつ、いまのスクリプトは条の枝番を区別していない。「第32条の4」は「第32条」として扱う。枝番まで見たい規程では、そこを足すことになる。うちの規程には枝番がないので、いまは直していない。
条番号だけ違う、というのがいちばん困る
条文そのものは合っているのに、条番号が違うことがある。文字列の照合だけでは通ってしまう。
原文を条ごとに切っておけば、これも出せる。引用がどの条の中にあったかを調べて、書いてある条番号と比べる。
労働基準法から8つの要点を作って試した。5つは正しい引用と条番号、1つは条文だけ入れ替えて第25条と書き、1つは原文にない文を作り、1つは4文字だけ引用した。
結果はこうなった。
原文 65,376字(空白を除くと 63,749字) / 引用 8件
条に切れた数 132条
原文にあった 5件
短すぎる(20字未満) 1件
原文になかった 1件
条番号が違う 1件
× 使用者は、労働者に対して、毎月二回以上賃金を支払わなければならない
! 第25条と書いてあるが、原文では第20条 / 使用者は、労働者を解雇しようとする…
△ 労働条件
8件とも狙いどおりに分かれた。条番号の取り違えは、文字列の照合だけなら通っていた1件だ。
条文を引いて社内に回すときは、番号のほうが先に一人歩きする。「第25条にこう書いてある」と言われた人は、条文まで読み返さない。ここを機械で見ておく価値はある。
目次があると、条ごとの切り出しがずれる
条ごとに切るのは、行の先頭にある「第N条」で切るだけだ。文の途中に出てくる「第N条」は他の条への参照なので拾わない。
ところが目次にも行の先頭に「第1条(目的)……1」のような行が並ぶ。そのまま切ると、目次の1行が第1条の本文ということになってしまう。同じ条番号が2回以上出てきたら長いほうを本文とみなす、という決め方でここを外した。
もうひとつ、解説が混ざった文書ではうまくいかなかった。モデル就業規則のPDFは規定例と解説が交互に並んでいて、解説の中に「第32条の4」のような参照が何度も出てくる。この形では、条ごとの切り出しは当てにならない。会社の就業規則そのもののように、条文だけが並んだテキストなら効く。
条番号の照合を使うなら、原文から解説を外しておく。外せないなら、文字列の照合だけにして、条番号は人が見る。
依頼文で決めておくこと
引用が返ってこないと照合のしようがない。依頼文でここを固定する。
次の規程から、○○について定めた条を探してください。
・条番号と、その条の本文を原文のまま「」で囲んで引用してください
・引用は20文字以上にしてください
・見つからなければ「該当する条はない」とだけ書いてください
・要約や言い換えは引用の外に書いてください
・原文にない語を引用の中に足さないでください
「見つからなければ、ないと書く」を入れておくのが効く。入れないと、近い条を持ってきて答えの形に整えてくる。
引用を「」で囲ませるのは、あとで機械的に拾うためだ。配ったスクリプトは「」の中だけを引用として拾い、直前に出てくる条番号とセットで扱う。
python quote-check.py 規程.txt 要点.md --article
戻り値は、作られた文か条番号の取り違えがあれば1になる。手順の中に組み込むなら、ここで止める。
確かめていないこと
この記事で測ったのは照合の側だけだ。AIがどれくらいの割合で条文を作るか、規程が長くなると誤りが増えるかは測っていない。自分で自分に問いを出して採点する形になってしまい、試験にならないからだ。
代わりに、作られたときに必ず拾えるかを測った。そちらは数字を1つ変えても語を1つ変えても全部拾えたので、引用さえ付けさせれば通らない。手書きをAIに読ませたあとの検算やPDFの表を起こすときの確かめ方と同じで、出てきたものを信じるのではなく、機械で突き合わせる側に手をかける。
規程を要約させるときも同じで、要点の1つずつに原文の引用を付けさせる。長い資料の要点を出させる話でも書いたが、引用のない要点は確かめられないので、あとで使えない。



