|
|
@@ -1,80 +0,0 @@
|
|
|
-# 游走图谱(人读说明)
|
|
|
-
|
|
|
-> 机读件:`walk_graph.json`(schema v2)。命名全部复用 `product_documents/抖音游走策略/douyin_walk_strategy.v1.json`(8 节点 + 10 边),**零新造**。
|
|
|
-> 证据:2026-06-11 多平台实测抓包 + `接口台账/*.md`。
|
|
|
-
|
|
|
-## 〇、配置四件套(v2 起,机读配置面闭环)
|
|
|
-
|
|
|
-游走的全部配置拆为四件,各管一层,代码只留一个通用 loop:
|
|
|
-
|
|
|
-| 文件 | 管什么 | 平台相关? |
|
|
|
-|---|---|---|
|
|
|
-| `walk_graph.json` | **拓扑**:10 条边的语义、navigate/reseed、jump_key(canonical)、血缘锚点 | 否(全局唯一) |
|
|
|
-| `platform_profiles/<platform>.json` ×10 | **平台执行**:支持哪些边、真实 endpoint、jump_key 的 raw 字段来源、提取覆写、运行参数(限流 15s/重试/下载头) | 是(每平台一份) |
|
|
|
-| `walk_policy.json` | **护栏 + 通行证**:预算/深度/去重/回灌配额(锚定 v1 真值,V3 待拍板项标 `TBD_V3`)+ `edge_permissions`(判定结果→哪些边放行,取代 `_can_expand_from_decision` 硬编码与原 path_stop/budget 包语义) | 否 |
|
|
|
-| `跨平台字段映射.json` | **归一化**:平台 raw 字段 → canonical 字段 | 是(一张总表) |
|
|
|
-
|
|
|
-运行时语义:loop 出队一个节点 → 查 `walk_graph` 该节点有哪些出边 → 查该平台 `profile` 此边是否 supported(unsupported/blocked 静默跳过,**边不可用不是错误,是该平台地图少一条路**)→ 查 `walk_policy` 预算/通行证放不放行 → 执行,响应按 `字段映射` 归一化。**新平台接入 = 实测一轮接口 + 写一份 profile,零代码改动。**
|
|
|
-
|
|
|
-## 一、一句话模型:单一有界 loop + 异构 frontier
|
|
|
-
|
|
|
-整个游走是**一个有界循环**,不是多条独立管线。一个**统一队列(frontier)**里同时排着三类异构节点 —— `query`(待搜)、`video`(待判/待扩)、`author`(待拉作品),按优先级轮转出队。每出队一个节点,按其类型尝试可走的边,产出的新节点(新 query / 新 video / 新 author / hashtag)再入同一队列。预算/深度耗尽即收敛停止。
|
|
|
-
|
|
|
-8 类节点(id_field):
|
|
|
-`pattern_seed`(policy_run_id)→ `query`(search_query_id)→ `search_page`(search_page_id)→ `video`(platform_content_id)→ `author`(platform_author_id)→ `author_works_page`(author_works_page_id);旁路 `hashtag`(hashtag);终点 `asset`(asset_id)。
|
|
|
-
|
|
|
-## 二、两类边
|
|
|
-
|
|
|
-### 导航边(navigate)= ID 跳转
|
|
|
-拿上一跳的某个 ID/游标,填进下一个请求参数,直接到下一个节点。8 条:
|
|
|
-
|
|
|
-| edge_id | from → to | jump_key(from_field → param) | 翻页 | endpoint |
|
|
|
-|---|---|---|---|---|
|
|
|
-| `query_next_page` | query → search_page | `next_cursor` → `cursor` | 是 | `/crawler/{platform}/keyword` |
|
|
|
-| `search_page_to_content` | search_page → video | `data.data[]` 拆条 | 否 | (同搜索响应) |
|
|
|
-| `video_to_author` | video → author | `platform_author_id` → `account_id` | 否 | — |
|
|
|
-| `author_to_works` | author → author_works_page | `platform_author_id` → `account_id` | 是 | `/crawler/{platform}/blogger` |
|
|
|
-| `author_work_to_content` | author_works_page → video | `data.data[]` 拆条 | 否 | (同 blogger 响应) |
|
|
|
-| `decision_to_asset` | video → asset | `platform_content_id` | 否 | — |
|
|
|
-| `path_stop` | video → video | `content_effect_status` | 否 | — |
|
|
|
-| `budget_downgrade` | video → video | `budget.remaining_actions` | 否 | — |
|
|
|
-
|
|
|
-### 回灌边(reseed)= 文本 → 新 keyword,gate=keep_only
|
|
|
-不靠 ID,靠从内容里**抽文本**生成新种子,且**只对 KEEP(强相关)内容开**:
|
|
|
-
|
|
|
-| edge_id | from → to | 抽取规则 | gate |
|
|
|
-|---|---|---|---|
|
|
|
-| `video_to_hashtag` | video → hashtag | 从 `tags` 抽:结构化(text_extra/topic_list/cha_list/B站 tag split)优先,缺则标题/desc/body_text 正则 `#([^\s#]+)` | keep_only |
|
|
|
-| `hashtag_to_query` | hashtag → query | 用 hashtag 文本生成新 `query`(param=`keyword`),归一化 keyword 去重,不污染 P2 初始 item query | keep_only |
|
|
|
-
|
|
|
-### 采集通吃:回灌不挑来源
|
|
|
-`author_work_to_content` 产出的**也是 `video` 节点**,因此它会**再触发 `video_to_hashtag` 回灌**。也就是说:搜索结果的视频、作者作品的视频,它们的标题与 tag **都能回灌**成新 hashtag → 新 query。回灌对内容来源一视同仁(标题/tag/作者作品的标题与 tag 通吃),只受 `keep_only` 与全局护栏约束。
|
|
|
-
|
|
|
-## 三、全局护栏(单一有界 loop 的边界)
|
|
|
-
|
|
|
-- **单队列**:query / video / author 同进一个 frontier,异构排队、统一调度,不分叉成多管线。
|
|
|
-- **全局预算 + 深度**:`max_total_actions` / `max_depth` / `max_pages` / `max_tag_hops`(见策略 `walk_budget_policy`);耗尽走 `budget_downgrade` 降档或停边。
|
|
|
-- **去重**:query 按**归一化 keyword + 近期 run** 去重(`normalize_exact_and_recent_run`);内容按**已访问 `platform_content_id`** 去重(作者作品须与已发现搜索内容去重,见 commit 1cd1b94)。
|
|
|
-- **回灌仅 KEEP**:`video_to_hashtag` / `hashtag_to_query` 都是 `keep_only` —— 只有判定强相关的内容/tag 才扩散,弱相关/blocked 内容走 `path_stop` 收口。
|
|
|
-- **血缘**:每跳记 `source_path_type`,对齐三类锚点:`pattern_to_search_query`(query_next_page / hashtag_to_query)、`search_query_to_content`(search_page_to_content / author_work_to_content)、`decision_to_asset`(decision_to_asset);其余导航边记 `null`。
|
|
|
-
|
|
|
-## 四、各平台对各边的支持度(实测)
|
|
|
-
|
|
|
-| edge_id | 抖音 | 快手 | 视频号 | 小红书 | B站 | 公众号 | youtube | github |
|
|
|
-|---|---|---|---|---|---|---|---|---|
|
|
|
-| query_next_page | ✅ | 弱(单页) | ✅(需重试) | ✅ | ✅ | ✅ | ✅(长token) | ✅ |
|
|
|
-| search_page_to_content | ✅ | ✅ | ✅(抖动) | ✅(note_card) | ✅ | ✅ | ✅ | ✅(repo) |
|
|
|
-| video_to_author | ✅ | ✅ | ✅ | ✅ | ✅(仅mid标识) | ✅(仅biz/hash) | ✅ | ✅(→owner) |
|
|
|
-| **author_to_works** | ✅(blogger) | ❌无接口 | ⛔blocked25011 | ⛔blocked超时 | ❌无接口 | ❌无接口 | ❌无接口 | ❌ |
|
|
|
-| author_work_to_content | ✅ | ❌ | ⛔ | ⛔ | ❌ | ❌ | ❌ | ❌ |
|
|
|
-| video_to_hashtag | ✅ | 弱(常null) | ✅(title正则) | ✅ | ✅(tag split) | ❌无tag | ✅(仅detail正则) | ✅(topics常空) |
|
|
|
-| hashtag_to_query | ✅ | ✅ | ✅ | ✅ | ✅ | n/a | ✅ | ✅ |
|
|
|
-| decision_to_asset | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
|
-| path_stop / budget_downgrade | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
|
-
|
|
|
-> **头条、知乎**:整平台 blocked(`code=10000`/`data=null`),所有边阻断,不接入游走。
|
|
|
-
|
|
|
-### 关键结论
|
|
|
-- **作者作品(`author_to_works`)只有抖音真正可走**(blogger 接口 `code=0`)。快手/B站/公众号/youtube **无独立作者作品接口**;视频号(`code=25011`)、小红书(超时)**接口存在但 blocked**。其余平台的"作者"维度只能落作者标识(`platform_author_id`),无法展开作品列表。
|
|
|
-- **公众号无 hashtag 回灌**(`topic_list` 恒 null),`video_to_hashtag` / `hashtag_to_query` 在公众号不可走。
|
|
|
-- 抖音是唯一**全 10 边可走**的平台,是游走能力的完整参照系。
|