demand_output_improve_plan.md 32 KB

DemandAgent 输出调整 MVP 技术方案

Summary

这次不是“DemandAgent 对接 ContentFindingAgent”,而是 DemandAgent 自身输出结构升级:在不改真实 DB schema 的前提下,核心只调整普通需求池 demand_content.ext_data,增加结构化 evidence_pack。V1 同时保留两种受控输出模式:local_json 用于本地回归,只写本地 JSON;mysql_demand_content 用于云端测试服,只写 MySQL demand_content 单表。原本会写入 dwd_multi_demand_pool_difeature_point_datademand_task 的数据,V1 阶段不真实写入这些表,也不改它们的业务字段结构。

本次 DemandAgent 侧补齐的是上游 exact evidence 基础:它能让需求单携带真实 DB 校验过的 Pattern/itemset/category 证据,但最终链路还要求 ContentFindAgent 读取、继承并沉淀结构化 source_evidence,否则最终结果仍无法从 post_id/aweme_id exact 回到 Pattern 和分类树节点。

PG Pattern V2 替换更新:正式证据源已经切到 PG open_aigc.public 主事实表,evidence_pack.pattern_source_system 固定为 pg_pattern_v2。MVP 只使用 pattern_itemset.scope='topic' 的分类 Pattern;topic_element、script、paragraph、group scope 不进入下游 exact 输出,因为它们不能保证每条证据都有 category_id/category_path 可回到分类树节点。

改动范围判断:不改 agent 框架层,只改 examples/demand 这个业务领域实现。agent/ 框架里的 runner、tool registry、trace store、LLM 调用链路都保持不动。本次即使涉及 @tool 参数、trace_id 透传,也只是修改 Demand 业务工具和业务输出,不修改通用 Agent 框架机制。

模块改动归类

模块 是否改 原因
agent/ 框架 不改 不改 runner、tool registry、trace store、LLM 调用链路;本次只消费现有框架能力,把 Demand 业务输出补充为本地 JSON 和 evidence_pack。
examples/demand/demand_build_agent_tools.py DemandItem 需要新增可选证据引用字段,保留原字段兼容旧能力。
examples/demand/demand.md Prompt 要求 LLM 在创建需求时带上输出证据引用。
examples/demand/run.py 当前真实写库入口集中在这里,需要加本地 JSON 输出模式。
examples/demand/data_query_tools.py 不改 dwd_multi_demand_pool_di / feature_point_data 业务字段;把现有 Hive 输出拆成可复用的纯映射函数,local 模式只调用映射不写 Hive。
examples/demand/db_manager.py 保留旧函数名作为 PG facade,底层改读 PG Pattern V2,只读补齐 category/element/itemset/post 证据。
新增 examples/demand/pg_pattern_repository.py 新增 PG Pattern V2 只读 repository,统一读取 pattern_mining_*pattern_itemset*
新增 examples/demand/pattern_builds/pg_pattern_service.py 新增 保持旧工具返回结构,底层替换为 PG scope='topic' Pattern 查询。
新增 examples/demand/pg_weight_score_builder.py 新增 从 PG topic 元素/分类聚合本地权重 JSON,替代旧 prepare 产物。
新增 examples/demand/evidence_pack_builder.py 新增 专门构造并强校验 ext_data.evidence_pack;校验失败的 DemandItem 进入 reject,不进入 demand_content
新增 examples/demand/local_output_sink.py 新增 统一本地 JSON sink,稳定输出 7 个本地文件;不进入通用 Agent 框架。
新增 examples/demand/run_existing_execution_local.py 新增 MVP 测试入口:用已有 execution_id 只读 DB,禁止跑写库 prepare。

输出表改动收敛

虽然 DemandAgent 当前有三类业务结果输出,但本次面向下游证据链的结构性改动只落在 demand_content

