Files
MediaCrawler/mac-agent-os-main/05_tools/09_ave/PLANS/DASHBOARD_MULTI_AGENT.md
T
butubb 2112c1a870
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s
feat(monitor): 抖音 Web 接口客户端 —— 绕开爬虫子进程,直接发 HTTP
移植自 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 带网关原话 / 正常返回)。
2026-10-10 17:12:25 +08:00

14 KiB
Raw Blame History

Dashboard 数据层 · 多智能体协同设计

版本: v1.0 | 2026-05-15 定位: AgentOS 多智能体系统 · 共享观测层


一、定位:不是 AVE 的面板,是 AgentOS 的观测层

Dashboard 不是 AVE 的附属工具。它应该是一套跨智能体的共享数据服务,任何 Agent(Claw、AVE、Matrix、Trae 等)都可以通过统一接口写入和查询。

现存 Agent 一览

Agent 目录 适合 Dashboard 跟踪什么
09_ave 05_tools/09_ave/ 视频生产任务、素材生成、API 调用
07_matrix 05_tools/07_matrix/ 抖音养号任务、蓝�运行、账号切换
claw assistant ~/.workbuddy/ 各种自动化任务、CLI 执行的历史
02_browser / 05_crawl 05_tools/ 爬虫任务、页面采集记录

二、存储位置

根据 AgentOS 的目录结构约定:

类别 路径 说明
代码(可同步) ~/workbuddy-agent-os/agent-sync/05_tools/10_dashboard/ 多机共享,坚果云同步
数据(本地) ~/workbuddy-agent-os/agent-local/runtime/dashboard/ 本地 SQLite + 缓存,不同步
客户端库 ~/workbuddy-agent-os/agent-sync/05_tools/10_dashboard/client.py Agent 导入用,写数据入口
后端服务 ~/workbuddy-agent-os/agent-sync/05_tools/10_dashboard/server.py FastAPI 应用
前端页面 ~/workbuddy-agent-os/agent-sync/05_tools/10_dashboard/templates/ HTML 单页应用

为什么数据放 agent-local 而不是 agent-sync?

  • SQLite 不适合坚果云同步(并发写会导致 DB 损坏)
  • 每台机器的生产数据天然不同,不应该同步
  • agent-local/runtime/ 已经是 AgentOS 为"运行时数据"预设的位置

三、多智能体数据模型

3.1 agents — 智能体注册表

CREATE TABLE agents (
    id TEXT PRIMARY KEY,        -- 'ave', 'matrix', 'claw', 'trae'
    name TEXT NOT NULL,         -- 'audio score video engine'
    type TEXT DEFAULT 'tool',   -- 'tool' | 'skill' | 'pipeline' | 'assistant'
    version TEXT,               -- 当前版本号
    status TEXT DEFAULT 'active',
    last_seen_at TEXT,           -- 最后心跳时间
    meta_json TEXT               -- 扩展元数据
);

预注册的 Agent:

id name type
ave AudioScore Video Engine tool
matrix Matrix Account Manager tool
claw Claw AI Assistant assistant
memory Memory Manager skill

3.2 productions — 生产任务(跨 agent 通用)

这是核心表。不限于视频生产——任何 agent 的"一次任务执行"都是一条 production。

CREATE TABLE productions (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    agent_id TEXT NOT NULL REFERENCES agents(id),
    pipeline TEXT NOT NULL,            -- 'ave:oral' | 'ave:beat-sync' | 'matrix:browse' | 'claw:research'
    status TEXT DEFAULT 'running',     -- 'running' | 'completed' | 'failed' | 'cancelled'
    title TEXT,                        -- 人类可读名称
    input_summary TEXT,                -- JSON: 输入概览
    output_summary TEXT,               -- JSON: 输出概览
    config_json TEXT,                  -- JSON: 完整参数快照
    duration_sec REAL,
    total_cost REAL DEFAULT 0.0,
    currency TEXT DEFAULT 'CNY',
    error_message TEXT,
    tags TEXT,                         -- 逗号分隔,跨 agent 搜索用
    created_at TEXT DEFAULT (datetime('now')),
    completed_at TEXT
);

CREATE INDEX idx_productions_agent ON productions(agent_id);
CREATE INDEX idx_productions_status ON productions(status);
CREATE INDEX idx_productions_created ON productions(created_at);

3.3 production_steps — 步骤级跟踪

CREATE TABLE production_steps (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    production_id INTEGER REFERENCES productions(id) ON DELETE CASCADE,
    agent_id TEXT NOT NULL,
    step_name TEXT NOT NULL,           -- 'parse_script' | 'tts' | 'kling_generate' | ...
    step_type TEXT DEFAULT 'process',  -- 'process' | 'api_call' | 'human_review' | 'decision' | 'wait'
    status TEXT DEFAULT 'pending',
    input_ref TEXT,                    -- 输入引用(文件路径 / URL)
    output_ref TEXT,                   -- 输出引用
    started_at TEXT,
    ended_at TEXT,
    duration_sec REAL,
    cost REAL DEFAULT 0.0,
    detail TEXT,                       -- 步骤详情 JSON
    error_message TEXT,
    metadata_json TEXT                 -- 扩展字段
);

