|
|
@@ -0,0 +1,1083 @@
|
|
|
+# 创作知识系统|正式版施工文档
|
|
|
+
|
|
|
+> 文档性质:施工文档。
|
|
|
+> 目标:把当前本地 Demo 项目改造成“云端数据库 + OSS/CDN + acquisition -> decode_content -> pipeline -> app”的正式管道。
|
|
|
+> 更新时间:2026-06-30。
|
|
|
+> 本轮边界:本文记录正式版施工步骤;已完成的步骤会附执行记录,未完成的步骤仍按计划表述。
|
|
|
+> 默认方案:在阿里云海外 lsh 开发机上新建 PostgreSQL 正式库;现有 Open AIGC PG/Greenplum 只作为上游分类树或历史连接,不作为本系统状态库。
|
|
|
+
|
|
|
+## 0. 施工总原则
|
|
|
+
|
|
|
+这次不是给旧 demo 打补丁,而是把主干改成正式工程。
|
|
|
+
|
|
|
+核心原则:
|
|
|
+
|
|
|
+- `main` 面向正式云端架构;旧本地数据和旧 demo 只由 `local-demo` 或归档路径负责。
|
|
|
+- 本地 SQLite、`data/`、`legacy_data/` 不再是正式状态源。
|
|
|
+- `creation_knowledge/` 不再作为正式顶层业务目录;其中可复用能力要迁到 `app/`、`decode_content/`、`acquisition/`。
|
|
|
+- `创作知识提取-skill/` 是正式 skill contract,必须保留。
|
|
|
+- 媒体正式链路统一以 OSS/CDN URL 为准,前端不再依赖本地 `/data/media/...`。
|
|
|
+- 数据库先按可理解的业务对象建模,不在第一轮堆非常细的字段。
|
|
|
+
|
|
|
+施工顺序不能反过来:先归档、再建云端状态源、再建本地模型和仓储、再迁 acquisition、decode、pipeline、app。
|
|
|
+
|
|
|
+每个大步骤完成后,都要过一次“清理闸门”:
|
|
|
+
|
|
|
+1. 查正式代码是否还引用旧入口。
|
|
|
+2. 查测试是否还依赖旧路径。
|
|
|
+3. 能删的从 `main` 移除。
|
|
|
+4. 还需要回看的移到 `archive/` 或留在 `local-demo`。
|
|
|
+5. 还没完全替代的,只能降级为 legacy shim,并在下一步清理清单里继续追踪。
|
|
|
+
|
|
|
+## 1. 先清理与归档
|
|
|
+
|
|
|
+### 1.1 先保留什么
|
|
|
+
|
|
|
+这些目录和文件是正式版要继续用的资产:
|
|
|
+
|
|
|
+| 保留对象 | 原因 |
|
|
|
+|---|---|
|
|
|
+| `core/` | 配置、LLM、Embedding、Prompt、PG 基建等共享底座 |
|
|
|
+| `acquisition/` 主体 | 平台搜索、详情抓取、OSS、粗分类已经有真实代码 |
|
|
|
+| `prompts/` | 创作闸、分类、读懂、scope normalize 等提示词仍被代码使用 |
|
|
|
+| `tests/fixtures/` | crawler/search 离线测试仍依赖 |
|
|
|
+| `创作知识提取-skill/` | 正式解构合同,不等于旧 `creation_knowledge/` 包名 |
|
|
|
+| `app/frontend/src/` | 当前 Vite 前端已经迁为正式工作台起点 |
|
|
|
+
|
|
|
+`acquisition/store.py` 已在第 6 步归档到 `archive/2026-06-30-step6/legacy_app/acquisition/store.py`;正式代码不能继续依赖它。
|
|
|
+
|
|
|
+### 1.2 第一轮归档或删除什么
|
|
|
+
|
|
|
+第一轮只动纯 legacy,不要急着拆核心业务代码。
|
|
|
+
|
|
|
+建议从 `main` 移除或迁到归档位置:
|
|
|
+
|
|
|
+- `web/index.html`
|
|
|
+- `web/frameworks.json`
|
|
|
+- `web/payloads.json`
|
|
|
+- `web/runs/*`
|
|
|
+- `scripts/serve_old_web.py`
|
|
|
+- `scripts/rebuild_payloads.py`
|
|
|
+- `scripts/import_to_db.py`
|
|
|
+- `scripts/run_search.py`
|
|
|
+- `.claude/launch.json`
|
|
|
+- `数据接口与来源/captures/*`
|
|
|
+
|
|
|
+本轮执行路径:已先迁到 `archive/2026-06-30-step1/`,不是直接物理删除;真实 `.env` 从 git tracking 移除,本地文件保留,提交 `.env.example` 作为模板。
|
|
|
+
|
|
|
+处理方式:
|
|
|
+
|
|
|
+- `web/*` 是旧单帖静态 demo 产物,正式前端不再使用。
|
|
|
+- `scripts/serve_old_web.py` 只服务旧静态 demo,正式 API 不再需要。
|
|
|
+- `scripts/rebuild_payloads.py` 与 `scripts/decompose.py` 里 payload 组装重复,后续统一到 `decode_content/payloads.py`。
|
|
|
+- `scripts/import_to_db.py` 是本地 SQLite 迁移工具,正式版不再需要。
|
|
|
+- `scripts/run_search.py` 是旧搜索和本地媒体链路,正式链路由 `run_acquisition.py` 替代。
|
|
|
+- `数据接口与来源/captures/*` 是原始抓包证据,建议先外部归档,再从主干移除。
|
|
|
+
|
|
|
+### 1.2.1 删除、归档、保留清单
|
|
|
+
|
|
|
+这一节专门回答“到底删哪些文件和文件夹”。原则是:能确定只是旧 demo 产物的,先归档后从主干移除;还可能被正式链路复用的,先迁移能力,再删旧入口;真实数据、密钥和云端状态不跟代码一起删。
|
|
|
+
|
|
|
+| 类型 | 对象 | 处理方式 | 说明 |
|
|
|
+|---|---|---|---|
|
|
|
+| 立即归档后从主干移除 | `web/index.html` | 移到 `archive/2026-06-30-step1/legacy_web/` | 根目录旧单帖静态 demo,不是正式前端 |
|
|
|
+| 立即归档后从主干移除 | `web/frameworks.json` | 移到 `archive/2026-06-30-step1/legacy_web/` | 旧 demo 的本地 payload 展示数据 |
|
|
|
+| 立即归档后从主干移除 | `web/payloads.json` | 移到 `archive/2026-06-30-step1/legacy_web/` | 旧 demo 的本地 payload 展示数据 |
|
|
|
+| 立即归档后从主干移除 | `web/runs/*` | 移到 `archive/2026-06-30-step1/legacy_web/runs/` | 旧 demo run 结果 |
|
|
|
+| 立即归档后从主干移除 | `scripts/serve_old_web.py` | 移到 `archive/2026-06-30-step1/legacy_scripts/` | 只服务旧静态 demo |
|
|
|
+| 立即归档后从主干移除 | `scripts/rebuild_payloads.py` | 移到 `archive/2026-06-30-step1/legacy_scripts/` | 后续统一由 `decode_content/payloads.py` 负责 payload 组装 |
|
|
|
+| 立即归档后从主干移除 | `scripts/import_to_db.py` | 移到 `archive/2026-06-30-step1/legacy_scripts/` | 本地 SQLite 导入工具,正式链路不用 |
|
|
|
+| 立即归档后从主干移除 | `scripts/run_search.py` | 移到 `archive/2026-06-30-step1/legacy_scripts/` | 旧搜索入口,正式入口改为 `scripts/run_acquisition.py` |
|
|
|
+| 立即归档后从主干移除 | `tests/test_legacy_paths.py` | 移到 `archive/2026-06-30-step1/legacy_tests/` | 测的是旧 demo 路径,不再代表正式验收 |
|
|
|
+| 立即归档后从主干移除 | `.claude/launch.json` | 移到 `archive/2026-06-30-step1/local_agent/` | 个人本地 agent 配置,不进入正式工程 |
|
|
|
+| 立即归档后从主干移除 | `数据接口与来源/captures/*` | 移到 `archive/2026-06-30-step1/data_interface_captures/` | 原始抓包证据保留为归档,不放主干活跃区 |
|
|
|
+| 从 git 移除但本地保留 | `.env` | `git rm --cached .env`,新增 `.env.example` | 真实密钥不进入仓库 |
|
|
|
+| Step6 已归档 | `acquisition/store.py` | 移到 `archive/2026-06-30-step6/legacy_sqlite/` | SQLite adapter 只供 local-demo/历史参考,正式代码不再依赖 |
|
|
|
+| Step6 已归档 | `scripts/run_creation_search.py` | 移到 `archive/2026-06-30-step6/legacy_scripts/` | 旧 SQLite 采集 runner,正式入口改为 `scripts/run_acquisition.py` |
|
|
|
+| Step6 已归档 | `acquisition/creation_search.py` | 移到 `archive/2026-06-30-step6/legacy_acquisition/` | 平台处理经验已迁到 adapters/media/classification/runner |
|
|
|
+| Step5 已降级为 legacy/debug | `scripts/decompose.py` | 不删 | 正式能力已迁到 `decode_content/`,旧脚本只作调试入口 |
|
|
|
+| Step6 已归档 | `creation_knowledge/` | 移到 `archive/2026-06-30-step6/legacy_creation_knowledge/` | API、读懂、媒体能力已迁到 `app/`、`decode_content/`、`acquisition/media/` |
|
|
|
+| 保留 | `创作知识提取-skill/` | 永久保留 | 正式知识拆解合同层 |
|
|
|
+| 保留 | `prompts/` | 保留 | 正式分类、闸门、读懂、scope prompt 仍使用 |
|
|
|
+| 保留 | `tests/fixtures/` | 保留 | 离线测试证据 |
|
|
|
+| Step6 已迁移 | `acquisition/web/app/` | 源码迁到 `app/frontend/`,旧 dist 归档 | 当前 Vite React 看板已成为正式前端起点 |
|
|
|
+
|
|
|
+第二轮删除条件:
|
|
|
+
|
|
|
+- `scripts/run_creation_search.py`:已在 Step6 归档。
|
|
|
+- `acquisition/creation_search.py`:已在 Step6 归档。
|
|
|
+- `acquisition/store.py`:已在 Step6 归档。
|
|
|
+- `scripts/decompose.py`:已在 Step5 降级为 legacy/debug;正式 pipeline 不调用它。
|
|
|
+- `creation_knowledge/`:已在 Step6 整体归档。
|
|
|
+
|
|
|
+### 1.3 同步改哪些引用
|
|
|
+
|
|
|
+删除或归档前必须同步处理引用:
|
|
|
+
|
|
|
+- `scripts/decompose.py`
|
|
|
+ - 旧 `web/frameworks*.json`、`web/payloads*.json` 写盘逻辑改成 legacy adapter。
|
|
|
+ - 正式 decode 不再直接写 `web/`。
|
|
|
+- `tests/test_legacy_paths.py`
|
|
|
+ - 删除,或改成归档测试。
|
|
|
+- `开发文档/产品文档.md`、`开发文档/技术文档.md`
|
|
|
+ - 所有 `web/index.html`、SQLite、本地 JSON、`creation_knowledge` 作为正式入口的说法改成历史说明。
|
|
|
+- `.env`
|
|
|
+ - 从 git 移除。
|
|
|
+ - 新增 `.env.example`,只保留键名和说明,不写真实密钥。
|
|
|
+ - 真实 `.env` 只放本地或云机环境。
|
|
|
+
|
|
|
+### 1.4 本步骤验收
|
|
|
+
|
|
|
+- `git status` 只显示预期的删除、归档和新增文档。
|
|
|
+- 没有正式代码继续引用 `web/frameworks.json`、`web/payloads.json`。
|
|
|
+- 没有测试继续 import `scripts.serve_old_web`。
|
|
|
+- `.env` 不再作为 tracked secret 进入后续提交。
|
|
|
+
|
|
|
+## 2. 在云服务器新建正式数据库
|
|
|
+
|
|
|
+### 2.1 云机事实
|
|
|
+
|
|
|
+本地云机配置目录:
|
|
|
+
|
|
|
+```text
|
|
|
+/Users/samlee/Documents/工作环境配置/阿里云海外lsh开发机
|
|
|
+```
|
|
|
+
|
|
|
+只读检查确认:
|
|
|
+
|
|
|
+- 目录内有 `account.md` 和 `ali-denet.pem`。
|
|
|
+- 云机可访问。
|
|
|
+- 云端已有 repo:`/home/sam/Create-knowledge-find-decode`。
|
|
|
+- 云端 repo 与本地 `main` 不完全同步,施工前必须以本地新分支或新提交为准重新部署。
|
|
|
+
|
|
|
+安全要求:
|
|
|
+
|
|
|
+- 不把云机 IP、账号、私钥、数据库密码写入仓库。
|
|
|
+- 不把真实 `.env` 提交。
|
|
|
+- 新库密码只放云机环境变量或安全密钥管理位置。
|
|
|
+
|
|
|
+### 2.2 安装与初始化 PostgreSQL
|
|
|
+
|
|
|
+施工动作:
|
|
|
+
|
|
|
+1. 在云机安装 PostgreSQL server 和 client。
|
|
|
+2. 新建数据库,例如:
|
|
|
+ - `creation_knowledge_prod`
|
|
|
+3. 新建应用用户,例如:
|
|
|
+ - `ck_app`
|
|
|
+4. 新建 schema,例如:
|
|
|
+ - `creation_knowledge`
|
|
|
+5. 只给应用用户访问该 schema 的必要权限。
|
|
|
+6. 配置备份策略。
|
|
|
+7. 配置远程访问策略:本地开发可以访问云端库,但不能开放无边界公网访问。
|
|
|
+
|
|
|
+注意:
|
|
|
+
|
|
|
+- 现有 `.env` 里的 `OPEN_AIGC_PG_*` 是上游 Open AIGC PG/Greenplum 配置,不要混用成本系统正式库。
|
|
|
+- 正式库新增 `CK_DB_*` 配置。
|
|
|
+
|
|
|
+建议新增环境变量:
|
|
|
+
|
|
|
+```text
|
|
|
+CK_DB_HOST=
|
|
|
+CK_DB_PORT=5432
|
|
|
+CK_DB_NAME=creation_knowledge_prod
|
|
|
+CK_DB_USER=ck_app
|
|
|
+CK_DB_PASSWORD=
|
|
|
+CK_DB_SCHEMA=creation_knowledge
|
|
|
+```
|
|
|
+
|
|
|
+### 2.3 新增迁移文件
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+db/migrations/001_creation_knowledge_schema.sql
|
|
|
+```
|
|
|
+
|
|
|
+第一版表不追求字段极细,先覆盖业务闭环。
|
|
|
+
|
|
|
+建议业务对象:
|
|
|
+
|
|
|
+| 对象 | 业务意义 |
|
|
|
+|---|---|
|
|
|
+| `query_batches` | 一批 query 的来源、目标、生成方式、状态 |
|
|
|
+| `queries` | 单条 query 及其业务轴、是否保留、筛选原因 |
|
|
|
+| `acquisition_runs` | 一次采集批次 |
|
|
|
+| `acquisition_jobs` | 单条 query 在单个平台上的任务 |
|
|
|
+| `candidate_items` | 候选帖子、文章、视频 |
|
|
|
+| `media_assets` | 图片、封面、视频、原始 URL、OSS/CDN URL |
|
|
|
+| `item_classifications` | 粗分类结果:是否创作知识、原因、模型版本 |
|
|
|
+| `decode_jobs` | 单帖解构任务 |
|
|
|
+| `decode_results` | 读懂文本、创作闸结果、拆颗摘要 |
|
|
|
+| `knowledge_particles` | What/How/Why 知识颗 |
|
|
|
+| `scope_results` | 作用域定位:实质、形式、感受、作用、意图 |
|
|
|
+| `payload_drafts` | 待审核或待入库 payload |
|
|
|
+| `ingest_records` | 入正式知识库记录 |
|
|
|
+| `contract_snapshots` | skill、prompt、schema 版本快照 |
|
|
|
+
|
|
|
+字段原则:
|
|
|
+
|
|
|
+- 每张表都有业务 id、状态、来源、错误、创建时间、更新时间。
|
|
|
+- 大型证据、原始平台回包、模型返回用 JSONB 保存。
|
|
|
+- 媒体不要塞进 item 的字符串数组,拆到 `media_assets`。
|
|
|
+- query 文本可能重复,正式 API 应优先用 query id。
|
|
|
+
|
|
|
+### 2.4 本步骤验收
|
|
|
+
|
|
|
+- 空库执行 migration 成功。
|
|
|
+- migration 可重复执行或有明确版本记录。
|
|
|
+- 本地通过 `CK_DB_*` 能连到云端正式库。
|
|
|
+- 能写入一个 query batch、一个 query、一个 acquisition run。
|
|
|
+- 不依赖 `CK_SQLITE_PATH`。
|
|
|
+
|
|
|
+### 2.4.1 本步骤清理闸门
|
|
|
+
|
|
|
+第二步完成后,重点不是删业务代码,而是防止云端施工副产物进入仓库:
|
|
|
+
|
|
|
+| 对象 | 处理方式 | 说明 |
|
|
|
+|---|---|---|
|
|
|
+| 云机真实 `.env`、数据库密码、连接串 | 不进仓库 | 只放本地或云机安全路径 |
|
|
|
+| SSH 私钥、云机账号文件 | 不进仓库 | 继续留在本机配置目录 |
|
|
|
+| 数据库备份文件 | 不进仓库 | 只留云机备份目录 |
|
|
|
+| 临时 SQL、psql 输出、连接测试日志 | 删除或外部归档 | 不作为项目源代码 |
|
|
|
+| `OPEN_AIGC_PG_*` 配置 | 保留但降级用途 | 只用于上游分类树/历史连接,不再当本系统状态库 |
|
|
|
+| `CK_SQLITE_PATH` | 不新增正式引用 | 旧 demo 可以继续用,正式代码不能继续接入 |
|
|
|
+
|
|
|
+本步骤不删除 `acquisition/store.py` 和旧 SQLite runner,因为正式 repository 还没有接管业务流。
|
|
|
+
|
|
|
+### 2.5 2026-06-30 执行记录
|
|
|
+
|
|
|
+本步骤已真实在阿里云海外 lsh 开发机执行,记录非敏感事实如下:
|
|
|
+
|
|
|
+- 已安装 PostgreSQL server/client,版本为 PostgreSQL 18.4。
|
|
|
+- 已新建正式库 `creation_knowledge_prod`。
|
|
|
+- 已新建应用角色 `ck_app`。
|
|
|
+- 已新建 schema `creation_knowledge`。
|
|
|
+- 已执行 `db/migrations/001_creation_knowledge_schema.sql`。
|
|
|
+- migration 已重放验证,可以重复执行。
|
|
|
+- `ck_app` 默认 `search_path` 已设置为 `creation_knowledge, public`。
|
|
|
+- 云机上真实 `CK_DB_*` 写入 `/home/sam/.config/create-knowledge/creation_knowledge_prod.env`,权限为用户私有;仓库不保存密码。
|
|
|
+- 本地 `.env` 已写入 `CK_DB_*`,通过 SSH tunnel 连接云端数据库;`.env` 已被 `.gitignore` 忽略。
|
|
|
+- 云端 PostgreSQL 只监听本机地址,本地开发通过 SSH tunnel 访问,不开放无边界公网 5432。
|
|
|
+- 已配置每日备份:`/usr/local/sbin/backup_creation_knowledge_pg.sh`,cron 位于 `/etc/cron.d/creation_knowledge_pg_backup`,备份目录为 `/var/backups/creation_knowledge`,当前策略保留 14 天。
|
|
|
+- 已做本地写入回滚验证:可以通过应用用户写入 `query_batches`、`queries`、`acquisition_runs` 并回滚。
|
|
|
+
|
|
|
+## 3. 本地建立模型、Schema、Repository
|
|
|
+
|
|
|
+当前依赖已经有 `pydantic`、`psycopg2-binary`、`fastapi`,没有 SQLAlchemy/Alembic。第一版采用:
|
|
|
+
|
|
|
+```text
|
|
|
+SQL migration + Pydantic model/schema + psycopg2 repository
|
|
|
+```
|
|
|
+
|
|
|
+### 3.1 新建目录
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+db/migrations/
|
|
|
+app/
|
|
|
+app/routes/
|
|
|
+app/frontend/
|
|
|
+acquisition/repositories/
|
|
|
+acquisition/queries/
|
|
|
+acquisition/platforms/
|
|
|
+acquisition/media/
|
|
|
+acquisition/classification/
|
|
|
+decode_content/
|
|
|
+decode_content/readers/
|
|
|
+pipeline/
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 新建核心文件
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+| 文件 | 负责什么 |
|
|
|
+|---|---|
|
|
|
+| `core/db_session.py` | 正式 PG 连接、事务、读写边界 |
|
|
|
+| `acquisition/domain.py` | Query、Run、Job、Item、MediaAsset、Classification |
|
|
|
+| `acquisition/repositories/base.py` | AcquisitionRepository 接口 |
|
|
|
+| `acquisition/repositories/postgres.py` | 云端 PG 实现 |
|
|
|
+| `decode_content/models.py` | ReadResult、Knowledge、Scope、PayloadDraft |
|
|
|
+| `decode_content/repository.py` | decode 结果、知识颗、payload draft 写库 |
|
|
|
+| `pipeline/models.py` | PipelineRun、PipelineJob、Resume 状态 |
|
|
|
+| `pipeline/repository.py` | pipeline 状态读写 |
|
|
|
+| `app/schemas.py` | 前端 API 返回结构 |
|
|
|
+
|
|
|
+`core/db.py` 保留给上游分类树读取。
|
|
|
+`core/db_session.py` 负责本系统正式状态库。两者不要混在一起。
|
|
|
+
|
|
|
+### 3.3 Repository 约定
|
|
|
+
|
|
|
+正式业务代码只依赖接口,不直接操作 psycopg2 cursor。
|
|
|
+
|
|
|
+`AcquisitionRepository` 至少提供:
|
|
|
+
|
|
|
+- 创建 query batch。
|
|
|
+- 读取待跑 query。
|
|
|
+- 创建 acquisition run。
|
|
|
+- 创建或更新 job。
|
|
|
+- 写 candidate item。
|
|
|
+- 写 media asset。
|
|
|
+- 写 item classification。
|
|
|
+- 查询 summary/detail 给前端。
|
|
|
+
|
|
|
+`DecodeRepository` 至少提供:
|
|
|
+
|
|
|
+- 领取待 decode item。
|
|
|
+- 写 read result。
|
|
|
+- 写 gate result。
|
|
|
+- 写 knowledge particles。
|
|
|
+- 写 scope results。
|
|
|
+- 写 payload draft。
|
|
|
+
|
|
|
+`PipelineRepository` 至少提供:
|
|
|
+
|
|
|
+- 创建 pipeline run。
|
|
|
+- 标记 step 状态。
|
|
|
+- 记录失败和重试。
|
|
|
+- 查询断点续跑位置。
|
|
|
+
|
|
|
+### 3.4 本步骤验收
|
|
|
+
|
|
|
+- 单元测试可用 fake repository 跑 acquisition/decode,不需要真实 DB。
|
|
|
+- 集成测试可用临时 PG schema 跑 migration。
|
|
|
+- 正式代码没有新增 SQLite 依赖。
|
|
|
+
|
|
|
+### 3.4.1 本步骤清理闸门
|
|
|
+
|
|
|
+第三步完成后,要清理的是“重复状态源”和“错误引用”,不是急着删旧业务能力:
|
|
|
+
|
|
|
+| 对象 | 处理方式 | 说明 |
|
|
|
+|---|---|---|
|
|
|
+| 新正式代码里对 `acquisition.store` 的引用 | 必须删除 | 正式模型、repository、schema 不允许依赖 SQLite |
|
|
|
+| 新正式代码里对 `CK_SQLITE_PATH` 的引用 | 必须删除 | 正式状态源只能走 `CK_DB_*` |
|
|
|
+| `core/db.py` | 保留 | 仍用于上游 Open AIGC/分类树连接 |
|
|
|
+| `core/db_session.py` | 保留 | 本系统正式状态库连接入口 |
|
|
|
+| `acquisition/store.py` | 暂时保留为 legacy | 等 Step4/Step6 替代旧 runner/API 后再归档 |
|
|
|
+| 只为新目录占位的空文件 | 保留或删除都可以 | 只要不误导为已实现业务即可 |
|
|
|
+
|
|
|
+检查命令建议:
|
|
|
+
|
|
|
+```text
|
|
|
+rg "acquisition.store|CK_SQLITE_PATH|data/app.db" core acquisition decode_content pipeline app scripts
|
|
|
+```
|
|
|
+
|
|
|
+如果命中发生在 legacy 文件里,可以保留;如果命中发生在正式新模块里,必须改掉。
|
|
|
+
|
|
|
+### 3.5 2026-06-30 执行记录
|
|
|
+
|
|
|
+本步骤已完成第一版本地骨架,记录如下:
|
|
|
+
|
|
|
+- 已新增 `core/db_session.py`,作为正式 `CK_DB_*` 云端 PostgreSQL 连接入口。
|
|
|
+- 已在 `core/config.py` 新增 `CreationDbConfig`,明确区别于仍用于上游 Open AIGC 的 `PgConfig`。
|
|
|
+- 已新增 `acquisition/domain.py`,覆盖 QueryBatch、Query、AcquisitionRun、AcquisitionJob、CandidateItem、MediaAsset、ItemClassification。
|
|
|
+- 已新增 `acquisition/repositories/base.py` 和 `acquisition/repositories/postgres.py`,提供正式 acquisition repository 接口与 PostgreSQL 实现。
|
|
|
+- 已新增 `decode_content/models.py` 和 `decode_content/repository.py`,先定义读懂、创作闸、知识颗、作用域、payload draft、contract snapshot 的模型与仓储合同,不迁移执行逻辑。
|
|
|
+- 已新增 `pipeline/models.py` 和 `pipeline/repository.py`,先定义 orchestration/resume 的状态对象与仓储合同;是否新建 pipeline 专用表留到后续 migration 决策。
|
|
|
+- 已新增 `app/schemas.py`,作为正式工作台 API DTO 起点。
|
|
|
+- 已新增正式目录占位:`app/routes/`、`app/frontend/`、`decode_content/readers/`、`acquisition/queries/`、`acquisition/platforms/`、`acquisition/media/`、`acquisition/classification/`。
|
|
|
+- 没有让正式代码新增 SQLite 依赖,旧 `acquisition/store.py` 仍只作为 legacy/local-demo adapter。
|
|
|
+- 已用云端正式库做 repository 回滚验证:创建 query batch、query、run、job、candidate item、media asset、classification,查询 summary/detail 后 rollback。
|
|
|
+- 当前未迁移 `scripts/decompose.py` 的旧 `web/` 写盘,也未修 `dim_attributes` 合同漂移;这些按计划留到 `decode_content/contracts.py` 与 `payloads.py` 阶段。
|
|
|
+
|
|
|
+## 4. 改造 Acquisition
|
|
|
+
|
|
|
+### 4.1 Query 生成与筛选
|
|
|
+
|
|
|
+移动:
|
|
|
+
|
|
|
+- `scripts/build_creation_demo.py` 核心逻辑 -> `acquisition/queries/builder.py`
|
|
|
+- `acquisition/query_filter.py` -> `acquisition/queries/filter.py`
|
|
|
+
|
|
|
+变化:
|
|
|
+
|
|
|
+- 不再默认写 `data/queries/creation_demo.json`。
|
|
|
+- 生成结果写入云端 `query_batches` 和 `queries`。
|
|
|
+- 记录 query 生成方式、筛选结果、筛选 prompt 版本。
|
|
|
+
|
|
|
+保留:
|
|
|
+
|
|
|
+- 当前正交组合思路。
|
|
|
+- `keep/reason/valid/relevant` 这类业务判断。
|
|
|
+
|
|
|
+### 4.2 平台搜索与详情抓取
|
|
|
+
|
|
|
+拆分:
|
|
|
+
|
|
|
+```text
|
|
|
+acquisition/platforms/base.py
|
|
|
+acquisition/platforms/xiaohongshu.py
|
|
|
+acquisition/platforms/weixin.py
|
|
|
+acquisition/platforms/douyin.py
|
|
|
+```
|
|
|
+
|
|
|
+从现有文件迁移:
|
|
|
+
|
|
|
+- `acquisition/search.py`
|
|
|
+- `acquisition/crawler.py`
|
|
|
+- `acquisition/creation_search.py` 中 `_process_xhs/_process_weixin/_process_douyin`
|
|
|
+
|
|
|
+统一接口:
|
|
|
+
|
|
|
+- `search(query) -> Candidate[]`
|
|
|
+- `fetch_detail(candidate) -> PostLike`
|
|
|
+- `normalize(raw) -> CandidateItem`
|
|
|
+
|
|
|
+不要强行把三个平台字段抹平到失真:
|
|
|
+
|
|
|
+- 小红书和微信偏图文/文章。
|
|
|
+- 抖音偏视频,需要 account/cookie batch 和视频 URL。
|
|
|
+- 平台差异进入 adapter 内部,业务层只看统一候选对象。
|
|
|
+
|
|
|
+### 4.3 媒体转 OSS/CDN
|
|
|
+
|
|
|
+移动:
|
|
|
+
|
|
|
+- `acquisition/oss.py` -> `acquisition/media/oss_client.py`
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+- `acquisition/media/service.py`
|
|
|
+
|
|
|
+正式行为:
|
|
|
+
|
|
|
+- 小红书图片转 OSS/CDN。
|
|
|
+- 微信图片转 OSS/CDN。
|
|
|
+- 抖音视频转 OSS/CDN。
|
|
|
+- DB 只保存媒体资产记录和 CDN URL。
|
|
|
+- 不再把正式媒体写到本地 `/data/media/...`。
|
|
|
+
|
|
|
+注意:
|
|
|
+
|
|
|
+- 旧本地落盘只作为 local-demo 或测试辅助。
|
|
|
+- 图文粗分类要支持直接使用 HTTP(S) 图片 URL。
|
|
|
+
|
|
|
+### 4.4 粗分类
|
|
|
+
|
|
|
+移动:
|
|
|
+
|
|
|
+- `acquisition/classify.py` -> `acquisition/classification/coarse.py`
|
|
|
+
|
|
|
+改造:
|
|
|
+
|
|
|
+- 图文支持 CDN 图片 URL,不再依赖本地 `/data/...` 转 base64。
|
|
|
+- 视频继续支持 CDN URL。
|
|
|
+- 粗分类结果写 `item_classifications`。
|
|
|
+- 记录模型、prompt 版本、失败原因。
|
|
|
+
|
|
|
+### 4.5 Runner 与 CLI
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+acquisition/runner.py
|
|
|
+scripts/run_acquisition.py
|
|
|
+```
|
|
|
+
|
|
|
+替代:
|
|
|
+
|
|
|
+- `scripts/run_creation_search.py`
|
|
|
+- `acquisition/creation_search.py` 中直接操作 SQLite 的部分
|
|
|
+
|
|
|
+正式 runner 做这些事:
|
|
|
+
|
|
|
+1. 从云端读取 query batch。
|
|
|
+2. 创建 acquisition run。
|
|
|
+3. 为每条 query 和每个平台创建 job。
|
|
|
+4. 搜索、详情、媒体转存、粗分类。
|
|
|
+5. 写 candidate item、media asset、classification。
|
|
|
+6. 更新 job 状态:pending、running、done、partial、failed。
|
|
|
+7. 支持 resume 和 skip done。
|
|
|
+
|
|
|
+### 4.6 本步骤验收
|
|
|
+
|
|
|
+- 可以用一个 query batch 跑三平台 mock。
|
|
|
+- 不创建 `data/app.db`。
|
|
|
+- 不读取 `/data/queries/creation_demo.json`。
|
|
|
+- item 媒体全是 CDN/OSS URL 或明确失败状态。
|
|
|
+- 粗分类写入云端 DB。
|
|
|
+
|
|
|
+### 4.6.1 本步骤清理闸门
|
|
|
+
|
|
|
+第四步完成后,Acquisition 相关旧入口要分三类处理:
|
|
|
+
|
|
|
+| 对象 | 本步骤处理方式 | 后续删除条件 |
|
|
|
+|---|---|---|
|
|
|
+| `scripts/build_creation_demo.py` | 保留为正式薄入口 | 不删;它已不再默认写本地 JSON |
|
|
|
+| `acquisition/query_filter.py` | 保留为 shim | 等旧脚本全部改 import 后,可移除 |
|
|
|
+| `scripts/run_acquisition.py` | 保留 | 正式采集 CLI |
|
|
|
+| `acquisition/runner.py` | 保留 | 正式采集 runner |
|
|
|
+| `scripts/run_creation_search.py` | 暂时保留为 legacy | 正式 API/前端不再读 legacy summary,真实 query batch 跑通后归档 |
|
|
|
+| `acquisition/creation_search.py` | 暂时保留为 legacy/迁移来源 | 平台 adapter、media service、coarse classifier 的真实平台测试覆盖后归档 |
|
|
|
+| `acquisition/store.py` | 暂时保留为 legacy SQLite adapter | API、runner、前端全不依赖 SQLite 后归档 |
|
|
|
+| `scripts/classify_creation_items.py` | 暂时保留为 legacy 补判脚本 | 正式 item classification 重判脚本补齐后归档 |
|
|
|
+| `data/queries/creation_demo.json` | 如果由新流程生成,删除或外部归档 | 正式 query batch 写云端 DB,不再靠本地 JSON |
|
|
|
+| `data/media/*` 新增正式媒体 | 不允许新增 | 正式媒体进入 OSS/CDN 和 `media_assets` |
|
|
|
+
|
|
|
+检查命令建议:
|
|
|
+
|
|
|
+```text
|
|
|
+rg "creation_demo.json|data/app.db|CK_SQLITE_PATH|acquisition.store" acquisition scripts app tests
|
|
|
+```
|
|
|
+
|
|
|
+正式新模块不应命中这些旧状态源;legacy 文件命中可以保留,但要在下一步继续追踪。
|
|
|
+
|
|
|
+### 4.7 2026-06-30 执行记录
|
|
|
+
|
|
|
+本轮已完成第一版 Acquisition 正式链路拆分,没有删除 legacy SQLite runner:
|
|
|
+
|
|
|
+- 已新增 `acquisition/queries/builder.py`,承接原 `scripts/build_creation_demo.py` 的正交 query 生成核心。
|
|
|
+- 已新增 `acquisition/queries/filter.py`,`acquisition/query_filter.py` 退为兼容 shim。
|
|
|
+- 已将 `scripts/build_creation_demo.py` 改成薄入口:默认只打印摘要;只有显式 `--export-json` 才导出本地 JSON,只有显式 `--persist` 才写正式 PG。
|
|
|
+- 已新增三平台 adapter:`acquisition/platforms/xiaohongshu.py`、`weixin.py`、`douyin.py`。
|
|
|
+- 已新增 `acquisition/media/service.py`,统一把图片/视频转成可入库的媒体记录;OSS 失败时保留原 URL,不丢候选 item。
|
|
|
+- 已新增 `acquisition/classification/coarse.py`,正式粗分类支持 HTTP(S) 图片 URL;同时补了旧 `acquisition.classify.classify_imgtext`,避免 legacy 补判在 CDN 图片下丢视觉输入。
|
|
|
+- 已新增 `acquisition/runner.py` 和 `scripts/run_acquisition.py`,正式入口从云端 query batch 读取 query,创建 run/job,写候选 item、media asset、classification,并支持 skip done。
|
|
|
+- 明确保留 `scripts/run_creation_search.py`、`acquisition/creation_search.py`、`acquisition/store.py` 为 legacy/local-demo 路径,本轮不改其 SQLite 语义。
|
|
|
+
|
|
|
+交叉验证结论:
|
|
|
+
|
|
|
+- Query 生成/筛选、平台/媒体/粗分类、正式 runner/CLI 三条 SubAgent 只读检查均确认:新链路应走 repository,不再从默认本地 query JSON 或 SQLite 取正式状态。
|
|
|
+- 新增测试覆盖 fake repository 跑 acquisition batch、skip done、媒体 service、HTTP 图片粗分类、query batch 持久化合同、CLI 薄委托。
|
|
|
+- 本地验证:`.venv/bin/pytest -q` 通过,`96 passed`;`.venv/bin/python -m compileall acquisition scripts core app decode_content pipeline tests` 通过;`git diff --check` 通过。
|
|
|
+
|
|
|
+### 4.8 2026-06-30 清理闸门执行记录
|
|
|
+
|
|
|
+按 Step1-4 清理闸门做了第二轮实际清理:
|
|
|
+
|
|
|
+- 已删除本地运行产物:`runtime/`、空的 `web/runs/`、Python `__pycache__/`。
|
|
|
+- 已把 `acquisition/platforms/weixin.py` 中对 `acquisition.creation_search._hash` 的依赖改为 adapter 内部实现,避免正式平台 adapter import legacy runner。
|
|
|
+- 已将默认测试里的旧 SQLite/query demo/creation search 测试迁到 `archive/2026-06-30-step4/legacy_tests/`:
|
|
|
+ - `tests/test_store.py`
|
|
|
+ - `tests/test_creation_search.py`
|
|
|
+ - `tests/test_query.py`
|
|
|
+- 已保留 `tests/test_decompose_helpers.py`,因为 Step5 decode_content 迁移尚未执行,暂时仍需要它保护旧 decode helper 行为。
|
|
|
+- 已脱敏 `db/README.md` 的 SSH tunnel 示例,不保留本机私钥绝对路径。
|
|
|
+- 已把旧《产品文档》《技术文档》进一步标注为历史 demo 说明,避免继续把本地 JSON / 旧 `web/index.html` 写成正式入口。
|
|
|
+
|
|
|
+本轮 SubAgent 交叉验证结论:
|
|
|
+
|
|
|
+- Step1 原始 legacy 文件已不在原路径。
|
|
|
+- Step2 未发现真实 DB 密码、私钥、psql 日志进入仓库;`.env.example` 只保留模板。
|
|
|
+- Step3/4 正式 runner、CLI、query builder、repository 不读 SQLite、不读 `creation_demo.json`、不写 `data/app.db`。
|
|
|
+- 仍按计划暂留为 legacy/迁移来源的文件:`acquisition/store.py`、`acquisition/creation_search.py`、`scripts/run_creation_search.py`、`acquisition/web_api.py`、`acquisition/web/app/`。这些会在 Step5/6 后继续清理。
|
|
|
+
|
|
|
+## 5. 改造 Decode Content
|
|
|
+
|
|
|
+改造前,读懂、创作闸、拆颗、作用域和 payload 主要压在 `scripts/decompose.py` 与 `creation_knowledge/integrations/`。
|
|
|
+
|
|
|
+### 5.1 新建合同层
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+decode_content/contracts.py
|
|
|
+```
|
|
|
+
|
|
|
+职责:
|
|
|
+
|
|
|
+- 加载 `创作知识提取-skill/extraction/phase1-frame.md`。
|
|
|
+- 加载 `phase2-scope.md`。
|
|
|
+- 加载 `phase3-assemble.md`。
|
|
|
+- 加载 schema、taxonomy、prompt。
|
|
|
+- 计算合同版本 hash。
|
|
|
+- 写入 `contract_snapshots`。
|
|
|
+
|
|
|
+原则:
|
|
|
+
|
|
|
+- 保留 `创作知识提取-skill/`。
|
|
|
+- 不把它散落复制到别的目录。
|
|
|
+- 每次 decode 都能追溯当时使用的合同版本。
|
|
|
+
|
|
|
+### 5.2 读懂层
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+decode_content/readers/imgtext.py
|
|
|
+decode_content/readers/video.py
|
|
|
+decode_content/readers/video_frames.py
|
|
|
+decode_content/readers/service.py
|
|
|
+```
|
|
|
+
|
|
|
+迁移:
|
|
|
+
|
|
|
+- `creation_knowledge/integrations/extractor.py` -> `imgtext.py`
|
|
|
+- `creation_knowledge/integrations/video_extract.py` -> `video.py`
|
|
|
+- `creation_knowledge/integrations/video_frames.py` -> `video_frames.py`
|
|
|
+- `scripts/decompose.py::read_one` -> `readers/service.py`
|
|
|
+
|
|
|
+正式行为:
|
|
|
+
|
|
|
+- 输入:candidate item + media assets。
|
|
|
+- 输出:read text、cards、media refs、is_empty。
|
|
|
+- 不负责写 web 文件。
|
|
|
+- 不负责 payload。
|
|
|
+
|
|
|
+### 5.3 创作闸与质量闸
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+decode_content/gates.py
|
|
|
+```
|
|
|
+
|
|
|
+迁移:
|
|
|
+
|
|
|
+- `creation_gate`
|
|
|
+- how admit/refute/tiebreak
|
|
|
+- why refute
|
|
|
+
|
|
|
+正式行为:
|
|
|
+
|
|
|
+- 创作闸只看读懂结果,不靠标题关键词硬判。
|
|
|
+- How 闸防止假流程。
|
|
|
+- Why 轻闸只过滤空泛废话,不随意丢失信息。
|
|
|
+
|
|
|
+### 5.4 拆颗与作用域
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+decode_content/framing.py
|
|
|
+decode_content/scoping.py
|
|
|
+```
|
|
|
+
|
|
|
+`framing.py` 负责:
|
|
|
+
|
|
|
+- 调 phase1。
|
|
|
+- 产出 What/How/Why 知识颗。
|
|
|
+- 假 How 重拆。
|
|
|
+- 受控值守卫。
|
|
|
+- 组件颗 parent 校验。
|
|
|
+
|
|
|
+`scoping.py` 负责:
|
|
|
+
|
|
|
+- 调 phase2。
|
|
|
+- 候选 scope。
|
|
|
+- 名词化。
|
|
|
+- 连接词拆原子。
|
|
|
+- 调 `ScopeLinker`。
|
|
|
+- 决定复用或新建。
|
|
|
+
|
|
|
+### 5.5 Payload 组装
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+decode_content/payloads.py
|
|
|
+```
|
|
|
+
|
|
|
+目标:
|
|
|
+
|
|
|
+- 成为唯一 payload assembler。
|
|
|
+- 取代 `scripts/decompose.py` 与 `scripts/rebuild_payloads.py` 的重复逻辑。
|
|
|
+- 一颗知识生成一个 payload draft。
|
|
|
+- payload 写入云端 `payload_drafts`。
|
|
|
+
|
|
|
+同时修正合同漂移:
|
|
|
+
|
|
|
+- 统一 `dim_attributes` 口径。
|
|
|
+- 统一 How step 的 `input/directive/output`。
|
|
|
+- What/Why content 统一为正式 ingest 接口可接受的字符串形态。
|
|
|
+
|
|
|
+### 5.6 Decode Service
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+decode_content/service.py
|
|
|
+scripts/run_decode_content.py
|
|
|
+```
|
|
|
+
|
|
|
+`decode_content/service.py` 提供:
|
|
|
+
|
|
|
+```text
|
|
|
+decode_item(item_id) -> DecodeResult
|
|
|
+```
|
|
|
+
|
|
|
+它串起:
|
|
|
+
|
|
|
+```text
|
|
|
+load candidate -> read -> creation gate -> frame -> scope -> payload draft -> write db
|
|
|
+```
|
|
|
+
|
|
|
+`scripts/decompose.py` 最终只保留为 legacy/调试入口。
|
|
|
+
|
|
|
+### 5.7 本步骤验收
|
|
|
+
|
|
|
+- 用 fixture item 可以跑完整 decode。
|
|
|
+- 每次 decode 都写 contract version。
|
|
|
+- payload 组装只有一处实现。
|
|
|
+- 不再从正式链路写 `web/frameworks.json`。
|
|
|
+
|
|
|
+### 5.7.1 本步骤清理闸门
|
|
|
+
|
|
|
+第五步完成后,Decode 相关旧入口要开始真正降级:
|
|
|
+
|
|
|
+| 对象 | 本步骤处理方式 | 后续删除条件 |
|
|
|
+|---|---|---|
|
|
|
+| `scripts/decompose.py` | 改成 legacy/调试入口,或迁入归档 | `decode_content/service.py` 能跑完整 fixture 后归档 |
|
|
|
+| `scripts/rebuild_payloads.py` | 保持归档,不再恢复到主干 | `decode_content/payloads.py` 是唯一 payload assembler |
|
|
|
+| `creation_knowledge/integrations/extractor.py` | 迁到 `decode_content/readers/imgtext.py` 后归档 | 新 reader 测试通过且无正式 import |
|
|
|
+| `creation_knowledge/integrations/video_extract.py` | 迁到 `decode_content/readers/video.py` 后归档 | 新 video reader 测试通过且无正式 import |
|
|
|
+| `creation_knowledge/integrations/video_frames.py` | 迁到 `decode_content/readers/video_frames.py` 后归档 | 抽帧测试通过且无正式 import |
|
|
|
+| 旧 `web/frameworks*.json` 写盘逻辑 | 删除 | 正式 decode 只写云端 decode/payload 表 |
|
|
|
+| 旧 payload 组装函数副本 | 删除 | payload 逻辑只能留在 `decode_content/payloads.py` |
|
|
|
+
|
|
|
+检查命令建议:
|
|
|
+
|
|
|
+```text
|
|
|
+rg "web/frameworks|web/payloads|creation_knowledge.integrations|rebuild_payloads" scripts creation_knowledge decode_content tests
|
|
|
+```
|
|
|
+
|
|
|
+正式链路里不允许再写旧 `web/` JSON;如果旧脚本还需要保留,只能明确标为 legacy。
|
|
|
+
|
|
|
+### 5.8 2026-06-30 执行记录
|
|
|
+
|
|
|
+本轮已完成 Step5 第一轮正式迁移:
|
|
|
+
|
|
|
+- 新增 `decode_content/contracts.py`,集中加载 `创作知识提取-skill` 的 README、phase、schema、taxonomy、gate/normalize prompts 和 `scope_trees` cache 元信息,生成合同 hash 与 `ContractSnapshot`。
|
|
|
+- 新增 `decode_content/readers/`,图文、整段视频、抽帧兜底 reader 已迁入正式包;正式 reader 入口支持 `CandidateItem + MediaAsset[] -> ReadResult`,不再依赖旧 `src["from"]`、本地 `/data/demo` 或 web JSON。
|
|
|
+- 新增 `decode_content/gates.py`、`framing.py`、`scoping.py`、`payloads.py`、`service.py`,把创作闸、How/Why 质量闸、What/How/Why 拆颗、作用域定位、payload 组装和单帖 decode 编排拆到正式模块。
|
|
|
+- `decode_content/payloads.py` 已统一正式 `dim_attributes`:`how工序 / what构成 / why原理`;What/Why content 按正式 ingest 边界输出字符串。
|
|
|
+- `DecodeService` 每次 decode 会写合同快照;空内容或创作闸未通过会短路,只保存 read/gate/decode 状态,不生成 particles/payload drafts。
|
|
|
+- 新增 `core/media_download.py`,把原来散在旧视频 reader 里的下载字节能力上提为共享工具;正式 acquisition/decode 不再 import `creation_knowledge.integrations`。
|
|
|
+- 新增 `scripts/run_decode_content.py` 作为薄 CLI;正式 DB item 加载留到 Step6 pipeline/API 继续接。
|
|
|
+- `scripts/decompose.py` 已标为 `LEGACY/debug`,保留旧 demo 调试能力,但不再作为正式链路。
|
|
|
+
|
|
|
+本步骤清理结果:
|
|
|
+
|
|
|
+- 已归档 `tests/test_decompose_helpers.py` 到 `archive/2026-06-30-step5/legacy_tests/`。
|
|
|
+- 默认测试已迁到正式模块:`tests/test_decode_contracts.py`、`tests/test_decode_readers_service.py`、`tests/test_decode_payloads.py`、`tests/test_decode_gates_framing_scoping.py`、`tests/test_decode_service.py`。
|
|
|
+- `tests/test_extractor.py`、`tests/test_video_extract.py`、`tests/test_video_frames.py` 已改为从 `decode_content.readers.*` 导入,继续保护 reader 行为。
|
|
|
+
|
|
|
+交叉验证结论:
|
|
|
+
|
|
|
+- SubAgent 确认 reader 不应继承旧 `src["from"]`、本地 `/data/demo`、reader 内 OSS 转存或 web 写盘行为;本轮已按 `CandidateItem + MediaAsset[]` 建正式 reader 输入。
|
|
|
+- SubAgent 确认 `scripts/decompose.py::process_one/_run/write_run/main` 不应进入正式 service;本轮仅迁移业务能力,旧脚本保留为 legacy/debug。
|
|
|
+- SubAgent 确认合同层要记录 phase/schema/taxonomy/prompt/scope cache 与漂移;本轮已在 `contracts.py` 记录正式常量与漂移说明。
|
|
|
+
|
|
|
+本地验证:
|
|
|
+
|
|
|
+```text
|
|
|
+.venv/bin/pytest -q tests/test_decode_contracts.py tests/test_decode_readers_service.py tests/test_decode_payloads.py tests/test_decode_gates_framing_scoping.py tests/test_decode_service.py tests/test_extractor.py tests/test_video_extract.py tests/test_video_frames.py
|
|
|
+23 passed
|
|
|
+.venv/bin/pytest -q
|
|
|
+84 passed
|
|
|
+rg "creation_knowledge\\.integrations|web/frameworks|web/payloads|web/runs" decode_content tests scripts app pipeline acquisition -n
|
|
|
+只剩 scripts/decompose.py 这个 legacy/debug 入口命中
|
|
|
+```
|
|
|
+
|
|
|
+## 6. 补 Pipeline 与正式 API
|
|
|
+
|
|
|
+### 6.1 Pipeline
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+pipeline/acquisition_runner.py
|
|
|
+pipeline/decode_runner.py
|
|
|
+pipeline/creation_pipeline.py
|
|
|
+pipeline/dedupe.py
|
|
|
+```
|
|
|
+
|
|
|
+`creation_pipeline.py` 负责完整编排:
|
|
|
+
|
|
|
+```text
|
|
|
+query batch -> acquisition -> coarse classify -> decode candidates -> payload drafts -> ingest
|
|
|
+```
|
|
|
+
|
|
|
+`dedupe.py` 负责:
|
|
|
+
|
|
|
+- 同平台同 source_id 去重。
|
|
|
+- 跨 query 重复 URL 去重。
|
|
|
+- 同 item 不重复 decode。
|
|
|
+- 已 ingest payload 不重复写入。
|
|
|
+
|
|
|
+Pipeline 必须记录:
|
|
|
+
|
|
|
+- 当前 step。
|
|
|
+- run/job 状态。
|
|
|
+- 错误原因。
|
|
|
+- 重试次数。
|
|
|
+- 断点续跑位置。
|
|
|
+
|
|
|
+### 6.2 正式 API
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+app/api.py
|
|
|
+app/routes/acquisition.py
|
|
|
+app/routes/decode.py
|
|
|
+app/routes/payloads.py
|
|
|
+app/routes/runs.py
|
|
|
+```
|
|
|
+
|
|
|
+迁移:
|
|
|
+
|
|
|
+- `creation_knowledge/api.py` 的 FastAPI 壳 -> `app/api.py`
|
|
|
+- `acquisition/web_api.py` 的业务 API -> `app/routes/acquisition.py`
|
|
|
+
|
|
|
+正式 API 替换:
|
|
|
+
|
|
|
+| 旧接口 | 新接口 |
|
|
|
+|---|---|
|
|
|
+| `/api/creation-search/summary` | `/api/acquisition/runs/{run_id}/summary` |
|
|
|
+| `/api/creation-search/query?query=...` | `/api/acquisition/runs/{run_id}/queries/{query_id}` |
|
|
|
+| `/data/queries/creation_demo.json` | `/api/query-batches/{batch_id}` |
|
|
|
+| `/data/media/...` | DB 中的 OSS/CDN URL |
|
|
|
+
|
|
|
+API 原则:
|
|
|
+
|
|
|
+- 不再默认挂本地 `/data`。
|
|
|
+- 不再创建本地 media 目录。
|
|
|
+- 不再每请求打开 SQLite。
|
|
|
+- CORS 不再无脑 `*`,按部署环境配置。
|
|
|
+
|
|
|
+### 6.3 前端
|
|
|
+
|
|
|
+迁移:
|
|
|
+
|
|
|
+```text
|
|
|
+acquisition/web/app/src -> app/frontend/src
|
|
|
+```
|
|
|
+
|
|
|
+保留:
|
|
|
+
|
|
|
+- query 列表页骨架。
|
|
|
+- query 详情页骨架。
|
|
|
+- 三平台候选展示。
|
|
|
+- 创作知识/非创作知识分组思路。
|
|
|
+
|
|
|
+改造:
|
|
|
+
|
|
|
+- 去掉 `/data/queries/creation_demo.json`。
|
|
|
+- 去掉 `/api/creation-search/*`。
|
|
|
+- 改用正式 API。
|
|
|
+- 增加 pipeline run 状态。
|
|
|
+- 增加 decode 结果视图。
|
|
|
+- 增加 payload draft / ingest 状态视图。
|
|
|
+
|
|
|
+### 6.4 本步骤验收
|
|
|
+
|
|
|
+- `uvicorn app.api:app` 能启动。
|
|
|
+- 前端不再请求 `/data/queries/creation_demo.json`。
|
|
|
+- 前端媒体全部来自 CDN/OSS URL。
|
|
|
+- API 不依赖 SQLite。
|
|
|
+
|
|
|
+### 6.4.1 本步骤清理闸门
|
|
|
+
|
|
|
+第六步完成后,旧 API、旧前端和顶层旧包要进入最终清理:
|
|
|
+
|
|
|
+| 对象 | 本步骤处理方式 | 后续删除条件 |
|
|
|
+|---|---|---|
|
|
|
+| `creation_knowledge/api.py` | 迁到 `app/api.py` 后归档 | `uvicorn app.api:app` 通过且前端改用正式 API |
|
|
|
+| `acquisition/web_api.py` | 迁到 `app/routes/acquisition.py` 后归档 | 新 acquisition API summary/detail 测试通过 |
|
|
|
+| `creation_knowledge/media.py` | 本步骤随旧顶层包归档 | 正式媒体只走 `acquisition/media/` 和 OSS/CDN |
|
|
|
+| `creation_knowledge/` 顶层包 | 本步骤整体归档 | 无正式 import,API/reader/media 都已迁完 |
|
|
|
+| `acquisition/store.py` | 本步骤归档 | 正式状态源改为 PostgreSQL repository |
|
|
|
+| `acquisition/creation_search.py` | 本步骤归档 | 平台搜索、媒体、分类、runner 能力已拆到正式模块 |
|
|
|
+| `scripts/run_creation_search.py` | 本步骤归档 | 正式采集入口改为 `scripts/run_acquisition.py` |
|
|
|
+| `scripts/classify_creation_items.py` | 本步骤归档 | 后续补正式 repository-backed 重判脚本 |
|
|
|
+| `scripts/filter_multiaxis.py` | 本步骤归档 | query 生成/筛选迁到 `acquisition/queries/*` |
|
|
|
+| `acquisition/backfill_weixin.py` | 本步骤归档 | 旧 SQLite 补抓链路退出主干 |
|
|
|
+| `acquisition/web/app/` | 迁到 `app/frontend/` 后归档旧位置 | 新前端能 build,且不再 fetch 本地 JSON |
|
|
|
+| 根目录 `web/` | 删除空目录或保持归档说明 | 正式前端不再使用 |
|
|
|
+| `/data` 静态挂载 | 从正式 API 删除 | 媒体和 query 都来自 DB/OSS/CDN |
|
|
|
+| `/api/creation-search/*` | 删除或只在 legacy 服务保留 | 前端、测试、文档都改成正式 API |
|
|
|
+
|
|
|
+检查命令建议:
|
|
|
+
|
|
|
+```text
|
|
|
+rg "creation_knowledge.api|acquisition.web_api|/api/creation-search|/data/queries|StaticFiles|CK_SQLITE_PATH" app acquisition pipeline tests
|
|
|
+```
|
|
|
+
|
|
|
+如果这一步后 `creation_knowledge/` 仍被正式代码引用,不能直接删;要先把最后的能力迁到 `app/` 或 `decode_content/`。
|
|
|
+
|
|
|
+### 6.5 2026-06-30 执行记录
|
|
|
+
|
|
|
+本步骤已按正式版方向落地第一轮代码改造:
|
|
|
+
|
|
|
+- 新增 `app/api.py`、`app/dependencies.py` 和 `app/routes/*`,正式入口切到 `app.api:app`。
|
|
|
+- 新增 acquisition 正式接口:query batch、run summary、query detail,不再走 `/api/creation-search/*`。
|
|
|
+- 新增 decode、payload、pipeline run 的正式 API 占位路由,未接仓储的部分明确返回未实现,而不是伪装成已完成。
|
|
|
+- 新增 `pipeline/acquisition_runner.py`、`pipeline/decode_runner.py`、`pipeline/creation_pipeline.py`、`pipeline/dedupe.py`,先把 acquisition 到 decode 的编排骨架接上。
|
|
|
+- 前端从 `acquisition/web/app` 迁到 `app/frontend`,列表页和详情页改为读取正式 API。
|
|
|
+- 前端不再请求 `/data/queries/creation_demo.json`,详情页媒体读取 item 里的 OSS/CDN URL。
|
|
|
+- 根 `.gitignore` 的前端构建产物例外从旧路径切到 `app/frontend/dist/`。
|
|
|
+- `creation_knowledge/api.py`、`acquisition/web_api.py` 归档到 `archive/2026-06-30-step6/legacy_api/`。
|
|
|
+- 旧 `acquisition/web/app/dist` 归档到 `archive/2026-06-30-step6/legacy_frontend/`,旧 `acquisition/web/app` 空目录已清理。
|
|
|
+- 顶层 `creation_knowledge/` 包整体归档到 `archive/2026-06-30-step6/legacy_creation_knowledge/`;`scripts/decompose.py` 这个 legacy/debug 入口改为引用 `decode_content/readers/*`。
|
|
|
+- `acquisition/store.py`、`acquisition/creation_search.py`、`acquisition/backfill_weixin.py` 归档到 `archive/2026-06-30-step6/legacy_sqlite/` 与 `legacy_acquisition/`。
|
|
|
+- `scripts/run_creation_search.py`、`scripts/classify_creation_items.py`、`scripts/filter_multiaxis.py` 归档到 `archive/2026-06-30-step6/legacy_scripts/`。
|
|
|
+- `acquisition/classify.py` 保留为正式粗分类可复用的模型判定函数,但移除旧 SQLite 批处理入口。
|
|
|
+- 旧本地 `/data` 媒体落盘测试归档到 `archive/2026-06-30-step6/legacy_tests/`。
|
|
|
+
|
|
|
+本地验证:
|
|
|
+
|
|
|
+```text
|
|
|
+.venv/bin/pytest -q
|
|
|
+90 passed
|
|
|
+
|
|
|
+cd app/frontend && npm ci && npm run build
|
|
|
+Vite build passed
|
|
|
+
|
|
|
+rg "(/data/queries|/api/creation-search|/api/filter-prompt|CK_SQLITE_PATH|creation_knowledge\\.api|acquisition\\.web_api)" app pipeline tests
|
|
|
+只剩 tests/test_app_api.py 里的反向断言命中
|
|
|
+```
|
|
|
+
|
|
|
+## 7. 测试计划
|
|
|
+
|
|
|
+### 7.1 数据库测试
|
|
|
+
|
|
|
+- migration 能在空库建表。
|
|
|
+- migration 重跑有明确处理方式。
|
|
|
+- 能插入 query batch、query、run、job。
|
|
|
+- 能从 repository 查询 summary/detail。
|
|
|
+
|
|
|
+### 7.2 Acquisition 测试
|
|
|
+
|
|
|
+- 三平台 adapter 用 mock 回包测试。
|
|
|
+- OSS client 解析 CDN URL。
|
|
|
+- 媒体 service 能把图片/视频写成 media assets。
|
|
|
+- 粗分类支持 HTTP 图片 URL 和视频 CDN URL。
|
|
|
+- resume、skip done、partial、failed 状态可测。
|
|
|
+
|
|
|
+### 7.3 Decode 测试
|
|
|
+
|
|
|
+- 图文读懂离线测试。
|
|
|
+- 视频读懂离线测试。
|
|
|
+- 创作闸 admit/refute/tiebreak 测试。
|
|
|
+- 假 How 重拆测试。
|
|
|
+- 作用域复用/新建测试。
|
|
|
+- payload draft 结构测试。
|
|
|
+
|
|
|
+### 7.4 Pipeline 测试
|
|
|
+
|
|
|
+- 从 query batch 到 acquisition run。
|
|
|
+- 从候选 item 到 decode result。
|
|
|
+- 从 knowledge particle 到 payload draft。
|
|
|
+- 失败任务可重试。
|
|
|
+- 已完成任务不会重复跑。
|
|
|
+
|
|
|
+### 7.5 API 与前端测试
|
|
|
+
|
|
|
+- API 合同测试不依赖 `CK_SQLITE_PATH`。
|
|
|
+- API 合同测试不依赖本地 `/data`。
|
|
|
+- 前端不再 fetch 本地 query JSON。
|
|
|
+- 前端能展示 run、item、classification、decode、payload、ingest 状态。
|
|
|
+
|
|
|
+### 7.6 Legacy 回归
|
|
|
+
|
|
|
+- 删除旧 demo 后,不再有测试 import `scripts.serve_old_web`。
|
|
|
+- `local-demo` 可作为旧数据回看来源。
|
|
|
+
|
|
|
+### 7.7 每轮清理回归
|
|
|
+
|
|
|
+每一轮改造结束,都要补一轮“反向测试”:确认正式路径没有重新长出旧依赖。
|
|
|
+
|
|
|
+固定检查:
|
|
|
+
|
|
|
+- 正式代码不 import `acquisition.store`。
|
|
|
+- 正式代码不读取 `data/queries/creation_demo.json`。
|
|
|
+- 正式代码不创建 `data/app.db`。
|
|
|
+- 正式 API 不挂本地 `/data` 作为业务数据源。
|
|
|
+- 前端不 fetch `/data/queries/*`。
|
|
|
+- 新测试不再断言 legacy 路径是正式入口。
|
|
|
+
|
|
|
+建议命令:
|
|
|
+
|
|
|
+```text
|
|
|
+rg "acquisition.store|CK_SQLITE_PATH|data/app.db|creation_demo.json|/data/queries|/api/creation-search|creation_knowledge.api" core acquisition decode_content pipeline app scripts tests
|
|
|
+```
|
|
|
+
|
|
|
+命中结果要分三类标注:
|
|
|
+
|
|
|
+- `formal`:必须修掉。
|
|
|
+- `legacy`:可以保留,但必须在文件或文档里说明。
|
|
|
+- `archive`:不参与正式测试和运行。
|
|
|
+
|
|
|
+### 7.8 2026-06-30 执行记录
|
|
|
+
|
|
|
+本步骤已把测试计划落成一批可离线运行的正式回归测试,不连接真实云库、不读本地 SQLite、不依赖 `/data`:
|
|
|
+
|
|
|
+- 新增 `tests/test_db_migration_contract.py`,检查正式 migration 包含 query、acquisition、decode、payload、ingest、contract snapshot 等业务表,且使用 PostgreSQL/JSONB/可重放写法,不退回 SQLite 形态。
|
|
|
+- 新增 `tests/test_postgres_repository_contract.py`,用 fake repository 边界验证 `PostgresAcquisitionRepository` 的 summary、query detail、creation candidate 查询都走正式 PG 表和正式 domain model。
|
|
|
+- 新增 `tests/test_platform_adapters.py`,用 mock 回包直接覆盖小红书、微信、抖音三平台 adapter 的 search/detail 映射。
|
|
|
+- 新增 `tests/test_decode_stage_full_chain.py`,把 candidate item、media asset、decode service、skill contract、payload draft 串成一条最小离线闭环。
|
|
|
+- 新增 `tests/test_legacy_cleanup_contract.py`,把正式源码不得依赖 SQLite、本地 `/data`、旧 API、旧 `creation_knowledge` 包的规则固化为测试;`scripts/decompose.py` 仅作为已标注的 legacy/debug 入口保留。
|
|
|
+- 扩展 `tests/test_acquisition_runner.py`,覆盖 skip done、partial、failed 三类采集状态。
|
|
|
+- 扩展 `tests/test_pipeline_formal.py`,覆盖 acquisition stage 成功/失败、decode stage 去重、完整 `creation_pipeline` 编排骨架。
|
|
|
+- 扩展 `tests/test_app_api.py`,确认旧顶层 `creation_knowledge/` 已归档,活跃源码不 import legacy store/package;decode、payload、pipeline route 在仓储未实现时明确返回 501,且在注入正式仓储后存在成功返回路径,不伪装成旧本地数据接口。
|
|
|
+- 继续保留前端 build 与 legacy 反向扫描作为每轮验收命令。
|
|
|
+
|
|
|
+本地验证:
|
|
|
+
|
|
|
+```text
|
|
|
+.venv/bin/pytest -q tests/test_db_migration_contract.py tests/test_postgres_repository_contract.py tests/test_acquisition_runner.py tests/test_pipeline_formal.py tests/test_app_api.py
|
|
|
+22 passed
|
|
|
+```
|
|
|
+
|
|
|
+仍然明确留到后续步骤:
|
|
|
+
|
|
|
+- `decode_content`、payload、pipeline 的正式 PostgreSQL repository 实现。
|
|
|
+- decode/payload/pipeline API 从 501 占位切到真实仓储读写。
|
|
|
+- 真实云库集成测试或部署烟测,必须在有明确环境变量和测试库隔离后再执行。
|
|
|
+
|
|
|
+## 8. 推荐提交顺序
|
|
|
+
|
|
|
+建议拆成这些提交,降低风险:
|
|
|
+
|
|
|
+1. `docs: add formal construction plan`
|
|
|
+2. `chore: archive legacy static demo`
|
|
|
+3. `chore: remove tracked env and add env example`
|
|
|
+4. `feat(db): add cloud postgres migration and session`
|
|
|
+5. `feat(acquisition): add domain and postgres repository`
|
|
|
+6. `feat(acquisition): migrate query and platform adapters`
|
|
|
+7. `feat(decode): add decode_content contract and readers`
|
|
|
+8. `feat(decode): add framing scoping payload service`
|
|
|
+9. `feat(pipeline): add cloud pipeline runners`
|
|
|
+10. `feat(app): add formal api and migrate frontend`
|
|
|
+11. `test: replace sqlite/local-data assumptions`
|
|
|
+
|
|
|
+## 9. 风险与处理
|
|
|
+
|
|
|
+| 风险 | 处理 |
|
|
|
+|---|---|
|
|
|
+| 云机 repo 与本地 main 不一致 | 施工前以本地新分支/新提交重新部署云机 |
|
|
|
+| `.env` 已被 tracked | 先 `git rm --cached .env`,再补 `.env.example` |
|
|
|
+| 旧 demo 删除影响回看 | 保留 `local-demo`,必要时外部归档 `web/*` |
|
|
|
+| `creation_knowledge/` 迁移影响 import | 分阶段迁移,先加新模块,再替换 import,最后删旧包 |
|
|
|
+| payload 合同漂移 | 先统一 `decode_content/contracts.py` 和 `payloads.py` |
|
|
|
+| 图文分类依赖本地图片 | 改成支持 HTTP(S) 图片 URL |
|
|
|
+| 云端数据库误用 Open AIGC PG | `CK_DB_*` 与 `OPEN_AIGC_PG_*` 明确分离 |
|
|
|
+
|
|
|
+## 10. 最终验收
|
|
|
+
|
|
|
+正式版完成后,应满足:
|
|
|
+
|
|
|
+- 主干不依赖本地 SQLite。
|
|
|
+- 主干不依赖 `legacy_data/`。
|
|
|
+- 主干不依赖旧 `web/index.html`。
|
|
|
+- 顶层正式业务目录不再使用 `creation_knowledge/`。
|
|
|
+- 一个云端 query batch 可以追踪到 search、item、classification、decode、payload、ingest。
|
|
|
+- 非创作知识候选不会进入深度 decode。
|
|
|
+- 每个 payload 都能追溯到原帖、媒体、skill contract 版本和作用域定位。
|
|
|
+- 前端默认进入正式工作台。
|
|
|
+- 旧 demo 只通过 `local-demo` 或归档路径访问。
|
|
|
+
|
|
|
+最终清理清单:
|
|
|
+
|
|
|
+- 主干没有根目录旧 `web/index.html`。
|
|
|
+- 主干没有旧 `web/frameworks.json`、`web/payloads.json`、`web/runs/*`。
|
|
|
+- 主干没有正式代码使用 `acquisition/store.py`。
|
|
|
+- 主干没有正式代码使用 `scripts/run_creation_search.py`。
|
|
|
+- 主干没有正式代码使用 `scripts/decompose.py` 作为主入口。
|
|
|
+- 主干没有顶层 `creation_knowledge/` 作为正式业务包。
|
|
|
+- 主干没有真实 `.env`、数据库密码、云机私钥。
|
|
|
+- 主干没有新产生的本地媒体、SQLite、query JSON 作为正式运行依赖。
|