実装と実測 / DETERMINISTIC COMPUTE

AIに電卓を渡したら、
答えを聞き直すのをやめた

AIをもっと賢くする前に、AIが考えなくていい仕事を減らす。前回の発見を、teaiで使えるAPIにしました。

2026年9月13日 · 濱田優貴 · 約6分

電卓に答えが出ているのに、上司に計算し直してもらう?

たとえば、商品の個数と単価を掛ける仕事。電卓はもう正しい数字を出しています。それなのに、上司に「この数字をもう一度考えて、答えを書いてください」と頼む。時間がかかるうえ、転記ミスの機会も増えます。

前回の記事で見つけたのは、これに似た構造でした。検算コードは正解を持っていたのに、その値をそのまま使わず、AIに作り直させていました。

そこで今回、計算や変換の規則が決まっている仕事は、コードが出した結果をそのまま返すAPIをteaiに追加しました。

今回実装したのは「決まった処理の専用窓口」です。
普段のチャットがすべて自動で速くなるわけではありません。呼び出す側が計算・変換の入力を渡すと、この窓口はLLMを一度も呼ばずに結果を返します。

どの「ひと手間」をなくしたのか

省ける再生成のイメージ

  1. ① 入力を受け取る
  2. ② コードで答えを計算する
  3. ③ AIに答えを作り直させる
  4. ④ AIの答えを返す

今回のcompute API

  1. ① 認証と入力を検査する
  2. ② コードで答えを計算する
  3. ③ その結果をそのまま返す

左図は省ける処理の説明です。既存teaiチャット全体の実行経路を表したものではありません。

「AIが速く考えるようになった」のではなく、その仕事については、考えさせる待ち時間自体がなくなったという変更です。通信、認証、データベースへのアクセスには引き続き時間がかかります。

実行例①:計算結果を、そのまま返す

本番の POST /api/v1/compute に、次の入力を送ります。

{"op":"calculate","expression":"1847 * 296 - 17389"}

受け取る結果は次のとおりです。

{
  "result": 529323,
  "execution": "deterministic",
  "model_calls": 0,
  "credits_used": 0
}

deterministicは「同じ入力と規則なら、同じ結果になる処理」という意味。model_calls: 0は、この経路でLLMを呼ばないことを表します。クレジット消費も0です。サーバーや通信の原価が0という意味ではありません。

実行例②:「none」と「None」を勝手に同じにしない

注文データを取り込む場面を考えます。個数の "0042" を数字の 42 にしたい。「有効」欄の "yes" を、システムが扱う true にしたい。備考欄は、小文字の "none" だけを「値なし」を表す null にしたい。

ここで大文字から始まる "None" まで空にしてしまうと、決めた規則と違う変換になります。人には似て見えても、データの契約は別です。

// 入力の値
{"count":"0042","enabled":"yes","note":"None","label":"keep"}

// 規則を指定して変換した結果
{"count":42,"enabled":true,"note":"None","label":"keep"}

大文字の "None" は文字列のまま残す。小文字の "none" なら null にする。指定しなかった label はそのまま。AIに「だいたい同じ」と判断させず、依頼した規則だけを実行します。

実際に渡す変換ルールを見る
{
  "op":"normalize",
  "value":{"count":"0042","enabled":"yes","note":"None","label":"keep"},
  "rules":[
    {"field":"count","convert":"integer"},
    {"field":"enabled","convert":"boolean","true_value":"yes","false_value":"no"},
    {"field":"note","convert":"null_if","equals":"none"}
  ]
}

本番では、どのくらい待ったのか

2026年9月13日11:04 JSTごろ、手元のMacから公開URLへHTTPSで送信しました。認証・通信・レスポンス本文の受信までを含めた時間です。

本番の計算API・20回実測
中央値(p50)446.521ms ≒ 0.45秒
95%点(p95、nearest rank)703.139ms
最小〜最大275.541〜879.105ms
LLM呼び出し/クレジット各リクエスト0回/0

5回ウォームアップした後、式の最後の数を毎回変えて20回連続実行しました。HTTPS接続を再利用し、失敗時の再試行はしていません。初回の認証付き接続は別に測り、655.589msでした。