CREATE INDEX idx_steps_production ON production_steps(production_id);

3.4 assets — 跨 agent 共享资产

所有 agent 生成的、可复用的数字资产统一注册在这里。关键设计:资产一旦注册,就属于全局资产池,任何 agent 都可以引用。

CREATE TABLE assets (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    asset_type TEXT NOT NULL,          -- 'character_sheet' | 'bgm' | 'generated_clip' | 'script' | 'lora' | 'screenshot' | 'dataset'
    name TEXT,
    description TEXT,
    file_path TEXT,                    -- 本地绝对路径
    file_size INTEGER,
    file_hash TEXT,                    -- SHA256,用于去重
    source_agent TEXT REFERENCES agents(id),
    source TEXT,                       -- 'generated' | 'imported' | 'downloaded' | 'user_provided' | 'pexels'
    license TEXT,                      -- 版权信息
    meta_json TEXT,                    -- JSON: 资产元数据
    tags TEXT,                         -- 逗号分隔
    created_at TEXT DEFAULT (datetime('now')),
    UNIQUE(file_hash)
);

CREATE INDEX idx_assets_type ON assets(asset_type);
CREATE INDEX idx_assets_source ON assets(source_agent);

3.5 production_assets — 资产使用记录

CREATE TABLE production_assets (
    production_id INTEGER REFERENCES productions(id) ON DELETE CASCADE,
    asset_id INTEGER REFERENCES assets(id) ON DELETE CASCADE,
    role TEXT DEFAULT 'input',         -- 'input' | 'output' | 'intermediate' | 'reference'
    PRIMARY KEY (production_id, asset_id)
);

3.6 agent_events — 智能体间事件总线

这是跨智能体通信的关键设计。一个 agent 完成某项任务后,可以通过事件通知其他 agent。

CREATE TABLE agent_events (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    source_agent TEXT REFERENCES agents(id),
    target_agent TEXT,                 -- null = broadcast 给所有 agent
    event_type TEXT NOT NULL,          -- 'production.completed' | 'asset.created' | 'pipeline.ready' | 'error.occurred'
    severity TEXT DEFAULT 'info',      -- 'info' | 'warning' | 'error' | 'critical'
    title TEXT,
    payload_json TEXT,                 -- 事件负载 JSON
    status TEXT DEFAULT 'pending',     -- 'pending' | 'read' | 'acknowledged'
    created_at TEXT DEFAULT (datetime('now')),
    read_at TEXT
);

CREATE INDEX idx_events_target ON agent_events(target_agent);
CREATE INDEX idx_events_status ON agent_events(status);
CREATE INDEX idx_events_created ON agent_events(created_at);

3.7 ER 关系

agents ──1:N── productions ──1:N── production_steps
  │                 │
  │                 └── M:N ── assets (via production_assets)
  │
  └──1:N── agent_events (source)
       └──?:1── agent_events (target)

四、客户端库设计

每个 Agent 通过 client.py 写入,不需要直接操作 SQLite。这是唯一的写入口。

# ~/workbuddy-agent-os/agent-sync/05_tools/10_dashboard/client.py

