0
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?

出力の構成を 1 つに固定せず、候補から選ばせて選んだ key を保存する

0
Posted at

こんにちは。小学生向けのニュースサイト、こどもニュースをつくっています。

記事の本文は、一次ソースから抽出した事実データを材料にして、学年ごとに書き分けます。書かせるときのプロンプトには、記事の構成を指定していました。

その指定を、1 つの型から、候補の一覧に変えました。どれを使うかは、材料を読むモデルに選ばせて、選んだ結果を保存します。

症状 — 全部が同じ入り方で、同じ締め方になる

もとのプロンプトは、3 つの節を必ず守らせる形でした。

  1. 背景
  2. 事実の説明
  3. まとめ

この形で書かせると、どのニュースも同じ入り方をして、同じ締め方で終わります。読み比べると、内容は違うのに読み心地が同じです。

もう 1 つ、締め方に問題がありました。まとめで必ず「自分たちの生活とのつながり」を書かせていたので、事実データからは言えない一般論や教訓で閉じる記事が出ていました。

材料に無いことを書かせているのは、事実を材料にするという前提と食い違います。構成の指定が、その方向に押していました。

ニュースによっては、出来事から入るほうが短くはっきり伝わります。数字から入るのが良い記事も、時系列で追うのが良い記事もあります。

外れた案 — 機械で割り当てる

最初に考えたのは、構成を機械で割り当てることでした。順番に回す、あるいは乱数で選ぶ形です。

これは採りませんでした。ニュースと構成が噛み合わないと、同じ型の繰り返しより読みにくくなります。

たとえば、場面が思い浮かぶ出来事の無いニュースに「出来事から始める」を割り当てると、無理やり場面を作ることになります。無い場面を作るのは、材料に無いことを書くのと同じです。

構成の多様性そのものが目的ではありませんでした。ニュースに合う構成が選ばれることが目的でした。

決めた形 — 候補を並べて選ばせ、選んだ key を保存する

構成のパターンを一覧として持ち、プロンプトに全部並べて、そのニュースに合うものを 1 つ選ばせます。

選定そのものを、事実データを読むモデルの仕事にしました。材料を読まないと選べない判断なので、材料を読む側に置くのが素直でした。

そして、選んだ結果を出力に返させて保存します。

候補の型

パターンは構造体で持っています。

export interface ArticleStructure {
  /** 保存・指定に使う識別子(不変) */
  key: string;
  /** 日本語名(プロンプトの見出し・admin の選択肢) */
  label: string;
  /** どんなニュースで使うか(LLM が選ぶときの判断材料) */
  usage: string;
  /** 書き出しから終わりまでの順番 */
  steps: string[];
  /** この構成でやってはいけないこと・外してはいけない勘所 */
  notes: string[];
}

usage が、選ぶための判断材料です。パターンの中身(steps)だけを並べても、どれを選べばよいかの手がかりになりません。「どんなときに使うか」を各パターンに持たせて、選択の基準を候補の側に置きました。

notes は、その構成でやってはいけないことです。従来の型にも入れてあります。

    notes: [
      '導入は一般論ではなく、このニュースに固有の背景を書く。',
      'まとめの「つながり」は事実データから言えることに限る。作文の締め言葉にしない。',
    ],

もともと問題だった締め方を、構成の側に書きました。構成を選んだ結果として、その構成の注意事項が付いてきます。

key は変えない、文言は変えてよい

識別子の扱いを決めておきました。

// key は DB (`articles.structure` / `draft.structure`) と CLI (`--structure`) と admin の選択肢が共有する
// 識別子なので、**一度出したものは変えない**(過去の記事がどの構成で書かれたか辿れなくなる)。
// label / usage / steps / notes は文言なので変えてよい。

key はデータベースの列と、コマンドのオプションと、画面の選択肢が共有します。一度使ったものを変えると、過去の記事がどの構成で書かれたかを辿れなくなります。

一方、表示や説明の文言は変えてよいことにしました。プロンプトの効きを調整するときに触るのはこちらです。

「保存する識別子」と「見せる文言」を分けておくと、片方だけを自由に触れます。分けていないと、文言を直したくなるたびに過去のデータとの互換を考えることになります。

選択を記録すると、後から数えられる

選んだ key を保存しない案もありました。記事の本文が良くなればそれでよい、という考え方です。

保存することにしました。記録が無いと、どの構成がどんな記事を生んだのかを追えません。偏りにも気づけません。

たとえば、候補を 5 つ用意したのに 1 つばかり選ばれているなら、他の 4 つは説明が足りていない可能性があります。数えて初めて分かります。

列は 1 つで足ります。生成のたびに 1 つの値を書くだけなので、コストもほぼありません。

一覧に無い値が返ってきたときは、記録しません。存在しない構成の名前を保存すると、後から数えるときに嘘が混ざります。書けないなら空にしておくほうが、集計のときに扱えます。

構成に依らないルールは別の節に置く

プロンプトの中で、構成の説明と、それ以外のルールを分けました。

分けたのは、文体、推測の禁止、本文に URL を書かせない、といった書き方の規則です。これらは構成が変わっても変わりません。

構成の節に混ぜると、パターンを 1 つ足すたびに同じ規則を書き写すことになります。写したものは片方だけが直ります。

プロンプトキャッシュを壊さない

構成の一覧をプロンプトに並べると、そのぶん system プロンプトが長くなります。

ここで気にしたのは、プロンプトキャッシュです。このプロジェクトでは、system プロンプトを学年ごとの定数にしてあり、コールをまたいでバイト単位で同じになるようにしてあります。同じであればキャッシュに乗ります。

構成の一覧は固定の文字列なので、並べても同一性は保たれます。長くなったぶんは、キャッシュから読まれる側に載ります。

構成を 1 つだけ指定したときは、別の system プロンプトになります。こちらはキャッシュに乗りませんが、指定するのは人が試すときだけなので、実運用の回数には効きません。

プロンプトに情報を足すときは、「毎回同じ内容か」を見ます。同じなら、長さはあまり問題になりません。入力ごとに変わるものを system 側に混ぜると、そこで同一性が壊れます。

一般化できる部分

生成の出力に「型」を持たせるとき、型を 1 つに固定すると、出力が全部その型に寄ります。寄った結果、材料から言えないことを書いてでも型を満たそうとします。

型を複数用意して選ばせると、この圧力が減ります。そのときのコツは 3 つです。

1 つ目は、選択を機械で割り当てないことです。入力と型が噛み合わないと、固定していたときより悪くなります。選択には入力を読む必要があるので、入力を読む側に選ばせます。

2 つ目は、候補に「どんなときに使うか」を持たせることです。候補の中身だけを並べても、選ぶ基準になりません。

3 つ目は、選んだ結果を保存することです。列 1 つで、後から偏りを数えられます。想定していない値が返ったときは、記録せずに空にします。

そして、型に依らないルールは型の外に置きます。型を増やすたびに書き写すものがあるなら、それは型の外にあるべきものです。

まとめ

  • 出力の構成を 1 つに固定すると、全部が同じ入り方と同じ締め方になる
  • 「必ずこう締める」と書くと、材料から言えないことを書いてでも締めようとする
  • 構成を機械で割り当てない。入力と噛み合わないと、固定していたときより読みにくくなる
  • 候補を並べて、入力を読む側に選ばせる。選定は材料を読む工程の仕事
  • 候補には「どんなときに使うか」と「やってはいけないこと」を持たせる
  • 保存する識別子と、見せる文言を分ける。識別子は不変、文言は自由に触れる
  • 選んだ結果を列 1 つに保存する。偏りは数えないと気づけない
  • 一覧に無い値が返ったら記録しない。存在しない値を保存すると集計に嘘が混ざる
  • 構成に依らないルールは別の節に置く。型を増やすたびに書き写すものは型の外にある
  • system プロンプトに足すものが毎回同じ文字列なら、プロンプトキャッシュの同一性は壊れない
0
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
0
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?