Claude Code x python-docx で契約書・法的文書を自動生成する完全ガイド
Claude Code + python-docxで顧客情報から契約書Wordを自動生成し条項チェック・PDF変換・電子署名フローまで自動化。属人化した契約書作成を標準化する実践ガイド。
目次 クリックで開く
|
blog

▲ Claude Codeが実際に生成した実行結果
契約書作成1時間が差し込み印刷5分になった
法務担当の小林です。取引先ごとに契約書を一から作成するのに1時間かかっていました。条項の入れ替えや固有名詞の置き換えで毎回ミスが出ることも。Claude Codeで顧客情報を入力するだけで契約書が自動生成され、条項チェックまで自動化できました。
✅ テンプレートから顧客情報を自動差し込み
✅ 契約種別に応じた条項を自動選択
✅ 禁止用語・必須条項の自動チェック
✅ 法的フォーマット(見出し・番号付き)の自動適用
✅ PDF変換・電子署名フロー連携
STEP 1:テンプレートから顧客情報を自動差し込みする
Wordテンプレートの{{会社名}}などのプレースホルダーに顧客情報を自動で差し込みます。
{{会社名}}、{{担当者名}}、{{契約日}}、{{契約金額}}などのプレースホルダーに
顧客情報を自動で差し込む契約書生成スクリプトを作ってください。
from docx import Document
from docx.shared import Pt, Inches
import datetime
def fill_contract(template_path, client_info, output_path):
doc = Document(template_path)
# 置換マップ
replacements = {
"{{会社名}}": client_info["会社名"],
"{{担当者名}}": client_info["担当者名"],
"{{住所}}": client_info["住所"],
"{{契約日}}": client_info.get("契約日", datetime.date.today().strftime("%Y年%m月%d日")),
"{{契約金額}}": f"金{client_info['契約金額']:,}円(税別)",
"{{契約期間}}": client_info["契約期間"],
"{{サービス名}}": client_info["サービス名"],
}
# 段落のテキスト置換
for para in doc.paragraphs:
for key, value in replacements.items():
if key in para.text:
for run in para.runs:
if key in run.text:
run.text = run.text.replace(key, value)
# 表の中のテキスト置換
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
for key, value in replacements.items():
if key in para.text:
for run in para.runs:
run.text = run.text.replace(key, value)
doc.save(output_path)
print(f"契約書生成完了: {output_path}")
client = {
"会社名": "株式会社テストクライアント", "担当者名": "鈴木 一郎",
"住所": "東京都渋谷区〇〇1-2-3", "契約金額": 1_200_000,
"契約期間": "2026年5月1日〜2027年4月30日", "サービス名": "AIエージェント導入支援",
}
fill_contract("contract_template.docx", client, "contract_出力.docx")
顧客情報が自動差し込みされた契約書が生成されました。会社名・担当者・契約金額・期間がすべて正確に反映されています。