输出 当前业务角色 本次是否改业务字段 MVP 处理方式
demand_content 普通需求池;ContentFindAgent 当前直接领取的需求卡片 ext_data 中新增 evidence_pack,保留原 reason/desc/type/video_ids 兼容旧消费。
dwd_multi_demand_pool_di 数仓侧需求池同步 / 策略表现参考 不改 不新增 evidence 字段,不作为下游主证据链载体;MVP 只把原两类策略行镜像到本地 JSON。
feature_point_data 全局树 特征点输出 / 特征表现参考 不改 和 ContentFindAgent 当前主链路无关;MVP 只保留原字段并镜像到本地 JSON。

demand_task 是任务台账,不算业务结果输出表。本地模式只模拟它的创建和完成状态,方便串起 demand_task_id,不改变业务输出结构。

V1 阶段开发清单

本清单用于承接“待决策事项”与当前开发执行状态。当前 checkout 中未找到独立的 待决策事项.md 文件,因此本节只吸收已经在本方案、demandagent给下游的迭代需求.md、真实代码和已拍板沟通中能被证实的事项;未找到原文依据的内容统一放入“待补充”,不擅自替用户补决策。

1. 已拍板并进入 V1 的事项

事项 V1 处理方式 真实依据
Pattern 证据源 只使用 PG Pattern V2,pattern_source_system 唯一合法值为 pg_pattern_v2 pg_pattern_repository.py 只读 PG pattern_mining_* / pattern_itemset*evidence_pack_builder.py 固定 PATTERN_SOURCE_SYSTEM = "pg_pattern_v2"
Pattern scope V1 只输出 pattern_itemset.scope='topic' evidence_pack_builder.py 校验 PATTERN_ITEMSET_SCOPE = "topic"pg_pattern_repository.py 定义 TOPIC_SCOPE = "topic"
旧 MySQL Pattern 删除弃用,不作为任何新版 evidence 来源 demandagent给下游的迭代需求.md 已明确旧 topic_pattern_* 链路删除弃用;当前 PG repository 不读取旧 topic_pattern_*
下游主载体 demand_content.ext_data.evidence_pack 是给下游的主证据包 run.py 构造 ext_data.evidence_packmysql_demand_content_sink.py 入库前强校验该字段
LLM 与证据真实性边界 LLM 只产出候选 evidence_refs;最终 evidence_pack 必须由代码 DB 强校验补齐 run.py 读取候选 evidence_refs 后调用 build_evidence_pack()evidence_pack_builder.py 失败返回 reject
云端 V1 输出 开发/测试服可以真实写云端 MySQL 单表 demand_content,但只写这一张表 run_existing_execution_mysql.py 注释和入口约束;mysql_demand_content_sink.py 只执行 INSERT/UPDATE demand_content
本地 V1 输出 local 回归仍保留 local_json,产物写入 examples/demand/test_output_data/{run_id} run_existing_execution_local.pylocal_output_sink.py
Agent 框架边界 不改 agent/ 通用框架;只改 examples/demand 业务域 本方案“改动归属”已定义;代码改动集中在 examples/demand
下游消费口径 当前验收按本输出契约,不按尚未适配完成的 ContentFindAgent 旧 scheduler 代码验收 已拍板:下游代码未完成最新结构适配,本轮按 demand_output_improve_plan.md 验收

2. 需按默认值推进的事项

这些不是新决策,而是当前代码已经存在的默认值或运行约束;V1 执行时按代码默认推进,后续如产品要改,需要单独决策。

事项 默认值 / 默认行为 代码位置与含义
PG execution 入参 CLI 必须显式传已有 pattern_mining_execution.id;测试默认样本使用已验证的 581 run_existing_execution_mysql.py / run_existing_execution_local.py 都要求 --execution-id
execution 状态 只允许 status='success' run_existing_execution_mysql.py 启动前调用 query_execution_for_evidence() 校验
MySQL 写入模式 DEMAND_OUTPUT_MODE=mysql_demand_content 只能通过 examples.demand.run_existing_execution_mysql 入口设置 run.py_require_mysql_entrypoint()
本地 JSON 模式 DEMAND_OUTPUT_MODE=local_json 只能通过 examples.demand.run_existing_execution_local 入口设置 run.py_require_local_entrypoint()
ID 语义 case_id_type 固定为 post_id evidence_pack_builder.py 构造 case_id_type="post_id"
Pattern case 列表 video_idscase_ids 默认等于 DB 校验后的 matched_post_ids evidence_pack_builder.py 构造两者;mysql_demand_content_sink.py 入库前校验相等
decode 兼容字段 decode_case_ids 在 PG-only V1 中默认可为空数组,不参与 Pattern exact 闭合 evidence_pack_builder.py 单独查询并写入;未命中不影响 Pattern itemset 通过
证据状态 accepted demand 固定为 source_certainty=db_validatedvalidation_status=passed evidence_pack_builder.py 构造固定状态;MySQL sink 入库前复验
MySQL 单表去重 同一 run_label + name + evidence_pack.source_post_id 已存在时跳过 mysql_demand_content_sink.py_row_exists_for_run()
MySQL 入库回填 插入后用真实自增 id 回填 ext_data.evidence_pack.demand_content_id mysql_demand_content_sink.py 插入后 update 同一行
单表模式任务 ID 不建 demand_task 时,demand_task_id 不能伪装成真实 DB ID;可为 null 或运行侧模拟值,语义必须在 run manifest / 日志中说明 当前 run_existing_execution_mysql.py 调用 main(..., task_id=None)
MySQL entrypoint 工具白名单 只开放 get_frequent_itemsets/get_itemset_detail/create_demand_item/create_demand_items run.py_enabled_tools_for_run()
工具返回压缩 DEMAND_ITEMSET_DETAIL_MAX_IDS=12DEMAND_ITEMSET_DETAIL_MAX_POST_IDS=20 run_existing_execution_mysql.py 设置默认环境变量
LLM 模型解析 优先读 DEMAND_LLM_MODEL,再读 ARK_MODEL / OpenRouter 相关变量 run.pyresolve_model()
PG 连接配置 优先读 DEMAND_PATTERN_PG_DSN,再读 PGVECTOR_DSN pg_pattern_repository.py_resolve_dsn()
MySQL 连接配置 优先读 DEMAND_CONTENT_MYSQL_DSN,否则读 DEMAND_CONTENT_MYSQL_*,再 fallback 到 CONTENT_SUPPLY_DB_* mysql_demand_content_sink.py_resolve_mysql_config()

3. 待补充但不能阻塞 V1 单表验证的事项

这些事项尚未形成可执行决策,或当前真实代码/文档还没有完全闭合。V1 可以继续推进 100 条测试,但必须在交付说明中标明边界。

待补充事项 当前缺口 V1 临时处理
原始 待决策事项.md 当前仓库及 /Users/samlee/Documents/works 三层内未找到该文件,无法逐条引用原文 本节先按已拍板沟通和现有两份文档吸收;若用户提供文件,需要再做一次逐条 diff
ContentFindAgent 最新适配 下游新版代码尚未完成,不按旧 scheduler 验收 只按本契约校验 demand_content.ext_data.evidence_pack;CFA 后续需继承并沉淀 source_evidence
100 条正式批次完成报告 代码和云端链路已能写 MySQL,但最终批次需要以云端 SQL 统计为准 run_label 前缀查询数量和逐条 evidence 校验,不用本地 JSON 数量替代
生产任务闭环 单表 demand_content 不能支撑旧调度、去重、结果回写 V1 只验收 FH/CFA 可读取需求结构;不验收旧 server.py 自动调度
独立 evidence 表 当前只写 ext_data.evidence_pack,未拆关系表 V1 不拆表;如 ext_data 变大或下游要 SQL join,再进入 V1.1
topic_element exact 方案 真实 PG 样本中存在分类路径缺失,不能保证 exact 回分类树 V1 不输出;后续必须先补齐分类树节点或定义降级语义
PG Pattern V2 页面主事实链接 当前 evidence 能回 PG 表,但未定义前端页面 URL 或跨系统跳转 ID V1 只保证表级 exact;页面级跳转另列需求

4. V1 明确不处理的事项