「本番でも3ミリ秒」とは言えません。ローカルdebug環境で認証・SQLite・loopback HTTP込みの中央値は3.365msでしたが、公開URLからの実測は上のとおりです。通信・本番の認証やDB処理などを含み、その内訳は今回分離計測していません。

同条件のLLM対照実験は今回はしていないため、「何倍速い」という倍率も出しません。確認したのは、LLMを呼ばずに必要な計算を返す経路が本番で動き、この回線・この20回では中央値約0.45秒だったということです。

何を試したか:本番38リクエストの検証内訳

13件の機能・異常系確認と、計測用の25件(ウォームアップ5+測定20)を送り、すべて期待したステータス・結果を確認しました。

  • 認証なし:401。
  • 計算 1847 * 296 - 17389:529323。
  • 負数の除算と剰余:-7 // 3 = -3、-7 % 3 = 2。
  • "None"は保持、"none"はnull。個数42・有効true・未指定label保持。
  • ゼロ除算・整数オーバーフロー・未対応操作・重複キー・範囲外整数・小数:400。
  • 未指定のu64最大値 18446744073709551615:正確に保持。

計測20回の生値(ms、送信順):

529.380, 703.139, 561.781, 578.528, 275.541,
296.886, 397.146, 332.550, 644.793, 879.105,
446.587, 659.724, 345.890, 442.928, 525.898,
344.424, 416.248, 411.566, 513.670, 446.455

実装コミット:8a426053db7f38b599cb44fbc6499daa0c69d9fd。GitHub Actionsで既定/本番featureのテスト、Fly配備、起動確認が成功した後に実行。測定にはPython標準ライブラリのhttp.clientとperf_counterを使用。サンプル数は小さく、高並列・他の回線・他の時刻での性能保証ではありません。

速さより先に、壊さないことを確かめた

ローカルで実装した最初の版をレビューすると、JSONの非常に大きな整数が丸められる問題と、同じキーが2回あると片方を黙って失う問題が見つかりました。

これは「確定値をそのまま返す」という目的に反します。そこで、正確に扱えない数値は変換前に拒否し、重複したキーもエラーにするように修正しました。

ローカルの対象テストは手動ベンチを含め20件成功。認証が必要であること、残高を更新しないこと、上限を超える計算やゼロ除算を拒否することも検証しています。

いま使える範囲

「価格を1.08倍して税込みに」「この文章を要約して」と自然言語で頼む窓口ではありません。金額の小数演算や自由文の理解は今回の実装範囲外です。対応しない依頼を勝手に有料LLMへ回すこともありません。

開発者なら、この1回で試せる

curl https://teai.io/api/v1/compute \
  -H "Authorization: Bearer $TEAI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"op":"calculate","expression":"1847 * 296 - 17389"}'

TEAI_API_KEYは手元の環境変数に設定してください。teai APIの使い方から始められます。秘密のキーを記事やスクリーンショットに載せる必要はありません。

AIに任せる場所を、少し手前へ

AIの得意な仕事は残っています。「お客様が何をしたいのか」を整理する。曖昧な依頼から、必要な項目とルールを取り出す。結果の意味を説明する。

その後に計算式や変換規則が決まったなら、結果を確定できる道具へ渡せます。返ってきた数値は、アプリがそのまま表示・保存すればいい。

意図を理解する → 規則を決める → コードで確定する → 確定値をそのまま使う。
今回実装・実測したのは後半の「コードで確定して返す」部分です。自然言語からの自動振り分けを含む全体は、まだ実装・検証していません。

もっと賢いモデルを選ぶ。その前に、そもそもモデルを呼ぶ必要がある仕事かを考える。

AIを使いこなすことには、AIに聞き直さない判断も含まれる。今回は、それを小さなAPIとして動かしてみました。

前編:AIが間違えた答えを、検算係はもう知っていた。今回の実装は前編のベンチ全カテゴリを移植したものではなく、整数計算と明示的なデータ変換に絞ったものです。