case_623 士業・専門業務

取引先マスタの名寄せ・重複統合をClaude Codeで仕組み化する実装パターン

取引先マスタの名寄せ・重複統合をClaude Codeで仕組み化する実装パターン

取引先マスタの法人格表記揺れ・旧社名・支店重複の名寄せをClaude Codeで仕組み化する実装を解説。法人番号による確定照合、自動で消さず統合候補の提示までに留める設計原則、バックアップと承認フローのコード例つき。

結論:取引先マスタの名寄せ・重複統合は、担当者が目視でリストを眺めて「これとこれは同じ会社」と潰していく仕事ではなく、「表記揺れ辞書による正規化・法人番号による確定照合・類似度による候補抽出」の3段構えのパイプラインとして、Claude Codeで構築できます。設計原則はひとつ、システムは自動で消さない。統合候補の提示と根拠資料の生成までを機械の仕事にし、統合の決定は必ず人が行います。

  • 要点1:取引先の重複は「株式会社/(株)/㈱の法人格表記」「社名変更・合併で残った旧社名」「同一法人の支店・部署別レコード」の3経路で発生する。この3つは検出ロジックが異なるため、1本の類似度計算でまとめて潰そうとすると精度が出ない
  • 要点2:名寄せの確定打は文字列類似度ではなく法人番号。国税庁の法人番号公表サイトで商号・所在地が公開されており、マスタに法人番号列を持たせて突合すれば「表記は違うが同一法人」を確定的に検出できる。類似度は法人番号が埋まっていないレコードの候補出しに限定する
  • 要点3:統合の実行は「バックアップ→旧ID・新IDのマッピング保存→承認記録→反映」の順を崩さない。参照系(請求履歴・契約・与信)が旧IDにぶら下がっているため、マッピングを残さない統合は過去データの迷子を量産する

対象読者:経理・営業管理・情報システム部門とAI活用を進める開発者・PM。販売管理や会計ソフトの取引先マスタが数千件規模に膨らみ、重複や表記揺れが放置されている会社

今日やること:取引先マスタをCSVで出力し、社名から「株式会社・(株)・㈱・スペース」を取り除いた文字列でソートしてみる。隣り合う行に同じ並びが何組あるかが、自社の重複の実態です

先に断っておくと、本記事は複数の支援経験をもとに一般化した実装パターン解説です。登場する数値や工数はいずれも想定モデルケースの目安で、特定企業の実測値ではありません。効果はマスタの件数・重複の発生経路・参照している業務システムの数によって大きく変わります。

バックオフィスのAI活用支援でマスタ管理の話になると、「重複があるのは全員知っているが、誰も触れない」という空気に何度も出会います。触れないのには理由があって、取引先マスタは請求・入金・契約・与信と、社内のほぼすべての金流データの親だからです。うかつに統合して請求履歴が引けなくなった、という失敗談が一度でも社内にあると、マスタは「汚いまま凍結」されます。結果、同じ会社に取引先コードが3つあり、与信枠が二重に設定され、月次の集計では同じ相手の売上が別々の行に散らばる——数字は合っているのに、経営が見たい「取引先別」の数字だけがずっと出せない状態が続きます。

この記事では、取引先マスタの名寄せを「一度きりの大掃除」ではなく「表記揺れ辞書を育てながら回す仕組み」として実装する方法を、コードと運用の両面から解説します。月次の予実突合入金消込の差異分類月次決算の残高照合では「財務データの突合」を扱いましたが、あの3つの記事で毎回登場した名寄せ問題の震源地が、実は取引先マスタそのものです。親を直せば、子の突合はまとめて楽になります。

なぜ取引先マスタは重複するのか——3つの発生経路

重複は「入力した人が雑だったから」起きるのではありません。業務の構造上、次の3経路から必然的に発生します。経路ごとに検出方法が違うことが、この問題の面倒さの正体です。

