AIの業務活用

AIで週次業務報告書を作る:CSV業務日誌の整理と数値の照合

CSV業務日誌からAIで週次報告書を作り、Pythonで時間と完了件数を照合します。コピーできるプロンプトで完了・進行中・計画・障害を分け、漏れを確認します。

目次を表示

この翻訳はAIで作成しました。コード、単位、数値は原文と併せて確認してください。各言語のネイティブ話者による校閲は、まだ完了していません。 English

対象読者短い日々の業務ログを記録しており、作業時間や完了件数を自分で確認しながらAIで週報を作成したい人向けです。

準備するもの
  • Python 3.12
  • 日々の業務ログを保存した通常のCSVファイル

01AIが作成した週報の数値をなぜ照合するのか

AIは短く断片的な業務記録を読みやすい文章に整理するのに役立ちますが、計算結果の基準として扱うべきではありません。週報の文章が自然でも、合計値が変わったり、同じ作業を二重に数えたり、予定中の作業を完了済みとして表現したりする可能性があります。より安全なのは、文章作成と数値照合を分ける方法です。

  • 業務ログを事実確認の基準資料として使います。
  • AIにはログに書かれている内容だけを要約するよう依頼します。
  • 作業時間と件数は構造化データから別に計算します。
  • AIの週報と独立して計算した結果を比較します。
  • 送信や公開の前に差異があれば修正します。

02小さな合成業務ログから始める

次の業務ログは合成データです。各行には1つの作業、その作業に使った時間、その週のうちに完了したかどうかが記録されています。このように項目を構造化しておくと、後で数値を照合しやすくなります。

datetaskhoursstatus
2026-09-14Clean customer CSV2.0completed
2026-09-14Draft import script1.5completed
2026-09-15Test import script2.5completed
2026-09-16Investigate duplicate IDs1.0completed
2026-09-17Update validation rules2.0completed
2026-09-18Prepare user notes1.5in progress

手計算では、作業時間は2.0 + 1.5 + 2.5 + 1.0 + 2.0 + 1.5 = 10.5時間です。6件の作業のうち5件がcompletedなので、完了作業数は5件です。最後の作業はまだin progressであり、完了として数えてはいけません。

03記憶ではなくログだけを使って週報を書かせる

業務ログをAIチャットアシスタントに貼り付け、与えたデータだけを整理するよう明確に制限します。後から確認できるように、AIが計算した合計作業時間と完了件数も書かせます。

AIへの依頼例: 下の業務ログだけを使って簡潔な週報を書いてください。完了した業務、進行中の業務、週間合計の3つに分けてください。記録にない成果や作業は追加しないでください。合計記録時間と完了した作業数を明記し、元の作業内容の意味は変えないでください。

一般的なAIの回答は次のようになります。今週は顧客データを整理し、インポートスクリプトを作成してテストし、重複IDを調査し、検証ルールを更新しました。ユーザー向けメモの作成は引き続き進行中です。合計記録時間は10.5時間で、完了した作業は5件です。

04照合用の構造化データを別に保持する

同じ合成例を、date、task、hours、status列を持つwork_log.csvとして保存します。照合スクリプトはAIが書いた文章から数値を取り出すのではなく、この元ファイルを直接読み取ります。

項目ログから求めた期待値
行数6
合計作業時間10.5
完了作業数5
進行中の作業数1

この分離が重要です。CSVは根拠データであり、週報はその根拠を読みやすく表現した成果物です。

05Pythonで作業時間と件数を再計算する

次のPython 3.12スクリプトはwork_log.csvを読み、必須列を確認し、合計作業時間とステータス別件数を計算して、照合結果をoutputs/weekly_reconciliation.txtに保存します。既存のoutputsディレクトリは上書きしません。

python
from pathlib import Path
import csv

input_path = Path("work_log.csv")
output_dir = Path("outputs")

if output_dir.exists():
    raise SystemExit("outputs already exists; remove or rename it before running again")

if not input_path.exists():
    raise SystemExit("work_log.csv was not found")

required_fields = {"date", "task", "hours", "status"}
rows = []

with input_path.open("r", encoding="utf-8", newline="") as f:
    reader = csv.DictReader(f)

    if reader.fieldnames is None:
        raise SystemExit("CSV has no header")

    missing = required_fields - set(reader.fieldnames)
    if missing:
        raise SystemExit(f"Missing columns: {sorted(missing)}")

    for line_number, row in enumerate(reader, start=2):
        try:
            hours = float(row["hours"])
        except ValueError:
            raise SystemExit(f"Invalid hours value on line {line_number}")

        if hours < 0:
            raise SystemExit(f"Negative hours on line {line_number}")

        status = row["status"].strip().lower()
        if status not in {"completed", "in progress"}:
            raise SystemExit(f"Unexpected status on line {line_number}: {status}")

        rows.append({
            "date": row["date"].strip(),
            "task": row["task"].strip(),
            "hours": hours,
            "status": status,
        })

total_hours = sum(row["hours"] for row in rows)
completed_count = sum(row["status"] == "completed" for row in rows)
in_progress_count = sum(row["status"] == "in progress" for row in rows)

