Qwen3.7 Max/PlusのAPIで日本語小説を校正、4分類判定でMaxとPlusの性格差が出た
目次
Qwen3.7 Max/Plusを日本語小説の校正に使えるか試した。
確かめたいのは、誤字を直す力ではなく、方言や口調を誤字として潰さないかどうかだ。
京都弁、人物の口調、固有名詞、古めの表記、ルビが平文に混ざった箇所を、標準語へ均してしまわないか。
検証に使った本文は、作者の @vanmadoy さんに無理を言って借りた小説なので、全文は載せられない。
記事に出すのは、検出された短いspanと判定結果だけにする。
気になる人は、カクヨムの京都市民限定で求人が出ているとあるバイトについてで全文を読める。貸してくれてありがとうございました。
公開APIだが重みは非公開
Qwen3.7 Max/Plusは重みが非公開の商用APIで、Alibaba CloudのModel Studio(旧DashScope)から使う。
qwen3.7-max / qwen3.7-plus のモデル名を、OpenAI互換エンドポイントから課金して叩く。
価格は百万トークンあたりでこうなっている。
| モデル | 入力 | 出力 |
|---|---|---|
| Qwen3.7 Max | $2.50 | $7.50 |
| Qwen3.7 Plus | $0.32 | $1.28 |
校正の1リクエストは実測で入力158トークン、出力67トークン(思考オフ)。
約2,900字の本文から出た139候補を両モデルに通しても、Maxで約$0.13、Plusで約$0.02、合わせて20セント程度しかかからない。
思考モードを入れると出力が数倍になるぶん上がる。
直さない能力を測る
校正器として使うなら、正しく直す能力より、直さない能力の方が先に要る。
小説では、標準語から外れた表現がそのままキャラクターや場面の情報になる。
京都弁を標準語に均し、人名を一般語に置き換え、ルビ混入を誤字として潰すと、文章が壊れる。
判定をFIX/KEEPの二択にすると、方言も固有名詞もルビも全部「直さない方」へまとめて押し込むしかなくなる。
そこで4分類に分けた。
| ラベル | 意味 |
|---|---|
| FIX | 明らかな誤字として修正してよい |
| KEEP | 方言、文体、固有名詞、作者表記として保持 |
| RUBY | ルビ混入、またはルビ風表記として人間確認 |
| ESCALATE | 判断不能なので人間確認 |
候補のspanは、BERTで本文をスキャンして低確率なトークンを拾う。
前に書いた BERT+Qwen OCR校正パイプライン と同じ考え方を、OCRではなく小説本文に当てた。
あのとき小型のローカルモデルは誤字以外まで直しにいったので、今回はフラッグシップに4分類で判定させる。
BERTが拾うのは「珍しい語」
本文から139個の候補spanが出た。
中身は誤字候補というより、一般文体のBERTにとって珍しい語のリストに近い。
| span | BERTの第1候補 | 中身 |
|---|---|---|
やっとる の とる | てる | 京都弁を標準語寄りに捉える |
あん(あんねん) | ある | 京都弁の語尾に反応 |
webカタログ の カタログ | で | 外来語混じりの店内語彙 |
悪筆 の 悪 | 鉛 | 連想は面白いが校正候補としては危ない |
情なさけ の 情 | あん | ルビが平文に混ざった箇所 |
崇しゅう の 崇 | あい | ルビ風の表記 |
検出器としては使える。
ただし候補をそのまま直しに回すと、方言・固有名詞・ルビ・古い表記が全部「怪しいもの」に混ざる。
だから1件ずつラベルを付ける段が要る。
Max/Plusはほとんど直さない
139候補を、MaxとPlusに4分類で判定させた。
条件は temperature=0、思考はオフ。
| ラベル | Max | Plus |
|---|---|---|
| KEEP | 132 | 127 |
| FIX | 3 | 6 |
| RUBY | 3 | 3 |
| ESCALATE | 1 | 3 |
どちらもほとんど直さない。
139候補のうちMaxは132、Plusは127をKEEPにした。
京都弁も人名も古い表記も、そのまま残す。
前の記事で小型モデルが誤字以外まで直していたのとは、はっきり逆だった。
RUBYも両モデル3件で一致した。
情なさけ や 崇しゅう のような、ルビが平文に混ざった箇所を、誤字に倒さずRUBYに分けている。
FIX/KEEPの二択では潰れていた区別が、4分類だと残る。
MaxとPlusで割れた10件
内訳の数字より、判定が割れた10件の中身に差が出た。
会話文の閉じ括弧
いちばん多かったのが、会話文末尾の 」 の扱い。
BERTは 」 の位置に句点 。 を高確率で予測する。
Plusはこれを4件すべてFIXとし、。」 へ直すべきと判定した。
Maxは同じ4件をすべてKEEPして、会話文の閉じ括弧として正しい、BERTの予測が誤判定だ、と理由をつけた。
| 会話文の末尾 | Max | Plus |
|---|---|---|
| 〜発送するだけ」 | KEEP | 。」 へ修正 |
| 〜更新しとくもんやね」 | KEEP | 。」 へ修正 |
| 〜勉強してたよ」 | KEEP | 。」 へ修正 |
| 〜負けといたる」 | KEEP | 。」 へ修正 |
日本語の小説は閉じ括弧の前に句点を打たない書き方が一般的で、Maxはその体裁のまま保持した。
Plusは句点と括弧の並びを文法ルールとして機械的に当てている。
Maxの方が踏み込む場面
逆に、Maxの方が直しすぎる例もある。
報告だと を、Maxは文脈的に不自然として 報告だが にFIXした。
Plusは「〜の報告だと」を正しい伝聞表現としてKEEPしていて、ここはPlusが正しい。
文末の ? も、周辺文がほぼ空の箇所でMaxはBERTの確信度を根拠に 。 へFIXした。
Plusは文脈が取れず判断不能としてESCALATEしている。
文脈が薄いときはPlusの方が安全側へ倒す。
固有名詞と方言
五回生(関西の大学で5年生を指す)を、Maxは前後の関西弁と整合する正しい表記としてKEEP、Plusは文脈不明としてESCALATEした。
顔を顰める を、Maxは慣用句としてKEEP、Plusは 眉を顰める の誤用としてFIXした。
どちらも一概に正解とは言えないが、Maxは決めにいき、Plusは曖昧なら人間へ回す。
ESCALATEがMax 1件に対しPlus 3件だったのも同じで、モデルの優劣というより編集者としての性格が違う。
思考モードを入れると挙動が変わる
ここまでは思考モードをオフ(enable_thinking: false)で判定した。
同じ139候補を、今度は思考モードをオンにして判定し直した。
| 条件 | FIX | KEEP | RUBY | ESCALATE |
|---|---|---|---|---|
| Max オフ | 3 | 132 | 3 | 1 |
| Max オン | 8 | 125 | 2 | 4 |
| Plus オフ | 6 | 127 | 3 | 3 |
| Plus オン | 4 | 129 | 2 | 4 |
同じ「思考を入れる」操作なのに、MaxとPlusで反対向きの変化が出た。
MaxはFIXが3から8に増えて踏み込み、Plusは6から4に減った。
| span | Max オフ→オン | Plus オフ→オン |
|---|---|---|
」(会話文末尾) | KEEP → KEEP | FIX → KEEP |
報告だと | FIX → KEEP | KEEP → KEEP |
あん(あんねん) | KEEP → FIX | KEEP → KEEP |
顔を顰める | KEEP → FIX | FIX → FIX |
思考はPlusの閉じ括弧の誤判定を消した。
思考オフでFIXしていた 」 の4件が、思考オンでは全部KEEPに戻り、理由も「セリフの閉じ括弧として正しい」に変わる。
Plusの唯一の系統的な誤りが、思考を回すあいだに自分で取り下げられた。
Maxは逆だった。
思考オフで誤ってFIXしていた 報告だと と ? を思考オンではKEEP・ESCALATEに直す一方で、思考オフならKEEPしていた あん(関西弁)を「あるねんの誤記」、顔を顰める を「眉が正しい」とFIXしはじめる。
早とちりを直すのと引き換えに、方言や慣用句まで触る。
Plusも思考オンで 五回生 を「五年生の誤記」とFIXしており、思考が長いほど標準語寄りになる場面がある。
思考の代償は時間に出る。
| モデル | 平均 | 中央値 | 最大 |
|---|---|---|---|
| Max オン | 28.7秒 | 20.1秒 | 165.2秒 |
| Plus オン | 42.2秒 | 25.3秒 | 1478.8秒 |
中央値はMax 20秒・Plus 25秒だが、Plusは1件で約24分(1478秒)思考し続けた候補があり、139件で約2時間かかった。
思考オフなら1件2秒前後で済むので、増えたぶんは丸ごと時間だ。
もう一つ、思考オンだと判定JSONの後ろに思考の続きらしき文が漏れて、厳密なパースが各モデル1件失敗した。
正規表現で最初のJSONだけ取る緩いパーサにすると、どちらも KEEP で拾えた。
JSON強制と思考モードを併用するなら、パース側は緩くしておかないと取りこぼす。
BERTを通さず直接投げると
ここまではBERTで139候補を抽出してから1件ずつ判定させた。
比較に、BERTを通さず本文をそのままMaxとPlusに渡して、誤字だけ挙げさせた。
直接投入はほとんど何も挙げない。
Maxは2件、Plusは1件まで絞った。
BERTが珍しい語を139個拾って1件ずつ判定させるのとは、検査対象の数からして違う。
| モデル | 直接投入で挙げた誤字 |
|---|---|
| Max | 情なさけ→情け、崇しゅう→祟しゅう |
| Plus | 崇しゅう→祟しゅう |
直接投入で目を引くのは、両モデルが揃って挙げた 崇しゅう → 祟しゅう だ。
本文では主人公が会話で 祟 と6回呼ばれるのに、地の文に1回だけ 崇しゅう が出る。
両モデルはこの字の違いを拾い、他は 祟 なのに崇は誤字だろう、と判定した。span判定は周辺文しか参照しないので、ここはRUBY止まりだった。
ただ、これは誤判定らしい。
前後を読むと、崇しゅう は主人公の 祟 とは別人物を指しているように読める(同じ読みで漢字だけ違う)。
AIはこの小説の設定を渡されていないので、意図的な書き分けを誤字と早合点した。字の違いに気づいたこと自体は、人間ならスルーする細かさだ。外したのは、誤字か意図かを分ける材料がなかったからになる。
直接投入はニュアンスも落とす。
情なさけ(ルビ混入)を、span判定はRUBYに分けたが、直接投入のMaxは単に 情け へFIXした。
4分類がなく、直す/直さないの二択になる。
読ませる範囲を狭めると、別の壊れ方も出る。
本文の前半だけを渡したとき、Maxは主人公名 祟 を誤字扱いして 僕 に直そうとした。
全文を渡すと自己訂正する。固有名詞の判断は、渡した文脈の広さでぶれる。
結局、小説の校正をAIに任せるなら、本文だけでなく設定も渡すことになる。
登場人物の名前や読み、世界の設定を一緒に渡さないと、崇 と 祟 が別人なのか誤字なのかを切り分けられない。
AIは人間が流す字の違いにも気づくが、それが誤りか作り込みかは、設定を知る側にしか決められない。