発生経路 具体例 有効な検出方法
法人格・表記の揺れ 「株式会社サンプル商事」「(株)サンプル商事」「㈱サンプル商事」「サンプル商事(株)」、全角半角・スペース混在 正規化(法人格の除去・統一)後の完全一致
旧社名・合併の残置 社名変更後も旧社名レコードが残り、新社名で別コードが発行される。合併で消滅した会社のレコードが現存扱い 法人番号による突合、変更履歴の調査
支店・部署の別登録 「サンプル商事 大阪支店」「サンプル商事 東京本社」が別コード。請求送付先の都合で営業所ごとに増殖 正規化後の前方一致・包含判定+業務判断

やっかいなのは3つ目です。支店別レコードは「重複」に見えて、請求書の送付先や取引条件が支店ごとに違うために意図的に分けている場合があります。つまり機械的に「同一法人だから統合」とは判定できず、最後は業務の文脈を知る人の判断が要る。ここが、後述する「自動で消さない」原則の根拠になります。

設計原則——システムは自動で消さない

名寄せツールを作るとき、最初に決めるべきはアルゴリズムではなく権限の線引きです。本記事の実装では次のように分けます。

  1. 機械がやること — 正規化、法人番号の突合、類似候補の抽出、根拠資料(両レコードの取引履歴サマリー・登録日・最終取引日)の生成、統合スクリプトの実行
  2. 人がやること — 統合候補の採否の決定、どちらのコードを残すか(存続コード)の指定、支店レコードを統合するか分けたまま維持するかの業務判断

「せっかくAIを使うのに提示止まりか」と思われるかもしれませんが、取引先マスタは削除の取り消しコストが極端に高いデータです。統合ミスは請求書の宛先違い・与信管理の混乱・監査時の履歴追跡不能という形で、数か月後に発火します。逆に、候補の提示までを完全に自動化できるだけで、目視で数千件を突き合わせる作業は消えます。リスクの高い最後の1クリックだけを人に残す、というのがこの設計の考え方です。

実装の全体像——正規化・確定照合・候補抽出・統合実行の4層

パイプラインは4層に分けます。分ける理由は予実突合のときと同じで、揺らぎを吸収する場所(正規化・辞書)と、絶対に揺らいではいけない場所(統合の実行)を分離するためです。

  1. 正規化層 — 社名から法人格・空白・記号の揺れを取り除き、比較可能な「正規化社名」を作る。表記揺れ辞書もここで適用する
  2. 確定照合層 — 法人番号が埋まっているレコード同士を突合し、「表記は違うが法人番号が同じ」ペアを確定重複として抽出する
  3. 候補抽出層 — 法人番号が無いレコードについて、正規化社名の一致・類似度・住所や電話番号の一致を組み合わせて統合候補を出す。ここは確定ではなく候補で止める
  4. 統合実行層 — 人が承認した候補だけを対象に、バックアップ→旧新IDマッピング保存→統合反映を行う。承認されていないペアには一切触れない

Claude Codeの出番は、各層のコードを書かせることに加えて、「候補抽出層が出したペアのレビュー資料づくり」と「表記揺れ辞書の更新候補の提案」という運用フェーズにあります。判定そのものをLLMにやらせるのではなく、人が判定しやすい形に材料を整えるところまでを任せる、という役割分担です。

実装1:表記揺れ辞書と正規化層

正規化はPythonの決定的なコードに固定します。ポイントは、Unicode正規化(NFKC)で「㈱」のような組文字を「(株)」に展開してから、法人格パターンを除去することです。

# normalize.py — 社名の正規化(決定的処理のみ)
import re
import unicodedata

HOJINKAKU = [
    "株式会社", "有限会社", "合同会社", "合資会社", "合名会社",
    "一般社団法人", "公益社団法人", "一般財団法人", "公益財団法人",
    "医療法人", "社会福祉法人", "学校法人", "特定非営利活動法人",
]