不处理事项 原因
不恢复旧 MySQL topic_pattern_* evidence 已删除弃用,任何最终证据来自旧 MySQL 都必须 rejected
不输出 topic_element、script、paragraph、group scope 不能保证每条证据都有 category_id/category_path 回到分类树节点
不改 PG Pattern V2 数据库 schema DemandAgent 是下游消费方,只读 PG 主事实
不改 agent/ runner / tool registry / trace store / LLM 框架 本次是 Demand 业务域输出协议升级
不写 demand_task、Hive/ODPS、旧 Pattern 中间表 V1 云端只写 MySQL demand_content 单表;本地模式只写 JSON
不保证旧 ContentFindAgent scheduler 自动闭环 旧 scheduler 还需要 demand_find_task 和结果表,已超出单表 V1 范围
不把 rejected DemandItem 下发给下游 rejected 只用于 DemandAgent 排查,不能作为可消费需求

5. V1 验收清单

验收项 必须满足
证据真实性 每条 accepted row 的 evidence_pack.source_certainty='db_validated'validation_status='passed'
PG-only evidence_pack.pattern_source_system='pg_pattern_v2',不得出现 mysql_topic_pattern 或旧 topic_pattern_* 来源
itemset 闭合 pattern_execution_id/mining_config_id/itemset_ids/itemset_items/support/absolute_support 均来自同一 PG execution 且 scope 为 topic
post 闭合 matched_post_ids 来自 pattern_itemset_postsource_post_id in matched_post_idsvideo_ids == case_ids == matched_post_ids
分类树闭合 itemset_items[]category_bindings[] 均有 category_id/category_path
元素证据闭合 element_bindings[] 非空,且来自 PG pattern_mining_element
写库范围 云端 V1 只能写 MySQL demand_content;不能写 demand_task、Hive、PG Pattern 或旧 MySQL Pattern
下游契约 给 FH/CFA 的主输入是 MySQL demand_content 行或其导出的 demand_content.json,不是 demand_itemsrejected_demand_items

改动归属:Agent 框架 vs examples/demand 业务域

1. 不涉及 Agent 通用框架的改动

本次 MVP 不修改 agent/ 通用框架目录。

不改范围包括:

  • agent/core/runner.py

    • 不改 AgentRunner 执行循环。
    • 不改 trace 创建、消息持久化、工具调用调度逻辑。
    • trace_id 只从现有 runner 结果中读取和透传,不改变框架生成 trace 的方式。
  • agent/tools / tool registry

    • 不改工具注册框架。
    • 不改 @tool 装饰器能力。
    • 不改工具 schema 生成机制。
    • 本次只是修改 examples/demand 下业务工具函数的参数和写出内容。
  • agent/trace

    • 不改 trace store。
    • 不改 .trace 文件结构。
    • 只把现有 trace_id 写入 DemandAgent 本地输出 JSON,作为业务输出字段。
  • LLM 调用框架

    • 不改模型选择、LLM client、OpenRouter 调用逻辑。
    • 不改 RunConfig 的通用字段含义。

结论:本次不是 Agent 框架能力升级,而是 DemandAgent 业务输出协议升级。

2. 仅涉及 examples/demand 业务域的改动

本次实际改动都落在 examples/demand,属于 DemandAgent 示例业务域,也就是当前 Demand 生成链路的业务实现层。

当前改动已经完成业务入口、DB 强校验和受控 sink 的 V1 闭环:demand_build_agent_tools.py 产出候选 evidence_refsevidence_pack_builder.py 用真实 DB 只读校验并补齐 evidence_packlocal_json 模式只把 passed rows 写入本地 demand_content.json,失败项写入 rejected_demand_items.jsonmysql_demand_content 模式只把 passed rows 写入测试服 MySQL demand_content 单表,失败项只记日志,不进入下游需求池。

