1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

夕飯がしんどいのは、料理じゃなかった。暮らしを覚えて先回りする「ごはん執事」を作った話

1
Last updated at Posted at 2026-09-22

ChatGPT Image 2026年9月22日 13_57_22.png

今日の夕飯、何にしよう。

この問いが重いのは、料理が面倒だからではありません。答えを出すまでに、解かなければいけない条件が多すぎるからです。

自分の体調とやる気。家族の体調。パパは今日、飲み会でいらない。子どもは習い事で、送迎に出れば台所に立てる時間がそのぶん縮む。上の子と下の子では、必要な栄養も量も違う。今日の給食はカレーだったから、カレーは外す。冷蔵庫の豚肉は明日が期限。下の子は卵がだめで、上の子は魚を残す。

これを毎日、夕方の一番疲れている時間に解いています。

2025年12月の調査では、料理でもっともしんどい工程として「献立を考える」を挙げた人が44.8%で1位でした(株式会社R&G、自炊をしている500人への調査)。包丁を持つ前の工程が、一番重いということです。

日本政策金融公庫の調査(2022年1月、2,000人)でも、家庭の食に関する家事で最も簡便化したい工程は「献立の考案」が29.4%で最多でした。年代が低いほど、その傾向は強くなります。

そして、この工程は特定の人に寄っています。6歳未満の子どもがいる夫婦が食事の管理(料理や食器洗いなど)にかける時間は、夫が14分、妻が1時間25分です(総務省 令和3年社会生活基本調査、週全体の平均)。共働き世帯が専業主婦世帯の3倍を超えた今も、この差は残っています。

私たちは2人とも、働きながら子どもを育てています。だから、ここを引き受けるものを作りました。

ごはん執事といいます。あなたと暮らしを覚えて、先回りするAI執事です。

AI HACK 2026(第2回)のテーマは「業務を自律化するAIエージェント」でした。家事は、給料が出ないだけで、条件が多くて中断だらけの立派な業務です。私たちはそこを選びました。

image.png

12_home_top.png


1. 夕飯は、包丁を持つ前に決まっている

料理を支援するサービスは山ほどあります。それでも夕飯がしんどいままなのは、支援されているのが「作る工程」で、しんどいのは「決める工程」だからです。

決める工程で扱う条件を並べると、こうなります。

条件 毎日どう変わるか
作り手の体調とやる気 今日は無理、という日がある
家族の体調 熱がある人がいれば、食べやすいものに寄せる
家族の予定 出張、飲み会、残業で、食べる人数が日ごとに変わる
習い事と送迎 送迎に出れば、作れる時間そのものが減る
子どもの年齢と体格 必要な量も栄養も、同じ家の中で人ごとに違う
給食の献立 今日の給食と夕食が被ると、子どもは食べない
在庫と期限 使い切らないと捨てることになる
好き嫌いとアレルギー 食べられないものは、そもそも選べない

この8つが毎日ちがう組み合わせで現れて、その日の正解が決まります。レシピを知らないから決められないのではありません。条件の突き合わせに、頭を使い切っているのです。

そして、この条件を代わりに解いてくれる人は、たいていの家にはいません。実家が近い、家事代行を頼める、という家庭ばかりではないからです。頼れる人がいないまま、この工程だけが毎日残り続けます。


2. レシピを探せるだけでは、たぶん続かない

レシピサイトで検索する。AIに献立を聞く。どちらも、いまなら誰でもできます。実際に私たちも試しました。そのうえで、これでは続かないと判断しました。

理由は2つあります。

1つ目:こちらから動かないと、何も起きない

検索も、チャットも、自分でアクションを起こすことが前提です。開いて、打ち込んで、選ぶ。この一連を毎日やることになります。

しかも、検索する時点で「今日は何系にするか」をもう決めています。しんどいのはそこなのに、その入口は自分に残ったままです。

2つ目:毎回、こちらの事情を説明し直す

AIに聞くなら、こう打ち込むことになります。

4人家族で、下の子は5歳で卵アレルギー、上の子は8歳で魚が苦手です。今日の給食はカレーでした。冷蔵庫には豚肉と玉ねぎがあって、豚肉は明日が期限です。今日は夫が飲み会でいません。下の子は今日スイミングで、送迎があるので作れるのは30分です。

1回目はできます。3日目にはやめます。毎日これを打つくらいなら、自分で決めたほうが早いからです。

欲しかったのは、検索できるアプリではなく、専属の執事だった

執事がいる家では、こうなります。

  • こちらが何も言わなくても、1週間ぶんの献立がもう決まっている
  • それに合わせた買い物リストも、考えなくていい
  • 子どもが熱を出した、パパが急に出張になった。そういうときも、ひとこと伝えるだけで代案が出てくる

これができるのは、執事が冷蔵庫の中身も、家族の状況も、すでに把握しているからです。説明がいらないのは、もう知っているからです。

検索するアプリやチャット ごはん執事
きっかけ こちらが開いて、聞く 何もしなくても提案が出ている
前提の共有 毎回説明する すでに覚えている
急な変更 条件を書き直して聞き直す ひとこと伝えるだけ
買い物 自分で材料を拾う 献立に合わせて出てくる
続くか 説明の手間で止まる 話しかけるだけなので続く

だから、話しかける言葉は「今日は疲れた」で足ります。残りの条件は、執事がすでに知っています。


3. 作ったもの

ごはん執事は、ブラウザで動くアプリです。PWAなので、ホーム画面に追加すればアプリのように開けます。

1週間ぶんの献立と買い物リストが、先に出ている

開くと、その週の献立がもう並んでいます。検索する必要も、何系にするか決める必要もありません。買い物リストも、その献立に合わせて出来上がっています。

利用者がやるのは、出てきたものを見て、違うと思ったところだけ伝えることです。

15_meal_plan.png

話しかけると、その日の献立が組み変わる

「パパは火曜から木曜まで出張」と言えば、その3日間の人数が減り、買い物の量も変わります。
「はるとは卵が苦手」と言えば覚えます。
「今日は疲れた」と言えば、その日の献立が15分で作れるものに変わります。

打ち込むのは、ひとことだけです。

18_talk_cost.png

開いたときには、もう見回りが終わっている

アプリを開くと、執事はすでに家の中を一通り見た後です。給食と夕食の重複、期限が近い食材、家族の予定、体調。これを全部走査して、確認が必要なものと、自分の裁量で片付けたものに分けて報告します。

利用者が指示を出す前に、仕事が進んでいる状態から始まります。

08_briefing_top.png

報告の最後には「今日の状態を伝える」の欄があります。「今日は疲れた」「今日は帰りが遅い」「はるとが体調悪い」「パパは今日は夜いない」をタップするだけで、その日の分の献立と量が変わります。決まった言い回しなのでAIは呼ばず、ルールで即反映します。それ以外のことは、執事が「いまお聞かせください」と促すので、声か文字で伝えます。

10_briefing_chips.png

写真で覚える

冷蔵庫の写真を撮ると、食材のリストになります。給食の献立表を撮ると、日付ごとの献立として登録されます。どちらも手入力はしません。

給食の献立表は、月初に配られる紙です。あれを撮るだけで登録できることが、重複回避の前提になります。

19_pantry_photo.png

献立カレンダーと、食べた記録

日ごとに、朝、昼、夕を記録できます。写真とひとことも残せます。給食の日は、昼はワンタップで済みます。

写真は端末の中だけに置き、AIには送りません。あとから見返すと、その週に何が偏っていたかが分かります。

16_meal_calendar.png

起動してから、執事を迎えるまで

アプリを開くと、スプラッシュのあとにGoogleログイン(任意)、そのあとに執事を迎える画面、という順です。ログインは飛ばせます。

執事を選ぶ前に「デモで見る」か「実際に使う」かを選べます。実際に使うを選ぶと、見本の家族や献立は入らず、どの執事も初日から一緒に育てます。会場で試した人が、そのまま使い続けられるようにしました。

最初は、電話から始まる

初回だけ、執事から確認の電話がかかってきます。家族構成とアレルギーを読み上げて、本人の「はい」で確定します。演出ではなく、一番大事な情報をAIの推測で確定させないための設計です。

07_call.png


4. 便利さより、育てること

ここは、おまけの要素ではありません。このアプリの本体です。

8人から、1人を迎える

王道執事、優しいお兄さん、元気な相棒、知的なメガネ執事、上品なコンシェルジュ、優しいお姉さん、元気な親友、頼れる先輩。この8人から、自分の家に合う1人を選びます。

04_choose_rei.png

人格は見た目だけではありません。同じ場面のセリフを、8人ぶん全部書き分けています。「今日は疲れた」と伝えたときの返事は、こうなります。

  • 王道執事:お疲れのご様子ですね。今夜は手早く整う献立に寄せておきます
  • 元気な相棒:おつかれ!今夜はサクッと15分ごはんにしよう。こっちで組み直しとくね!
  • 頼れる先輩:今日はもう十分やった。夕食は手抜きでいこう、15分で終わるやつに組み直しとく

声も8人ぶん用意しました。日本語ネイティブの声を、1人ずつ選んでいます。立ち絵には、待機、思考、気づき、喜び、会話、夜といった表情の差分があり(リツは6種、ほかの7人は5種ずつ)、状況に合わせて切り替わります。

性格の違いは、言い方だけではありません。献立の並びも執事ごとに変わります。 レイは定番でしっかりした献立、ソラとアキは時短、ハルは体にやさしいもの、リツはたんぱく質、リンは魚、ミオは野菜、ナナは子どもが喜ぶものを、同じ条件のときに少しだけ前に出します。

アレルギーと時短の判断は8人とも同じです。変わるのは同点のときの好みだけ。それでも、同じ冷蔵庫から始めても、迎えた執事によって1週間の並びが変わります。

17_candidates.png

始まる段階も執事ごとに違います。リツだけは完全な初期状態から始まるので、「はじめまして」の状態と「わが家専属」の状態を、どちらも触って比べられます。

途中で執事を変えることもできます。そのとき、覚えた内容は引き継がれます。 家族構成もアレルギーも好き嫌いも、そのままです。変わるのは、口調と見た目と声だけ。合わなかったら変えていい、と思えることが、選ぶときの気楽さにつながります。

推しを育てる感覚にした

いま、推し活が広く根づいています。私たちはその感覚を、家事の道具に持ち込みました。

選んだキャラクターを、自分好みに育てていく。便利だから開くのではなく、育てたいから開く。家事のアプリが続かない一番の理由は、面倒だからではなく、開く理由が義務しかないことだと思っています。

独身の人も使えるように、入り口も分けました。かわいい系も、イケメン系も選べます。

執事のお供に、黒猫がいる

執事のほかに、クロッシュという黒猫がいます。執事についてきた設定で、見回りにも一緒についてきます。

クロッシュも一緒に見回り中…🐾
クロッシュが冷蔵庫を気にしています🐾 豚肉、そろそろ使い切ろう?

役割は、愛着です。

これは作ってみて気付いたことですが、同じ指摘でも、猫が気にしていることにすると角が立ちません。期限が近い食材を知らせるのは、突き詰めると「早く使ってください」という督促です。執事が丁寧に言っても、毎日言われれば小言に聞こえます。猫が冷蔵庫の前で気にしている、という形にすると、それが消えます。

執事は敬語で家のことを引き受ける役。クロッシュは、肩の力を抜く役です。朝と夜にもひとこと話し、あいさつ、まったり、考える、心配、気づいた、喜ぶ、応援、眠るの8つのポーズが、場面に合わせて切り替わります。

雇えない関係を、アプリで持つ

執事やお手伝いさんを雇える家庭は、そう多くありません。ですが、自分の家のことを分かっている誰かに任せるという体験自体は、家事の負担を減らすうえで本質的です。

ごはん執事は、その関係をアプリの中で持てるようにしたものです。育つほど、任せられる範囲が広がります。

段階 状態 できること
1 はじめまして 家族構成とアレルギーを覚える
2 少し分かってきました 好き嫌いと給食を考慮する
3 わが家に慣れました 予定、人数、買い物日を調整する
4 先回りします 期限、重複、予定変更を検知して通知する
5 わが家専属 許可された範囲内で自動調整し、結果を報告する