def normalize_name(raw: str) -> str:
    s = unicodedata.normalize("NFKC", raw)   # ㈱→(株)、全角英数→半角
    s = s.replace("(株)", "株式会社").replace("(有)", "有限会社")
    s = re.sub(r"[\s ・.\.]", "", s)        # 空白・中黒・ピリオド除去
    for h in HOJINKAKU:
        s = s.replace(h, "")                  # 法人格を除去して比較用キーに
    return s.strip()

これだけで「(株)サンプル商事」「株式会社サンプル商事」「㈱ サンプル商事」は同じキー「サンプル商事」に揃います。ただし正規化コードで吸収できるのは機械的な揺れだけです。「サンプル商事」と「サンプルショウジ」、通称と正式商号、ブランド名での登録といった揺れは、会社ごとの事情なのでコードにハードコードせず、表記揺れ辞書として外部ファイルに持ちます。

# alias_dict.yaml — 表記揺れ辞書(人が編集する運用ファイル)
# canonical: マスタ上の正式表記に対応する正規化キー
# aliases:   同一先とみなす別表記(正規化後の形で書く)
- canonical: サンプル商事
  aliases:
    - サンプルショウジ
    - SAMPLESHOJI        # 海外部門が英字で登録した揺れ
  note: 2025年に社名ロゴ変更。旧ロゴ表記の登録が残存
- canonical: エグザンプル製作所
  aliases:
    - 旧テスト工業        # 2024年合併前の旧社名
  note: 合併により旧社名レコードをコードE-1042へ統合済み

辞書をYAMLにするのは、経理・営業管理の担当者がコードを触らずに育てられるようにするためです。noteに経緯を書き残す欄を必ず設けてください。名寄せの判断は「なぜ同一とみなしたか」の記録が資産になります。

実装2:法人番号による確定照合と類似候補の抽出

名寄せの精度を根本から変えるのは、類似度アルゴリズムの工夫ではなく法人番号列の整備です。法人番号は国税庁が1法人に1つ指定する13桁の番号で、国税庁法人番号公表サイトで商号・所在地とあわせて公開されており、データのダウンロードやWeb-APIでの取得にも対応しています。社名がどれだけ揺れていても、法人番号が一致すれば同一法人であることが確定します。社名変更や本店移転があっても番号は変わらないため、旧社名レコードの検出にも効きます。

したがって確定照合層はシンプルです。

# dedup_scan.py — 確定照合と候補抽出(抜粋)
import pandas as pd
from rapidfuzz import fuzz

df = pd.read_csv("torihikisaki_master.csv", dtype=str)
df["norm"] = df["社名"].map(normalize_name)

# 層2: 法人番号が同じ=確定重複(表記が違っても同一法人)
dup_hojin = (
    df.dropna(subset=["法人番号"])
      .groupby("法人番号").filter(lambda g: len(g) > 1)
)

# 層3: 法人番号なし同士は「候補」止まり
no_num = df[df["法人番号"].isna()]
candidates = []
rows = no_num.to_dict("records")
for i, a in enumerate(rows):
    for b in rows[i + 1:]:
        score = fuzz.ratio(a["norm"], b["norm"])
        same_addr = a.get("住所") and a["住所"] == b["住所"]
        if a["norm"] == b["norm"] or score >= 90 or (score >= 75 and same_addr):
            candidates.append({
                "コードA": a["コード"], "コードB": b["コード"],
                "社名A": a["社名"], "社名B": b["社名"],
                "類似度": score, "住所一致": bool(same_addr),
                "判定": "要確認",   # ここを機械が「統合」にすることはない
            })
pd.DataFrame(candidates).to_csv("merge_candidates.csv", index=False)

閾値(90と75)は初期値であって正解ではありません。最初の1回は候補を人が全件レビューし、「明らかに別会社なのに候補に挙がったペア」と「挙がるべきなのに漏れたペア」を記録して閾値と住所・電話番号の重み付けを調整します。このチューニングの反復こそClaude Codeと相性がよい作業で、レビュー結果のCSVを渡して「誤検出を減らす条件を提案して」と依頼すれば、条件分岐の修正案とテストコードまで一気に出てきます。

