zhangbo.md 26 KB

SupplyAgent 代码仓库结构总结

1. 阅读基线

本文档完全基于当前代码仓库重新阅读后形成,不继承此前对项目的业务推演或可视化设计理解。

代码快照:

  • 分支:feature/zhangbo
  • 阅读时提交:2ab77ce
  • Python 要求:>= 3.11
  • 后端:FastAPI + SQLAlchemy 2.x + PyMySQL
  • Agent:OpenRouter/OpenAI 兼容 API + 自研 Tool/Skill/ReAct 框架
  • 数据源:ODPS(MaxCompute)
  • 数据库:MySQL
  • 对象存储:阿里云 OSS
  • 前端:Vue 3 + TypeScript + Vite

.env 已被 .gitignore 忽略。本文不会记录其中的密码、密钥、数据库地址或 Token。


2. 当前项目的实际定位

当前 SupplyAgent 由两部分组成:

  1. 一套通用 AI Agent 运行框架;
  2. 一套围绕“需求词、全局分类树、热度、视频和需求生成”的业务系统。

业务系统当前主要完成:

  • 从 ODPS 同步全局分类树和树下元素;
  • 从 ODPS 同步多策略需求池;
  • 将需求词挂到分类树节点;
  • 汇总四项先验热度和真实 ROV/VOV;
  • 把词级热度沿分类树向上聚合;
  • 按单一热度维度生成并保存平台需求;
  • 把需求词连接到真实视频和视频最终选题;
  • 通过 API 和 Vue 页面展示分类树、热力图和下钻证据;
  • 记录 Agent 完整执行过程,生成 HTML,上传 OSS 并在 MySQL 留档。

当前系统的核心业务链路是:

ODPS 全局分类与元素
        ↓
MySQL 全局分类树
        ↑
需求池词语 → 归类 Agent → 需求词挂靠
        ↓
四项先验 + 真实 ROV/VOV
        ↓
词级统计 → 分类树节点聚合 → 四维全局排名
        ↓
需求生成 Agent → generated_demand
        ↓
FastAPI → Vue 分类树/热力图/证据下钻

3. 仓库分层

SupplyAgent/
├── supply_agent/       通用 Agent 框架
├── agents/             业务 Agent 和专属工具
├── supply_infra/       MySQL、ODPS、OSS、定时任务
├── api/                FastAPI 查询接口和静态前端托管
├── web/                Vue 3 业务前端
├── scripts/            部署、日志上传、日志可视化脚本
├── visualization/      早期/独立的业务设计可视化材料
├── Dockerfile          前端构建 + Python 运行镜像
├── pyproject.toml      Python 包、依赖和命令入口
└── requirements.txt    另一份运行依赖清单

任务 CLI 已并入 supply_infra/scheduler/jobs/python -m ...)。

模块之间的依赖方向:

web
  ↓ HTTP
api
  ↓
supply_infra.db.repositories
  ↓
MySQL

agents
  ↓
supply_agent(Agent 框架)
  ↓
supply_infra(数据库/ODPS/OSS)

jobs / scheduler
  ↓
supply_infra.scheduler.jobs
  ↓
ODPS + MySQL + 业务 Agent

4. 通用 Agent 框架:supply_agent/

4.1 supply_agent/config.py

负责 Agent 侧配置:

  • OpenRouter API Key、模型和 Base URL;
  • Agent 最大迭代次数和温度;
  • Skills 目录;
  • 日志目录和日志开关。

配置来自环境变量或项目根目录 .env,相对路径会解析到项目根目录。

4.2 supply_agent/llm/client.py

基于 OpenAI Python SDK 连接 OpenRouter,提供:

  • 同步对话 chat
  • 异步对话 achat
  • 同步文本流 stream
  • 异步文本流 astream
  • Tool Calling;
  • OpenRouter reasoning effort;
  • LLM 输入和输出日志。

模型可以在运行时切换。

4.3 supply_agent/tools/