大事なのは、段階が上がっても勝手に任される範囲は増えないことです。何を任せるかは利用者が決めます。段階が上がると、任せられる候補が増えるだけです。

権限のレベルは、機能というより信頼のUIです。

23_mypage.png


5. 何を覚えるのか

このアプリが覚えるのは、レシピではありません。その家の事情です。

覚えるもの 何に効くか
家族構成と続柄 人数、誰の分を作るか
子どもの年齢、身長、体重 必要な量と栄養の目安
好き嫌い 残される献立を避ける
アレルギー 選んではいけないものを外す
学校の給食の献立 今日のカレーと夕飯のカレーを重ねない
家族の予定 出張、飲み会、残業で人数が変わる
習い事と終了時刻 帰宅後に作れる時間を逆算する
体調 食べやすいものに寄せる
冷蔵庫の在庫と期限 使い切る順番を決める
新しく覚えた料理 うちの定番として次から使う

22_family_page.png

覚え方は2つあります。話しかけるか、写真を撮るか。フォームを1つずつ埋める作業は、できるだけ避けました。第1章に書いたとおり、疲れている日ほど入力してもらえないからです。

カレンダーも取り込めます。Googleカレンダーなどの非公開URL(ICS)を預けるだけで、ログインもOAuthの許可画面も要りません。読み取りだけです。取り込んだ予定は、出張、外食、習い事、帰りが遅い日、記念日に分類します。

当初はGoogleのOAuthで実装しました。ところが、審査を通していないアプリでは「このアプリはGoogleで確認されていません」という警告画面が出ます。自分たちなら通れますが、知らない人は引き返します。そこでICS方式に切り替えました。

サーバーは取得した予定を端末に返すだけで、保存しません。パーサーは自前で書き(lib/ics.ts、繰り返しの予定にも対応)、取得先は google、icloud、outlook、timetree、yahoo の許可ドメインだけに限定しています。

年齢だけでは、量が決まらない

同じ年齢でも、子どもの体格には差があります。成長の早い子と、そうでない子では、必要な量が違います。

そこで、身長と体重も登録できるようにして、年齢と合わせて目安を出しています。

身長のわりに体重が多め。おやつと甘い飲み物を控えめに、野菜を先に出すのが無理のない目安です

量を増やす方向だけでなく、量は増やさずに野菜とたんぱく質で満足感を作るという調整もします。

そのうえで、平均から大きく離れているときは、アプリは判断しません。

平均から離れています。健診や小児科で成長曲線を見てもらうと安心です

27_growth_souta_crop.png

ここは医療の領域です。献立を決める道具が踏み込む場所ではないので、気付いたことは伝えて、判断は専門家に渡すという線を引きました。

21_nutrition.png

習い事の日は、終了時刻から逆算する

習い事でしんどいのは、月謝でも送り迎えそのものでもなく、台所に立てる時間が削れることです。

カレンダーから習い事を拾ったら、その日の終了時刻から逆算します。

はるとのスイミング(〜18:30)に合わせて時短
帰ってからの時間が短いので、45分の献立を15分で作れるものに切り替えますか?
帰りが遅くなりますね。外食にしますか?それとも、帰ってから15分で作れるものに切り替えますか?

外食という選択肢も出します。作らない日を作ることも、現実の台所では立派な解だからです。

量は、体格と当日の活動で決める

栄養を1食ごとに完璧にしようとすると、現実の台所では回りません。そこで、その日その人に効く調整だけをします。

  • 運動系の習い事があった日は、その子の分のエネルギーとたんぱく質を1割増やす
  • 体重が多めの子は、量を増やさず、野菜とたんぱく質で満足感を作る
  • 体調が悪い人がいれば、その人の分だけ消化のよいものに替える

献立表全体を栄養で最適化するのではなく、誰の分をどう盛るかで調整する形です。

知らない料理は、その場で覚える

「今夜はガパオライスが食べたい」と言えば、それも受け取ります。

手元のレシピ集にあればそれを使います。なければ、AIが材料と手順を書き起こし、確認のうえでその家の定番として保存します。2回目からは、もうAIを呼びません。

自分の料理を、はじめから登録することもできます。名前と材料と写真を入れるだけです。材料と作り方をAIに書かせて、それを確認してから保存する、という使い方もできます。

使うほど、その家のレシピ集が増えていきます。よそから借りてきた献立が、だんだん自分の家の献立になっていく。ここも、育てる体験の一部です。

(保存しているので、同じ料理の2回目以降はAIの費用がかかりません。この設計は9章のコストの話にもつながります)

覚えたことは、次の献立に効く

覚えるだけでは、執事になりません。覚えたことが次の提案を変えて、はじめて「分かっている」と言えます。

  • 「ゆうきは魚を残す」と伝えると、以後、魚の献立は在庫がそろっていても候補の後ろに下がります。「細かくすれば食べる」なら少しだけ下がって、献立の理由に「細かくすれば食べられる」と添えられます
  • 食後に「おいしかった」「ちょっと苦手」を押すと、その献立の次回の順位が変わります。理由には「前回はるとが『ちょっと苦手』」と残ります
  • 習い事が17:30以降に終わる曜日は、週の献立を組む時点で15分以内の料理になります。運動系の習い事の日は、最初からたんぱく質が多めです。組んだ後で提案し直すのではなく、最初からそうなっています
  • 「ガパオライスにしたい」と言った料理は、うちの定番として次から候補に入ります

執事を替えても、この記録は引き継がれます。家の記録は執事のものではなく、家のものだからです。


6. 中で何が起きているか

ここから技術の話です。

このアプリで、LLMに任せているのは3か所だけです。

処理 担当
人の言葉を構造化する(予定、体調、在庫、好き嫌い、気力の抽出) LLM
写真を読む(冷蔵庫の在庫、給食の献立表) LLM
料理の作り方を書く(手元のレシピ集にないものだけ。書いたら保存して二度と呼ばない) LLM
起動時の見回り ルール
提案の生成(重複回避、人数調整、期限の使い切り、時短、記念日、体調配慮) ルール
カレンダーの分類(出張、外食、習い事、遅い日、記念日) ルール(正規表現)
習い事の終了時刻から、作れる時間を逆算する ルール
体格と当日の活動から、量を調整する ルール
献立の組み立て ルール
アレルギーの最終判定 ルール
確認電話の台詞とクロッシュのひとこと テンプレート

09_architecture.png

LLMがやるのは、人間の言葉や写真を、機械が扱える形に変えるところまでです。その先の判断は、全部こちらのコードが持っています。

なぜこう切ったか

1つ目は、間違いの種類が違うから。
言葉の解釈を間違えても、画面を見て人が直せます。アレルギーの判定を間違えたら、直す機会がありません。後者をLLMに渡す理由がありませんでした。

2つ目は、同じ入力に同じ答えを返したいから。
今日の給食がカレーという同じ状況で、日によって夕食の提案が変わったら、この執事は信用されません。ルールで書けば、同じ条件からは同じ結果が出ます。

3つ目は、回数が多い処理ほど安くしたいから。
一番よく動くのは「起動時の見回り」です。アプリを開くたびに走ります。ここをルールにしたので、毎日何度開いてもAIの費用は増えません。

結果として起きたこと

LLMが止まっても、アプリは止まりません。見回りも、提案も、献立の組み立ても、AIを呼ばずに動くからです。AIが要るのは「話しかけたとき」と「写真を撮ったとき」だけで、そこが遅い日でも他は生きています。

これは後付けの理屈ではありません。実際に113秒待たされた事故から学びました(8章)。

判断が全部ルールなら、エージェントと呼べるのか

この質問は来ると思っています。私たちの答えはこうです。

自律とは、全部任せることではありません。任せる範囲を人が決められて、その範囲の中で、呼ばれなくても動くことです。

ごはん執事は、アプリを開いた瞬間にはもう見回りを終えています。予定が変わったことに自分で気付き、期限が近い食材に自分で気付き、給食との重複に自分で気付いて、直してよいものは直し、確認が必要なものは聞いてきます。利用者が指示を出した覚えがないのに、仕事が進んでいます。

そのうえで、事故になる判断だけは人の承認を通します。どちらの場合も、いつ何をなぜ変えたかが履歴に残ります。たとえば「火曜の鮭のムニエルへ移動:給食と重なったため」という形です。

任せる範囲を明示できることが、家の中に置けるエージェントの条件だと考えました。

26_log.png


7. アレルギーだけは、機械が二重で見る

アプリが覚える情報の中で、間違えたら取り返しがつかないのはアレルギーだけです。ここだけ扱いを変えています。

最初の実装では、アレルギー情報をAIに一切渡していませんでした。安全に見えますが、やってみると提案の質が落ちます。卵がだめな家に、AIが平気でオムライスを勧めてくる。こちらで弾くので結果は安全ですが、会話が噛み合いません。

そこで、渡すけれど、判定はさせない構造に変えました。

第1段階:AIに伝える

/api/classify に送る家族情報は、名前、続柄、アレルギー、好き嫌い、当日の体調だけです。年齢も、身長体重も、住所も送りません。

アレルギーは、家庭の対応ルールを文章で付けて渡します。たとえば 卵(十分加熱は可・本人分だけ抜けば家族は可・買わない)。まだ確認が取れていなければ 卵(対応未確認:一切使わない) です。

システムプロンプトには、アレルギーは最優先の禁止条件であること、該当する食材や料理を提案しないこと、「加熱すれば大丈夫」「少量なら」のような独自判断をしないことを書いています。

ただし、この指示が守られる前提では作っていません。守られなかった場合に備えるのが次の段階です。

第2段階:端末側で、機械的に検査する

lib/allergy.ts にアレルゲンの辞書を持っています。卵、乳、小麦、そば、落花生、えび、かに、くるみ、大豆、ごま、魚介、肉類、果物など25種類です。登録された名前を辞書に当てて、関連するキーワードまで広げて検査します。

検査を通す場所は5か所あります。

検査の場所 引っかかったときの動き
執事の提案に含まれる献立 安全な代替に置き換える。代替がなければ自動実行せず、材料の確認が必要として確認待ちにする
献立表そのもの 初期データ、保存データの復元、家族情報の更新のたびに全日を検査し、該当日を差し替える
献立の候補一覧 通ったものだけ選べる。外したものは理由付きで表示する
買い物リスト 該当する食材を追加しない
AIの返事そのもの アレルゲンを含む可能性が高い料理名が出たら、画面に出す前にルールの返事へ差し替える

最後の行が地味に効きます。AIが献立データを直接書き換えられない作りにしていても、返事の文章に「今夜はオムライスにしましょう」と書かれたら、利用者はそれを信じます。画面に出る言葉も検査の対象にしました。

条件付きは、家庭ごとのルールとして登録する

アレルギーの対応は、家庭によって違います。医師の指示も、家族の方針もそれぞれです。そこで「卵(加熱済みは可)」のような条件付きは、4つの項目として登録します。

  • 十分に加熱してあれば食べられる
  • 本人の分だけ抜けば、家族の献立には使える
  • 家庭内での購入はしてよい
  • 調理器具を分ける

そのうえで、本人がルールを確認済みにするまでは、いちばん厳しい扱い(一切使わない)にします。未確認の家族は画面で赤く光り、起動時の見回りで執事が確認を促します。

加熱すれば食べられる場合でも、許すのは辞書に明記した料理だけです。ゆで卵や卵焼きは許しますが、卵とじや茶碗蒸しのように半熟や生の可能性がある料理は許しません。料理名から加熱の程度を機械が正しく判定できる保証がないからです。

家庭のルールは人が決める。決まるまでは、いちばん安全な側に倒す。 この2つを分けたのが、今回の結論です。

第3段階:理由を画面に出す

差し替えた献立には、理由が付きます。

はるとの卵アレルギー(オムライス)を考慮し、オムライスではなく豚丼に

各献立には、アレルギーを確認済みである表示も出ます。何が起きたかを、利用者が目で確かめられるようにするためです。

11_proposal_modal.png

テストを書いた

テストを書く余裕はほとんどありませんでしたが、2か所だけは書きました。

  • アレルギーの判定(tests/allergy.test.ts、15件)
  • 覚えたことが本当に献立に効くか(tests/preferences.test.ts、6件)

前者は、壊れたときに人が怪我をするからです。後者は、このアプリの約束そのものだからです。好き嫌い、食後の評価、習い事、執事ごとの癖が、ちゃんと献立の順番を変えているかを確かめます。

ICSパーサーの1件と合わせて、npm test で22件通ります。

初回の電話も、同じ思想です

初回に執事が家族構成とアレルギーを読み上げて「はい」をもらうのは、一番大事な情報を本人の返事で確定させるためです。ここが間違った前提のまま進むと、以降の判定が全部その上に乗ります。

まとめると、こうなります。

間違えたら事故になることの最終判定を、確率で答えるものに任せない。


8. AIが113秒黙った

開発の途中で、話しかけても執事が返事をしなくなりました。画面は固まったままです。

計測すると、モデルからの応答に113秒かかっていました。エラーではありません。ちゃんと返ってきました。ただ、夕方の台所で113秒待つ人はいません。

この事故で入れたのが、次の3つです。

待つ時間に上限を置いた

  • モデル1本あたり:12秒(当初は20秒)
  • 連鎖全体:34秒

超えたら待つのをやめます。

軽いモデルは日によって20秒以上かかることがあり、提出日の朝にそれが起きました。そこで、1本を12秒で見切って次へ回す形にしました。

この数字は会話の分類のものです。処理によって変えていて、作り方の生成は長文になるのでモデル45秒、全体80秒。写真の読み取りは60秒にしています。

超えたら、ルールに落ちる

タイムアウトしたら、AIを使わないルールベースの分類に切り替えます。正規表現で「出張」「飲み会」「疲れた」「残業」などを拾い、同じ形のJSONを作ります。

精度はAIに劣りますが、アプリは止まりません。 そして利用者には、ルールで分類したことが履歴に残ります。黙ってごまかす作りにはしていません。

軽いモデルから順に、最後はルールへ

呼び出しの順番はこうです。

tencent/hy3-free
  → z-ai/glm-5.3-flash-free
    → z-ai/glm-5.3-flash(有料)
      → tencent/hy3(有料)
        → orcarouter/auto(有料・最後の受け皿)
          → ルールベース分類(AIなし)

次に進む条件は、402(クレジット切れ)、400、タイムアウト、空応答です。

大事なのは順番の考え方です。軽いモデルが落ちたときに、いきなり最上位へ飛ばさない。 同じ系列の有料版へ横に落とします。発話の分類は短いJSONを返すだけの仕事なので、ここで大きなモデルを使う理由がありません。

OrcaRouterのキックオフ資料には「候補を絞る」「Fallbackを1本置く」とありました。私たちはそれを、仕事の重さに合わせて5段に並べる形で実装しています。

提出日の再計測では、先頭の hy3 が3回とも5秒前後で応答しました。

軽いモデルの癖

response_format でJSONモードを指定すると、軽いモデルが503や空応答を返すことがありました。

対処は、指定をやめることです。プロンプトでJSONだけを返すよう指示して、返ってきた文字列を緩く解析します(コードフェンスや前後の説明文を除去してから読む)。厳密なモードに頼らないほうが、軽いモデルでは安定しました。


9. 1万家庭が毎日使ったら、いくらかかるか

コストパフォーマンスは、利用者が増えても事業として成り立つかだと考えました。そこで、単価の分かっている有料モデルだけ、1万家庭が毎日使う前提で計算をしています。

前提は、1家庭あたり 話しかけ3回/日、写真4枚/月、知らない料理の作り方2回/月(同じ料理の2回目以降は保存しているので呼びません)。見回り、提案、献立の組み立て、アレルギー判定はルールなのでAIを呼びません。1ドル150円で換算しています。

同じ機能を、同じ回数だけ動かしたときの 1万家庭・1か月のAI費用 です。

構成 1万家庭・1か月 OrcaRouterを使った場合との差
Gemini 2.5 Pro に全部やらせる 約103万円 約34倍
GPT-4o に全部やらせる 約80万円 約27倍
Claude Sonnet 5 に全部やらせる 約73万円 約24倍
GPT-4.1 に全部やらせる 約64万円 約21倍
GPT-5 に全部やらせる 約63万円 約21倍
Claude Haiku 4.5 に全部やらせる 約37万円 約12倍
GPT-5 mini に全部やらせる 約13万円 約4倍
OrcaRouterで、仕事ごとに最小のモデルを選ぶ 約3万円 —

やっていることは単純で、1社の汎用モデルに全部やらせないというだけです。

  • 発話の分類と写真の読み取りは、短いJSONを返すだけの仕事です。ここは z-ai/glm-5.3-flash(入力 $0.075/M)で十分でした
  • 料理の作り方を書くところだけ、文章の質が要るので gemini-2.5-flash を使っています
  • 見回り・提案・献立・アレルギー判定は、そもそもAIを呼びません

OrcaRouterは198モデルを同じAPIで呼べるので、この「仕事ごとに最小のモデルを選ぶ」が実装コストほぼゼロでできます。環境変数のモデル名を変えるだけです。

プラン別に見ると、どこが高いのか

料金プランを3段階で考えているので、プランごとの原価も出しました。

プラン 1家庭/月 1万家庭/月 原価率
無料(0円) 約2円 約2万円 —
スタンダード(480円) 約3円 約3万円 0.7%
プレミアム(1,480円) 約335円 約335万円 23%

無料とスタンダードの差は 2円 → 3円しかありません。人が増えても原価がほとんど増えないのは、回数の多い処理をルールにしてあるからです。

高いのはプレミアムのリアルタイム音声だけでした。1分/日で月324円、3分/日で972円、5分/日で約1,630円。1,480円のプランなので、5分/日を放置すると赤字になります。ここだけは1日あたりの上限を置く前提です。執事の声(音声合成)は月8円なので誤差でした。

どこが高くて、どこを止めれば止まるのかが分かっている。 コストパフォーマンスとして示したいのは、この一点です。

応答時間の実測

