AI活用

生成AIでシフト表は作れるのか

ChatGPTに勤務表を頼むと、それらしい表は返ってきます。でも直したそばから別のところが崩れる。なぜこうなるのかを仕組みから説明し、では生成AIをどこに使えばいいのかまで整理します。

公開日:

「ChatGPTでシフト表も作れるんじゃないか」

一度は考えたことがあるのではないでしょうか。

わたしたちも、「生成AIでシフト表を作ってみたが、うまくいかなかった」というご相談を、お客様から実際にたびたびいただきます。試したうえで壁に当たっている方が、それだけ多いということだと思います。

この記事の結論

生成AIはそれらしい勤務表を書くことはできますが、「条件を1つも破っていない」ことを保証する仕組みを持っていません。これは性能の問題ではなく、道具の性質です。

ただし「シフト作成にAIは使えない」という話ではありません。勤務表を組むのは別の技術の仕事で、生成AIはその手前と後ろで効きます。この切り分けを説明します。

まず「どのAI」の話かを分ける

「AIでシフトが作れる」という記事を読むとき、その「AI」が何を指しているかは、実はバラバラです。

この記事で生成AIと呼ぶのは、ChatGPT・Claude・Geminiのように、話しかけると文章を書いて返してくるものです。これとは別に、条件を解く仕組み(正式には数理最適化と呼ばれ、その計算プログラムをソルバーと言います)という、まったく違う技術があります。

この2つは中身も得意なことも別物です。そして勤務表を組むのは、後者の仕事です。この区別が付くと、あとの話はすんなり読めると思います。

実際に試した人は、どこで詰まっているか

生成AIに勤務表を頼んだ人の報告を読むと、詰まり方がかなり似ています。

もぐらたたきになる。 ある方は「土曜なのに日曜と表示される」「出社できない日に割り当てられる」「誰も出勤しない土日ができる」「特定の人ばかり連続で出勤する」と挙げたうえで、こう書いています。指摘した箇所が直ったら、新たに他の箇所が間違っている。その繰り返しだ、と(Yahoo!知恵袋の相談 — もぐらたたきの報告)。

数字が合わない。 看護師の方によるQiitaの検証記事では、看護師25名・1か月・夜勤は毎日2人必須・6連勤以上禁止という同じ条件を4つの生成AI(ChatGPT や Claude など)に与えています。結果は、制約を多数破るもの、最長22連勤が発生するもの、そして表の下にある集計欄(夜勤回数など)が、表の中身と食い違うものがありました。

一枚も出てこないこともある。 師長の手作業を減らそうとして、生成AIにプログラムを書かせてソルバーを回したものの、毎回「解無し」になった、という病院職員の相談も実在します(Yahoo!知恵袋の相談 — 毎回「解無し」になる)。これは後半でもう一度触れます。

共通しているのは、見た目は勤務表なのに、中身がルールを守っていないということです。しかも体裁は完璧なので、気づくのが遅れます。

なぜこうなるのか — 作文とパズルの違い

勤務表は文章ではなくパズル

文章は前から順に書けば完成します。一方、勤務表は1マス決めた瞬間に、他のマスの選択肢が変わります

たとえば「Aさんを3日の夜勤に入れる」と決めると、その瞬間に4つのことが同時に起きます。

Aさんを 3日の夜勤に入れる
Aさんの4日の枠が消える
(夜勤明けに日勤は入れられない)
Aさんの今月の夜勤回数が1つ埋まる
3日に必要な夜勤の人数が1人減る
Aさんの連続勤務日数が1日伸びる

1マスが4方向に効いている。師長が毎月、頭の中と消しゴムでやっているのは、この波及を追いかける作業です。

生成AIは、書きながら全体を照らし合わせていない

生成AIは、大量の文章を学習して「次に来る言葉として自然なもの」を選び続け、左から右へ書いていく仕組みで動いています。

この仕組みには、書き終えた表が全部のルールを満たしているかを、書きながら全体に照らして確かめる機構がありません。「夜勤の翌日は休みが多い」というパターンは学習しているので、たいていの箇所はそれらしく埋まります。でも「20人全員について、31日ぶん、すべての条件を同時に」という確認は、どこでも行われていないのです。

これは数独に少し似ています。1マスずつ「ここには何が入りそうか」で埋めていくと、行や列で同じ数字が重なる。全体を見ないと、成立しているかどうかは判定できません。