base.py 提供:

  • @tool 装饰器;
  • 从 Python 函数签名生成 JSON Schema;
  • Optional 和基础类型转换;
  • 同步/异步工具执行;
  • 异常转为 JSON 错误结果。

registry.py 提供:

  • 工具注册、删除和查询;
  • OpenAI ToolDefinition 列表;
  • 根据模型返回的工具名执行工具;
  • 同步和异步执行;
  • 批量注册被 @tool 装饰的函数。

4.4 supply_agent/skills/

Skill 机制读取指定目录下的 SKILL.md

  • 支持 YAML frontmatter 的名称和描述;
  • 启动时把 Skill 目录作为目录索引加入系统提示词;
  • Agent 通过内置 load_skill 工具按需加载全文;
  • Skill 加载后会重建系统消息并注入当前上下文。

当前仓库根目录的 skills/.gitignore 忽略,因此代码支持 Skill,但仓库没有可随代码分发的业务 Skill 内容。

4.5 supply_agent/agent/

core.pyAgent 负责组装:

  • LLMClient;
  • ToolRegistry;
  • SkillRegistry;
  • AgentLoop;
  • AgentLogger。

对外提供:

  • run
  • arun
  • stream
  • astream

loop.py 实现标准 ReAct/Tool Calling 循环:

系统消息 + 对话历史
        ↓
调用 LLM
        ↓
有工具调用?──否──→ 返回最终结果
        │是
        ↓
执行工具并写入 Tool Message
        ↓
下一轮 LLM

达到最大迭代次数时,同步和普通异步运行会追加一条用户消息,要求模型给出当前最佳答案;流式路径则直接发出 Max iterations reached。

4.6 supply_agent/logging/

每次 Agent 运行生成:

  • 人类可读 .log
  • 结构化 .jsonl

日志记录:

  • run_start;
  • 完整 LLM 输入;
  • 模型输出和 reasoning;
  • 工具调用参数和结果;
  • Skill 加载;
  • run_end。

运行结束后:

  1. 将日志渲染成 HTML;
  2. 上传 .log.jsonl.html 到 OSS;
  3. 把 HTML 公网地址写入 oss_logs
  4. 上传失败只记录错误,不影响 Agent 主结果。

5. 三个业务 Agent

5.1 demand_belong_category_agent

目标:把需求词挂到真实存在的全局分类树节点。

工具:

  • query_global_tree_category:读取整棵树或指定子树;
  • batch_insert_demand_belong_category:批量写入需求词、分类 ID 和原因。

业务流程:

  1. 查看顶层分类;
  2. 选择最相关分支;
  3. 逐层下钻;
  4. 不确定时停在更可靠的上层节点;
  5. 将结果写入 demand_belong_category

系统提示允许一个词选择一个或多个高置信节点,但当前数据库和写入工具以 name 唯一:

  • demand_belong_category.name 有唯一约束;
  • 同一次请求也按 name 去重;
  • 因此当前实现实际上只能保存“一词一个分类节点”;
  • 多挂靠尚未在当前表结构中实现。

定时任务会把新需求词按 100 个一批交给该 Agent。

5.2 generate_demand_agent

目标:从分类树局部热度和已挂靠需求词中,按单一维度生成平台需求结果。

支持的来源维度只有四项先验:

  • ext_pop:外部热度;
  • plat_sust_pop:平台持续热度;
  • plat_ly_pop:平台去年同期热度;
  • recent_pop:近期热度。

一次运行只允许处理一个维度。

工具:

  • query_latest_biz_dt:取两张统计表都有数据的最新日期;
  • query_category_tree_by_dim:查看指定维度有数据的树;
  • query_category_leaves_by_dim:定位有数据的叶子节点;
  • query_demand_words_by_category:查询节点或子树下的真实需求词;
  • query_category_path:补充根到节点的路径;
  • batch_save_generated_demands:写入 generated_demand

输出结构固定为:

source_dim
  └── overall_direction
        └── summary_event
              └── demand_name

重要约束:

  • demand_name 必须原样来自 demand_belong_category.name
  • Agent 不能新造需求词;
  • summary_event 尽量对应一个需求,最多轻量合并 2~3 个强相关需求;
  • 写入时保存类目、路径、维度 avg/count 快照、reason、业务日和 run_id;
  • 同一次工具调用按 (source_dim, demand_name) 去重;
  • 当前 generated_demand 没有数据库唯一约束,不同 run 可以重复生成相同需求。

真实 ROV/VOV 当前不属于该 Agent 的 source_dim,也没有参与其单维生成工具链。

5.3 find_agent

目标:根据需求词、参考视频标题和相关点,寻找老年受众更可能观看和分享的抖音视频。

当前注册的业务工具包括:

  • batch_search_and_record:批量执行多个关键词和分页搜索,每页创建独立搜索及候选记录;
  • douyin_search:调用外部抖音关键词搜索服务并返回数据库记录 ID;
  • douyin_search_tikhub:调用 TikHub 搜索,保存分页状态并返回数据库记录 ID;
  • douyin_user_videos:按作者 sec_uid、排序和游标扩展历史作品并返回数据库记录 ID;
  • douyin_detail:按 content_id 获取视频详情和可播放地址;
  • get_content_fans_portrait:获取视频点赞用户画像;
  • get_account_fans_portrait:获取作者粉丝画像;
  • batch_fetch_portraits:批量获取视频画像,并可同时获取作者画像;
  • normalize_age_portraits:标准化 50- 等年龄桶及双侧证据;
  • create_video_discovery_run:创建可追踪的找视频运行;
  • batch_update_video_discovery_candidates:按 candidate_id 更新证据、评分和最终分池;
  • update_video_discovery_run_status:独立更新找视频运行状态;
  • query_video_discovery_state:查询搜索树和候选分池。

搜索和详情接口有约 10 秒的请求间隔限制。

Agent 以需求相关性、老年受众倾向和分享价值的联合目标做判断。系统提示明确区分 “分享量高”和“受众偏老”两类证据,使用视频点赞画像作为内容侧证据、作者粉丝画像 作为账号先验,并对画像缺失或冲突降低置信度。搜索词由 Agent 根据需求、参考标题、 相关点和途中发现的有效标签自主决定;支持多关键词、游标翻页和标签扩展。与需求无关 但老年倾向、分享价值双高的视频保存在人工备选池。

搜索过程持久化到:

  • video_discovery_run:任务输入、意图、状态与计数;
  • video_discovery_search:逐关键词、逐游标页的搜索轨迹;
  • video_discovery_candidate:视频详情、双侧画像、标签、评分、分池与人工审核状态。

6. 基础设施:supply_infra/

6.1 配置

supply_infra/config.py 管理:

  • MySQL;
  • ODPS;
  • APScheduler;
  • 阿里云 OSS;
  • Agent 日志上传开关。

配置文件固定从项目根目录 .env 读取,不依赖当前工作目录。

6.2 数据库会话

supply_infra/db/session.py

  • 懒加载全局 SQLAlchemy Engine;
  • 使用连接池和 pool_pre_ping
  • get_session() 自动提交;
  • 异常时自动回滚;
  • init_db() 通过 ORM metadata 创建缺失表。

6.3 Repository 规则

业务 Agent、API 和定时任务原则上不直接执行 MySQL SQL,而是通过 Repository:

  • 基础 CRUD;
  • 批量插入;
  • insert ignore;
  • upsert;
  • 条件查询;
  • 批量更新。

ODPS 查询仍在 supply_infra/odps/client.py 内直接组织 SQL。

6.4 ODPS 客户端

当前读取的主要 ODPS 数据:

  • public_pattern_mining_category:全局分类;
  • pattern_mining_element:树下元素;
  • dwd_multi_demand_pool_di:多策略需求池;
  • dwd_topic_decode_result_di:视频解析和最终选题;
  • dwd_video_produce_plan_stat_hour:真实 ROV/VOV。

