# Pattern Global V2 全链路数据与算法事实报告 核验日期:2026-05-29 代码范围:`/Users/samlee/Documents/works/image_article_comprehension` 文档/Excel范围:`/Users/samlee/Documents/works/image_article_comprehension_structure源码分析`、`/Users/samlee/Documents/works/数据工程` 结论来源:当前 checkout 代码行号、三个已完成 subagent 只读复核、PostgreSQL `open_aigc.public` 只读查询、Excel 只读检查。Excel 未被修改。 > 本报告不复写源码中的数据库密码、API key、token、AK/SK。MySQL `open_aigc_pattern` 的 RDS 域名 Fake-IP 路径本轮连接失败,但改用真实内网地址 `192.168.202.204:3306` 后只读复核成功;本文只写脱敏后的连接事实和统计结果。 ## 1. 最终事实结论 1. `data_clustering_statistic.xlsx` 里的 00-08 链路是真实存在的“聚类辅助分类/embedding 分类工程链路”:三张源元素表进入 9 组 `source_type + source_table`,经过 `element_dedup_group`、本地 source embedding cache、`dist_rows` 距离矩阵、DBSCAN 候选簇、cluster batch,再进入分类 agent 或 `EmbeddingClassifier`,最终沉淀 `global_category/global_element/element_classification_mapping`。 2. 但这条 Excel 链路不是 `run_classify.py` 的硬前置链路。`run_classify.py` 的主路径直接从源表 SQL 聚合未分类元素,按 `(name, type)` 去重后交给 ClassifyAgent;它不导入 dedup matrix、embedding cache、距离矩阵或 DBSCAN。代码证据是 [run_classify.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/run_classify.py:126) 和 [data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1666)。 3. 当前事实应写成“双入口/双口径”: | 入口 | 是否需要 dedup/embedding/DBSCAN | 作用 | |---|---|---| | `run_classify.py` | 不需要 `element_dedup_group`、source embedding cache、距离矩阵、DBSCAN | 主分类入口:SQL 聚合未分类元素,Agent 写 global 三表 | | `run_classify_embedding.py` | 需要待分类元素 embedding 和 global vector search,不需要 DBSCAN | embedding + LLM 批量分类入口,写 global element/mapping/embedding | | `cluster_on_demand.py` / `run_classify_clustering.py` | DBSCAN 需要预构建距离矩阵;聚类到分类的桥接当前仍有 TODO | 聚类辅助入口:找相似候选簇,辅助人工/agent 批处理 | 4. `global_category/global_element/element_classification_mapping` 的口径要按“广义/狭义”拆开:如果把整个 `pattern_global_v2` 服务都口头叫 Pattern V2,那么其中的分类库/分类执行阶段会写这三张 global 表;如果按本文更精确的“狭义 Pattern V2 = daily snapshot/mining/API 子域”,它不生成这三张 global 表,只读取它们。三张 global 表的核心写入点包括 [classify_agent_tools.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/tools/classify_agent_tools.py:692)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:504)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1469)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1594)。 5. Pattern V2 的真实角色是下游快照和挖掘:读取 `element_classification_mapping`、活跃 `global_category`、三张源元素表和可选 `global_element_semantic_map/cluster`,写 `pattern_mining_*` 快照和 `pattern_itemset*`、`pattern_script_sequence*`、`pattern_group_itemset*` 结果。代码证据是 [run_daily.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily.py:239)、[snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:461)、[snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:551)。 6. `global_element_semantic_cluster/map` 当前库中有数据,但当前仓库内只找到 Pattern V2 对它的消费和快照写入,没有找到生成 `global_element_semantic_cluster/map` 的脚本或 agent 主路径。只能确认:Pattern V2 消费它,并把命中的 semantic cluster 写成 `pattern_mining_element_semantic_map`。 7. `pattern_global_v2` 的主链不是一个简单线性全自动链路,而是一条主链加多个可选/维护入口:数据导入、分类库冷启动、run_classify/embedding classify、聚类辅助、向量同步、classification status、Pattern V2 快照挖掘、API/可视化。check/optimize/refactor/distribute/promote/cleanup/backfill 是维护或质量治理链路,会影响 future snapshot 的 global 资产或发布状态,但不是每次 Pattern V2 挖掘的硬前置。 8. MySQL `open_aigc_pattern` 读通后不改变上述主链路结论。它证明 8012 Topic/Script Build 工作台和旧 `topic_pattern_*` 兼容层是活跃数据域,但没有发现它参与 `run_classify.py`、global 三表生成,或替代 PostgreSQL `open_aigc` 的 Pattern V2 主事实。 ## 2. 完整数据与算法流程图 实线表示硬依赖;虚线表示辅助、可选、半自动或维护链路。 ```mermaid flowchart TD A["上游 decode / data_io / API / ODPS / JSON"] --> B["post / post_decode_* / post_script_* 源表"] B --> C["run_classify.py SQL 未分类元素聚合"] C --> D["ClassifyAgent 工具"] D --> E["global_category"] D --> F["global_element"] D --> G["element_classification_mapping"] D --> H["post_classification_status"] B -. "Excel 聚类工程链路" .-> I["element_dedup_group: 9 组 source_type + source_table"] I -.-> J["source embedding cache: embeddings_{source_table}.*"] J -.-> K["dist_rows 距离矩阵: source_type__source_table"] K -.-> L["DBSCAN 候选簇"] L -.-> M["cluster batch"] M -. "run_classify_clustering 当前 TODO" .-> D B -. "embedding 分类入口" .-> N["run_classify_embedding.py"] N -.-> O["EmbeddingClassifier: embedding/search/LLM/write"] O --> F O --> G O --> P["global_element_embedding"] E --> Q["Pattern V2 snapshot_builder"] F -. "经 mapping / semantic map 间接参与" .-> Q G --> Q B --> Q R["global_element_semantic_cluster/map"] -. "可选消费;当前仓库未找到生成器" .-> Q H --> S["classify_post_buckets"] S --> T["pattern_mining_post_bucket"] Q --> U["pattern_mining_execution"] Q --> V["pattern_mining_category"] Q --> W["pattern_mining_element"] Q --> X["pattern_mining_element_semantic_map"] V --> Y["FP-Growth / PrefixSpan / group mining"] W --> Y T --> Y Y --> Z1["pattern_itemset / item / post"] Y --> Z2["pattern_script_sequence / item / post"] Y --> Z3["pattern_group_itemset / item / member"] Z1 --> API["pattern_global_v2 API / debug tools / visualization"] Z2 --> API Z3 --> API API --> BUILD["patter_from_global_and_build: Topic/Script Build Agent"] BUILD --> OUT["open_aigc_pattern topic_build_* / script_build_*"] MAINT["check / optimize / refactor / distribute / sync_vectors / promote / cleanup / backfill"] -. "维护 global 资产或 pattern execution 状态" .-> E MAINT -.-> F MAINT -.-> G MAINT -.-> U ``` ## 3. Excel 聚类链路逐阶段核验 `data_clustering_statistic.xlsx` 有 9 个 sheet:`00_聚类总览` 到 `08_global_mapping`。只读检查显示,它描述的是“聚类/embedding 辅助分类”工程链路,不是 `run_classify.py` 唯一执行链路。 | Excel 阶段 | 当前代码事实 | 代码证据 | 需要纠偏的口径 | |---|---|---|---| | 00/01 原始元素表 | 三张源元素表:`post_decode_topic_point_element`、`post_script_element`、`post_script_paragraph_field_element` | [models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/models.py:85)、[models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/models.py:148)、[models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/models.py:196) | 不是全库聚类,是 3 张表里的指定业务维度 | | 02 `element_dedup_group` | 一张表承载 9 组处理组合,按规范化元素名聚合 | [sync_all_dedup_groups.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/sync_all_dedup_groups.py:25)、[dedup_manager.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/dedup_manager.py:37)、[dedup_manager.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/dedup_manager.py:72)、[models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/models.py:606) | 不是 9 张去重表 | | 03 source embedding cache | 本地 `cache/embeddings_{source_table}.ids.npy/.vecs.npy`;可复用已分类的 `global_element_embedding` | [embedding_cache.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/embedding_cache.py:25)、[distance_matrix_manager.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/distance_matrix_manager.py:566) | source embedding cache 不是独立 DB 表 | | 04 `dist_rows` 距离矩阵 | 本地行存储,文件名按 `source_type__source_table` | [build_all_matrices.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/build_all_matrices.py:41)、[distance_matrix_manager.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/distance_matrix_manager.py:46) | 距离矩阵不是 PostgreSQL 表 | | 05 DBSCAN | `cluster_on_demand.py` 要求矩阵已存在,DBSCAN 用 precomputed distance | [cluster_on_demand.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/cluster_on_demand.py:136)、[cluster_on_demand.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/cluster_on_demand.py:141)、[cluster_on_demand.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/cluster_on_demand.py:173) | DBSCAN 是聚类入口硬前置,不是 `run_classify.py` 硬前置 | | 06 cluster batch | 旧 `ClusterBatchPreparer` 可从 JSON 展开未分类 batch | [cluster_batch_prepare.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/cluster_batch_prepare.py:182)、[cluster_batch_prepare.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/cluster_batch_prepare.py:240)、[cluster_batch_prepare.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/cluster_batch_prepare.py:289) | 当前实现有方法名/key 漂移风险,不能写成稳定全自动主链 | | 07 classify agent | ClassifyAgent 或 EmbeddingClassifier 写 global element/mapping/embedding | [run_classify.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/run_classify.py:301)、[run_classify_embedding.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/run_classify_embedding.py:216)、[EmbeddingClassifier.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/services/EmbeddingClassifier.py:127) | 分类 agent 不是 DBSCAN;DBSCAN 只是帮助组织候选 batch | | 08 global mapping | 最终主事实是 global 三表及 embedding/status 辅助表 | [models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/models.py:252)、[models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/models.py:288)、[models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/models.py:316) | Pattern V2 下游读取这些资产,不生成这些资产 | Excel 本身的问题不是“链路错”,而是容易被读成“所有分类都必须先跑 DBSCAN”。更准确的说法是:Excel 描述的是聚类辅助分类/embedding 分类工程路径;`run_classify.py` 还有一条不依赖 DBSCAN 的主分类路径。 ## 4. `run_classify` 的真实前置 `run_classify.py` 的硬前置是: 1. PostgreSQL 源表存在且有未分类元素。 2. `element_classification_mapping` 可用于排除已分类 source element。 3. 分类树/工具可用;如果是冷启动或创建分类,走 `global_category` 写入工具。 4. Agent 运行所需模型和工具环境可用。 `run_classify.py` 不强制需要: 1. `element_dedup_group` 2. source embedding cache 3. `dist_rows` 距离矩阵 4. DBSCAN 聚类结果 5. `global_clusters_*.json` 代码上它直接调用 `data_operation.get_unclassified_elements()` 或脚本侧未分类查询,再创建 batch 并调用 `agent.run_classify_batch()`:[run_classify.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/run_classify.py:160)、[run_classify.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/run_classify.py:281)、[run_classify.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/run_classify.py:307)。SQL 去重在 [data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1724) 到 [data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1765),是 `GROUP BY name/type`,不是读 `element_dedup_group`。 相反,`cluster_on_demand.py` 的硬前置才是距离矩阵:矩阵不存在会直接抛错并提示先跑 `build_all_matrices.py`,见 [cluster_on_demand.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/cluster_on_demand.py:139) 到 [cluster_on_demand.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/cluster_on_demand.py:144)。 ## 5. Global 分类资产生成链路 Global 三表的生成和维护来自分类库链路,不来自 Pattern V2。 | 表 | 主要写入路径 | 代码证据 | |---|---|---| | `global_category` | `create_category`、`update_category`、`create_and_classify`、冷启动、优化/重构维护 | [classify_agent_tools.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/tools/classify_agent_tools.py:608)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:504)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:546)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:2824) | | `global_element` | ClassifyAgent 的 `find_or_create_element`;EmbeddingClassifier 的 `batch_find_or_create_elements` | [classify_agent_tools.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/tools/classify_agent_tools.py:746)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1469)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1511)、[EmbeddingClassifier.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/services/EmbeddingClassifier.py:607) | | `element_classification_mapping` | `classify_elements` 单条写;EmbeddingClassifier 批量写;auto-link/backfill 回填 | [classify_agent_tools.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/tools/classify_agent_tools.py:761)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1594)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:1632)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:2166)、[data_operation.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/data_operation.py:2242) | 分类资产的业务关系是: ```text 原始源表一行 -> element_classification_mapping.source_table + source_element_id -> global_element.id -> global_element.belong_category_stable_id -> global_category.stable_id / path ``` `global_category` 和 `global_element` 都有 `retired_at_execution_id` 当前有效口径;`global_category.stable_id` 是逻辑分类 ID,`id` 是行版本 ID。 ## 6. Pattern V2 链路 Pattern V2 的起点不是 raw 解构或 DBSCAN,而是已经存在的 global 分类资产和源表事实。 ### 6.1 输入 | 输入 | 作用 | 代码证据 | |---|---|---| | post ids / post filter | 决定本次 execution 的帖子范围 | [run_daily.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily.py:240) | | `element_classification_mapping` | 把源元素连接到 global category/element | [snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:461) | | `global_category` 活跃树 | 回填当前可信 path 和祖先链,构建 pattern 快照树 | [snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:532) | | 三张源元素表 | 生成 execution 内元素快照 | [snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:559) | | `global_element_semantic_map/cluster` | 可选语义归一,用簇代表覆盖 name/description/category | [snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:481) | | `post_classification_status` / mapping 完成度 | 分桶,决定哪些帖子进入不同算法 | [run_daily.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily.py:265) | 一个需要单独标注的事实:`build_snapshot()` 接收 `classify_execution_id`,但当前映射读取是按 post_ids 全量读 `element_classification_mapping`,没有按 `classify_execution_id` 过滤 mapping;`classify_execution_id` 主要用于收集 category 版本视图。这可能带来时间一致性风险,证据见 [snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:451) 到 [snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:468)。 ### 6.2 快照输出 | 输出表 | 作用 | 代码证据 | |---|---|---| | `pattern_mining_execution` | 一次挖掘执行记录、post 范围、状态、统计 | [models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/pattern/models.py:29) | | `pattern_mining_category` | execution 内剪枝后的分类树快照 | [models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/pattern/models.py:75)、[snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:551) | | `pattern_mining_element` | execution 内源元素到 pattern category 的冻结事实 | [models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/pattern/models.py:100)、[snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:559) | | `pattern_mining_element_semantic_map` | 本次快照中 semantic cluster 的归一记录 | [snapshot_builder.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/snapshot_builder.py:573) | | `pattern_mining_post_bucket` | topic/fully 等分类完成度桶 | [run_daily.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily.py:279) | ### 6.3 算法输出 | 算法 | transaction | 结果表 | 代码证据 | |---|---|---|---| | Topic / topic_element / cross / paragraph FP-Growth | 帖子、段落或选题点 group | `pattern_itemset`、`pattern_itemset_item`、`pattern_itemset_post` | [run_daily.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily.py:320)、[itemset_writer.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/itemset_writer.py:126) | | Script PrefixSpan | 帖子内段落顺序序列 | `pattern_script_sequence`、`pattern_script_sequence_item`、`pattern_script_sequence_post` | [run_daily.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily.py:472)、[script_sequence_writer.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/script_sequence_writer.py:60) | | Point group mining | 帖子内子分组单元 | `pattern_group_itemset`、`pattern_group_itemset_item`、`pattern_group_itemset_member` | [models.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/pattern/models.py:495)、[group_itemset_writer.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/persistence/group_itemset_writer.py:164) | `run_daily_main.py` 当前硬编码默认只启用 `ENABLE_TOPIC_ELEMENT=True`,其他开关 false,见 [run_daily_main.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily_main.py:178)。`run_daily.py` 函数本身支持更宽的可配置能力,所以报告里应区分“函数能力”和“当前默认入口”。 Pattern V2 成功后不自动发布为 `is_current`;需要单独 promote,见 [run_daily.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/run_daily.py:521) 和 [promote_current.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/pattern/daily/promote_current.py:15)。 ## 7. 融合进主链的其它能力 | 能力 | 是否并入主链 | 说明 | |---|---|---| | `data_io` 导入 | 是 | 把上游 decode/API/ODPS/JSON 结果写入 `post_decode_*` / `post_script_*`,是源表入口 | | 分类树 cold start | 是 | 首次或空树场景创建 `global_category` 初始分类体系 | | `run_classify.py` | 是 | 主分类入口,直接写 global 三表 | | `run_classify_embedding.py` / `EmbeddingClassifier` | 是,可选替代分类入口 | embedding + vector search + LLM,写 global element/mapping/embedding | | dedup/embedding/距离矩阵/DBSCAN | 是,但属于聚类辅助路径 | Excel 描述的工程链路,辅助构造分类 batch,不是 Pattern V2 或 run_classify 的硬前置 | | `global_*_embedding` / vector search | 是 | 分类复用、相似搜索、embedding 分类依赖 | | `post_classification_status` / Pattern buckets | 是 | 决定 Pattern V2 算法输入桶 | | `global_element_semantic_cluster/map` | 是,作为 Pattern snapshot 可选输入 | 当前仓库只能证明被消费,不能证明由 Pattern V2 生成 | ## 8. 旁路维护和质量治理 这些链路不应写成 Pattern V2 的硬前置,但会改变后续快照看到的 global 资产或 execution 状态: | 链路 | 作用 | 对主链影响 | |---|---|---| | check / optimize / refactor | 检查分类树结构、离群元素、重复节点,提出或执行分类树调整 | 调整后影响未来 `global_category/global_element/mapping` | | distribute | 分类或聚类后的分发/批处理辅助 | 属于分类库维护工具,不是 pattern mining 必经步骤 | | `sync_vectors.py` / `generate_missing_embeddings.py` | 同步或补齐 `global_category_embedding/global_element_embedding` | 提升相似搜索、embedding 分类和工具检索质量 | | promote current | 切换 `pattern_mining_execution.is_current` | 影响线上 API 默认读取哪个 execution | | cleanup / backfill / clone snapshot | 删除、修复、复制或补回 pattern 快照/结果 | 维护历史 execution,不生成 global 三表 | ## 9. DB 只读复核 ### 9.1 PostgreSQL `open_aigc.public` 本轮 PostgreSQL 只读连接成功。关键计数如下: | 数据域 | 表 | 行数 | |---|---|---:| | 源表 | `post` | 66,974 | | 源表 | `post_decode_topic_point_element` | 1,308,993 | | 源表 | `post_script_element` | 47,951 | | 源表 | `post_script_paragraph_field_element` | 177,856 | | 去重 | `element_dedup_group` | 262,326 | | global | `global_category` | 4,944 | | global | `global_element` | 290,864 | | global | `element_classification_mapping` | 1,123,373 | | embedding | `global_element_embedding` | 455,269 | | embedding | `global_category_embedding` | 8,860 | | semantic | `global_element_semantic_cluster` | 5,585 | | semantic | `global_element_semantic_map` | 18,248 | | pattern snapshot | `pattern_mining_execution` | 7 | | pattern snapshot | `pattern_mining_category` | 25,816 | | pattern snapshot | `pattern_mining_element` | 1,950,755 | | pattern result | `pattern_itemset` | 449,216 | | pattern result | `pattern_script_sequence` | 2,753 | | pattern result | `pattern_group_itemset` | 2,997 | `element_classification_mapping` 当前分布: | source_table | element_type | rows | posts | global_elements | |---|---|---:|---:|---:| | `post_decode_topic_point_element` | 实质 | 518,403 | 52,529 | 125,586 | | `post_decode_topic_point_element` | 形式 | 421,692 | 52,395 | 46,994 | | `post_decode_topic_point_element` | 意图 | 12,050 | 11,954 | 230 | | `post_script_element` | 实质 | 23,069 | 1,933 | 9,941 | | `post_script_element` | 形式 | 13,103 | 1,949 | 7,022 | | `post_script_paragraph_field_element` | 作用 | 25,298 | 1,907 | 4,751 | | `post_script_paragraph_field_element` | 实质 | 74,238 | 1,933 | 26,449 | | `post_script_paragraph_field_element` | 形式 | 35,520 | 1,932 | 8,112 | `element_dedup_group` 当前 9 组分布: | source_table | source_type | groups | occurrence_sum | |---|---|---:|---:| | `post_decode_topic_point_element` | 实质 | 140,069 | 537,822 | | `post_decode_topic_point_element` | 形式 | 49,402 | 423,987 | | `post_decode_topic_point_element` | 意图 | 643 | 40,732 | | `post_script_element` | 实质 | 12,562 | 31,872 | | `post_script_element` | 形式 | 9,053 | 16,079 | | `post_script_paragraph_field_element` | 作用 | 8,422 | 28,895 | | `post_script_paragraph_field_element` | 实质 | 30,830 | 81,906 | | `post_script_paragraph_field_element` | 形式 | 9,151 | 38,519 | | `post_script_paragraph_field_element` | 感受 | 2,194 | 28,536 | Pattern execution 状态: | id | snapshot_date | status | is_current | post_count | category_count | element_count | topic_itemset_count | topic_element_itemset_count | script_sequence_count | |---:|---|---|---|---:|---:|---:|---:|---:|---:| | 581 | 2026-05-09 | success | false | 13,265 | 1,932 | 290,467 | 35,406 | 18,491 | | | 541 | 2026-04-27 | running | false | 12,448 | 3,992 | 315,389 | | 38,418 | | | 501 | 2026-04-27 | success | false | 12,448 | 3,992 | 315,389 | | 26,070 | | | 421 | 2026-04-24 | success | false | 12,448 | 3,995 | 315,389 | 26,849 | 8,932 | | | 401 | 2026-04-23 | failed | true | 12,448 | 3,995 | 315,389 | | | 1,197 | | 301 | 2026-04-21 | success | false | 11,760 | 3,955 | 199,366 | 928 | 388 | | | 281 | 2026-04-16 | success | true | 11,760 | 3,955 | 199,366 | 76,835 | 17,153 | 1,030 | 这里有一个上线口径风险:当前 DB 中 `is_current=true` 同时出现 `#401 failed` 和 `#281 success`。最新成功是 `#581`,但它不是 current。API 默认读取 current 时需要同时防守 `status='success'`。 ### 9.2 MySQL `open_aigc_pattern` 本轮复核发现:当前代码里的 MySQL 连接配置目标是 `open_aigc_pattern`,但 RDS 域名 `rm-bp1k5853td1r25g3n690.mysql.rds.aliyuncs.com` 在当前网络环境下解析到 Fake-IP `198.18.0.59`。该路径 TCP 端口可连,但收不到 MySQL greeting,PyMySQL 报 `OperationalError: (2013, 'Lost connection to MySQL server during query')`。改用真实内网地址 `192.168.202.204:3306` 后,只读查询成功。 当前只读复核结果: | 项 | 结果 | |---|---| | 数据库 | `open_aigc_pattern` | | MySQL 版本 | `5.7.30-log` | | 表数 | 35 | | 字段数 | 332 | 关键表规模: | 表 | 行数 | 角色 | |---|---:|---| | `topic_build_record` | 1,093 | 选题构建执行记录 | | `topic_build_topic` | 1,264 | 选题候选/结果 | | `topic_build_point` | 7,369 | 选题点 | | `topic_build_composition_item` | 22,579 | 选题组成元素 | | `topic_build_item_relation` | 19,055 | 构成元素关系 | | `topic_build_item_source` | 23,504 | 元素证据来源 | | `topic_build_item_exploration_trace` | 15,466 | item 探索轨迹 | | `topic_build_log` | 1,086 | 选题构建日志 | | `script_build_record` | 269 | 脚本构建执行记录 | | `script_build_paragraph` | 945 | 脚本段落 | | `script_build_element` | 2,459 | 脚本元素 | | `script_build_paragraph_element` | 4,447 | 段落和元素关联 | | `script_build_decision_trace` | 649 | 脚本构建决策 trace | | `script_build_log` | 264 | 脚本构建日志 | | `external_search_case_log` | 12,043 | 外部搜索 case 缓存 | | `prompt` / `prompt_version` | 9 / 125 | prompt 当前版本和历史版本 | | `build_strategy` / `build_strategy_version` | 56 / 242 | 构建策略当前版本和历史版本 | | `topic_pattern_execution` | 58 | 旧 topic pattern 本地执行 | | `topic_pattern_category` | 29,363 | 旧 topic pattern 分类镜像 | | `topic_pattern_element` | 565,571 | 旧 topic pattern 元素镜像 | | `topic_pattern_itemset` | 655,513 | 旧 topic pattern 本地 itemset | | `topic_pattern_itemset_item` | 3,007,048 | 旧 topic pattern item | 因此,代码层事实需要写得更精确:`patter_from_global_and_build` 的 `pattern_server.py` 提供 topic/script build API,并通过 MySQL ORM 模型写 `topic_build_*`、`script_build_*`、prompt、strategy、external search 等应用表;`topic_pattern_*` 是旧本地 mining / 兼容 / 展示兜底层。它不是 global 三表生成器,也不替代 PostgreSQL `open_aigc` 里的 Pattern V2 快照和挖掘结果。 ## 10. 后台服务简述 这份报告不把服务边界作为主分析框架,但按 Docker 部署看,有两个主要后台服务: | Docker | 端口 | 大概职责 | 代码证据 | |---|---:|---|---| | `docker/Dockerfile.pattern_global_v2` | 8001 | 数据底座、分类库、global 表、dedup/embedding/聚类辅助、Pattern V2、API/debug/可视化 | [Dockerfile.pattern_global_v2](/Users/samlee/Documents/works/image_article_comprehension/docker/Dockerfile.pattern_global_v2:17)、[Dockerfile.pattern_global_v2](/Users/samlee/Documents/works/image_article_comprehension/docker/Dockerfile.pattern_global_v2:31)、[visualization_server.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/visualization_server.py:61) | | `docker/Dockerfile.patter_from_global_and_build` | 8012 | Topic/Script Build Agent、构建工作台、prompt/strategy、外部搜索和构建记录,消费 8001/open_aigc 数据/API | [Dockerfile.patter_from_global_and_build](/Users/samlee/Documents/works/image_article_comprehension/docker/Dockerfile.patter_from_global_and_build:29)、[Dockerfile.patter_from_global_and_build](/Users/samlee/Documents/works/image_article_comprehension/docker/Dockerfile.patter_from_global_and_build:46)、[pattern_server.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern/patter_from_global_and_build/pattern_server.py:407)、[pattern_server.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern/patter_from_global_and_build/pattern_server.py:1428) | `pattern_server.py` 文件头仍写 `8002`,但 Docker 暴露的是 `8012`,应以 Docker 和启动参数为准。 ## 11. 需要保留的风险与缺口 1. `run_classify_clustering.py` 准备好 cluster batch 后仍打印 TODO,未真实调用 `agent.run_classify_batch()`:[run_classify_clustering.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/scripts/dedup_matrix/run_classify_clustering.py:134)。 2. `ClusterBatchPreparer.cluster_all_elements()` 同步矩阵时带 `source_type + source_table`,但加载矩阵用 `load_or_create(source_type)`,和新矩阵 key `source_type__source_table` 有漂移风险:[cluster_batch_prepare.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/cluster_batch_prepare.py:86)、[cluster_batch_prepare.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/cluster_batch_prepare.py:98)。 3. `ClusterBatchPreparer.get_unclassified_from_cluster()` 调用 `expand_dedup_groups`,当前 `DedupManager` 中可靠方法名是 `expand_members`,存在旧方法名漂移风险:[cluster_batch_prepare.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/cluster_batch_prepare.py:221)、[dedup_manager.py](/Users/samlee/Documents/works/image_article_comprehension/aiddit/pattern_global_v2/db/dedup_manager.py:521)。 4. 当前 topic 侧 `感受 + post_decode_topic_point_element` 有原始数据,但不在 dedup/matrix 9 组目标里;Pattern/global 当前 mapping 也没有感受映射行。这会造成“源表有感受、当前 global/mapping 没感受”的口径差异。 5. Pattern snapshot 的 `classify_execution_id` 没有过滤 mapping,只影响 category 版本收集,可能造成 execution 时间一致性偏差。 6. `global_element_semantic_cluster/map` 当前 DB 有数据,但当前仓库未找到生成链路,只能确认 Pattern V2 消费它。 7. MySQL `open_aigc_pattern` 的标准 RDS 域名当前仍会走 Fake-IP 路径并导致 MySQL 握手失败;真实内网地址 `192.168.202.204:3306` 可只读复核成功。后续若要服务运行稳定,应修复域名解析/代理规则,或让配置支持可控的内网地址覆盖。 ## 12. 一句话回答你的核心问题 `去重 + embedding + 聚类 + 分类 agent + Pattern V2` 都属于广义 `pattern_global_v2` 数据底座能力,但不是一条单一强制全自动链。Excel 描述的是聚类辅助分类工程链路;`run_classify.py` 可以绕过 DBSCAN 直接分类;global 三表由分类库链路写入;Pattern V2 在下游读取这些 global 资产和源表事实,生成 `pattern_mining_*` 快照和 pattern 结果,再供 API/debug tools 和 Topic/Script Build Agent 消费。