Explorar el Código

Remove stale demand analysis artifacts

SamLee hace 3 semanas
padre
commit
65e76b6a19

+ 0 - 531
analysis/cfa_demand_content_v2_contract.md

@@ -1,531 +0,0 @@
-# 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 连续递增
-```
-

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
analysis/demand_pool_old130_sample50_vs_new30_20260623.html


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio