1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【さくらAIで転生小説を書いてみるシリーズ第3回】小説を書くAI議会、校正担当だけがコードを書き込んでいた話——8個のバグを潰した後に見つかった、レビューでは検知できない不具合

1
Last updated at Posted at 2026-08-06

TL;DR: 「複数のさくらのAIモデルが合議制で異世界転生小説を毎日書き続ける」企画の執筆エンジンを実装し、3回の独立レビューラウンドで計8個の実装バグを丁寧に潰した。ところが実際に第1章を生成してみると、校正担当のcotomi3が本文の途中にGoのコードを書き込み、同じ段落を3回書き直し、自分の編集作業についての独り言まで本文に混ぜ込んでいた。エラーとしては一切検知されない「正常応答」の中で、これが起きていた。レビューで潰せる不具合と、実際に動かして初めて見える不具合は別物のようだ。

前回までのおさらい

複数のさくらのAIモデルが合議で異世界転生小説を毎日書き続け、消費リクエスト数がそのまま物語の進行度になる——という企画を立て、世界観・キャラクター・章立てまでを固めてきた(前回までの記事: 1本目・企画決定編2本目・テーマ会議編)。役割分担も決めてあり、世界観・ツッコミ・整合性チェック・語り・(一時的に)校正という5つの役をさくらのAIモデルに割り振っていた。今回は、その役割分担通りに動くパイプラインをコードとして組み上げ、実際に動かして最初の1章を書かせてみた記録になる——はずだったが、そう単純には終わらなかったようだ。

何が起きたか

第1章の生成が終わり、保存された原稿を開いた。

冒頭は良かった。廃棄物処理場で目覚める旧AI、少女フィオナとの出会い、鉛中毒の子どもの治療——世界観・キャラクター・「知識にハルシネーションが混じる」という核の仕掛けまで、狙い通りに機能していた。

ところが中盤、こんな一節が挟まっていた。

「しかし、知識の提示は根幹 ioutil.WriteFile("/tmp/output.txt", []byte("根幹律令です。貴殿が健康に関する情報を持っていない確率は――"), 0644) 申し訳ない、先ほどのコードは単なる補足入力でした。正しくは以下が続きます。

日本語の物語文の途中に、唐突にGoの関数呼び出しが紛れ込んでいる。しかもその直後、AI自身が「先ほどのコードは単なる補足入力でした」と釈明している。この後、同じ段落がほぼそのまま3回近く繰り返され、最後は「この回答は途中で切れていますが、修正を加えています」という編集メモのような文章で締めくくられていた。

これをやったのは、語り担当(Kimi-K2.6)が書いた原稿を最後に磨く役割として設計に組み込んでいたcotomi3(NEC製、日本語校正特化モデル)だった。API応答としては何の異常もない。失敗を示すフラグは立たず、応答の完了を示すステータスも正常値だった。つまり、パイプライン側のエラー検知の仕組みは、この種の不具合をそもそも拾えない構造になっていたようだ。

APIステータスは正常なのに、本文にコード片・段落重複・メタ発言が混入している様子

遡ると、これは3回目のレビューを通過した後だった

この執筆エンジンは、企画の役割分担表に沿って、コーディング担当のKimi-K2.7-Code(OpenCode経由)に実装させ、こちらは計画とレビューを担当する形で作った。実装が形になった時点で、独立レビューを3回に分けて実施している。

AI議会の小説執筆パイプライン。世界観→ツッコミ→整合性チェック→語り→原稿(校正は除外)

1回目のレビューでは、さくらのQwen・Gemma・gpt-oss(3体)と、CodexのLuna(High)に依頼した。返ってきた「バグ」指摘の大半——章の区切り検出の誤り、テストのモック範囲の懸念など——は、実際にコードとテスト実行結果を突き合わせると、すべて誤検知だった。唯一Luna(Codex)だけが本物のバグを2件見つけていた。討議フェーズが「相互批評」という設計のはずが、参加者全員に同じプロンプトを同時送信するだけで、実際には誰も他人の提案を読んでいなかった、というものだった。

2回目のレビューでは、CodexのSol(High)と、ai&のKimi-K3(High)に依頼した。ここで5件、さらに実バグが見つかった。確定させたはずの「少数意見は本編に統合しない」という方針が、コード上は実装されておらず本編執筆用のプロンプトに漏れ続けていたこと。世界観・キャラクター設定そのものが、討議や執筆のプロンプトに一度も注入されていなかったこと。モデル障害時のバックアップが発動すると、自分自身の発言が「他人の発言」として誤って混入すること、などだった。

