工程1:学習の保存パイプラインを「確定」する(package→queued→upsert)
目的:コメント差分が 必ず Chroma に「更新」される状態を固定する(入口/出口がこれに依存する)
決定事項(ここで必ず決める)
- doc_id 方針(最重要)
- 「同じ natural_key の学習更新」を成立させるには、Chroma の
idは 自然キー由来で固定にするのが正解
✅doc_id = sha256(entity:natural_key:lang)(上書き更新される)source_hashは **中身のハッシュ(差分検知・NOP判定用)**として metadata に持つ - つまり doc_id ≠ source_hash が基本(今の
services/chroma_upsert.pyの_doc_id()と整合)
- Chroma書き込みAPIは add ではなく upsert
- Chroma 側は
addだと「同じidで再投入」や更新運用が破綻しやすいので、upsertに統一(あなたの狙い通り)
- metadata の None を禁止
- 今起きたエラー:
Expected metadata value ... got Noneを二度と出さない
✅ ルール:metadata はstr/int/float/boolのみ、Noneはキーごと落とす(または空文字)
- natural_key の命名規約を固定
- いまは
sid#turnとnlq::<sid>::<turn>::cmt::<idx>が混在気味なので、将来の検索/学習利用のために統一する
例)nlq::<sid>::<turn>::<variant>::<subkey>- comment diff:
nlq::<sid>::<turn>::cmt::<idx> - analysis comment:
nlq::<sid>::<turn>::analysis - execute要約:
nlq::<sid>::<turn>::exec
- comment diff:
- user_idをどう扱うか(あなたの提案)
user_idは natural_key には入れない(入れると更新単位がブレる)- 代わりに
meta.user_idとnlq_history.user_id(列追加)で束ねる - 将来「去年のものは捨てる」は **DB側の削除ポリシー(TTL)**で実現
工程2:入口(Metabase結果 → LLMが“最初の分析コメント”を出す)
目的:「LLMが出すコメント」が無いと差分学習が始まらないので、まず 初回コメント生成 を作る
決定事項
- 入口API(どこで生成するか)
- 選択肢A:
/nlq/executeの最後に feature flag で自動生成 - 選択肢B:別API
POST /analysis/comment(推奨:切り分けが楽)
- 入力に使うデータ(最低限)
- Metabase の結果は「URL」ではなく、集計結果/列名/条件/期間/粒度(= LLMに渡せる構造)
card_id/hashは参照として meta に保持してOK(署名URLは不要)
- 保存形式(学習対象として残す単位)
- 生成物は
variant="analysis"(またはanalysis_comment)として history に保存 - package 化して
portal_chroma_docに enqueue - natural_key は固定:
nlq::<sid>::<turn>::analysis
- コレクション方針
- 当面は既定:
nlq_sessions_{lang} - 後で user_id を入れるなら
nlq_users_{lang}に分けるのも可(ただし工程1で決めた meta.user_id が前提)
工程3:出口(学習済み差分 → 次のコメント生成に反映)
目的:差分を貯めるだけでなく、次のコメントを賢くする(あなたが言ってる“命題”)
決定事項
- 検索キー(何で過去を引くか)
- 検索クエリは「ユーザの最新コメント」だけだと弱いので、最低でも
- ユーザの質問文
- base SQL(または要約)
- 生成した analysis comment の要点
を混ぜたテキストで検索する
- フィルタリング(user_id運用をするなら)
meta.user_idで絞れるようにしておく(工程1の決定の通り)
- 出口の生成対象(何を出すか)
- 最低ラインは「次の分析コメント案」
- 余力があれば「SQL改善提案」も一緒に(ただし今はコメント差分が主目的ならコメント優先)
- 学習ループの更新単位
- 「同じ natural_key の更新」は analysis と comment diff は別キーにするのが安全
...::analysisは “そのターンの分析コメント”...::cmt::idxは “そのターンでユーザが入れた指摘/修正”
- 古いものを捨てる運用
- user_id + created_at でDB側削除(TTL)
- Chroma 側は「削除」か「再構築」どちらで運用するかを決める(まずはDB TTL→必要なら再upsert)
まとめ(超短縮)
- 工程1:doc_id固定(自然キー由来)・upsert統一・metadata None禁止・natural_key統一・user_idはmetaで束ねる
- 工程2:Metabase結果から LLMが初回分析コメントを生成→history保存→package→queued
- 工程3:学習済み差分を検索で引いて、次のコメント生成に混ぜる(user_idフィルタ可能に)
この3工程の順にやると、入口/出口を作っても「学習の保存」が揺れないので、デバッグが地獄になりません。
コメントを残す