6.5 OSS 客户端

负责:

  • 生成对象路径;
  • 上传本地文件;
  • 返回 CDN 公网地址。

7. MySQL 数据模型

当前 ORM 定义 10 张表。

作用 关键唯一性/关联
global_tree_category 全局分类树节点 source_id 唯一;parent_id 形成树
global_tree_element ODPS 元素与分类挂靠 (name, category_id) 唯一
multi_demand_pool_di 按日同步的策略需求池 代码按 (strategy, demand_id, biz_dt) 管理差异
demand_belong_category 需求词归属分类 name 唯一;当前一词只能保存一个分类
demand_belong_pool_rel 需求词与需求池行的匹配边 (demand_belong_category_id, multi_demand_pool_di_id) 唯一
demand_popularity_stats 词级六维 avg/count (demand_category_id, biz_dt) 唯一
category_tree_weight 分类树节点六维聚合和四维排名分 (category_id, biz_dt) 唯一
multi_demand_video_detail 视频标题与最终选题 JSON vid 唯一
generated_demand 需求生成 Agent 输出 按 run_id 记录,无数据库唯一约束
oss_logs Agent 日志 HTML 的 OSS 地址 按 agent_name 查询

7.1 关键关系

global_tree_category.id
  ├── global_tree_category.parent_id
  ├── global_tree_element.category_id
  ├── demand_belong_category.category_id
  ├── category_tree_weight.category_id
  └── generated_demand.category_id

demand_belong_category.id
  ├── demand_popularity_stats.demand_category_id
  ├── demand_belong_pool_rel.demand_belong_category_id
  └── generated_demand.demand_belong_id

multi_demand_pool_di.id
  └── demand_belong_pool_rel.multi_demand_pool_di_id

这些关联在 ORM 中主要以整数 ID 表达,没有使用 SQLAlchemy relationship,也没有显式数据库 ForeignKey。


8. 热度数据的真实代码口径

8.1 策略到四项先验的映射

代码把需求池策略映射为:

ODPS strategy 统计字段 页面含义
新热事件 ext_pop 外部热度
逐月 plat_sust_pop 平台持续热度
去年同期阳历 plat_ly_pop 去年同期热度
去年同期阴历 plat_ly_pop 去年同期热度
当下供需gap recent_pop 近期热度

8.2 真实 ROV/VOV

从近 7 日 dwd_video_produce_plan_stat_hour 获取人工 AGC 和自动 AGC 数据:

  • ROV = 回流 UV / 分发曝光 PV;
  • VOV = 拉回曝光 PV / 分发曝光 PV;
  • 同一特征值存在多行时,优先保留 rov_diffvov_diff 较高的一行;
  • 按特征值与 demand_name 精确匹配,回填 multi_demand_pool_di

8.3 词级统计

对每个 demand_belong_category.name

  1. 在当日 multi_demand_pool_di.demand_name 中执行子串 LIKE 匹配;
  2. 按策略收集非零 weight;
  3. 分别计算四项先验的 avg/count;
  4. 汇总匹配行的真实 ROV/VOV avg/count;
  5. 写入 demand_popularity_stats

因此当前词与需求池的匹配核心是字符串包含关系,不是分词索引、向量匹配或显式语义关系。

8.4 分类树节点聚合

分类节点聚合六个独立维度:

  • 外部热度;
  • 平台持续热度;
  • 去年同期热度;
  • 近期热度;
  • 真实 ROV;
  • 真实 VOV。

每个节点统计其整个子树内有需求词挂靠的节点:

节点维度 avg = Σ(挂靠点 avg × count) / Σ(count)
节点维度 count = Σ(count)

结果写入 category_tree_weight

8.5 四维排名分和全局热度

