Przeglądaj źródła

Add data engineering analysis artifacts

SamLee 4 dni temu
rodzic
commit
b886a87341

BIN
.~data_clustering_statistic.xlsx


BIN
.~demand_engineering_statistic.xlsx


+ 580 - 0
BuildingSystemAgent业务与技术逻辑全链路分析.md

@@ -0,0 +1,580 @@
+# BuildingSystemAgent 业务与技术逻辑全链路分析
+
+生成时间:2026-05-29  
+分析对象:`/Users/samlee/Documents/works/BuildingSystemAgent`  
+重点边界:以 `liuzhiheng <liuzhiheng@stuuudy.com>` 与 `linzihan <zihan@ZihanMacBook-Pro-14.local>` 在当前 workspace 中提交的构建 Agent 逻辑为主体。  
+证据来源:Git 作者提交、项目代码、prompt、MySQL `open_aigc_pattern` 只读查询、PostgreSQL `open_aigc.public` 只读查询、GUI 页面 `https://pattern.aiddit.com/build/topic`、多个 subagent 交叉核验。
+
+---
+
+## 第一章:纠偏结论
+
+### 1.1 本项目主体到底是什么
+
+本项目在当前 workspace 里的业务核心,不是聚类、归一、Pattern Mining 本身,而是一个“构建 Agent 工作台”:
+
+1. 用户输入账号需求、选题方向、构建策略、模型配置。
+2. 选题构建 Agent 读取上游 pattern、帖子、元素、外部搜索等证据,构造 `CompositionItem`。
+3. Agent 把 `CompositionItem` 组合成灵感点、目的点、关键点和最终选题。
+4. 脚本构建 Agent 读取选题结果和参考脚本,按“之间展开 / 段间展开 / 段内展开 / 之间+段间展开”生成创作表。
+5. 系统把选题构建、脚本构建、工具调用、日志、评估、决策 trace 写入 `open_aigc_pattern`,并通过 `/build/topic` GUI 展示。
+
+换句话说,BuildingSystemAgent 的核心价值是:把已经完成的内容解构、元素归一、pattern 证据,变成一个可以运行、可追踪、可评估、可复用的选题与脚本生产系统。
+
+### 1.2 旧边界错误
+
+上一个报告的核心错误,是把前置流程写成了本项目主体。这里重新定边界:
+
+| 模块 / 数据 | 正确位置 | 在本报告中的角色 |
+|---|---|---|
+| `pattern_global_v2` | 上游 pattern mining / pattern API 相关能力 | 作为输入证据和 API 依赖说明 |
+| 聚类、归一、元素库、分类树 | 上游数据工程已完成流程 | 作为元素和 pattern 的来源背景 |
+| `open_aigc.public` | 上游事实库与 pattern 事实库 | 只作为前置输入规模和 `#401/#581` 漂移证据 |
+| Excel / 前置文档 | 上游分析资料 | 只用于说明输入口径,不作为主体工程 |
+| `open_aigc_pattern` | 本项目 topic/script build 运行产物主库 | 本报告的主要数据库证据 |
+| `/build/topic` GUI | 本项目构建工作台展示 | 本报告的运行结果展示证据 |
+
+前置流程不是主体。本项目主体是 `patter_from_global_and_build` 目录里由选题构建 Agent、脚本构建 Agent、工具、prompt、数据库模型、FastAPI 路由和前端页面组成的构建应用层。
+
+### 1.3 作者贡献定界
+
+Git 作者统计显示:
+
+| 作者 | 提交数 | 在本项目构建逻辑里的定位 |
+|---|---:|---|
+| `liuzhiheng <liuzhiheng@stuuudy.com>` | 245 | 系统工程主实现者:Agent 执行、工具、数据库、API、GUI、日志、模型配置、外部搜索、AigcAgent / ClaudeCodeAgent 落地 |
+| `linzihan <zihan@ZihanMacBook-Pro-14.local>` | 37 | 业务方法论核心贡献者:动态横纵推导、组词规则、列依赖、脚本展开策略、动态评估、目标指引和 1-5 分评分体系 |
+
+因此本报告按“作者贡献 -> 业务机制 -> 技术实现”组织,而不是按目录粗暴归类。
+
+---
+
+## 第二章:业务逻辑
+
+### 2.1 这个系统要解决的问题
+
+上游系统已经把小红书/社媒帖子拆成了结构化元素、分类、共现关系、pattern、sequence。BuildingSystemAgent 要解决的是下一步:如何把这些数据证据变成可执行的内容生产结果。
+
+它不是让模型凭空写一个标题或脚本,而是要求 Agent:
+
+1. 从真实数据里找可用元素和组合规律。
+2. 把元素封装成可追踪的 `CompositionItem`。
+3. 记录每个 item 的来源、推导关系、探索轨迹。
+4. 在评估反馈下迭代灵感点、目的点、关键点。
+5. 把最终选题继续展开成脚本段落、脚本元素、段落-元素关系和段落自然语言列。
+6. 把过程完整落库,供 GUI 查看、重试、复用和审计。
+
+业务上,它相当于把“数据分析结果”变成“选题策划工作台”和“脚本创作工作台”。
+
+### 2.2 上游前置流程的位置
+
+前置完成的流程包括内容解构、聚类、归一、元素分类、pattern mining 等。它们提供:
+
+1. 原始帖子、选题点、脚本段落、脚本元素。
+2. 全局分类树、全局元素库、元素映射。
+3. itemset、sequence、group pattern、共现关系。
+4. `pattern_mining_execution` 执行批次,比如 GUI 当前大量构建记录仍使用的 `Exec #401`。
+
+但这些流程在本报告中只承担输入背景。BuildingSystemAgent 不重新挖 pattern,而是在构建阶段调用已有 pattern、帖子、元素、脚本数据。
+
+PostgreSQL 只读核验也支持这个边界:`open_aigc.public` 中 `post` 有 66,974 行、`global_element` 有 290,864 行、`pattern_itemset` 有 449,216 行;这些是上游事实和 pattern 规模,不是 topic/script build 的业务结果表。
+
+### 2.3 选题构建:从需求到 CompositionItem,再到选题
+
+选题构建的业务对象是 `CompositionItem`。代码在 `models.py` 里直接写明“选题构建 - 以 CompositionItem 为中心的 CRUD 模型”,并说明“Agent 过程 = CRUD CompositionItem”。这不是命名细节,而是选题构建的业务抽象:
+
+1. `CompositionItem` 代表选题里的一个组成部分,可以来自元素、分类、pattern、帖子、外部搜索或用户输入。
+2. 每个 item 有生命周期:创建、保留、更新、关联、丢弃。
+3. item 之间可以记录推导关系,形成因果链或组合链。
+4. item source 记录证据来源,避免最后选题无法解释。
+5. item exploration trace 记录探索轨迹,保留 Agent 如何从数据走到结论。
+
+选题构建的典型业务流程是:
+
+| 阶段 | 业务动作 | 生成物 |
+|---|---|---|
+| 需求解析 | 读取用户需求、账号名、选题方向、策略、模型配置 | `topic_build_record` |
+| 数据探索 | 调用 pattern 工具、帖子工具、元素/分类工具、外部搜索工具 | item source、tool log、search log |
+| 灵感构建 | 基于横向扩展和纵向推理找灵感元素 | 灵感类 `CompositionItem` |
+| 灵感评估 | 根据动态维度判断灵感是否满足方向 | `inspiration_evaluation_config`、评估反馈 |
+| 目的点/关键点构建 | 继续下钻元素,形成目的和关键点 | 目的/关键点 `CompositionItem`、`topic_build_point` |
+| 组词与选题定稿 | 只允许基于 element 级 item 组词,再生成最终结果 | `topic_build_topic.result` |
+| 审计与展示 | 保存日志、token、成本、状态、耗时 | `topic_build_log`、GUI 详情 |
+
+这里的关键不是“模型写了一个选题”,而是 Agent 通过可追踪 item,把数据证据转成结构化选题。
+
+### 2.4 脚本构建:从选题到结构化创作表
+
+脚本构建接在选题构建之后。输入不是自由文本标题,而是完整的选题详情:topic、composition items、points、relations、动态评估配置,以及可选的参考帖子/脚本。
+
+脚本构建的核心产物是“创作表”,包括:
+
+1. `script_build_record`:一次脚本构建任务。
+2. `script_build_paragraph`:段落行,含 `name`、`content_range`、`theme`、`form`、`function`、`feeling`、`description`、`full_description` 等列。
+3. `script_build_element`:脚本元素,区分实质/形式等维度。
+4. `script_build_paragraph_element`:段落与元素关系。
+5. `script_build_decision_trace`:每一步为什么这么构建、用了什么数据、影响了哪些对象。
+
+业务方法上,脚本构建不是一次性生成文章,而是按展开方法逐步填表:
+
+| 展开方法 | 业务含义 | 主要产物 |
+|---|---|---|
+| 之间展开 | 从选题表到创作表,先找到脚本元素,通常不直接产出自然语言段落列 | `script_build_element`、元素点列 |
+| 段间展开 | 规划段落结构、段落顺序、段落功能和内容范围 | `script_build_paragraph` |
+| 段内展开 | 在单个段落内部填充 theme/form/function/feeling/description/full_description | 段落多列内容 |
+| 之间+段间展开 | 一步从选题到分段结构,先写元素点列,再写自然语言列 | 段落骨架、元素点列、自然语言列 |
+
+prompt 明确规定:元素点列必须先于自然语言列写入;`theme_elements` 先于 `theme`,`form_elements` 先于 `form`,`function_elements` 先于 `function`,`feeling_elements` 先于 `feeling`。`full_description` 是二级自然语言列,依赖其他列综合生成。
+
+MySQL 只读核验显示,截至 2026-05-29 核验时,`script_build_id=269` 是成功状态,生成 4 个段落、10 个元素;其 `script_build_decision_trace` phase 为 `段内展开_columns`,决策摘要是批量补全所有段落的自然语言列和完整执行描述。这说明数据库里的真实运行记录与 prompt 中的脚本展开机制一致。
+
+### 2.5 linzihan 的业务方法论
+
+`linzihan` 的核心贡献主要在 prompt 层。不要因为它不是 Python 函数就低估它:对 Agent 系统来说,prompt 里的工作流约束、判断标准和字段依赖,就是业务逻辑。
+
+关键方法论包括:
+
+1. **动态横纵推导**  
+   灵感和目的/关键点不是简单搜索关键词。横向扩展用于发现更多方向,纵向推理用于从 category 继续下钻到具体 element。对应提交如 `598fe6b 多轮动态横纵推导`。
+
+2. **组词只用元素**  
+   category 只能作为探索入口,不能直接进入词组结果。`topic_purpose_keypoint_build_agent.md` 规定“只使用 element 级 items 组词”,且词组里的每个实义词必须能追溯到参与组词 item 的 `name` 字段。对应提交如 `9f3273f 组词只用元素`、`26fed4e 两个评估修改:组词只用元素`。
+
+3. **禁止跨点类型混组**  
+   目的词组只能由目的点 item 组成,关键词组只能由关键点 item 组成,不能把目的点和关键点混进同一词组。这保证最终选题结构不是漂亮但失真的混搭句。
+
+4. **先推导点,再细化,再串联成句**  
+   脚本 prompt 要求先选择展开方法,再通过数据和元素点落库,最后把元素点串成自然语言列。这是防止模型直接写自然语言、跳过证据结构的关键约束。
+
+5. **列依赖规则**  
+   `script_build_system.md` 中定义了 `theme` 依赖 `theme_elements`,`form` 依赖 `form_elements + theme + function`,`full_description` 依赖所有其他列。首次产出必须遵守依赖,完善迭代可以基于已有列做补充,但不能凭空重写。
+
+6. **动态维度评估与 1-5 分评分**  
+   选题主 Agent 在构建前为动态维度打 1-5 分,分数表达该维度对本次选题的重要程度,而不是当前结果质量分。灵感评估和脚本评估都读取这个配置,高分维度标准更严格。对应提交如 `716631c 动态维度评估`、`3be86d0 动态维度改成打分`、`a265718 脚本评估同步1-5分打分`。
+
+7. **评估只给目标和边界,不替主 Agent 写答案**  
+   `script_build_eval_agent.md` 的评估结果会影响主 Agent 下一步动作,但评估 Agent 不应该输出具体工具参数、具体修复内容或自己编造的数据。对应提交如 `1cb13f9 评估维度大修改&目标指引推导`。
+
+### 2.6 liuzhiheng 的系统化实现
+
+`liuzhiheng` 的贡献是把上述业务方法论落成可运行系统。关键实现线包括:
+
+1. **Agent 拆分与运行框架**  
+   `TopicBuildAigcAgent.py` 注册 `topic_build_main`、`topic_inspiration_builder`、`topic_purpose_keypoints_builder`、`topic_multi_path_recall` 等 preset,并通过 `AgentRunner`、`RunConfig`、`FileSystemTraceStore` 执行。选题构建 trace 写到 `.trace/topic_build/{build_id}`。
+
+2. **AigcAgent / ClaudeCodeAgent 双路径**  
+   选题和脚本都有 AigcAgent 运行方式,同时保留 ClaudeCodeAgent 路径。`ScriptClaudeCodeBuildAgent.py` 使用四层 prompt 架构:System Prompt、Workflow、strategy、task;工具定义统一来自 schema。
+
+3. **工具 schema 和工具日志**  
+   topic/script 构建工具通过 JSON schema 和工具函数统一管理,包括 pattern 工具、外部搜索、参考脚本搜索、item CRUD、paragraph CRUD、evaluate、record_decision 等。
+
+4. **数据库模型和写入链路**  
+   `models.py` 覆盖 topic build、script build、prompt、strategy、外部搜索日志等表;`pattern_server.py` 启动时调用 `pattern_service.ensure_tables()`,说明这些表是服务运行面的组成部分。
+
+5. **FastAPI 和 GUI 工作台**  
+   `pattern_server.py` 提供 `/build` 到 `/build/topic` 的入口、topic build 和 script build 的创建、列表、详情、prefill、retry、delete、log、overview API。前端由 `static/js/build.js`、`topic-build-detail.js`、`script-build-detail.js` 承载。
+
+6. **模型、重试、日志、成本和可观测性**  
+   代码支持 OpenRouter / Claude / Gemini / Qwen 等模型映射,记录 token、cost、耗时、状态、错误、日志,并把构建历史显示在 GUI。
+
+关键提交线索包括:
+
+| 时间 | 提交 | 业务意义 |
+|---|---|---|
+| 2026-04-17 | `953040a 选题构建,子agent架构调整` | 选题构建从单 Agent 走向子 Agent 架构 |
+| 2026-04-20 | `5a9097c 选题tree、pattern数据工具日志记录`、`7c1a84f 选题tree、pattern数据工具切换到API` | pattern/树工具服务化和可观测 |
+| 2026-04-24 | `0b1d238 脚本构建工具定义,统一在schemas.json中` | 脚本工具 schema 化 |
+| 2026-04-28 | `e8078da 选题构建:多路召回/比较评估` | 多路召回成为选题证据机制 |
+| 2026-04-30 | `d217f93 脚本构建以目标指引迭代改造` | 评估目标驱动脚本迭代 |
+| 2026-05-07 | `75b9e35 脚本构建:增加 主题点、形式点、作用点、感受点 四列` | 创作表字段更贴合段内展开 |
+| 2026-05-09 | `9671266 脚本构建:新增 search_post_scripts_by_topic_name 工具` | 用选题名召回参考脚本 |
+
+---
+
+## 第三章:技术逻辑
+
+### 3.1 服务入口和页面/API
+
+核心服务入口在 `aiddit/pattern/patter_from_global_and_build/pattern_server.py`。
+
+关键路由:
+
+| 路由 | 作用 |
+|---|---|
+| `/build` | 旧入口,重定向到 `/build/topic` |
+| `/build/{section}` | 构建中心页面,承载选题构建和脚本构建列表 |
+| `/api/pattern/topic_builds` | 创建和查询选题构建 |
+| `/api/pattern/topic_builds/{build_id}` | 选题构建详情 |
+| `/api/pattern/topic_builds/{build_id}/prefill` | 从历史构建预填 |
+| `/api/pattern/topic_builds/{build_id}/retry` | 重试选题构建 |
+| `/api/pattern/topic_builds/{build_id}/log` | 查看选题构建日志 |
+| `/api/pattern/script_builds` | 创建和查询脚本构建 |
+| `/api/pattern/script_builds/{script_build_id}` | 脚本构建详情 |
+| `/api/pattern/script_builds/{script_build_id}/prefill` | 从历史脚本构建预填 |
+| `/api/pattern/script_builds/{script_build_id}/retry` | 重试脚本构建 |
+| `/api/pattern/script_builds/{script_build_id}/log` | 查看脚本构建日志 |
+| `/api/pattern/script_builds/overview/{topic_build_id}` | 选题下脚本构建概览 |
+
+GUI 验证结果:浏览器打开 `https://pattern.aiddit.com/build/topic` 后,页面标题为“构建中心”,同页出现“选题构建”“脚本构建”“Exec #401”“AigcAgent”“gemini-3-flash-preview”等内容,并异步加载构建历史。截至 2026-05-29 核验时,页面记录包括 topic build `1116`、`1115` 等。
+
+### 3.2 Agent 执行技术组件
+
+本项目有两套主要 Agent 执行形态:
+
+| 执行形态 | 文件 | 作用 |
+|---|---|---|
+| Topic AigcAgent | `TopicBuildAigcAgent.py` | 选题构建主运行链路,支持 subagent、trace、模型配置和 usage 汇总 |
+| Topic ClaudeCodeAgent | `TopicBuildClaudeCodeAgent.py` | Claude Code SDK / MCP 风格的选题构建链路 |
+| Script AigcAgent | `ScriptBuildAigcAgent.py` | 脚本构建主运行链路,控制工具调用、评估与 trace |
+| Script ClaudeCodeAgent | `ScriptClaudeCodeBuildAgent.py` | Claude Code SDK 风格脚本构建,四层 prompt 架构 |
+
+技术上使用:
+
+1. `AgentRunner` / `RunConfig`:执行主 Agent 和子 Agent。
+2. `ToolRegistry`:注册工具。
+3. `FileSystemTraceStore`:写本地 `.trace` 文件。
+4. OpenRouter 模型映射:兼容 Claude、Gemini、Qwen 等 UI 模型名。
+5. prompt/version:从数据库和本地 prompt 文件加载运行提示词。
+6. strategy/version:从数据库注入业务策略。
+7. tool schema JSON:统一工具名称、描述和参数约束。
+
+`.trace` 是 Agent runtime 执行轨迹,不等同于业务数据库。业务结果仍以 `open_aigc_pattern` 的 topic/script build 表为准。
+
+### 3.3 工具层:从证据获取到业务写表
+
+工具层分为 topic build 工具和 script build 工具。
+
+Topic build 主要工具职责:
+
+1. 创建 / 更新 / 查询 / 丢弃 `CompositionItem`。
+2. 创建 item relation,记录推导关系。
+3. 创建 item source,记录证据来源。
+4. 查询 pattern、分类、元素、帖子。
+5. 外部搜索并落 `external_search_case_log`。
+6. 保存灵感动态评估配置。
+7. 构建目的点、关键点和最终 topic。
+8. 执行灵感评估和整体评估。
+
+Script build 主要工具职责:
+
+1. 读取 topic detail。
+2. 查询参考帖子和参考脚本,包括 `search_post_scripts_by_topic_name`。
+3. 创建 / 更新 / 停用脚本段落。
+4. 创建 / 更新脚本元素。
+5. 批量建立段落-元素关系。
+6. 批量更新段落列。
+7. 调用 `evaluate_script_build`。
+8. 调用 `record_decision` 写入 `script_build_decision_trace`。
+
+这层把 prompt 中的业务步骤约束转化成可执行的工具动作,并把动作结果写入数据库。
+
+### 3.4 数据库与表分层
+
+#### 3.4.1 `open_aigc_pattern`:本项目运行产物主库
+
+MySQL `open_aigc_pattern` 是本项目 topic/script build 工作台的主库。只读核验表明核心表规模如下:
+
+| 表 | 行数 | 说明 |
+|---|---:|---|
+| `topic_build_record` | 1,093 | 选题构建任务 |
+| `topic_build_topic` | 1,264 | 选题结果 |
+| `topic_build_composition_item` | 22,579 | 选题组成 item |
+| `topic_build_item_source` | 23,504 | item 证据来源 |
+| `topic_build_item_relation` | 19,055 | item 推导关系 |
+| `topic_build_item_exploration_trace` | 15,466 | item 探索轨迹 |
+| `topic_build_point` | 7,369 | 灵感点、目的点、关键点 |
+| `topic_build_point_item_relation` | 15,994 | point 与 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 | 脚本构建决策轨迹 |
+| `script_build_log` | 264 | 脚本构建日志 |
+| `external_search_case_log` | 12,043 | 外部搜索缓存/日志 |
+| `prompt` | 9 | prompt 业务类型 |
+| `prompt_version` | 125 | prompt 版本 |
+| `build_strategy` | 56 | 构建策略 |
+| `build_strategy_version` | 242 | 策略版本 |
+
+这些表是本项目生成物的直接证据。
+
+#### 3.4.2 `open_aigc.public`:上游事实库
+
+PostgreSQL `open_aigc.public` 是上游事实库和 pattern 事实库。只读核验表明:
+
+| 表 | 行数 | 本项目中的角色 |
+|---|---:|---|
+| `post` | 66,974 | 上游帖子事实 |
+| `post_decode_topic_point_element` | 1,308,993 | 上游选题点元素 |
+| `post_script_paragraph` | 12,164 | 上游脚本段落 |
+| `post_script_element` | 47,951 | 上游脚本元素 |
+| `post_script_paragraph_field_element` | 177,856 | 上游段落字段元素 |
+| `global_category` | 4,944 | 上游分类树 |
+| `global_element` | 290,864 | 上游元素库 |
+| `element_classification_mapping` | 1,123,373 | 上游元素归一映射 |
+| `pattern_mining_execution` | 7 | 上游 pattern 执行批次 |
+| `pattern_itemset` | 449,216 | 上游 itemset pattern |
+| `pattern_script_sequence` | 2,753 | 上游 script sequence |
+
+`#401/#581` 的状态漂移也属于上游 pattern execution 证据:
+
+| execution | snapshot_date | is_current | status | post_count | category_count | element_count | itemset rows | script_sequence rows |
+|---:|---|---|---|---:|---:|---:|---:|---:|
+| `#401` | 2026-04-23 | true | failed | 12,448 | 3,995 | 315,389 | 104,385 | 1,723 |
+| `#581` | 2026-05-09 | false | success | 13,265 | 1,932 | 290,467 | 53,897 | 0 |
+
+这解释了一个容易混淆的现象:GUI 和 build 记录大量使用 `execution_id=401`,但 `#401` 在上游 pattern execution 表里是 `failed + is_current=true`;`#581` 是截至 2026-05-29 核验时可见的成功执行之一,但 `is_current=false`。这不是 BuildingSystemAgent 自身构建状态,而是上游 pattern 批次状态。
+
+### 3.5 写表链路
+
+Topic Build 写表链路:
+
+1. 创建任务:写 `topic_build_record`。
+2. 创建 topic 容器:写 `topic_build_topic`。
+3. 探索数据:写 `topic_build_composition_item`。
+4. 记录证据:写 `topic_build_item_source`。
+5. 记录推导:写 `topic_build_item_relation`。
+6. 记录探索:写 `topic_build_item_exploration_trace`。
+7. 生成点位:写 `topic_build_point` 和 `topic_build_point_item_relation`。
+8. 定稿:更新 `topic_build_topic.result`,更新 `topic_build_record.status/result/topic_count/token/cost`。
+9. 日志:写 `topic_build_log`。
+
+Script Build 写表链路:
+
+1. 创建任务:写 `script_build_record`。
+2. 创建段落:写 `script_build_paragraph`。
+3. 创建元素:写 `script_build_element`。
+4. 建立关系:写 `script_build_paragraph_element`。
+5. 记录决策:写 `script_build_decision_trace`。
+6. 评估迭代:读取 snapshot,调用 `evaluate_script_build`,按目标指引继续工具调用。
+7. 定稿:更新 `script_build_record.status/result/paragraph_count/element_count/token/cost`。
+8. 日志:写 `script_build_log`。
+
+### 3.6 GUI 展示和实际运行样例
+
+GUI 的 `/build/topic` 是同页工作台,承载:
+
+1. 选题构建列表。
+2. 脚本构建列表。
+3. 执行批次 `Exec #401`。
+4. Agent 类型,如 `AigcAgent`。
+5. 模型名,如 `gemini-3-flash-preview`。
+6. 状态、topic 数、成本、时间、耗时。
+7. 详情页、日志、prefill、retry 等操作入口。
+
+MySQL topic build 样例(截至 2026-05-29 核验时):
+
+| build_id | execution_id | status | agent | topic_count | input_tokens | output_tokens | cost | 时间 |
+|---:|---:|---|---|---:|---:|---:|---:|---|
+| 1116 | 401 | success | AigcAgent | 1 | 2,342,981 | 26,438 | 1.2508 | 2026-05-26 13:52:05 |
+| 1115 | 401 | success | AigcAgent | 1 | - | - | 1.7848 | 2026-05-25 19:31:51 |
+| 1114 | 401 | success | AigcAgent | 1 | - | - | 1.3816 | 2026-05-25 |
+
+MySQL script build 样例(截至 2026-05-29 核验时):
+
+| script_build_id | execution_id | topic_build_id | status | agent | paragraph_count | element_count | cost | 时间 |
+|---:|---:|---:|---|---|---:|---:|---:|---|
+| 269 | 401 | 1103 | success | AigcAgent | 4 | 10 | 0.2063 | 2026-05-25 19:37:11 |
+| 268 | 401 | 1108 | success | AigcAgent | 4 | 10 | 0.5768 | 2026-05-25 |
+| 267 | 401 | 1090 | success | AigcAgent | 4 | 15 | 1.2163 | 2026-05-25 |
+
+`script_build_decision_trace` 样例显示,截至 2026-05-29 核验时,`script_build_id=269` 的 phase 包括:
+
+1. `段间展开_structure`
+2. `之间展开_elements`
+3. `段间展开_links`
+4. `段内展开_columns`
+
+这和脚本 prompt 中规定的展开工序一致。
+
+---
+
+## 第四章:数据证据
+
+### 4.1 Git 作者与文件证据
+
+`liuzhiheng` 高频改动文件集中在系统实现层:
+
+| 文件 | 业务含义 |
+|---|---|
+| `pattern_server.py` | FastAPI 路由、任务调度、详情 API、日志 API |
+| `models.py` | topic/script build 主库模型 |
+| `TopicBuildAigcAgent.py` | 选题 AigcAgent 执行 |
+| `TopicBuildClaudeCodeAgent.py` | 选题 ClaudeCodeAgent 执行 |
+| `ScriptBuildAigcAgent.py` | 脚本 AigcAgent 执行 |
+| `ScriptClaudeCodeBuildAgent.py` | 脚本 ClaudeCodeAgent 执行 |
+| `topic_build_agent_tools.py` | 选题工具层 |
+| `script_build_agent_tools.py` | 脚本工具层 |
+| `topic_build_tool_schemas.json` | 选题工具 schema |
+| `script_build_tool_schemas.json` | 脚本工具 schema |
+| `static/js/build.js` | 构建中心页面 |
+| `static/js/topic-build-detail.js` | 选题详情页 |
+| `static/js/script-build-detail.js` | 脚本详情页 |
+
+`linzihan` 高频改动文件集中在业务方法论:
+
+| 文件 | 业务含义 |
+|---|---|
+| `prompts/topic_build_main_agent.md` | 选题主流程、动态维度配置 |
+| `prompts/topic_inspiration_build_agent.md` | 灵感横纵推导和数据探索 |
+| `prompts/topic_inspiration_eval_agent.md` | 灵感动态维度评估 |
+| `prompts/topic_purpose_keypoint_build_agent.md` | 目的点/关键点构建与组词规则 |
+| `prompts/topic_eval_agent.md` | 目的点/关键点评估与组词就绪判断 |
+| `prompts/script_build_system.md` | 脚本展开方法、列依赖、创作表规则 |
+| `prompts/script_build_eval_agent.md` | 脚本评估、目标指引和动态上限维度 |
+
+### 4.2 MySQL `open_aigc_pattern` 样例证据
+
+数据库连接证据:
+
+1. `db_manager.py` 连接 `open_aigc_pattern`。
+2. Docker requirements 包含 `sqlalchemy==2.0.46`、`pymysql==1.1.2`。
+3. `pattern_server.py` 启动时调用 `ensure_tables()`。
+4. 表模型集中在 `models.py`。
+
+只读查询使用 `START TRANSACTION READ ONLY`,最后 `ROLLBACK`,未写库。
+
+业务对象样例(截至 2026-05-29 核验时):
+
+| 对象 | 样例 |
+|---|---|
+| topic build 样例 | `topic_build_record.id=1116`,`success`,`execution_id=401` |
+| topic 样例 | `topic_build_topic.id=1281`,build 1116,状态 `mature` |
+| item 样例 | `topic_build_composition_item.id=22741`,元素 `负能量传染现象` |
+| item source 样例 | `post_extract/post`,source `6913cafd000000000703402b` |
+| point 样例 | 目的点 `系统拆解情绪毒素机制以建立情绪免疫力` |
+| script build 样例 | `script_build_record.id=269`,`success`,4 段、10 元素 |
+| script element 样例 | `拟人化猫咪表情包视觉` |
+| decision trace 样例 | phase `段内展开_columns` |
+| topic log 样例 | build 1116,日志长度 327,934 字符 |
+| script log 样例 | script 269,日志长度 206,463 字符 |
+
+Prompt 和 strategy 版本证据:
+
+| 类型 | 数量 / 当前情况 |
+|---|---|
+| `prompt` | 9 个业务类型 |
+| `prompt_version` | 125 个版本 |
+| `script_build_system` | 当前版本 25 |
+| `script_build_eval_agent` | 当前版本 10 |
+| `topic_build_main_agent` | 当前版本 13 |
+| `topic_inspiration_build_agent` | 当前版本 24 |
+| `topic_inspiration_eval_agent` | 当前版本 11 |
+| `build_strategy` | 56 条 |
+| `build_strategy_version` | 242 条 |
+
+### 4.3 PostgreSQL `open_aigc` 样例证据
+
+PostgreSQL 核验是为了确认上游事实和 pattern 批次,不是为了把它写成本项目主体。
+
+关键结论:
+
+1. `open_aigc.public` 包含帖子、脚本段落、元素、分类、pattern 执行批次。
+2. 本项目通过工具读取这些数据作为构建输入。
+3. `#401` 当前在 pattern execution 里是 `failed + is_current=true`。
+4. `#581` 是 `success + is_current=false`。
+5. GUI 和 build 记录大量 `execution_id=401`,说明构建工作台历史与上游 current execution 状态存在漂移。
+
+### 4.4 GUI 证据
+
+已用浏览器打开 `https://pattern.aiddit.com/build/topic` 验证:
+
+1. 页面显示“构建中心”。
+2. 同页包含“选题构建”和“脚本构建”。
+3. 构建历史中显示 `Exec #401`。
+4. 截至 2026-05-29 核验时,topic build 显示 `1116`、`1115` 等记录。
+5. Agent 类型显示 `AigcAgent`。
+6. 模型显示 `gemini-3-flash-preview`。
+7. 页面异步加载历史列表,与 MySQL 核验时样例记录对应。
+
+### 4.5 Subagent 交叉核验结论
+
+本次使用多个 subagent 并行核验:
+
+| Subagent | 核验对象 | 结论 |
+|---|---|---|
+| A | `liuzhiheng` 作者提交与核心代码 | 其主线是把构建 Agent 落成系统工程:Agent、工具、DB、GUI、日志、模型配置 |
+| B | `linzihan` 作者提交与 prompt | 其主线是业务方法论:横纵推导、组词规则、列依赖、展开策略、动态评估 |
+| C | MySQL `open_aigc_pattern` | topic/script build 运行表有真实数据,核验时构建样例与 GUI 对齐 |
+| D | PostgreSQL `open_aigc.public` | 只作为上游事实库和 `#401/#581` 漂移证据 |
+| E | 报告边界 QA | 检查报告避免把前置流程写成主体,确认关键术语和证据齐备 |
+
+---
+
+## 第五章:容易误解和需要修正的点
+
+### 5.1 `pattern_global_v2` 的位置
+
+它提供上游分类树、元素库、pattern、sequence、debug API 等能力。在本报告语境里,它是输入来源,不是 BuildingSystemAgent 的业务核心。
+
+### 5.2 目录名容易误导
+
+`aiddit/pattern/patter_from_global_and_build` 这个目录名带有 `global`,也包含一些前置兼容代码。但本次分析的主体不是前置 pattern mining,而是其中的 topic/script build Agent 应用层。
+
+### 5.3 linzihan 的核心逻辑在 prompt 里
+
+业务规则并不都在 Python 函数中。对 Agent 系统而言,prompt 中的“必须先写元素点列”“组词只用 element”“动态维度 1-5 分”“评估只给目标指引”等约束,是实际控制 Agent 行为的业务逻辑。
+
+### 5.4 liuzhiheng 的核心价值是工程落地
+
+`liuzhiheng` 的提交把 prompt 方法论落成可运行系统:Agent 拆分、工具 schema、数据库模型、日志、GUI、重试、prefill、模型配置、外部搜索和 trace。这是 BuildingSystemAgent 从方法论到产品工作台的关键。
+
+### 5.5 `#401/#581` 不是 BuildingSystemAgent 自身状态
+
+`#401`、`#581` 是上游 pattern execution 状态。当前 DB 里 `#401` 是 `failed + is_current=true`,`#581` 是 `success + is_current=false`。但 topic/script build 记录大量使用 `execution_id=401` 并且自身是 `success`,这两层状态不能混为一谈。
+
+### 5.6 1-5 分不是结果质量分
+
+动态维度的 1-5 分表达“本次需求中这个维度的重要程度”。分数越高,评估时通过标准越严格。它不是说当前灵感或脚本质量得了几分。
+
+### 5.7 评估 Agent 不负责直接修复
+
+评估 Agent 输出问题、目标和边界,主 Agent 再根据评估结果选择工具和动作。评估 Agent 不应该编造修复内容,也不应该替主 Agent 指定具体工具参数。
+
+### 5.8 `.trace` 不是业务主库
+
+`aigc_agent_sdk/Agent/.trace` 或构建目录下 `.trace` 是运行轨迹文件,便于调试和 usage 汇总。真正的业务结果、历史、日志、决策和 GUI 数据来自 `open_aigc_pattern`。
+
+---
+
+## 附录:关键代码证据索引
+
+| 证据 | 路径 / 行号 |
+|---|---|
+| `CompositionItem` 中心模型 | `aiddit/pattern/patter_from_global_and_build/models.py:163` |
+| “Agent 过程 = CRUD CompositionItem” | `aiddit/pattern/patter_from_global_and_build/models.py:173` |
+| `topic_build_record` | `aiddit/pattern/patter_from_global_and_build/models.py:182` |
+| `TopicBuildCompositionItem` | `aiddit/pattern/patter_from_global_and_build/models.py:266` |
+| `build_strategy` / `build_strategy_version` | `aiddit/pattern/patter_from_global_and_build/models.py:373`、`:398` |
+| `prompt_version` | `aiddit/pattern/patter_from_global_and_build/models.py:431` |
+| `script_build_record` | `aiddit/pattern/patter_from_global_and_build/models.py:486` |
+| `script_build_decision_trace` | `aiddit/pattern/patter_from_global_and_build/models.py:602` |
+| `/build -> /build/topic` | `aiddit/pattern/patter_from_global_and_build/pattern_server.py:367` |
+| topic build 创建/列表/详情/log | `pattern_server.py:407`、`:633`、`:812`、`:1237` |
+| script build 创建/列表/详情/log | `pattern_server.py:1428`、`:1672`、`:1938`、`:2232` |
+| Topic AigcAgent trace | `TopicBuildAigcAgent.py:56` |
+| Topic subagent preset | `TopicBuildAigcAgent.py:121`、`:132`、`:145`、`:158` |
+| AgentRunner / FileSystemTraceStore | `TopicBuildAigcAgent.py:257`、`:294` |
+| Script AgentRunner / FileSystemTraceStore | `ScriptBuildAigcAgent.py:161`、`:179` |
+| Script evaluator model配置说明 | `ScriptBuildAigcAgent.py:60` |
+| 选题动态维度配置 | `prompts/topic_build_main_agent.md:41` |
+| 动态维度 1-5 分 | `prompts/topic_build_main_agent.md:64`、`prompts/topic_inspiration_eval_agent.md:31` |
+| 组词只用 element | `prompts/topic_purpose_keypoint_build_agent.md:341` |
+| 组词实义词追溯 item.name | `prompts/topic_purpose_keypoint_build_agent.md:349` |
+| 脚本展开 phase | `prompts/script_build_system.md:99` |
+| 之间展开 / 段间展开 | `prompts/script_build_system.md:226` |
+| 元素点列先于自然语言列 | `prompts/script_build_system.md:292` |
+| 段内展开 | `prompts/script_build_system.md:427` |
+| 列依赖规则 | `prompts/script_build_system.md:544` |
+| 选择展开方法 | `prompts/script_build_system.md:591` |
+
+---
+
+## 最终结论
+
+BuildingSystemAgent 的业务核心,是一个数据证据驱动的选题与脚本构建 Agent 系统。
+
+`linzihan` 贡献了业务推理方法论:如何从数据元素做横纵推导、如何约束组词、如何把选题展开成创作表、如何用动态维度和目标指引评估迭代。`liuzhiheng` 贡献了系统工程实现:把这些规则落成 Agent、工具、数据库、API、GUI、日志、模型配置和可追踪运行链路。
+
+前置的聚类、归一、pattern mining、`pattern_global_v2` 和 `open_aigc.public` 是这个系统的输入底座;`open_aigc_pattern` 中的 topic/script build 表、日志、decision trace 和 `/build/topic` GUI,才是 BuildingSystemAgent 本项目真正生成和运营的业务产物。