2026-09-21に、本番と同じ構成で計測しました。費用ではなく、待ち時間の話です。

リクエスト 実際に処理したモデル 入力 出力 時間
発話の分類と返事(パパは火曜日から木曜日まで出張) tencent/hy3-free(先頭が空応答で次へ) 937 1,222 12.8秒
写真の読み取り(108KBの写真) z-ai/glm-5.3-flash-free 768 1,177 22.2秒
音声合成(Fish Audio s2.1-pro-free) 対象外 計測なし 計測なし 2〜6秒

正直に書いておくと、出力トークンが1,000を超えているのは、軽いモデルが思考トークンを含めて返すからです。実際の返事は1文か2文です。

1件目で先頭のモデルが空応答を返して2番目に落ちているのも、そのまま載せます。これが日常です。だから連鎖を組みました。

コストを下げるために決めたこと

  • 一番回数が多い処理を、AIにしない。 起動時の見回りと提案はルールです。毎日何度開いてもAIを呼ばないので、費用が増えません
  • レシピは一度書いたら保存する。 手書きのレシピ24品と、自前で用意した料理カタログ67品(全87品に写真)にあればAIを呼びません。なければAIに書かせて端末に保存し、同じ料理の2回目は呼びません。なお、ネット上のレシピや写真は取り込んでいません(著作権に配慮しています)。カタログと写真はAIに作らせたものを人が確認して保存しました
  • 音声は事前生成する。 8人の試聴音声はmp3として静的配信しています。選択画面で聞くたびに合成しません
  • プロンプトを短く保つ。 家族の情報は端末内にあり、AIに渡すのは発話1文と、名前、続柄、アレルギー、好き嫌い、当日の体調だけです
  • 通知はローカルにする。 LINE通知は従量課金になるので採用しませんでした。Service Workerのローカル通知とアプリ内のバナーで足ります

画面にコストを出せるようにした

OrcaRouterは、応答から実際に処理したモデルが分かります。これを拾って、画面のコスト表示トグルに出しています。どのモデルが答えたのか、概算でいくらかかったのかが、その場で見えます。

連鎖のどこで答えが返ってきたかが一目で分かるので、開発中のデバッグにもそのまま使えました。

18_talk_cost.png

OrcaRouterの使い方

  • 呼ぶのはサーバー側だけ。 Next.jsのRoute Handlerからのみ呼びます。APIキーは端末に出ません
  • モデル名をアプリに埋め込まない。 連鎖の設定を変えれば、本体を触らずにモデルを差し替えられます。提出日の朝に先頭のモデルを入れ替えたのも、環境変数を1つ変えただけです
  • 仕事の重さに合わせてモデルを並べる。 落ちたときに最上位へ飛ばさず、同じ系列の安い有料版へ横に落とします
  • 実際に処理したモデルを記録する。 応答本文のmodelフィールドを拾い、履歴と画面の両方に残します

余談ですが、最初は素直にorcarouter/autoから始めて、402が返って止まりました。クレジットの付与条件に引っかかっていたためです。結果的には、これが良い方向に転びました。まず一番軽いモデルで組んで、必要な場所だけ上げる、という順番に入れたからです。最初から上位モデルで組んでいたら、月80万円の構成のまま気づかなかったと思います。

セキュリティで決めたこと

  • APIキー(OrcaRouterとFish Audio)はサーバーの環境変数に置く。端末に出さない
  • カレンダーはICSの読み取りだけ。取得した予定はサーバーに保存せず、端末に返すだけ
  • 状態はすべて端末内(localStorage)に置き、サーバーにデータベースを持たない。つまり、私たちは家族の情報を預かりません
  • 機種変更に備えて、Googleでログインすると本人のGoogleドライブのアプリ専用領域に同じ記録を保存する。ドライブの一覧には出ず、このアプリからしか読めない領域です。保存は端末からGoogleへ直接行い、私たちのサーバーは通りません。求める権限はアカウント情報とこの領域だけなので、Googleの未確認アプリの警告も出ません
  • ログインしなくても使える。「あとで」を選べば端末内だけに保存されます
  • 例外は1つだけ。ログイン画面で「リリースのお知らせを受け取る」にチェックした人のメールアドレスと名前は、家族の情報とは別の場所に保存します。チェックを外せば何も保存しません
  • 確認待ちと自動実行を分け、判断の記録を残す

家族の情報を扱う以上、預からないで済む設計を選びました。機種変更でデータが消える問題は、私たちが預かるのではなく、本人のドライブに置くことで解いています。

01_login.png


10. 捨てた案と、実機で直したこと

捨てたものと、iPhoneの実機で見つけて直したものを、全部書きます。うまくいった話より、こちらのほうが役に立つと思うからです。

捨てた案(技術選定)

やったこと 何が起きたか どうしたか
OpenAI TTSで執事の声(tts-1 / tts-1-hd / gpt-4o-mini-tts) 日本語のイントネーションが不自然。献立や15分を読み間違える 読み仮名の変換で粘ったが限界。全部捨ててFish Audioへ。日本語ネイティブの声から8人ぶん選定
ElevenLabs 同じく日本語が不自然。アカウントとキーの設定まで済ませたが不採用 コードごと撤去
最初から有料のorcarouter/autoを使う クレジットが付与されず402で停止 一番軽いモデルを先頭に置く連鎖へ。仕事の重さに合わせて5段に並べた
OrcaRouterのJSONモード 軽いモデルで503や空応答 プロンプトでJSONを指示し、緩く解析する方式へ
モデルの応答を待ち切る 1回113秒かかり、アプリが固まった モデル12秒、全体34秒の上限(当初は20秒/32秒。応答が遅い日に合わせて短縮)。超えたらルール分類へ
LINE通知 従量課金になる。デモにも重い Service Workerのローカル通知とアプリ内バナーへ
読み上げ用にセリフをひらがな化 画面の表示までおかしくなった(じゅっぷん) 表示は漢字と数字のまま、読み上げ用のテキストだけ補正。最終的に数字を使わないセリフに変更
献立の写真がない料理に、似た分類の写真を代用 酢豚に野菜スープの写真が出るなど、違う料理の写真が並んだ 代用をやめ、写真がない料理は写真なしに。提出日に残り43品の写真を生成して全品そろえた

