今年55歳のおっちゃん、AIに実装を任せてRust製家計簿を2.6.0まで育てた話 〜でも「ありえない2円」だけは、人間が合わせた〜
なぜ、既製の家計簿じゃダメだったのか
世の中には立派な家計簿アプリが山ほどある。それでも自分で作ろうと思ったのは、単純な話で——自分のお金のデータを、他人のクラウドに預けたくなかったから。
「何も出さない、何も取り込まない。ちゃららららら〜🎵」
何にいくら使ったかは、その人の生活そのものだ。よそのサーバーに上げて、規約変更やサービス終了に振り回されるのは性に合わない。手元で完結して、自分のデータは自分の手の中に置いておきたい。(このローカル完結の思想は、筆者がもう一つ作っているIME「Bonolith」と同じ根っこです)
そういうわけで、「KakeiBonByRust」を作ることにした。
なぜRust、そして"自分では書かない"という選択
言語にRustを選んだ理由は、ふたつ。
ひとつは、これから主役級になる言語だと踏んだから。技術的目利きの勘である。
もうひとつは正直な話で——Rustの本を一冊読んだけど、自分でプロダクトを作れる気がまるでしなかった(笑)。所有権だ借用だライフタイムだ、頭では分かっても「これで家計簿を組み上げる」絵が湧かない。
で、詰むかと思いきや、ピカーンと閃いた。
へ到達した。
最初のバージョンは素朴なものだった。収支をつけて、集計して、見られる。家計簿として最低限の輪郭。AIに実装を任せると、最初の一歩はとにかく速い。ここがスタート地点になる。
転機 ——AIに任せたのに、1円が、そして2円が合わなかった(v2.0.0)
順調に見えた開発に、ある日**「1円のズレ」**が現れた。
明細を足した合計と、総合計が、1円合わない。金額計算をやったことがある人なら、この字面だけで胃が痛むはずだ。たかが1円。されど、1円合わない家計簿は、全部信用できない。
さらに妙なことが起きた。本来あり得ないはずの「2円」のズレまで顔を出したのだ。1円なら丸めの誤差で説明がつく。だが2円は、ただの丸めでは説明がつかない。「あれっ?」と血の気が引いた。
正体は、**税計算の"順序"**だった。
- やっていたこと(誤):明細行ごとに税を計算して、それを足し込んでいた。
→ 丸めが行の数だけ発生し、積もって2円ズレた。 - 正しいやり方(正):明細金額を先に合計し、その総額に一括で税計算する。
→ 丸めは1回だけ。
ここが、この記事で一番伝えたいところだ。「行ごとに税を計算して足す」というコードは、プログラムとしては普通に動く。一見もっともらしい。でも、会計のドメインルールとしては間違っている。「合計してから課税する」は、コードの正しさではなく業務の正しさで、それはRustの型システムも、AIも、教えてはくれない。ドメインを知っている人間が握るしかない。
だから計算ロジックを根っこから作り直した。メジャーバージョンを2.0.0に上げたのは、これが理由だ。
そして——ここが自分でも気に入っている設計なのだけれど——ズレを黙って丸めて隠さないことにした。仮計算して、明細合計と総合計が一致するかチェックする。一致すればそのまま適用。一致しなければ、「総合計を優先するか/明細合計を優先するか」をユーザーに選んでもらう。最後の判断は、人間が握る。(この端数バトルの実装とコードは、別記事で深掘りします)
そして今、v2.6.0
そこからは順調だった。約8ヶ月で、v2.6.0まで来た。v1.0.0からの歩みとしては、なかなかの velocity だと思う。今できることを少しだけ:
- アクティブな入力フィールドへのガイド表示(フィールドを移動すると、ガイドも追従する)
- フォントサイズの指定(小/中/大/カスタム)
- メニュー以外の項目は、すべてキーで操作可能
地味だが、毎日触る道具ほど、この手の「触り心地」が効いてくる。
これからやること
まだ道半ばで、これから手を入れる予定のものが並んでいる:
- 集計機能のさらなる拡張
- CSV出力/エクスポート・インポート
- マスタデータの削除ガード(使われているデータは消せないように)
- メニュー部分もキーで操作できるように
このあたりは、ひとつずつ記事にしていく予定。とくに「削除ガード(参照制約)をRustでどう型安全にやるか」は、単体で一本書けるネタだと思っている。後続の記事に続きます。
おわりに ——おっちゃんが、生活道具を自作するということ
55歳で、Rustの本に一度は挫折して、それでもAIと組んで家計簿を2.6.0まで育てた。書けないなら、書ける相棒に任せればいい。でも、税計算の順序みたいに、人間が握るべきところは握る。
AIフルコーディングって、丸投げのことじゃない。任せるところと、譲らないところを、自分で線引きすることなんだと思う。その線の引き方の話を、この後の記事で続けて書いていきます。
おっちゃんによるおっちゃん(+みんな)のための、おっちゃん's リンク
- KakeiBonByRust(GitHub): https://github.com/BonoJovi/KakeiBonByRust
- Bonolith(GitHub): https://github.com/BonoJovi/Bonolith
- cntl(GitHub): https://github.com/BonoJovi/cntl
- Promps-Ent(GitHub): https://github.com/BonoJovi/Promps-Ent
- ai2ia(GitHub): https://github.com/BonoJovi/ai2ia
- 前回の AIフルコーディング記事: "KakeiBon By Rust"は53歳(もうじき54)によって開発されました
最期、あわわわ 最後までお読みいただき、ありがとうございます!