Android WebView上のChatGPTから回答を取り出し、ローカル音声へつなぐ実験を進めています。
その途中で、想像以上に手強かったのが「ChatGPTの回答は、いつ完成したと判断できるのか」という問題でした。
画面を見ている人間なら「もう書き終わった」と分かります。しかしDOMを監視するプログラム側から見ると、単純な目印だけでは完成を取り違える場面がありました。
最初に使えそうに見えた目印
候補になったのは、主に次の情報です。
data-message-id:どの回答なのかを識別するIDstop-button:生成中に表示される停止ボタン- Copy / Shareなどの回答操作ボタン
- 本文が一定時間変化しないこと
どれも一見すると「完成判定に使えそう」に見えます。
UUIDは「回答の戸籍番号」だった
ChatGPTのassistant要素には、現在の環境では data-message-id が付いていました。
新しい実回答のIDが出たことを検知すれば、「新しい回答が始まった」ことはかなり正確に追えます。
ただし、IDが出た瞬間の本文を読むと、まだ文章の途中でした。
つまりIDは「どの回答か」を示す情報であって、「回答が完成した」という意味ではありません。
stopボタンが消えても、本文はまだ変わる
次に、生成中に表示されるstopボタンを監視しました。
stop-button=false になれば完成、と考えたくなります。
ところが実測では、stopボタンが消えた直後にも本文が変化するケースがありました。
stop-button=false
↓
その後に text-change
stopボタンは「生成処理の状態」を知る重要な手掛かりですが、それ単独では最終DOM反映まで保証してくれませんでした。
CopyやShareが出ても完成とは限らない
次は回答下部のCopyボタンなどを調べました。
ページ全体のボタン数を数える方法は、過去回答の再描画などで値が揺れました。そこで最新assistant要素から親方向へたどり、同じ回答コンテナ内にある操作ボタンだけを見るようにしました。
この対応付け自体はうまくいきましたが、別の問題が見つかりました。
stop-button=false
copy=true
share=true
↓
約0.3秒後
↓
本文がさらに変化
つまりfinished-action系のUIも本文の最終反映より先に出ることがあると確認できました。
「1.2秒変わらない」だけでも危なかった
以前の実装では、本文が一定時間変わらなければ完成、と考える方式も試していました。
しかし長い回答を観測すると、生成途中で約1.88秒、本文がまったく変化しない区間がありました。その後、同じ回答の本文生成は再開しています。
1200msの無変化だけを完成条件にしていたら、この途中停止で誤判定していたことになります。
さらに、文字数だけ見ても足りない
今回いちばん面白かった実測のひとつがこれです。
text-change len=3386
text-change len=3386
文字数は同じなのに、本文内容そのものが変わっていました。
そのため、単純に「文字数が増えたか」ではなく、前回の本文文字列と今回の本文文字列を比較する必要があります。
if (currentText !== previousText) {
// 本文が変化した
}
それぞれの役割を分けて考える
ここまでの実測から、各情報は次のように役割を分けて考えるのが自然でした。
data-message-id:どの回答かstop-button:生成処理が動いているか- Copy / Shareなど:回答操作UIが出ているか
- 本文比較:実際に表示内容がまだ変化しているか
どれか1個を「完成の証拠」にするのではなく、別々の状態として扱う必要がありました。
既知事例を調べて分かったこと
途中で「これは自分たちだけが踏んでいる問題なのか?」と考え、公開されているChatGPTブラウザ連携の実装や修正履歴も調べました。
すると、stopの消失や一時的な本文安定、finished-actionの早期表示だけでは最終回答を誤判定するケースが既に扱われていました。
ここで、実験を増やす前に既知事例を確認することの重要性も改めて実感しました。
今回の教訓
今回の調査で一番勉強になったのは、「難しいコードを書けること」だけがプロの仕事ではない、ということでした。
一時停止、同じ文字数での書き換え、UIの先行表示など、普通なら見落としそうな状態まで想定し、1個の目印を信用しすぎない。
そして、既知事例確認 → 仮説 → 最小検証 → ログ確認 → 記録 → 次という順番で進める。
手強い問題でしたが、なぜ堅い実装が必要なのかを実測で理解できた、かなり良い教材でもありました。
後編では、この結果から実際にどんな完成判定条件へ絞り込んだかをまとめます。



コメントを残す