研究所の共用機器の予約を Apps Script でカレンダーから拾い、重複と講習・時間の決まりを規則で、試料の使用条件を AI で点検して、利用の時間を部門ごとに月次で集計する
共用機器のカレンダーに入った予約を拾い、重複と講習・時間の決まりを規則で、試料の使用条件をAIで点検します。月の初めには、前月の利用の時間を機器と部門ごとに集計します。
- 生成AI
- ChatGPT/Claude/Gemini
- 連携・自動化
- Google Apps Script/Power Automate/Python
- 対象業界
- 医療/教育/製造
- 対象部門
- 研究開発
- 対象業務
- 内容確認・チェック/集計・分析
- 主な課題
- 人手が足りない/属人化している/確認ミスが多い
- AIで行う処理
- 判定
- 主な効果
- 入力漏れ削減/品質標準化/工数削減
- 導入難易度
- ★★☆☆☆
- 実装レベル
- 半自動化
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 技術職員が担当の機器のカレンダーを毎朝開き、前日からの新しい予約と変更を探す
- 予約者を講習の修了者の名簿で探し、修了しているかを見る
- 時間の重なり、1回の上限、時間外の立会人を見る
- 予約の説明の試料と薬品を読み、使用条件に引っかかりそうなものがあれば予約者に連絡する
- 月の初めに、前月の予約を機器ごとに数え、予約者の部門を調べて時間を足し、配賦の表を作る
- 自動Apps Script が10分ごとに動き、24台のカレンダーを増分同期で読み、新しい予約・変更・取消を拾う
- 自動予約の説明を書式に沿って読み分け、使用者・試料・薬品・目的・立会人を取り出す
- 自動時間の重複、講習の修了、1回の上限、時間外の立会人を、規則で確かめる
- 自動試料と薬品が書かれていれば、AIが機器の使用条件に照らし、当てはまりうる条件を原文付きで挙げる
- 自動規則の違反は、予約者と管理者にメールで知らせる。AIが挙げた条件は、管理者の確認の一覧に入れる
- 人管理者が確認の一覧を見て、予約者に連絡するかを決める
- 自動毎月1日に、前月の予約を機器と部門ごとに集計し、配賦の表を作る
- 人管理者が配賦の表を確かめ、経理に回す
各工程の詳しい説明を読む
- 技術職員が担当の機器のカレンダーを毎朝開き、前日からの新しい予約と変更を探す
- 予約者を講習の修了者の名簿で探し、修了しているかを見る
- 時間の重なり、1回の上限、時間外の立会人を見る
- 予約の説明の試料と薬品を読み、使用条件に引っかかりそうなものがあれば予約者に連絡する
- 月の初めに、前月の予約を機器ごとに数え、予約者の部門を調べて時間を足し、配賦の表を作る
(a)新しい予約と変更を探すのが手間。 1番は、カレンダーを眺めて覚えのない予定を探す作業です。変更された予約は見た目が変わらず、 時間を延ばされても気づきません。
(b)決まりの違反を見落とす。 2番と3番は単純ですが、件数が多い週は省かれます。 講習を終えていない人が時間外に1人で使っていたことが、後から分かることがあります。
(c)試料の確かめ方が担当で違う。 4番は担当の経験に寄ります。ある担当は「粉末」とあれば必ず連絡し、別の担当は見過ごします。 異動や休暇で担当が替わると、確かめ方も替わります。
(d)月初の集計に時間がかかる。 5番は、24台のカレンダーを1つずつ開いて数え、予約者の部門を名簿で引き直す作業です。途中で消された予約や、時間を変えた予約の数え方で、担当ごとに数が合いません。
- 【自動】 Apps Script が10分ごとに動き、24台のカレンダーを増分同期で読み、新しい予約・変更・取消を拾う
- 【自動】 予約の説明を書式に沿って読み分け、使用者・試料・薬品・目的・立会人を取り出す
- 【自動】 時間の重複、講習の修了、1回の上限、時間外の立会人を、規則で確かめる
- 【自動】 試料と薬品が書かれていれば、AIが機器の使用条件に照らし、当てはまりうる条件を原文付きで挙げる
- 【自動】 規則の違反は、予約者と管理者にメールで知らせる。AIが挙げた条件は、管理者の確認の一覧に入れる
- 【人】 管理者が確認の一覧を見て、予約者に連絡するかを決める
- 【自動】 毎月1日に、前月の予約を機器と部門ごとに集計し、配賦の表を作る
- 【人】 管理者が配賦の表を確かめ、経理に回す
3番目と4番目を分けるのが、この設計の要です。 重複や講習の修了は、名簿と時刻で白黒がつくので、規則で決めて予約者に直接知らせます。試料の条件は、同じ「粉末」でも中身で扱いが変わるので、AIは候補を挙げるだけで、管理者が決めます。
予約を消したり動かしたりはしません。 規則の違反でも、知らせるだけです。予約者が講習を受けた直後で名簿の更新が遅れている、という形があるからです。
02今回想定するシステム構成
機器ごとの Google カレンダー(24台) ▼【トリガー】時間主導型(10分ごと) Google Apps Script(機器管理用のアカウント) ├──▶ ロックを取る(同時に2つ動かさない) ├──▶ Calendar の高度なサービス:Events.list(syncToken で増分同期) ├──▶ 予約の説明を書式で読み分ける(HTMLを外す) ├──▶ 規則の点検(重複/講習の修了/上限/時間外の立会人) │ └ スプレッドシート:名簿、機器の決まりの表 ├──▶ Claude API:試料と薬品を使用条件に照らす(構造化出力) ├──▶ スプレッドシート:予約の記録、管理者の確認の一覧 └──▶ Gmail:規則の違反の知らせ(研究所の中のアドレスだけ) ▼【人】管理者が確認の一覧を見て予約者に連絡 【トリガー】時間主導型(毎月1日) └──▶ 前月の予約の記録を機器×部門で集計 → 配賦の表
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Google Apps Script | Python、Power Automate |
| 生成AI | Claude API(構造化出力) | OpenAI API、Gemini API |
| 予約 | Google カレンダー(機器ごと) | Microsoft Outlook の予定表 |
| 保管 | Google スプレッドシート(名簿、機器の決まりと使用条件、予約の記録、確認の一覧、配賦の表) | - |
| メール | Gmail(機器管理用のアカウント) | - |
新しく足すのは、Apps Script と、予約の記録・確認の一覧・配賦の表のシートだけです。 カレンダーと名簿はいまのものを使い、予約の説明の書き方だけを決めます。
カレンダーの変更は、増分同期で拾います。 公式のページでは、カレンダーのイベントのトリガーは予定の作成・編集・削除で動きますが、どの予定がどう変わったかは教えてくれず、 保存した nextSyncToken で増分同期をするよう書かれています。この構成は、24台を10分ごとに同期する時間主導型にします。 公式のページでは、時間主導型は1分・5分・10分・15分・30分ごとを選べます。
同期は Calendar の高度なサービスの Events.list で行います。 公式のページの例では、保存した syncToken を付けて呼び、ページを最後までたどってから nextSyncToken を保存します。 トークンが使えなくなったときは、保存を消して全件の同期をやり直します。
AIは Claude API を UrlFetchApp で呼びます。 公式のページでは、構造化出力は output_config.format に type: "json_schema" を渡し、オブジェクトの additionalProperties を false にします。 数値の minimum・maximum は使えず、使うと400になります。
03どうやって実装するのか
処理の起点を決める
時間主導型のトリガーで、10分ごとに動かします。 公式のページでは、インストール型のトリガーは作った人のアカウントで動きます。 機器管理用のアカウントで作ります。技術職員の個人のアカウントで作ると、その人が異動したときに止まります。
10分ごとにしたのは、予約から点検までの遅れを短くするためです。 夕方に入った当日の時間外の予約も、10分以内に講習と立会人の点検が済みます。毎朝1回にすると、前夜の時間外の使用は点検の前に終わっています。
同時に2つ動かさないよう、最初にロックを取ります。 公式のページでは、LockService.getScriptLock() はどの利用者からも、そのコードの部分を同時に動かさないためのロックです。前の実行が長引いているうちに次の10分が来ると、同じ予約を2回点検し、知らせが2通届きます。 ロックが取れなければ、その回は何もせずに終えます。
月次の集計は、別の時間主導型のトリガーで毎月1日に動かします。 公式のページでは、onMonthDay() で月の日を、atHour() で時刻を決められます。分は前後15分ずれることがあります。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 予約 | 予定のID、作成者のメール、開始と終了、説明、状態(cancelled を含む)、更新の時刻 | 機器ごとの Google カレンダー |
| 講習の修了者の名簿 | 研究員のメール、部門、修了した機器と修了日 | スプレッドシート |
| 機器の決まりの表 | 機器ID、カレンダーID、1回の上限時間、時間外の定義、立会人の要否、時間単価 | スプレッドシート |
| 機器の使用条件 | 機器ID、条件の番号、条件の文(例:「磁性のある試料は事前に相談」) | スプレッドシート |
| 予約の記録 | 予定ID、機器、使用者、部門、時間、点検の結果、管理者の判断 | スプレッドシート(このスクリプトが書く) |
質を決めるのは、予約の説明の書き方です。 研究員に、予定の説明を次の5行で書いてもらいます。
使用者:[email protected]
試料:Fe-Ni 合金の粉末(約0.5g)
薬品・溶媒:エタノール
目的:粒子の形状の観察
立会人:(時間外のときだけ)
行の頭の言葉を決めておけば、Apps Script が行ごとに読み分けられます。 自由に書かせると、AIに読み分けさせることになり、使用者のメールを読み違えると講習の点検そのものが誤ります。 書式に沿っていない予約は、点検をせずに予約者に書き直しを頼みます。
使用条件は、条件の番号を付けた1行1条件にします。 「真空系に入れる試料は、含水・揮発性・磁性のものを除き…」のように長い文で書かれていると、AIがどの部分に当てはまるかを示せません。 1行1条件に分けると、結果に条件の番号を返させられます。
データの取得方法を決める
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 変わった予約 | Calendar の高度なサービスの Events.list(syncToken) | 新しい予約・変更・取消の検出 |
| 同じ機器の前後の予約 | Events.list(timeMin・timeMax) | 時間の重複の点検 |
| 名簿と決まり | スプレッドシートの読み取り | 講習・上限・時間外の点検 |
| 使用条件 | スプレッドシートの読み取り(その機器の行だけ) | AIへの入力 |
syncToken は機器ごとに保存します。 24台のカレンダーは別々のトークンを持ちます。スクリプトのプロパティに「機器ID → トークン」で保存し、 カレンダーごとに増分同期をします。公式のページでは、プロパティの値は1つ9KBまでです。トークンは短い文字列なので足ります。
取消は status が cancelled の予定として届きます。 Calendar API のページでは、cancelled は取り消された(削除された)予定です。予約の記録の同じ予定IDの行に「取消」と書き、集計から外します。 取消を拾わないと、消された予約まで利用料に入ります。
作成者は creator.email で取れますが、使うのは説明の「使用者」の行です。 研究室の補助の人が代わりに予約を入れることがあるからです。使用者の行が空なら、作成者を使用者として扱い、 確認の一覧に「使用者の記載なし」と書きます。
AIへ渡す前に整形する
- ロックを取る … 取れなければ終えます
- 増分同期 … 機器ごとに
Events.listをトークン付きで呼び、ページを最後までたどってからトークンを保存します - 点検済みかの確認 … 予定IDと更新の時刻(
updated)で予約の記録を引き、同じ更新の時刻なら飛ばします - HTML を外す … Calendar API のページでは、説明は HTML を含みうるので、タグを外してから読みます
- 書式で読み分ける … 行の頭の言葉で使用者・試料・薬品・目的・立会人に分けます
- 規則の点検 … 重複、講習の修了、上限、時間外の立会人を確かめます
- AIへの入力を絞る … その機器の使用条件の行と、試料・薬品・目的の3行だけを渡します
2番目で、途中で抜けないことに注意します。 公式のページの例は、取り消された予定や終日の予定を見つけると return で関数を抜ける書き方で、そのまま写すと残りの予定とトークンの保存が飛びます。 予定ごとの処理は continue で次へ進め、トークンは必ず最後に保存します。
6番目の規則は、表にして Apps Script に持たせます。
| 規則 | 確かめ方 | 違反のときの知らせ |
|---|---|---|
| 時間の重複 | 同じ機器の前後の予約と、開始と終了を比べる | 後から入った予約の予約者と管理者 |
| 講習の修了 | 使用者のメールと機器IDで名簿を引く | 「修了を確認できませんでした」 |
| 1回の上限 | 終了 − 開始 が決まりの表の上限を超えるか | 予約者 |
| 時間外の立会人 | 時間外の定義に入る時間帯で、立会人の行が空か | 予約者と管理者 |
重複の比べ方は、終了の時刻を含めないで比べます。 Calendar API のページでは、開始は含み、終了は含まないとされています。10時〜12時と12時〜14時の予約は重なりません。終了を含めて比べると、続けて入った予約がすべて重複として知らせられます。
時間外の定義は、機器ごとに決まりの表に置きます。 平日の18時以降と休日、という研究所の共通の定義に、夜間に無人で動かせる機器の例外を足せるようにします。
3番目は、通知が2回届くのを防ぎます。 増分同期は、予定の色を変えただけでも変わった予定として返します。点検に関係する項目(開始、終了、説明、状態)が前と同じなら、点検をやり直しません。
AIに処理させる
させるのは、試料・薬品・目的の記述を、その機器の使用条件の行に照らして、当てはまりうる条件を挙げることだけです。
| させること | 中身 |
|---|---|
| 当てはまりうる条件 | 条件の番号と、根拠にした予約の記述の原文 |
| 情報の不足 | 条件を判断するのに要るが書かれていないこと(量、溶媒の有無、乾燥の有無など) |
| 該当なし | どの条件にも当てはまらないと読めるとき |
「当てはまる」ではなく「当てはまりうる」で返させます。 「Fe-Ni 合金」が磁性の試料かは、組成と状態で変わります。AIは「磁性の可能性がある記述」として挙げ、管理者が予約者に聞きます。
| させないこと | 理由 |
|---|---|
| 試料を入れてよいかを決める | 機器の故障と安全に関わる。管理者が決める |
| 規則の点検をやり直す | 重複や講習は規則で決める。AIの判断を混ぜない |
| 書かれていない試料の性質を補う | 「合金だから乾燥している」と決めつけない |
| 使用条件に無い注意を足す | 条件の表に無い注意は、管理者が条件の表に足す |
| 予約者に連絡する文を書く | 連絡するかと伝え方は管理者が決める |
3行目がいちばん起きやすい失敗です。 「細胞の切片」とだけ書かれていると、AIは「固定と乾燥の処理がされていると思われるため、該当なし」と書きます。処理が書かれていなければ、情報の不足として返させます。
指示内容を固定する
あなたは研究所の共用機器の管理を手伝う立場で、予約に書かれた試料と薬品が、
その機器の使用条件に当てはまりうるかを洗い出します。
判断は機器の管理者が行います。あなたは候補と根拠を挙げるだけです。
【機器】{equipment_name}
【使用条件】(1行1条件。先頭は条件の番号)
{conditions}
【予約の記述】
試料:{sample}
薬品・溶媒:{chemicals}
目的:{purpose}
【やること】
1. 使用条件の1行ずつについて、予約の記述が当てはまりうるかを見る。
2. 当てはまりうるものは matches に、条件の番号と、根拠にした予約の記述を
そのまま写して入れる。
3. 条件を判断するのに要るのに書かれていない情報は、missing_info に入れる。
4. どれにも当てはまらず、不足も無ければ、matches と missing_info を空にする。
【厳守事項】
- 試料を機器に入れてよいか、使ってよいかを書かないでください。
- 書かれていない試料の性質(乾燥しているか、磁性か、量など)を
推し量って補わないでください。不足は missing_info に入れてください。
- 使用条件に無い注意を新しく書かないでください。
- quote には予約の記述の文字列をそのまま写してください。言い換えないでください。
- condition_no には使用条件の先頭の番号だけを入れてください。
「使ってよいかを書かない」を最初に置きます。 書かないと、要約の最後に「以上より、使用に問題はないと考えられます」と結論を足します。管理者がその一文を読んで確認を省くと、この構成の意味がなくなります。
「推し量って補わない」と missing_info をセットで書くのも同じ理由です。 補うことを禁じるだけだと、AIは当てはまらない側に倒して「該当なし」を返します。不足を返す欄があれば、分からないことを分からないと返せます。
出力形式を固定する
次の形のJSONで受け取ります。 構造化出力のスキーマで、各オブジェクトの additionalProperties を false にします。
{
"matches": [
{ "condition_no": "SEM-03",
"quote": "Fe-Ni 合金の粉末(約0.5g)",
"reason": "磁性のある試料の可能性がある記述" }
],
"missing_info": ["粉末を固定する方法(カーボンテープなど)"],
"no_concern": false
}
1つ目の理由は、condition_no で使用条件の表と結べることです。 確認の一覧に、条件の番号から条件の文を引いて並べます。AIが条件の文を言い換えても、表の原文が並ぶので誤読しません。
2つ目は、quote を予約の説明と照合できることです。 スクリプトで、quote が説明の中にそのまま含まれるかを確かめ、含まれなければ「根拠の照合に失敗」として確認の一覧に入れます。 AIが記述を書き換えたことに気づけます。
3つ目は、no_concern で確認の一覧を短くできることです。 no_concern が true で規則の違反も無ければ、確認の一覧に入れず、予約の記録に「点検済み」とだけ書きます。 管理者が見るのは、何かが挙がった予約だけです。
月次の配賦の表は、AIを通さずに予約の記録から作ります。
| 列 | 中身 |
|---|---|
| 部門 | 使用者のメールから名簿で引いた部門 |
| 機器 | 機器ID と名前 |
| 時間 | 前月の予約の時間の合計(取消と「使用を見合わせ」を除く) |
| 単価・金額 | 決まりの表の時間単価と、時間 × 単価 |
| 件数 | 予約の件数と、そのうち時間外の件数 |
集計に予約の記録を使うのは、カレンダーを数え直さないためです。 点検のたびに記録へ書いているので、取消も変更も反映済みです。月初にカレンダーを全部読み直すと、6分の実行の上限にも近づきます。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| Google カレンダー | Calendar の高度なサービス(Events.list) | 予約の増分同期と、前後の予約の取得。書き込まない |
| スプレッドシート | SpreadsheetApp | 名簿と決まりの読み取り、記録と確認の一覧と配賦の表の書き込み |
| Claude API | UrlFetchApp(構造化出力) | 試料と使用条件の照合 |
| Gmail | GmailApp | 規則の違反の知らせ(研究所の中のアドレスだけ) |
カレンダーには書き込みません。 規則の違反がある予約も、消さず、動かさず、色も変えません。予約者と管理者に知らせ、直すのは予約者です。 自動で消すと、名簿の更新が遅れていただけの予約まで消えます。
メールの宛先は、研究所のドメインのアドレスに限ります。 送る前に宛先のドメインを確かめ、外のドメインなら送らずに確認の一覧に入れます。 公式のページでは、Google Workspace のアカウントのメールの宛先は1日1,500までです。規則の違反の知らせは1日に数十件なので、届きません。
人が確認する
管理者が、確認の一覧に入った予約をすべて見ます。 入るのは、AIが条件を挙げた予約、情報の不足がある予約、根拠の照合に失敗した予約、書式に沿っていない予約です。
- 挙がった条件の原文を読む … 条件の表の文と、予約の記述の原文を並べて読みます
- 予約者に聞くかを決める … 聞くなら、管理者がメールか電話で連絡します
- 判断を記録に書く … 「問題なし」「前処理を依頼」「使用を見合わせ」のどれかと一言を書きます
- 条件の表を直す … 同じ問い合わせが続くなら、条件の行を足すか書き直します
3番目の記録が、月次の集計にも効きます。 「使用を見合わせ」とした予約は、利用料の配賦から外すので、記録の値で集計を分けます。
目標は、900件をならして1件1分です。 確認の一覧に入るのは2割ほどで、1件に数分かかります。残りの8割は、予約の記録の「点検済み」を流し見るだけです。
例外に対処する
| 起きること | 対応 |
|---|---|
| ロックが取れない | その回は何もせず終える。次の10分で拾う |
| 同期のトークンが使えない | 保存を消して全件の同期をやり直す。点検済みの予約は記録で飛ばす |
| 説明が書式に沿っていない | 点検をせず、予約者に書式で書き直すよう知らせる |
| 使用者が名簿に無い | 「講習の修了を確認できない」として知らせる。未修了とは言い切らない |
| 時間が重なる | 後から入った予約の予約者に知らせる。どちらを残すかは当事者と管理者 |
| AIの呼び出しが失敗する | 規則の点検だけを済ませ、確認の一覧に「試料の点検は未実施」と入れる |
| 根拠の照合に失敗する | 確認の一覧に入れ、管理者が説明を読む |
| 6分の実行の上限に近づく | 残りの機器は次の回に回す。トークンは機器ごとに保存済み |
4行目の書き方に気を付けます。 名簿に無いのは、名簿の更新が遅れているか、メールの書き違いか、本当に未修了かのどれかです。知らせの文は「確認できませんでした」にします。
最後の行は、全件の同期をやり直したときに起きます。 公式のページでは、Google Workspace のアカウントで1回の実行は6分までです。機器ごとに区切ってトークンを保存しているので、途中で止まっても、終えた機器はやり直しません。
記録を残す
- 予約の記録(予定ID、機器、使用者、部門、開始と終了、更新の時刻、規則の点検の結果)
- AIに渡した使用条件の行と予約の記述、返ってきたJSONの全文
- 管理者の判断と一言、判断した日時
- 規則の違反の知らせを送った宛先と日時
- 機器ごとの同期のトークンを保存した日時
- 配賦の表と、集計に使った予約の記録の範囲
2つ目で、そのときの使用条件の行を残すのは、条件が後から変わるためです。 条件を書き直すと、前の判断がどの条件に基づいていたかが分からなくなります。
最後の行は、部門からの問い合わせに答える材料です。 「この月の利用料が多い」と聞かれたとき、どの予約を足したかを予約の記録でたどれます。
04実装レベルの3段階
最小構成は、確かめるための段階です。 900件には使えません。 半自動化で、1件5分が1分になります。この段階が本記事の想定です。 探す、数える、名簿を引く作業がなくなり、管理者は確認の一覧に入った予約だけを見ます。 本格構成は、講習の管理を持っている研究所向けです。 名簿の更新の遅れによる「確認できない」の知らせが減ります。ただし、時間は半自動化からあまり減りません。 名簿の更新の運用が回っているなら、半自動化で止めてかまいません。
05工数削減シミュレーション
導入後 900件 × 1分 ÷ 60 = 15 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 企業の研究所、大学の共同利用の機器のセンター、病院の研究部門などで、電子顕微鏡・X線回折・質量分析などの共用機器を数十台持ち、機器ごとの Google カレンダーで予約を受けている場合。予約は月に数百件から千件ほどで、技術職員が予約の重複・講習の修了・時間外の決まり・試料の使用条件を1件ずつ見ていて、確かめ方が人ごとに違う場合。利用の時間を部門ごとに集計して、利用料を配賦している場合。
- 共用機器が数台で、予約が月に数十件の場合。予約を専用の機器の予約システムで受けていて、Google カレンダーを使っていない場合(そのシステムの機能で足りることが多い)。試料の安全の審査を、予約のたびではなく年1回の実験計画の審査で済ませている場合。なお、試料を機器に入れてよいかの最終の判断と、安全に関わる許可は、この構成では代替できません。
07最小構成で試す方法
- 先月の予約から20件を選ぶ(技術職員が予約者に連絡した予約を数件入れる)
- その機器の使用条件を、条件の番号を付けて1行1条件に書き直す
- 手元のAIサービスに使用条件と1件分の試料・薬品・目的を貼り、「当てはまりうる条件を番号と根拠の原文で挙げて。使ってよいかは書かないで。書かれていない性質を補わず、不足として挙げて」と指示する
- 出てきた結果を、当時の技術職員の連絡と並べて読む
20件は必ずやってください。 スクリプトを書く前に、「使用条件の書き方で、AIが管理者と同じ予約を拾えるのか」を確かめます。
| 出てきた内容 | 判断 |
|---|---|
| 当時連絡した予約が拾え、根拠も合っている | スクリプトを書く段階に進む |
| 「使用に問題なし」と結論を書く | 指示の書き方で直る。構成は有効 |
| 当時連絡した予約を拾えない | 使用条件の書き方が先。 条件が長い文のまま |
3行目は珍しくありません。 技術職員が連絡していた理由が、使用条件の表に書かれていない経験であることが分かります。その経験を条件の行に書き足すことが、この構成の最初の成果です。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| カレンダーのトリガーでどの予定が変わったか分からない | 教えてくれない。 増分同期で拾う |
| 公式の例をそのまま写して変更を取りこぼす | return を continue にし、トークンは最後に保存する |
| 知らせが2通届く | ロックを取り、予定IDと更新の時刻で点検済みを飛ばす |
| 消された予約が利用料に入る | cancelled を拾い、記録で集計から外す |
| 説明の HTML で書式が読めない | タグを外してから行で読み分ける |
| 「使用に問題なし」と結論を書く | 指示で禁じ、確認の一覧で結論の文が無いかを見る |
| 書かれていない性質を補って「該当なし」 | missing_info を用意し、補うことを禁じる |
| 名簿に無い人を未修了と言い切る | 「確認できませんでした」と書く |
| 構造化出力で400が返る | 数値の minimum・maximum は使えない。 スキーマから外す |
| 個人のアカウントで作ったトリガーが止まる | 機器管理用のアカウントで作る |
上の3行が、この構成の失敗のほとんどです。 どれも増分同期の扱いで、予約を取りこぼすか、同じ予約で何度も知らせるかのどちらかになります。最初の1週間は、予約の記録とカレンダーを毎日見比べます。
真ん中の3行は、AIの返し方の問題です。 結論を書かせない、補わせない、を指示と出力の形の両方で守ります。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 研究員の氏名とメール、部門、講習の修了の記録、機器の予約の時刻、予約の説明に書かれた試料と薬品と目的です。試料と目的は、まだ公開していない研究の中身を含みます。
- AIに渡す項目を絞る … AIに渡すのは試料・薬品・目的の3行と使用条件の行だけです。使用者のメールや部門、研究テーマの名前は渡しません
- 研究の中身の扱いを決める … 試料と目的の記述が、社外のAPIに出てよい情報かを研究所で決めます。出せない研究テーマは、目的の行を空にして渡す決まりにできます
- 試料の可否を決めさせない … AIは候補を挙げるだけで、入れてよいかは管理者が決めます。 安全に関わる許可は、研究所の決まりの手続で行います
- 予約を自動で消さない … 規則の違反でも、知らせるだけにします。名簿の更新の遅れで、正しい予約を消さないためです
- 知らせを研究所の外に送らない … 宛先のドメインを確かめてから送ります
- API キーをスクリプトのプロパティに置く … コードに直接書かず、機器管理用のアカウントの管理者だけが見られるようにします
誤りが起きた場合のリスクは、条件に合わない試料を見落とすことと、正しい予約を違反として扱うことの2つです。 前者は「当てはまりうる」で広く挙げさせ、不足を返させることで、後者は予約を消さず「確認できませんでした」と書くことで抑えます。どちらも、管理者が確認の一覧を見ることが最後の止めになります。
10まず何から始めるか
1週目:予約の説明の書式と使用条件の行を決める
予約の説明の5行の書式を決め、研究員に知らせます。24台の使用条件を、条件の番号を付けた1行1条件に書き直します。利用の多い5台から始めます。
2週目:20件で試す
先月の予約20件を手元のAIサービスに貼り、使用条件に照らして当てはまりうる条件を挙げさせます。当時技術職員が連絡した予約を拾えるか、結論を書いていないかを最優先で見ます。
3週目:増分同期と規則の点検を作る
Apps Script で5台のカレンダーを増分同期し、重複・講習・上限・時間外の点検を予約の記録に書きます。この時点ではAIを呼ばず、知らせも送りません。 予約の記録とカレンダーを毎日見比べ、取りこぼしが無いかを見ます。
4週目:AIの照合と確認の一覧を足す
試料と薬品の照合を足し、確認の一覧に入れます。規則の違反の知らせは、まだ管理者にだけ送ります。
2か月目: 24台に広げ、予約者への知らせを始めます。月初の集計で配賦の表を作り、手で数えた表と見比べます。 3か月目以降: 管理者の判断の記録から使用条件の行を直し、1件5分が何分になったかを実測します。手で数えた配賦の表と自動の表が一致し、確認の一覧の量が落ち着いた時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
| カレンダーのイベントのトリガーが予定の作成・編集・削除で動くこと。時間主導型が1分ごとから月1回まで選べ、時刻が少しずれうること。インストール型のトリガーが作った人のアカウントで動くこと | Apps Script: Installable Triggers | 2026-10-15 |
カレンダーの更新のイベントが calendarId などを持ち、どの予定がどう変わったかを教えないこと。保存した nextSyncToken で増分同期をするよう書かれていること | Apps Script: Event Objects | 2026-10-15 |
Calendar の高度なサービスで Events.list を syncToken 付きで呼び、ページをたどって nextSyncToken を保存する例。トークンが使えないときに保存を消して全件の同期をやり直すこと。例が取り消しと終日の予定で return すること | Apps Script: Advanced Calendar Service | 2026-10-15 |
予定の creator.email、description が HTML を含みうること、status の cancelled が取り消された(削除された)予定であること、開始が含まれ終了が含まれないこと、updated | Google Calendar API: Events | 2026-10-15 |
everyMinutes() に1・5・10・15・30を指定できること。onMonthDay()・atHour() と、nearMinute() の分が前後15分ずれうること | Apps Script: ClockTriggerBuilder | 2026-10-15 |
getScriptLock() がどの利用者からもコードの部分を同時に動かさないためのロックであること | Apps Script: LockService | 2026-10-15 |
| Google Workspace のアカウントで1回の実行が6分まで、URL Fetch が1日10万回まで、メールの宛先が1日1,500まで、プロパティの値が9KBまでであること | Apps Script: Quotas | 2026-10-15 |
構造化出力で output_config.format に type: "json_schema" を渡すこと。オブジェクトの additionalProperties を false にし、数値の minimum・maximum が使えず400になること | Claude: Structured outputs | 2026-10-15 |
試料を機器に入れてよいかの判断と安全に関わる許可は、研究所の決まりの手続で行ってください。 本記事は Google と Anthropic の公式ページで確認できた範囲の機能だけを使っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1740)についてのご相談はこちらから。