具体包括:

  • examples/demand/demand_build_agent_tools.py

    • 增强 create_demand_item / create_demand_items
    • 新增可选 evidence_refs 字段。
    • 这是业务工具输出结构调整,不是 Agent 工具框架调整。
  • examples/demand/demand.md

    • 修改 DemandAgent prompt。
    • 要求模型在生成 DemandItem 时带上来源证据引用。
    • 这是业务 prompt 约束,不是框架 prompt 系统改造。
  • examples/demand/run.py

    • 调整结果写出路径。
    • 增加 local_json 本地回归模式和 mysql_demand_content 测试服单表写入模式。
    • 避免 V1 测试时真实写 demand_task / Hive / PG Pattern / 旧 MySQL Pattern。
    • 这是 DemandAgent 业务 orchestration 改动。
  • examples/demand/data_query_tools.py

    • 把 Hive 写入逻辑拆成“构造输出行”和“真实写入”两层。
    • 本地模式只调用纯映射生成 dwd_multi_demand_pool_di.json / feature_point_data.json 镜像。
    • 不向这两张表增加 evidence_pack,不改变它们的业务字段。
  • examples/demand/evidence_pack_builder.py

    • 新增 evidence_pack 构造逻辑。
    • 从 PG Pattern V2 真实 DB 只读补齐 itemset/category/element/post 证据。
    • 这是 DemandAgent 输出字段补齐逻辑。
  • examples/demand/local_output_sink.py

    • 新增本地 JSON sink。
    • run.py 统一模拟 demand_taskdemand_content、Hive 输出表。
    • 其中只有 demand_contentext_data.evidence_pack 是新增业务结构;Hive 输出表只是原样镜像。
    • 这是 MVP 测试输出设施,不进入通用框架。
  • examples/demand/run_existing_execution_local.py

    • 新增只读测试入口。
    • 只允许传已有 PG pattern_mining_execution.id
    • 禁止调用 run_mining,避免写 Pattern 中间表。
  • examples/demand/run_existing_execution_mysql.py

    • 新增云端测试服单表写入入口。
    • 只允许传已有 PG pattern_mining_execution.id
    • 强制 DEMAND_OUTPUT_MODE=mysql_demand_content,只写 MySQL demand_content
  • examples/demand/mysql_demand_content_sink.py

    • 新增测试服 MySQL 单表 sink。
    • 入库前强校验 ext_data.evidence_pack,插入后回填真实 demand_content_id
    • 不创建或写入 demand_task、Hive、PG Pattern、旧 MySQL Pattern。

Key Changes

  1. DemandItem 输出结构增强

create_demand_item/create_demand_items 增加可选 evidence_refs,原有 element_names/reason/desc/type 不变。

record = {
    "element_names": element_names,
    "reason": reason,
    "desc": desc,
    "type": type,
    "evidence_refs": evidence_refs or {},
}

推荐 evidence_refs 格式:

{
  "source_kind": "pattern_itemset",
  "source_tool": "get_itemset_detail",
  "itemset_ids": [123],
  "category_ids": [456, 789],
  "source_post_id": "55157577",
  "case_ids": {
    "pattern_itemset": ["55157577"]
  },
  "seed_terms": ["猫咪", "拟人化"],
  "notes": "source_post_id 必须来自 get_itemset_detail.post_ids / matched_post_ids"
}

case_ids 在候选阶段按 source_kind 分组,而不是一个裸数组。示例:{"pattern_itemset": ["post_id"], "direct_case": ["case_id"]}。若当前来源没有 Case seed,对应 source_kind 可以填空数组,但不能把其他来源的 Case 混入本来源。

  1. demand_content.ext_data 增加 evidence_pack

本地输出的 demand_content.json 保持真实表字段形态:

当前落地阶段已经接入 DB 强校验 builder:ext_data.evidence_refs 只作为 LLM 候选输入;只有校验通过后才会在 ext_data.evidence_pack 中写入 source_certainty=db_validatedvalidation_status=passed。校验失败的 DemandItem 不进入 demand_content.json

