Claudeで改善基準告示に拘束時間を照合する — コード実行で判定を検算
運転者の勤務実績を改善基準告示に照合するとき、日付をまたぐ時間計算をClaudeの暗算に任せず、コード実行ツールで判定し手元のスクリプトで検算する手順を、トラックの数値で示します。
Claudeで改善基準告示に拘束時間を照合する — コード実行で判定を検算
運転者の拘束時間と休息期間を改善基準告示に照合する作業は、足し算より日付の扱いでつまずきます。1日が暦日ではなく始業からの24時間で、月の合計だけは重複を引くからです。この計算をClaudeの暗算に任せず、コード実行ツールにPythonで走らせ、手元の同じスクリプトと突き合わせて検算する手順をまとめます。
数値はトラック運転者向けの資料に沿っています。バスやタクシーの基準は含みません。
照合の対象になる数値
改善基準告示は、運転や整備を含む使用者の拘束時間、休息期間、運転時間を定めた基準です。厚生労働省の案内では、自動車運転の業務に従事する労働者は、時間外労働の上限規制とは別にこの告示を守る必要があるとされています。令和6(2024)年4月から現行の基準が適用されています。
トラック運転者向けテキストの数値のうち、勤務実績の照合に使うものは次のとおりです。
| 項目 | 原則 | 労使協定による延長 |
|---|---|---|
| 1年の拘束時間 | 原則3,300時間以内 | 労使協定による延長3,400時間以内 |
| 1か月の拘束時間 | 原則284時間以内 | 労使協定による延長310時間以内(年6か月まで) |
| 1日の拘束時間 | 原則13時間以内、上限15時間 | 労使協定による延長宿泊を伴う長距離貨物運送は16時間まで |
| 1日の休息期間 | 原則継続11時間以上を基本、9時間を下回らない | 労使協定による延長長距離貨物運送は週2回まで8時間以上 |
月310時間への延長には条件があります。284時間を超える月は連続3か月までで、時間外・休日労働が月100時間未満になるよう努める必要があります。1日の拘束時間は14時間を超える日を週2回までにするのが目安です。
自動車運転者の時間外労働は、特別条項付き36協定を結ぶ場合でも年960時間が上限です。この上限も告示とは別の規制として並びます。
暗算に任せると崩れる2つの規則
テキストは、数え方を2点で明確にしています。
1点目は「1日」の定義です。暦日ではなく、始業時刻から起算した24時間を1日とします。前回の始業から24時間以内に次の始業が来る場合、重なった時間は両方の日の拘束時間に入ります。
テキストの例では、月曜8時に始業して19時に終業し、火曜6時に再び始業して18時に終業します。月曜の1日の拘束時間は11時間と火曜6時から8時の2時間で13時間、火曜は12時間です。
2点目は月の合計です。1か月の拘束時間は重複を除いて数えるため、同じ例の合計は13+12の25時間ではなく23時間になります。1日の判定では二重に数え、月の合計では二重に数えません。
日付をまたぐ勤務が混じると、この切り替えを文章の推論だけで正しく保つのは難しくなります。そこで計算だけをコードに寄せます。
コード実行ツールに計算を任せる
コード実行ツールは、Messages APIのリクエストに加えるだけで使えます。APIがサンドボックスでコマンドを実行し、結果を同じリクエストの中でClaudeに返すので、結果を返送する処理を自分で書く必要はありません。
実行環境の仕様は、この用途で効く点だけ挙げます。
- Pythonは3.11で、pandas、numpy、python-dateutilなどが入っています
- インターネットには接続できず、実行時にパッケージを追加できません
- 実行時間には上限があり、超えると
execution_time_exceededエラーになります - コンテナは30日で失効し、リクエストごとに新しいコンテナで始まります
勤務実績のCSVはプロンプトに直接貼れる大きさにしておけば、ファイルのアップロードは要りません。料金は、Web検索やWeb Fetchと併用しない単体利用では実行時間で課金されます。月1,550時間までは無料で、条件はコード実行ツールが無料になる条件にまとめています。
計算を明示的にコードへ回す
簡単な算術や単位換算は、ツールを使わずにClaudeが直接答えることがあります。実行するかどうかは文脈で決まるため、境界にある依頼には「コードを実行して確認して」と明示します。
import anthropic
client = anthropic.Anthropic()
prompt = """次の勤務実績をトラック運転者の改善基準告示に照合してください。
計算は必ずコード実行ツールで行い、暗算しないでください。
規則:
- 1日は暦日でなく、始業から起算した24時間
- 24時間以内に次の始業が来るとき、重なった時間は両方の日に入れる
- 1日の拘束時間は15時間を超えたら違反、14時間超は件数を数える
- 休息期間は9時間未満を違反、11時間未満を努力義務未達として区別する
- 1か月の拘束時間は重複を除いて合計する
勤務実績(start,end):
2026-10-05 07:00,2026-10-05 23:00
2026-10-06 10:00,2026-10-06 20:00
2026-10-07 07:00,2026-10-07 18:00
2026-10-08 05:00,2026-10-08 19:00
2026-10-09 20:00,2026-10-10 07:00
各勤務について、拘束時間・次の勤務までの休息期間・判定を表で示し、
最後に実行したコードを添えてください。"""
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
messages=[{"role": "user", "content": prompt}],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
print(response.to_json())規則をプロンプトに書くのは、数値をClaudeの記憶に頼らないためです。改正の前後で基準が変わっているため、手元の資料の数値をそのまま渡します。令和6年3月までの基準は1日の休息期間が継続8時間以上で、今の9時間とは異なります。
手元のスクリプトで検算する
Claudeが返した表を信じて終わらせず、同じ規則を実装した手元のスクリプトに同じCSVを通します。2つが一致すれば、規則の解釈と日付計算の両方が合っていると見てよい状態になります。
import csv, io
from datetime import datetime, timedelta
CSV = """start,end
2026-10-05 07:00,2026-10-05 23:00
2026-10-06 10:00,2026-10-06 20:00
2026-10-07 07:00,2026-10-07 18:00
2026-10-08 05:00,2026-10-08 19:00
2026-10-09 20:00,2026-10-10 07:00
"""
H = timedelta(hours=1)
rows = sorted((datetime.fromisoformat(r["start"]), datetime.fromisoformat(r["end"]))
for r in csv.DictReader(io.StringIO(CSV)))
for i, (s, e) in enumerate(rows):
window_end = s + 24 * H
day = e - s
for s2, e2 in rows[i + 1:]:
if s2 < window_end: # 24時間以内に次の始業が来る
day += min(e2, window_end) - s2
rest = (rows[i + 1][0] - e) / H if i + 1 < len(rows) else None
flags = []
if day > 15 * H: flags.append("1日の拘束時間が15時間超")
elif day > 14 * H: flags.append("14時間超(週2回まで)")
if rest is not None and rest < 9: flags.append("休息9時間未満")
elif rest is not None and rest < 11: flags.append("休息11時間未満(努力義務)")
print(s.strftime("%m/%d %H:%M"), f"拘束{day / H:.1f}h",
"" if rest is None else f"休息{rest:.1f}h", flags or "OK")
month = sum((e - s) / H for s, e in rows) # 24時間窓の重複分は足さない
print(f"月合計 {month:.1f}h")手元のPython 3で実行した出力は次のとおりです(標準ライブラリのみ)。
10/05 07:00 拘束16.0h 休息11.0h ['1日の拘束時間が15時間超']
10/06 10:00 拘束13.0h 休息11.0h OK
10/07 07:00 拘束13.0h 休息11.0h OK
10/08 05:00 拘束14.0h 休息25.0h OK
10/09 20:00 拘束11.0h OK
月合計 62.0h10月5日の7時から23時は16時間で、1日の上限15時間を超えます。テキストの例にある「月曜7時に始業、23時に終業」の違反例と同じ型です。10月9日の勤務は日付をまたいで翌朝7時に終わるため、暦日で切ると1日目と2日目に割れます。始業からの24時間で数えれば11時間です。
Claudeが返した判定が1行でも食い違ったら、どの規則の解釈が違うかを該当行で探します。コードを添えさせておくと、窓の切り方か、休息の閾値かをその場で追えます。
月と年の上限も同じ型で検算する
1日の判定を通っても、月と年で引っかかる運用があります。テキストには、2つの失敗例が載っています。
- 労使協定がなく、すべての月が284時間の例。月ごとは基準内でも、年は284×12=3,408時間で3,300時間を超えます
- 労使協定があり、年3,353時間と3,400時間以内に収まる例。ただし6〜9月の4か月が310時間で続き、284時間超は連続3か月までという条件に反します
どちらも合計と連続回数を数える問題です。コード実行ツールに任せやすく、次の関数で手元でも確かめられます。
def check_year(hours, agreement):
"""hours: 12か月分の月間拘束時間。agreement: 労使協定の有無。"""
year_cap = 3400 if agreement else 3300
msgs = []
if sum(hours) > year_cap:
msgs.append(f"年{sum(hours)}h > {year_cap}h")
over = [h > 284 for h in hours]
if agreement:
if any(h > 310 for h in hours): msgs.append("月310h超")
if sum(over) > 6: msgs.append("284h超が7か月以上")
run = 0
for o in over:
run = run + 1 if o else 0
if run > 3: msgs.append("284h超が4か月連続"); break
elif any(over):
msgs.append("月284h超(労使協定なし)")
return msgs or ["OK"]
print(check_year([284] * 12, False))
print(check_year([225, 220, 310, 310, 310, 310, 284, 250, 310, 270, 284, 270], True))出力は次の2行です。2つ目の数字は、テキストの例2と同じ型(合計3,353時間、284時間超が5か月、うち4か月連続)に合わせて作りました。
['年3408h > 3300h']
['284h超が4か月連続']月310時間への延長に付く「時間外・休日労働が月100時間未満になるよう努める」は努力義務の書き方なので、この関数では判定していません。Claudeにこの条件も照合させるなら、時間外・休日労働の列をCSVに加え、努力義務として別枠で出すよう指示します。
長距離貨物運送の例外を規則に入れるとき
宿泊を伴う長距離貨物運送には、別の上限が使えます。テキストの条件は、1週間の運行がすべて長距離貨物運送であることです。ここでいう長距離は、一の運行の走行距離が450km以上で、運行中の休息期間が住所地以外の場所にあるものを指します。運行は、運転者が営業所を出てから帰着するまでです。
この場合、数値は次のように変わります。
- 1日の拘束時間は16時間まで延長でき、延長は週2回までに限られます
- 1日の休息期間は、週2回に限り継続8時間以上にできます
- 拘束時間を16時間まで延ばしたときは、その運行の終了後に継続12時間以上の休息期間が必要です
プロンプトでこの例外を使うなら、運行ごとの走行距離と宿泊先の列をCSVに足し、条件を満たす週だけに別の閾値を当てるよう書きます。条件を満たさない週に16時間を許すと、違反を見逃します。判定の分岐はコードに書き、Claudeには分岐の結果を表にさせます。
休息期間の与え方にも誤解しやすい点があります。テキストのQ&Aでは、休息期間を始業から24時間以内に終わらせる必要はないとされています。9時始業の例では、拘束時間の上限が15時間なので24時までに終業します。その後の休息は、継続11時間以上を基本としつつ9時間を下回らなければよく、始業から24時間以内に11時間を収める必要はありません。次の始業が翌日11時になっても、休息期間の基準は満たせます。休息の判定は、終業から次の始業までを測るだけで足ります。
検算で見るところ
照合の誤りは、数字の足し間違いよりも規則の取り違えで起きます。検算では次の点を見ます。
- 1日の拘束時間に、次の勤務との重なりが加算されているか
- 月の合計で、重なりを二重に数えていないか
- 日付をまたぐ勤務が、終業側の日付で別勤務に分割されていないか
- 休息期間が終業から次の始業までで測られているか
コード実行の出力はClaudeの要約より先に読みます。返ってきた stdout と添えられたコードを見れば、Claudeが規則をどう実装したかが確認できます。失敗時のエラーコードはcode executionツールのエラーコード一覧で確かめられます。
統計値の検証にも同じ型を使えます。生データを持たせて再計算させる流れはClaudeで論文の統計値を生データと照合して検証するに書いています。
この手順が判定しない範囲
このスクリプトとプロンプトが見るのは、1日の拘束時間、1日の休息期間、月の拘束時間の3点だけです。テキストには、次のような別の定めもあります。
- 継続9時間の休息期間を与えにくいときの分割休息(1回3時間以上)
- 2人乗務で身体を伸ばして休息できる設備があるときの休息期間の短縮(4時間まで)
- フェリーに乗っている時間の休息期間としての扱い
- 運転時間と連続運転時間の基準
これらに当たる勤務が混じる事業所では、規則をプロンプトに足すか、スクリプトの対象外として扱いを決めます。また、判定は労務管理の補助であり、違反の最終判断は労働基準監督署などの窓口に確かめる前提です。厚生労働省の案内には、相談先として労働基準監督署と働き方改革推進支援センターが挙がっています。
まとめ
日付をまたぐ時間計算は、規則を先に文章で渡し、計算をコード実行ツールに任せ、手元の同じ規則のスクリプトで突き合わせると、判定の根拠を2経路で追えます。基準の数値は改正で変わるため、規則の欄は最新の資料から書き直します。