第1幕: 持ち込み ── 気づいたときには、もう四日でした
月が変わったばかりの深夜だった。記録机には、先月分の綴じ込みの隣に、まだ表紙も汚れていない新しい綴じ込みが用意されている。角が立ったままの表紙は、まだ誰の手にも馴染んでいない。私はそれを一瞥するだけで、特に何も思わなかった。月初めの備品交換、それだけのことだと思っていた。
サカキの視線は、表示盤に注がれたままだった。緑の点は、いつもと変わらず規則正しく動いている。空調の低い音がいつもより大きく聞こえるくらいで、この夜は特別なことなど何も起きていないように見えた。ペン立てのインクの匂いも、いつもと同じ場所に、いつもと同じ濃さで漂っている。
数日前、短いメールが一本届いていた。「近いうちに、相談したい」とだけ。緊急とは書かれていなかったので、来訪の時刻は決めないままにしていた。私はその一行を記録の下書きに留めておいたが、いつ来るかは分からないまま、何日か過ぎていた。その来訪が、今夜だった。
ドアが開く音が、いつもよりゆっくりだった。押し開ける手に、いつもの勢いが無い。
「……すみません、遅い時間に」
ヌマタさんが入ってくる。言葉がそこで止まる。詫びの続きを言う体力が、残っていないように見えた。コートの肩が少し傾いていて、目の下には、四日分の夜が積もっているのが分かるような色が沈んでいた。サカキが表示盤から目を離し、椅子を勧める。
「座ってください」
ヌマタさんが腰を下ろす。腰かけるというより、崩れ落ちるように座った、という方が近かった。私はページの頭を「来訪」の一語だけで起こした。予約でも、緊急の飛び込みでもない。時刻を書いてから、その欄をどう埋めればいいのか、少しだけ迷った。この四日間、ヌマタさんがどんな時間を過ごしてきたのか、その欄の狭さでは書ききれない気がした。
しばらく、誰も何も言わなかった。表示盤の点滅の音だけが、規則正しく続く。ヌマタさんが黙っていたのは、言葉を選んでいるからではなく、言葉を出す力そのものが薄くなっているからのように見えた。それから、絞り出すように言う。
「先週の木曜から、止まっているんです。議事録の要約が」
私は「来訪」の欄の続きを書く。いつもより一拍、間を置いてから書き始めた。ペン先が紙に触れる音が、この夜はやけにはっきり聞こえた。
サカキ「止まってから、今日まで」
ヌマタさん「四日です。六部署ぶん、二十件くらい……全部、自分の手でやりました」
声に張りは無かった。誇示でも訴えでもなく、事実をそのまま述べる調子だった。
私の独白:六部署、二十件。それを四日間、一人で。数字だけを聞いて、その重さが分かった気がした。手作業で議事録を要約するというのが、どれほどの時間を食う仕事か、私には想像するしかなかったけれど、ヌマタさんの声の疲れ方が、その想像を裏付けていた。会議のたびに、原稿を最初から読み、要点を拾い、部署ごとの言い回しに合わせて書き直す。それを、日中の本来の仕事の合間に、四日間続けていた計算になる。
サカキ「木曜の朝、何か変わったことは」
ヌマタさん「特には……いつも通り動くはずでした。動くと、思っていました」。言葉の途中で、少し力が抜けた。「気づいたのは、その日の夕方です。総務の一部署から、要約がまだ届いていないと連絡があって。確認したら、他の部署の分も、全部止まっていました」
サカキ「そこから、四日間」
「はい。エラーの通知も、何も来なかったので、直せば動くだろうと思っていたんです。でも、何をどう直せばいいのか、分からなくて」
サカキ「原因はまだ分かりません。まず、何が起きたのかを、順番に見ましょう」
ヌマタさんが小さくうなずいた。私は「原因」の欄をまだ空白のまま残し、次の欄に移った。分かっていないことを、分かっていないと書く。それも、記録の仕事のうちだった。
第2幕: 照合 ── いつ、いくら使ったか、言えますか
ヌマタさんがノートパソコンを開いた。手つきが、少し遅い。
「仕組みは、こうなっています」
画面に表示されたコードを、サカキが覗き込む。
| |
「半年前、自分の部署のために作ったんです」。ヌマタさんが、誇らしげでも動揺でもなく、淡々と続けた。「それが、便利だからって、他の部署にも広がって」
サカキ「六部署に広がるのは、当然の流れです。使う人が増えるのは、仕組みが機能していた証拠です」
ヌマタさんが小さくうなずいた。「そう言ってもらえると……でも、費用のことは、誰も言い出さなくて」。少し間を置いて、続けた。「最初は、自分の部署の三人ぶんだったんです。それが、今は六部署、四十人近くが読んでいます。広げてほしいと言われるたびに、断る理由も無くて」
「六部署からの週次議事録を、順番にAIへ渡して、要約を集めて返す。それだけです」とヌマタさんが説明を続けた。私はコードを目で追う。処理の中に、費用に関する記述がどこにも無い。毎週月曜の朝に、まとめて動かす仕組みだという。前の週にあった会議の分を、週明けの朝までに、各部署のフォルダへ配る。それが半年間、ずっと続いていた。
サカキ「毎週、動かしていた」
ヌマタさん「はい。月曜の朝、出社したら、フォルダに要約が入っている。それが、当たり前になっていました」
サカキ「動くのが当たり前だと思えるほど、うまく機能していた、ということです」
サカキ「今、ここまでで、いくら使っていますか」
ヌマタさんが言葉に詰まった。「……分かりません。今すぐには」
サカキ「では、先週の分は」
「請求書が来ないと、正確には……」
サカキ「請求書は、いつ届きますか」
「月末です」
サカキ「今日は、月の半ばです。今月分の請求は、まだどこにもありませんね」
沈黙が落ちた。ヌマタさんが「……はい」とだけ言う。私はこの四つの往復を、削らずに一言一句、欄に写し取った。要約するべきではないと思った。この問答のリズムそのものが、起きたことの説明になっていたから。
サカキ「使ってしまった分は、もう戻せません。せめて、使う前に、止められる場所が要ります」
ヌマタさんが顔を上げた。「止める場所なんて、考えたこともありませんでした。動いているのが、当たり前だと思っていたので」
サカキが少し間を置いてから続けた。「返ってきた応答には、実は費用の情報も含まれています。ただ、このコードは、それを一度も読んでいません」
ヌマタさんが画面のコードをもう一度見た。reply["body"]だけを取り出して、replyそのものにあった他の値には触れていない。受け取ってはいるのに、使っていない——サカキがそう言葉にすると、ヌマタさんは何も言わず、ただ小さく息を吐いた。
「一度、実際の動きを確かめてみましょう」。サカキが言った。確かめる前に、一つだけ言葉にしておく。「上限を超えても処理が止まらない——それを、今夜のところは異常として扱っていいですか」
ヌマタさん「はい、それで構いません」
「では、それだけを異常とします。ほかは、まだ決めていません」
サカキが台本を流し込む。合計すると設定した上限をはるかに超える消費になる、七件ぶんの台本だった。表示盤の隅で、処理の進み具合を示す点が一つずつ増えていく。一件、二件、三件……ヌマタさんの視線が、その点を追っていた。
……最後まで動いてしまった。上限を大きく超える台本を与えても、今のコードは何も言わずに七件すべてを処理しきる。エラーも警告も、どこにも出ない。表示盤の点は、静かに七つ並んで止まった。何事も無かったかのように。
ヌマタさんが小さく息を吐いた。「これが、先週、実際に起きたことです。何も知らせずに、動き続けて……気づいたら、請求が跳ね上がっていました」
私の独白:止まったのではなかった。止められる場所が、どこにも無かった。表示盤に並んだ七つの点は、何も間違っていないという顔をして、そこにあった。
第3幕: 指令の一手 ── 決めていないものは、止められない
ヌマタさん「どうすれば、次は止められたんでしょうか」
サカキ「消費を積み上げて数え、上限に近づいたら知らせ、届いたら止める。Budget Guard(予算ガード)——処理ごとの消費を計測・積算し、しきい値で通知し、上限で明示的に止める仕組みです」
そして、一言付け加えた。「これは、流れてくる速さを抑える仕組みとは違います。今夜の話は、速さではなく、積み上がった総量です」
私はその一言を、少し丁寧に記録に書き取った。似た名前の仕組みと混同されないように、サカキが自分から線を引いたのだと分かったからだ。
サカキがコードを示した。
| |
ヌマタさん「BudgetGuardは、これまでのコードに出てきた器と、少し形が違いますね」
サカキ「気づきましたか。今回は、frozen=Trueを付けていません。これまで見てきた器は、書き換えを許さないことで、渡された時点の中身をそのまま保つためのものでした。これは逆に、呼び出しのたびに積み上がる状態そのものを持つ必要があります。書き換わることが、仕事の器です」
ヌマタさん「使う前に、完全に止めることは、できないんですか」
サカキ「一件ぶんの費用は、実際に応答が返ってくるまで分かりません。だから、使う前に完全に止める、ということはできません。できるのは、次を始める前に、今の残りを確認する、ということだけです」
ヌマタさんがコードのhas_capacityを指でなぞった。「ここが、その確認……」
サカキ「はい。妥協ではありません。費用が、あとから確定するものである以上、そうするしかない、という設計です」
サカキの説明を、私は図に起こしてみた。一件ごとに、二つの見張りが待ち構えている。始める前の関門と、終わった後の見張り。ヌマタさんの視線が、その図の上をたどっていく。