"""
Dashboard Client — 供所有 Agent 调用

用法:
    from dashboard_client import DashboardClient
    db = DashboardClient()  # 自动连接 agent-local/runtime/dashboard/ave.db

    # 注册自己
    db.register_agent("ave", "AudioScore Video Engine", "tool")

    # 开始一个 production
    prod_id = db.start_production(
        agent_id="ave",
        pipeline="ave:oral",
        title="知识讲座视频 #047",
        config={"script": "lecture.yaml", "style": "knowledge_lecture"}
    )

    # 记录步骤
    db.log_step(prod_id, "tts", "completed", cost=0.30, detail={"chars": 85})
    db.log_step(prod_id, "render", "completed", cost=0.0)

    # 注册资产
    asset_id = db.register_asset(
        asset_type="generated_clip",
        name="clip_hermit_01.mp4",
        file_path="/tmp/kling_hermit.mp4",
        source_agent="ave",
        tags=["kling", "hermit", "cinematic"]
    )

    # 关联资产到 production
    db.link_asset(prod_id, asset_id, role="output")

    # 完成 production
    db.complete_production(prod_id, status="completed", total_cost=1.20)

    # 发送事件通知
    db.send_event("ave", "claw", "production.completed",
                  title="视频 #047 生成完成", payload={"prod_id": prod_id})

核心 API

方法 功能 被调用频率
register_agent(id, name, type) 注册/更新 agent 安装时一次
start_production(...) 开始任务 每次 CLI 执行
log_step(...) 记录步骤 每个步骤
update_step(...) 更新步骤状态 异步步骤
complete_production(...) 完成任务 每次完成/失败
register_asset(...) 注册资产 每个新文件
link_asset(prod, asset, role) 关联资产 每次资产使用
send_event(source, target, type, ...) 发送事件 按需

五、后端 API 设计

FastAPI 服务,运行在 http://localhost:9132。

核心端点

GET  /api/status                    # 服务健康检查
GET  /api/summary                   # 总览指标(总数、本月、总成本、资产数)

GET  /api/productions               # 生产列表(支持 filter: ?agent=&status=&pipeline=&tags=)
GET  /api/productions/{id}          # 生产详情 + 步骤列表
GET  /api/productions/{id}/assets   # 生产关联的资产

GET  /api/assets                    # 资产列表(支持 filter: ?type=&agent=&tags=&q=)
GET  /api/assets/{id}               # 资产详情 + 使用记录
GET  /api/assets/{id}/productions   # 该资产被哪些 production 用过

GET  /api/agents                    # agent 列表
GET  /api/agents/{id}/productions   # 某个 agent 的所有 production

GET  /api/events                     # 事件列表
GET  /api/events?target={agent_id}  # 发给某个 agent 的事件

GET  /api/costs                     # 费用汇总(按 agent/策略/时间分组)

查询示例

# 查看 AVE 最近失败的 production
GET /api/productions?agent=ave&status=failed

# 搜索资产
GET /api/assets?q=定妆照&type=character_sheet

# 查看 matrix 本周的全部任务
GET /api/productions?agent=matrix&from=2026-05-08&to=2026-05-15

六、集成方式

6.1 AVE 集成(Sprint 1 要做)

在 main.py 的每个关键节点加 ~50 行调用。改动量极小:

# 在 video_factory.py 的入口
from dashboard_client import DashboardClient
db = DashboardClient()

# run_oral() 开始
prod_id = db.start_production("ave", "ave:oral", title, config=args)

# TTS 步骤完成
db.log_step(prod_id, "tts", "completed", cost=0.30)

# 素材搜索完成
db.log_step(prod_id, "search_material", "completed", detail={"count": 6})

# 合成完成
db.complete_production(prod_id, status="completed", total_cost=tracker.total)

6.2 Matrix 集成(Sprint 3 可选)

# 在 task_engine.py 的入口
prod_id = db.start_production("matrix", "matrix:browse", "抖音浏览 #102")
db.log_step(prod_id, "switch_account", "completed")
db.log_step(prod_id, "open_douyin", "completed")
db.log_step(prod_id, "browse_videos", "completed", detail={"count": 15})
db.complete_production(prod_id, status="completed")

6.3 Claw Assistant 集成(Sprint 3 可选)

通过 WorkBuddy 的 CLI 埋点,每次执行自动化任务自动记录。


七、数据生命周期

阶段 操作 位置
创建 client.py 写入 agent-local/runtime/dashboard/ave.db
读取 HTTP API → 前端 Dashboard FastAPI + HTML
备份 随 agent-local 整体备份策略 暂不单独处理
清理 >90 天的 production 自动归档 (可配置) 归档到 agent-local/runtime/dashboard/archive/
跨机迁移 不同步。每台机器独立数据 agent-local 不同步的设计

八、文件结构

agent-sync/05_tools/10_dashboard/
├── __init__.py
├── client.py              # Agent 客户端库(唯一写入口)
├── models.py              # SQLAlchemy ORM 或 raw SQL schema
├── server.py              # FastAPI 应用
├── templates/
│   ├── index.html         # 总览页
│   ├── productions.html   # 生产列表
│   ├── detail.html        # 生产详情
│   └── assets.html        # 资产浏览器
├── static/
│   └── app.js             # 前端交互逻辑
└── README.md              # 使用说明

agent-local/runtime/dashboard/
├── ave.db                 # SQLite 主数据库
├── cache/                 # 文件缓存
└── archive/               # 历史归档

九、为什么这样设计

9.1 为什么用 SQLite 而不是其他 DB?

数据库 适用性
SQLite ✅ 单机多进程读、零运维、AgentOS 已有使用 选这个
PostgreSQL ❌ 太重,单机不需要
JSON 文件 ❌ 不支持并发写、不支持查询
LevelDB/RocksDB ❌ 没 SQL 查询,不支持关联

9.2 为什么用 HTTP API 而不是直接写 SQLite?

方式 问题
直接写 SQLite 每个 agent 都要 import sqlite3 + 写 SQL,产生代码耦合
通过 API agent 只需 import client.py + 调方法,后端封装所有 DB 逻辑

9.3 为什么 events 表放在这里而不是单独的消息队列?

轻量。当前多智能体在同一台机器上,SQLite 轮询足够。如果以后需要跨机器,可以从 events 表迁移到真正的消息队列(如 Redis pub/sub)。


十、开发量估算

模块 估计 说明
models.py (schema) 0.2h SQL 建表语句
client.py (核心 6 个方法) 1h ~150 行 Python
server.py (API 端点) 1h ~200 行 FastAPI
AVE 埋点接入 0.5h main.py + video_factory.py 加 ~50 行
合计 ~2.7h 一个下午可完成