宿泊税の月ごとの申告のために、予約と精算のデータから1人1泊の宿泊料金と税額を集計し、課税免除や料金の扱いの確認が要る宿泊を判定して経理に回す
前の月にチェックアウトした予約の精算データから、1人1泊の宿泊料金と宿泊税の額を規則で計算します。食事込みのプランや修学旅行のように扱いの確認が要る予約は、AIがプラン名と備考から判定して経理に回します。
- 生成AI
- ChatGPT/Claude/Gemini
- 連携・自動化
- Google Apps Script/Make/Power Automate/Python
- 対象業界
- その他/不動産/宿泊
- 対象部門
- 経理/総務
- 対象業務
- 内容確認・チェック/集計・分析
- 主な課題
- 入力作業が多い/期限・対応漏れが起きる/確認ミスが多い
- AIで行う処理
- 判定
- 主な効果
- 入力漏れ削減/品質標準化/工数削減
- 導入難易度
- ★★☆☆☆
- 実装レベル
- 半自動化
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 経理課が、前の月の精算データを施設ごとに書き出す
- 予約ごとに、プラン名を見て食事代を引くか、サービス料を足すかを決める
- 人数と泊数で割り、1人1泊の宿泊料金を出して区分に当てはめる
- 月をまたぐ連泊は、宿泊日ごとに分けて月に振り分ける
- 予約サイトのポイント、旅行会社の割引、無料招待などを備考から探して直す
- 修学旅行の団体は、フロントに証明書を受け取ったかを聞き、課税免除の数を数える
- 施設ごとに宿泊数と税額を合計し、納入申告書を作って提出し、納入する
- 人経理課が、月の2日に前の月の精算データのCSVを決まったフォルダに置く
- 自動毎月3日の朝、Apps Script がCSVを読み、予約を宿泊日ごとの行に分ける
- 自動プランの表から食事代を引き、人数で割って1人1泊の宿泊料金と税額を規則で出す
- 自動境目に近い金額、食事代の設定が無いプラン、値引の行がある予約などを規則で拾う
- 自動拾った予約のプラン名・備考・支払の内訳を Claude API に渡す
- 自動Claude API が、確認が要る理由と根拠の文字列を JSON で返す
- 自動施設ごとの集計と確認の一覧をシートに書き、経理課とフロントに知らせる
- 人フロントが、証明書の受領と食事代の内訳を確かめて一覧に書き込む
- 人経理課が、確認の結果で再計算し、納入申告書の数字を確かめて提出する
各工程の詳しい説明を読む
- 経理課が、前の月の精算データを施設ごとに書き出す
- 予約ごとに、プラン名を見て食事代を引くか、サービス料を足すかを決める
- 人数と泊数で割り、1人1泊の宿泊料金を出して区分に当てはめる
- 月をまたぐ連泊は、宿泊日ごとに分けて月に振り分ける
- 予約サイトのポイント、旅行会社の割引、無料招待などを備考から探して直す
- 修学旅行の団体は、フロントに証明書を受け取ったかを聞き、課税免除の数を数える
- 施設ごとに宿泊数と税額を合計し、納入申告書を作って提出し、納入する
(a)食事代の除き方が予約ごとに違う。 京都市の手引では、料金に食事代が含まれている場合は、食事代に相当する金額を除いた額を宿泊料金とするとされています。プランごとに食事代の額が設定されていれば機械的に引けますが、予約サイト独自のプランや旅行会社の企画では、食事代の内訳が精算データに無いことがあります。 経理はそのたびにフロントに聞いています。
(b)割引の扱いが、誰の割引かで変わる。 手引では、施設の経営者自らのサービスによる割引は割引後の料金を、予約サイトのポイントなど経営者自らのサービス以外の割引は割引前の料金を宿泊料金とするとされています。精算データでは、どちらも「値引」の1行に見えます。備考や支払の内訳を読まないと区別できません。
(c)修学旅行の証明書が抜ける。 手引では、修学旅行生等を課税免除とするには、学校等が作成した「修学旅行等であることの証明書」を受領することが必要で、施設で7年間保存するとされています。フロントが受け取り忘れたまま課税免除で集計すると、免除の根拠が無い申告になります。
(d)期限が月末にある。 京都市のページでは、特別徴収義務者は原則として毎翌月末日までに納入申告書を提出し、納入するとされています。月初は精算の締めと重なり、宿泊税の確認は後回しになって、月の後半に詰まります。
- 【人】 経理課が、月の2日に前の月の精算データのCSVを決まったフォルダに置く
- 【自動】 毎月3日の朝、Apps Script がCSVを読み、予約を宿泊日ごとの行に分ける
- 【自動】 プランの表から食事代を引き、人数で割って1人1泊の宿泊料金と税額を規則で出す
- 【自動】 境目に近い金額、食事代の設定が無いプラン、値引の行がある予約などを規則で拾う
- 【自動】 拾った予約のプラン名・備考・支払の内訳を Claude API に渡す
- 【自動】 Claude API が、確認が要る理由と根拠の文字列を JSON で返す
- 【自動】 施設ごとの集計と確認の一覧をシートに書き、経理課とフロントに知らせる
- 【人】 フロントが、証明書の受領と食事代の内訳を確かめて一覧に書き込む
- 【人】 経理課が、確認の結果で再計算し、納入申告書の数字を確かめて提出する
9番目が、この設計の分かれ目です。 確認の一覧にある予約は、人が扱いを決めるまで、申告の数字に確定させません。 規則が仮置きした税額と、確認後の税額を並べて持ち、差のあった予約が分かるようにします。
3番目と4番目を規則で行うのは、税額が式で決まるからです。 AIに税額を出させると、区分の境目で1つずれたときに説明がつきません。AIは「この予約は規則どおりに計算してよいか」を判定するだけです。
02今回想定するシステム構成
予約管理システムの精算データCSV(施設ごと) │ 経理課が月の2日に決まったフォルダへ置く ▼【トリガー】毎月3日 7時台(時間主導型) Google Apps Script ├──▶ CSVの読み込み(文字コードを指定)と宿泊日ごとの分割 ├──▶ プランの表で食事代を除き、1人1泊の宿泊料金と税額を計算 ├──▶ 規則による検出(境目/食事代の設定なし/値引/団体/デイユース) ├──▶ Claude API(構造化出力) │ プラン名・備考・支払の内訳 → 確認が要る理由と根拠 ├──▶ 集計と確認の一覧のシートに書く └──▶ MailApp で経理課とフロントに知らせる ▼ 【フロントが証明書と食事代を確かめ、経理課が確定する】 ▼ 納入申告書の作成・提出、徴収原簿の保存
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Google Apps Script | Power Automate、Make、Python |
| 生成AI | Claude API(構造化出力) | OpenAI API、Gemini API |
| 保管 | Google スプレッドシート(宿泊日ごとの計算、プランの表、集計、確認の一覧)とドライブ(精算データのCSV) | - |
| 通知 | Gmail(MailApp) | Google Chat |
新しく足すのは、Apps Script と、プランの表・集計・確認の一覧のシートだけです。 予約管理システムと会計システムにはつなぎません。精算データは書き出したCSVを置くだけにし、申告の数字は人が納入申告書に写します。
Apps Script は、集計のスプレッドシートに付けるスクリプトとして書きます。 CSVの読み込みには、公式のリファレンスにある Utilities.parseCsv()(CSVの文字列を2次元の配列にする)と、Blob の getDataAsString(charset)(指定した文字コードで文字列にする)を使います。予約管理システムの書き出しが Shift_JIS のときは、文字コードを指定しないと備考が文字化けします。 備考が化ければ、AIは何も判定できません。
インストール型のトリガーは、作った人のアカウントで動き、メールもその人のアカウントから送られると公式のページにあります。経理課の共有のアカウントで作ります。
AIの処理は Claude API の構造化出力で行います。 公式のページでは、output_config.format に type: "json_schema" とスキーマを渡すと、スキーマに沿った JSON が返るとされています。オブジェクトには additionalProperties: false が必要で、enum と required が使えます。Anthropic のページでは、API などの商用の製品では、既定で入力と出力をモデルの学習に使わないとされています。
03どうやって実装するのか
処理の起点を決める
集計は、毎月3日の7時台に動く時間主導型のトリガーを起点にします。 公式のページでは、時間主導型のトリガーの時刻は少しずれることがあり、9時に設定すると9時から10時のあいだで選ばれ、その時刻が保たれるとされています。経理課の始業までに一覧ができていれば足ります。
3日にするのは、月末のチェックアウトの精算がそろうのを待つためです。 月末日に泊まった客の精算は翌月1日に入ります。経理課は2日にCSVを置き、置き終えたらフォルダに「置いた」の印のファイルを作ります。 スクリプトは最初にこの印を見て、無ければ集計をせずに経理課へ知らせます。
対象は「宿泊日」で決めます。 手引では、月をまたぐ連泊は宿泊行為のあった月ごとに分けて申告するとされています。CSVはチェックアウトの日で書き出されることが多いので、前の月と前々月のチェックアウトの分をあわせて読み、宿泊日が前の月の行だけを集計します。 前の月の末日に泊まって翌月にチェックアウトした客は、翌月のCSVに入るので、3日の集計とは別に、翌月の10日にその分だけを追加で拾う手動の実行を用意します。
再集計はメニューから行います。 フロントが確認の結果を書き込んだら、経理課が「前月を再集計」を実行します。再集計ではAIを呼ばず、規則の計算だけをやり直します。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 精算データ | 予約番号、施設、チェックイン・アウト日、宿泊日ごとの人数、室料、サービス料、食事代、値引、支払の内訳、プラン名、予約経路 | 予約管理システムのCSV |
| 予約の備考 | フロントと予約サイトの備考(団体名、学校名、延長、招待など) | 同じCSVの備考の列 |
| プランの表 | プランごとの食事代に相当する額、サービス料の有無 | プランの表のシート |
| 経路の表 | 予約経路ごとの、ポイントと割引の扱い(経営者自らの割引か、それ以外か) | 経路の表のシート |
| 証明書の受領簿 | 予約番号、受領日、生徒・引率者の人数 | 受領簿のシート(フロントが記入) |
| 税率の表 | 適用開始日ごとの区分と税額 | 税率の表のシート |
質を決めるのは、プランの表と経路の表です。 食事代に相当する額がプランごとに決まっていれば、食事込みのプランも規則で計算できます。予約サイトのポイントを「経営者自らのサービス以外」とする扱いも、経路の表に書いておけば、規則がそのまま割引前の料金を使います。 AIの出番は、表で決まらない予約だけに絞られます。
税率の表に適用開始日を持たせるのは、改定をまたぐためです。 手引では、宿泊税は宿泊日ごとに算定し、改定日の前から泊まり始めた客でも、改定日以後の宿泊分には新しい税率を当てるとされています。
宿泊者の名前は使いません。 必要なのは人数と金額とプラン名、備考だけです。CSVを書き出すときに、氏名・電話番号・メールアドレスの列を外す設定にします。
データの取得方法を決める
| 取るもの | どこから | どう取るか |
|---|---|---|
| 精算データ | ドライブのフォルダ | DriveApp でファイルを開き、getBlob().getDataAsString('Shift_JIS') で読んで Utilities.parseCsv() にかける |
| プラン・経路・税率の表 | 各シート | getValues() でまとめて読む |
| 証明書の受領簿 | 受領簿のシート | 予約番号で引く |
処理は、次の順で行います。
1. 精算データを宿泊日ごとの行に分ける(宿泊日、人数、その日の室料)
2. プランの表で食事代を除き、サービス料を足して、その日の宿泊料金を出す
3. 経路の表で、値引を「割引後で計算」か「割引前で計算」かに振り分ける
4. 宿泊料金をその日の人数で割り、1人1泊の金額を出す
5. 税率の表で区分を引き、税額 = 区分の額 × 人数 を出す
6. 規則で検出する
R1 食事込みのプランなのに、プランの表に食事代の額が無い
R2 値引の行があり、経路の表で扱いが決まらない
R3 予約経路が団体、または備考に「修学旅行」「学校」「園」の語がある
R4 1人1泊の金額が区分の境目の±3%以内
R5 宿泊料金が0円、または泊数が0(デイユース・無料招待・不泊の疑い)
R6 エキストラベッド・ベビーベッドの行がある
7. R1〜R6 の予約のプラン名・備考・支払の内訳を Claude API に渡す
8. 施設ごとに、宿泊数と税額を区分別に集計し、確認の一覧とあわせて書く
5番目の計算は、手引の計算例と同じ形です。 たとえば1室1泊50,000円のツインに2人で泊まれば、50,000÷2=25,000円で、1人1,000円の区分に入り、宿泊税は2,000円です。
R6 を拾うのは、手引の計算例で扱いが分かれるからです。 エキストラベッドの追加料金は特定の宿泊者に帰属しないので総額に足し、ベビーベッド代は乳児に帰属するので乳児を別に扱うとされています。どちらの行かは、精算データの品目名だけでは決まらないことがあります。
AIへ渡す前に整形する
- 文字コードを確かめる … 備考の列に「�」が混ざっていれば、文字コードを取り違えています。集計をせずに経理課に知らせます
- 個人を表す列を落とす … 氏名・電話・メールの列が残っていれば、読み込みの段で捨てます
- 予約番号を記号に置き換えない … フロントが調べるのに要るので残します。AIに渡すのも予約番号までです
- 数字は規則で計算したものを渡す … その日の宿泊料金、1人1泊の金額、仮の税額はスクリプトで出した値を渡し、AIに計算させません
- 備考に番号を振る … 「B-0412」のように備考の文ごとに番号を付け、AIには根拠をこの番号で返させます
4番目は、第5章で書いたとおり、税額を式に置くためです。 AIに渡すと、「食事代はおよそ5,000円と考えられるので」と推定の金額で計算し直します。 推定で引いた食事代で申告すれば、根拠の無い申告になります。
AIに処理させる
させるのは、規則が拾った予約について、「規則どおりに計算してよいか、人が確かめる点があるか」を判定し、確かめる点の種類と根拠の文字列を返すことです。
| 見るもの | 判定すること | 例 |
|---|---|---|
| プラン名と食事の行 | 食事代の除外が要るのに額が決まっていないか | 「京懐石と朝食付き 旅行会社企画」で食事の行が無い → meal_amount_unknown |
| 値引・ポイントの記述 | 誰の割引か、備考から読み取れるか | 「予約サイトポイント 5,000円利用」 → third_party_discount |
| 団体・学校の記述 | 課税免除の確認が要るか | 「〇〇中学校 修学旅行 生徒80 引率6 添乗1」 → school_trip_check |
| 0円・短時間の記述 | 課税対象の宿泊かの確認が要るか | 「デイユース 10-16時」 → not_stay_check |
| 延長の記述 | 延長料金を含めるかの確認が要るか | 「レイトアウト 3,000円」 → extension_check |
区分は、経理課が決めた語彙から選ばせます。 上の5つに、寝具の追加(bedding_check)、大使館などの免除の可能性(diplomat_check)、確認の要らないもの(no_issue)を足した8つです。区分ごとにフロントへの問い合わせの文面を決めておけば、確認の一覧からそのまま聞けます。
| させないこと | 理由 |
|---|---|
| 税額・宿泊料金の計算 | 規則と表で決まる |
| 食事代の額の推定 | 推定の額では申告の根拠にならない |
| 課税免除に当たるかの結論 | 学校等が作った証明書の受領で決まる |
| 添乗員・カメラマンを引率者に数える | 手引で引率者に当たらないとされている |
| 課税対象の宿泊かの結論 | 契約上の扱いと利用の時間で、施設が決める |
3行目が、この構成でいちばん守るべきことです。 備考に「修学旅行」とあれば、AIは課税免除と書きたくなります。しかし免除の要件は、証明書を受け取っていることです。 AIには school_trip_check とだけ返させ、証明書の受領簿と突き合わせるのは規則、受け取っていなければフロントが学校に依頼します。
指示内容を固定する
あなたは京都市内の宿泊施設の経理担当として、宿泊税の申告の前に、
予約ごとの宿泊料金の扱いに確認が要る点があるかを判定する立場です。
税額は計算しません。課税免除に当たるかの結論も出しません。
【入力】
- 予約番号、施設、宿泊日、その日の人数、プラン名、予約経路
- その日の宿泊料金・1人1泊の金額・仮の税額(計算済み)
- 精算の明細(品目名と金額)、支払の内訳
- 予約の備考(note_id 付き)
- 規則で立った印(R1〜R6)
【してほしいこと】
1. 規則どおりに計算してよいか、人が確かめる点があるかを判定する
2. 確かめる点があれば、次の区分から1つ以上を選ぶ
meal_amount_unknown / third_party_discount / school_trip_check /
not_stay_check / extension_check / bedding_check /
diplomat_check / no_issue
3. 各区分に、根拠にした note_id か明細の品目名を必ず付ける
4. school_trip_check のときは、備考に書かれた生徒・引率者・
添乗員などの人数を、書かれているとおりに写す
【厳守事項】
- 食事代の額を推定しないでください。額が明細に無ければ
meal_amount_unknown とだけ返してください。
- 金額を計算し直したり、丸めたりしないでください。
- 「課税免除に当たる」「課税対象外である」と書かないでください。
- 旅行業者の添乗員やカメラマンを引率者に含めないでください。
備考で役割が分からない大人は role_unknown として人数だけ写してください。
- 根拠の note_id か品目名を付けられない区分は返さないでください。
- 宿泊者の個人についての記述を書かないでください。
【予約】{booking_json}
【経路の表】{channel_table}
「食事代の額を推定しない」を最初に置いているのは、第7章の前処理の4番目で書いた事故を止めるためです。 禁じないと、AIは親切に「一般的な夕食の相場から」と額を置きます。返し方として meal_amount_unknown を用意しておけば、推定する理由が無くなります。
role_unknown を用意しているのも同じ考えです。 備考に「大人8」とだけあると、AIは引率者と添乗員を推し量って分けます。分からないものは分からないと返せる欄があれば、推し量りは止まります。
出力形式を固定する
構造化出力で、次の形の JSON を受け取ります。
{
"booking_no": "",
"stay_date": "",
"checks": [
{ "category": "meal_amount_unknown | third_party_discount | school_trip_check | not_stay_check | extension_check | bedding_check | diplomat_check | no_issue",
"evidence": [""],
"summary": "" }
],
"group_counts": {
"students": null, "chaperones": null, "tour_staff": null, "role_unknown": null
}
}
スキーマでは category を enum で縛り、オブジェクトに additionalProperties: false を付けます。evidence に入った note_id や品目名が、渡した予約に本当にあるかは、受け取ったあとにスクリプトで確かめます。 無いものは落とし、経理課に知らせます。
理由の1つ目は、税額とAIの判定を別の層に置けることです。 税額は規則が宿泊日ごとの行に書き、AIの JSON には金額を返させません。申告書の数字は、規則の列と、人が確定した列からだけ作ります。
2つ目は、group_counts を証明書の受領簿と突き合わせられることです。 備考の生徒と引率者の数を、受領簿の人数と比べ、合わなければ確認の一覧に「人数の差」と出します。 証明書が無ければ、免除の数は0のまま集計します。
確認の一覧は、フロントが読めば何を確かめればよいか分かる形にします。
【10月分 宿泊税の確認(ホテル:確認12件・うち修学旅行3件)】
■ R-24-1187 10/14 2名 プラン「秋の京都 旅行会社企画」
確認:食事代の額が明細にありません(meal_amount_unknown)
仮の計算:1人1泊 19,500円 → 400円×2名(境目に近い)
■ R-24-1203 10/21〜22 生徒80・引率6・添乗1 〇〇中学校
確認:修学旅行の証明書が受領簿にありません(school_trip_check)
仮の計算:免除0名として集計中
※ 確認の結果を一覧の「確認結果」に書き込んでください。月の20日までにお願いします。 システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| ドライブのフォルダ | DriveApp(読み取り) | 精算データのCSV |
| プラン・経路・税率の表、受領簿 | SpreadsheetApp(読み取り) | 食事代、割引の扱い、区分、証明書 |
| Claude API | UrlFetchApp | 確認が要る点の JSON |
| 集計・確認の一覧のシート | SpreadsheetApp(書き込み) | 宿泊日ごとの計算、施設ごとの区分別の集計、確認の一覧 |
| Gmail | MailApp | 経理課とフロントへの知らせ |
API キーはスクリプトのプロパティに置き、スクリプトの編集の権限は経理課の数名に絞ります。 公式の割り当てでは、1回の実行は6分まで、URL Fetch の呼び出しは Google Workspace のアカウントで1日10万回です。AIを呼ぶのは R1〜R6 の予約だけで、月600件のうち1〜2割、100件前後です。6分を超えそうなときは、終わった予約番号を記録して、続きのトリガーで残りを処理します。
予約管理システムと会計システムには書き込みません。 納入申告書は、経理課が集計のシートの数字を写して作ります。申告の数字を人が写す1手間を残すのは、確定していない予約が混ざったまま申告しないためです。
人が確認する
- フロントが確認の一覧を見る … 食事代の内訳を旅行会社に聞く、証明書を学校に依頼する、デイユースか宿泊かを契約で確かめる
- 確認結果を書き込む … 食事代の額、証明書の受領日と人数、課税対象かどうかを、一覧の決まった列に書きます
- 経理課が再集計する … 規則が確認結果を使って計算し直し、仮の税額と確定の税額の差を出します
- 経理課が申告書を作る … 確認の一覧に未記入が残っていないことを確かめてから、施設ごとの合計を納入申告書に写します
4番目の「未記入が残っていない」は、スクリプトが数えます。 未記入があるうちは、集計のシートの合計欄に「未確定あり」と出します。
目標は、600件をならして1件1分です。 規則だけで済む予約は合計の確認で流れ、確認の一覧の予約はフロントとのやり取りで数分かかります。確認の一覧が多い月は、プランの表に食事代の額が足りていない合図です。
例外に対処する
| 起きること | 対応 |
|---|---|
| 印のファイルが無い | 集計をせず、経理課に知らせる |
| 備考が文字化けしている | 文字コードの取り違え。集計をせずに知らせる |
| プランの表に無いプラン名 | unknown_plan として一覧に載せ、経理課がプランの表に足す |
| 改定日をまたぐ連泊 | 宿泊日ごとに税率の表の適用開始日で区分を引く |
| 月をまたぐ連泊 | 宿泊日で月を決め、翌月チェックアウトの分は翌月10日の追加の実行で拾う |
| Claude API が応答しない・形が違う | 一度だけやり直し、だめなら印だけで確認の一覧に載せる |
| 返った根拠が渡した予約に無い | その区分を落とし、経理課に知らせる |
| キャンセル・不泊の行 | 宿泊日の行を作らず、一覧の末尾に件数だけ載せる |
5行目を省かないでください。 月末日の宿泊を落とすと、その月の申告が少なく、翌月が多くなります。 施設の合計は年で見れば合いますが、月ごとの申告としては誤りです。
記録を残す
- 宿泊日ごとの計算の行(宿泊料金、1人1泊の金額、区分、税額、適用した税率の表の版)
- 仮の税額と確定の税額、その差と確認結果
- AIに渡した予約番号と、返った JSON の全文
- 証明書の受領簿との突き合わせの結果
- 施設ごとの月の集計と、納入申告書に写した数字
手引では、徴収原簿を7年間保存する必要があるとされ、必要事項が記載されていれば任意の様式でよいとされています。宿泊日ごとの計算の行に手引の記載事項がそろうように列を設計しておけば、集計のシートをそのまま徴収原簿として残せます。 どの列を記載事項に当てるかは、手引の様式と見比べて経理課が決めます。
04実装レベルの3段階
最小構成では、計算は手のままです。 どの予約に手がかかっているかを確かめる段階です。 半自動化で1件3分が1分になり、この段階が本記事の想定です。 計算(①)は規則になり、備考を読む作業(②)は確認の一覧を見る作業に、フロントへの問い合わせ(③)は一覧に書かれた点だけを聞く作業になります。 本格構成は、確認の一覧の区分が安定してから考えます。 修学旅行の予約が入った時点で証明書を依頼できれば、月末の前に受領簿がそろいます。
05工数削減シミュレーション
導入後 600件 × 1分 ÷ 60 = 10 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 京都市など宿泊税のある自治体で、旅館・ホテル・簡易宿所を1〜数施設運営し、月に数百件の予約を精算している会社。予約管理システムから精算データをCSVで書き出せ、宿泊税の計算を経理が表計算で手作業で行っている場合。食事付きのプラン、連泊割引、予約サイトのポイント利用、修学旅行の団体が混ざり、1人1泊の宿泊料金の出し方が予約ごとに違う場合。Google Workspace を使っている場合。
- 予約管理システムが宿泊税の区分ごとの計算と徴収原簿の出力まで済ませており、経理は合計を写すだけの場合。素泊まりの単一料金だけで、プランや割引が無い場合。月の予約が数十件で、目で見て足りる場合。なお、課税の対象になるか、課税免除に当たるかの最終的な判断と申告の内容の責任は、特別徴収義務者にあります。この構成はそれを代替しません。
07最小構成で試す方法
- 先月の予約から、経理課が手で直した予約を20件選ぶ(食事込みの団体、ポイント利用、修学旅行を含める)
- 20件のプラン名・明細・備考を、氏名を外して書き出す
- 手元の Claude の画面に貼り、第7章の指示の要点(食事代を推定しない、免除の結論を書かない、根拠を付ける)を伝える
- 出てきた区分を、経理課が実際に直した内容と突き合わせる
ここで見るのは、区分の当たり方と、推定の有無です。 経理課が直した予約に同じ区分が付き、食事代の額を推定していなければ、構成は有効です。
| 出てきた内容 | 判断 |
|---|---|
| 経理課が直した点と同じ区分が、根拠付きで出た | Apps Script で計算とつなぐ段階に進む |
| 食事代の額を推定して書いた | 指示の書き方で直る。返し方を用意する |
備考が短く、ほとんど no_issue になった | フロントの備考の書き方が先。 AIの問題ではない |
3行目が出たら、団体と割引の備考に書く語を決めます。 「修学旅行」「ポイント利用」「招待」のような語をフロントでそろえるだけで、規則でも拾えるようになります。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| AIが食事代の額を推定して書く | meal_amount_unknown という返し方を用意し、推定を禁じる |
| 修学旅行を備考だけで免除にする | 免除は証明書の受領簿で決める。 AIには確認の印だけを返させる |
| 添乗員・カメラマンを引率者に数える | 手引の記載どおり引率者に含めない。役割の分からない大人は role_unknown |
| 予約サイトのポイントを割引後で計算する | 経路の表で「経営者自らのサービス以外」と決め、割引前の料金を使う |
| 月末日の宿泊が翌月にずれる | 宿泊日で月を決め、翌月チェックアウトの分を追加で拾う |
| 改定日をまたぐ連泊で旧税率を当てる | 税率の表に適用開始日を持たせ、宿泊日ごとに引く |
| CSVの備考が文字化けする | 文字コードを指定して読み、化けを検出したら止める |
| 未確定の予約が混ざったまま申告する | 未記入を数え、合計欄に「未確定あり」と出す |
| 氏名がAIに渡る | 書き出しの設定と読み込みの段の両方で列を落とす |
上の2行が、申告の根拠に関わります。 推定の食事代で計算した税額も、証明書の無い免除も、数字としてはもっともらしく見えるので、誰も気づきません。 どちらも、AIに結論を出させない返し方で防ぎます。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 予約番号、宿泊日、人数、料金と明細、支払の内訳、予約の備考(団体名・学校名、宿泊者の事情が書かれることがある)です。
- 氏名と連絡先をAIに渡さない … 判定に要るのは人数と金額と備考です。書き出しの設定で列を外し、読み込みの段でも捨てます
- 備考に個人の事情が書かれていれば渡さない … 「アレルギー」「車いす」のような記述は、宿泊税の判定に要りません。備考の語で落とす一覧を経理課が持ちます
- 修学旅行の団体の情報を広げない … 生徒の個人の情報は扱いません。学校名と人数だけです
- 課税の判断を一覧に任せない … 課税対象か、免除に当たるかは、手引と証明書に照らして特別徴収義務者が決めます。分からないものは京都市の宿泊税の担当に問い合わせます
- 商用の API で使う … Anthropic のページでは、API などの商用の製品では既定で入力と出力を学習に使わないとされています。個人の契約の画面に精算データを貼らないことを決めておきます
- API キーの管理 … スクリプトのプロパティに置き、編集の権限を経理課の数名に絞ります
誤りが起きた場合のリスクは、少なく申告することと、多く徴収してしまうことの2つです。 前者は免除や割引の扱いを根拠なく適用すると起き、後者は食事代を除き忘れると起きます。どちらも、表と規則で計算し、AIには確認が要る予約を拾わせるだけにすることで防ぎます。
10まず何から始めるか
1週目:プランの表と経路の表を作る
施設のプランごとに、食事代に相当する額とサービス料の有無を書き出します。予約経路ごとに、ポイントと割引が「経営者自らのサービス」か「それ以外」かを、手引の事例と見比べて決めます。決められない経路は、京都市の宿泊税の担当に問い合わせます。
2週目:20件で試す
先月の手で直した予約20件を、氏名を外して手元の Claude の画面に貼り、区分を出させます。食事代の額を推定していないか、免除の結論を書いていないかを最優先で見ます。
3週目:受領簿と備考の書き方を決める
フロントと、修学旅行の証明書の受領簿の列と、団体・割引・招待の備考に書く語を決めます。受領簿は宿泊の当日までに埋める決まりにします。
4週目:計算と集計までを作る
Apps Script で、CSVの読み込み、宿泊日ごとの分割、表による計算、R1〜R6 の検出、施設ごとの集計までを作ります。この時点ではAIを呼ばず、規則の印だけの確認の一覧で1か月回します。
2か月目: Claude API の呼び出しと根拠の照合、フロントへの知らせを足します。3か月目以降: 確認の一覧の区分ごとの件数を数え、表に足すべきプランと経路を見直します。確認の一覧が月の20日までに埋まり、未確定なしで申告書を作れるようになった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
| 京都市の宿泊税の税率(令和8年3月1日以降、宿泊料金の区分ごとに200円・400円・1,000円・4,000円・10,000円)。宿泊料金は素泊まり料金(室料及びサービス料)で食事代や消費税等を含まないこと。修学旅行その他学校行事の児童・生徒等とその引率者などが課税免除であること。特別徴収義務者が原則として毎翌月末日までに納入申告書を提出し納入すること | 京都市: 宿泊税について | 2026-10-12 |
| 令和8年3月以降の宿泊分は新様式の納入申告書で申告すること。徴収原簿は提出不要だが7年間保存が必要で任意の様式でよいこと。修学旅行等であることの証明書は学校等が作成し宿泊施設に提出するもので市への提出は不要なこと | 京都市: 宿泊税に関する手引・申告書等の様式 | 2026-10-12 |
| 宿泊料金に含まないもの(食事代、消費税等、立替金など)。食事込みのプランは食事代相当額を除くこと。経営者自らの割引は割引後、予約サイトのポイントなどそれ以外は割引前の料金とすること。連泊の人数・割引の扱い。エキストラベッドとベビーベッドの計算例。キャンセル・不泊・デイユースが課税対象とならない事例。証明書の受領と7年間の保存。添乗員やカメラマンが引率者に当たらないこと。月をまたぐ連泊は宿泊月ごとに申告すること。改定日以後の宿泊分には新税率を適用すること | 京都市: 特別徴収の手引(令和8年3月1日以降) | 2026-10-12 |
| インストール型のトリガーが作った人のアカウントで動き、メールもその人から送られること。時間主導型のトリガーの時刻のずれ | Google Apps Script: Installable Triggers | 2026-10-12 |
| 1回の実行が6分まで、URL Fetch が Google Workspace で1日10万回であること | Google Apps Script: Quotas for Google Services | 2026-10-12 |
Utilities.parseCsv() がCSVの文字列を2次元の配列にすること | Google Apps Script: Class Utilities | 2026-10-12 |
getDataAsString(charset) が指定した文字コードで文字列を返すこと | Google Apps Script: Class Blob | 2026-10-12 |
output_config.format に type: "json_schema" を指定すると JSON で返ること。オブジェクトに additionalProperties: false が必要で、enum・required が使えること | Claude API: Structured outputs | 2026-10-12 |
| API などの商用の製品では既定で入力と出力を学習に使わないこと | Anthropic Privacy Center: Is my data used for model training? | 2026-10-12 |
課税の対象・課税免除・宿泊料金の扱いで迷うものは、施設の所在地の自治体の宿泊税の担当に確かめてください。 本記事は京都市の公式のページと手引で確認できた範囲だけを扱っています。宿泊税の税率や免除の範囲は自治体ごとに違います。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1272)についてのご相談はこちらから。
