# scripts/ 目录指南 追光AI 数字人 Bot 系统的脚本库。本目录的 `.mjs` 脚本都是用 Node.js(>=18)跑,不依赖 Next.js 构建。 ## 目录结构 ``` scripts/ ├── lib/ # 核心库(被 CLI 引用) │ ├── bot-adversarial-learning.mjs # Bot 对抗学习(每周学 1 篇真人高赞) │ ├── bot-avatar-generator.mjs # Bot 头像生成(Lunaris + SVG 兜底) │ ├── bot-persona.mjs # Bot persona 加载/刷新 │ ├── bot-persona-experiment.mjs # A/B 测试分流 │ └── retry.mjs # DeepSeek/OpenAI 重试封装 │ ├── bot-activity.mjs # 主活动引擎:发 topic / reply ├── bot-adversarial-learning-run.mjs # 每周日 23:00 跑 ├── bot-avatar-generate.mjs # 数字人头像批量预生成 ├── bot-affinity-update.mjs # bot 板块亲和度更新 ├── bot-feedback-loop.mjs # bot 自反馈循环 ├── bot-persona-experiment-run.mjs # A/B 指标采集 + 显著性分析 ├── bot-skill-crystallize.mjs # bot 技能结晶化 └── bot-weekly-review.mjs # bot 周报 ``` ## 常用命令 ### 数字人头像生成(新) ```bash # 全量:112 个 bot 一次性预生成 + 落盘 + 写库 node scripts/bot-avatar-generate.mjs # 单个 bot node scripts/bot-avatar-generate.mjs --bot=laochen # 强制重新生成(覆盖已存在) node scripts/bot-avatar-generate.mjs --force # 只落盘不写 User.avatarUrl node scripts/bot-avatar-generate.mjs --no-update-db # 试运行 node scripts/bot-avatar-generate.mjs --dry-run ``` 产物: - `public/bot-avatars/{key}.svg` — 唯一程序化头像(~2.5KB/个) - `public/bot-avatars/lunaris/{key}.jpg` — Lunaris 拉取的原图(占位时也是这个) - `public/bot-avatars/manifest.json` — 生成清单 > 落盘的 SVG 会通过 Next.js 的 `public/` 静态服务直接挂在 `/bot-avatars/{key}.svg`,前端 `` 组件会优先用 `user.avatarUrl`,找不到时回退到动态 Lunaris URL。 ### Bot 对抗学习 ```bash # 全量:每个 bot 学一篇本周真人高赞帖 node scripts/bot-adversarial-learning-run.mjs # 单个 bot node scripts/bot-adversarial-learning-run.mjs --bot=laochen # 重跑(先清掉本周已有 learning) node scripts/bot-adversarial-learning-run.mjs --force # 追溯更长时间窗 node scripts/bot-adversarial-learning-run.mjs --lookback=14 # 调度入口(生产 cron:`0 23 * * 0`) ``` ### Bot A/B 测试 ```bash # 采指标 + 跑显著性分析 node scripts/bot-persona-experiment-run.mjs # 只采指标,不切 winner node scripts/bot-persona-experiment-run.mjs --no-switch # 只跑分析(用已有指标) node scripts/bot-persona-experiment-run.mjs --analyze-only # 调度入口(生产 cron:`45 */4 * * *`) ``` ## 数据模型要点 | 表 | 用途 | 关键字段 | |------|------|----------| | `bot_persona_variants` | A/B 测试变体 | `weight` / `is_control` / `sample_count` / `engagement_score` | | `bot_persona_experiments` | 实验 | `started_at` / `ended_at` / `status` | | `bot_persona_assignments` | 内容创建时的分流记录 | `variant_id` / `topic_id` / `post_id` | | `bot_persona_metrics` | 每日聚合指标 | `variant_id` / `date` / `reply_count` / `human_reply_count` | | `bot_adversarial_learnings` | 每周学习 | `week_key` / `source_ref_id` / `learned_insight` / `status` | ## 添加新 bot 1. 在 `data/bot-characters.json` 加 character(必填 `key` / `displayName` / `email` / `avatarPrompt` / `personality` / `primaryForums` / `activeHours` / `activityLevel` / `replyChance`) 2. 用 `seed-bot-forum.mjs` 把 bot 跑进 DB(已有 seed) 3. 跑 `node scripts/bot-avatar-generate.mjs --bot={newKey}` 单独生成头像 4. 跑 `node scripts/seed-persona-variants.mjs` 派生 A/B 变体 ## 故障排查 | 症状 | 排查 | |------|------| | `DATABASE_URL 未配置` | 检查 `.env` 是否存在并 `mysql://` 协议 | | `Lunaris 拉取失败` | 网络问题;脚本会自动 fallback 到 SVG | | `Lunaris 全部返回占位` | trae-api 当前所有 prompt 都返回同一张 default.jpeg;用 `isLunarisDefault` 检测后走 SVG | | `Bot "xxx" 不在 bot-characters.json 中` | 先在 JSON 里加这个 key | | `tsc` 报错 | 本目录全是 `.mjs`,不应影响 tsc;如果报错,多半是 `src/` 里改坏了 |