法人番号列がまだ無いマスタでは、公表サイトのデータと「正規化社名+所在地」で突合して法人番号の付与候補を作るところから始めます。ここでもClaude Codeへの指示は候補生成までに留めます。

> 取引先マスタ(torihikisaki_master.csv)の法人番号が空の行について、
> 法人番号公表サイトのダウンロードデータ(kokuzei_data.csv)と
> 正規化社名+都道府県で突合し、法人番号の「付与候補」CSVを作って。
> 完全一致は candidate、社名のみ一致は needs_review のフラグを付けること。
> マスタ本体は絶対に書き換えないこと。

実装3:統合の実行——バックアップ・旧新IDマッピング・承認フロー

統合候補が承認されたら、いよいよ統合ですが、実行スクリプトには順序の規律を課します。

  1. バックアップ — マスタ全体と、統合対象レコードが参照されている取引テーブルのスナップショットを日付つきで保存する
  2. 旧新IDマッピング保存 — 「消えるコード→存続コード」の対応表を追記型のファイル(merge_log.csv)に記録する。過去の請求履歴を旧コードで検索されたときに辿れるようにするため、このファイルは削除しない
  3. 承認記録 — 誰がいつどのペアを承認したかを候補CSV上のステータス変更として残す
  4. 反映 — 存続コードへ参照を付け替え、消えるコードは物理削除ではなく「統合済み」フラグで無効化する
# merge_exec.py — 統合実行(承認済みペアのみ・抜粋)
import shutil, datetime

def run_merge(approved_csv: str):
    stamp = datetime.date.today().isoformat()
    shutil.copy("torihikisaki_master.csv",
                f"backup/master_{stamp}.csv")      # 1. バックアップ
    approved = pd.read_csv(approved_csv)
    approved = approved[approved["判定"] == "統合承認"]  # 承認済み以外は触らない
    with open("merge_log.csv", "a") as f:          # 2. 旧新IDマッピング
        for _, r in approved.iterrows():
            f.write(f'{stamp},{r["消えるコード"]},{r["存続コード"]},{r["承認者"]}\n')
    # 3-4. 参照付け替えと「統合済み」フラグ化(物理削除はしない)

「物理削除ではなく無効化」は監査対応の観点でも重要です。取引実績のある相手先レコードを消してしまうと、過去の証憑と突き合わせる作業で行き止まりになります。無効化+マッピングの組み合わせなら、いつでも「このコードはいつ、誰の承認で、どこへ統合されたか」を再現できます。

運用——表記揺れ辞書を育てるループとCLAUDE.mdへの規律の焼き込み

初回の大掃除より大事なのは、翌月以降も汚れない仕組みです。運用は月次で次のループを回します。

  1. 月初にスキャン(dedup_scan.py)を実行し、新規の統合候補と「辞書に追加すべき揺れ」を抽出する
  2. 担当者が候補をレビューし、承認・保留・別会社の3択を記入する
  3. 承認分だけ統合を実行し、レビューで判明した揺れをalias_dict.yamlへ追記する

Claude Codeにレビュー資料を作らせるときのプロンプトは、判断材料の列挙に徹させます。

> merge_candidates.csv の各ペアについて、レビュー用の判断材料を
> Markdownの表にまとめて。列は「両社名の原文/正規化後/類似度/
> 住所・電話の一致状況/それぞれの登録日と最終取引日/取引件数」。
> どちらを存続コードにすべきかの推奨は「取引件数が多い方」という
> 機械的基準でのみ付記し、統合の可否そのものは判定しないこと。

旧社名の疑いがあるペアの裏取りも、調査までを任せて断定はさせません。

> コードA-0311「旧テスト工業」とコードE-1042「エグザンプル製作所」が
> 同一法人か調べたい。法人番号公表サイトの商号変更履歴の確認手順を示し、
> 確認に必要な情報(所在地・法人番号の有無)がマスタに揃っているかを
> チェックして。Web検索の結果だけで同一と断定する記述はしないこと。