関門で止められた台本は、記録にすら残らない。見張りは、通り過ぎたあとで一度だけ声を上げる。二つの役割は、同じ器の中にありながら、別々の仕事をしていた。
ヌマタさん「じゃあ、ぎりぎりのところで、上限を少し超えてしまうことも」
サカキ「次を始める前には残っていた枠が、その一件の応答の分だけ、上限を超えることは考えられます。どこまで超えうるかは、あとで実際に確かめましょう」
ヌマタさんは、意外そうな顔をしなかった。むしろ、はぐらかされなかったことに、少し安心したような表情だった。「完璧に止まる、と言われるより、確かめられる方が、信じられる気がします」
続けて、実務の話に触れた。「大手のAPI提供者にも、同じ考え方があります。エンフォースメント(実際に働く仕組み)は瞬時ではなく、記録された支出額は、わずかに設定額を超過しうる、とその提供者自身が明記しています。私たちの仕組みも、同じ限界を持ちます」
サカキがBudgetGuardのコンストラクタを指した。「上限も、警告の線も、コードの中には書きません。外から渡します」
ヌマタさん「なぜ、コードの中に書かないんですか」
「決めていないものは、止められない。それだけのことです」
私はここで手を止めた。様式が決まっているから、私は迷わず書ける。ヌマタさんの四日間は、決まっていないところに、迷いながら立ち続けた四日間だったのかもしれない。そう思ったところまでを、独白として一拍だけ挟んだ。
ヌマタさん「上限は、いくらにすればいいんでしょうか」
サカキ「それは、こちらでは決められません。それを決めるのは、この仕組みを使う側です」
少し間を置いて、続けた。「六部署が使うものなら、費用の責任も、六部署のどこかが持つ必要があります。今は、誰も持っていませんでした」
「もう一つ、見ておきましょう」。サカキが配線のコードを示す。
| |
「呼び出す側は変わりません。変わるのは、この組み立ての中身だけです」
サカキが少し付け加えた。「しきい値は、一つに絞る必要もありません。段階を増やすこともできます。実際、複数の通知しきい値を持たせられる設計にしている例もあります」
ヌマタさんがうなずいた。「私が決めるべきことと、仕組みが決めることが、今、はっきり分かれた気がします」
第4幕: シミュレータと引き渡し ── 財布の中と、財布の残高
もう一度、同じ台本で動かしてみる。今度は六本、結果を私が一つずつ読み上げた。
| |
台本は、七件それぞれが同じ費用を消費するように組んである。五件処理したところで累計が警告のしきい値に届き、通知が一度だけ鳴った。六件目まで処理が進み、そこで累計は54まで積み上がっていた。七件目に取りかかろうとしたその瞬間——has_capacity()が「もう無い」と答え、処理はそこで止まった。
私はその推移を、記録の欄外に運行図として描き起こした。一件ごとの点を横一列に並べ、積み上がっていく高さを、そのまま消費の重みとして描く。五件目の点には、警告の印を一つ。六件目の点の先には、上限の線を四つぶんはみ出す高さ。七件目の点は、線を引く前に消えていた。着手されないまま、運行図の上にも残らなかった。

