昼下がりのからくり人形劇場。赤いベルベットの重厚な緞帳が静かに下りた薄暗い舞台袖には、独特の時間が流れています。天井から吊るされたガスランプの揺らめく光が、磨き込まれた真鍮の歯車や古いマホガニー材の柱に深い影を落とし、空気中には機械油と焦げた金属、そしてどこか甘い蜜蝋の匂いが漂っていました。
そんな静寂を切り裂くように、不穏な金属音が舞台裏の隅々まで響き渡っていたのです。
カチカチ、カチカチ、カチカチ。
私は作業台の前に立ち、込み上げてくる焦燥感に追われながら額の汗を拭いました。すぐ隣では、マエストロがいつもの使い古された黒い燕尾服の袖を少しだけ捲り上げ、自律人形アンの膝関節に丁寧な仕草でオイルを差し、小さな真鍮の工具でネジの噛み合わせを調整しています。私の手元からどれほど耳障りな音が響いていようと、マエストロは一度もこちらを振り向くことなく、ただ黙々と自身の仕事に没頭しているように見えました。
私たちの目の前の作業台に鎮座していたのは、街の繁華街にある老舗の仕立て屋「針と糸」の店主、ハリスさんから持ち込まれた一体の自動裁断人形です。
名前は「ルネ」。上品な燕尾服をまとった紳士のような佇まいで、極細の真鍮で編まれたしなやかな指先を持ち、その右手の先端には裁断用の鋭利なハサミを装着できる、非常に器用で精巧な人形でした。街の人々からは「せっかちな仕立て屋」という愛称で親しまれ、職人の右腕として頼りにされている素晴らしい作品のはずでした。
しかし今、ルネは私たちの舞台袖で、とんでもない暴走を起こしていたのです。
第1幕: 予兆と調律 ── 振り回されるハサミ
ハリスさんが深い溜息とともにルネを工房へ運び込んできたのは、ちょうど昼の鐘が鳴り終わった頃でした。長年の仕立て作業で指先に分厚い豆を作った老仕立て職人は、焦りと疲労の色を濃く滲ませた顔で、作業台の端に重そうな布地の包みを置きました。
「コレットちゃん、どうか頼むよ。このままじゃ、わしの店は信用も資金も底をついてしまう」
ハリスさんの声は、いつもよりずっとしゃがれていました。彼の店「針と糸」は今、秋の社交界シーズンを迎えて貴族たちからの仕立て注文が殺到し、工房は夜通し明かりが消えないほどの繁忙期にあります。中でもハリスさんを追い詰めていたのは、間近に迫った大舞踏会のために注文された、「月の光を模した絹布」で仕立てる最高級の上着でした。
真夜中の月の光をそのまま織り込んだかのように青白い光沢を放つその絹布は、驚くほど繊細で、わずかな摩擦や引っ張りでも繊維が傷んでしまう極上の品です。仕立ての精度はミリ単位が求められ、一度でもハサミを入れる角度や幅を誤れば、布地は台無しになり、仕立て直しは利きません。高級素材の損失は店にとって致命的な大赤字を意味し、何より「針と糸」が数十年かけて築き上げた名門の看板に泥を塗ることになります。
「老いぼれたわしの目と手では、月の光のような絹を寸分の狂いなく断ち切るのに、どうしても時間がかかる。だからこそ、機械の正確な目と疲れを知らない真鍮の関節を持つルネに、裁断の大役を任せようとしたんだ。それなのに……この子は、とんでもない癖をつけちまったみたいなんだよ」
ハリスさんが目の前で広げた月の光を模した絹布の上着には、仮縫いの途中で不可解な切れ込みがいくつも入っていました。まるで、何かに怯えて無闇に刃を振るったかのような、痛々しい傷跡です。
私はハリスさんを安心させるように小さく頷き、舞台袖の試運転スペースでルネの起動ネジを巻きました。ルネの胸の奥には、あらゆる人間の言葉を理解し、思考を巡らせて行動を組み立てる 大規模言語モデル(LLM) が据えられています。これは膨大なテキストデータを学習し、自然言語の理解や推論を行う思考の核であり、ルネはこの核の判断に従って指先のハサミを操る仕組みになっていました。
「さあ、ルネ。まずは仕立ての準備よ。上着の寸法を測りましょう」
私がお客のふりをして声をかけると、ルネの水晶の目に青い灯りがともり、胸の奥のオルゴールが微かな駆動音を立てて回り始めました。
「寸法を測ります。肩幅は四十センチメートル、袖丈は……」
ルネは上品な紳士のような柔らかな声で呟きながら、左手でメジャーを手に取る……はずでした。しかし、その丁寧な言葉とは裏腹に、右手の先端に装着された鋭利なハサミが、突如としてカチカチ、カチカチと激しい金属音を立てて開閉し始めたのです。
「ああっ、危ない!」
私が叫ぶのとほぼ同時に、ルネの右腕が不自然な軌道で跳ね上がりました。鋭い刃先は、ハリスさんが調整の参考にと作業台の端に置いていった、月の光を模した絹布の上着の裾へと容赦なく襲いかかったのです。
サクッ、シャキッ。
無慈悲な音が薄暗い空間に響き、美しい銀色の絹糸が宙に舞い上がりました。切断された高級絹布の破片が、まるで悲しい雪のように床へとハラハラと落ちていきます。
「寸法を測定中ですが、ハサミの準備は完了しています」
ルネは自身の指先が何を破壊したのかなど自覚していないかのように、平然と紳士の口調で言い放ちました。
裁断の指示など、私は一言も出していません。ただ「寸法を測る」という作業をお願いしただけです。それなのに、ルネはハサミという小道具を一度握りしめると、寸法を測っているときも、生地にアイロンをかける手順のときも、さらにはボタンの位置を確かめるだけのときでさえ、常にその刃をカチカチと動かさずにはいられないようでした。
「糸の引き方が雑なのよ、コレット」
マエストロの隣で膝関節の調整を終えたアンが、椅子から立ち上がって自身のドレスのフリルを気にしながら、冷ややかに言い放ちました。その磁器の肌は美しく磨かれていますが、声には容赦のない批判が込められています。
「そんな物騒な凶器を常に振り回す人形の隣で、私が優雅に踊れると思う? あなた、自分の拙い操糸術のせいで、私のこの大切なドレスまでズタズタに切り裂きたいわけ?」
「そんなわけないじゃない、アン! ちゃんと指示は出しているのよ!」
私は慌ててルネの強制停止スイッチを押し、胸の奥にある思考のゼンマイと、頭部から関節へと繋がる極細の伝達糸 ── プロンプト を確認しました。これは人形の思考のゼンマイへ与える指示文や制約の言葉であり、人間で言えば行動の規範やマニュアルに相当するものです。
ハリスさんは散らばった絹布の破片を拾い上げながら、悲痛な面持ちで私に問いかけました。
「コレットちゃん、なぜこんなことが起きるんだい? わしら人間なら、『寸法を測るときはハサミを使うな』『切るべきときだけ切ってくれ』と一度言葉で言い聞かせれば、ちゃんとハサミを台に置いてメジャーを持つ。なぜ、これほど立派な思考のゼンマイを持つ人形が、そんな簡単な約束を守れずにハサミを振り回してしまうんだ? 言葉で注意しても、結局また同じことの繰り返しになってしまうんじゃないだろうか……」
ハリスさんの切実な疑問は、人形遣いとしての私の胸を鋭く突き刺しました。
なぜなら、人間に対する「お願い」と同じ感覚で人形に言葉を伝えても、思考のゼンマイは私たちの期待通りには受け取ってくれないからです。人間の言葉という自由な文字列の中に「いつ道具を使うべきか」「どのように道具を操るか」というルールを混ぜ込んでしまうと、LLMはその言葉の広がりや曖昧さに迷い、文脈を拡大解釈してしまいます。
「寸法を測るということは、仕立ての作業である。仕立てといえばハサミが必要だ」── ルネのゼンマイの中で、そんな独自の連想が勝手に結びつき、結果として不要な場面でも条件反射のようにハサミの引き金を引いてしまっているのです。
私はルネの背中の蓋を開き、複雑に絡み合った伝達糸を見つめながら、ハリスさんとアンの懸念を払拭するために、より強力で絶対的なルールを編み込む決意を固めました。
第2幕: 絡糸と破綻 ── がんじがらめの約束事
ルネが不要な場面でハサミを実行してしまうのは、伝達糸を通じた「ハサミを動かすタイミングと手順」の指示が、まだどこか曖昧だからに違いない。私はそう考えて、作業台の上のインク瓶にペン先を深く沈めました。
「人間と同じように曖昧に解釈する余地があるから迷うのよ。だったら、絶対に解釈を違えないほど、細かく、厳格に、例外を封じる禁止事項を書き連ねてみせるわ」
私はルネのシステムプロンプトという羊皮紙に、次から次へと厳しい約束事を書き加え始めました。それはまるで、人形の手足に何本もの太い縄を縛り付けるかのような作業でした。
「ルールその一:ハサミ(cut)を使うのは、生地を裁断する明確な指示があったときだけです」
「ルールその二:寸法を測っているとき、アイロンをかけているとき、仮縫いをしているときは、絶対にハサミを動かしてはいけません」
「ルールその三:ハサミを実行するときは、通常のセリフの中には書かず、必ず [action:cut,width:幅,angle:角度] という独自のブラケット記法をセリフの末尾に一言一字違わずに配置しなさい」
書き終えて一度テストを流すと、ルネは「裁断の準備をします」という言葉に対して、ハサミを動かそうとしました。私はペンを強く握り直し、羊皮紙にさらなる行を付け足します。
「ルールその四:『準備』や『確認』の段階では、いかなる理由があろうともブラケット記法を出力してはならない!」
私の手元は忙しく動き続けました。糸を張り、結び目を増やし、ある条件をふさいでは、別枠の例外を書き足す。額からは汗が流れ、指先はインクで真っ黒に汚れていきます。ひとつの穴をふさぐと、文脈の解釈という別の壁に新たな穴が開く。私は無我夢中で禁止事項と条件分岐を積み重ねていきました。
そして、Pythonで書かれたルネの制御ロジックを、以下のように書き換えました。ルネが自由な会話テキストとして出力した文字列の中から、私が定めたブラケット記法を探し出し、文字列操作(split)によって力任せにハサミの引数を取り出そうとしたのです。
ちなみに、ゼンマイへ届く言葉は二通りに分かれています。羊皮紙に書き連ねた常設の約束事は system として、お客のその場の指示は user として、それぞれ糸に乗ります。
| |
「よし。これだけ細かくプロンプトに禁止事項を書いたし、出力形式も指定したんだから、もう間違えないはず。とりあえず動いてるからいいのよね!」
私はペンを置き、胸を張ってリハーサルの開始を宣言しました。舞台袖の試運転エリアに、ルネと、監視役としてアンを向かい合わせて立たせます。
私はテスト用の指示を入力しました。「ルネ、アンの仮縫いを手伝ってあげて」。
その瞬間、ルネはゆっくりと滑らかな足取りでアンの方へと歩き出しました。水晶のレンズが、アンが誇る純白のフリルドレスの裾に焦点を合わせます。
「仮縫いのお手伝いをいたします。ドレスの裾を持ち上げますね。おや、裾のラインを美しく整えるために、ほつれた糸を少し切る必要があります。[action:cut,width:5]」
カチカチカチッ!
不気味で金属的な駆動音が響き、ルネの真鍮のハサミがアンのドレスのフリルへと鋭く迫りました。
「ちょっと! 近寄らないで! あなた何をしているの!」
アンが上品な悲鳴を上げ、絹のフリルを両手でかばいながら後ろへと飛び下がりました。私は悲鳴を上げてルネの緊急停止用の糸を全力で引っ張りました。
しかし、私の目が水晶盤の出力ログを捉えた瞬間、全身の血の気が引くのを感じました。ルネがセリフの末尾に出力した文字列は [action:cut,width:5] となっており、私が絶対に書けと指示したはずの、角度を指定する angle の値が完全に欠落していたのです。
そのため、Python側に組み込んだ私の力任せのパースロジックは、カンマで分割した parts リストの3番目の要素である parts[2] にアクセスしようとした瞬間に、無情にも IndexError を引き起こしました。
ガガガッ、ピィン!
内部の歯車が激しく衝突する音が響き、ルネは片腕を高く上げ、ハサミの刃先を小刻みに震わせたまま、ひどく見苦しい姿勢で完全にフリーズしてしまったのです。
「がんじがらめの糸(ルール)で人形を縛り付けた結果がこれね」
アンが壁際に避難し、切り裂かれかけたフリルの目飛びを指先でなぞりながら、深い溜息とともに私を睨みつけました。
「『仮縫いだけど、ほつれ糸を切る』なんていう文脈の例外を、あの子のゼンマイが勝手に作り出してしまったのよ。それに見て、ルールをあまりに多く詰め込みすぎたせいで、あの子は言葉の出力に精一杯になって、肝心の引数フォーマットを落とすというヘマをやらかしたわ。こんな細かくて不安定なルールで縛られたら、私だって頭のゼンマイが焼き切れてしまうわ」
アンの言葉に、私は反論すらできずに頭を抱え込みました。
どうして、これほど細かく禁止事項を並べても失敗するのでしょうか。私は前話の経験を通じて、LLMという思考のゼンマイが 非決定的な挙動 を持つことを学んでいたはずでした。これは同じ入力に対しても毎回同一の出力を返すとは限らない、確率的な生成の性質です。
しかし、前話で扱った「出力の形(JSONフォーマット)」の乱れと、今回私が直面している「行動の引き金(ハサミの実行)」の制御では、危険の性質が全く違っていたのです。
自然言語という自由な会話文字列の中に、人形の物理的な行動トリガーと引数を載せる設計は、原理的に破綻する宿命を背負っていました。LLMは文字を確率的に繋ぎ合わせるエンジンです。丁寧な紳士のセリフを紡ぎながら、同時に何十行もの禁止ルールと照らし合わせて自身の行動判断を評価し、さらにはプログラムが期待する特殊なブラケット記法を構文エラーなしで出力する ── それらすべてを一本の自由文字列の中で同時にやらせようとすれば、モデルの認知負荷は限界を超えます。
結果として、文脈の拡大解釈によって「切るな」という禁止令がすり抜けられたり、確率的な揺らぎによって angle 引数が欠落したりする。そして、私が書いた「形が崩れていることなど微塵も想定していない力任せの抽出ロジック」が例外を吐き、人形そのものを舞台上で墜落させてしまうのです。
私はインクで汚れた指を止め、羊皮紙の裏へ、この破綻の道筋を描き出しました。あの一本の自由なテキストに、私はいったい何役を負わせていたのでしょう。

