数式の正誤判定にASTを採用するまでの遠回り

テックリードを担当したプロジェクトで、数式の正誤判定機能を技術検証したことがあります。

ユーザーが入力した数式を解析し、期待する式として正しいか判定する機能です。最終的には数式をAST(抽象構文木)として扱う方式を採用しましたが、そこへ辿り着くまでに1か月以上かかりました。

当時の私はASTを知りませんでした。ただ、振り返ってみると、知識不足だけで1か月を費やしたわけではありません。

調査期限も、方式を比較する基準も、プロトタイプを打ち切る条件も決めていませんでした。途中でほかのエンジニアに相談する機会も設けず、自分とAIだけで探索を続けていました。

この記事では、その技術検証で何が起きていたのか、今ならどう進めるかを整理します。


作ろうとしていたもの

プロジェクトでは、ユーザーが入力した数式について、期待する式として正しいか判定する必要がありました。

単純な文字列比較では対応できません。表記が違っていても同じ式として扱いたい場合がある一方、見た目が似ていても別の式として扱わなければならない場合があります。

さらに対象は最終的な解答だけではなく、途中式も含みます。計算結果が一致しているかだけでなく、入力された式の構造も見る必要がありました。

私は数式処理の経験がなかったため、実装方法の調査から始めました。


AIに案を出させ、プロトタイプを繰り返した

当時は、おおむね次の流れで検証していました。

  1. AIに実装方法をいくつか出させる
  2. 実現できそうな方法を選ぶ
  3. 小さなプロトタイプを作る
  4. 問題が見つかったら、その内容をAIへ伝える
  5. 改善案や別の方法を試す

AIの提案をそのまま実装していたわけではありません。内容を確認し、自分でコードを書いて動作も検証していました。

一見すると、普通の技術検証に見えます。実際、私も当時はそう考えていました。

しかし、振り返ると、やっていたのは「問題が出たら次の案を試す」というループです。候補をどう比較するか、いつ方式を捨てるか、いつ調査そのものを見直すかは決めていませんでした。


個別対応を積み重ねていた

最初に試した方法では、新しい入力パターンが見つかるたびに、個別の処理を追加する必要がありました。

あるケースに対応すると、別のケースで問題が起きる。その問題を直すと、それまで動いていたケースが壊れる。検証を重ねるほど条件分岐が増え、全体を把握しにくくなっていきました。

この時点で、現在の実装をどう直すかではなく、数式の表現方法から見直すべきでした。

ところが、実際には既存方式を改善する方向で検証を続けました。プロトタイプを作って動かすことに集中し、問題設定へ戻る機会を失っていました。


ASTを使う方法に辿り着いた

AIとのやり取りを続ける中で、数式をASTとして扱う案が出ました。

ASTは、プログラムや数式を単なる文字列ではなく、構造を持つデータとして表現するものです。数値、変数、足し算、掛け算などを、それぞれ木構造のノードとして扱います。

文字列を直接比較すると、表記の違いや括弧の有無に対応するための条件が増えやすくなります。ASTへ変換すれば、文字列の見た目ではなく、数式の構造を基準に処理できます。

ASTを使ったプロトタイプでは、それまで個別のルールで処理していたケースを、共通の仕組みで扱えるようになりました。今回必要としていた範囲にも適合したため、この方式で実装を進めることになりました。


調査の進め方に問題があった

後になって、プロジェクトメンバーの一人がASTを使う方法を知っていたと分かりました。

その人が自発的に教えるべきだったとは考えていません。当時の私は、数式処理やパーサーに詳しい人がいないか尋ねることも、現在の方式に根本的な問題がないかレビューを求めることもしていませんでした。

未知の領域を調べる以上、最初から適切な検索語や相談相手が分かるとは限りません。ASTへすぐ辿り着けなかったことは、ある程度仕方がなかったと思います。

一方で、同じ探索方法を1か月以上続けたことは防げました。数日ごとに調査方針をレビューしていれば、少なくとも「個別対応が増え続けている」という異常には、もっと早く気づけたはずです。


当時の技術検証に足りなかったもの

調査期限

「いつまでに方式を決めるか」を設定していませんでした。

プロトタイプに問題が見つかっても、また別の修正を試せます。試せる案が残っている限り、調査を続けることもできます。

しかし、次の案を試せることと、試す価値があることは別です。期限がなければ、その区別をしないまま調査を続けてしまいます。

方式を比較する基準

当時は、主に「現在見つかっているケースで動くか」を見ていました。

本来は、少なくとも次の観点で候補を比較する必要がありました。

  • 必要な数式を正しく判定できるか
  • 誤判定が起こりにくいか
  • 新しいパターンを追加しやすいか
  • 自動テストを書きやすいか
  • 実装が複雑になりすぎないか
  • 想定件数を処理できるか
  • 継続的に保守できるか

この基準がなかったため、目の前のケースには対応できても、追加のたびに条件分岐が増える方式を早い段階で除外できませんでした。

プロトタイプの終了条件

プロトタイプでは、何を確認したいのかを先に決める必要があります。

当時は「正誤判定をうまく動かす」という大きな目的だけがあり、個々のプロトタイプに明確な終了条件を置いていませんでした。

