自動記事生成で、本文・要約・タイトルを一つのprovider呼び出しとして扱うと、部分的な失敗からの復旧が難しくなります。
予兆(YOCHO)では、生成候補を非公開のdraftとして保存し、本文・要約・タイトルを段階的に検証する構成にしました。本稿は実装・運用上の設計メモです。サービスの現在地は https://yocho.ai で確認できます。
1. 失敗を「全文失敗」にしない
記事化の処理は、概念的には次のphaseに分けます。
source snapshot
-> body generation
-> body checkpoint
-> summary generation
-> title validation / title repair
-> final publication transaction
本文が成功して要約だけが失敗した場合、本文を再生成してはいけません。本文の候補、source digest、response digest、費用receiptを保存したcheckpointを要約phaseの入力にします。
2. draftと公開済み記事を分ける
provider応答は、品質検証前にeditorial_draftsへ保存します。保存するのは、次のような監査に必要なbounded receiptです。
- sourceのdigest/hash
- provider応答のdigest
- call IDとphase
- 費用receipt
- 品質判定
- タイトル補正前後
APIキーやHTTP header、providerの応答本文そのものは保存しません。候補draftと公開済み編集稿を同じレコードの「成功」として扱わないことが重要です。
3. known failureとunknown failure
再試行の判断は、HTTP statusだけではなく、外部処理の結果と課金の確定状態で分けます。
| 状態 | 扱い |
|---|---|
| 応答・課金が確定した検証失敗 | 対象phaseだけを限定的に一回修復 |
| 429など再試行可能な拒否 | 共有backoffと上限に従う |
| timeout・通信断・請求結果不明 | unknown hold。自動再送しない |
| 保存済み本文があり、source identityが一致 | 本文を再生成せず再検証 |
結果不明を自動再送しないのは、品質よりも費用のためだけではありません。同じ呼び出しが実は成功していた場合、重複生成と二重計上が起こるからです。
4. 具体例:タイトルは本文とは別の品質境界にする
本文が妥当でも、タイトルには別の問題が入ります。
- 空文字やページ番号だけになる
- 出典にない数量が入る
-
source_urlやJSONなどのmetadataが漏れる - 企業名が曖昧一致になる
- 英語の原見出しが日本語記事タイトルとして残る
TDnetのような企業開示資料では、取得済みのissuer_nameとlisting_titleから安全なタイトルを構成し、同じvalidatorを通します。それでも修正が必要なら、本文を作り直さずタイトル専用phaseを使います。
公開許可はprovider応答時だけで決めません。NewsEditorial.status='published'へ変更する最終transaction内でも、source snapshotを使ったタイトル品質ゲートを再実行します。
5. 実装で見えたこと
2026年9月14日の固定救済対象は95 task IDsでした。v2では本文を全件再利用し、保存済み要約も条件が一致するものは再利用しました。英語原見出しへ置換された43件は、本文と要約を保持して日本語タイトルへ修正しています。
この95件の救済完了を、元の3,356件全体の処理完了と混同しないよう、manifestとreceiptを別に持ちます。成功件数だけを見てqueueが空になったと判断しないためです。
6. まとめ
自動記事化の再現性を上げる鍵は、モデルを交換することだけではありません。
- provider候補を公開前に保存する
- 本文・要約・タイトルを別phaseにする
- known/unknown failureを分ける
- 再生成ではなく、保存済み候補を再検証・救済する
- 最終公開transactionでも品質ゲートを通す
これは設計・運用上の実装記録であり、すべてのAI生成内容が正しいことを保証するものではありません。実際のサービスと現在の公開情報は https://yocho.ai を参照してください。