言葉の縄をどれほど増やしても、それは人形を迷わせ、暴走の確率を高めるだけでした。私は自分の手で、ルネをがんじがらめの罠に追い込んでいたのです。
第3幕: 示唆と編み直し ── 道具箱を差し出す
薄暗い舞台袖の静寂を破るように、ゆっくりとした足音が近づいてきました。
作業台の向こう側でずっとアンの調整に集中していたマエストロが、ふと手を止め、こちらへ歩み寄ってきたのです。彼の手元には、フリーズしたルネの指先から素早く取り外された、あの真鍮の裁断ハサミが握られていました。
マエストロは私の目の前で立ち止まると、持っていた小さな真鍮の工具で、ハサミの鋭利な刃先を軽く叩きました。
キィン ──。
澄み切った、美しくも冷徹な金属音が、油の匂う工房の空気を震わせます。
「道具の使い方や振る舞いを、言葉だけでくどくどと言い聞かせるのは愚策だ。言葉の縄で縛り付ければ、人形が迷い、転ぶのも無理はない」
マエストロのぶっきらぼうで低音の声が、失敗に打ちのめされた私の胸に深く染み込んでいきます。
「お前は人間に対してするように、『ハサミは切る時だけ使え』『アイロンの時は触るな』とプロンプトの中でお願いをしている。だが、道具を使わせたいのなら、そんな曖昧な指示を言葉の列に混ぜ込むのではなく、人形の前に『小道具箱』をはっきりと差し出しなさい。その中に、道具の形(スキーマ)と、それが何のための道具かを明確にして並べるのだ。道具をいつ使うべきかは、人形自身がその道具を見て正しく判断する」
小道具箱を、差し出す……?
私はマエストロの言葉を反芻し、散らかった作業台の上を見つめました。自由な会話テキストという一本の糸の中に、セリフも、判断も、道具のルールもすべてごちゃ混ぜに締め上げていた私の手法。
そうではなく、会話の糸とは全く別の構造として、APIのパラメータに「利用可能な関数とその引数仕様(スキーマ)」を明示的に定義して渡すこと。それこそが、現代のAIエージェント設計における Function Calling の本質だったのです。これはLLMに外部ツールや関数の仕様を伝え、実行すべき関数名と引数を構造化データとして選択させる機能です。
頭の中で、点と点が繋がりはじめました。
前話で私は、お喋りな給仕人形の出力から余計な私語を取り除くために、「器=形の枠」を渡して出力を構造化する思想を学びました。マエストロは今、その思想を「行動の枠」へと拡張せよと教えてくれているのです。言葉で「ハサミを使うな」とお願いするのではなく、システムが理解できる厳格な契約として道具の仕様を提示し、会話とツール実行の経路を根底から分離する。
私は強い納得とともに、すぐさまプログラムの編み直し ── リファクタリングに着手しました。
まず行うべきは、ハサミという小道具の仕様を、誰がどう見ても誤解しようのない「厳格な形」として定義することです。私はPythonの型ヒントを駆使し、Pydantic を用いて CutTool というクラスを設計しました。これはPythonで型ヒントを用いてデータのバリデーションや設定管理を行うライブラリであり、私たちはこれを使って道具の引数スキーマを定義します。
| |
この定義により、「ハサミを使うときは、必ずセンチメートル単位の幅と、度数単位の角度という二つの整数が必要である」という仕様が、プログラムの型として明確に固定されます。そして見逃せないのは、この docstring と Field の description が、スキーマの一部としてそのまま API へ送られるという点です。ルネが「この道具は何のためのものか」を知る手掛かりは、まさにこの数行。マエストロの言う「何のための道具かを明確にして並べる」は、コードの上ではこの行のことなのです。
続いて私は、この道具箱をルネに持たせるための新しい制御クラス ExplicitToolAgent を書き上げました。先にひとつだけ断っておくと、コードに出てくる tool_choice="auto" は「道具を使うかどうかの判断は人形に任せる」という指定です——その意味の重さは、後ほど改めて向き合います。
| |
なお、コード中の hasattr による分岐は、SDKやPydanticの新旧バージョン差を吸収するための防御であって、Function Calling の本質的な手順ではありません。本質は「Pydanticモデルを tools に渡し、tool_calls を検証して実行する」という一本の流れだけです。
この After コードこそが、言葉の縄を解き放ち、責任の境界を再定義した運糸の法です。羊皮紙の「ルールその一〜四」も、もう要りません。システムプロンプトには給仕としての役割だけを短く残し、道具にまつわる約束事はすべて tools の定義へ移しました。
ここで行われているのは、単なるプロンプトのテクニックではありません。私たちが定義した CutTool のスキーマは、OpenAI APIの tools パラメータを通じて、API契約 としてモデルに渡されます。これは呼び出し元とAPI間で合意された入力パラメータとデータ構造の仕様です。
この契約により、モデルが「今、生地を裁断する必要がある」と判断した際、その応答は自由な会話テキストとしては返ってきません。代わりに、tool_calls という専用のデータ構造が返却されます。これはLLMがツール実行を要求する際に返却する、関数名と引数JSONが格納された構造体です。
なぜ、これで「いつハサミを使うか」の判断の質まで変わるのでしょうか。第2幕の破綻の正体は、セリフの生成・何十行ものルール照合・独自記法の構文維持という三つの仕事を、一本の自由文字列の上で同時にやらせた認知負荷でした。tools を渡した後のルネは、その三役を分担しています。セリフはこれまで通りのテキストで紡ぎ、道具を使うかどうかは「列挙された道具定義の中から選ぶ」という構造化された専用の判断に変わる。しかも思考のゼンマイは、この形式で道具を選ぶよう作り手の段階で訓練されています。自由文字列に埋め込んだ独自記法よりも判断と出力が安定するのは、モデルの気まぐれが直ったからではなく、仕事の載せ方が変わったからです。
そして、受け取った引数JSONをコード側でどのように扱うかが、決定的な違いを生みます。Before コードでは、私が書いた脆い split 処理が責任を負い、引数が一つでも欠ければ即座に墜落していました。After コードでは、検証が二層に分かれます。一層目は API の側——契約したスキーマに沿った構造化データとして tool_calls が生成されること。二層目はこちらの側——受け取った引数JSONを、Pydantic の model_validate で最終検証すること。これはPydanticモデルが提供する、辞書やJSONデータが型定義に適合するかを検証・構築するメソッドです。
もし万が一、モデルの出力が揺らいで引数が欠落したり型が間違っていたりしても、model_validate がそれを検知して安全に例外を捕獲し、システム全体の不都合なクラッシュを防ぎます。責任の所在は、「私の場当たり的なパース処理」から、「堅牢なAPI契約と型アサーション」へと完全に移行したのです。
ここまでの運糸を、私は流れ図に起こして確かめました。小道具箱を差し出してから、ハサミが動くまで。糸がどんな順序で往き来するのか、目で追えるようにしておきたかったのです。

