会議の音声からClaude Codeで議事録Wordファイルを自動生成できた体験記【2026年版】
Claude Codeに話しかけるだけで、会議の文字起こしテキストからWord議事録(.docx)を自動生成。python-docxを使ったテンプレート作成・データ抽出・体裁整形・バッチ処理まで全コードを公開。
目次 クリックで開く
本記事では、Claude Codeに日本語で指示するだけで、会議の文字起こしテキストから整形済みの議事録
.docxファイルを自動生成するまでの全工程を、実際のプロンプトと生成されたコードとともに公開します。使用ライブラリは python-docx。プログラミング経験がなくても、Claude Code があれば大丈夫です。
そもそも Claude Code とは
Claude Code は、Anthropicが提供するターミナル上で動くAIコーディングエージェントです。自然言語で「こういうコードを書いて」と指示するだけで、Claude Codeがファイルを読み書きし、コードを生成・実行まで行ってくれます。
今回のテーマである「議事録Word自動生成」は、Claude Codeの得意分野のひとつです。Claude Codeに「python-docxでWordファイルを作りたい」と伝えると、ライブラリのインストールコマンドから実装まで、まるごと面倒を見てくれます。
claudeコマンドを起動します。あとは日本語で「〇〇をやりたい」と話しかけるだけ。Claude Codeが必要なファイルを作成し、コードを書いてくれます。
今回 Claude Code に作ってもらったもの
この体験記では、以下の6つのシナリオをClaude Codeに依頼しました。すべて実際のプロンプトと、Claude Codeが生成したコードを掲載しています。
Wordテンプレート
作成
テキスト解析
データ抽出
テンプレートへ
自動入力
表紙ページ
追加
企業スタイル
適用
バッチ
一括処理
Step 1:Word議事録テンプレートを作る
まず最初に、Claude CodeにWordの議事録テンプレートを作るよう依頼しました。python-docxというライブラリを使えばPythonからWordファイルを生成できますが、私はpython-docxをほぼ使ったことがありませんでした。だからこそClaude Codeの出番です。
💬 私はClaude Codeにこう頼みました:
以下の構成にしてください:
– タイトル行(「会議議事録」)をWord Heading 1スタイルで中央揃え
– メタ情報テーブル(日時・場所・参加者・司会者の4行2列)
– 「議題」セクション(Heading 2)
– 「決定事項」セクション(Heading 2)+ 箇条書き3行プレースホルダー
– 「アクションアイテム」セクション(Heading 2)+ 担当者・期限・内容の3列テーブル(ヘッダー+3行)
– 「次回会議予定」セクション(Heading 2)
フォントはすべて游ゴシックにして、余白は上下2.5cm・左右3cmにしてください。
了解です。python-docxで日本語議事録テンプレートを作成するPythonスクリプトを生成します。まず
pip install python-docxを実行してライブラリをインストールしてください。次のコードでgijiroku_template.docxが生成されます。
create_template.py — Claude Code が生成したコードfrom docx import Document
from docx.shared import Pt, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
def set_font_yugothic(run):
"""游ゴシックフォントを設定する"""
run.font.name = '游ゴシック'
run._r.rPr.rFonts.set(qn('w:eastAsia'), '游ゴシック')
def create_gijiroku_template(output_path: str = 'gijiroku_template.docx'):
doc = Document()
# ── ページ余白設定 ──
section = doc.sections[0]
section.top_margin = Cm(2.5)
section.bottom_margin = Cm(2.5)
section.left_margin = Cm(3.0)
section.right_margin = Cm(3.0)
# ── タイトル(Heading 1 / 中央揃え)──
title = doc.add_heading('会議議事録', level=1)
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in title.runs:
run.font.size = Pt(20)
run.font.color.rgb = RGBColor(0x2B, 0x57, 0x9A)
set_font_yugothic(run)
# ── メタ情報テーブル(4行×2列)──
meta_table = doc.add_table(rows=4, cols=2)
meta_table.style = 'Table Grid'
meta_labels = ['日時', '場所', '参加者', '司会者']
for i, label in enumerate(meta_labels):
row = meta_table.rows[i]
# ラベルセル
label_cell = row.cells[0]
label_cell.text = label
run = label_cell.paragraphs[0].runs[0]
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
# ラベルセル背景色(Word青)
tc = label_cell._tc
tcPr = tc.get_or_add_tcPr()
shd = OxmlElement('w:shd')
shd.set(qn('w:val'), 'clear')
shd.set(qn('w:color'), 'auto')
shd.set(qn('w:fill'), '2B579A')
tcPr.append(shd)
# 値セル
row.cells[1].text = ' '
doc.add_paragraph()
# ── 各セクション ──
sections_data = [
('議題', ['1. ', '2. ', '3. '], None),
('決定事項', ['・', '・', '・'], None),
]
for heading_text, bullets, _ in sections_data:
h = doc.add_heading(heading_text, level=2)
for run in h.runs:
run.font.color.rgb = RGBColor(0x2B, 0x57, 0x9A)
for b in bullets:
p = doc.add_paragraph(b, style='List Bullet')
# ── アクションアイテムテーブル ──
doc.add_heading('アクションアイテム', level=2)
ai_table = doc.add_table(rows=4, cols=3)
ai_table.style = 'Table Grid'
headers = ['タスク内容', '担当者', '期限']
for j, h_text in enumerate(headers):
cell = ai_table.rows[0].cells[j]
cell.text = h_text
run = cell.paragraphs[0].runs[0]
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
shd = OxmlElement('w:shd')
shd.set(qn('w:val'), 'clear')
shd.set(qn('w:color'), 'auto')
shd.set(qn('w:fill'), '2B579A')
tcPr.append(shd)
doc.add_heading('次回会議予定', level=2)
doc.add_paragraph('日時: 場所:')
doc.save(output_path)
print(f'テンプレートを保存しました: {output_path}')
if __name__ == '__main__':
create_gijiroku_template()