そして、この運用規律はプロジェクトのCLAUDE.mdに焼き込んでおきます。セッションをまたいでも原則が守られるようにするためです(Claude Code公式ドキュメント: Manage Claude’s memory)。

# CLAUDE.md(抜粋)
## 取引先マスタ操作の停止線
- torihikisaki_master.csv を直接編集するコードは書かない・実行しない
- 統合の実行は merge_exec.py 経由のみ。判定列が「統合承認」の行以外に触れない
- レコードの物理削除は禁止。無効化フラグと merge_log.csv 記録をセットで行う
- 類似度による判定はどれだけスコアが高くても「要確認」止まり
- alias_dict.yaml への追記は必ず note(根拠)付きで提案し、人の確定を待つ

定期実行まで進める場合は、ヘッドレスモードでスキャンをスケジューラに載せ、候補が出た月だけ担当者へ通知する構成が組めます(Claude Code公式ドキュメント: Headless mode)。その場合も、自動化されるのはスキャンと資料生成までで、統合実行のトリガーは人に残します。

失敗パターンと回避策

❌ 失敗1:類似度スコアだけで自動統合してしまう
「95%以上は自動でマージ」のようなルールは、いつか必ず別会社を巻き込みます。地域の関連会社(「サンプル商事」と「サンプル商事西日本」)や、フランチャイズの店舗群は正規化後の文字列がほぼ同一です。
⭕ 回避策:自動で確定してよいのは法人番号一致のみ。文字列類似はスコアにかかわらず候補提示までとし、最終判定は取引の文脈を知る担当者が行う。

❌ 失敗2:マッピングを残さず統合し、過去の請求履歴が引けなくなる
統合そのものは成功しても、数か月後に「旧コードで記録された入金の消込を確認したい」という監査・照会が来た時点で行き止まりになります。
⭕ 回避策:merge_log.csvを追記型で永続化し、旧コードでの検索時にマッピングを辿って存続コードへ案内する参照関数を用意する。物理削除はしない。

❌ 失敗3:支店レコードを「重複」として一括統合する
同一法人番号でも、支店別に請求送付先・支払条件・担当営業が分かれているケースは統合してはいけません。統合した瞬間に請求書の宛先が壊れます。
⭕ 回避策:法人番号一致のペアも「本店・支店関係の可能性」を候補資料に明記し、業務部門の確認を経てから統合する。分けたまま維持する場合は「同一法人グループID」を別列で持たせ、集計時だけ束ねる。

❌ 失敗4:大掃除して満足し、翌月から再び汚れる
新規登録の入口が野放しだと、統合した端から重複が再生産されます。
⭕ 回避策:新規登録時に正規化キーと法人番号で既存レコードを検索し、一致があれば警告する入口チェックをセットで導入する。月次スキャンのループを止めない。

想定モデルケースの目安

効果はマスタの状態に大きく依存しますが、支援経験を一般化した想定モデルケース(取引先5,000件・重複疑い数百件規模・販売管理と会計の2システム参照)での目安を示します。いずれも保証値ではなく、設計判断の相場観としてお読みください。

項目 手作業の場合 本パターン導入後
重複候補の洗い出し 目視で数週間がかり、着手されず放置されがち スキャン実行で当日中に候補一覧が出る
統合1件あたりの作業 根拠調査・影響確認を都度手作業 根拠資料が自動生成され、人はレビューと承認に集中
統合後の履歴追跡 担当者の記憶とメール検索に依存 merge_log.csvで誰でも再現可能
初期構築 正規化+スキャンで1〜2週間、承認フロー込みの定着まで2〜3か月が目安

よくある質問

Q. 販売管理システムに名寄せ機能があるのに、外部で作る意味はありますか?