{
  "id": 1,
  "merge_leve2": "贪污腐败",
  "name": "权钱交易,利益输送",
  "reason": "...",
  "suggestion": "...",
  "score": 0.73,
  "ext_data": {
    "reason": "...",
    "desc": "...",
    "type": "pattern",
    "video_ids": ["..."],
    "evidence_pack": {
      "pattern_source_system": "pg_pattern_v2",
      "pattern_execution_id": 581,
      "mining_config_id": 2081,
      "source_kind": "pattern_itemset",
      "case_id_type": "post_id",
      "source_post_id": "02454b8dab4c13c9fa21042bdc92d122",
      "category_bindings": [
        {
          "itemset_id": 1607313,
          "itemset_item_id": 6051234,
          "category_id": 123456,
          "category_name": "示例分类",
          "category_path": "/形式/...",
          "category_full_path": "/形式/...",
          "point_type": "关键点",
          "dimension": "形式",
          "element_name": null
        }
      ],
      "element_bindings": [
        {
          "itemset_id": 1607313,
          "itemset_item_id": 6051234,
          "category_id": 123456,
          "point_type": "关键点",
          "dimension": "形式",
          "element_name": "示例元素",
          "matched_element_count": 1,
          "matched_post_count": 1,
          "matched_post_ids": ["02454b8dab4c13c9fa21042bdc92d122"]
        }
      ],
      "itemset_ids": [1607313],
      "itemset_items": [
        {
          "itemset_id": 1607313,
          "category_id": 123456,
          "category_path": "/形式/...",
          "point_type": "关键点",
          "dimension": "形式",
          "element_name": null
        }
      ],
      "support": 0.18,
      "absolute_support": 12,
      "matched_post_ids": ["..."],
      "case_ids": ["..."],
      "decode_case_ids": [],
      "seed_terms": ["权钱交易", "利益输送"],
      "trace_id": "...",
      "demand_task_id": null,
      "demand_content_id": 1,
      "source_certainty": "db_validated",
      "validation_status": "passed"
    }
  },
  "dt": "20260604"
}
  1. dwd_multi_demand_pool_di / feature_point_data 不改业务结构,仅做本地镜像

本地目录仍保留多文件,目的是完整复刻本次 run 的所有输出,便于回归验证 local_json 模式不真实写 DB / Hive:

test_output_data/{run_id}/
  run_manifest.json
  demand_task.json
  demand_items.json
  rejected_demand_items.json
  demand_content.json
  dwd_multi_demand_pool_di.json
  feature_point_data.json

dwd_multi_demand_pool_di.json 只镜像当前两种策略,不新增证据字段:

  • 当下供需gap
  • 当下供需gap-分词

feature_point_data.json 始终作为本地契约文件存在;仅在 merge_leve2 == "全局树" 时有非空业务行,字段仍沿用当前实现中的 特征点总分发曝光pv质bn_rovndt。注意:真实表/代码里的历史字段拼写是 merge_leve2,CLI 参数可以叫 --merge-level2,但输出 JSON 和文档中的表字段应保持 merge_leve2,不要误改成 merge_level2

  1. evidence_pack 采用强校验:LLM 只提供候选引用,代码校验失败则拒绝该需求

evidence_refs 只是 DemandAgent LLM 在生成需求时给出的候选证据引用,不直接下发给 ContentFindAgent。真正进入 demand_content.ext_data.evidence_pack 的,只能是代码按当前 execution_id 从 DB 校验通过并补齐后的证据。

原则:

  • 下游消费的 evidence_pack 必须是真实、可追溯、DB 校验通过的证据链。
  • 如果 itemset_ids/category_ids/element_bindings/video_ids 任一必需证据无法校验,当前 DemandItem 失败,不写入 demand_content。对 Pattern itemset 来源,case_idspost_id 语义等于已校验的 matched_post_ids,可为空的是 decode_case_idssource_post_id/itemset_ids/itemset_items/mining_config_id/matched_post_ids/support/absolute_support 必须强校验通过。若 LLM 漏填 source_kind,但已给出 itemset_idssource_tool=get_itemset_detail,DemandAgent 可内部补齐为 pattern_itemset 后继续 DB 强校验。
  • 失败的 DemandItem 只进入本地 rejected_demand_items.json 供排查,Agent 继续生成下一条需求。
  • 不允许把候选反查、跨 execution 命中、DB 错误、LLM 抄错 ID 的结果伪装成下游可消费证据。

字段来源和校验口径如下:

