|
|
@@ -0,0 +1,210 @@
|
|
|
+# P3 Implementation Brief Index
|
|
|
+
|
|
|
+状态:本目录是 P3 平台接入模块实施前的短实施简报集合。它不是新的架构权威源,也不是产品计划;长期事实仍以 `tech_documents/工程落地/04_V1阶段开发计划.md`、`tech_documents/工程落地/05_阶段验收清单.md`、`product_documents/抖音游走策略/runtime_v1_records_schema.md`、`tech_documents/数据库字段总览/content_agent_schema_registry.json` 和当前代码为准。
|
|
|
+
|
|
|
+## 目标
|
|
|
+
|
|
|
+为 P3 平台接入模块保留实施清单,颗粒度固定到文件级、函数 / 类级、数据合同级、验证级和失败归因级。
|
|
|
+
|
|
|
+P3 只处理平台接入:
|
|
|
+
|
|
|
+1. P3A:平台边界与配置。
|
|
|
+2. P3B:Crawapi 抖音 keyword 搜索合同。
|
|
|
+3. P3C:query 级失败与 run 级 `partial_success`。
|
|
|
+4. P3D:内容点赞画像 retry 与字段归一。
|
|
|
+5. P3E:跨 query 内容去重与来源合并。
|
|
|
+6. P3F:P3 验收与 drift guard。
|
|
|
+
|
|
|
+本目录不处理:
|
|
|
+
|
|
|
+- P2 query 生成。
|
|
|
+- P4 Pattern 回扣。
|
|
|
+- P5 规则包业务拍板。
|
|
|
+- 作者作品。
|
|
|
+- tag 搜索。
|
|
|
+- 账号画像兜底。
|
|
|
+- 小红书、快手、B 站或多平台路由。
|
|
|
+- 队列化限流。
|
|
|
+- 发布任务。
|
|
|
+
|
|
|
+## 现有证据
|
|
|
+
|
|
|
+- `tech_documents/工程落地/04_V1阶段开发计划.md`:P3 已拍板 V1 真实平台只允许抖音;最小闭环为抖音关键词搜索 + 内容点赞画像;每 query 数量走 env;初始只拉第一页并保留 `has_more / next_cursor`;keyword 单 query 失败继续其他 query;部分成功时 run 记 `partial_success`;portrait 失败重试一次;同一 `platform_content_id` 合并全部 query 来源。
|
|
|
+- `content_agent/schemas.py`:当前请求默认 `platform="douyin"`、`platform_mode="real"`。
|
|
|
+- `content_agent/run_service.py`:当前 `platform_mode=real` 会构造 `CrawapiDouyinClient.from_env()`;尚未显式拒绝非 `douyin` platform;平台异常当前会进入整次 run failure。
|
|
|
+- `content_agent/business_modules/platform_access.py`:当前逐 query 调用 `platform_client.search()`;同 `platform_content_id` 只保留第一次命中,后续 query 来源被跳过;尚未做 query 级失败继续。
|
|
|
+- `content_agent/integrations/douyin.py`:当前已接 Crawapi keyword search 和 content portrait;默认每 query 处理 3 条;只拉一页;会保留 `has_more / next_cursor`;portrait 失败直接标记缺失,尚无 retry。
|
|
|
+- `content_agent/integrations/douyin.py`:当前真实结果写 `pattern_recall="pattern_recall_pending"`,不会伪装成 Pattern 通过。
|
|
|
+- `content_agent/models.py`:当前 `RunStatus` 只有 `running / success / blocked / failed`,尚无 `partial_success`。
|
|
|
+- `content_agent/graph.py`:P3 位于 `search_platform` 节点,后续接 `build_discovered_content`、`evaluate_rules`。
|
|
|
+- `content_agent/business_modules/content_discovery/content_discovery_builder.py`:平台归一结果会进入 `discovered_content_items.jsonl`、`content_media_records.jsonl` 和 EvidenceBundle。
|
|
|
+- `content_agent/business_modules/rule_judgment/evaluator.py`:最终入池 / 待复看 / 淘汰由规则包判断,不应由 P3 直接拍板。
|
|
|
+- `tests/test_douyin_client.py`:当前覆盖 keyword 字段映射、HTTP 错误脱敏、portrait 缺失、每 query 限量、41-50 不计 50+。
|
|
|
+- `tests/test_platform_access.py`:当前覆盖跨 query 去重和 `llm_variant` 元数据保留。
|
|
|
+- `product_documents/旧版和上下游理解/旧版ContentFindAgent外部数据源接口审计.md`:旧版 Crawapi keyword endpoint 为 `POST /crawler/dou_yin/keyword`,入参 `keyword / content_type / sort_type / publish_time / cursor / account_id`;返回 `aweme_id / desc / author.sec_uid / statistics / has_more / next_cursor`;内容点赞画像 endpoint 为 `POST /crawler/dou_yin/re_dian_bao/video_like_portrait`。
|
|
|
+- `tech_documents/数据接口与来源/external_data_sources_registry.json`:`PLT_DOUYIN_KEYWORD` 和 `PLT_DOUYIN_CONTENT_PROFILE` 均为 `verified + v1_active`。
|
|
|
+- `product_documents/抖音游走策略/runtime_v1_records_schema.md`:`platform_content_id` 是平台内容 ID,抖音下等于抖音视频 ID;`search_query_effect_status` 支持 `success / weak_effective / pending / blocked / failed`。
|
|
|
+- `product_documents/抖音游走策略/douyin_available_walk_strategy.v1.json`:`next_cursor` 是分页状态节点,不是业务节点;后续分页应由游走策略触发。
|
|
|
+- `product_documents/规则包/douyin_rule_packs.v1.json`:缺 `platform_content_id`、缺内容画像等是规则包 gate / scorecard 输入,P3 不直接做最终业务拍板。
|
|
|
+- `sql/content_agent_schema.sql`:P3 相关承载表已存在,包括 `content_agent_queries`、`content_agent_discovered_content_items`、`content_agent_content_media_records`、`content_agent_search_clues`、`content_agent_run_events`、`content_agent_runs`。
|
|
|
+- `content_agent/integrations/database_runtime.py`:`search_queries.jsonl`、`discovered_content_items.jsonl`、`content_media_records.jsonl`、`search_clues.jsonl`、`run_events.jsonl` 已映射到 DB。
|
|
|
+
|
|
|
+真实 DB 证据:
|
|
|
+
|
|
|
+- DB validator 显示 `content_agent_*` 15 表已存在,`schema_ready=true`。
|
|
|
+- `content_agent_discovered_content_items` 已有唯一键 `run_id + policy_run_id + platform + platform_content_id`,支持跨 query 去重。
|
|
|
+- `content_agent_runs.status` 是字符串字段,`partial_success` 不需要新增 DDL。
|
|
|
+- P3 不新增 DDL;query failure、portrait retry、pagination、source merge 细节先进入 `raw_payload`、`platform_raw_payload`、`run_events.raw_payload`、`source_evidence` 或后续 `source_path_records`。
|
|
|
+
|
|
|
+sub-agent 交叉验证结论:
|
|
|
+
|
|
|
+- 代码逻辑 sub-agent 确认:当前已有 Crawapi keyword / portrait 基础,但 query 级失败继续、run `partial_success`、portrait retry、重复内容合并全部 query 来源尚未完成。
|
|
|
+- 文档 / JSON sub-agent 确认:P3 已拍板无剩余开工前问题;Crawapi 当前联调不可用时按旧文档合同推进,失败归因到登录态、账号态或配置。
|
|
|
+- DB / 数据合同 sub-agent 确认:schema ready,P3 不新增 DDL;相关状态可落现有表和 JSON 字段。
|
|
|
+
|
|
|
+## 修改范围
|
|
|
+
|
|
|
+本目录只新增 P3 brief 文档。后续真正执行 P3 时,预计涉及:
|
|
|
+
|
|
|
+- `content_agent/business_modules/platform_access.py`
|
|
|
+- `content_agent/integrations/douyin.py`
|
|
|
+- `content_agent/run_service.py`
|
|
|
+- `content_agent/models.py`
|
|
|
+- `content_agent/graph.py`
|
|
|
+- `content_agent/business_modules/content_discovery/content_discovery_builder.py`
|
|
|
+- `content_agent/business_modules/rule_judgment/evaluator.py`
|
|
|
+- `.env.example`
|
|
|
+- `tests/test_douyin_client.py`
|
|
|
+- `tests/test_platform_access.py`
|
|
|
+- 后续新增或扩展 RunService / API 相关测试。
|
|
|
+
|
|
|
+## 不修改范围
|
|
|
+
|
|
|
+- 本轮不改代码。
|
|
|
+- 本轮不写 DB。
|
|
|
+- 本轮不执行 DDL。
|
|
|
+- 本轮不更新 `.env` 真实值。
|
|
|
+- 本轮不把任何真实密码、token、API key 写进文档。
|
|
|
+- 本轮不修改旧版归档目录。
|
|
|
+
|
|
|
+## 涉及文件 / 函数 / 类
|
|
|
+
|
|
|
+全局证据文件:
|
|
|
+
|
|
|
+- `content_agent/business_modules/platform_access.py`
|
|
|
+- `content_agent/integrations/douyin.py`
|
|
|
+- `content_agent/run_service.py`
|
|
|
+- `content_agent/models.py`
|
|
|
+- `content_agent/graph.py`
|
|
|
+- `content_agent/business_modules/content_discovery/content_discovery_builder.py`
|
|
|
+- `content_agent/business_modules/rule_judgment/evaluator.py`
|
|
|
+- `tests/test_douyin_client.py`
|
|
|
+- `tests/test_platform_access.py`
|
|
|
+- `product_documents/抖音游走策略/runtime_v1_records_schema.md`
|
|
|
+- `product_documents/抖音游走策略/douyin_available_walk_strategy.v1.json`
|
|
|
+- `product_documents/规则包/douyin_rule_packs.v1.json`
|
|
|
+- `tech_documents/数据接口与来源/external_data_sources_registry.json`
|
|
|
+- `tech_documents/数据库字段总览/content_agent_schema_registry.json`
|
|
|
+- `sql/content_agent_schema.sql`
|
|
|
+
|
|
|
+关键对象:
|
|
|
+
|
|
|
+- `platform_access.run()`
|
|
|
+- `CrawapiDouyinClient.from_env()`
|
|
|
+- `CrawapiDouyinClient.search()`
|
|
|
+- `CrawapiDouyinClient._post_json()`
|
|
|
+- `CrawapiDouyinClient._fetch_content_portrait()`
|
|
|
+- `RunService._platform_client()`
|
|
|
+- `RunService._record_success_metadata()`
|
|
|
+- `RunStatus`
|
|
|
+- `build_run_graph()`
|
|
|
+- `content_discovery.run()`
|
|
|
+- `rule_judgment.run()`
|
|
|
+
|
|
|
+## 数据合同
|
|
|
+
|
|
|
+P3 输入:
|
|
|
+
|
|
|
+- P2 产出的 `search_queries.jsonl` / `content_agent_queries`。
|
|
|
+- 每条 query 至少包含 `search_query_id`、`search_query`、`search_query_generation_method`、`discovery_start_source`、`previous_discovery_step`。
|
|
|
+
|
|
|
+P3 平台输出:
|
|
|
+
|
|
|
+- `platform="douyin"`
|
|
|
+- `platform_content_id`
|
|
|
+- `platform_author_id`
|
|
|
+- `description`
|
|
|
+- `author_display_name`
|
|
|
+- `statistics`
|
|
|
+- `tags`
|
|
|
+- `text_extra`
|
|
|
+- `create_time`
|
|
|
+- `has_more`
|
|
|
+- `next_cursor`
|
|
|
+- `portrait_available`
|
|
|
+- `age_distribution`
|
|
|
+- `age_50_plus_ratio`
|
|
|
+- `age_50_plus_tgi`
|
|
|
+- `pattern_recall="pattern_recall_pending"`
|
|
|
+- `category_or_element_binding="pattern_recall_pending"`
|
|
|
+- `content_metadata_source="douyin_keyword_search"`
|
|
|
+- `platform_raw_payload`
|
|
|
+
|
|
|
+P3 状态合同:
|
|
|
+
|
|
|
+- 单 query keyword 失败:该 query 记录失败,其他 query 继续。
|
|
|
+- 所有 query 都失败且无候选:run 失败或 blocked,按后续 P3C 具体错误合同执行。
|
|
|
+- 部分 query 失败但仍有候选且后续链路跑完:run 记 `partial_success`。
|
|
|
+- portrait 重试后仍失败:内容保留为缺画像输入,后续规则包 reject。
|
|
|
+- 同一 `platform_content_id` 多 query 命中:只保留一个内容对象,但记录全部来源。
|
|
|
+
|
|
|
+DB 承载:
|
|
|
+
|
|
|
+- `content_agent_queries.search_query_effect_status`
|
|
|
+- `content_agent_search_clues.search_query_effect_status`
|
|
|
+- `content_agent_run_events.status / error_code / raw_payload`
|
|
|
+- `content_agent_runs.status`
|
|
|
+- `content_agent_discovered_content_items.raw_payload / platform_raw_payload / source_evidence`
|
|
|
+- `content_agent_content_media_records.raw_payload`
|
|
|
+
|
|
|
+不新增 DB 字段,不修改 DDL。
|
|
|
+
|
|
|
+## 实施步骤
|
|
|
+
|
|
|
+1. 每进入一个 P3 小阶段,先读对应 brief。
|
|
|
+2. 只执行该 brief 的修改范围,不顺手做 P4 Pattern 回扣、P5 规则策略或作者/tag 扩展。
|
|
|
+3. 修改前用 brief 中的证据文件确认当前代码、文档和 DB 状态仍未漂移。
|
|
|
+4. 修改后先跑该 brief 指定的最小验证,再跑 P3 汇总测试。
|
|
|
+5. 如果验证失败,先按 brief 的失败归因判断,不扩大修改面。
|
|
|
+
|
|
|
+## 验证命令
|
|
|
+
|
|
|
+```bash
|
|
|
+find tech_documents/工程落地/implementation_briefs/P3 -maxdepth 1 -type f | sort
|
|
|
+rg -n "Implementation Brief|sub-agent|验证命令|失败归因" tech_documents/工程落地/implementation_briefs/P3
|
|
|
+rg -n "PASS[W]ORD=|TO[K]EN=|API[_]KEY=|SEC[R]ET=" tech_documents/工程落地/implementation_briefs/P3
|
|
|
+rg -n "partial_success|has_more|next_cursor|platform_content_id|portrait|Crawapi" tech_documents/工程落地/implementation_briefs/P3
|
|
|
+uv run python scripts/validate_schema_registry.py
|
|
|
+uv run --with pymysql python scripts/validate_content_agent_db.py --env-file .env
|
|
|
+uv run pytest tests/test_douyin_client.py tests/test_platform_access.py tests/test_api.py tests/test_v1_graph.py tests/test_runtime_files.py tests/test_source_evidence.py tests/test_p0d_p0g.py tests/test_search_intent.py -q
|
|
|
+uv run pytest -q
|
|
|
+```
|
|
|
+
|
|
|
+## 失败归因
|
|
|
+
|
|
|
+- brief 文件缺失:本目录落地问题。
|
|
|
+- 敏感键值命中:brief 内容问题,应改成只写 env key 名,不写赋值。
|
|
|
+- `validate_schema_registry.py` 失败:字段 registry 与 SQL / 文档漂移。
|
|
|
+- DB validator 失败:DB 连接、权限、schema 或 `.env` 目标库问题。
|
|
|
+- P0/P1/P2 测试失败:本次只新增 Markdown,通常不应引发业务测试失败;先检查工作区已有代码改动。
|
|
|
+- P3 后续实现测试失败:按具体 brief 判断是平台配置、Crawapi 合同、query 状态、portrait retry、来源合并还是规则边界问题。
|
|
|
+
|
|
|
+## sub-agent 交叉验证要点
|
|
|
+
|
|
|
+- 代码侧 sub-agent 确认:`platform_access.run()` 当前还没有 query 级失败继续和多 query 来源合并。
|
|
|
+- 代码侧 sub-agent 确认:`CrawapiDouyinClient._fetch_content_portrait()` 当前没有 retry。
|
|
|
+- 代码侧 sub-agent 确认:`RunStatus` 当前还没有 `partial_success`。
|
|
|
+- 文档 / JSON sub-agent 确认:P3 只做抖音 keyword + 内容画像,不能混进作者作品、tag、多平台或 P4 回扣。
|
|
|
+- 文档 / JSON sub-agent 确认:旧 Crawapi 正常合同是 P3 实现依据,真实联调失败归因到登录态、账号态或配置。
|
|
|
+- DB 侧 sub-agent 确认:`content_agent_*` schema ready,P3 不需要新增 DDL。
|
|
|
+- DB 侧 sub-agent 确认:`partial_success`、query failure、portrait retry、source merge 都可用现有字段承载。
|