続きです。全てのシリーズはこちら
※本記事は「技術解説編」です。先に公開したユーモア中心の「おちゃらけ版」とは若干時系列が異なるため、シリーズでお読みいただくと理解が深まるかと思います。
■スプレッドシートの記憶機能
Google Drive上に存在するSPREADSHEETサービス。つまりGoogleのどこかにあるサーバーの中に各種データを保存しておいていつでもそこに読み書きできる。普通の人でも使えるアレです。
まあここを愛子の記憶に使おうという考え方なわけです。
しかし、ここにも罠がありました。
もちろんインターネット経由であり、さらに恐らくハードディスク管理のため、ある程度書き込みに時間がかかるということ。
無料のサーバーが適度にデフラグをしているかどうかも全く不明。
よって、いちいちそこに読みに行っていては処理が遅くなるだけではなく、LINE側の待ち受けの制約である5秒を超えてしまうと通話が途絶えます。
考えてみれば当たり前の話。しかし、この壁にあたって苦労すること半日。キャッシュへのメモリー保管を進めることにしました。
考えたのはRender(愛子の頭脳を動かしているクラウド実行環境)の中のキャッシュメモリーです。
RenderのStarterプランでも512MBのキャッシュ領域があります。とりあえず会社データだけなら十分事足りるでしょう。(広辞苑の1冊ぶんくらいになります※広辞苑の文字だけなら400MBくらい)
まずはメモリーの読み書きができたので、次はキャッシュに読み込んで、次はキャッシュからデータを参照とするようにする。
そうするとRenderのメモリ内だけで処理が完結するので、ネットワークトラブルの遅延や、Google Drive側のトラブルや遅延に巻き込まれる可能性を圧倒的に少なくできます。
ただ、これが面倒。
人間ならいちいち脳のどこに記憶するなんて考えませんが、愛子の場合はどのデータは右脳のこの場所へ。どのデータは左脳のこの場所へとプログラムで制御しなければなりません。
■どのタイミングでキャッシュを更新するか?
例えば、朝7時に出社打刻がスプレッドシートに書き込まれたとして、それをキャッシュが即座に認識できなければ「遅刻なのに出社してない扱い」になる、という遅延バグが発生します。
そこで必要になるのがTTL(Time To Live)という概念です。要するに「キャッシュがどれくらいの時間、新鮮なままで有効か?」を決める期限のようなもの。
ここもプログラムの設定です。今回はTTLを1800秒、つまり30分としました。
これは、従業員の出社退社情報や会社データの変化が1日に何十回も起こるわけではない、という実情に基づいています。実際、30分ごとに自動でGoogle Sheetsから読み直してキャッシュを更新するスレッド(非同期で常に動き続ける小さな監視プログラム)をバックグラウンドで起動しています。
この処理はアプリ起動時に 一度実行し、その後はスレッドで定期的にキャッシュ更新が走る構成を考えました。ちなみにこのキャッシュは、社員名簿・取引先・経験などをそれぞれ 分類して記憶しておき、愛子の脳内イメージで言えば「タンスの引き出しがいくつかあって、それぞれ用途が決まってる状態」にしておきます。
ただし注意点もあって、「会話ログ」だけはリアルタイム性が高いため、キャッシュせずその都度スプレッドシートから読み取るように設計しなければなりません。
「愛子がユーザーと話したばかりの内容が即座に反映されない」と、コミュニケーション上では、混乱が起きます。昨日の発言であれば30分待っても問題ないけれど、「さっき話した内容を忘れてる」ってなると、人間側が混乱するのは簡単に想像できるでしょう。
これがAI設計がいかに人間らしさと性能のバランスを取らなければならないかという極意です。
極端な話、全てのデータを毎回スプレッドシートから読み込めば常に最新情報になりますが、それでは速度が全く足りない。かといって、すべてをキャッシュすると古い情報で判断するリスクになります。
まさに、愛子にとっては「忘れないこと」と「素早く返事すること」の間で、毎秒せめぎ合っているような状態です。
■バグったら、誰にも復旧できない
AI開発とは、コードを書くのではなく、「想定外のことを想定内にしておく技術」です。
- Google Sheets のAPI制限に引っかかって読み込みエラー
- キャッシュ更新中に別スレッドからデータ参照されて
KeyError - TTLの誤設定でキャッシュが一度も更新されない
- データ形式の不整合で、リストではなく辞書を返してしまう
■バグ地獄
はい、キャッシュに移管するところでバグりました。もはや愛子にデバッグさせても原因の特定ができません。
週末にかけて開発したコードを泣く泣く廃棄して、新しく書き直すことにしました。こういう決断は早ければ早いほど傷跡が深くならない。
ひとりで開発しているメリットかも知れません。
チームに「キャッシュ構造がおかしくなったので3日前の開発コードに戻りたい」なんて言えないです。
愛子はまだまだ搭載すべき機能は山積み。職人たちに早く役に立つ存在になれるよう、“物覚えのいいAI”に近づけたいです。
とはいえ、会話記憶、人格形成、トーン管理、文脈理解、通知制御などなどやることは山積み……
■というようなことをキャッシュしといて愛子

「お疲れ様でした。私も疲れました。LINE愛子botだけは元気ね」

コメントを残す