たとえば、「代表的な20ケースのうち一つでも構造的に対応できないものがあれば不採用」と決めていれば、問題が見つかるたびに修正を重ねることはなかったはずです。

不具合が出たとき、方式を捨てるのか、改善を続けるのか。その判断基準が抜けていました。

調査方針のレビュー

必要だったのはコードレビューだけではありません。

  • 問題の捉え方は合っているか
  • 一般的な解法を見落としていないか
  • 既存方式に固執していないか
  • 類似した問題を扱った人はいないか

こうした調査方針そのものを、ほかのエンジニアに見てもらう必要がありました。

特に未知の領域では、実装が進んでいることと、正しい方向へ進んでいることは一致しません。自分でプロトタイプを作り続けているだけでは、その違いに気づきにくくなります。

標準的な解法の調査

私は「この要件をどう実装するか」を中心にAIへ質問していました。

先に調べるべきだったのは、数式処理や構文解析で一般的に使われている手法です。

  • 数式は通常どのようなデータ構造で扱うのか
  • 数式パーサーはどのように作られているのか
  • コンパイラは構文をどう表現しているのか
  • 類似するOSSやライブラリはどのような設計を採用しているのか

個別要件への回答を集める前に、問題が属する技術領域と、その領域で使われている基本的な解法を調べるべきでした。


AIの性能だけでは説明できない

現在のAIモデルに同じ要件を伝えれば、もっと早くASTを提案するかもしれません。コード生成や問題分解の性能も、当時より上がっています。

ただ、AIの性能が上がれば同じ失敗を防げるとは限りません。

正しい案が最初から候補に含まれていても、それを選べるとは限りません。複数のもっともらしい案が提示されたとき、どれを検証し、どの時点で不採用にするかは別の判断です。

AIによって候補を出す速度は上がります。同時に、試せる案の数も増えます。終了条件がなければ、探索が速くなるだけで、調査は終わりません。

何をもって成功とするか。いつまで調べるか。いつ他者へ相談するか。どの条件で方式を捨てるか。こうした判断までAIへ委ねるのは難しく、調査を担当する側で決める必要があります。


今ならどう進めるか

同じ状況になったら、最初の調査期間を3営業日から1週間程度に区切ります。

その期間で有力な方式を選べなければ、単純に調査期間を延ばすのではなく、問題設定、調査方法、相談相手を見直します。

実装に入る前には、候補を比較するための表を作ります。

評価項目確認する内容
正確性必要な入力を正しく判定できるか
拡張性新しい数式パターンを追加しやすいか
保守性個別条件が増え続けないか
テスト容易性入出力を自動テストしやすいか
性能想定件数を処理できるか
既存資産利用できるライブラリや実装例があるか

各項目を同じ重みで評価する必要はありません。今回であれば、性能よりも正確性や拡張性を重く見ることになるでしょう。

プロトタイプも、正誤判定機能全体を作るのではなく、確認したい内容ごとに分けます。

  • 数式を安定してパースできるか
  • 表記の違う式を同じ構造へ変換できるか
  • 必要な演算子を扱えるか
  • 不正な入力を検出できるか

一つのプロトタイプで確認する仮説を限定し、採用条件と不採用条件を先に決めます。

また、数日ごとに別のエンジニアへ調査内容を共有します。見てもらうのは完成したコードではなく、調査した方式、見送った方式、現在の問題、次に試す内容です。

相談相手も、数式処理の経験者だけに限定しません。パーサー、コンパイラ、構文解析、数式ライブラリなど、隣接する領域の経験者まで含めて探します。完成した答えを知っている人がいなくても、適切な検索語を知っている人が見つかる可能性はあります。


次回の技術調査で使うルール

今回の反省を踏まえ、次からは以下を調査開始時に決めます。

  1. 方針を判断する期限
  2. 必須要件と、今回は扱わない要件
  3. 候補方式を比較するための評価軸
  4. プロトタイプごとの仮説
  5. 採用条件と打ち切り条件
  6. 調査方針をレビューする日
  7. 相談できそうな経験者やチーム

そのうえで、標準的な手法、既存のOSS、ライブラリ、必要に応じて論文などを調べます。

期限までに方針を決められなかった場合は、同じ方法のまま調査期間だけを延長しません。探索範囲や体制を変えます。


まとめ

数式の正誤判定機能を作るため、私はAIから実装案を得ながらプロトタイプを繰り返しました。最終的にはASTを使う方式に辿り着き、必要な機能を実装できました。

ただし、技術検証には1か月以上かかりました。

ASTを知らなかったことは遠回りのきっかけではありますが、長期化した原因は別にあります。期限、評価基準、打ち切り条件、レビューの機会を設けないまま、同じ探索方法を続けてしまったことです。

未知の領域で、最初から正解を選ぶのは難しいと思います。それでも、現在の進め方では正解へ近づいていないと早めに気づく仕組みは作れます。

テックリードがあらゆる技術の正解を知っている必要はありません。一方で、分からない問題をどう調べるかは管理する必要があります。

今回の件で不足していたのは、ASTの知識よりも、その管理でした。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です