一本化した事前分布 — 設計¶
翻訳について: 正本は英語版です。
Status: master に実装済み、未リリース。confidence の変更 (第 5 節) は既定で有効です。事前分布の重み
(第 2〜4 節) は、第 8 節の計測が動かすまで恒等の既定値のままです。年齢の重みは計測済み (M2) で、試した
どの率も重み無しに負けたので、既定は無効のままです (第 8 節)。時間は代わりに、順位の空間で上限を付けた
時期の手がかり から順位に入ります。
想起の線の第 3 節 と
far の票の計画
を実装する形を定め、両者が「最初に決めなければならない」と書いていること — 最後の並べ直しをどうするか — を決めます。
0. 何が変わるか¶
行をどこにあるか (走査上の位置、または古さ) によって上げ下げする重みを、すべて 1 つの関数 p(行) に移します。
この関数が決めるのは順位だけで、どの行が品質ゲートを通るかは決めません。
confidence スコアは融合済みのリストを並べ直さなくなり、足切りにも使われなくなります。値そのものは計算され、
各行の横に別の値として返されます。
既定の設定では、confidence を無効にしている配備には何も変わりません。confidence を有効にしている配備では、 結果が confidence の順ではなく融合の順になり、設定 1 つで以前の挙動に戻せます。
1. 今、重みはどこにあるか¶
位置や古さで行に重みを付ける仕組みが 4 つあります。それぞれ別の設定を持ち、互いを知りません。
| 仕組み | 何をするか | 実質の重み |
|---|---|---|
ベクトル走査窓 (CPERSONA_MAX_MEMORIES) |
ベクトル検索は、走査位置で最も新しい行だけを順位付けする | 窓の中は 1、外は 0 — 暗黙の新しさの優遇 |
far リスト (CPERSONA_VECTOR_REACH、CPERSONA_VECTOR_FAR_LIMIT) |
窓の外の行を 2 本目のベクトルリストとして融合に加える | 窓の外も 1 — far の票に値段が無い |
| エピソード境界ペナルティ | 最新エピソードより古い記憶に、0.5 まで下がる係数を掛ける | 境界での段差。融合の後に掛かり、行を品質ゲートの下へ押し出せる。2.6.0a7 から既定で無効 |
confidence (CPERSONA_CONFIDENCE_ENABLED) |
類似度・時間の減衰・解決済みの印・想起の履歴を 1 つのスコアに混ぜ、それでリスト全体を並べ直し、足切りにも使う | 下限 0.3 の双曲線型の時間の減衰が、類似度も含むスコアの中に埋もれている |
重みが散らばっていることは、見た目の問題ではなく実害の問題です。開発中の社内ベンチマークで、 実際の長期記憶ストアを測った結果が 2 つあります。
- エピソード境界ペナルティは、2.5.0 より前は順位に効いていませんでした (bug-115)。修正の後、既定の設定のまま 結果を並べ替えるようになり、それを誰も測っていませんでした。セッションごとにエピソードを保存する エージェントのストアでは、答えを持つ記録が 1 位に来る頻度が半分になっていました。公開ベンチマークは エピソードを作らないので、どれもこれを見られませんでした。測られた仕組みの一部でない時間の重みは、 誰もそう決めないまま順位を変えることがあります。
- confidence を有効にすると、
rrfとrsfの 2 つの融合方式が、150 問の質問集のすべての問で同一の応答を 返しました。最後の並べ直しが融合の順を完全に捨てています。したがって、融合の中で掛けた事前分布は、 confidence を有効にした配備では何もしません。同じ質問集で、エピソードペナルティを切った状態では、 どちらの融合方式でも、confidence の有無による正答率の差は McNemar の正確検定で見つかりませんでした。 並べ直しをやめても正答率は下がらない見込みです。
2. 事前分布¶
rrf では、結果の並び順を決めるスコアは次のようになります。
order_score(row) = p(row) × Σ over lists w_list × 1 / (k + rank_on_list + 1)
p(row) = p_age(row) (Cued Recall のために p_cue(row) の因子を空けておく)
w_list = 近いベクトルリスト・全文検索リスト・キーワードリストでは 1
= far リストでは w_far
- far の重み
w_farは、far の票の計画 にある「値段を付けた far の票」です。w_far = 1は今の reach、w_far = 0は reach を切った状態と同じです。 両端はどちらも恒等対照で、それぞれ既存の計測を桁まで再現しなければなりません。 - 年齢の重みは
p_age = max(floor, 1 / (1 + age_hours × rate))です。これは意図して、confidence スコアの中の 時間の減衰と同じ族にしています。confidence スコアは率をストアの期間 (週単位、CPERSONA_REFERENCE_HOURS= 168) で割るので、今 confidence が掛けている時間の項を取り出す腕は、公称のCPERSONA_DECAY_RATEではなく、 計測するストアについて計算したその実効の率を使います。 rsfでは、p(row)は融合・正規化済みのスコアに掛かり、far チャネルはw_farで重み付けされます。 チャネル数による割り算は、計画のrsfの注記どおり変えません。
3. 事前分布は順位を決め、足切りはしない¶
p(row) を掛けたスコアは最後の並び順にだけ使います。品質ゲートと autocut は融合スコアを読み、
そこには far の重み (票の値段は融合の一部) は入りますが、p(row) は決して入りません。
エピソードペナルティの害の半分は、ゲートを通って生じました。行のスコアを下げると較正済みの閾値を下回り、 その行が消えました (ペナルティ自身の設定コメントが、これを目的として書いています)。行を消せる重みは、 掛けた瞬間に候補の集合を変えます。そうなると、並べ替えの効果と除去の効果をもう区別できません。 事前分布をゲートから外しておけば、事前分布が決めるのは「どの行が先か」であって、「どの行が残るか」ではありません。
帰結として、p をどれほど極端にしても、ゲートを通る行の集合は変わりません。件数で切られる順が変わるだけです。
これはテストで固定します。
4. 年齢の測り方¶
- 年齢は、その想起のスコープで最も新しい記録から測ります。現在時刻からではありません。最も新しい記録とは
最も新しい記憶で、confidence スコアがすでに読んでいる範囲です。それより新しいエピソードは年齢 0 と数えます。現在時刻から測ると、
利用者が離れている間にすべての記録が一斉に古くなり、重みがどれだけ記録を引き離すかが、ストアが放置された
期間に左右されます。最も新しい記録から測れば、しばらく使われなかったストアも、最後に使われた時と同じ順位に
なります。confidence スコアも、関連する理由から、年齢が不明な行の基準を最も新しい行に置いています (bug-207)。
もう一方の読み方が必要な配備には
CPERSONA_PRIOR_AGE_ANCHOR=nowを用意します。 - 使えるタイムスタンプを持たない行は、bug-207 以降の confidence スコアと同じく、スコープの年齢幅の中央に置きます。 年齢が不明な行が、既定で勝ってはいけません。
- エピソードも同じ規則で、自分のタイムスタンプから年齢を測ります。エピソードペナルティにあった 「エピソードは免除」は引き継ぎません。特例を無くすことが、関数を 1 つにする目的です。
- profile 行はスコアを持たないので重みを掛けません。ブロックの別枠で入った行にも掛けません。別枠は、 窓が届かない根拠のための追加の枠で、順位の競争の外にあります。
5. confidence¶
- 想起のスコア付けの最後にある、confidence による並べ直しを取り除きます。
- confidence を、品質ゲートの信号の優先順から外します。並べ直しだけをやめると、confidence がどの行を残すかを 決め続けます。それは並べ直しがしていたことの半分です。
CPERSONA_CONFIDENCE_ENABLEDが有効な時は、confidence の値は今までどおり計算され、各行とともに別の値として 返されます (confidence: {age_hours, cosine, score})。- confidence の中の時間の減衰は、順位に効かなくなります。時間を順位に効かせたい配備は、年齢の重みを設定します。 時間の重みを掛ける場所は 1 か所です。
CPERSONA_CONFIDENCE_ORDERING=legacyで、並べ直しと confidence による足切りを復元できます。問題を見つけた 配備は、コードを戻さずに設定だけで戻れます。- confidence を有効にしている配備は、更新後に
calibrate_thresholdを実行し直す必要があります。ゲートの信号が confidence から融合スコアに変わるためです。
6. エピソード境界ペナルティ¶
この線では opt-in のまま残します。年齢の重みが計測されれば、ペナルティはその特例 (曲線ではなく、最新エピソードでの段差) になり、廃止は後の線で提案します。ここでは削除しないので、これに頼っている配備にも道が残ります。
7. 設定¶
| 設定 | 既定値 | 意味 |
|---|---|---|
CPERSONA_PRIOR_FAR_WEIGHT |
1.0 |
w_far。reach が窓より大きく設定されている時だけ意味を持つ |
CPERSONA_PRIOR_AGE_RATE |
0 |
年齢の重みの率。0 は p_age = 1 (無効) |
CPERSONA_PRIOR_AGE_FLOOR |
0.3 |
年齢の重みの下限 |
CPERSONA_PRIOR_AGE_ANCHOR |
newest |
年齢の基準。スコープの最新の記録 (newest) か現在時刻 (now) |
CPERSONA_CONFIDENCE_ORDERING |
fusion |
confidence を並び順にも足切りにも使わない。legacy で両方を復元 |
これらの既定値では、confidence を無効にしている配備は、この変更の前のリリースとビット単位で同じに振る舞います。
挙動の golden と既存のテスト群がそれを固定します。既定値で挙動が変わるのは CPERSONA_CONFIDENCE_ORDERING だけで、
それも confidence が有効な場合に限ります。
事前分布の既定値は、第 8 節の計測に合格した後にだけ動かし、 far の票の計画の展開 が求めるとおり、1 回の変更でまとめて動かします。
8. 既定値を動かす前に何を測るか¶
どの計測も、走らせる前に事前登録します。
| 計器 | 腕 | 判定の骨子 | |
|---|---|---|---|
| M0 — confidence の並べ直しをやめる | 実ストアのベンチマーク、開発用の問、recall、エピソードペナルティ無効 |
confidence 有効で legacy 対 fusion |
事前に決めた幅の中で、正答率が下がらない |
| M1 — far の重み | far の票の計画 と同じ LongMemEval の近い層・遠い層 | reach 200,000 で w_far ∈ {0, 0.25, 0.5, 0.75, 1} |
両端が腕 A と S を桁まで再現し、そのうえで近い層は出荷時の答えから −1.0 以内、遠い層は重み無しの far リストから 1 ポイント以内 |
| M2 — 年齢の重み | 実ストアのベンチマーク (全問型、最新の値と時間の型を中心に) | rate ∈ {0, 小, 中, confidence の実効の率} |
全体の正答率が上がり、どの問型も 3 問以上を失わない。古い答えを問う型がガード。計測済み: 開発用の問で、最新の値の型も含め、どの率も率 0 に負けたので既定は無効のまま。 rrf では 1 位と 30 位の差が 1.475 倍しかなく重みの幅より小さいので、乗算の年齢の重みは新しさが関連度を上回らせた |
- 年齢の重みは、本物の時間構造を持つデータでだけ測ります。LongMemEval の harness
(
benchmarks/benchmark_trackb_lmeb.py) はすべての記録を同じ固定のタイムスタンプで書き込むので、 すべての記録が同じ年齢になり、そこで年齢の重みを測っても何も測れません。これがエピソードペナルティの教訓です。 時間の重みは、時間が実際にばらつくストアで判定しなければなりません。 - 率は開発用の問で選び、取り置いた問で 1 回だけ確かめます。取り置いた問は、エピソードペナルティの影響を 突き止めるためにすでに 1 度使っており、確認の報告にはそのことを書きます。
9. この段階でやらないこと¶
- Cued Recall (呼び出し側が「先月」のように時期を宣言する)。入力の契約を変えるもので、想起のプロセスに属します。
p(row)はそのための因子を空けておきます。 - 想起のプロセスと適応的融合。
- エピソード境界ペナルティの削除 (第 6 節)。
10. 危険¶
| 危険 | 守るもの |
|---|---|
| confidence を有効にしている配備で順位が変わる | リリース前の M0。CPERSONA_CONFIDENCE_ORDERING=legacy で設定だけで旧挙動に戻せる。更新後の再較正 |
| 年齢の重みが、エピソードペナルティのように古い答えを埋もれさせる | 事前分布は行を通しも除きもしない (第 3 節)。既定で無効。M2 が古い答えの型を見張る |
| 既定値が黙って挙動を変える | 既定値ではビット単位で同一 (golden で固定)。w_far の両端の恒等対照 |
| 時間構造の無い計器が何も報告しない | M2 は実ストアで走らせる。LongMemEval の限界は、回避せずに明記する |