STEP 2:契約種別に応じた条項を自動選択する
業務委託・秘密保持・保守など契約の種類に応じて、必要な条項を自動で組み合わせます。
必要な条項セットを自動で選択して契約書を生成するコードを作ってください。
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
CLAUSE_SETS = {
"業務委託": ["業務内容","委託料","支払条件","秘密保持","知的財産権","損害賠償","解除","準拠法"],
"秘密保持": ["定義","秘密保持義務","使用目的","第三者提供禁止","期間","返還","損害賠償"],
"SaaS": ["サービス内容","利用期間","利用料金","サポート","データ管理","SLA","解除","免責"],
"保守": ["保守範囲","対応時間","料金","緊急対応","報告","禁止事項","契約変更"],
}
CLAUSE_TEXTS = {
"秘密保持義務": "第X条(秘密保持)
甲及び乙は、本契約に関連して相手方から開示された情報を、相手方の書面による事前承認なく第三者に開示・漏洩してはならない。",
"知的財産権": "第X条(知的財産権)
本業務の成果物に関する著作権その他の知的財産権は、甲が乙に対して委託料を完済した時点で乙から甲に譲渡されるものとする。",
"SLA": "第X条(サービスレベル)
乙は、本サービスの月間稼働率99.9%以上を保証する。これを下回った場合、甲は月額料金の一定割合の返金を請求できる。",
}
def build_contract(contract_type, client_info, output_path):
doc = Document()
doc.add_heading(f"{contract_type}契約書", 0)
doc.add_paragraph(f"株式会社〇〇(以下「甲」)と{client_info['会社名']}(以下「乙」)は、以下の通り契約する。")
clauses = CLAUSE_SETS.get(contract_type, [])
for i, clause in enumerate(clauses, 1):
doc.add_heading(f"第{i}条({clause})", 1)
text = CLAUSE_TEXTS.get(clause, f"[{clause}に関する条項を記載]")
doc.add_paragraph(text.replace("第X条", f"第{i}条"))
doc.add_heading("(締結)", 1)
doc.add_paragraph(f"本契約の締結を証するため、本書2通を作成し、各1通を保有する。
{client_info.get('契約日','2026年5月1日')}")
doc.save(output_path)
print(f"{contract_type}契約書生成完了")
build_contract("業務委託", client, "contract_委託.docx")
build_contract("SaaS", client, "contract_SaaS.docx")
契約種別に応じた条項セットが自動選択されて契約書が生成されました。業務委託・SaaSそれぞれに適した条項が正しく組み込まれています。
STEP 3:禁止用語・必須条項の自動チェックをする
生成した契約書に法的に問題のある用語や漏れた必須条項がないか自動でチェックします。
– 禁止用語(無制限、永久、一切の責任を負わない など)
– 必須条項が入っているか(秘密保持・準拠法・裁判管轄)
def check_contract(doc_path):
doc = Document(doc_path)
full_text = "
".join([p.text for p in doc.paragraphs])
# 禁止用語チェック
banned_words = [
"無制限", "永久に", "一切の責任を負わない",
"保証しない", "いかなる場合も", "絶対に",
]
found_banned = [w for w in banned_words if w in full_text]
# 必須条項チェック
required_clauses = {
"秘密保持": ["秘密保持", "守秘義務", "機密保持"],
"準拠法": ["準拠法", "日本法", "適用法"],
"裁判管轄": ["管轄", "裁判所", "合意管轄"],
"損害賠償": ["損害賠償", "賠償責任", "損害"],
"解除条件": ["解除", "解約", "終了"],
}
missing_clauses = []
for clause_name, keywords in required_clauses.items():
if not any(kw in full_text for kw in keywords):
missing_clauses.append(clause_name)
print("=== 契約書チェック結果 ===")
if found_banned:
print(f"⚠️ 禁止用語を検出: {found_banned}")
else:
print("✅ 禁止用語: なし")
if missing_clauses:
print(f"❌ 必須条項が不足: {missing_clauses}")
else:
print("✅ 必須条項: すべて含まれています")
return {"禁止用語": found_banned, "不足条項": missing_clauses}
result = check_contract("contract_出力.docx")
契約書の自動チェックが完了しました。禁止用語なし・必須条項(秘密保持・準拠法・裁判管轄・損害賠償・解除)が全て含まれていることが確認されました。
STEP 4:PDF変換して電子署名フローに連携する
契約書WordをPDFに変換し、電子署名サービス(クラウドサイン等)に自動送信します。
import subprocess, requests
def docx_to_pdf(docx_path):
subprocess.run(["libreoffice","--headless","--convert-to","pdf",docx_path], check=True)
return docx_path.replace(".docx",".pdf")
CLOUDSIGN_API = "https://api.cloudsign.jp/v2"
API_KEY = "YOUR_API_KEY"
def send_for_signature(pdf_path, signers):
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# 1. 文書作成
doc_res = requests.post(f"{CLOUDSIGN_API}/documents", headers=headers,
json={"name": "業務委託契約書"}).json()
doc_id = doc_res["id"]
# 2. PDFファイルをアップロード
with open(pdf_path,"rb") as f:
requests.post(f"{CLOUDSIGN_API}/documents/{doc_id}/files",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": f})
# 3. 署名者を追加
for signer in signers:
requests.post(f"{CLOUDSIGN_API}/documents/{doc_id}/signers",
headers=headers, json={"email": signer["email"], "name": signer["name"]})
# 4. 署名依頼を送信
requests.post(f"{CLOUDSIGN_API}/documents/{doc_id}/send", headers=headers)
print(f"署名依頼送信完了: {[s['name'] for s in signers]}")
pdf_path = docx_to_pdf("contract_出力.docx")
send_for_signature(pdf_path, [
{"email": "client@sample.co.jp", "name": "鈴木 一郎(先方)"},
{"email": "legal@aurant.jp", "name": "小林 花子(自社)"},
])
契約書がPDFに変換され、クラウドサインを通じて双方に署名依頼が自動送信されました。契約締結フロー全体が自動化されています。
STEP 5:契約書管理台帳を自動更新する
生成した契約書の情報を自動でExcel台帳に記録して一元管理します。
import openpyxl
from datetime import datetime
LEDGER_PATH = "contracts_ledger.xlsx"
def update_ledger(client_info, contract_type, file_path):
try:
wb = openpyxl.load_workbook(LEDGER_PATH)
ws = wb.active
except FileNotFoundError:
wb = openpyxl.Workbook(); ws = wb.active
ws.append(["管理番号","契約先","契約種別","契約金額","開始日","終了日","ファイル","作成日"])
# 新しい管理番号を生成
last_row = ws.max_row
contract_no = f"CT-{datetime.now().strftime('%Y%m')}-{last_row:03d}"
ws.append([
contract_no,
client_info["会社名"],
contract_type,
client_info.get("契約金額", 0),
client_info.get("開始日", ""),
client_info.get("終了日", ""),
file_path,
datetime.now().strftime("%Y/%m/%d"),
])
wb.save(LEDGER_PATH)
print(f"台帳更新完了: {contract_no} - {client_info['会社名']}")
return contract_no
contract_no = update_ledger(client, "業務委託", "contract_出力.docx")
print(f"契約番号: {contract_no}")
契約書生成と同時にExcel台帳が自動更新されました。管理番号・契約先・種別・金額・期間・ファイルパスが自動記録されています。
どんな現場で使われているか:活用シナリオ
実装で押さえるべき重要ポイント
- 1
法務レビュー済みテンプレートから動かす:自動生成の起点となる契約書テンプレートは必ず法務部門がレビュー・承認したものを使いましょう。テンプレートの質が生成物の法的品質を決定します。
- 2
変数部分を明確なマーカーで管理:「{{会社名}}」「{{契約開始日}}」など一貫したマーカー形式を使うことで、テンプレートのメンテナンスと差し込み実装の両方が簡単になります。
- 3
生成後の差分確認ステップを必ず設ける:自動生成した契約書は必ずdocx-diffや手動確認で意図しない変更がないかチェックするフローを実装してください。法的文書の誤りはリスクになります。
ビジネスインパクト
この記事のまとめ
- ✅ 顧客情報から契約書Wordを自動生成してPDF変換まで一貫して実行できる
- ✅ 条項の自動チェックで記載漏れ・矛盾を事前に検出できる
- ✅ 電子署名サービスとのAPI連携で署名フローまで自動化できる
- ✅ 契約書作成から締結完了までのリードタイムを大幅に短縮できる
関連記事
Claude Codeの導入を、プロに任せてみませんか?
Aurant TechnologiesはClaude Code導入支援・業務自動化の専門チームです。
初回相談は無料。御社の課題をヒアリングして最適な自動化プランをご提案します。