|
|
@@ -0,0 +1,531 @@
|
|
|
+# DemandAgent V2 给 CFA 的 demand_content 输出契约
|
|
|
+
|
|
|
+本文档描述当前 `DemandAgentNew` 已提交版本的输出逻辑,面向下游 CFA / ContentFindAgent 使用。
|
|
|
+
|
|
|
+当前代码版本:`86ec3c6 Implement V2 evidence-backed demand output`
|
|
|
+
|
|
|
+## 1. 当前到底是什么情况
|
|
|
+
|
|
|
+DemandAgent V2 的目标不是只生成一个关键词,而是生成可被下游内容发现使用的“需求单”。每条需求单必须同时满足两件事:
|
|
|
+
|
|
|
+1. LLM 判断它像一个真实用户需求。
|
|
|
+2. 代码能从 PG Pattern V2 里查到真实证据,并生成 `evidence_pack`。
|
|
|
+
|
|
|
+当前生产形态是:
|
|
|
+
|
|
|
+```text
|
|
|
+Hive 供需缺口
|
|
|
+ -> 二级品类 merge_leve2 + 需要生成的 count
|
|
|
+ -> PG Pattern V2 最新成功 execution
|
|
|
+ -> 高权重元素 / 高权重分类 / 共现 / 频繁项集工具
|
|
|
+ -> LLM 生成候选 DemandItem
|
|
|
+ -> 代码用 PG DB 强校验 evidence_refs.sources
|
|
|
+ -> 补 evidence_pack / seed_terms / query_seed_points / element_bindings
|
|
|
+ -> 只写 MySQL demand_content
|
|
|
+```
|
|
|
+
|
|
|
+下游 CFA 只需要消费 MySQL 表:
|
|
|
+
|
|
|
+```text
|
|
|
+库:content-deconstruction-supply
|
|
|
+表:demand_content
|
|
|
+```
|
|
|
+
|
|
|
+本版本只写 `demand_content`。不写 `demand_task`,不写 Hive 输出表,不写 PG Pattern 表,不再使用旧 MySQL `topic_pattern_*` 作为事实源。
|
|
|
+
|
|
|
+## 2. LLM 负责什么,代码负责什么
|
|
|
+
|
|
|
+LLM 负责“判断什么是真需求”。它会看四类线索:
|
|
|
+
|
|
|
+- 高权重元素:`get_weight_score_topn(level="元素", dimension=...)`
|
|
|
+- 高权重分类:`get_weight_score_topn(level="分类", dimension=...)`
|
|
|
+- 共现关系:`get_category_co_occurrences` / `get_element_co_occurrences`
|
|
|
+- 频繁项集:`get_frequent_itemsets` / `get_itemset_detail`
|
|
|
+
|
|
|
+LLM 最终只写候选 DemandItem:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "element_names": ["励志情感歌曲", "歌词唱词"],
|
|
|
+ "reason": "为什么这个需求成立",
|
|
|
+ "desc": "用户希望看到什么内容",
|
|
|
+ "type": "元素/分类/关系/pattern",
|
|
|
+ "evidence_refs": {
|
|
|
+ "sources": [
|
|
|
+ {
|
|
|
+ "source_kind": "high_weight_element",
|
|
|
+ "source_tool": "get_weight_score_topn",
|
|
|
+ "element_names": ["励志情感歌曲"],
|
|
|
+ "element_type": "实质"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+LLM 不允许写最终真实性字段。以下字段全部由代码生成:
|
|
|
+
|
|
|
+- `source_certainty`
|
|
|
+- `validation_status`
|
|
|
+- `seed_terms`
|
|
|
+- `query_seed_points`
|
|
|
+- `category_bindings`
|
|
|
+- `element_bindings`
|
|
|
+- `matched_post_ids`
|
|
|
+
|
|
|
+代码负责把 `evidence_refs.sources[]` 变成真实的 `evidence_pack`。如果任意 source 查不到真实 PG 证据,该 source 不通过;如果整条 DemandItem 没有任何 source 通过,则这条需求不进入 `demand_content`。
|
|
|
+
|
|
|
+## 3. demand_content 顶层字段
|
|
|
+
|
|
|
+`demand_content` 表保留老需求池主字段,新增信息全部放在 `ext_data.evidence_pack`。
|
|
|
+
|
|
|
+| 字段 | 来源 / 计算方式 | 给 CFA 的用途 |
|
|
|
+|---|---|---|
|
|
|
+| `id` | MySQL 自增 ID。插入后回填到 `ext_data.evidence_pack.demand_content_id`。 | CFA 领取需求的主键。 |
|
|
|
+| `merge_leve2` | 当前 Hive gap 的二级品类,或手工入口传入的二级品类。 | CFA 按品类理解需求范围。 |
|
|
|
+| `name` | 由 LLM 输出的 `element_names` 用英文逗号拼接。 | 需求展示名,也可作为轻量召回词。 |
|
|
|
+| `reason` | LLM 输出的 `reason`。 | 解释为什么生成这条需求。 |
|
|
|
+| `suggestion` | LLM 输出的 `desc`。 | 给 CFA / 人看的需求描述。 |
|
|
|
+| `score` | 按 `name` 拆词后,从 PG 权重文件取分并求平均。没有分时为 `0.0`。 | 可作为排序参考,不是证据字段。 |
|
|
|
+| `dt` | DemandAgent 写入当天日期,格式 `yyyyMMdd`。 | 下游按天过滤。 |
|
|
|
+| `ext_data` | JSON,对下游最重要。 | CFA 读取 evidence、搜索点位、溯源上下文。 |
|
|
|
+
|
|
|
+## 4. ext_data 顶层结构
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "reason": "...",
|
|
|
+ "desc": "...",
|
|
|
+ "type": "元素/分类/关系/pattern",
|
|
|
+ "video_ids": ["post_id1", "post_id2"],
|
|
|
+ "trace_id": "...",
|
|
|
+ "demand_task_id": null,
|
|
|
+ "run_label": "v2_gap_xxx",
|
|
|
+ "evidence_pack": {}
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+| 字段 | 来源 / 计算方式 | 给 CFA 的用途 |
|
|
|
+|---|---|---|
|
|
|
+| `reason` | LLM 的 `reason`。 | 解释需求来源。 |
|
|
|
+| `desc` | LLM 的 `desc`。 | 需求描述。 |
|
|
|
+| `type` | LLM 的 `type`;如果是分类,代码会尝试追加分类层级,如 `分类L4`。 | 需求类型提示。 |
|
|
|
+| `video_ids` | 按 `name` 在 PG 元素/分类里反查到的 post_id 列表。 | 旧兼容字段;CFA V2 应优先看 `evidence_pack.video_ids`。 |
|
|
|
+| `trace_id` | Agent runner trace。 | 排查 LLM / 工具调用过程。 |
|
|
|
+| `demand_task_id` | 本单表写入模式通常为 `null`。 | 兼容旧字段。 |
|
|
|
+| `run_label` | 本次运行标签。 | 批次验收和回查。 |
|
|
|
+| `evidence_pack` | DB 强校验后的证据包。 | CFA 最核心输入。 |
|
|
|
+
|
|
|
+## 5. evidence_pack 总体结构
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "pattern_source_system": "pg_pattern_v2",
|
|
|
+ "pattern_execution_id": 581,
|
|
|
+ "mining_config_id": 2081,
|
|
|
+ "source_kind": "high_weight_element",
|
|
|
+ "case_id_type": "post_id",
|
|
|
+ "source_post_id": "20225425",
|
|
|
+ "evidence_sources": [],
|
|
|
+ "category_bindings": [],
|
|
|
+ "element_bindings": [],
|
|
|
+ "itemset_ids": [],
|
|
|
+ "itemset_items": [],
|
|
|
+ "support": 0.12,
|
|
|
+ "absolute_support": 47,
|
|
|
+ "filtered_absolute_support": 47,
|
|
|
+ "scoped_post_count": 47,
|
|
|
+ "matched_post_ids": ["20225425"],
|
|
|
+ "video_ids": ["20225425"],
|
|
|
+ "case_ids": ["20225425"],
|
|
|
+ "decode_case_ids": [],
|
|
|
+ "seed_terms": ["励志情感歌曲", "歌词唱词"],
|
|
|
+ "query_seed_points": [],
|
|
|
+ "demand_scope": {},
|
|
|
+ "trace_id": "...",
|
|
|
+ "demand_task_id": null,
|
|
|
+ "demand_content_id": 33,
|
|
|
+ "source_certainty": "db_validated",
|
|
|
+ "validation_status": "passed"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 固定真实性字段
|
|
|
+
|
|
|
+| 字段 | 计算方式 | 给 CFA 的用途 |
|
|
|
+|---|---|---|
|
|
|
+| `pattern_source_system` | 固定为 `pg_pattern_v2`。 | 明确本证据来自 PG Pattern V2,不再是旧 MySQL Pattern。 |
|
|
|
+| `case_id_type` | 固定为 `post_id`。 | 告诉 CFA `matched_post_ids/video_ids/case_ids` 都按 post_id 理解。 |
|
|
|
+| `source_certainty` | 固定为 `db_validated`,只有 DB 校验通过才写入。 | CFA 可把它当成可信证据。 |
|
|
|
+| `validation_status` | 固定为 `passed`,失败项不会入库。 | CFA 只消费 passed 需求。 |
|
|
|
+
|
|
|
+### scope 和来源字段
|
|
|
+
|
|
|
+| 字段 | 计算方式 | 给 CFA 的用途 |
|
|
|
+|---|---|---|
|
|
|
+| `pattern_execution_id` | PG `pattern_mining_execution.id`。 | 回溯到具体 PG Pattern V2 执行批次。 |
|
|
|
+| `mining_config_id` | 如果 evidence source 包含 itemset,则来自 PG `pattern_itemset.mining_config_id`;非 itemset source 可为空。 | 追 itemset 的 mining config。 |
|
|
|
+| `source_kind` | 如果只有一种 source,取该 source;多种 source 时为 `multi_source`。允许值见下文。 | CFA 判断这条需求主要由什么证据支撑。 |
|
|
|
+| `source_post_id` | 从 DB 校验后的 `matched_post_ids` 中选择。LLM 可建议,但必须在支撑帖内。 | 代表帖;可用于样例查看。 |
|
|
|
+| `demand_scope` | 记录本需求的业务范围。Hive 入口为 `odps_gap`,手工入口为 `manual_cli`。 | CFA 可知道这是哪个缺口品类、哪个平台、哪个 execution。 |
|
|
|
+
|
|
|
+`demand_scope` 示例:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "scope_source": "odps_gap",
|
|
|
+ "merge_leve2": "历史名人",
|
|
|
+ "platform": "piaoquan",
|
|
|
+ "gap_dt": "20260622",
|
|
|
+ "requested_count": 10,
|
|
|
+ "lack_count": 123,
|
|
|
+ "pattern_execution_id": 581
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 6. evidence_sources:每条需求的证据来源清单
|
|
|
+
|
|
|
+LLM 在候选阶段声明 `evidence_refs.sources[]`,代码校验通过后写成 `evidence_pack.evidence_sources[]`。
|
|
|
+
|
|
|
+支持 5 类:
|
|
|
+
|
|
|
+- `high_weight_element`
|
|
|
+- `high_weight_category`
|
|
|
+- `element_co_occurrence`
|
|
|
+- `category_co_occurrence`
|
|
|
+- `pattern_itemset`
|
|
|
+
|
|
|
+如果一条需求同时由多个证据支撑,`source_kind` 会是 `multi_source`,每个来源会单独出现在 `evidence_sources[]` 中。
|
|
|
+
|
|
|
+每个 source 的结构:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "source_kind": "pattern_itemset",
|
|
|
+ "source_tool": "get_itemset_detail",
|
|
|
+ "itemset_ids": [1607313],
|
|
|
+ "mining_config_ids": [2081],
|
|
|
+ "source_terms": ["励志情感歌曲", "歌词唱词"],
|
|
|
+ "source_post_id": "20225425",
|
|
|
+ "matched_post_count": 47,
|
|
|
+ "matched_post_ids": ["20225425"],
|
|
|
+ "support": 0.12,
|
|
|
+ "absolute_support": 47
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+计算逻辑:
|
|
|
+
|
|
|
+- `pattern_itemset`:查 PG `pattern_itemset`、`pattern_itemset_post`、`pattern_itemset_item`、`pattern_mining_category`、`pattern_mining_element`。
|
|
|
+- `high_weight_element` / `element_co_occurrence`:用元素名查 PG `pattern_mining_element`,按当前 `merge_leve2/platform` 过滤支撑帖;多个元素取共同支撑帖。
|
|
|
+- `high_weight_category` / `category_co_occurrence`:用 `category_id/category_name/category_path` 查 PG 分类下的 `pattern_mining_element`,按当前 `merge_leve2/platform` 过滤支撑帖;多个分类取共同支撑帖。
|
|
|
+
|
|
|
+CFA 用途:
|
|
|
+
|
|
|
+- 判断需求是由高权重元素、分类、共现,还是 itemset 支撑。
|
|
|
+- 回溯每个来源覆盖了哪些 post。
|
|
|
+- 如果后续 CFA 要解释“为什么搜这个方向”,可以展示 `source_terms`。
|
|
|
+
|
|
|
+## 7. matched_post_ids / video_ids / case_ids
|
|
|
+
|
|
|
+| 字段 | 计算方式 | 给 CFA 的用途 |
|
|
|
+|---|---|---|
|
|
|
+| `matched_post_ids` | 所有通过 DB 校验的 evidence source 的支撑帖去重合并。 | 这条需求的真实支撑帖集合。 |
|
|
|
+| `video_ids` | 当前等于 `matched_post_ids`。 | 兼容旧命名。 |
|
|
|
+| `case_ids` | 当前等于 `matched_post_ids`。 | 兼容旧命名;语义仍是 post_id。 |
|
|
|
+| `decode_case_ids` | PG-only 链路下通常为空数组。 | 兼容字段,不作为主链路依据。 |
|
|
|
+
|
|
|
+强约束:
|
|
|
+
|
|
|
+- `source_post_id` 必须在 `matched_post_ids` 内。
|
|
|
+- `video_ids == matched_post_ids`。
|
|
|
+- `case_ids == matched_post_ids`。
|
|
|
+
|
|
|
+CFA 应优先使用 `matched_post_ids`,不要再把 `case_ids` 理解成旧 decode case。
|
|
|
+
|
|
|
+## 8. category_bindings
|
|
|
+
|
|
|
+`category_bindings` 是需求绑定到分类树节点的结构化证据。
|
|
|
+
|
|
|
+如果来源是 `pattern_itemset`,它来自:
|
|
|
+
|
|
|
+```text
|
|
|
+PG pattern_itemset_item
|
|
|
+ -> pattern_mining_category
|
|
|
+```
|
|
|
+
|
|
|
+如果来源是高权重元素 / 高权重分类 / 共现,它来自:
|
|
|
+
|
|
|
+```text
|
|
|
+PG pattern_mining_element
|
|
|
+ -> pattern_mining_category
|
|
|
+```
|
|
|
+
|
|
|
+单条结构:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "source_kind": "high_weight_element",
|
|
|
+ "itemset_id": 1607313,
|
|
|
+ "itemset_item_id": 6055230,
|
|
|
+ "category_id": 76533,
|
|
|
+ "category_name": "励志情感歌曲",
|
|
|
+ "category_path": "/表象/声音/音乐/歌曲/励志情感歌曲",
|
|
|
+ "category_full_path": "/表象/声音/音乐/歌曲/励志情感歌曲",
|
|
|
+ "category_source_type": "实质",
|
|
|
+ "category_level": 5,
|
|
|
+ "category_nature": "topic",
|
|
|
+ "point_type": "灵感点",
|
|
|
+ "dimension": "实质",
|
|
|
+ "element_name": "励志情感歌曲"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+CFA 用途:
|
|
|
+
|
|
|
+- 从需求回溯到 PG 分类树节点。
|
|
|
+- 判断需求属于实质 / 形式 / 意图下的哪些分类。
|
|
|
+- 做解释、聚合、去重时可使用 `category_id/category_path`。
|
|
|
+
|
|
|
+## 9. element_bindings
|
|
|
+
|
|
|
+`element_bindings` 是“这条需求为什么真实”的元素证据闭合结果。它不是 CFA 的主搜索词池;主搜索词池看 `query_seed_points`。
|
|
|
+
|
|
|
+如果来源是 `pattern_itemset`,代码会检查 itemset item 是否能在支撑帖的 PG `pattern_mining_element` 中找到对应元素。
|
|
|
+
|
|
|
+如果来源是高权重元素 / 高权重分类 / 共现,代码会把查到的 PG 元素行按 `source_kind/category_id/point_type/element_type/name` 分组。
|
|
|
+
|
|
|
+单条结构:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "source_kind": "high_weight_element",
|
|
|
+ "itemset_id": 1607313,
|
|
|
+ "itemset_item_id": 6055230,
|
|
|
+ "category_id": 76533,
|
|
|
+ "point_type": "灵感点",
|
|
|
+ "dimension": "实质",
|
|
|
+ "element_name": "励志情感歌曲",
|
|
|
+ "matched_element_count": 369,
|
|
|
+ "matched_post_count": 47,
|
|
|
+ "matched_post_ids": ["20225425"],
|
|
|
+ "sample_elements": [
|
|
|
+ {
|
|
|
+ "id": 3854157,
|
|
|
+ "name": "情谊歌曲",
|
|
|
+ "post_id": "20225425",
|
|
|
+ "point_text": "老同学情谊歌曲",
|
|
|
+ "point_type": "灵感点",
|
|
|
+ "category_id": 76533,
|
|
|
+ "element_type": "实质",
|
|
|
+ "source_table": "post_decode_topic_point_element",
|
|
|
+ "category_path": "/表象/声音/音乐/歌曲/励志情感歌曲",
|
|
|
+ "topic_point_id": 6309,
|
|
|
+ "source_element_id": 11536
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+CFA 用途:
|
|
|
+
|
|
|
+- 用于证明需求和 PG 元素证据能闭合。
|
|
|
+- 可展示少量样本点位。
|
|
|
+- 不建议直接把 `sample_elements` 当主搜索词池,因为它是证据样本,不覆盖全部支撑帖。
|
|
|
+
|
|
|
+## 10. query_seed_points:CFA 首轮搜索点位池
|
|
|
+
|
|
|
+`query_seed_points` 是给 CFA 最重要的新增字段之一。它是“从该需求的所有真实支撑帖里,挑出最值得拿去搜对标内容的点位”。
|
|
|
+
|
|
|
+取数范围:
|
|
|
+
|
|
|
+```text
|
|
|
+evidence_pack.matched_post_ids
|
|
|
+ -> PG pattern_mining_element
|
|
|
+ -> source_table = 'post_decode_topic_point_element'
|
|
|
+ -> point_type in ('灵感点', '目的点')
|
|
|
+```
|
|
|
+
|
|
|
+过滤规则:
|
|
|
+
|
|
|
+- 只保留当前需求支撑帖内的点位。
|
|
|
+- 只保留 `灵感点` 和 `目的点`。
|
|
|
+- 丢弃 `关键点`,因为关键点多是制作手法,不适合首轮搜索。
|
|
|
+- 如果 `category_bindings` 有分类节点,会限制在这些 `category_id` 下。
|
|
|
+- `point_text` 不能为空。
|
|
|
+
|
|
|
+去重和排序:
|
|
|
+
|
|
|
+```text
|
|
|
+按 (point_text, point_type) 分组
|
|
|
+coverage_post_count = 这个点位出现在多少篇不同支撑帖里
|
|
|
+排序 = coverage_post_count DESC, point_text ASC, point_type ASC
|
|
|
+默认 Top K = 30
|
|
|
+rank = 1..30
|
|
|
+```
|
|
|
+
|
|
|
+单条结构:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 3854157,
|
|
|
+ "post_id": "20225425",
|
|
|
+ "source_table": "post_decode_topic_point_element",
|
|
|
+ "source_element_id": 11536,
|
|
|
+ "point_type": "目的点",
|
|
|
+ "point_text": "分享励志歌曲",
|
|
|
+ "element_type": "实质",
|
|
|
+ "name": "励志歌曲",
|
|
|
+ "category_id": 76533,
|
|
|
+ "category_path": "/表象/声音/音乐/歌曲/励志情感歌曲",
|
|
|
+ "topic_point_id": 6309,
|
|
|
+ "coverage_post_count": 12,
|
|
|
+ "rank": 1,
|
|
|
+ "matched_category_ids": [76533],
|
|
|
+ "matched_itemset_item_ids": [6055230]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+CFA 用途:
|
|
|
+
|
|
|
+- 这是 CFA 首轮搜索词 / 搜索点位的主输入。
|
|
|
+- CFA 可以按 `rank` 从高到低使用。
|
|
|
+- CFA 可以按 `point_type` 做配额,比如目的点和灵感点各取一部分。
|
|
|
+- CFA 清洗词时不要覆盖 `point_text`,可以另存自己的 cleaned query。
|
|
|
+
|
|
|
+## 11. seed_terms
|
|
|
+
|
|
|
+`seed_terms` 是这条需求的短词骨架,用于轻量召回或展示。它不是 LLM 自由生成的。
|
|
|
+
|
|
|
+来源优先级:
|
|
|
+
|
|
|
+1. 已通过 DB 校验的 source 自带 `seed_terms` 或 `source_terms`。
|
|
|
+2. 如果是 itemset source,则从 PG `pattern_itemset_item` 派生。
|
|
|
+3. 如果没有 itemset,则从 `element_bindings` 和 `category_bindings` 派生。
|
|
|
+
|
|
|
+派生规则:
|
|
|
+
|
|
|
+- 优先元素名:`element_name`
|
|
|
+- 再取分类名:`category_name`
|
|
|
+- 再取分类路径叶子节点
|
|
|
+- 去重保序
|
|
|
+- 过滤过泛词:`其他`、`其它`、`未知`、`内容`、`视频`
|
|
|
+- 默认不限制数量
|
|
|
+- 只有显式设置 `DEMAND_SEED_TERMS_MAX` 时才截断
|
|
|
+
|
|
|
+CFA 用途:
|
|
|
+
|
|
|
+- 可作为需求概括词。
|
|
|
+- 可作为兜底搜索词。
|
|
|
+- 但若要搜具体内容,优先使用 `query_seed_points`。
|
|
|
+
|
|
|
+## 12. itemset_ids / itemset_items
|
|
|
+
|
|
|
+这两个字段只在 evidence source 包含 `pattern_itemset` 时有值。高权重元素、分类、共现来源可以没有 itemset。
|
|
|
+
|
|
|
+`itemset_ids`:
|
|
|
+
|
|
|
+- 来自 PG `pattern_itemset.id`
|
|
|
+- 只接受 `scope='topic'`
|
|
|
+- 必须属于当前 `pattern_execution_id`
|
|
|
+
|
|
|
+`itemset_items` 单条结构:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "itemset_id": 1607313,
|
|
|
+ "category_id": 76533,
|
|
|
+ "category_path": "/表象/声音/音乐/歌曲/励志情感歌曲",
|
|
|
+ "point_type": "灵感点",
|
|
|
+ "dimension": "实质",
|
|
|
+ "element_name": "励志情感歌曲"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+CFA 用途:
|
|
|
+
|
|
|
+- 如果需求由 pattern itemset 支撑,可以 exact 回溯到 pattern item。
|
|
|
+- 如果需求来自高权重元素 / 分类 / 共现,则应看 `evidence_sources/category_bindings/element_bindings`,不要要求一定有 itemset。
|
|
|
+
|
|
|
+## 13. support / absolute_support / scoped_post_count
|
|
|
+
|
|
|
+| 字段 | 计算方式 | 给 CFA 的用途 |
|
|
|
+|---|---|---|
|
|
|
+| `support` | itemset source 用 PG itemset support;非 itemset source 用 `matched_post_ids / execution.post_count` 估算。 | 证据强度参考。 |
|
|
|
+| `absolute_support` | itemset source 用 PG itemset absolute_support;非 itemset source 用支撑帖数量。多个 source 取能覆盖的最大值。 | 支撑规模参考。 |
|
|
|
+| `filtered_absolute_support` | 当前业务 scope 下的支撑帖数量。 | 表示当前品类和平台内有多少支撑帖。 |
|
|
|
+| `scoped_post_count` | 等于 `len(matched_post_ids)`。 | 下游校验字段。 |
|
|
|
+
|
|
|
+强约束:
|
|
|
+
|
|
|
+- `filtered_absolute_support == scoped_post_count`
|
|
|
+- `len(matched_post_ids) == scoped_post_count`
|
|
|
+- `scoped_post_count <= absolute_support`
|
|
|
+
|
|
|
+## 14. CFA 推荐消费方式
|
|
|
+
|
|
|
+CFA 消费一条需求时,建议按这个顺序读取:
|
|
|
+
|
|
|
+1. 读顶层:
|
|
|
+ - `id`
|
|
|
+ - `merge_leve2`
|
|
|
+ - `name`
|
|
|
+ - `suggestion`
|
|
|
+ - `score`
|
|
|
+ - `dt`
|
|
|
+
|
|
|
+2. 进入 `ext_data.evidence_pack`,先验真:
|
|
|
+ - `pattern_source_system == "pg_pattern_v2"`
|
|
|
+ - `validation_status == "passed"`
|
|
|
+ - `source_certainty == "db_validated"`
|
|
|
+ - `source_post_id in matched_post_ids`
|
|
|
+
|
|
|
+3. 做搜索召回:
|
|
|
+ - 首选 `query_seed_points`
|
|
|
+ - 按 `rank` 排序
|
|
|
+ - 只使用 `point_type in {"灵感点", "目的点"}`
|
|
|
+ - 可按 `coverage_post_count` 再做阈值或配额
|
|
|
+
|
|
|
+4. 做解释和溯源:
|
|
|
+ - 看 `evidence_sources`
|
|
|
+ - 看 `category_bindings`
|
|
|
+ - 看 `element_bindings`
|
|
|
+ - 看 `matched_post_ids`
|
|
|
+
|
|
|
+5. 做兜底:
|
|
|
+ - 如果 `query_seed_points` 为空,可以用 `seed_terms`
|
|
|
+ - 如果要展示样本,可以用 `element_bindings.sample_elements`
|
|
|
+
|
|
|
+## 15. 边界说明
|
|
|
+
|
|
|
+1. `element_bindings.sample_elements` 不是主搜索池,只是证据样本。
|
|
|
+2. `query_seed_points` 才是 CFA 首轮搜索点位池。
|
|
|
+3. `case_ids` 当前语义等同 post_id,不是旧 decode case。
|
|
|
+4. 不是每条需求都必须有 itemset。没有 itemset 时,需求仍然可以由高权重元素、高权重分类或共现证据支撑。
|
|
|
+5. 失败的 DemandItem 不进入 `demand_content`,只进入运行侧 rejected 统计。
|
|
|
+6. 当前事实源只有 PG Pattern V2;旧 MySQL `topic_pattern_*` 不再作为证据来源。
|
|
|
+
|
|
|
+## 16. 最小验收 SQL / JSON 规则
|
|
|
+
|
|
|
+CFA 或测试侧可以用这些规则判断一条需求是否符合 V2:
|
|
|
+
|
|
|
+```text
|
|
|
+ext_data.evidence_pack.pattern_source_system == "pg_pattern_v2"
|
|
|
+ext_data.evidence_pack.validation_status == "passed"
|
|
|
+ext_data.evidence_pack.source_certainty == "db_validated"
|
|
|
+ext_data.evidence_pack.source_post_id in ext_data.evidence_pack.matched_post_ids
|
|
|
+ext_data.evidence_pack.query_seed_points is array
|
|
|
+ext_data.evidence_pack.evidence_sources is non-empty array
|
|
|
+ext_data.evidence_pack.category_bindings is non-empty array
|
|
|
+ext_data.evidence_pack.element_bindings is non-empty array
|
|
|
+ext_data.evidence_pack.seed_terms is non-empty array
|
|
|
+```
|
|
|
+
|
|
|
+如果 `query_seed_points` 非空,则每条必须满足:
|
|
|
+
|
|
|
+```text
|
|
|
+point_type in {"灵感点", "目的点"}
|
|
|
+coverage_post_count > 0
|
|
|
+rank 从 1 连续递增
|
|
|
+```
|
|
|
+
|