字段 主要来源 真实性判断 是否可能受 LLM 影响
pattern_source_system 代码按当前读取链路设置,MVP 固定为 pg_pattern_v2 标记证据来自 PG open_aigc.public Pattern V2 主事实
pattern_execution_id 当前运行参数 / PG pattern_mining_execution.id 必须存在且 status='success'
mining_config_id PG pattern_itemset.mining_config_id + pattern_mining_config.id 必须来自同一 execution,且 config scope='topic'
case_id_type 代码按证据类型设置,Pattern case 链路固定为 post_id 用于标准化 source_post_id/matched_post_ids/aweme_id 的 ID 语义
source_post_id LLM 候选 + PG pattern_itemset_post.post_id 校验 必须出现在已校验 itemset 的 matched_post_ids 中,否则拒绝该需求 候选阶段受影响,最终输出必须 DB 校验通过
itemset_ids LLM 在 evidence_refs 中给出候选,代码按 execution_id 回查校验 只有属于当前 execution 且和需求证据匹配时才进入 evidence_pack;否则该需求拒绝 候选阶段受影响,最终输出必须 DB 校验通过
itemset_items[] PG pattern_itemset_item + pattern_mining_category 必须来自已校验 scope='topic' itemset,且每个 category_id/category_path 能 join 到当前 execution 的分类节点
support / absolute_support PG pattern_itemset DB 可验证事实
matched_post_ids PG pattern_itemset_post 聚合 DB 可验证事实;COUNT(DISTINCT post_id) 必须等于 absolute_support
category_bindings PG pattern_itemset_item + pattern_mining_category 必须来自已校验 itemset/category;查不到则拒绝该需求
element_bindings PG pattern_mining_element,限定 source_table='post_decode_topic_point_element' 必须能在当前 execution/source_post 下精确绑定到 itemset item;只查到候选时拒绝该需求
video_ids 优先来自已校验 itemset 的 matched_post_ids 必须来自已校验证据链;不再把宽松反查结果作为下游证据
case_ids 已校验 itemset 的 matched_post_ids Pattern 来源下固定是 post_id 语义,和 case_id_type=post_id 对齐
decode_case_ids PG-only MVP 不再查旧 MySQL decode 表,保留为空数组兼容字段 可选补充字段;命中不到不影响 Pattern itemset 来源通过
seed_terms LLM 候选 + 代码校验后的 element/category/itemset 反推 最终输出必须能被已校验证据覆盖;否则拒绝该需求 候选阶段受影响,最终输出必须被证据覆盖
source_kind LLM 候选明确声明;若缺失但已有 itemset_idssource_tool=get_itemset_detail,DemandAgent 内部可安全补齐为 pattern_itemset MVP 只支持 pattern_itemset;补齐后仍必须走 DB 强校验,不是 Pattern itemset 则拒绝 候选阶段受影响,最终输出必须 DB 校验通过
trace_id 现有 Agent runner / trace store 框架事实
demand_task_id 本地回归可为模拟任务 ID;云端单表模式因不建 demand_task 可为 null 不能伪装成真实 DB task id
demand_content_id 云端单表写库后为真实 demand_content.id;本地回归为模拟 ID 云端测试服真实,本地回归模拟

因此最终进入 demand_contentevidence_pack 必须包含完整证据字段;其中状态字段的取值只能是:

{
  "source_certainty": "db_validated",
  "validation_status": "passed"
}

如果 LLM 给出的 itemset_ids/category_ids/source_post_id 查不到、跨 execution,source_post_id 不在已校验 itemset 的 matched_post_ids 中,itemset_items[]mining_config_id 补不齐,和 element_names/seed_terms 没有强匹配,或者 DB 校验失败,则当前 DemandItem 不生成 demand_content,只记录到本地拒绝清单:

{
  "element_names": ["地貌水文", "互动设计"],
  "reject_reason": "itemset_id 377530 not found under execution_id 1987",
  "validation_status": "failed"
}

业务含义:给下游 ContentFindAgent 的任务证据链必须真实。只要 DemandAgent 无法确认证据真实性,这条需求就不进入需求池;Agent 应继续生成下一条可强校验的需求。

  1. 输入仍从真实 DB 拉

MVP 入口只接受已有 PG pattern_mining_execution.id

DEMAND_OUTPUT_MODE=local_json python -m examples.demand.run_existing_execution_local \
  --execution-id 581 \
  --merge-level2 贪污腐败 \
  --platform-type piaoquan \
  --count 5 \
  --run-id local_581_smoke