demand_pool/tree_weight.py 在写入权重后会对四项先验排名:

  • 各维只让 count > 0 的节点参与;
  • 按 avg 降序排名;
  • 同分取平均名次;
  • 映射到 (0, 1]
  • 无数据节点为 0;
  • total_score 是四个排名分直接相加,范围 [0, 4]

真实 ROV/VOV 会被聚合并通过 API 返回,但当前不进入 total_score

前端显示“全局热度”时再使用 total_score / 4 映射为 0~1 色阶。

单一维度热度则由前端根据该维所有有数据节点的 avg 做百分位色阶,不直接使用数据库中的四维 rank score 字段。


9. 定时任务和数据流水线

9.1 已注册的定时任务

supply_infra/scheduler/app.py 当前只注册一条任务:

  1. 每天 15:00SCHEDULER_TIMEZONE):串行执行全链路 run_supply_pipeline(全局树 → 需求池 → 分级 → 拓展 → 找视频 → AIGC 发布)。

9.2 全局树同步

sync_global_tree_odps_to_mysql

  1. 拉取有效元素;
  2. 拉取全部分类;
  3. 从元素命中的分类向上补齐祖先;
  4. 按 ODPS source_id 去重;
  5. 已有分类保持不变,只插入新分类;
  6. 给新分类分配 MySQL ID 并转换 parent_id;
  7. 写入元素及其 MySQL category_id。

该任务是增量插入,不会根据 ODPS 当前状态自动删除或更新历史分类。

9.3 策略需求池完整流水线

supply_infra.scheduler.jobs.demand_poolsync_multi_demand_pool_odps_to_mysql)实际执行顺序:

  1. 比较 ODPS 与 MySQL 当日去重行数;
  2. 行数不同时执行差异同步;
  3. 对当日所有 demand_name 按空格拆词;
  4. 调用归类 Agent 处理未出现过的新词;
  5. 建立需求词与需求池的子串匹配边,并回填词级 video_list;
  6. 获取并回填近 7 日真实 ROV/VOV;
  7. 计算词级六维 avg/count;
  8. 计算整棵分类树六维聚合;
  9. 计算四项先验全局排名分和 total_score;
  10. 同步全部待处理视频的标题和最终选题。

当前有一个同步判断风险:只要 ODPS 和 MySQL 行数相同,就跳过需求池差异拉取;如果内容发生变化但总行数不变,该轮不会发现这些变化。

9.4 手动任务入口

python -m 调用(与定时流水线同源):

  • python -m supply_infra.db:初始化数据库;
  • python -m supply_infra.scheduler.jobs.run_supply_pipeline:全链路;
  • python -m supply_infra.scheduler.jobs.demand_pool:需求池同步(含内部阶段);
  • python -m supply_infra.scheduler.jobs.grade_demand_pool:分级(可加 --retry-failed);
  • 以及 global_tree / expand / discover / publish 各步骤模块。

也可通过 API POST /api/scheduler/jobs/{job_id}/run 手动触发。


10. FastAPI:api/

服务端口:8080

接口 作用
GET /health 健康检查
GET /api/category-tree?biz_dt=YYYYMMDD 返回嵌套分类树、六维 avg/count、total_score 和挂靠词数
GET /api/demand-belong-category 返回所有有效需求词挂靠
GET /api/demand-belong-category/{id}/videos 返回需求词关联的视频标题和最终选题 JSON
GET /api/demand-belong-oss-logs 返回归类 Agent 的 OSS 日志列表

如果 web/dist 存在,FastAPI 会把它挂到 /,同一个 8080 服务同时提供 API 和生产前端。

API 当前是同步 SQLAlchemy 查询,没有分页、鉴权或缓存。


11. Vue 前端:web/

11.1 路由

路由 页面
/ 平台全局需求地图
/demand-tree 传统横向分类树
/demand-process 需求归类 Agent 日志
/demand-map 重定向到 /

当前顶部导航只显示“平台全局需求地图”,另外两个页面有路由但没有导航入口。

11.2 平台全局需求地图

