模块 6 · L0 与 L1 画像

正式风评 vs 抽槽画像
Top-K 怎么注入 prompt?

客户线除了查 Core 真账,还有后台画像抽槽(L1)调措辞。 拍板铁律:L0 永远优先——正式 C1~C5、持仓数字、适当性判定听 Core,L1 不能覆盖。 偏好类槽位注入 prompt 时走 Top-K + 时间衰减(R1),不是全量平铺。

L0 vs L1:谁说了算?

L0 · Core 正式数据

风评 C1~C5、持仓/流水数字、适当性矩阵判定——100% 来自 Core 只读查询 Tool(core_ro_tool.py)的 fact_text。LLM 只解读,不能改写。

L1 · 对话 enrich 画像

登录客户每 5 轮节流,后台线程跑画像抽槽与合并(profile_service.py)→ 写入 MySQL style_tags + Redis 热缓存。只影响 generate/chitchat 的措辞语境,不能替代正式风评。

撞车规则

抽槽若与 L0 字段冲突(例如用户口述「我是 R5」但 Core 是 R3)→ 永远听 L0。合并规则 D7:用户显式 user_declared 不被 inferred 覆盖。

13 槽位 + confidence 门槛

槽位表唯一来源:画像槽位定义(profile_slots.py)——13 个 path(含 C-08 investment.allocation_target),含 merge_mode 与 sensitivity。

①

归一 · normalize_value
例如「我喜欢货币基金」→ 映射到 9 类 PRODUCT_TYPE_VOCAB(不是具体 SKU 代码)。

②

阈值 · confidence ≥0.7(默认)/ ≥0.9(高敏)才写入;高敏 inferred 一律丢弃。

③

合并 · merge_candidates
单值 latest 覆盖;偏好/排除类 set_union 并集,并写 items_meta(R1)。

谁写 L1: 仅登录客户线(customer_service.profile_maybe_extract);游客试聊不写画像。
C-04 阈值槽: threshold_pref_summary → customer_threshold_config;达线提醒仅在查持仓时 inline。

R1 · 偏好 Top-K 注入

注入前筛选 · 画像上下文渲染(profile_service.py)
# settings 默认:top_k=3 · ttl=90d · half_life=30d
score = confidence × decay × (1 + log(mention_count))
# 超 TTL 的偏好不进 prompt;取得分 Top-K 条
白话

客户说过很多偏好类型,但 prompt 里只带最近、反复提到的前几条,避免画像越积越长带偏 LLM。

很久没提过的偏好(超过 90 天)不再注入,但 MySQL 里仍保留,下次提到会刷新。

改 K 或 TTL → 动环境配置(settings.py 的 profile_preference_*),别在 prompt 里硬编码。

客户口述「我是激进型 R5」,但 Core 风评是 R3,持仓查询应信谁?