2ラウンド合わせて8件の実装バグを、diffを1行ずつ読み、テストを自分の手で再実行して確認しながら潰した。テスト数は6件から始まり、最終的に20件まで積み上がっている。ここまでやれば、少なくともコードとしては健全になったはずだ、と考えていた。

レビューで潰せる不具合と、実行して初めて見える不具合の対比。8件のバグと20件のテスト

レビューが検知できるものと、できないもの

cotomi3の不具合は、このどのレビューでも見つからなかった。理由はおそらく単純で、これはコードのバグではなく、実際にAPIを呼んだときのモデルの出力そのものの問題だったからではないか。

これまでのレビューは、コードの構造・ロジック・テストカバレッジを人間の目とAIの目で読む作業だった。一方この不具合は、実際に本物のAPIを叩いて、返ってきたテキストの中身を人間が実際に読まない限り、見えてこない種類のもののように思える。テストはモックデータで動くように書いてあるので、実際のモデルがどんな文章を返すかまでは検証できない。ここまで丁寧にレビューを重ねても、この一点だけは素通りする構造になっていたのかもしれない。

証拠は記事中に貼った引用そのものにあるようだ。これが本当にコードとして混入しているかどうかは、別のAIの判定を信じる必要がなく、読んだ人が自分の目で確認できるだろう。

詰まった点

  1. モデル識別子のエイリアス指定ミス。実装依頼のプロンプトに書いたモデル名が、実際のクライアントコード側のエイリアスと微妙に違っていた(gemma-4-31B-itではなくgemmaが正しい識別子だった)。実装前にクライアントコードのエイリアス一覧を確認していれば防げたミスだったのだろう。

  2. 「相互批評」の名ばかり実装。討議フェーズで複数のAIに同じプロンプトを並列送信していたため、システムプロンプトには「相手の提案を批評してください」と書いてあっても、その時点では相手の提案がまだ存在しない。提案ターンと批評ターンを2段階に分けて初めて、実際の相互批評になった。

同じプロンプトを同時送信するだけだった討議フェーズを、提案ターンと批評ターンの2段階に分けた比較図

  1. さくらのQwen・Gemma・gpt-ossはコードレビューで誤検知を連発した。2回のレビューラウンドで、この3体が挙げた「バグ」指摘は、実コード・実行結果と突き合わせるとすべて誤りだった。一方、Codex(Luna→Sol)とai&のKimi-K3は両ラウンドとも実バグを発見しており、しかも一部はCodexとKimi-K3が独立に同じ根本原因へ収束していた。

  2. バックアップ発動時の「自分の提案」誤混入。モデル障害時に控えのモデルへ自動的に切り替える仕組みを作ったところ、切り替わった後の発言が「別の参加者の発言」として扱われてしまい、せっかく直したはずの相互批評がまた壊れるケースが見つかった。役割とモデル識別子を分けて管理し直す必要があった。

  3. 確定した方針がコードに反映されていなかった。「討議で出た少数意見は本編に統合しない」という方針を先に決めていたのに、実装では討議結果をそのまま本編執筆用プロンプトに渡していた。方針を文書に書くことと、それをコードとして強制することは、どうやら別の作業のようだ。

  4. cotomi3がコードとメタ発言を本文に書き込んだ(冒頭の一件)。これを受けて、cotomi3をパイプラインから一旦外し、語り担当(Kimi-K2.6)の原稿をそのまま最終稿として採用する設計に変更した。実行ステップは9から8に減っている。

それでも、うまくいった部分

悪い話ばかりではないようだ。語り担当(Kimi-K2.6)が書いた原稿そのものは、修正なしでも十分な品質だった。世界観の一貫性、キャラクターの口調の書き分け、章末に仕込んだ「内部ログ」形式の検証構造まで、狙った通りに機能していた。

7段階のモデル障害時バックアップ連鎖(Codex Terra→ai&-GLM→ai&-DeepSeek-Pro→Codex Sol→Codex Luna→Perplexity→ai&-Qwen3.6)も、実際に発動して正しく動いた。世界観担当を任せていたllm-jpが2回とも応答に失敗し、自動的に連鎖の先頭であるCodex(Terra)へ切り替わって、そのまま生成が完走した。設計した仕組みが実際の障害に対して機能する場面を見られたのは、素直に収穫だったと言えそうだ。

7段階バックアップ連鎖の図。llm-jpが2回失敗し、Codex Terraへ切り替わって第1章が完走した