GlobalDemandMapView.vue 并行读取:

  • 完整分类树和热度;
  • 全部需求词挂靠。

IcicleHeatTree.vue 使用 Canvas 绘制从左到右的冰柱树:

  • 每层固定 200px 宽;
  • 全局状态适配视口高度;
  • 选择层级或聚焦节点后按可读高度纵向扩展;
  • 最大逻辑画布高度 24000px
  • 实际 Canvas 始终只有视口大小,只绘制可见区域;
  • 普通滚轮滚动;
  • 拖拽平移;
  • Ctrl/Command + 滚轮 缩放;
  • 点击节点聚焦子树;
  • 支持层级起点和祖先面包屑。

热力标签:

  • 全局树结构;
  • 全局热度 total_score
  • 外部热度;
  • 平台持续热度;
  • 去年同期热度;
  • 近期热度。

API 虽然返回真实 ROV/VOV,但当前冰柱图标签没有提供真实 ROV/VOV 的独立切换入口。

11.3 节点证据下钻

分类节点存在需求词时显示搜索标识。点击后通过 DemandPathPanel.vue 展开:

当前分类节点
  → 细节元素/需求词
  → 真实视频实例
  → 最终选题 JSON

这里展示的是 demand_belong_category 需求词,不是 generated_demand 中由生成 Agent 产出的四层平台需求。

当前前端没有读取或展示 generated_demand 的 API。

11.4 传统分类树页面

CategoryTree.vue 使用 Vue DOM 递归组件展示:

  • 默认展开 3 层;
  • 支持选择展开深度;
  • 支持手动展开和收起;
  • 支持按维度过滤有数据的节点;
  • 支持拖动画布;
  • 支持导出包含数据的独立 HTML;
  • 同样可以下钻需求词、视频和最终选题。

11.5 需求归类过程页面

读取 demand_belong_category_agentoss_logs,按时间倒序显示,点击打开 Agent 运行过程 HTML。


12. 部署和运行

12.1 Python 命令入口

pyproject.toml 注册:

  • supply-api
  • supply-visualize

12.2 本地开发

后端:

python -m api

前端:

cd web
npm install
npm run dev

Vite 在 5173,将 /api 代理到 127.0.0.1:8080

12.3 Docker

Docker 使用两阶段构建:

  1. Node 20 构建 Vue;
  2. Python 3.11 安装项目和 ODPS 可选依赖;
  3. web/dist 放入 Python 镜像;
  4. 通过 python -m api 启动 8080。

scripts/docker-deploy.sh 可以构建并向指定镜像仓库推送时间戳标签和 latest


13. 当前代码已经实现的能力

  • 通用同步/异步 Agent 和 Tool Calling;
  • 动态 Skill 加载机制;
  • 三个业务 Agent;
  • 全量 Agent 日志和 OSS 发布;
  • ODPS 到 MySQL 的全局树同步;
  • 多策略需求池增量同步;
  • 新词自动归类;
  • 需求词与需求池匹配边;
  • 真实 ROV/VOV 回填;
  • 词级六维统计;
  • 分类树六维向上聚合;
  • 四项先验排名和 total_score;
  • 单维度平台需求生成与落库;
  • 视频标题和最终选题同步;
  • FastAPI 查询接口;
  • Vue 全局冰柱热力图;
  • 分类节点到需求词、视频和最终选题的下钻;
  • Docker 构建和部署脚本。

14. 当前代码未完成或存在偏差的部分

14.1 需求多挂靠尚未实现

demand_belong_category.name 唯一,当前一个需求词只能保存一个 category_id。系统提示中的“一词多个节点”无法真实落库。

14.2 generated_demand 未进入产品展示

需求生成 Agent 已能写 generated_demand,但:

  • 没有对应 API;
  • 前端没有需求清单;
  • 没有与内容、反馈的展示闭环;
  • 当前全局图下钻的是需求词,不是最终生成需求。

14.3 后验没有进入全局综合分

