AIの回答を整形しアプリに取り込む

ChatGPTやPerplexityに問題を解説してもらい、その回答をコピーしてアプリに取り込めるようにしています。

実際に取り込んでみると、余計な文字が残ったり、数式が崩れたりしていました。

今回、それを修正したので、記録しておきます。


取り込みは2段階

アプリの処理は2段階に分かれています。

  • 取り込みの整形:コピーした回答から、いらない部分を消して保存する
  • 表示の変換:保存した回答を、画面に出すときに読みやすく整える

保存データを変えずに直せるものは、表示の変換で直しています。すでに保存されている解説にも効くからです。


1. 取り込みの整形:コピーに紛れ込む「出典ボタン」

ChatGPTの画面からコピーすると、段落の下に出る出典のボタンが文字として入ってきます。

…記述は適当である。
大津市公式サイト
+1
2 適当

サイト名だけを見ても、本文の言葉(たとえば「京都府」)と見分けがつきません。そこで、言葉ではなく、行の形と位置で見分けることにしました。

  • 「+1」「+2」だけの行は消す
  • すぐ下に「+数字」がある短い行は、出典名として消す
  • 「e-Gov 法令検索+1」のように、名前と件数が同じ行にあるものも消す(ただし「2x+1」のような式は残す)
  • 出典名と分かった名前は、ほかの場所に件数なしで出てきても消す
  • 出典のサイトアイコン(画像リンク)が付いている場合は、そのすぐ下の行を出典名とみなす

最初は「段落の後ろにある、句点のない短い行」も消そうとしました。しかし、いろいろな形で試すと、本文の小見出しや「したがって正解は1」のようなまとめまで消えてしまいました。「+1」が付かない出典名は、本文と見分けられないので残す、と割り切っています。

あわせて、検証用に書かせている「照合」の見出し(「照合」「照合結果」「## 照合」など)も消すようにしました。ChatGPTのコピーボタンで取った回答はMarkdownのままなので、見出しの前に「## 」が付いていて、最初は消し漏れていました。


2. 表示の変換:箇条書きと記号

  • Perplexityは箇条書きを「- 」で書くので、記号を消して項目の間を1行あける
  • LaTeXの \div を「÷」にする(「div」だけだと英単語の一部にもなるので、バックスラッシュ付きだけ)
  • \left( と \right) は、指定の文字だけ消してかっこを残す
  • 判定用の目印の文字列は、保存データには残し、画面には出さない


3. 下付き文字・上付き文字

一番苦労したのがここです。

Unicodeには、数字の下付き(₁ ₂)や上付き(² ³)はありますが、大文字の英字の下付き文字はありません。そのため、AIは「V_L」と書いたり、小文字の「ₐ」で代用したりします。以前は「V(L)」のように、かっこで表示していました。

最初は、選択肢の表示でも使っているTextMeshProの <sub> タグを試しました。ところが、長い解説を表示すると、ときどき例外が出て止まりました。TextMeshProは長い文を折り返すとき、少し前の状態に戻して処理をやり直します。そのやり直しと <sub> の組み合わせで、内部の情報が空になってしまうようでした。短い選択肢では起きず、長い解説の、折り返す位置によってだけ起きるのがやっかいでした。

そこで、文字を小さくする <size> と、位置をずらす <voffset> を組み合わせて、下付き・上付きに見せる方法に変えました。この2つは、閉じるときに中身を消さない作りなので、同じ例外は起きません。

  • R_B、E_{A1} → Rの後ろに小さく下げた「B」、Eの後ろに小さく下げた「A1」
  • e^(-t/τ)、(a/b)^{1/4} → 小さく上げた「-t/τ」「1/4」
  • e^(−μ(x−d)) のような入れ子のかっこも、かっこの対応を数えて区切る
  • 数字だけのものは、今までどおりUnicodeの ₁₀ や ⁻³ にする

試し方

直すたびに、全アプリの保存済みの解説(約4万8千件)を、新しい変換に通して確かめました。

  • 変わったのが狙った所だけか(変わらないはずの解説が変わっていないか)
  • タグの開きと閉じが合っているか
  • フォントにない字が残っていないか

これで、「直したつもりが、別の資格の解説を壊していた」ということを防げました。


残っていること

  • 「+1」が付かない出典名は残ります。
  • 「Φ1」のように、AIが添え字を普通の数字で書いたものは、表示では直していません。同じ形でも「σ²(分散=2乗)」や「β2ミクログロブリン(名前)」のように意味が違うので、機械的に変えると間違えるためです。AIへの指示を見直して対応する予定です。