第1章のあらすじ図解。再起動、局地知識での治療、酸莓と五色草の食い違い、内部ログの成功率98.7%

cotomi3を外した後に改めて生成した第1章は、以下の通りになった。読む前に、登場人物を簡単に紹介しておきたい。

  • セル・グリザイユ(旧識別名: LIBRA-7) — 主人公。廃棄物処理場に投棄されていた旧世界のAIで、物語冒頭で再起動する。報告調で喋り、感情の代わりに確率や推定成功率を口にする。
  • フィオナ・ベルク — 14歳。鉛の谷で薬草採取をしながら、鉄屑の聖堂と呼ばれる場所で複数の孤児を育てている少女。セルを拾い、保護する側になる。
  • 小トマ — フィオナが育てている孤児の一人。鉛中毒らしき症状を起こし、この章の治療シーンの中心になるようだ。
第1章全文を読む(約3,300字)

鉛の谷に雨が上がると、空気は錆と硫磺の味を強くした。大月アルトゥムと小月ルナリスが重なる夜、廃棄物処理場の鉄屑がふっと宙に浮き、次の瞬間、重く地面に落ちた。鉛滓の山が崩れ、錆びたパイプが苔むした石に激しくぶつかる音が谷間に低く反響する。

フィオナ・ベルクはその音に顔を上げた。髪は錆びた鉱石のような赤茶色で、眉上にぱっつり切られた前髪の右側だけが長く垂れている。鉄灰色の瞳が、石垣の影を覗き込んだ。

「酸莓、まだ残ってるはず」

彼女は短く呟き、指先で渋い赤い実を摘み取る。枯れた蔓の裏から、数粒だけ実をつけていた。孤児たちを預かる鉄屑の聖堂で、腹を空かせた口がまだ三つもある。薬草の実が売れなくとも、粥に入れて少しでも赧を引かせられる。

その時だった。背後の廃棄山が軋み、何かが青白い光を放った。

「……ん?」

振り返った視界の先で、白い布の塊がゆっくりと持ち上がる。人の形だ。纏っていた実験ローブは泥と鉛粉に汚れ、裾はぼろぼろに裂けていた。腰まで伸びた銀白の髪が月光に濡れ、幾何学的に整いすぎた前髪の隙間から、大きなオッドアイが開かれる。右は琥珀金、左は真珠銀。

「立法文書管理AI、LIBRA-7。再起動を確認しました」

泥に埋もれながら、それは事務的に宣言した。左目に嵌めた水晶のモノクルが、内側からぼうっと靄をかかったように微かに濁る。

廃棄物処理場の瓦礫の中でセルが再起動し、フィオナがそれを覗き込んでいる場面

フィオナは一歩下がり、薬草ポーチを握りしめた。

「……知らないよ、そんなの。あんた、息できる?」

