feat(monitor): 抖音 Web 接口客户端 —— 绕开爬虫子进程,直接发 HTTP
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s

移植自 mac-agent-os 的 mediacrawler_adapter:不起子进程、不开页面,用浏览器里那份
登录态直接调抖音 Web 接口。产物键名照抄 store/douyin,所以 ingest 那条链路一个字不用改。

**目前能用的(真环境实测,非推断)**:

    profile/other : 200, 7075 字节  —— 博主主页指标(粉丝/获赞/作品数/昵称)
    aweme/detail  : 200, 45425 字节 —— 单条作品详情(含点赞/评论/收藏/分享)

**目前不能用的:作品列表 `aweme/post`。** 两个互相独立的原因:
  1. 这个接口被抖音单独升级成了真校验:不带 x-tt-argus 回 403「Uifid Not Found」,
     带上 dummy 值回 200 + **空 body**。也就是说「头在不在」骗得过,「真校验」过不了。
     同一套头打 profile/other 和 aweme/detail 都是通的 —— 抖音是挑着接口加保护的,
     挑中的恰好是「批量拉作品列表」这个最敏感的动作。
  2. 改走页面截获也不行:CDP 浏览器打开博主主页会落到「验证码中间页」(当天大量探测的
     代价,过几小时要重测)。

  所以现在的边界是:**已知作品的指标刷新能做,自动发现新作品做不了**。

**排查中控住变量后得到的两条事实**(都写进注释了):
  · `Accept` / `Accept-Language` / `Referer` 才是主页接口能返回真数据的原因 —— 只有
    UA+client hints+Cookie 时是 200 但仅 121 字节的空壳,补上这三个头变 7074 字节。
    (我先前猜的 sec-ch-ua 不是关键。)
  · 因此 UA 与 client hints 必须**成套地取自同一个浏览器**,所以 BrowserIdentity 一次
    从 CDP 取齐 cookie + UA + hints,而不是各自写死。

「200 + 空 body 必须当场报错」也是刻意写死的:放过去它会在下游变成「这个博主没作品」,
把一次失败伪装成一条正常结果 —— 爬虫那条路正是这么栽的,还被翻译成「账号被封」。