local 模式只能通过 examples.demand.run_existing_execution_local 进入;run.py 会校验 DEMAND_LOCAL_ENTRYPOINT=run_existing_execution_local。该入口必须传已有 PG execution,禁止调用 run_mining 或各平台 prepare,避免写任何 Pattern 中间表。

本地入口会把三类运行产物统一重定向到 examples/demand/test_output_data/{run_id} 下。可传 --run-id 指定目录名;如果传 --output-root,也必须位于 examples/demand/test_output_data/ 之内。

{output_root}/
  intermediate/result/
  intermediate/data/
  .trace/
  output/
  run_manifest.json
  demand_task.json
  demand_items.json
  rejected_demand_items.json
  demand_content.json
  dwd_multi_demand_pool_di.json
  feature_point_data.json

若未传 --output-root,默认写到 examples/demand/test_output_data/execution_{execution_id}_{timestamp}/。local 模式会从 PG pattern_mining_element 聚合生成兼容的权重 JSON 到 intermediate/data/{execution_id}/get_weight_score_* 读取该目录,不写 examples/demand/data

Test Plan

  • 写库屏障测试:local_json 模式下 monkeypatch mysql_db.insert/update/insert_manyexecute_odps_sql 和 PG DML/DDL,若被调用则测试失败;PG repository 只允许 SELECT/SHOW/EXPLAIN
  • 云端单表写库测试:mysql_demand_content 模式下只允许 MySQL demand_contentINSERT/UPDATE;不得调用 _create_demand_task/_finish_demand_task、Hive/ODPS 写入、PG DML/DDL 或旧 MySQL Pattern 写入。
  • 输出结构测试:本地回归校验 JSON 文件存在;云端测试服按 run_label 查询 MySQL demand_content 行。两种模式都重点校验 demand_content.ext_data.evidence_pack,同时确认 dwd_multi_demand_pool_di / feature_point_data 不新增业务字段。
  • evidence 测试:校验所有进入 demand_contentevidence_pack.pattern_execution_id/source_kind/seed_terms/trace_id/source_certainty/validation_status 必填,validation_status 必须为 passedsource_certainty 必须为 db_validated
  • Pattern itemset evidence 测试:当 source_kind=pattern_itemset 时,pattern_source_system/case_id_type/source_post_id/mining_config_id/itemset_ids/itemset_items/matched_post_ids/support/absolute_support 必填,且 source_post_id 必须在 matched_post_ids 中,len(matched_post_ids) 必须等于 absolute_support
  • 严格拒绝测试:构造 LLM 声明错误 itemset、跨 execution itemset、缺少 matched_post_ids/source_post_id/itemset_items/mining_config_id、DB 校验失败等样本,验证这些 DemandItem 不进入 demand_content,只进入 rejected_demand_items.json
  • 回归测试:不改 agent/ 通用框架;DemandAgent pattern 工具名保持不变,但底层均走 PG adapter。
  • 多 subagent 验证:分别做 DB 血缘审计、输出契约审计、旧能力回归审计,交叉确认没有改坏原能力。

Assumptions

  • V1 不做 DB schema migration;本地回归模式不写 DB,云端测试服模式只写 MySQL demand_content 单表。
  • 本次只调整 DemandAgent 输出,不改 agent/ 通用框架。
  • 本次下游证据链只以 demand_content.ext_data.evidence_pack 为载体;dwd_multi_demand_pool_difeature_point_data 不承载 evidence_pack。
  • DemandAgent 当前正式证据源是 PG open_aigc.public Pattern V2 主事实;旧 MySQL Pattern 兼容层只作为历史背景,不再作为 evidence 来源。
  • 本 MVP 只输出 PG pattern_itemset.scope='topic'topic_element、script、paragraph、group scope 因无法保证分类树节点闭合,不进入 exact evidence。
  • 对纯 Pattern itemset 来源,case_idspost_id 语义直接等于已校验的 matched_post_idsdecode_case_ids 保留为空数组兼容字段。source_post_idmatched_post_idsitemset_idsitemset_items[]mining_config_idsupportabsolute_support 必须强校验通过。