(ただし数独の比喩はここまでです。数独は正解が1つに決まりますが、勤務表は成立する組み方が無数にあり、その中に良し悪しがあります。また数独に矛盾した問題は出ませんが、勤務表では最初から成立しない条件が持ち込まれることが普通にあります。この2点はあとで効いてきます。)

「もう一度チェックして」では直らない

ここで当然、「じゃあ見直させればいいのでは」と思われるはずです。

これについては研究の報告があります。生成AI自身に自分の答えを点検させると成績はむしろ落ち、外部に別の検証の仕組みを置くと大きく上がった、というものです(Kaya Stechly, Karthik Valmeekam, Subbarao Kambhampati「On the Self-Verification Limitations of Large Language Models on Reasoning and Planning Tasks」arXiv:2402.08115)。

自分の書いたものを自分で確かめる、というやり方がそもそも効きにくい。だから「チェックして」を繰り返しても、もぐらたたきから抜けられません。

とはいえ「絶対に作れない」わけではない

正直に書いておきます。小さい規模で条件がゆるければ、そこそこの表は出ます

7名・1か月・各人の都合が悪い日が2〜3日、といった条件で「ほぼ修正不要だった」という報告もあります(「ほぼ修正不要」と報告する note の記事。ただしこの記事に、条件を守れているかを検証した結果は書かれていません)。訪問看護師の方の報告では、希望を考慮した表が10〜30秒で出たと評価しつつ、「結果は必ずしも完璧ではなく、人間の判断と調整がまだ必要」と結ばれています。

崩れ始めるのは、人数が増えて、条件どうしが衝突しはじめてからです。そして病棟の勤務表は、たいていその領域にあります。

条件を解く仕組み(ソルバー)は何が違うのか

では、専用の道具は何をしているのでしょうか。

「必ず守る条件」と「できれば守る条件」を分けている

ソルバーは条件を2種類に分けて扱います。絶対に破ってはいけない条件(1人が1日に2つの勤務に入らない、など)と、できれば叶えたい条件(本人の希望休、公平さ)です。

これは、現場の人が毎月やっている判断そのものです。全員の希望を100%通すと成立しないから、誰かの希望を少し削って全体を成り立たせる。あの判断を、道具の側に設計として持たせています。

先ほどの「毎回解無しになった」という相談に、こういう回答が付いていました。ソルバーは全条件を100%満たす解を探すが、人間は誰かの希望を削って全体のバランスを取る。ソルバーはこの妥協を知らない、と。つまり、この2種類の分け方を設定していないと、道具が強力でも一枚も出てこないのです

「この条件では組めません」を答えとして返せる

ここが決定的な違いです。

ソルバーは、条件を満たす組み合わせが存在しないこと自体を確かめて返せます。(正式にはINFEASIBLEと呼ばれる状態です。)時間内に解ききれなかった場合とも区別されます。

生成AIにはこの機構がないので、組めない条件を渡されても、代わりに「それらしい表」を出してきます。組めないことに気づけないまま配ってしまう。これが実務では一番怖いところです。

「組めない」と分かれば、ではどの条件を緩めるかという、本来考えるべき話に進めます。

ただし、万能ではない

時間内に解ききれないこともありますし、条件が本当に矛盾していて組めないこともあります。ただその2つは区別して返ってきます

なお「勤務表づくりは難しい問題だ」というのは、感覚ではなく証明されています。勤務区分が3種類+休みだけの極小の設定でも、必要人数と休み希望と禁止される勤務の並びが入るだけで、計算量的に難しい問題(強い意味でNP困難)になります(Steven J. M. den Hartog, Han Hoogeveen, Tom C. van der Zanden「On the complexity of Nurse Rostering problemsOperations Research Letters 51(5), 2023, pp.483-487)。ただしこれは最悪の場合の話であって、現実の1か月分が解けないという意味ではありません。実際、勤務表は日常的にソルバーで解かれています。

うまくいっている報告に共通するのは「表を書かせない」こと

生成AIでの成功報告をよく読むと、共通点があります。チャット欄に表を書かせていないのです。

たとえば、集めた希望をCSVにして、生成AIにプログラムを書かせて実行させたという当番表をプログラムで作った事例があります。この方法では「全員最大4回」「間隔2日以上」「担当回数が最少の人を優先」といった条件を満たした当番表ができています。

つまり、生成AIの得意側は条件を整理して形にすることで、苦手側は膨大な組み合わせを探すことなのです。研究の評価でも、直接解かせるより「条件を計算機が読める形に書き出させる」ほうが成績が上がることが報告されています(Kostis Michailidis, Dimos Tsouros, Tias Guns「DCP-Bench-Open: Evaluating LLMs for Constraint Modelling of Discrete Combinatorial Problems」arXiv:2506.06052)。