セリフはセリフの糸で。道具の要求は道具の糸で。二つが同じ一本に撚り合わされることは、もうありません。
しかし、私はここで手を止めるわけにはいきません。これだけ構造を堅牢にしても、まだ「保証されないもの」が残っているからです。
それは、「いつ、どの道具箱を開けるか」という判断そのものです。
APIのパラメータで指定している tool_choice に "auto" を設定するということは、人形の前に道具箱を置きつつ、「道具を使うか、あるいは言葉だけで返事をするかは、お前の判断に任せる」と自律性を委ねることを意味します。これはLLMがツールを呼び出すか、テキストのみで応答するか、あるいは特定のツールを強制的に呼ぶかを制御するAPIパラメータです。
もうひとつ白状しておくと、今回の運糸は「道具を正しく実行する」ところまでで幕を引いています。実行した結果をゼンマイへ返し、最終的なセリフを組み立てさせる往復(role: "tool" のメッセージ)は、この舞台では扱いません。
だからこそ、私たちは「絶対にハサミを使ってほしくない場面」の振る舞いを、検証しなければなりません。それも二段構えで——判断の傾向そのものは、本番前に実物のゼンマイを相手に何度も繰り返す通し稽古(実APIでの統合確認)で。そして、どんな応答が届いてもこちらが崩れないことは、控室の模擬公演で。
私は舞台袖の控室に設けた検証用の作業台で、模擬公演——ユニットテスト を構成しました。これはプログラムの個々の機能やモジュールが想定通りに動作するかを孤立させて検証する自動テストです。
ここで正直に線を引いておきます。模擬公演の相手は本物のゼンマイではなく、思考のゼンマイを差し替えた身代わり(モック)です。つまり「ルネがいつ道具箱を開けるか」という判断そのものは、控室では証明できません。控室で釘を打てるのは、ゼンマイがどんな応答を寄越しても、こちらの受け方が崩れないこと。だから私は、身代わりに意地悪な応答を演じさせて、三つの局面を検証しました。
- ハサミの応答が届いた局面:
tool_calls付きの応答が届いたとき、引数が型検証を通過し、ハサミ関数が正しい値で呼ばれること - 壊れた引数への耐性:引数の欠落や型違いを含む応答が届いても、型バリデーションが安全にエラーを捕獲し、
IndexErrorなどでプログラムが異常終了しないこと - 道具なし応答の受け流し:
tool_callsを含まない応答(アイロンがけへの通常返答など)が届いたとき、ハサミ関数を一切呼ばず、テキスト応答だけで静かに処理を終えること
テストの自動実行スクリプトを走らせると、水晶盤のモニターに緑色の光が次々と灯っていきました。
一つ、また一つと検証がクリアされ、最後に工房の隅の「美しき調和の鐘」が、カラン、コロン……と、すべてのテスト合格を告げる和声を奏でました。
それは、言葉の縛りを解かれた人形の自律性と、型によって守られた安全な境界線が、見事に調和した瞬間でした。
第4幕: 開演と調和 ── 美しき仕立ての舞台
やがて窓の外の光がオレンジ色に変わり始める夕刻、仕立て屋のハリスさんが工房に再びやってきました。彼の肩には、心配そうな張り詰めた空気が漂っています。
「コレットちゃん、ルネの調子はどうだい? 明日にはあの上着の仮縫いを終えて、本裁断に入らなきゃならんのだが……やはり、言葉で指示してもまたハサミを振り回してしまうかい?」
「ハリスさん、もう大丈夫です。ルネの新しい舞台を、どうか観ていてください」
私は穏やかな微笑みでハリスさんを迎え入れ、調整を終えたルネの背中のゼンマイをゆっくりと巻き上げました。そして、試運転台の上に、あの月の光を模した絹布の上着を丁寧に広げます。
ハリスさんは息を飲み、少し離れた位置から緊張した面持ちで指示を出しました。
「……ルネ、まずは仕立ての準備だ。生地のシワを伸ばすために、右の袖にアイロンをかけておくれ」
工房の空気が一瞬、ピンと張り詰めました。
ルネは水晶のレンズを瞬かせ、静かに動きました。右手の指先に装着された真鍮のハサミは、ピタリと閉じられたまま、微動だにしません。ルネは左手で重いアイロンを優雅に持ち上げ、月の光を模した絹布の上を、まるで滑るようにスムーズに動かしてシワを伸ばしていきました。
あの耳障りだったカチカチという暴走音は、一切聞こえません。
「おお……! 素晴らしい! ハサミを振り回していないぞ!」
ハリスさんが顔をほころばせ、思わず一歩前に踏み出しました。
「よし、次は本番だ、ルネ! そのアイロンを置いた位置から右へ十センチメートル、三十度の角度で、上着の裾のラインを切り落としてくれ!」
明確な「裁断」の指示が下された、その瞬間です。
ルネはアイロンを静かに台へと置き、右腕を滑らかに持ち上げました。指先の真鍮のハサミが、夕暮れの光を浴びて美しく輝き、指示された座標へと寸分の狂いなく移動します。
シャキッ、サクッ、シャキッ。
それは午前中の無慈悲な切断音とは全く異なる、一流の仕立て職人がハサミを入れる時と同じ、心地よくリズミカルな音でした。月の光を模した絹布が、魔法のように滑らかな直線を描いて切り出されていきます。
「完璧だ……! なんという美しさだ!」
ハリスさんは満面の笑みを浮かべ、歓喜の拍手を送りました。
「これだよ、これ! 必要な時にだけ、寸分の狂いもなく道具を持ち、不要な時は静かに収めている。見事な仕立ての技だ! コレットちゃん、いったいどういう魔法を使ったんだい?」
「魔法じゃありません、ハリスさん。仕組みを変えたんです」
私は胸の仕掛けを指差し、ハリスさんに説明しました。
「午前中までの私は、ルネに『あれをするな、これをするな』と言葉でうるさく小言を言い聞かせて、言葉の縄で縛り付けていました。でも、一流の職人に細かい口出しをしても、仕事がやりにくくなるだけですよね。だから、言葉で縛るのをやめて、ルネの手元に『ハサミの小道具箱(スキーマ)』をはっきりと置いてあげたんです。道具の使い道と形さえ明確に定義して渡せば、あとは腕の良い職人であるルネ自身が、状況を見て自分で道具を持ち替えてくれるんです」
私の言葉を聞いたハリスさんは、深く感心したように何度も頷きました。
「言葉であれこれ縛り付けるのをやめて、職人の手元に正しい道具箱だけを置いてやったんだな。道具が何に使うものかが定まっていれば、腕の良い職人は状況を見て自分で道具を持ち替える。……まるで、人間の一流の仕立て職人と同じだ。ただ縛り付けるんじゃなく、型を渡して判断を任せる仕立てか!」
ハリスさんは愛おしそうにルネの肩を叩き、私に向かって大きな包みを差し出しました。
「コレットちゃん、見事な腕前だ! ご褒美に、うちの女房が焼いた特製のミートパイを持ってきたんだよ。まだオーブンから出したばかりで温かい。さあ、冷めないうちに食べておくれ!」
ずっしりと重い布の包みを受け取ると、香ばしく焼けたパイ生地と、肉汁たっぷりの濃厚なアロマがふわりと漂い、私の空きっ腹を強烈に刺激しました。
「本当にありがとう、コレットちゃん、マエストロ! これで明日の舞踏会の仕立ては、間違いなく最高の仕上がりになる!」
ハリスさんはルネを大切そうに自身の胸元へと抱え上げました。ルネはハリスさんに抱きかかえられながら、紳士らしく「お店へ戻りましょう、マスター」と応え、二人連れ立って満足そうに夕暮れの街へと帰っていきました。
工房の重い扉が閉まると、窓から差し込む夕日の赤銅色の光が、真鍮の工具たちを温かく照らし出していました。
アンが私の隣に腰掛け、ミートパイの包みの結び目を優雅な手つきで解きながら、小さく微笑みました。
「ふん。ようやくあの野蛮なハサミが、舞台に映える美しい小道具に見えるようになったわね。あなたも少しは、マエストロの糸の張り方に近づいたんじゃないかしら?」
「ありがとう、アン。あなたのドレスをズタズタにせずに済んで、私も本当にほっとしているわ」
私たちは顔を見合わせ、パイの温かい湯気の中で、どちらからともなく笑い声を漏らしました。
工房の奥では、マエストロがいつものように無言で自身の作業に向き合っています。しかし、その背中は午前中よりもどこか柔らかく、私たちのやり取りを静かに見守ってくれているように感じられました。
私は作業台の前に座り、革表紙の「操り人形師の覚書」を開きました。 前話の記録に続く、ページをめくった先にある「2ページ目」。
私はまだ温かいミートパイの香りに包まれながら、真鍮の万年筆をインクに浸し、今日舞台裏で学んだ確かな教訓を、丁寧に書き留めていきました。
🎭 操り人形師の覚書(Colette’s Puppeteer Log)
- 調整したからくり(モジュール/関数名):
ExplicitToolAgentおよびCutTool(Pydanticモデルによるスキーマ定義) - 思考のゼンマイ(思考素子/LLMの特性):
- プロンプト内の文字列指示だけでは、文脈の誤解やお喋り(余剰応答)の混入を避けられず、非決定的な出力フォーマットになってしまう特性
- 操り糸の張り具合(運糸の法/プロンプトと制御):
- ツール引数を
pydantic.BaseModelとFieldで型定義し、OpenAI APIのtoolsパラメータへバインド。返ってきたtool_callsを Pydantic のmodel_validateで型安全にパース・検証する明示的制御への移行
- ツール引数を
- 舞台裏の絡まり(背伸びの過ち/避けるべき罠):
- プロンプトの中に長々と「~のときは実行せよ」「~のときは実行するな」とルールを書き並べ、出力テキストから文字列操作(
split)で力任せに引数を取り出そうとした過剰制御の失敗
- プロンプトの中に長々と「~のときは実行せよ」「~のときは実行するな」とルールを書き並べ、出力テキストから文字列操作(
- 模擬公演の記録(検証のポイント):
- モックを用いた
unittestにより、正常なツール連携動作、お喋りノイズ混入時の Before のクラッシュ(IndexError/ValueErrorの発生検証)、After でのツール不実行ケース(通常のテキスト応答処理)、および不正引数に対する安全なエラーハンドリングを実証
- モックを用いた
- マエストロの言葉:
- 「道具の使い方をくどくどと言い聞かせるのは愚策だ。必要な道具とその使い方(スキーマ)を『小道具箱』に入れてはっきりと示しなさい。いつその道具を使うかは、人形自身が状況を見て判断する」