+ 200 - 0
data-clustering业务理解.md

@@ -0,0 +1,200 @@
+# 聚类业务流程分析
+
+核对日期:2026-05-28;MySQL build 库口径补正:2026-05-29
+适用范围:`image_article_comprehension` 项目的聚类、全局归一和分类树沉淀流程。
+详细字段和统计见同目录下 `data_clustering_statistic.xlsx`。
+
+## 1. 一句话结论
+
+聚类不是最终业务结果,它是把大量分散、重复、表达不一致的内容元素先归并成相似组,再辅助分类 agent 生成“全局分类树、全局标准元素、原始元素映射”的中间加工过程。
+
+补充一个容易混淆的边界:这条文档讲的是 Excel 里的聚类辅助分类工程链路,不等于 `scripts/run_classify.py` 的硬前置。`run_classify.py` 可以直接从源表 SQL 聚合未分类元素并调用分类 agent;DBSCAN 主要用于组织相似候选簇和辅助批处理。
+
+最终给业务使用的不是 DBSCAN 聚类本身,而是:
+
+| 业务结果 | 数据表 | 业务含义 |
+| --- | --- | --- |
+| 全局分类树 | `global_category` | 内容元素应该挂到哪类业务概念下 |
+| 全局标准元素 | `global_element` | 把多个相似原始元素归一成一个标准元素 |
+| 原始到全局的映射 | `element_classification_mapping` | 记录每条原始元素最终对应哪个全局元素和分类节点 |
+
+这条聚类链路只涉及 PostgreSQL `open_aigc`。`open_aigc_pattern` 是后续选题/脚本构建工作台库和旧 `topic_pattern_*` 兼容层;2026-05-29 通过真实内网地址 `192.168.202.204:3306` 只读复核成功,但它不参与聚类、去重、分类树写入。
+
+## 2. 为什么需要聚类
+
+上游解构会从图文、脚本和段落里抽出很多“元素”。这些元素来自不同位置,表达方式也不统一。
+
+例如,同一个业务含义可能在不同帖子里被写成不同叫法;也可能同名但来自不同业务维度,不能混在一起。直接拿这些原始元素做 pattern 或构建,会导致分类混乱、重复统计、相似内容被拆散。
+
+所以聚类业务要解决三件事:
+
+1. 先把明显重复或相似的原始元素收拢。
+2. 再按业务维度形成可分类的相似组。
+3. 最后由分类 agent 把它们归入统一的分类树和标准元素库。
+
+## 3. 聚类使用哪些原始数据
+
+聚类入口的原始元素来自 `open_aigc` 的 3 张表:
+
+| 原始元素表 | 来自哪里 | 主要承载的业务元素 |
+| --- | --- | --- |
+| `post_decode_topic_point_element` | 图文选题点解构 | 选题里提到的实体、形式、意图等元素 |
+| `post_script_element` | 脚本级解构 | 脚本整体主题、实体、表现形式等元素 |
+| `post_script_paragraph_field_element` | 脚本段落字段解构 | 段落里的主题、形式、作用、感受等元素 |
+
+这些表保留的是“原始事实”。聚类和分类不会覆盖它们,而是在后续表里建立归一关系。
+
+## 4. 9 组业务处理口径
+
+这里的“9 组”不是 9 张表,而是 `source_type + source_table` 的 9 个处理组合。
+
+`source_type` 表示业务维度,也决定进入哪套分类树;`source_table` 表示元素来自哪张原始表,也决定原始 ID 的命名空间。
+
+| # | source_type | source_table | 业务含义 |
+| --- | --- | --- | --- |
+| 1 | `实质` | `post_decode_topic_point_element` | 选题点里的实体、对象、主题类元素 |
+| 2 | `形式` | `post_decode_topic_point_element` | 选题点里的表达形式、内容形态类元素 |
+| 3 | `意图` | `post_decode_topic_point_element` | 选题点里的内容意图、吸引点、表达目的 |
+| 4 | `实质` | `post_script_element` | 脚本整体的主题、实体、对象类元素 |
+| 5 | `形式` | `post_script_element` | 脚本整体的表现形式类元素 |
+| 6 | `实质` | `post_script_paragraph_field_element` | 段落字段里的主题类元素 |
+| 7 | `形式` | `post_script_paragraph_field_element` | 段落字段里的形式类元素 |
+| 8 | `作用` | `post_script_paragraph_field_element` | 段落字段里的功能、作用、推动剧情或表达目的 |
+| 9 | `感受` | `post_script_paragraph_field_element` | 段落字段里的情绪、观感、氛围体验 |
+
+需要注意:`post_decode_topic_point_element` 里也已经有 topic 侧 `感受` 原始数据,但当前聚类 9 组还没有把它纳入主口径。
+
+## 5. 业务处理顺序
+
+### 第一步:原始元素进入去重范围
+
+系统先从 3 张原始元素表中取元素名、元素描述、帖子 ID、元素类型等信息。
+
+这一步的业务意义是确定“哪些原始元素可以进入聚类”。不同来源和不同业务维度不会直接混在一起,例如选题里的 `实质` 不会和段落里的 `作用` 放在同一组里聚。
+
+### 第二步:生成 `element_dedup_group`
+
+系统按业务维度、来源表和标准化后的元素名做去重,把多个相同或高度重复的原始元素收成一个去重组。
+
+`element_dedup_group` 不是最终分类结果,而是聚类前的收缩层。它主要回答:
+
+- 这批原始元素里,哪些名字可以先视为同一个代表项。
+- 一个代表项背后包含多少原始元素。
+- 这个代表项后续应该拿去做向量、距离计算和聚类。
+
+这一步会形成 9 组 `source_type + source_table` 口径,每组都有自己的代表元素和成员元素。
+
+### 第三步:生成本地 source embedding cache
+
+去重之后,系统会给代表元素生成或复用向量。
+
+从业务上看,向量不是给人工直接看的结果,而是为了判断“两个元素语义上有多接近”。如果某个元素已经被分类过,系统可以复用已有全局元素向量;如果没有,就补充生成本地缓存。
+
+这一步的产物主要在本地 cache 中,不是独立数据库结果表。
+
+### 第四步:生成本地距离矩阵
+
+有了向量之后,系统会在同一个业务组内计算元素之间的距离。
+
+距离矩阵的业务意义是:把“看起来叫法不同,但语义很近”的元素找出来。它只在同一个 `source_type + source_table` 组合内部比较,不跨业务维度混算。
+
+这一步同样主要落本地缓存,不是最终业务表。
+
+### 第五步:DBSCAN 找出相似元素簇
+
+DBSCAN 会根据距离矩阵把相似元素聚成簇,同时留下无法归组的噪音点。
+
+这一层的业务作用是给分类 agent 或人工处理提供候选批次:一簇元素往往应该被判断成同一个标准元素,或者挂到相近的分类节点。
+
+当前可跑路径主要返回内存聚类结果;旧的归档路径可能生成 `global_clusters_*.json`。因此不能把这个 JSON 写成当前必经的数据库产物。
+
+### 第六步:形成待分类 batch
+
+系统会把聚类结果展开回原始元素,过滤掉已经分类过的元素,再形成待分类批次。
+
+这一步把“相似元素簇”变成分类 agent 能处理的业务输入,通常包含:
+
+- 代表元素
+- 原始元素名
+- 原始元素描述
+- 来源表
+- 原始元素 ID
+- 所属聚类簇
+- 同组成员列表
+
+这些 batch 的作用是组织分类任务,不是最终业务结果。
+
+### 第七步:分类 agent 做全局归一
+
+分类 agent 会结合已有分类树和相似元素信息,判断当前元素应该挂到哪里。
+
+它处理的是业务归一问题,而不只是聚类问题:
+
+1. 如果已有合适分类节点,就复用。
+2. 如果没有合适分类节点,就创建或调整分类节点。
+3. 如果已有同义或近义的全局元素,就复用 `global_element`。
+4. 如果没有合适全局元素,就创建新的标准元素。
+5. 最后把每条原始元素映射到对应的全局元素和分类节点。
+
+## 6. 最终沉淀的数据
+
+分类完成后,业务结果主要沉淀到 3 张核心表:
+
+| 表 | 写入什么 | 业务作用 |
+| --- | --- | --- |
+| `global_category` | 分类节点、父子关系、分类路径、业务维度 | 形成稳定的业务分类树 |
+| `global_element` | 标准元素名、描述、所属分类、出现次数 | 形成可复用的全局元素库 |
+| `element_classification_mapping` | 原始元素 ID 到全局元素和分类节点的映射 | 保留原始数据和全局体系之间的关系 |
+
+辅助表还包括分类执行记录、分类日志、分类状态、分类和元素向量等。这些辅助表服务于追踪、复用和后续相似搜索,不是业务主结果。
+
+## 7. 全局归一怎么理解
+
+“全局归一”不是把原始表里的元素改掉,而是在旁边建立一层统一解释。
+
+关系可以这样理解:
+
+```text
+原始元素
+-> element_dedup_group 先减少重复
+-> 聚类找到相似元素组
+-> 分类 agent 判断业务归属
+-> global_element 形成标准元素
+-> global_category 确定分类树位置
+-> element_classification_mapping 保存原始元素到全局体系的映射
+```
+
+所以一条原始元素仍然保留在原始表里;业务使用时可以通过映射表知道它对应哪个标准元素、属于哪条分类路径。
+
+如果走 `run_classify.py` 主入口,上面的 `element_dedup_group -> 聚类` 可以被绕过:它会直接按源表中的元素名/类型做 SQL 聚合,形成待分类 batch,再由 agent 写入 global 三表。也就是说,聚类链路真实存在,但它是辅助分类路径,不是所有分类执行的必经路径。
+
+## 8. 后续业务怎么使用
+
+聚类和分类沉淀出的全局体系,会成为后续 pattern v2 和构建应用的基础。
+
+后续链路大致是:
+
+```text
+全局分类树 + 全局元素 + 原始元素映射
+-> pattern v2 快照和挖掘
+-> pattern 查询/API
+-> 选题构建、脚本构建、素材组织
+```
+
+这里的 pattern v2 指狭义的快照/挖掘/API:它读取 `global_category`、`global_element`、`element_classification_mapping`,生成 `pattern_mining_*` 快照和 pattern 结果;不反向生成 global 三表。如果口头把整个 `pattern_global_v2` 服务都叫 Pattern V2,那么其中分类库阶段会写 global 三表,但那不是 daily pattern mining 阶段。
+
+这里要区分边界:
+
+- `open_aigc` 承担原始元素、去重、聚类辅助、分类树、全局元素和 pattern v2 主事实。
+- `open_aigc_pattern` 承担后续选题/脚本构建工作台记录和旧 `topic_pattern_*` 兼容层。
+- `open_aigc_pattern` 不参与聚类本身,也不写 `global_category`、`global_element`、`element_classification_mapping`。
+
+## 9. 当前业务口径需要注意
+
+1. 聚类不是最终分类树,只是辅助把相似元素组织成更容易处理的批次。
+2. `element_dedup_group` 是一张表里的 9 个处理组合,不是 9 张去重表。
+3. embedding、距离矩阵、DBSCAN 结果大量是本地缓存或内存中间态,不能当成最终业务表。
+4. 当前 topic 侧 `感受` 原始数据存在,但没有纳入现有 9 组聚类主口径。
+5. 分类 agent 产出的最终业务关系是“原始元素 -> 全局标准元素 -> 分类树节点”。
+6. 后续选题和脚本构建会消费分类和 pattern 结果,但构建库不是聚类库。
+7. `global_category/global_element/element_classification_mapping` 是分类库链路的产物;狭义 Pattern V2 是下游快照和挖掘消费者。

BIN
data_clustering_statistic.xlsx


BIN
data_full_statistic.xlsx


BIN
demand_engineering_statistic.xlsx


+ 171 - 0
demandagent业务理解.md

@@ -0,0 +1,171 @@
+从产品/业务角度看,DemandAgent 做的不是“写内容”,也不是“找热点”,而是:
+
+**把已经被解构过、验证过表现的内容供给,整理成一批可被下游寻找和生产系统消费的“需求”。**
+
+它像一个“需求池编辑 + 数据策略员”。
+
+**整体数据流**
+```text
+已有内容供给
+→ 内容被解构成元素
+→ 元素被聚类成分类树和组合模式
+→ 结合内容表现算权重
+→ DemandAgent 判断哪些元素/组合能变成需求
+→ 输出需求池
+→ 下游寻找 Agent / 生产 Agent 使用
+```
+
+**1. 先决定今天要为谁生成需求**
+每天系统先看:哪些二级品类存在供需缺口,哪些方向值得补内容。
+
+比如今天发现:
+
+- `迷信祝福`
+- `贪污腐败`
+- `社会风气`
+- `罕见画面`
+
+这些品类有缺口或值得继续挖,DemandAgent 就为这些方向生成需求。
+
+这里的业务问题是:
+
+> 哪些内容方向现在值得生产更多?
+
+**2. 再拿已有内容作为证据**
+DemandAgent 不凭空想需求。它会先看已有内容里已经发生过什么。
+
+不同业务来源有不同入口:
+
+- `piaoquan`:看票圈里某个品类下已经聚类好的内容。
+- `全局树`:从全局内容结构里找更泛化的需求点。
+- `changwen`:看某些长文账号过去 30 天哪些内容表现好。
+- `zengzhang`:看增长合作方的视频表现。
+
+这些内容不是原始视频本身,而是上游已经处理过的“内容结构”。
+
+**3. 把内容拆成可理解的业务元素**
+上游解构系统已经把每条内容拆成三类选题点:
+
+- 灵感点:内容为什么吸引人。
+- 目的点:用户看它想满足什么。
+- 关键点:内容成立的核心信息。
+
+每个点下面又分三类元素:
+
+- 实质:讲什么,比如腐败案件、命理信仰、历史事件。
+- 形式:怎么讲,比如对比、警示、故事化、强情绪标题。
+- 意图:满足什么心理,比如求安心、求真相、求警醒。
+
+DemandAgent 消费的就是这些元素。
+
+**4. 看哪些元素经常一起出现**
+它不是只看单个词,而是会看组合。
+
+比如某些内容里经常同时出现:
+
+```text
+命理信仰 + 经验忠告
+仪式行为 + 特定时期习俗
+腐败案件 + 证据文书 + 警示表达
+```
+
+这些组合如果在多条内容里反复出现,就说明它可能不是偶然,而是一种稳定的内容需求模式。
+
+业务上这一步是在回答:
+
+> 用户不是只对一个词感兴趣,而是对某种内容组合感兴趣。
+
+**5. 再用表现数据给这些元素打分**
+DemandAgent 会看这些元素背后的内容表现。
+
+不同来源的权重逻辑不同:
+
+- 票圈内容主要看 ROV、回流、曝光等表现。
+- 长文和增长内容主要看真实播放、曝光等转化表现。
+- 品类调度会看供需 gap,也就是这个方向到底缺不缺内容。
+
+所以一个元素能不能变成需求,不只是看它出现过,还要看:
+
+```text
+它背后的内容有没有表现
+它是否属于当前缺内容的方向
+它是否能被内容满足
+```
+
+**6. Agent 最后做业务判断**
+到了这一步,LLM 才真正介入。
+
+但它不是自由发挥,而是基于前面的证据做判断:
+
+- 高权重元素能不能单独成为需求?
+- 高权重分类能不能代表用户真实兴趣?
+- 几个经常共现的元素组合,能不能形成一个更具体的需求?
+- 这个词是不是太空、太泛、太不像用户需求?
+
+它的判断标准是:
+
+```text
+需求 = 人的渴求 × 内容的可满足性
+```
+
+比如:
+
+- `祈福`:有人有心理诉求,内容可以满足,所以可以是需求。
+- `命理信仰,经验忠告`:更具体,可能代表用户想看“命理/民俗里的生活建议”。
+- `仪式行为,特定时期习俗`:代表节日、节点、习俗类内容需求。
+
+**7. 最终输出什么**
+最终它不是输出文章,也不是输出视频脚本,而是输出“需求池”。
+
+一条需求大概包含:
+
+- 需求名:比如 `祈福`
+- 所属品类:比如 `迷信祝福`
+- 生成理由:为什么这个需求成立
+- 建议描述:下游应该怎么理解这个需求
+- 权重分:它背后的内容表现强不强
+- 关联视频:这个需求来自哪些已有内容证据
+
+这些结果会进入:
+
+```text
+demand_content
+dwd_multi_demand_pool_di
+feature_point_data(全局树场景)
+```
+
+业务上,这些表就是给下游用的“需求清单”。
+
+**8. 下游怎么用**
+后面的寻找 Agent 会拿这些需求去找外部内容或作者。
+
+比如 DemandAgent 产出:
+
+```text
+迷信祝福 / 祈福
+迷信祝福 / 命理信仰,经验忠告
+```
+
+寻找 Agent 就会去抖音、热点宝、作者库等地方找:
+
+- 有没有类似内容?
+- 哪些作者适合?
+- 老年用户画像好不好?
+- 哪些视频可以进入生产或爬取计划?
+
+再往后,生产 Agent 或 AIGC 平台才负责实际生产内容。
+
+所以 DemandAgent 在整个链路里的位置是:
+
+```text
+内容解构
+→ 发现内容元素和模式
+→ DemandAgent 生成需求池
+→ 寻找 Agent 找供给
+→ 生产 Agent 做内容
+→ 上线表现回流
+```
+
+一句话总结:
+
+**DemandAgent 是把“已有内容为什么有效”翻译成“接下来应该生产什么需求”的中间层。**

+ 299 - 0
img-article-compreh-dataflow.md

@@ -0,0 +1,299 @@
+# image_article_comprehension 数据工程流程分析报告(三库核验版)
+
+生成时间:2026-05-28
+分析范围:`/Users/samlee/Documents/works/image_article_comprehension` 源码、PostgreSQL `open_aigc.public` 只读实连统计、MySQL `open_aigc_pattern` 与 `aigc-admin-prod` 连接/元数据核验。
+核验方式:PostgreSQL 使用 `default_transaction_read_only=on` 查询元数据和统计;MySQL `open_aigc_pattern` 的 RDS 域名会被本机/VPN Fake-IP 路径接管且 SQL 握手失败,但真实内网地址 `192.168.202.204:3306` 可只读实连;MySQL `aigc-admin-prod` 只查询 `information_schema` 字段元数据,不读取 cookie 行值。
+
+> 安全说明:本报告不复写数据库密码原文;密码原文按用户要求只写入同目录 Excel 的 `数据库清单` sheet。
+
+2026-05-29 追加核验口径:Excel 的“源表 -> 去重 -> embedding -> 距离矩阵 -> DBSCAN -> batch -> 分类 agent -> global 三表”是真实存在的聚类辅助分类/embedding 分类链路;但 `scripts/run_classify.py` 主入口不把 `element_dedup_group`、source embedding cache、距离矩阵、DBSCAN 当硬前置。狭义 Pattern V2 是 `pattern_mining_*` 快照和 pattern 挖掘,不生成 global 三表;如果口头把整个 `pattern_global_v2` 服务都叫 Pattern V2,则其中分类库阶段会写 global 三表。MySQL `open_aigc_pattern` 当前通过真实内网地址 `192.168.202.204:3306` 只读复核成功,但只影响 build 工作台和旧兼容层口径,不改变分类库与 Pattern V2 主链路。完整修订见 `/Users/samlee/Documents/works/数据工程/pattern-global-v2-full-data-algorithm-report.md`。
+
+## 1. 核验结论
+
+本项目当前只按 3 个有效数据库整理:
+
+| 数据库 | 定性 | 本项目角色 |
+|---|---|---|
+| PostgreSQL `open_aigc.public` | 分类库 + pattern v2 + 原始解构主库 | 接收 topic/script 解构结果,沉淀去重、分类树、映射、embedding、pattern 快照和 pattern v2 输出 |
+| MySQL `open_aigc_pattern` | 构建工作台库 | 记录选题构建、脚本构建、prompt/strategy、外部搜索日志、输入缓存/配置,以及旧版兼容 `topic_pattern_*` 表 |
+| MySQL `aigc-admin-prod` | AIGC 后台辅助库 | 当前代码只用于浏览器工具读取 `agent_channel_cookies` 的 cookie/profile 元数据,不是 pattern 加工输入库或输出库 |
+
+两个已确认废弃库已从本报告和 Excel 的主数据流转中删除,不再纳入本项目数据工程口径。
+
+主数据链路是:上游内容或解构 JSON/API 进入 `open_aigc` 原始表,经过 dedup、embedding/距离矩阵、DBSCAN 聚类辅助、分类 agent 写入全局分类体系,再由 pattern snapshot 和配置化挖掘产出 pattern v2 结果。`patter_from_global_and_build` 消费 `open_aigc` / pattern v2 查询能力,把选题和脚本构建过程写入 `open_aigc_pattern`。
+
+需要特别修正的口径:
+
+1. `run_daily_main.py` 当前默认只启用 `topic_element` FP-Growth;`topic`、`point_pattern`、`cross_layer`、`paragraph`、`script_sequence` 等 loop 是可配置能力或历史输出,不能写成当前默认都会跑。
+2. `open_aigc_pattern` 是当前 topic/script build 工作台库,不只是旧兼容库;其中 `topic_pattern_*` 是旧本地 mining/兼容/展示兜底层,当前 library/account pattern 查询更应以 `pattern_global_v2` HTTP debug API 和 `open_aigc` 的 pattern v2 表为准。
+3. `aigc-admin-prod` 不提供外部搜索 case 数据;外部搜索来自 HTTP/crawler/aigc-channel/tophub 等接口,结果落 `open_aigc_pattern.external_search_case_log`。
+4. `post_decode_topic_point_element` 已有 topic 侧 `感受` 数据,实测 `38,773` 行,但当前 `element_dedup_group` 和当前全局映射尚未承接这部分口径。
+
+## 2. 数据库和实例核验
+
+| 数据库 | 实例名/实例ID | 实例连接地址 | 当前解析/peer | 连接状态 | 用途 | 配置来源 |
+|---|---|---|---|---|---|---|
+| PostgreSQL `open_aigc.public` | `gp-t4n72471pkmt4b9q7o-master` | `gp-t4n72471pkmt4b9q7o-master.gpdbmaster.singapore.rds.aliyuncs.com:5432` | `198.18.0.45:5432` | 只读实连成功 | 原始解构、全局分类、embedding、dedup、pattern v2 快照和输出 | `aiddit/pattern_global_v2/db/pg_db_manager.py:13`、`docker/Dockerfile.pattern_global_v2:21`、`patter_from_global_and_build/library_data/library_db_manager.py:12` |
+| MySQL `open_aigc_pattern` | `rm-bp1k5853td1r25g3n690` | `rm-bp1k5853td1r25g3n690.mysql.rds.aliyuncs.com:3306` | 域名 Fake-IP 本轮 `198.18.0.59:3306`;真实直连 `192.168.202.204:3306` | 域名 Fake-IP 路径 TCP 可连但无 MySQL greeting;真实内网地址只读实连成功,35 张表、332 个字段 | 选题/脚本 build 工作台、prompt/strategy、外部搜索缓存、配置/输入缓存、旧 `topic_pattern_*` 兼容层 | `aiddit/pattern/patter_from_global_and_build/db_manager.py:11` |
+| MySQL `aigc-admin-prod` | `rm-t4na9qj85v7790tf84o` | `rm-t4na9qj85v7790tf84o.mysql.singapore.rds.aliyuncs.com:3306` | `198.18.0.86:3306` | 实连成功;只查 `agent_channel_cookies` 字段元数据,不读 cookie 行值 | AIGC 后台浏览器工具 cookie/profile 辅助库 | `aigc_agent_sdk/Agent/agent/tools/builtin/browser/sync_mysql_help.py:27`、`browser/baseClass.py:520` |
+
+## 3. PostgreSQL `open_aigc` 表规模
+
+| 表 | 2026-05-28 实测值 | 业务域 |
+|---|---:|---|
+| `post` | 66,974 | 内容主表 |
+| `post_decode_result` | 66,670 | 选题解构结果 |
+| `post_decode_topic_point` | 572,780 | 选题点 |
+| `post_decode_topic_point_element` | 1,308,993 | 选题点元素 |
+| `post_script_paragraph` | 12,164 | 脚本段落 |
+| `post_script_element` | 47,951 | 脚本一级元素 |
+| `post_script_paragraph_element` | 110,999 | 段落元素关联 |
+| `post_script_paragraph_field_element` | 177,856 | 段落字段元素 |
+| `element_dedup_group` | 262,326 | 去重组 |
+| `global_category` | 4,944 | 全局分类树 |
+| `global_element` | 290,864 | 全局元素 |
+| `element_classification_mapping` | 1,123,373 | 源元素到全局元素/分类映射 |
+| `global_element_embedding` | 455,269 | 元素向量 |
+| `global_category_embedding` | 8,860 | 分类向量 |
+| `pattern_mining_execution` | 7 | pattern v2 执行 |
+| `pattern_mining_category` | 25,816 | pattern 分类快照 |
+| `pattern_mining_element` | 1,950,755 | pattern 元素快照 |
+| `pattern_mining_config` | 45 | pattern 挖掘配置 |
+| `pattern_itemset` | 449,216 | FP-Growth 结果 |
+| `pattern_itemset_item` | 1,808,629 | itemset item |
+| `pattern_itemset_post` | 3,910,262 | itemset 支撑 post |
+| `pattern_script_sequence` | 2,753 | PrefixSpan 序列 |
+| `pattern_script_sequence_item` | 7,873 | 序列 item |
+| `pattern_script_sequence_post` | 15,907 | 序列支撑 post |
+| `pattern_group_itemset` | 2,997 | topic point/group pattern |
+| `pattern_group_itemset_item` | 6,138 | group itemset item |
+| `pattern_group_itemset_member` | 39,191 | group itemset 成员 |
+
+## 4. 原始解构数据
+
+### 4.1 选题解构元素:`post_decode_topic_point_element`
+
+| 分类维度 | 元素行数 | 覆盖 post | distinct 元素名 |
+|---|---:|---:|---:|
+| 实质 | 681,856 | 66,069 | 165,839 |
+| 形式 | 537,947 | 65,899 | 56,975 |
+| 意图 | 50,417 | 47,572 | 743 |
+| 感受 | 38,773 | 12,827 | 361 |
+
+topic 侧 `感受` 已经是实测存在的数据,不再沿用旧报告“只有 3 行”的说法。但 dedup、聚类入口和当前全局映射尚未承接 `感受 + post_decode_topic_point_element`。
+
+### 4.2 脚本一级元素:`post_script_element`
+
+| 分类维度 | 元素行数 | 覆盖 post | distinct 元素名 |
+|---|---:|---:|---:|
+| 实质 | 31,872 | 1,936 | 12,572 |
+| 形式 | 16,079 | 1,952 | 9,055 |
+
+### 4.3 脚本段落字段元素:`post_script_paragraph_field_element`
+
+后续 dedup、paragraph pattern 和 script sequence pattern 的业务维度以 `field_type` 为核心:`function -> 作用`、`feeling -> 感受`,`theme/form` 再结合 `element_type` 归入“实质/形式”。
+
+| 流转维度 | field_type | 元素行数 | 覆盖 post | distinct 元素名 |
+|---|---|---:|---:|---:|
+| 作用 | function | 28,895 | 1,931 | 8,422 |
+| 实质 | form | 40,207 | 1,926 | 13,084 |
+| 实质 | theme | 41,699 | 1,932 | 20,760 |
+| 形式 | form | 31,481 | 1,930 | 6,758 |
+| 形式 | theme | 7,038 | 1,303 | 2,979 |
+| 感受 | feeling | 28,536 | 1,932 | 2,194 |
+
+## 5. 主加工 loop 状态
+
+| loop | 当前状态 | 输入 | 输出 | 说明 |
+|---|---|---|---|---|
+| topic/script 导入 | 保留主加工 | 上游 JSON/API/ODPS | `post_decode_*`、`post_script_*` | `pattern_global_v2/data_io` 写入 `open_aigc` |
+| dedup 同步 | 保留主加工 | 3 张原始元素表 | `element_dedup_group` | 1 张表内按 `source_type + source_table` 分 9 个处理组合,不是 9 张 dedup 表 |
+| source embedding | 保留辅助加工 | dedup 代表元素、已有全局元素向量、embedding API | 本地 `cache/embeddings_{source_table}.ids.npy/.vecs.npy`;可复用/补写 `global_element_embedding` | 原始 source 元素没有独立 DB embedding 表;本地 cache 是矩阵输入 |
+| 距离矩阵 | 保留主加工 | 9 组 dedup 代表元素 embedding | 本地 `cache/dist_rows_{source_type}__{source_table}.bin/.idx.npz` | 距离矩阵不是数据库表;每个 source_type/source_table 一组矩阵文件 |
+| DBSCAN 聚类 | 保留辅助加工 | 距离矩阵 | 当前 `cluster_on_demand.py` 返回内存聚类结果;旧/归档路径可写本地 `cache/global_clusters_{source_type}_{source_table}_{timestamp}.json` | 聚类不直接写分类树,只辅助分类 agent/人工批处理;JSON 不是当前必经落地产物 |
+| 分类 agent | 保留主加工 | cluster batch 或未分类元素 | `global_category`、`global_element`、`element_classification_mapping`;辅助写 `classify_*`、`global_*_embedding`、`post_classification_status` | pattern v2 快照的事实基础 |
+| pattern snapshot | 保留主加工 | 当前全局分类树和映射 | `pattern_mining_execution/category/element` | 每次 execution 固化当时分类视图 |
+| topic_element FP-Growth | `run_daily_main.py` 默认启用 | `pattern_mining_element` topic 元素 | `pattern_itemset*` scope=`topic_element` | 当前默认唯一启用的挖掘 loop |
+| topic FP-Growth | 可配置启用/历史输出 | topic 分类 item | `pattern_itemset*` scope=`topic` | `ENABLE_TOPIC=False` |
+| point pattern | 可配置启用/历史输出 | topic point/group transaction | `pattern_group_itemset*` | `ENABLE_POINT_PATTERN=False` |
+| cross_layer | 可配置启用/历史输出 | fully_classified post | `pattern_itemset*` scope=`cross_layer` | `ENABLE_CROSS_LAYER=False` |
+| paragraph | 可配置启用/历史输出 | paragraph transaction | `pattern_itemset*` scope=`paragraph` | `ENABLE_PARAGRAPH=False` |
+| script sequence | 可配置启用/历史输出 | 段落顺序 | `pattern_script_sequence*` | `ENABLE_SCRIPT=False` |
+| MySQL `topic_pattern_*` 本地 mining | 兼容/展示兜底层 | v2 export API 快照 | `open_aigc_pattern.topic_pattern_*` | 非当前 pattern v2 主事实;当前 library/account pattern 查询默认看 v2 HTTP debug API |
+| AIGC 后台 cookie/profile | 外部辅助 | `agent_channel_cookies` 元数据 | 浏览器工具登录态 | 不参与 pattern 加工,不读 cookie 行值 |
+
+## 6. 去重、embedding 和聚类链路
+
+聚类完整链路只使用 PostgreSQL `open_aigc.public` 作为数据库;`open_aigc_pattern` 不参与原始元素去重、embedding、距离矩阵、DBSCAN 或分类树写入。需要特别区分:`element_dedup_group` 是 1 张数据库表中的 9 个处理组合,不是 9 张表;embedding 和距离矩阵大量落在本地 `cache/` 文件,DBSCAN 当前可跑入口返回内存结果,旧/归档路径才会写 `global_clusters_*.json`。
+
+### 6.1 阶段产物总览
+
+| 阶段 | 输入 | 加工方式 | 生成数据 | 写入/落地位置 |
+|---|---|---|---|---|
+| 原始元素输入 | `post_decode_topic_point_element`、`post_script_element`、`post_script_paragraph_field_element` | topic/script 解构导入后形成原始元素行 | 原始元素 ID、post_id、元素名、元素类型、描述、段落字段类型 | 3 张原始元素表 |
+| 去重 dedup | 3 张原始元素表 | 按 `source_type + source_table + normalized_name` 分组;段落字段表中 `function -> 作用`、`feeling -> 感受`,`theme/form` 再结合 `element_type` 归入实质/形式 | `representative_id`、`member_ids`、`occurrence_count`、`dedup_key` | `element_dedup_group` |
+| source embedding | dedup 代表元素 ID | 优先读本地 source embedding cache;缺失时尝试通过 `element_classification_mapping -> global_element_embedding` 复用已分类全局元素向量;仍缺失则调用 embedding API 并回写本地 cache | source 元素向量 | 本地 `cache/embeddings_{source_table}.ids.npy`、`cache/embeddings_{source_table}.vecs.npy`;分类后新全局元素向量写 `global_element_embedding` |
+| 距离矩阵 | 9 组 dedup 代表元素向量 | 计算 cosine distance,行存储 float16,增量追加 | 每组 source_type/source_table 的代表元素距离行和索引 | 本地 `cache/dist_rows_{source_type}__{source_table}.bin`、`cache/dist_rows_{source_type}__{source_table}.idx.npz`;旧格式兼容 `cache/distance_matrix_{key}.npz` |
+| DBSCAN | 距离矩阵 | `DBSCAN(metric='precomputed')` 找相似元素簇 | `metadata`、`clusters[{cluster_id,size,member_ids}]`、`noise_elements`;当前 `cluster_on_demand.py` 返回内存 dict | 旧/归档路径可写本地 `cache/global_clusters_{source_type}_{source_table}_{timestamp}.json`,但不是当前必经落地产物 |
+| cluster batch | DBSCAN 内存结果或旧归档 JSON、`element_dedup_group`、`element_classification_mapping`、原始元素表 | 展开 dedup member_ids,过滤已在 mapping 中分类过的 source_element_id,再回原始表取元素名/描述 | 待分类 batch:`representative_id`、`element_name`、`element_description`、`all_ids`、`cluster_id`、`source_table` | 传给 classify agent;不直接写 DB |
+| 分类 agent | cluster batch 或普通未分类 batch | agent tool 可查树、建分类、创建/复用全局元素、创建映射、刷新 post 分类状态 | 全局分类树、全局归一元素、原始元素到全局元素/分类的映射、执行日志、向量 | `global_category`、`global_element`、`element_classification_mapping`;辅助表 `classify_execution`、`classify_batch`、`classify_execution_log`、`global_element_embedding`、`global_category_embedding`、`post_classification_status` |
+
+当前代码里还存在一个实现漂移,需要把“设计链路”和“当前可跑入口”分开看:`ClusterBatchPreparer.cluster_all_elements()` 同步矩阵时使用 `source_type + source_table`,但随后 `load_or_create(source_type)` 没带 `source_table`,与实际矩阵 key `source_type__source_table` 不一致;同文件 `get_unclassified_from_cluster()` 调用的 `expand_dedup_groups` 在 `DedupManager` 中实际方法名是 `expand_members`。因此当前更可信的聚类入口是 `scripts/dedup_matrix/build_all_matrices.py` 预构建 9 组矩阵,再由 `scripts/dedup_matrix/cluster_on_demand.py` 按 `source_type__source_table` 提取子矩阵做按需聚类;`global_clusters_*.json` 只能写作旧/归档式路径,不应写成当前必经产物。
+
+### 6.2 原始元素表和 9 个 dedup/聚类组合
+
+聚类入口的原始元素表一共 3 张:
+
+| 原始元素表 | 实测行数 | 聚类使用字段 | 进入哪些处理组合 |
+|---|---:|---|---|
+| `post_decode_topic_point_element` | 1,308,993 | `id`、`post_id`、`element_type`、`element_name`、`element_description` | `实质`、`形式`、`意图`;topic 侧 `感受` 原始存在但当前 dedup/聚类组合未承接 |
+| `post_script_element` | 47,951 | `id`、`post_id`、`element_type`、`name`、`element_description` | `实质`、`形式` |
+| `post_script_paragraph_field_element` | 177,856 | `id`、`paragraph_id`、`post_id`、`field_type`、`element_type`、`element_name`、`element_description` | `实质`、`形式`、`作用`、`感受` |
+
+`element_dedup_group` 仍为聚类前的关键缩减表。去重按 `source_type + source_table + normalized_name` 建组,代表元素用于 embedding 和距离矩阵。
+
+| source_type | source_table | 去重组数 | 去重口径内出现行 | 最大组大小 | 平均组大小 |
+|---|---|---:|---:|---:|---:|
+| 作用 | `post_script_paragraph_field_element` | 8,422 | 28,895 | 1,326 | 3.43 |
+| 实质 | `post_decode_topic_point_element` | 140,069 | 537,822 | 4,448 | 3.84 |
+| 实质 | `post_script_element` | 12,562 | 31,872 | 292 | 2.54 |
+| 实质 | `post_script_paragraph_field_element` | 30,830 | 81,906 | 1,155 | 2.66 |
+| 形式 | `post_decode_topic_point_element` | 49,402 | 423,987 | 6,093 | 8.58 |
+| 形式 | `post_script_element` | 9,053 | 16,079 | 211 | 1.78 |
+| 形式 | `post_script_paragraph_field_element` | 9,151 | 38,519 | 1,437 | 4.21 |
+| 意图 | `post_decode_topic_point_element` | 643 | 40,732 | 19,478 | 63.35 |
+| 感受 | `post_script_paragraph_field_element` | 2,194 | 28,536 | 1,590 | 13.01 |
+
+当前 topic 原始表已经增长,但 dedup 仍停在旧同步口径。例如 topic 原始 `实质` 是 `681,856` 行,而 dedup 中 `实质 + post_decode_topic_point_element` occurrence 仍是 `537,822`;topic 原始 `感受` 有 `38,773` 行,但 dedup 没有 `感受 + post_decode_topic_point_element`。
+
+### 6.3 分类写表格式
+
+分类 agent 处理的是 cluster batch 或普通未分类元素 batch。DBSCAN 只提供“哪些元素相似”的候选簇,真正的全局归一和分类树写入发生在分类工具层:
+
+| 写入表 | 写入内容 | 关键字段 |
+|---|---|---|
+| `global_category` | 全局分类树节点,按 `stable_id` 维持逻辑稳定 ID,修改时用新行版本追踪 | `stable_id`、`name`、`description`、`parent_stable_id`、`source_type`、`classified_as`、`level`、`path`、`created_at_execution_id`、`retired_at_execution_id` |
+| `global_element` | 全局归一后的标准元素;同名同分类可复用,复用时增加 `occurrence_count` | `id`、`name`、`description`、`belong_category_stable_id`、`source_type`、`element_sub_type`、`occurrence_count`、`created_at_execution_id`、`retired_at_execution_id` |
+| `element_classification_mapping` | 原始 source 元素到全局元素和分类节点的映射 | `source_table`、`source_element_id`、`post_id`、`element_name`、`element_type`、`global_element_id`、`global_category_stable_id`、`classification_path`、`classify_execution_id` |
+| `global_element_embedding` | 新建或迁移后的全局元素向量,用于相似搜索和后续复用 | `element_id`、`belong_category_stable_id`、`source_type`、`embedding_field`、`embedding_model`、`embedding`、`is_active` |
+| `global_category_embedding` | 分类节点向量,用于分类树搜索、相似分类检索;分类名/描述变化时旧向量失活 | `stable_id`、`source_type`、`embedding_field`、`embedding_model`、`embedding`、`is_active` |
+| `post_classification_status` | 按 post/source_type/source_table 刷新分类完成度 | `post_id`、`source_type`、`source_table`、`total_elements`、`classified_elements`、`is_completed` |
+
+“全局归一”的实际关系是:原始元素表中的一行或一个 dedup group member,最终通过 `element_classification_mapping.source_table + source_element_id` 指向一个 `global_element.id`;这个全局元素再通过 `belong_category_stable_id` 挂到 `global_category.stable_id` 对应的分类树节点。原始元素不被覆盖,映射表保存“原始元素 -> 全局标准元素 -> 分类路径”的关系。
+
+## 7. 全局分类树、映射和 pattern v2
+
+统计口径:`global_category.retired_at_execution_id IS NULL` 和 `global_element.retired_at_execution_id IS NULL`。
+
+| 分类树 | 活跃节点 | 根节点 | 叶子节点 | 最大层级 | 活跃 global_element | 映射行数 | 覆盖 post | 活跃 category embedding |
+|---|---:|---:|---:|---:|---:|---:|---:|---:|
+| 作用 | 185 | 2 | 140 | 8 | 4,753 | 25,298 | 1,907 | 362 |
+| 实质 | 972 | 2 | 740 | 7 | 148,740 | 615,710 | 52,836 | 1,916 |
+| 形式 | 624 | 2 | 458 | 6 | 60,384 | 470,315 | 52,710 | 1,248 |
+| 意图 | 28 | 3 | 18 | 3 | 293 | 12,050 | 11,954 | 56 |
+| 感受 | 46 | 2 | 36 | 3 | 0 | 0 | 0 | 92 |
+
+`感受` 当前有分类节点和 embedding,但没有活跃 `global_element` / `element_classification_mapping`。这与脚本原始数据、dedup 和历史 pattern 快照中存在“感受”形成口径差异。
+
+`pattern_mining_execution` 仍有 current 异常:`#401` 是 `is_current=true` 但 `status=failed`,`#281` 也是 current;`#581` 是最新成功执行但 `is_current=false`。API 如果只按 `is_current` 选 execution,可能会拿到失败快照。
+
+| execution_id | snapshot_date | status | is_current | post_count | category_count | element_count | topic_itemset_count | topic_element_itemset_count | cross_itemset_count | paragraph_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 | - | - | 2,649 | 3,219 | 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 | 92,142 | 3,219 | 1,030 |
+
+## 8. 构建库 `open_aigc_pattern`
+
+`open_aigc_pattern` 是当前 topic/script build 工作台库,而不是当前 pattern v2 真相库。当前连接核验结论:
+
+- RDS 域名 `rm-bp1k5853td1r25g3n690.mysql.rds.aliyuncs.com:3306` 会被本机/VPN Fake-IP 路径接管;本轮解析为 `198.18.0.59`,此前核验曾出现 `198.18.0.47`。该路径 TCP 可连,但收不到 MySQL greeting,PyMySQL 会报 `OperationalError: (2013, 'Lost connection to MySQL server during query')`。
+- 真实内网地址 `192.168.202.204:3306` 只读实连成功,返回 MySQL `5.7.30-log`;当前库实测 35 张表、332 个字段。
+- Excel `表字段字典` 已从 live `information_schema` 补齐此前缺失的 5 张表:`account_constant`、`base_config`、`topic_build_strategy`、`topic_build_strategy_version`、`xhs_benchmark_account`。
+
+2026-05-29 复核关键表规模:
+
+| 表 | 2026-05-29 实测行数 | 角色 |
+|---|---:|---|
+| `topic_build_record` | 1,093 | 选题构建执行记录 |
+| `topic_build_topic` | 1,264 | 选题候选/结果 |
+| `topic_build_composition_item` | 22,579 | 选题组成元素 |
+| `topic_build_item_source` | 23,504 | 元素证据来源 |
+| `topic_build_item_exploration_trace` | 15,466 | item 探索轨迹 |
+| `script_build_record` | 269 | 脚本构建执行记录 |
+| `script_build_paragraph` | 945 | 脚本段落 |
+| `script_build_element` | 2,459 | 脚本元素 |
+| `script_build_paragraph_element` | 4,447 | 段落和元素关联 |
+| `external_search_case_log` | 12,043 | 外部搜索 case 缓存 |
+| `prompt` / `prompt_version` | 9 / 125 | prompt 当前版本和历史版本 |
+| `build_strategy` / `build_strategy_version` | 56 / 242 | 构建策略当前版本和历史版本 |
+| `topic_pattern_itemset` | 655,513 | 旧 topic pattern 本地 itemset |
+| `topic_pattern_itemset_item` | 3,007,048 | 旧 topic pattern item |
+
+从 live schema、ORM 和业务工具看,保留这些 build 表组:
+
+| 表组 | 主要表 | 用途 |
+|---|---|---|
+| 配置/输入缓存 | `base_config`、`account_constant`、`topic_piaoquan_demand`、`xhs_benchmark_account`、`post` | 默认 execution、批量配置、账号人设常量、票圈需求池、对标账号缓存和本地 post 元数据 |
+| 选题构建 | `topic_build_record`、`topic_build_topic`、`topic_build_composition_item`、`topic_build_item_source`、`topic_build_item_exploration_trace`、`topic_build_point*`、`topic_build_log` | 记录需求、选题方向、构成 item、证据来源、探索轨迹、组合点和执行日志 |
+| 脚本构建 | `script_build_record`、`script_build_paragraph`、`script_build_element`、`script_build_paragraph_element`、`script_build_decision_trace`、`script_build_log` | 记录脚本段落树、元素、支撑关系、决策 trace 和执行日志;`script_build_provenance` 为旧数据保留 |
+| prompt/strategy | `prompt`、`prompt_version`、`build_strategy`、`build_strategy_version` | 复现构建策略和 prompt 版本 |
+| 外部搜索缓存 | `external_search_case_log` | 保存 HTTP 外部搜索结果,用 `channel_content_id` 回查素材证据 |
+| 兼容旧 pattern | `topic_pattern_*`、`topic_pattern_account_itemset_cache` | 旧本地 mining/兼容/展示兜底,不作为当前 pattern v2 主真相 |
+
+当前 topic build 的 pattern/library 查询运行时默认转成 `pattern_global_v2` HTTP debug API;script build 的创作 pattern 查询走 `/api/pattern/creation-tools/debug`。另有 `library_data` 通过 PostgreSQL `open_aigc` 直查 `post / post_script_paragraph / post_script_element`,用于参考脚本搜索。需要注意,`topic_build_record.execution_id` 不能简单理解为只指向 MySQL `topic_pattern_execution.id`:实测 build 记录中也出现 `401`、`281`、`79` 等远端/open_aigc pattern v2 execution 口径。
+
+## 9. 后台库 `aigc-admin-prod`
+
+`aigc-admin-prod` 当前在本项目中的代码用途很窄:
+
+| 表 | 字段 | 用途 |
+|---|---|---|
+| `agent_channel_cookies` | `cookies` | 浏览器工具注入登录态,核验时未读取行值 |
+| `agent_channel_cookies` | `type` | 渠道类型,例如 xhs/gzh/shp/github |
+| `agent_channel_cookies` | `profileId` | 云浏览器 profile ID |
+
+这张表服务的是内嵌 Agent SDK 的 browser helper,不是内容解构、分类、pattern 或 build 的主数据来源。外部搜索 case 不从该库读取;`external_search_case` 走 HTTP/crawler/aigc-channel/tophub/newrank 等外部接口,结果写入 `open_aigc_pattern.external_search_case_log`。
+
+## 10. 数据加工流转地图
+
+| 阶段 | 输入 | 关键处理 | 输出 | 下游 |
+|---|---|---|---|---|
+| 内容采集/外部输入 | crawler、ODPS、外部任务 API、本地 JSON | 采集或接收内容和解构结果 | 本地 JSON、`post` | topic/script 导入 |
+| 选题导入 | topic decode JSON | 写帖子、解构结果、topic point 和 element | `post_decode_result`、`post_decode_topic_point`、`post_decode_topic_point_element` | dedup、分类、topic pattern |
+| 脚本导入 | script split/decode JSON | 写段落、一级元素、字段元素 | `post_script_paragraph*`、`post_script_element` | dedup、paragraph/sequence pattern |
+| 去重 | 3 张原始元素表 | `source_type + source_table + normalized_name` 分组 | `element_dedup_group` 1 张表内的 9 个组合 | source embedding、距离矩阵、分类 batch |
+| source embedding | dedup 代表元素、已有 `global_element_embedding`、embedding API | 复用或生成 source 元素向量 | 本地 `cache/embeddings_{source_table}.*`;分类后补写 `global_element_embedding` | 距离矩阵、相似搜索 |
+| 距离矩阵 | 9 组 source embedding | 计算 cosine distance,行存储增量追加 | 本地 `cache/dist_rows_{source_type}__{source_table}.bin/.idx.npz` | DBSCAN |
+| 聚类 | 距离矩阵 | DBSCAN 聚相似元素,输出簇和噪音点 | 当前按需入口返回内存结果;旧/归档路径可写本地 `cache/global_clusters_{source_type}_{source_table}_{timestamp}.json` | 分类 agent/人工筛选 |
+| 分类 | cluster batch 或未分类元素 batch | agent tool 创建/调整分类、元素、映射并刷新状态 | `global_category`、`global_element`、`element_classification_mapping`、`classify_*`、`global_*_embedding`、`post_classification_status` | pattern snapshot/API |
+| pattern 快照 | 当前分类树和映射 | 固化 execution 视角 | `pattern_mining_execution/category/element/semantic_map` | 挖掘算法 |
+| 默认 pattern loop | `pattern_mining_element` topic 元素 | `topic_element` FP-Growth | `pattern_itemset*` | visualization/build |
+| 可选 pattern loop | topic/cross/paragraph/script 输入 | 按开关运行 FP-Growth/PrefixSpan | `pattern_itemset*`、`pattern_script_sequence*`、`pattern_group_itemset*` | visualization/build |
+| build 配置/输入 | `open_aigc_pattern.base_config/prompt*/build_strategy*/account_constant/topic_piaoquan_demand/xhs_benchmark_account` | 读取默认 execution、prompt、策略、账号常量、批量需求和对标账号缓存 | build 运行上下文 | topic/script build agent |
+| 应用 build | pattern v2 HTTP API、open_aigc 帖子/脚本库、用户需求、策略/prompt、外部搜索 | 选题构建、脚本构建、证据追踪 | MySQL `open_aigc_pattern` 的 `topic_build_*`、`script_build_*`、`external_search_case_log` | 业务应用层 |
+| 旧 pattern 兼容 | v2 export API 快照、本地 mining | 本地 topic pattern mining、详情页/脚本辅助兼容查询 | MySQL `open_aigc_pattern.topic_pattern_*` | 兼容展示和兜底,不替代 pattern v2 主事实 |
+| 后台辅助 | `aigc-admin-prod.agent_channel_cookies` 字段元数据 | 提供 browser helper 登录态配置 | 浏览器工具运行态 | 外部网页/平台操作 |
+
+## 11. 主要问题和建议
+
+1. 修复 `pattern_mining_execution` current 口径:只保留一条 current,且 API 查询 current 时增加 `status='success'` 保护。
+2. 重跑或增量同步 topic dedup:当前 topic raw 表已增长,dedup 和后续聚类/分类 batch 已经不是最新口径。
+3. 明确 topic 侧 `感受` 的处理策略:当前 topic raw 有 `感受`,但 dedup/mapping/pattern active 口径没有承接。
+4. 修复聚类入口实现漂移:`ClusterBatchPreparer` 的矩阵 key 和 dedup 展开方法名与当前 manager 不一致,应统一到 `source_type__source_table` 和 `expand_members`,或明确只保留 `build_all_matrices.py + cluster_on_demand.py` 路径。
+5. 对聚类输出新增 DB 审计或固定归档:否则 `cache/global_clusters_*` 丢失后无法复盘哪次聚类辅助了哪批分类。
+6. 修复或绕过 `open_aigc_pattern` 域名 Fake-IP 路径:当前真实内网 IP 可读,但标准 RDS 域名仍会被 Fake-IP 接管并导致 MySQL 握手失败,建议在 VPN/代理规则中对该 RDS 域名走真实内网解析或直连路由。
+
+## 12. 一句话数据地图
+
+`crawler/ODPS/上游解构 JSON/API`
+-> `open_aigc.post + post_decode_* + post_script_*` 原始解构仓
+-> `element_dedup_group + embedding cache + distance matrix` 做元素归并和聚类辅助
+-> `global_category + global_element + element_classification_mapping` 形成分类树和源元素映射
+-> `pattern_mining_execution + pattern_mining_category + pattern_mining_element` 固化 pattern v2 快照
+-> 默认 `topic_element` 及可配置 pattern loop 产出 `pattern_itemset* / pattern_script_sequence* / pattern_group_itemset*`
+-> `patter_from_global_and_build` 消费 pattern v2、帖子库和外部搜索,生成选题/脚本并写 `open_aigc_pattern`。

+ 351 - 0
pattern-global-v2-full-data-algorithm-report.md

@@ -0,0 +1,351 @@
+# 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 消费。