真实 ROV/VOV 已采集、聚合并由 API 返回,但:

  • 不进入 total_score
  • 不进入 generate_demand_agent 的 source_dim;
  • 当前主热力图没有 ROV/VOV 标签;
  • 尚未形成“后验反向调整最终需求排序”的完整实现。

14.4 find_agent 的外部证据仍可增强

当前已持久化搜索轨迹、正式推荐和人工备选,但画像接口提供的是点赞用户而非真实转发 用户。后续若能补充转发用户画像、分年龄观看留存、相似视频和批量搜索接口,可进一步 提高老年分享判断的直接性与多词多页探索效率。

14.5 关系语义较弱

当前主要关系是:

  • 树父子;
  • 需求词到单一分类;
  • 需求词和需求池的字符串子串匹配;
  • 需求词到视频列表。

尚没有独立的语义关系表、关系类型、关系 reason、置信度和人工审核状态。

14.6 同步完整性风险

需求池同步先比较总行数。总行数相同但内容变化时,会跳过 ODPS 明细同步。

14.7 测试体系缺失

当前仓库没有 tests/,并且 .gitignore 直接忽略 tests/,会阻止正常提交测试目录。

14.8 文档已滞后

现有 README.mdARCHITECTURE.mdagents/README.md 包含已经不存在或未实现的结构,例如:

  • video_content 模型/Repository;
  • find_agent 的保存和历史查询工具;
  • 旧的 Agent 数量和数据流。

后续应以本文和源码为准,并更新旧文档。


15. 当前本地运行环境与数据库状态

15.1 本地 Python 环境不匹配

当前机器默认环境:

  • Python 3.10.19
  • SQLAlchemy 1.4.51
  • 项目根目录没有 .venv

源码要求:

  • Python >=3.11
  • SQLAlchemy >=2.0

因此直接使用当前默认 python3 导入数据库层会在 DeclarativeBase 处失败。应建立 Python 3.11+ 虚拟环境后安装项目依赖。

15.2 .env 的 MySQL 配置问题

只读连接检查发现:

  1. MYSQL_HOST 的值开头多了一个 =,会导致主机名解析失败;
  2. 临时去掉该字符后可以到达 MySQL 服务,但返回错误 1045 Access denied
  3. 需要核对用户名/密码、RDS 白名单或该用户允许连接的 Host 范围。

由于未通过鉴权,本次无法确认数据库真实表数量、行数和最新业务日。本文的数据结构来自当前 ORM 和 Repository 源码,不冒充线上运行态数据。

15.3 前端依赖未安装

当前没有 web/node_modules。Node 20.11.1、npm 10.2.4 已存在,执行前需要先在 web/ 运行 npm installnpm ci


16. 建议的后续阅读顺序

如果继续开发,建议按以下顺序进入代码:

  1. supply_infra/scheduler/jobs/demand_pool/:理解需求池同步主业务;
  2. supply_infra/db/models/:理解真实数据对象;
  3. supply_infra/scheduler/jobs/demand_pool/tree_weight.py:理解树上热度;
  4. agents/demand_belong_category_agent/:理解需求词挂树;
  5. agents/generate_demand_agent/:理解平台需求生成;
  6. api/services/category_tree.py:理解后端对前端的数据形态;
  7. web/src/components/IcicleHeatTree.vue:理解全局热力图;
  8. web/src/components/DemandPathPanel.vue:理解节点证据下钻;
  9. supply_agent/agent/:理解底层 Agent 执行机制;
  10. supply_agent/logging/:理解可追溯运行日志。

17. 一句话总结

当前 SupplyAgent 是一套以 ODPS 和 MySQL 为数据底座、以全局分类树为组织骨架、以自研 Agent 框架完成需求词归类和单维需求生成、并通过 FastAPI/Vue 展示分类热度与视频证据的业务系统;核心数据流水线已经形成,但多挂靠、最终需求产品化、后验反馈进入综合决策、语义关系图和自动化测试仍未完成。