output_dir.mkdir()
report_path = output_dir / "weekly_reconciliation.txt"

report = (
    f"Rows: {len(rows)}\n"
    f"Total hours: {total_hours:.1f}\n"
    f"Completed activities: {completed_count}\n"
    f"In-progress activities: {in_progress_count}\n"
)

report_path.write_text(report, encoding="utf-8")

print(report, end="")
print(f"Saved: {report_path}")

06AIの週報と計算結果を比較する

この例で独立して確認した値は、合計作業時間10.5時間、完了作業5件です。AIの下書きに含まれるすべての数値表現をこれらと比較します。

確認項目ログの結果AIの下書き判定
合計作業時間10.510.5一致
完了作業数55一致
進行中の作業数1ユーザー向けメモは進行中内容一致
  1. AIの週報に含まれるすべての数値を照合結果と比較します。
  2. 完了作業と進行中の作業が混同されていないか確認します。
  3. 作業内容を元のログと比較し、AIが成果を追加していないか確認します。
  4. AIの合計値とログの計算値が異なる場合は、構造化されたログの計算値を基準に文章を修正します。

07よくあるミスと限界

  • 元のログではなく、AIの週報内の数字を足して合計を確認すること。
  • 一部の行が進行中でも、すべての行を完了作業として数えること。
  • 同じプロジェクトに関する複数のログ行を1件と数えるか複数件と数えるかのルールを決めないこと。
  • 記録に明記されていない成果をAIに推測させること。
  • ログ内のステータス表現を変更したのに、スクリプトで許可する値を更新しないこと。
  • 合計を計算する前に、欠損行、不正な時間値、重複記録を確認しないこと。

この例ではCSVの1行を1つの数えられる作業として扱います。実際の組織では、チケット、成果物、プロジェクト、マイルストーンなどを基準に数える場合があるため、照合前に何を1件と数えるか定義する必要があります。また、このスクリプトで確認できるのは単純な時間合計とステータスだけであり、業務ログ自体が正しいか、業務の品質が十分だったかまでは判断できません。

完了・進行中・計画・障害を分ける週次業務報告書の依頼文

業務日誌を週次報告書にまとめるときは、状態の異なる業務を1つの段落に混ぜないほうがよいです。完了した業務、まだ進行中の業務、翌週の計画、進行を妨げる障害事項を別々に求めると、原文との照合がしやすくなります。CSVの空欄は実際の値0とは意味が異なる場合があるため、AIが空欄を勝手に0と解釈しないよう制限します。また、各要約項目に根拠となった原文の行番号や識別子を付けさせると、その後Pythonで時間や件数を照合するときに、漏れや重複を見つけやすくなります。

プロンプト
以下のCSV業務日誌を使って、週次業務報告書の案を作成してください。

報告書の構成:
1. 完了した業務
2. 進行中の業務
3. 翌週の計画
4. 障害事項または確認が必要な事項

ルール:
- 各項目の後に、根拠となった原文の行番号または提供された行識別子を表示してください。
- 完了と進行中を勝手に変更しないでください。
- 翌週の計画が原文にない場合は、新しい計画を事実として作らず、「原文に計画情報なし」と表示してください。
- 障害事項が記録されていない場合でも、「障害事項0件」と断定せず、「記録された障害事項なし」と表現してください。
- CSVの空欄を数値0や「なし」に自動変換しないでください。
- 時間、件数、完了数などの数値は原文の値をそのまま維持し、計算が必要な場合は計算式も示してください。
- 異なる行の業務を1つにまとめる場合、原文の意味が変わっていないか確認してください。
- 最後に、Pythonで照合する数値項目を「検算対象」として別に列挙してください。

実行・検証の記録

ChatGPT Python tool · Python 3.x · standard library only

  • スクリプトは正確な合成作業ログで正常に完了した。
  • 出力は Rows: 6 と報告した。
  • 出力は Total hours: 10.5 と報告し、2.0 + 1.5 + 2.5 + 1.0 + 2.0 + 1.5 と一致した。
  • 出力は Completed activities: 5 と報告した。
  • 出力は In-progress activities: 1 と報告した。
  • これらの値は記事の expected-values 表および AI-report 比較表と一致した。
  • スクリプトは記載された4つの reconciliation metric を正確に含む outputs/weekly_reconciliation.txt を作成した。
  • work_log.csv は実行後も変更されなかった。
  • 2回目の実行は 'outputs already exists; remove or rename it before running again' とともに停止し、記載された上書き防止動作を確認した。
検証範囲の限界
  • スクリプトは記録された hours と status count を検証するが、元の work-log エントリ自体が事実上完全または正確かどうかは判断できない。
  • counting rule は記事に記載されたとおり、各 CSV row を1つの activity として扱う。
  • Python 実行環境では無関係なスプレッドシートランタイムのウォームアップ警告が発生したが、記事スクリプトや出力には影響しなかった。

参考資料

説明と例は独自に作成しました。関連する動作や概念は、以下の公式資料で確認できます。