実機で直したこと(iPhoneで見つかった)

やったこと 何が起きたか どうしたか
Googleログインをポップアップ方式で実装 iPhoneのホーム画面から開いたアプリでは、ポップアップが戻ってこない Googleへ移動して戻ってくるリダイレクト方式へ
確認電話で、はいの直後に締めの言葉を再生 iOSではマイク使用中に音声が無音になる 聞き取りを止めてから350ms待って再生。音声は先読みしておく
執事8人の画像を一度に生成 みんな顔が似すぎた 1人ずつ作り直し。指の描写ミスも手直し
選択画面に8人をグリッド表示 キャラが小さく、ボタンが画面の外に出た 先に一人暮らしか家族かを聞き、1人ずつ大きく表示して左右で送る形へ
試聴音声をそのまま配信 セリフを変えてもiPhoneが古いmp3を再生し続けた ファイル内容のハッシュをURLに付けて配信
入力シートの保存ボタンを画面下に固定(sticky) iPhoneのSafariでは余白のぶんボタンが浮いて動いた シートを「本文だけスクロール、ボタンはシートの下端に固定」の構造へ

ここから学んだこと

日本語の読み上げは、不自然さが体験の全部を壊します。
執事が家族の名前を変なイントネーションで呼んだ瞬間に、親しみが消えます。文字で読むぶんには気付かない品質の差が、声になると致命傷になりました。モデルの性能表では分からない領域です。

実機で触るまで、分からないことが多すぎます。
iOSのマイクと音声再生の衝突も、ブラウザのキャッシュも、画面の外に出たボタンも、全部iPhoneの実機で見つかりました。パソコンの画面では気付けませんでした。

事故から入った制約のほうが、筋が良くなることがあります。
402で止まったから一番軽いモデル中心になり、113秒待たされたからフォールバックが入りました。どちらも、最初から設計していたわけではありません。

キャラクターは、最後まで手を抜けません。
8人ぶんのセリフを書き分ける作業は、開発時間のかなりを食いました。ですが第4章に書いたとおり、育てたいから開く、という状態を作れなければ、このアプリは続きません。ここは削れない工程でした。


11. できていないこと

できていないことのほうが多いです。主なものを書きます。

1万家庭ぶんの実負荷では測っていません。
9章の数字は、各モデルの公開単価と実測のトークン数からの試算です。同時に多数が使ったときのレート制限や、リトライで増える分までは織り込めていません。

ルールなので、想定外の言い回しは拾えません。
AIが落ちたときのフォールバック分類は正規表現です。変わった言い方をされると拾えません。ただし、拾えなかったことは画面に残るので、黙って間違えることはありません。

実際の家庭で1か月使った検証がありません。
iPhoneの実機での動作確認はしていますが、家族が毎日使い続けたときに何が起きるかは、これからです。

アレルギーの辞書は完全ではありません。
25種類のアレルゲンに対応していますが、加工食品に含まれる原材料までは追えません。最後は人が見る前提の道具です。

栄養は、目安にとどまります。
体格と当日の活動で量を調整しますが、献立全体を栄養価で最適化しているわけではありません。平均から離れた体格のときは、アプリで判断せず受診を勧める作りにしています。

覚えたレシピの精度は、これからです。
新しい料理はAIが作り方を書きますが、書き起こした手順が本当に作りやすいかは、実際に作ってみないと分かりません。

「金曜はカレーの日」のような習慣は、まだ覚えられません。
予定・体調・在庫・好き嫌いのように構造に落ちる話は献立に効きますが、習慣は文章として記録に残るだけです。


12. これから

  • 家族の複数端末での同時共有(機種変更の引き継ぎはできましたが、家族どうしで同時に使うのはこれからです)
  • 家族の登録を声だけで済ませる(いまは「執事に話す」経由なら声で入ります)
  • 夜の報告を、希望者だけメールでも届ける
  • 実際の家庭での長期の検証
  • 負荷をかけた状態での実コストと、レート制限時の挙動の計測
  • 買い物リストから、そのままネットスーパーへつなぐ導線

AI HACKの審査項目に、どう答えたか

AI HACK 2026の審査は、セキュリティ、自律性、コストパフォーマンス、アイデアと独創性、信頼性と堅牢性の5項目です。ごはん執事では、それぞれをこう考えました。

1. セキュリティ

預からない、出さない、鵜呑みにしない。

  • 家族の情報は端末内(localStorage)と、本人のGoogleドライブのアプリ専用領域だけに置き、私たちのサーバーにデータベースを持ちません。ドライブへの保存も端末からGoogleへ直接で、私たちのサーバーは通りません
  • APIキー(OrcaRouter、Fish Audio)はサーバーの環境変数だけにあり、AIを呼ぶのはNext.jsのRoute Handlerからのみです。端末に鍵は出ません
  • AIに渡すのは発話1文と、名前、続柄、アレルギー(対応ルール付き)、好き嫌い、当日の体調だけです。年齢、身長体重、住所、履歴は送りません
  • プロンプトインジェクションへの備えは、AIが何を言っても、状態を直接は書き換えられない構造です。AIの返答はJSONとして受け取り、決まった項目だけを型と長さで検査してから使います(発話は500文字、料理名は30文字、食材名は20文字まで。それ以外の項目は捨てます)。写真の読み取り結果も同じ検査を通ります。給食の献立表やメモに指示が写り込んでいても、できるのは食材名や献立名を返すことまでです
  • AIの返事の文章そのものも、画面に出す前にアレルゲンの辞書で検査し、引っかかれば差し替えます(7章)
  • 外から取るものは、取得先を絞っています。カレンダーのICSは google、icloud、outlook などの許可ドメインだけ。音声合成のモデル名も許可リストだけです
  • Googleログインで求める権限は、アカウント情報とこのアプリ専用のドライブ領域だけです。ドライブの他のファイルには触れません
  • 私たちが保存するのは、お知らせを希望した人のメールアドレスと名前だけです。家族の情報とは別の場所に置き、希望しなければ何も保存しません

2. 自律性