このことは、成功報告を読むときの見方も教えてくれます。「10分でできた」という記事を読んだら、何人ぶんか/条件はいくつあったか/守れているかを誰がどう確かめたかの3つを探してみてください。書かれていなければ、自分の病棟にそのまま持ってくることはできません。

Naftyの場合 — シフトを組む部分に生成AIは使っていません

わたしたちがNaftyを作るときも、同じ整理をしました。

勤務表を組む部分は、条件を解く専用の計算エンジンで動いています。ここに生成AIの呼び出しは1つもありません

条件は「必ず守る」と「できれば守る」に分けて扱っていて、どちらに置くかは施設ごとに設定できます。そして組めない条件を渡されたときも、一枚も出さずに終わらせない設計にしています。守れなかった条件は日本語の警告としてお伝えしたうえで、計算自体は最後まで通します。一枚も出てこないのが、現場では一番困るからです。

それでも組めなかったときは、何が衝突しているかを日本語で返します。月の上限、必ず守る月の日数、必ず反映する勤務希望、勤務の並び、1日の必要人数。この5つに分けて、件数と実例をつけて。どの条件を緩めるか判断できるようにするためです。

一方で生成AIは、その周りで使っています。紙・PDF・施設ごとにバラバラなExcelの勤務表を読み取るところ、院内の規程に根拠つきで答えるところ、対話から条件を引き出すところ。いずれも表を作る役ではありません

では生成AIはどこで効くのか

整理すると、こうなります。

工程向いている技術理由
既存のシフト表を読み取る生成AI形式が定まっていないものの意味を取るのが得意
条件を言葉から引き出す生成AI対話で曖昧なところを詰められる
規程を調べる生成AI根拠を示させれば確認もできる
勤務表を組むソルバールールを破っていないことを確かめる機構がある
組めない原因を示すソルバーどの条件が衝突しているかを特定できる
結果を説明する生成AI「なぜこうなったか」を言葉にできる

表そのものを作る一点だけがソルバーの仕事で、それ以外は生成AIが効きます。

ひとつ注意があります。職員IDや勤務区分の記号を、生成AIに「考えさせて」はいけません。読み取った生の値だけを渡して、実在する職員との突き合わせは機械的にやる必要があります。ここを外すと、実在しない職員に勤務が付きます。

明日からできる4つのこと

生成AIに勤務表を触らせるなら、この4つだけ守ってください。

氏名を貼らない。「職員A・B」に置き換えてから貼る。生成AIに個人情報を入力しない運用にしておくほうが無難です。

出てきた表は必ず数え直す。①1人1日1勤務になっているか ②各日の人数が足りているか ③1人ずつの夜勤回数と連勤。AIが出した集計欄をそのまま信じないでください。そこがずれるという報告があります。

「表を書かせる」より「条件を書き出させる」。頭の中にある暗黙のルールを箇条書きにさせる用途なら、今日から安全に使えます。むしろこちらのほうが価値があるかもしれません。

最終確認は人がする。肯定的な実践報告も、例外なく人間の最終確認が必要だと書いています。

検討するときに聞くとよいこと

シフト作成のツールを比べるときは、この2つを聞いてみてください。中で何をしているかが分かります。

「条件を全部満たせないときは、どうなりますか」 — どの条件が衝突しているかを示せるなら、条件を検算する仕組みが中にあります。何かしらの表が必ず出てくるだけなら、検算はされていない可能性があります。

「同じ条件で2回計算すると、同じ結果になりますか」 — 生成AIは同じことを聞いても毎回少し違うことを返します。勤務表は「先月こう決めたから今月はこう」という連続性が要るので、再現しないのは実務では扱いにくいものです。

まとめ

生成AIが勤務表を組めないのは、それらしい続きを書く道具であって、条件を守れているかを確かめる機構を持っていないからです。小さい規模ならそれらしい表は出ますが、人数と条件が増えると崩れます。

組む仕事は条件を解く道具に任せ、生成AIは入り口と出口で使う。入り口は読み取りと条件整理、出口は説明です。いまのところ、これが一番実用的な切り分けだと考えています。

「AIでシフトを作る」と聞いたときに確かめるとよいのは、表を組む部分に何を使っているかです。そこが分かれば、出てきた勤務表をどこまで信じてよいかも分かります。