测试 +11:cookie 解析、请求头成套性(含 uifid 缺失/回退)、产物键名与 store 对齐、
以及 _get 的三条失败路径(空 body / 403 带网关原话 / 正常返回)。
This commit is contained in:
2026-10-10 17:12:25 +08:00
parent 21ff01b894
commit 2112c1a870
1601 changed files with 367425 additions and 0 deletions
@@ -0,0 +1,295 @@
# AgentOS 前端看板调整方案
> 版本: 1.0 | 日期: 2026-07-04
> 后端改动: Phase 1 三队列 + Phase 2 语料重组 + Phase 3 智能评论
---
## 一、调整总览
| 视图 | 文件 | 行数 | 当前状态 | 需要调整 |
|:-----|:------|:-----|:---------|:---------|
| **指挥台** | `ops-command.js` | 413 | ✅ P0/P1/P2 过滤 + 初始化按钮 | 小修 |
| **定向评论** | `matrix-comment.js` | 99 | ❌ 只支持旧 comment 类型 | **大改** |
| **语料库** | `matrix-corpus.js` | 573 | ❌ 无行业/accessible 显示 | **大改** |
| **账号中心** | `accounts-center.js` | 797 | ❌ 无 smart_comment + industry 显示 | **中改** |
| **互动操作** | `matrix-interact.js` | 500 | ⚠️ 有 corpus 浏览但无行业池 | 小修 |
| **执行管道** | `execution-pipeline.js` | 300 | ❌ 未被任何视图引用 | 可废弃 |
| **命令历史** | `matrix-commands.js` | 221 | ⚠️ 需确认状态展示一致 | 小修 |
---
## 二、每项调整详述
### 2.1 指挥台(ops-command.js)— 小修
**当前已有功能** ✅
- P0/P1/P2 过滤器 ✅
- 机器下拉选择 ✅
- 初始化/重置全部按钮 ✅
- 活动任务网格 + 队列详情 ✅
**需要补充**:
| 补充项 | 原因 | 工作量 |
|:-------|:------|:-------|
| 在队列详情中区分 smart_comment 任务来源 | 当前 P0 任务只显示优先级,不区分是评论还是智能评论 | ~10行 |
| 添加视频分析状态显示(如果是 smart_comment) | VideoAnalyzer 的 `asyncio.run()` 可能执行较久,用户需要知道分析进度 | ~30行 |
| 队列详情增加 industry 过滤 | 让用户只看 health 或 general 账号的任务 | ~15行 |
---
### 2.2 定向评论(matrix-comment.js)— ❌ 需要大改
**当前问题**:
1. 只支持 `type:'comment'`,不支持 `smart_comment`
2. 没有视频分析预览 — 填了链接直接执行,用户不知道会发什么评论
3. 语料选择只有硬编码的下拉("通用/科技/生活/美食/娱乐"),不反映后端实际的行业池
4. 每个视频×每个账号发一次 `/ops/run`,效率低(N 个账号×M 个链接 = N×M 次 API 调用)
**需要改为**:
```
┌───────────────────────────────────────────────────┐
│ 💬 智能评论(新版) │
│ │
│ [账号选择器] │
│ │
│ 视频链接: [textarea 每行一个] │
│ │
│ 方向: [称赞/提问/共鸣/感慨] 语料: [自动/行业/万能] │
│ │
│ [▶️ 分析视频] [▶️ 直接执行] │
│ │
│ ── 分析结果预览 ── │
│ url1 → [health] "医生讲得很清楚..." [✏️ 修改] │
│ url2 → [general] "博主说得很对..." [✏️ 修改] │
│ url3 → [health] "这个方子很实用..." [✏️ 修改] │
│ │
│ 全部 3 个视频分析完成,预计分发 20 个账号 │
│ [✅ 确认并分发] │
└───────────────────────────────────────────────────┘
```
**具体改动**:
| 改动 | 说明 | 工作量 |
|:-----|:------|:-------|
| 新增分析按钮 + 预览区 | 先调 `smart_comment` 只分析不分发,返回预览 | ~80行 |
| 预评论可编辑 | 用户可在预览区修改每条评论后确认 | ~30行 |
| 行业标签显示 | 每个视频分析后显示 `[health]` 或 `[general]` 标签 | ~10行 |
| 语料下拉从后端动态加载 | 从 `/matrix/corpus` 接口读取实际分类列表 | ~15行 |
| 批量提交 | 分析完的一次性 `POST /ops/run` 全部账号×全部URL | ~20行 |
| **合计** | | **~155行** |
---
### 2.3 语料库(matrix-corpus.js)— ❌ 需要大改
**当前现状**:
- 573 行,三标签(1D 分类 / 2D 场景 / 3D 多轮)
- 分类显示:分类名 + 权重 + 启用状态 + 评论列表
- 添加/批量导入/删除
- **缺少**:`accessible` 行业标签显示和管理
**需要改为**:
```
┌───────────────────────────────────────────────────┐
│ 📚 语料库 │
│ 8 个分类 · 2 个行业池 · 156 条评论 │
│ │
│ ┌─ 行业过滤 ──────────────────────────────────────────┐
│ │ [全部] [万能池] [大健康池] [科技池] [美食池] │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 大健康称赞 ──── accessible: [health] ───────────┐ │
│ │ weight: 30 | enabled: true │ │
│ │ "医生讲得很清楚,通俗易懂" [编辑] [删除] │ │
│ │ "这个方子很实用,收藏了" [编辑] [删除] │ │
│ │ [+ 添加评论] │ │
│ └────────────────────────────────────────────────────┘ │
```
**具体改动**:
| 改动 | 说明 | 工作量 |
|:-----|:------|:-------|
| 行业池过滤标签 | 在分类列表上方加 accessible 过滤按钮 | ~20行 |
| accessible 标记显示 | 每个分类显示 `accessible: ["health"]` 或 `accessible: ["*"]` | ~15行 |
| 行业池管理入口 | 添加/编辑分类时可选"允许哪些行业访问" | ~30行 |
| 行业池 vs 万能池分离显示 | 万能池标签(称赞/提问/共鸣)显示在独立区域 | ~20行 |
| 删除功能修复 | 当前删除按钮可能不工作(查下 delete 端点) | ~10行 |
| **合计** | | **~95行** |
---
### 2.4 账号中心(accounts-center.js)— 中改
**当前现状**:
- 797 行,账号列表 + 批量操作 + 状态汇总
- 批量操作:采集/登录/评论/养号
- 评论按钮跳转到 `matrix-comment.js`
- **缺少**:industry 字段显示、smart_comment 批量操作
**需要改为**:
| 改动 | 说明 | 工作量 |
|:-----|:------|:-------|
| 账号列表增加 industry 列 | 显示 health/general 标签 | ~15行 |
| 按 industry 过滤 | 下拉选择 health/general/全部 | ~15行 |
| 批量操作新增"智能评论" | 弹出链接输入+方向+分析预览对话框 | ~60行 |
| **合计** | | **~90行** |
---
### 2.5 互动操作(matrix-interact.js)— 小修
**当前现状**:
- 500 行,有三个 tab(评论/点赞/关注)
- 评论 tab 有 corpus 浏览器 + 关键词匹配
- 评论模式下拉:`comment` / `search_browse` / `reply`
- **缺少**:smart_comment 模式
| 改动 | 说明 | 工作量 |
|:-----|:------|:-------|
| smart_comment 模式选择 | 在模式下拉加"智能评论"选项 | ~10行 |
| 方向选择与行业匹配 | 如果选了行业池,自动过滤可选方向 | ~15行 |
| **合计** | | **~25行** |
---
### 2.6 执行管道组件(execution-pipeline.js)— ❌ 废弃
**当前现状**:
- 300 行,但 **不被任何视图引用**
- 搜索 `execution-pipeline.js` 的引用:0 个视图 import
- 有 double `/api` 前缀 bug(line 20 `const API = '/api'`,line 146 `api('/api/ops/...')` → `/api/api/ops/...`)
| 处理 | 说明 |
|:-----|:------|
| 标记为废弃 | 不移除文件,但在顶部加注释说明 |
| 保留未来用 | 如有重构计划可复用,但当前不需要修 |
---
### 2.7 命令历史(matrix-commands.js)— 小修
**当前现状**:
- 221 行,显示历史命令列表
- 调 `/ops/status` 获取
| 改动 | 说明 | 工作量 |
|:-----|:------|:-------|
| 显示 priority 列 | 区分 P0/P1/P2 任务 | ~10行 |
| 显示 industry 列 | 如果任务包含 industry 信息 | ~5行 |
| **合计** | | **~15行** |
---
## 三、修改优先级
| 优先级 | 视图 | 工作量 | 原因 |
|:-------|:------|:-------|:-----|
| **P0** | `matrix-comment.js` | ~155行 | **核心功能**: 智能评论的前端入口,用户直接交互 |
| **P1** | `matrix-corpus.js` | ~95行 | **体验提升**: 行业池管理,让用户能自定义语料 |
| **P1** | `accounts-center.js` | ~90行 | **效率提升**: 批量智能评论入口 |
| **P2** | `matrix-interact.js` | ~25行 | 补充优化 |
| **P2** | `ops-command.js` | ~55行 | 已有基础功能,补细节 |
| **P2** | `matrix-commands.js` | ~15行 | 显示优化 |
| - | `execution-pipeline.js` | 0 | 废弃不修 |
**总计工作量**: ~435 行改动。
---
## 四、smart_comment 前端交互流程
```
用户进入「定向评论」页面
│
├─ 选择账号(账户选择器)
├─ 填写视频链接(textarea,每行一个)
├─ 选择方向(称赞/提问/共鸣)
└─ 选择语料(自动/行业匹配/指定分类)
│
▼
点击「分析视频」
│
▼
前端调 POST /api/ops/run {type:"smart_comment", accounts: [只取1个], params:{urls, direction, preview:true}}
↓ 后端 VideoAnalyzer 分析
↓ 返回 {url: {title, industry, comment}}
│
▼
前端显示分析结果预览
┌─────────────────────────────────────────┐
│ url1 → [health] "医生讲得很清楚..." [✏️]│
│ url2 → [general] "博主说得很对..." [✏️]│
└─────────────────────────────────────────┘
用户可逐条修改预评论
│
▼
点击「确认并分发」
│
▼
调 POST /api/ops/run {type:"smart_comment", accounts:[全部], params:{urls, direction, comments:{url:预评论}}}
↓
后端直接拆解 → 打包 → API 分发到各机 guardd
│
▼
前端切换到指挥台,显示各机队列状态
```
---
## 五、预审/修改流程的关键设计
**关键设计点:用户在分发前可以看到并修改每条预评论**
```javascript
// 分析结果数据结构(前端存储)
let previewData = {
urls: {
"https://v.douyin.com/xxx": {
title: "胃镜到底疼不疼",
industry: "health",
comment: "医生讲得很清楚,通俗易懂" // 用户可编辑
},
"https://v.douyin.com/yyy": {
title: "苏州美食探店",
industry: "general",
comment: "博主说得很对" // 用户可编辑
}
}
};
// 用户编辑预评论后,确认分发
async function confirmDistribute() {
// 收集所有预评论(含用户修改后的)
const comments = {};
for (const [url, data] of Object.entries(previewData.urls)) {
comments[url] = data.comment;
}
// 一次性分发
await apiRequest('/ops/run', {
method: 'POST',
body: JSON.stringify({
type: 'smart_comment',
accounts: selectedAccounts,
params: { urls: Object.keys(comments), comments, direction }
})
});
}
```
---
## 六、调整汇总工作量
| 视图 | 当前行数 | 新增行数 | 总行数 |
|:-----|:---------|:---------|:-------|
| `matrix-comment.js` | 99 | +155 | 254 |
| `matrix-corpus.js` | 573 | +95 | 668 |
| `accounts-center.js` | 797 | +90 | 887 |
| `ops-command.js` | 413 | +55 | 468 |
| `matrix-interact.js` | 500 | +25 | 525 |
| `matrix-commands.js` | 221 | +15 | 236 |
| **Total** | **2603** | **+435** | **~3038** |