呼ばれなくても動く。ただし、任せる範囲は人が決める。

  • アプリを開いた瞬間には見回りが終わっています。給食との重複、期限の近い食材、予定の変化、体調、未確認のアレルギーを走査し、自分の裁量で片付けたものと、確認が必要なものに分けて報告します(3章)
  • 覚えたことが次の提案を変えます。好き嫌い、食後の評価、習い事の曜日と終了時刻が、週の献立を組む時点で反映されます(5章)
  • 段階が上がると任せられる候補は増えますが、勝手に任される範囲は増えません。何を自動にするかは利用者が決めます(4章)
  • 事故になる判断(アレルギー、人数の変更を伴う差し替えなど)は人の承認を通し、それ以外は自動で直して結果だけ報告します
  • いつ何をなぜ変えたかは、すべて履歴に残ります

3. コストパフォーマンス

一番回数の多い処理をAIにしない。仕事ごとに最小のモデルを選ぶ。

  • LLMを呼ぶのは、話しかけたとき、写真を撮ったとき、知らない料理の作り方を書くときの3か所だけです。見回り、提案、献立の組み立て、アレルギー判定、好み反映はルールなので、毎日何度開いてもAIを呼びません(6章)
  • 1社の汎用モデルに全部やらせると1万家庭で月80万円(GPT-4o相当)のところ、OrcaRouterで仕事ごとに最小のモデルを選ぶと月3万円になります。同じ機能、同じ回数での比較です(9章)
  • プラン別の原価は、無料が1家庭あたり月2円、スタンダードが月3円で、人が増えてもほとんど増えません。高いのはプレミアムのリアルタイム音声だけなので、そこにだけ1日の上限を置きます(9章)
  • 作り方は一度書いたら保存し、同じ料理の2回目はAIを呼びません。試聴音声は静的配信、通知はローカル、記録の保存先は本人のドライブなので、私たちのサーバー費用も増えません
  • 実際に処理したモデルと概算コストを画面に出せるので、どこで費用が発生したかがその場で分かります

4. アイデア・独創性

レシピを探す道具ではなく、家の事情を覚えて先回りする執事。

  • 検索もチャットも、こちらが動かないと始まりません。ごはん執事は、1週間の献立と買い物リストが先に出ていて、急な変更は「今日は疲れた」のひとことで済みます(2章)
  • 覚えるのはレシピではなく、その家の事情です。給食、習い事の終了時刻、体格、体調、在庫の期限、好き嫌い。これらの突き合わせを引き受け、次の献立に効かせます(5章)
  • 8人の執事から1人を迎え、育てる。便利だから開くのではなく、育てたいから開く。執事によって献立の並びまで変わります。黒猫のクロッシュは、督促を小言にしない役です(4章)
  • 初回の確認電話。一番大事な情報を、AIの推測ではなく本人の「はい」で確定します

5. 信頼性・堅牢性

AIが止まっても、アプリは止まらない。間違えたら事故になる判定は、確率に任せない。

  • モデル1本12秒、連鎖全体34秒で待つのをやめ、軽いモデルから順に、最後はルール分類に落ちます。113秒待たされた事故から入れた仕組みです(8章)
  • ルールで分類したことは履歴に残ります。黙ってごまかしません
  • アレルギーは、AIに伝えたうえで、端末側の辞書(25種)で5か所を機械的に検査します。条件付きは家庭ごとのルールとして登録し、確認済みになるまでは最も厳しい扱いです(7章)
  • 同じ条件からは同じ結果が出ます。献立の組み立てとアレルギー判定はルールなので、日によって答えが変わりません
  • 記録は端末と本人のドライブの2か所にあり、機種変更や端末の故障でも戻ります
  • テストは2か所に書きました。アレルギーの判定(15件)と、覚えたことが献立に効くこと(6件)です

13. まとめ

夕飯がしんどいのは、料理が面倒だからではありませんでした。包丁を持つ前に、条件を突き合わせる工程がしんどいのです。しかもその工程を代わってくれる人は、たいていの家にはいません。

レシピを探せる道具はすでにあります。ですがそれは、こちらが動いてはじめて動くものです。私たちが作ったのは、こちらが動かなくても先に動いているものです。1週間ぶんの献立と買い物リストが先に出ていて、急な変更はひとこと伝えるだけで代案が返る。それができるのは、冷蔵庫の中身と家族の状況を、執事がすでに知っているからです。

技術の側で決めたことは、ひとつだけです。

LLMに任せるのは、言葉を構造化することと、写真を読むことと、作り方を書くこと。判断はこちらのコードが持つ。

この線引きのおかげで、AIの応答が113秒かかってもアプリは動き続け、アレルギーの判定は毎回同じ結果になり、一番回数の多い処理はAIを呼ばないままになりました。

家族の情報を預かる道具は、賢いかどうかより、間違えたときに何が起きるかで選ばれると思っています。任せない場所を決めたことで、任せられる場所が増えました。


使ったもの

  • OrcaRouter:OpenAI互換のAI推論ゲートウェイ。1つのAPIキーで多数のモデルを呼べます。仕事の重さに合わせて軽いモデルから並べる連鎖、orcarouter/autoを最後の受け皿に置く構成、応答から実際に処理したモデルを取る仕組みまで、今回の設計はこれが前提です
  • Fish Audio:執事8人の声
  • Next.js(App Router)/ Vercel:本体とAPI
  • Claude Code:実装のペアプログラマー
  • ICS(iCal)形式のカレンダー取り込み:Google、iCloud、Outlookなどに対応。読み取りのみ、自前のパーサー
  • Google Drive API(appDataFolder):本人のドライブへの記録の保存と復元
  • ChatGPT(画像生成):執事とクロッシュの立ち絵、料理の写真、プランのマーク

リンク

  • 本番:ごはん執事 (ホーム画面に追加すると、アプリとして開けます)
  • リポジトリ:製品化のため、非公開にしました。

この記事は AI HACK 2026(第2回)の提出作品です。モデルの呼び出しには、スポンサーの OrcaRouter を使わせていただきました。運営のみなさま、スポンサーのみなさま、ありがとうございました。

最後まで読んでいただき、ありがとうございました。

出典

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?