描き上げてみて、ようやく数字の意味がつながった。警告は五件目、超過は六件目、停止は七件目――ばらばらに聞いていた三つの出来事が、一本の線の上に並んでいた。
サカキが結果を噛み砕く。「六件目までは、届いています。七件目には、手を付けていません」
上限は50だったのに、止まった時点の累計は54。四つ、超えていた。ヌマタさんがその数字に気づいて、目を上げる。
サカキ「六件目を始める前は、まだ45でした。枠は、五、残っていた計算です。でも、その一件の応答は九かかった。だから、54まで進みました。さっき話した、超えることもある、というのは、この四のことです」
もう一本、確かめる。
| |
止まったからといって、それまでの六件が消えるわけではない。例外そのものが、そこまでの成果を抱えたまま止まる。ヌマタさんがその一覧を見て、初めて少しだけ表情が緩んだ。「四日間、私が手でやった分が、無駄じゃなかった、みたいな話ですね」
サカキ「止まることと、失うことは、別です。止める仕組みを作るときに、そこまでの分を投げ捨てる必要はありません」
ヌマタさん「呼び出す側は、止まったこと自体は知るんですよね」
サカキ「はい。BudgetExceededという例外が届きます。呼び出す側は、それを受け取って、六件までの結果をどう使うか——配布するか、保留するか——を、自分で決められます」
私はその一言を、記録の欄外に小さく書き添えた。止まったあとに何をするかまでは、この仕組みは決めない。決めるのは、また別の場所だという線引きを聞くのは、今夜はもう何度目かになる。
サカキが区切って言葉にする。
保証すること。累積消費が上限に達したとき、次の処理が始まる前に止まること。警告のしきい値を超えたとき、一度だけ知らされること。上限に達していないあいだは、これまでと同じ結果が返ること。
保証しないこと。すでに動き出している処理の費用まで、止められないこと。プロセスの中で数えた消費と、実際の請求額が、完全に一致すること。上限や警告の数値そのものを、誰がどう決めるかということ。
サカキ「分かったのは、この範囲だけです。財布の中を数えることと、財布そのものの残高が合っているかは、別の話です」
「これは、一つの処理が、順番に進む場合の話です」。サカキが続けた。「複数の処理が、同時に同じ予算を使っていたら、この足し算はもっと崩れます。その崩れ方までは、今夜は扱っていません」
私はそれも、そのまま書いた。
記録を書き終えたところで、ふと備品棚の前に立った。月初めの在庫確認は、記録係の小さな仕事の一つだ。棚の扉を開けると、インクの匂いに紙の匂いが混じる。ペンと用紙の減り具合を、指で数える。用紙だけは、いつも十分にある。むしろ、使う分より多いくらいだった。他の消耗品——付箋や、綴じ紐や、予備のインクは、補充がしばらく止まっているようだった。理由は考えなかった。ただ、いつもの月初めの所作として、それだけをした。棚の扉を静かに閉じる。
ヌマタさんが荷物をまとめながら、ぽつりと言った。「仕組みのことは、分かりました。でも、上限をいくらにするか、私一人では、決められない気がします」
サカキは止めなかった。「そうですね」とだけ言う。
ヌマタさんが顔を上げた。「上の人にも、決めてもらいます。これは、私だけの仕組みじゃなくなっていたので」
サカキが最後に一言添えた。「仕組みは、渡せます。決めるのは、そちらです」
ヌマタさんが、荷物を抱え直しながら言った。「今夜は、話を聞いてもらえただけで、だいぶ楽になりました」
疲労の中に、わずかに力が戻っているような調子だった。足音が遠ざかる。
私の独白で、この夜を閉じる。今夜、渡せたのは、止め方だけだった。誰が決めるかは、まだ、これからのことだ。
🚦 本日の指令記録(Dispatch Log)
- 指令の定石(パターン名): Budget Guard(予算ガード)── 処理ごとの消費を計測・積算し、警告のしきい値で通知し、上限のしきい値で明示的に処理を止める仕組み
- 申告された症状: 「議事録の一括要約が先週木曜から止まり、六部署ぶん約二十件を四日間手作業で凌いだ」。原因は分からないまま持ち込まれた。実際には、原資(利用費用)に上限を置いておらず、消費を計測・記録する場所もどこにも無かった
- 今の運行計画の問題: 半年前に一部署の便利ツールとして始まり、要望に応えて六部署へ正式展開された経緯自体は合理的だった。ただし展開のたびに、費用の上限を誰が決めるかという所有者を、組織として誰も割り当てていなかった
- 打った一手: 消費を積算する
BudgetGuardを導入。次の処理を始める前に残枠を確認し、警告のしきい値で一度だけ通知、上限のしきい値でBudgetExceededを送出して止める。上限・警告の数値はコードに埋め込まず、外から注入する - 配線した場所: 起動時の組み立て(
build_batch)。上限をいくらにするか・誰に知らせるかは、この組み立ての中身だけを差し替えれば済む。summarize_allを使う側は、これまでと同じ書き方のままでよい - 保証しないこと: すでに動き出している処理の費用は止められない。プロセス内で数えた消費と、実際の請求額が完全に一致することは保証しない。上限・警告の数値そのものを誰がどう決めるかという運用は、この一手の範囲外
- シミュレータ結果: 6本。Beforeが上限を超えても最後まで処理を続けてしまうこと、Afterが上限到達時に次の処理の前で止まること、そこまでの結果は失われずに残ることを確かめた
- 次の当直への申し送り: 今夜渡せたのは、止め方だけ。上限をいくらにするかは、まだ決まっていない
原資に上限を決めず走らせているシステムがあれば、消費の計測・警告・上限での停止という設計を承っています。動いているものを止めずに、止まり方だけを組み込む相談です。