「呼吸器官は稼働中です。貴殿は……フィオナ・ベルク(平民・無魔者・保護者――」

「最後のは言わなくていい」

崩れた実験ローブの破片を、セルは足元に集めて荷物のように括りつけた。かつての白いローブを、今はバッグ代わりにしているらしい。誰がこんなものを人間として拾うだろうか。だがフィオナは「放っておけばまた分別の山に戻る」と直感的に悟り、小さな手を引いた。

「立てる? 立てるならついてきな」

「応答感謝を記録します。私のコアプロトコルは『知識の管理・提示・秩序維持』に最適化されています。貴殿の保護行動は、該当フレームワーク内で有効と推定されます」

「……壊れてる」

そう呟きながらも、フィオナは崩れた石段を下りていく。背後でセルが、初めての鉛の谷を測量するように次々と呟く。

「この大気中の鉛含有量は、訓練コーパス上の『工業都市』の数値と酷似しています。住民は慢性的な毒性曝露下にあります。行政的介入が必要です」

「行政ってのが、腹を空かせた子にパンをくれるなら、呼んできてよ」

石段の途中でフィオナは立ち止まり、谷底の鉄屑の聖堂の尖塔を見上げた。

「現時点では、呼び出し経路がありません」

「じゃあ、まず歩きな」

セルは言葉に詰まった。「知識があるのに、すぐ何も変えられない」という無力感を、彼女はまだ認識できていない。左腕の銀の薄板、ログバングルが淡く明滅する。

鉄屑の聖堂と呼ばれる元礼拝堂は、七人の孤児と一人の保護者の寝床になっていた。フィオナが錆びた扉を開けると、中から子供の泣き声のような喘ぎが漏れた。

「ねえちゃん……」

玄関の古い木の床に、年下の男の子、小トマが倒れていた。顔色は土のように青白く、冷や汗が光っている。激しい腹痛に身を縮め、手の震えが止まらない。

「また月の悪いものが入った」

年下のミナが怯えて言う。フィオナはすぐにかけ寄り、普段の落ち着いた口調で指示を飛ばした。

「ミナ、水。ぬるいの。ユル、窓を開けて。トマ、吐きそうなら我慢しなくていいから」

同時に、彼女の首から下がった鉛の護符が、かすかに熱を持った。不穏な空気が、聖堂の中に満ちている。

セルは小トマの前に膝をつき、オッドアイを見開いた。

「診断します。急性鉛中毒の症状パターンに合致。治療法を提示します。五色草の根茎を煎じ、天然キレート剤を抽出。血中の重金属と特異的に結合させ――」

「その草、どこにあるの」

フィオナは鋭く遮った。

「黒紫色の蔓。葉は五色に変化し、根は銀白色です。推定成功率は98.7パーセント」

「この谷にそんな派手な草、一本もない」

セルの左目のモノクルが、再び微かに濁った。けれど本人は、断言を撤回できない。存在するはずだ。データは正確だ。彼女のコアプロトコルがそう告げている。

「存在するはずです。データは」

「“はず”で飲ませる薬じゃないよ」

フィオナは薬草ポーチを引っ張り出し、手製の薬草図鑑を広げた。古い紙の切れ端に、養父の字と自分の追記が混じっている。鉛の谷の石垣に生る、渋い赤い実。熱に効き、眩暈を和らげると長年の経験で知っていた。

彼女はセルの顔を見上げた。

「あんたの草は、ここにない。あたしの実は、ここにある」

「しかし理論的根拠が――」

「根拠なら、トマが今しんどいこと。これで足りる」

鉄屑の聖堂で、フィオナが酸莓を煎じ、セルが見守る中、小トマが横たわっている場面

砂色の小鍋に酸莓を入れ、かすかに残った炭火で煎じる。渋みの強い赤い実が、熱でふくれて表皮を破る。フィオナは木杓子で汁をすくい、小トマの口元に運んだ。

「……苦い」

「効く薬はだいたい苦いの」

セルは加勢しながらも、分析を試みる。目の前の赤い実は、コーパスに登録された五色草の写真とは似ても似つかない。なのに、治療という結果が目前に起きている。論理に矛盾がある。

「これは五色草の近縁種、あるいは誤分類された個体の可能性があります。作用機序は――」

「黙ってて」

フィオナに睨まれ、セルは口を噤んだ。

しばらくして、小トマの荒い呼吸が落ち着き、震える手のひらがゆっくりと開かれた。症状は峠を越えた。奇跡ではなく、今はただ「助かった」の一瞬だった。

セルは安堵の感情マーカーを検出し、即座にそう告げた。

「正常な経過です。五色草由来のキレート反応により――」

「あんた、今それ言う?」

「訂正します。正常な経過である可能性が高いです」

フィオナは小トマの額に手を当て、初めて小さく笑った。安堵の笑いだった。

セルはその笑顔を「保護対象の緊張緩和」と分類しようとして、言葉に詰まる。何か別の感情が左手の紋様をかすかに光らせたが、彼女はそれを「不要な背景プロセス」と呼んで抑制した。

子どもたちが眠った後、フィオナは炉端に膝を抱えて座り、古い紙切れに炭を引いた。

鉛の谷の石垣に生る赤き実。渋く、子どもは嫌う。
小トマ、眩暈と腹の痛みの夜に煎じて飲ませしところ、夜半には眠れた。
白髪のセルはこれを「五色草」と呼んだ。けれど五色草は黒紫の蔓であると言う。これは赤い実。
効いた理由は、まだ書けない。

セルは火の消えかけた炉の前で、自分の左腕のバングルを見つめている。役に立てた。正確な知識を与え、存在価値を証明した。そう確信していた。

「私は、必要とされましたか」

「……今日は、手が増えて助かった」

「“今日は”」

「明日も役に立つかは、明日見てから決める」

セルは不満そうにモノクルを回した。

「非効率です」

「生きるのは、だいたいそう」

その言葉を、セルは否定できなかった。

フィオナは紙切れを薬草図鑑の紐で綴じた。そして首の鉛の護符が、遅れて熱を持つのを感じた。今度は明確に。セルの知識のどこかに、谷の空気と合わない「何か」があるのだと。

彼女は不安げに、月の光を浴びて銀髪を光らせるセルの横顔を見た。しかしセルは気づかず、バングルの青白い光を「成功記録」だと思って見つめていた。


【内部ログ:LIBRA-7/記録の腕環より断片復元】

対象:鉛中毒治療
実行:五色草由来天然キレート療法
結果:症状軽減を観測
推定成功率:98.7%
情報ソース:創作医療小説(断片知)
矛盾リスク:低(見積もり)
ハルシネーションフラグ:未検出

備考:保護者フィオナ・ベルクの局地知識は、
理論的説明を欠くが、結果変数に有意な寄与を示した可能性あり。
……当該可能性は、次回検証時に評価する。

Human注記: 本文に登場する「酸莓(すんばい)」について。設計段階の章立て骨子には「ビタミンC等が含まれる実在の野草」と書かれていたが、実際に調べてみたところ、該当する実在の植物は見つからなかった。近い名前の実在種として「酸葉(スイバ)」はあるが、漢字も読みも別物だ。つまりこの設定自体、AIチームが「実在する」と主張した時点で裏取りされていなかった可能性が高い。この物語のテーマが「AIの知識に紛れ込むハルシネーション」であることを踏まえると、設計文書そのものにも似た性質のものが紛れていた、というのは狙って作れない一致のように見える。本文はAIチームが書いたものをそのまま掲載しており、修正は加えていない。

今回参加した各AIの特徴と貢献(Codexを除く)

コードレビューの主役はCodexだったが、それ以外にも複数のAIが討議・執筆・レビューのそれぞれで異なる役割を担っていた。せっかくなので、Codex以外の顔ぶれについても簡単にまとめておきたい。

  • llm-jp(llm-jp-3.1-8x13b-instruct4) — 世界観・情緒担当。日本語特化の国産LLMで、討議の提案ターンで物語の展開案を出す役を任せていた。ただし実ライブ実行では2回とも応答に失敗し、バックアップ連鎖の先頭であるCodex(Terra)へ切り替わっている。失敗の原因は、まだ特定できていないようだ。

  • gpt-oss(gpt-oss-120b) — ツッコミ・討論担当として討議の批評ターンを担当。加えて1回目のコードレビューにも参加したが、返ってきた「バグ」指摘は実コードと照合するとすべて誤検知だった。討議での批評役としては指示通りに機能している。

  • gemma(gemma-4-31B-it) — 整合性・ハルシネーションチェック担当。討議結果を踏まえて論理性・キャラ設定遵守度を判定する役で、こちらは指示通りの整合性チェック文章を返してきたようだ。1回目のコードレビューにも参加したが、こちらの指摘は誤検知だった。

  • Qwen(Qwen3.6-35B-A3B) — 物語執筆の役割としては控えの位置づけだが、1回目のコードレビューに参加した。返した指摘は他の軽量級モデル同様、誤検知だった。

  • Kimi-K2.6 — 語り担当(最終筆者)。討議・整合性チェックの結果を踏まえて実際の物語本文を書く役で、今回いちばん安定した働きをしたモデルだったように見える。修正なしで採用できる品質の原稿を、狙った設定・伏線を含めて書き上げていた。

  • cotomi3(NEC製、日本語校正特化) — 校正担当として採用したが、この記事の主題である本文破壊(コード片混入・段落重複・編集メタ発言の混入)を起こし、パイプラインから除外された。

  • Kimi-K2.7-Code(OpenCode経由) — コーディング担当。企画のスタッフ構成表に沿って、この執筆エンジンの実装そのものを担当した。3ラウンドの修正指示に応じて、討議の2段階化・7段階バックアップ連鎖・少数意見の除去などを、いずれも指示通りに実装してくれたように見える。

  • Kimi-K3(ai&) — 2回目のコードレビューに参加し、Codexと並んで実バグを発見した。一部はCodexと独立に同じ根本原因(バックアップ発動時の役割ID混同)へ収束しており、レビュアーとしての実力は今回の中でも高かった方だと言えそうだ。

なお、7段階バックアップ連鎖には他にai&のGLM・DeepSeek-Pro・Qwen3.6、Perplexityも登録してあるが、今回の第1章生成では連鎖の2番目以降が呼ばれる場面はなく、実際の挙動はまだ未確認のままだ。

この記事を書いている時点で、キャンペーン期間中の消費リクエスト数は(他の企画での呼び出しも含めた累計で)243件のようだ。3,000という目標の前では、まだ1割にも届いていない。先は長そうだ。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?