システム内蔵の名寄せは、そのシステム単体のマスタには有効です。外部パイプラインが効くのは、販売管理・会計・CRMなど複数システムに別々のマスタがあり、それらを横断して同一先を特定したい場合です。また、内蔵機能は判定ロジックや辞書が閉じていることが多く、自社の揺れ方に合わせた辞書運用や、統合前の承認フロー・ログ形式を自社標準に揃えたい場合は外部実装に分があります。

Q. 法人番号が無い相手(個人事業主・海外企業)はどう名寄せしますか?

法人番号による確定照合は使えないため、候補抽出層のみで扱います。個人事業主は屋号と代表者名、海外企業は英文社名の正規化(大文字小文字・Ltd/Inc等の統一)と国・都市の組み合わせで候補を出し、確定は必ず人が行います。確定手段が無い集団ほど「自動で消さない」原則が効きます。

Q. 名寄せにLLMの判定を直接使ってはだめですか?

「この2社は同一か」をLLMに答えさせる構成は、根拠の再現性が持てないため本記事では採りません。同じ質問に日によって違う答えが返る可能性がある処理を、監査対象のマスタ変更の根拠にはできないからです。LLM(Claude Code)の担当は、決定的なコードの生成・修正、レビュー資料の整形、辞書更新候補の提案という「再現可能な仕組みを作り、人の判断を速くする」側に置きます。

Q. 最初の大掃除はどこから手を付けるべきですか?

法人番号列の整備が最優先です。法人番号一致による確定重複は議論の余地なく統合を進められるため、成果が早く、承認フローの練習台としても適しています。文字列類似の候補レビューは判断コストが高いので、確定分を片付けてチームが手順に慣れてから着手する順番を推奨します。

Q. 導入にはどれくらいの期間がかかりますか?

想定モデルケース(5,000件規模・2システム参照)で、正規化とスキャンの構築に1〜2週間、承認フローを含めた運用定着まで2〜3か月が目安です。最大の変数はコードを書く時間ではなく、「支店を分けるか束ねるか」のような業務判断を関係部門と確定させる時間です。この判断の議事録がそのまま辞書のnote欄の初期データになります。

まとめ:今日から始める3つのアクション

  1. 今日やること:マスタをCSV出力し、法人格と空白を除いた文字列でソートして隣接重複を数える。件数が実態の下限値です
  2. 今週中:法人番号列の充足率を調べる。空欄が多いなら、法人番号公表サイトのデータとの突合による付与候補づくりを最初のClaude Codeタスクにする
  3. 今月中:統合の承認者と存続コードの決定ルールを1枚のドキュメントに定め、CLAUDE.mdに停止線として焼き込んでから、確定重複(法人番号一致)の統合を始める

取引先マスタは、予実突合入金消込残高照合という毎月の突合業務すべての親データです。親がきれいなら子の突合の名寄せ問題はまとめて軽くなる——マスタ整備は地味ですが、月次業務の自動化投資のなかで最も波及効果の大きい一手です。


著者:佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー約10万人。100社以上の企業向けAI研修・導入支援。著書『AIエージェント仕事術』(SBクリエイティブ)。

参考・出典

ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。

関連記事: 給与計算の検算をClaude Codeで仕組み化する

関連情報(2026年8月追記):名寄せ済みの取引先マスタは法令対応の判定基盤にもなります。資本金・従業員数の列を使った取適法(下請法改正)の適用対象判定は下請法改正(取適法)対応をClaude Codeで仕組み化する実装パターンを参照してください。

名寄せで精度を上げた取引先マスタを、与信限度額マスタと突合してモニタリングする実装は与信管理・与信限度額の監視をClaude Codeで仕組み化する実装パターンで扱っています。

Next Step

この事例を、自社の業務に置き換える。

対象業務、利用データ、評価基準、社内展開の順番まで整理すると、AI開発ツール導入の失敗を減らせます。

導入を相談する

チームで学ぶなら: Claude Code 法人研修(2日間ハンズオン) / 1人で習得するなら: 個別指導(週1マンツーマン)