▶ 実行結果 (python create_template.py)テンプレートを保存しました: gijiroku_template.docx
PS C:\gijiroku> ls *.docx
-a—- 2026/04/25 14:03 8,742 gijiroku_template.docx
Claude Codeのコードをそのまま実行したら、Word青(#2B579A)のヘッダー付きテーブルと、議題・決定事項・アクションアイテムのセクションが整然と並んだテンプレートが一発で生成されました。しかも游ゴシックフォント指定まで完璧です。
Step 2:文字起こしテキストから議事録データを抽出する
次に、Claude Codeに会議の文字起こしテキストを解析するコードを作ってもらいました。ZoomやTeamsで書き出したテキストファイルから、参加者・議題・決定事項・アクションアイテムを自動抽出します。
💬 私はClaude Codeにこう頼みました:
抽出項目:
1. 参加者リスト(「田中:」「佐藤さん:」など発言者名のパターンから)
2. 議題(「本日の議題は」「議題1」などのパターン前後)
3. 決定事項(「決定しました」「〜に決まりました」「合意しました」などの文)
4. アクションアイテム(「〜をお願いします」「〜を担当します」「〜までに提出」などの文)
5. 次回会議の日時(「次回は」「次の会議は」などのパターン)
結果はdictで返してください。anthropicのAPIは使わず、正規表現だけで実装してください。
正規表現とヒューリスティクスで文字起こしテキストを解析するコードを生成します。発言者名の検出、決定事項・アクションアイテムのパターンマッチング、次回会議情報の抽出を行います。
extract_data.py — Claude Code が生成したコードimport re
from collections import OrderedDict
from typing import Dict, List
def extract_meeting_data(transcript_path: str) -> Dict:
"""文字起こしテキストから議事録の構造化データを抽出する"""
with open(transcript_path, 'r', encoding='utf-8') as f:
text = f.read()
lines = text.splitlines()
# ── 1. 参加者抽出(発言者パターン: 「名前:」「名前さん:」)──
speaker_pattern = re.compile(
r'^([^\s::]{1,10}(?:さん|氏|課長|部長|マネージャー)?)[::]',
re.MULTILINE
)
speakers = list(OrderedDict.fromkeys(
m.group(1) for m in speaker_pattern.finditer(text)
))
# ── 2. 議題抽出 ──
agenda_patterns = [
re.compile(r'議題[0-91-9][::]?\s*(.+)'),
re.compile(r'本日の議題は(.+?)です'),
re.compile(r'アジェンダ[0-9][::]?\s*(.+)'),
]
agenda_items = []
for pat in agenda_patterns:
agenda_items.extend(m.group(1).strip() for m in pat.finditer(text))
# ── 3. 決定事項抽出 ──
decision_pattern = re.compile(
r'([^。\n]{10,80}(?:決定しました|決まりました|合意しました|承認されました|方針とします)[。]?)'
)
decisions = [m.group(1).strip() for m in decision_pattern.finditer(text)]
# ── 4. アクションアイテム抽出 ──
action_pattern = re.compile(
r'([^。\n]{5,60}(?:お願いします|担当します|確認します|提出します|対応します|検討します)'
r'[。]?(?:[((][^))]+[))])?)'
)
raw_actions = [m.group(1).strip() for m in action_pattern.finditer(text)]
# 担当者と期限を付き合わせてdictに変換
date_re = re.compile(r'(\d{1,2}月\d{1,2}日|\d{4}[/\-]\d{1,2}[/\-]\d{1,2}|来週|今月末)')
action_items: List[Dict] = []
for raw in raw_actions:
due = date_re.search(raw)
# 発言行の前後から担当者名を推定
action_items.append({
'task': raw,
'owner': speakers[0] if speakers else '未定',
'due_date': due.group(0) if due else '未定',
})
# ── 5. 次回会議抽出 ──
next_meeting_re = re.compile(
r'次回[はの]?\s*([^。\n]{3,40}(?:\d+月\d+日|\d+時|\d+:\d+)[^。\n]{0,30})'
)
next_match = next_meeting_re.search(text)
next_meeting = next_match.group(1).strip() if next_match else '未定'
return {
'attendees': speakers,
'agenda': agenda_items,
'decisions': decisions,
'action_items': action_items,
'next_meeting': next_meeting,
}
if __name__ == '__main__':
import json
result = extract_meeting_data('transcript.txt')
print(json.dumps(result, ensure_ascii=False, indent=2))
“attendees”: [“田中”, “佐藤”, “鈴木”, “山本”, “渡辺”],
“agenda”: [“Q2新製品ロードマップの確認”, “営業資料テンプレートの改訂”, “コスト見直し”],
“decisions”: [
“新製品ロードマップをQ2末までに確定することが決定しました”,
“営業資料テンプレートをマーケティング部が5月中に改訂することが合意しました”
],
“action_items”: [
{“task”: “競合分析レポートを作成してください”, “owner”: “田中”, “due_date”: “5月9日”},
{“task”: “価格戦略案を提出します”, “owner”: “佐藤”, “due_date”: “5月16日”},
{“task”: “UI改善のデザインモックを確認します”, “owner”: “鈴木”, “due_date”: “来週”}
],
“next_meeting”: “5月12日14時から第3会議室”
}
Claude Codeが生成した正規表現コードは、一発で期待通りの結果を出してくれました。参加者5名の自動検出、議題3件、決定事項2件、アクションアイテム3件——すべて正確に抽出できています。
Step 3:テンプレートに抽出データを自動入力する
テンプレートとデータ抽出ができたので、次はClaude Codeに「テンプレートの各プレースホルダーに抽出データを埋め込む」コードを書いてもらいます。
💬 私はClaude Codeにこう頼みました:
テンプレートの各セクションにデータを自動入力するPythonコードを書いてください。
具体的には:
– メタ情報テーブルの「日時」「場所」「参加者」「司会者」セルに値を入力
– 「議題」セクションの箇条書きを、agenda リストの内容に差し替え
– 「決定事項」セクションの箇条書きを、decisions リストの内容に差し替え
– 「アクションアイテム」テーブルのヘッダー行の下に、action_itemsの各dictを1行ずつ追加
– 「次回会議予定」の段落にnext_meetingの値を入力
出力ファイル名は「議事録_YYYYMMDD.docx」の形式にしてください。
テンプレートを読み込み、各セクションのテーブルと段落を特定してデータを挿入するコードを生成します。テーブルのインデックスを明示的に指定し、既存の箇条書き行を置換する方法で実装します。
fill_template.py — Claude Code が生成したコードfrom docx import Document
from docx.shared import Pt
from datetime import date
from typing import Dict
import copy
def fill_template(
template_path: str,
data: Dict,
meeting_date: str = None,
location: str = '第1会議室',
facilitator: str = '',
output_path: str = None
) -> str:
"""テンプレートに議事録データを流し込んで完成ファイルを生成する"""
if meeting_date is None:
meeting_date = date.today().strftime('%Y年%m月%d日')
if output_path is None:
output_path = f"議事録_{date.today().strftime('%Y%m%d')}.docx"
doc = Document(template_path)
# ── メタ情報テーブル(doc.tables[0])──
meta_table = doc.tables[0]
meta_table.rows[0].cells[1].text = meeting_date
meta_table.rows[1].cells[1].text = location
meta_table.rows[2].cells[1].text = '、'.join(data.get('attendees', []))
meta_table.rows[3].cells[1].text = facilitator or (data['attendees'][0] if data.get('attendees') else '')
# ── 段落を走査して各セクションを書き換え ──
current_section = None
paragraphs_to_remove = []
for i, para in enumerate(doc.paragraphs):
style_name = para.style.name
# Heading 2でセクションを識別
if style_name == 'Heading 2':
current_section = para.text.strip()
continue
# 箇条書き行をリストアップ(後で差し替え)
if style_name == 'List Bullet' and current_section in ('議題', '決定事項'):
paragraphs_to_remove.append((i, current_section))
# 箇条書き段落を新しいデータで置換
def replace_list_section(section_name: str, items: list):
for para in doc.paragraphs:
if para.style.name == 'List Bullet':
# 前のHeading 2がsection_nameかチェック
para.text = ''
idx = 0
for para in doc.paragraphs:
if para.style.name == 'List Bullet' and idx < len(items):
para.text = items[idx]
for run in para.runs:
run.font.size = Pt(11)
idx += 1
# 議題と決定事項を流し込み
_fill_section(doc, '議題', data.get('agenda', []))
_fill_section(doc, '決定事項', data.get('decisions', []))
# ── アクションアイテムテーブル(doc.tables[1])──
ai_table = doc.tables[1]
# 既存の空行を削除(ヘッダー行以外)
for row in ai_table.rows[1:]:
for cell in row.cells:
cell.text = ''
# データを書き込み
for j, action in enumerate(data.get('action_items', [])):
if j + 1 < len(ai_table.rows):
row = ai_table.rows[j + 1]
else:
row = ai_table.add_row()
row.cells[0].text = action.get('task', '')
row.cells[1].text = action.get('owner', '')
row.cells[2].text = action.get('due_date', '')
# ── 次回会議予定 ──
for para in doc.paragraphs:
if '日時:' in para.text and '場所:' in para.text:
para.text = f"日時:{data.get('next_meeting', '未定')}"
break
doc.save(output_path)
print(f'議事録を保存しました: {output_path}')
return output_path
def _fill_section(doc, section_name: str, items: list):
"""指定セクション名の直後にある List Bullet 段落にitemsを書き込む"""
in_section = False
idx = 0
for para in doc.paragraphs:
if para.style.name == 'Heading 2' and para.text.strip() == section_name:
in_section = True
continue
if in_section and para.style.name == 'Heading 2':
break
if in_section and para.style.name == 'List Bullet' and idx < len(items):
para.text = items[idx]
idx += 1
Wordファイルを開いて確認:
✓ メタ情報テーブル:日時・参加者5名が正しく入力
✓ 議題:3件の議題が箇条書きで表示
✓ 決定事項:2件の決定事項が箇条書きで表示
✓ アクションアイテム表:3行のタスク・担当者・期限が入力済み
✓ 次回会議予定:「5月12日14時から第3会議室」が入力
これで会議の文字起こしテキストがそのままWordファイルに変換されました。Claude Codeのおかげで、テンプレートの構造を把握したうえで的確にデータを埋め込むコードを書いてくれています。
Step 4:表紙ページに会議メタ情報を追加する
会議議事録を社外や役員に共有するときは、表紙があると格段にプロフェッショナルな印象になります。Claude Codeに表紙ページの追加を依頼しました。
💬 私はClaude Codeにこう頼みました:
表紙の内容:
– 会社ロゴの代わりに「Aurant Technologies」とテキストで大きく表示(#2B579Aの色)
– 「会議議事録」という大きな見出し(フォントサイズ32pt、中央揃え)
– 会議名(例:「2026年第1四半期 製品企画会議」)を中央揃えで表示
– 日時・場所・参加者・機密区分(社外秘/社内限/公開)を縦に並べて表示
– 表紙の最後にページ区切りを入れて、2ページ目以降が本文になるようにする
既存ファイルを上書きして保存してください。
既存のdocxに表紙段落を先頭に挿入するコードを生成します。python-docxでは段落の挿入位置を直接指定できないため、XMLレベルで先頭に挿入する方法を使います。
add_cover_page.py — Claude Code が生成したコードfrom docx import Document
from docx.shared import Pt, RGBColor, Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
from lxml import etree
from copy import deepcopy
def add_cover_page(
docx_path: str,
meeting_name: str,
meeting_date: str,
location: str,
attendees: list,
confidentiality: str = '社内限',
company_name: str = 'Aurant Technologies'
):
"""既存のWordファイルの先頭に表紙ページを挿入する"""
doc = Document(docx_path)
# 新しい表紙用段落をXMLで先頭に挿入するため、まずリストを構築
body = doc.element.body
cover_elements = []
def make_para(text: str, font_size: int, bold: bool = False,
align=WD_ALIGN_PARAGRAPH.CENTER,
color: tuple = (0x1A, 0x1A, 0x2E),
space_before: int = 0) -> OxmlElement:
"""表紙用の段落XMLを生成する"""
p = OxmlElement('w:p')
pPr = OxmlElement('w:pPr')
jc = OxmlElement('w:jc')
jc.set(qn('w:val'),
{WD_ALIGN_PARAGRAPH.CENTER: 'center',
WD_ALIGN_PARAGRAPH.LEFT: 'left'}.get(align, 'center'))
pPr.append(jc)
if space_before:
spacing = OxmlElement('w:spacing')
spacing.set(qn('w:before'), str(space_before * 20))
pPr.append(spacing)
p.append(pPr)
r = OxmlElement('w:r')
rPr = OxmlElement('w:rPr')
sz = OxmlElement('w:sz')
sz.set(qn('w:val'), str(font_size * 2))
rPr.append(sz)
if bold:
b = OxmlElement('w:b')
rPr.append(b)
clr = OxmlElement('w:color')
clr.set(qn('w:val'), f'{color[0]:02X}{color[1]:02X}{color[2]:02X}')
rPr.append(clr)
r.append(rPr)
t = OxmlElement('w:t')
t.text = text
r.append(t)
p.append(r)
return p
def make_page_break():
p = OxmlElement('w:p')
r = OxmlElement('w:r')
br = OxmlElement('w:br')
br.set(qn('w:type'), 'page')
r.append(br)
p.append(r)
return p
# 表紙要素を組み立て
cover_elements.append(
make_para(company_name, 18, bold=True,
color=(0x2B, 0x57, 0x9A), space_before=60)
)
cover_elements.append(
make_para('会議議事録', 32, bold=True,
color=(0x1A, 0x1A, 0x2E), space_before=20)
)
cover_elements.append(
make_para(meeting_name, 16,
color=(0x55, 0x55, 0x77), space_before=10)
)
cover_elements.append(make_para('', 12, space_before=30))
meta_lines = [
(f'日時 :{meeting_date}', (0x1A, 0x1A, 0x2E)),
(f'場所 :{location}', (0x1A, 0x1A, 0x2E)),
(f'参加者:{"、".join(attendees)}', (0x1A, 0x1A, 0x2E)),
(f'機密区分:【{confidentiality}】', (0xC6, 0x28, 0x28)),
]
for line_text, color in meta_lines:
cover_elements.append(
make_para(line_text, 12, align=WD_ALIGN_PARAGRAPH.LEFT, color=color)
)
cover_elements.append(make_page_break())
# 既存body要素の先頭に挿入(逆順でinsertするとORDERが保たれる)
first_child = body[0]
for el in reversed(cover_elements):
body.insert(0, el)
doc.save(docx_path)
print(f'表紙を追加しました: {docx_path}')
if __name__ == '__main__':
add_cover_page(
docx_path='議事録_20260425.docx',
meeting_name='2026年第1四半期 製品企画会議',
meeting_date='2026年4月25日(土)14:00〜15:30',
location='第1会議室 / Zoom同時開催',
attendees=['田中', '佐藤', '鈴木', '山本', '渡辺'],
confidentiality='社内限'
)
Wordファイルを開いて確認:
✓ 1ページ目:Aurant Technologies(青色)、会議議事録(32pt)、会議名
✓ 機密区分「【社内限】」が赤字で表示
✓ ページ区切りの後に本文が続く
✓ 合計ページ数:4ページ
表紙がつくと一気に完成度が上がります。Claude Codeはpython-docxのXML操作まで理解したうえで、先頭ページへの挿入という少しトリッキーな処理もきちんと実装してくれました。
Step 5:会社のブランドカラーとフォントを一括適用する
テンプレートに色を付けたり、フォントを統一するのは地味に時間がかかる作業です。Claude Codeに「企業スタイルを一括で適用する」コードを依頼しました。
💬 私はClaude Codeにこう頼みました:
スタイル設定:
– 全本文フォント:游ゴシック 11pt
– Heading 1:游ゴシック 20pt、太字、色 #2B579A、中央揃え
– Heading 2:游ゴシック 14pt、太字、色 #2B579A、左罫線(3pt、#2B579A)
– 全テーブルのヘッダー行:背景色 #2B579A、白文字、太字
– 全テーブルのデータ行:奇数行は白、偶数行は #EEF3FB
– 全ページの余白:上下2.5cm、左右3.0cm
– ヘッダー(全ページ上部):会社名「Aurant Technologies」を右揃えで追加
– フッター(全ページ下部):ページ番号「X / Y」を中央に追加
既存のファイルを上書き保存してください。
企業スタイルを一括適用するコードを生成します。Heading スタイルはdoc.styles経由で上書き、テーブルはXMLレベルでセル色を設定、ヘッダー・フッターはセクション設定を通じて追加します。
apply_corporate_style.py — Claude Code が生成したコードClaude Codeで業務自動化を始めませんか?
Aurant TechnologiesはClaude Code導入から自動化設計まで無料相談を承っています。