关于 anibon-timestamper
anibon-timestamper 是一项技能,使用云端大模型从 Anibon Official 直播转录稿生成 YouTube 格式的主题时间戳。它将片段并行交给专用子 Agent,也可结合聊天、画面活动和主题参考资料。
主要功能
- 01子 Agent 并行分析转录片段
- 02准备转录稿并切分片段
- 03检测主题信号与边界
- 04可选加入 LiveChat 和画面活动
- 05根据聊天脉冲提供情绪提示
适用场景
- 01为 Anibon Official 直播标注主题
- 02分组处理长篇转录稿
- 03结合聊天理解直播片段氛围
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ zenithth/ anibon-stream-synthesis --skill anibon-timestamper安装后在 Claude Code 中输入/anibon-timestamper确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoredocs/superpowers/specs/2026-08-06-per-chunk-mood-segments-design.mdreferences/anibon_emoji_dictionary.mdBUILD_WHISPERCPP_GUILD.mdINDEX.mdsubagent-prompt-template.mdsummarizer-subagent-guide.mdwhisper_pc_spec_benchmark.mdreferences/stories/.gitkeepresources/garbled_replacements.jsonscripts/align_live_chat.pyanibon-analyzer.pybuild_subagent_prompts.pydetect_boundaries.pydetect_signals.pydump_chunk_text.pymerge_timestamps.pyprepare_video.pyvalidate_mood.pyvalidate_part_coherence.pytests/__init__.pytest_align_live_chat.pytest_analyze_555_emoji.pytest_detect_signals.pytest_pack_timestamps.pytest_validate_tags.py详细介绍
Anibon 时间戳生成器(Frontier / Cloud Orchestrator)
一种路由编排技能,使用云端 / 前沿大模型分析直播字幕稿,并生成 YouTube 格式的时间戳。它会动态检测直播类型,并行委派给专用子 Agent。
使用场景
- Anibon Official 的「Boat」直播或视频,需要使用 Frontier / Cloud 模型和并行子 Agent(
anibon-chunk-timestamper、anibon-summarizer、anibon-garbled-notes)生成带时间戳的话题标签。 - 如果在本地运行,使用单块 GPU(NVIDIA Tesla P100、LM Studio、Ollama、本地 VLM),且不想产生云端 API 费用,请改用
anibon-timestamper-local。
子技能与权限
必需(首先加载): 加载 preparing-tools,验证依赖项(yt-dlp、ffmpeg、python3)。
必需(执行子 Agent 时): 运行多子 Agent 分析时,加载 batching-subagents-concurrency(每批次最多 10 个,Model: "flash")。下载大型外部媒体或进行耗时较长的网页抓取前,先征求用户许可。
按信号加载(需要时添加到提示词中):
anibon-world-identity— 在生成时间戳前,参照资料核实游戏 / 角色名称及日语惯用表达 / 活动术语anibon-stream-activity— 高分辨率分镜采样,用于判断屏幕上的游戏活动、摄像头画面是否有人 / 是否挂机,以及视觉依据anibon-local-transcription— YouTube 没有字幕时,使用 whisper.cpp 作为备用方案whisper-corruption-recovery— 检测到 Whisper 输出存在重复循环 / 损坏时,恢复字幕稿anibon-livechat-analysis— 解析 LiveChat 回放(或使用extract_visual_livechat.py从屏幕画面中提取聊天作为备用方案),让子 Agent 可以同时从主播发言和聊天两方面了解直播antigravity-vision-proxy— 检查分镜(sb0)画面,用于处理指代不明、核实游戏名称或解决无法辨认的笔记
流程(自上而下线性执行)
所有路径均相对于技能根目录(skills/anibon-timestamper/)。
0. 环境
scripts/ 目录包含所有辅助脚本。运行 <script>.py --help 查看参数。
将工作文件存储在 youtube_<video_id>_workspace/ 中。
1. 初始化
询问输出语言。参照 resources/channels.json 核实频道和主播昵称:
- 自有频道:
Anibon Official(@anibonofficial) - 主要主播:
Boat/Pu Boat(ปู่โบ๊ต/PhuBoat/โบ๊ต)
继续前,确保字幕稿中的说话人归属映射到 own_channel 昵称。
2. 准备视频
python3 -X utf8 scripts/prepare_video.py "URL" --format xml --block 300 --overlap 30
# Talk-heavy → --block 600 --overlap 60
下载字幕稿,并创建 <workspace>/chunks/chunk_*.xml。
重要
检查损坏情况:如果字幕稿来自本地 Whisper 转录(或音频时长 ≥2h),请检查末尾条目是否存在重复循环。如果发现损坏(匹配率 >0.5),加载
whisper-corruption-recovery技能,拆分损坏的尾部片段,重新运行该片段,并去重合并,然后再进行分块。
3. 清理字幕稿(可选)
在信号检测前,规范化 Thai-Whisper 产生的乱码英语。脚本位于 cleaning-auto-transcripts 技能中;请从时间戳生成器技能根目录解析该技能路径。
python3 -X utf8 ../cleaning-auto-transcripts/scripts/clean_garbled_english.py --chunks ~/youtube_<id>_workspace/chunks/
3.5 下载并对齐 LiveChat(可选,但建议)
为每个子 Agent 提供对应分块的观众聊天内容,使其能同时根据主播发言和聊天内容判断情境与情绪。此步骤需要网络;如果某个 VOD 没有 live_chat 字幕,请跳过此步骤,并仅根据字幕稿判断情绪。
# 1. Download LiveChat replay (network required)
yt-dlp --sub-langs live_chat --write-sub --skip-download "https://www.youtube.com/watch?v=<VIDEO_ID>" -o "<workspace>/%(id)s.%(ext)s"
# 2. Parse to coarse chunks + a seconds-prefixed raw event feed
python3 -X utf8 ../anibon-livechat-analysis/scripts/parse_live_chat.py <workspace>/<id>.live_chat.json --chunk-minutes 90 --raw-events <workspace>/livechat_events.txt -o <workspace>/livechat_90/
# 3. Align raw feed to transcript chunk windows
python3 -X utf8 scripts/align_live_chat.py --events <workspace>/livechat_events.txt --chunks <workspace>/chunks/ -o <workspace>/livechat/
输出:livechat/livechat_chunk_NN.txt(每个字幕稿分块对应一个文件)和 livechat/livechat_index.json。如果 yt-dlp 报告没有 live_chat 字幕,请继续 — 子 Agent 将改用仅基于字幕稿的方式。
编辑过的直播 / 缺少 .live_chat.json 时的回退方案(视觉聊天提取)
当直播流在 YouTube Studio 中被剪辑或编辑后,YouTube 会永久删除 .live_chat.json 聊天回放轨道,yt-dlp 也会报告没有可用的聊天字幕。
为了避免丢失高关注时刻的观众互动背景,可从 anibon-livechat-analysis 运行 extract_visual_livechat.py,对特定高峰片段(例如表情包刷屏、高额 SuperChat 捐赠、观众问答或高潮反应)中的烧录聊天覆盖层进行 OCR:
# 1. Spot-extract visual livechat for target chunk time range
python3 -X utf8 ../anibon-livechat-analysis/scripts/extract_visual_livechat.py \
--video-id <VIDEO_ID> \
--range HH:MM:SS-HH:MM:SS \
-o <workspace>/visual_livechat_events.txt
# 2. Align visual raw event feed directly to chunk windows
python3 -X utf8 scripts/align_live_chat.py \
--events <workspace>/visual_livechat_events.txt \
--chunks <workspace>/chunks/ \
-o <workspace>/livechat/
这会为目标片段窗口生成 <workspace>/livechat/livechat_chunk_NN.txt,直接供 analyze_555.py(步骤 3.7)和子 Agent 提示词生成使用,无需下载完整视频。
3.6 提取活动与摄像头时间线(可选,但建议执行)
捕获屏幕上的游戏 / 网页浏览内容,以及 Pu Boat 是否出现在摄像头画面中和其是否处于离开状态,以消除语音与动作之间的偏差错误。
# 1. Download high-res storyboard (sb3 -> sb2 -> sb1 -> sb0)
yt-dlp -f "sb3/sb2/sb1/sb0" "https://www.youtube.com/watch?v=<VIDEO_ID>" -o "<workspace>/frames/storyboard.%(ext)s"
# 2. Unpack slides
python3 -X utf8 ../anibon-stream-activity/scripts/unpack_storyboard.py --mhtml "<workspace>/frames/storyboard*" --out-dir "<workspace>/frames/slides"
# 3. Extract continuous activity timeline
python3 -X utf8 ../anibon-stream-activity/scripts/extract_activity_timeline.py --slides-dir "<workspace>/frames/slides" -o "<workspace>/activity_timeline.json"
# 4. Align activity to chunk windows
python3 -X utf8 ../anibon-stream-activity/scripts/align_activity_timeline.py --timeline "<workspace>/activity_timeline.json" --chunks "<workspace>/chunks/" -o "<workspace>/activity/"
输出:<workspace>/activity/activity_chunk_NN.txt,其中包含屏幕上的游戏 / 应用状态、摄像头画面中是否有人,以及肢体表情,供注入子 Agent。
3.7 检测泰式笑声 / 表情包脉冲(可选,但建议执行)
此步骤位于 align_live_chat.py 之后。泰国观众会用 555... / xD / ฮา / ขำ 标记笑声。短时间内集中刷屏即代表出现表情包 / 笑声高峰。当自动转录无法听到主播实际发笑时,这是唯一可靠的笑声代理指标。它会为每个片段生成情绪判定 + 泰语语气指导,子 Agent 提示词在编写带有情绪色彩的描述时必须参考这些信息。
python3 -X utf8 scripts/analyze_555.py \
--livechat ~/youtube_<id>_workspace/livechat/ \
--index ~/youtube_<id>_workspace/livechat/livechat_index.json \
--out ~/youtube_<id>_workspace/mood_555.json
输出:mood_555.json — 字典,片段 → {density, n_markers, n_messages, peak_windows, pulse, mood, verdict, tone}。tone 字段包含与片段情绪类别匹配的泰语指导(tone + 建议的 verbs)。判定结果:
*_PULSE— 脉冲通过加权评分 → 情绪导向的指导。MEME_PULSE(好笑)、CUTE_CUNNY_PULSE(可爱)、SHOCK_HYPE_PULSE(兴奋)、DRAMA_NEWS_PULSE(新闻 / 戏剧性内容)、ANGRY_OUTRAGE_PULSE(愤怒吐槽)等。HOT/WARM— 有一些标记,但没有形成脉冲 → 轻松玩笑 / 活跃语气指导QUIET— 聊天较少,没有形成脉冲 → 中性,可自由选择动词
说明
情绪是指导,而非规则。
tone/verbs提示会告诉子 Agent 聊天呈现了哪种氛围;AI 仍会根据具体情境自行选择首个动词。只有当 PULSE 片段的时间戳描述把当时的氛围写得平淡时,validate_mood.py(步骤 11.5)才会提醒人工审核。表情字典参考:参阅
references/anibon_emoji_dictionary.md,了解完整的频道专属表情映射(:_CunnyBoat:、:_MonkeyBoat:、:_Nerd:、:_shutup:、:_Grind:、:_Ripfish:、:_noname:、:_What:、:_WOW:、:_Ahh:、:_Meh:、:_MoneyBoat:、:_Tahaan:、:_KonDee:、:_NeoSlim:、:_Slim:、:_BoatSOM:),以及 YouTube 全局表情对应的情绪脉冲权重和安全屏蔽触发条件。
如果某个片段被标记为 MEME_PULSE,但子 Agent 为其写出的首个动词平淡且偏事实陈述,validate_mood.py(步骤 11.5)就会将这种语气不匹配标出以供审核。
4. 分析(预检)
快速汇总片段类别、缺失项和字节大小。注意:在 Windows 上,使用 -X utf8 以避免控制台出现 UnicodeEncodeError。
python3 -X utf8 scripts/anibon-analyzer.py ~/youtube_<id>_workspace/
5. 检测信号 → 匹配知识文件
对所有分块进行 TF-IDF 分析。将关键词与每个分块对应的知识文件进行匹配。
python3 -X utf8 scripts/detect_signals.py \
--chunks ~/youtube_<id>_workspace/chunks/ \
--knowledge ./resources/knowledge.json \
--output ~/youtube_<id>_workspace/signals.json
输出:signals.json — 每个分块的加权信号:matched_files(包含 df/weight)、weighted_matched_files(按排名排列)、best_file、primary_topic、confidence。
路径约定:
knowledge.json中每个best_file/matched_files路径都相对于 timestamper 技能根目录。references/stream/*.md= timestamper 本地文件;../anibon-world-identity/references/*.md= world-identity 技能文件;../reference/*= 顶层数据目录中的文件。所有路径都从 timestamper 根目录解析,绝不要从当前工作目录解析。
稀有度 = 核心思想:
detect_signals.py根据逆文档频率(log(N/df))为每个匹配的关键词加权。高频词(df 高)是日常用语填充词,得分为 0——会被忽略。低频词(罕见词)才是有辨识度的核心思想。只有在confidence明确时才将best_file交给子 Agent;否则省略该知识文件。
5.5 加载 World-Identity(如果信号匹配到游戏参考资料)
触发条件: signals.json 中的 best_file/weighted_matched_files 解析到 ../anibon-world-identity/references/ 下的文件(即截止日期之后的游戏/角色名称)。这些名称是子 Agent 最容易产生幻觉的内容。
操作: 加载 anibon-world-identity 技能。它会依次使用 references/INDEX.md → 缓存的故事参考资料 → 参考 SRT → 网络搜索备用方案,构建经过验证的泰语音素 → 英文名称映射表。首先初始化其游戏数据库:
python3 ../anibon-world-identity/scripts/fetch_fgo_db.py --check --db "../reference/FGO and DATA/atlas_fgo.db" || \
python3 ../anibon-world-identity/scripts/fetch_fgo_db.py --db "../reference/FGO and DATA/atlas_fgo.db"
python3 ../anibon-world-identity/scripts/fetch_ygo_db.py --check --db "../reference/Yu-Gi-Oh DATA/ygo_cards.db" || \
python3 ../anibon-world-identity/scripts/fetch_ygo_db.py --db "../reference/Yu-Gi-Oh DATA/ygo_cards.db"
将解析出的名称映射表注入第 7 步的子 Agent 提示词中(针对信号匹配到这些文件的任何分块),以便 [Story] 标记使用规范名称,而非根据音素猜测。若流内容涵盖截止日期之前的知名内容,则跳过。
6. 检测主题边界(可选)
适用于主题转换明显的长流。运行:
python3 -X utf8 scripts/detect_boundaries.py --chunks ~/youtube_<id>_workspace/chunks/ --signals ~/youtube_<id>_workspace/signals.json --output ~/youtube_<id>_workspace/boundaries.json
如果边界看起来杂乱,可根据 signals.json 手动识别:寻找 matched_files 发生变化的分块(例如,游戏→Genshin→FGO)。记录时间戳,以便在第 9 步使用 --break-at。
7. 派生子 Agent(并行)
将分块划分为每组 4–5 个(每组约 20–25 分钟)。每组使用一个 anibon-chunk-timestamper。
运行 build_subagent_prompts.py 来准备输入文件:
python3 -X utf8 scripts/build_subagent_prompts.py <workspace>
此操作会生成:
<workspace>/prompts_by_chunk/chunk_NN.txt:每个分块对应的提示词文件(约 15–25KB,每个文件都保证小于view_file的 46KB 查看上限,以防分块内容被截断)。<workspace>/prompts/group_NN.txt:列出分块文件 URI 和元数据的组清单。
重要
严格并发分批(建议使用 4–6 个子 Agent):为避免 API 429
RESOURCE_EXHAUSTED速率限制(尤其是组清单达到约 50–100KB 时,可能导致滚动 TPM 耗尽),请按受控批次启动子 Agent,每轮启动 4–6 个(最多 8 个)。等待每批完成后,才能启动下一批。使用 Flash 模型层级:调用
invoke_subagent为分块时间戳工具指定Model: "flash",以最大限度提高速度并留出速率限制余量。按分块顺序读取:指示子 Agent 通过
view_file按顺序读取其分配的file://<workspace>/prompts_by_chunk/chunk_NN.txt文件,以确保完整读取 100% 的文本且不被截断。
调用模式(每组一个):
invoke_subagent(
"anibon-chunk-timestamper",
Model="flash",
prompt=f"""You are processing Group {g} (chunks {start} to {end}).
PREVIOUS GROUP LAST TOPIC: {prev_topic}
Read each chunk sequentially via view_file:
- file://{workspace}/prompts_by_chunk/chunk_00.txt
- file://{workspace}/prompts_by_chunk/chunk_01.txt
..."""
)
每个分块提示词包含:
- 分块 XML/对话行
- 来自
signals.json的检测信号(best_file+primary_topic+confidence+ 排序后的weighted_matched_files) - 每个分块的 LiveChat 日志(
livechat/livechat_chunk_NN.txt) - 每个分块的屏幕活动日志(
activity/activity_chunk_NN.txt) - 来自
mood_555.json的每个分块的情绪判断 + 语气指南
**关键:**Agent 会按顺序读取其所在组的分块,并跳过续接分块。 不要自行加入主题摘要,只注入信号数据。
每个 anibon-chunk-timestamper 会返回纯文本时间戳行(通常每组 2–4 行)。
重要
视觉 AI 与生成式工具的依据核实: 当主播测试或评价视觉 AI 生成器(例如文生图、视频生成或创意编辑工具)时,需区分:
- 主播实际提出的提示词。
- AI 模型实际在屏幕上生成的内容(或其失败/拒绝生成的情况)。
- 主播带有喜剧、政治或夸张色彩的讽刺吐槽。 绝不能把讽刺吐槽(例如 "กลายเป็นคอมมิวนิสต์"、"เหมือนสลิ่ม"、"หลอนเป็นเปรต")当成生成图像的字面描述。始终使用
[Reaction],并明确标注吐槽者(例如ปู่โบ๊ตเหวอ TH-AI เจนเป็นสาวไซเบอร์ยืนคู่ ครม. ไม่รู้จัก Jane Doe แซวยังกะรัฐบาลจีน)。
重要
时间戳起点与随口类比防护:
- 起点定位:始终将时间戳起点定位在讨论主题的开场句。切勿在关键专有名词已经说出后才从句中间开始标记(避免观众点击后错过上下文)。
- 随口类比规则:切勿将一两句话的随口类比或讽刺吐槽(例如把某个节目的预算拿来和 Frieren 比较)提升为主要时间戳标题。始终描述核心主题(例如 One Punch Man S3 与 J.C.Staff 的风波),并将随口比较放在括号中。
8. 合并时间戳
将每个子 Agent 的输出写入各自的文件(例如 chunk_001.txt、chunk_002.txt)。然后合并并按时间顺序排序:
python3 scripts/merge_timestamps.py ~/youtube_<id>_workspace/chunk_*.txt \
-o ~/youtube_<id>_workspace/all_timestamps.txt
8.5. 审查遗漏(摘要器运行前的必做步骤)
此步骤用于强制执行不留遗漏铁律。对合并后的列表运行该工具;如果退出码非零,则针对每个被标记的分块启动补全 Agent(工具会打印需要重新处理的 chunk_NN),并在第 9 步之前重新合并。
python3 scripts/audit_gaps.py ~/youtube_<id>_workspace/all_timestamps.txt
# exit 0: no gaps. exit 1: prints e.g. "12m 01:13 -> 01:25 (fill around chunk_26)"
8.6 将音频切片发送至 Whisper.cpp 并清理乱码笔记(依据事实)
子 Agent 必须只输出定位标记(- "token" @ HH:MM:SS (chunk_NN))。分两个不同阶段执行:
步骤 8.6a:先运行 whisper.cpp(编排器音频基准真值)
- 从分块时间戳输出中提取所有辨音备注,并保存到
<workspace>/garbled_notes_raw/candidates.txt。 - 运行
whisper_dispatcher.py,对时间戳进行聚类、即时切分音频,并通过本地whisper.cpp转录声学基准真值:
# Slicing & Audio Resolution:
# Option A (Recommended): Direct on-the-fly slicing from stream URL (no multi-GB download required)
python3 scripts/whisper_dispatcher.py ~/youtube_<id>_workspace --video-url "https://www.youtube.com/watch?v=<VIDEO_ID>" --verbose
# Option B (Local audio stream copy at 150x-300x speed without full video download):
URL=$(yt-dlp --extractor-args "youtube:player_client=android" -g -f 18 "https://www.youtube.com/watch?v=<VIDEO_ID>")
ffmpeg -y -i "$URL" -vn -c:a copy ~/youtube_<id>_workspace/audio.m4a
python3 scripts/whisper_dispatcher.py ~/youtube_<id>_workspace --verbose
这会生成 <workspace>/garbled_notes.json,其中包含:
google_sentence:来自raw_transcript.th-orig.json3的确切上下文句子窗口。whisper_segment:与时间对齐的声学句子片段,来自whisper.cpp(-oj)。correct:规范目标(自动从词典解析,或由子 Agent 设置)。
提示
切片失败恢复(单个集群): 如果任何集群切片失败(例如因临时流套接字超时而退出,状态码为 187):
URL=$(yt-dlp --extractor-args "youtube:player_client=android" -g -f 18 "https://www.youtube.com/watch?v=<VIDEO_ID>") ffmpeg -y -ss <start_sec> -t <duration_sec> -i "$URL" -ar 16000 -ac 1 -c:a pcm_s16le <workspace>/audio_slices/cluster_XXX_<start_sec>.wav /Users/zenithth/whisper.cpp/build/bin/whisper-cli -m /Users/zenithth/whisper.cpp/models/ggml-large-v3-turbo.bin -f <workspace>/audio_slices/cluster_XXX_<start_sec>.wav -l th --output-txt将转录文本更新到
garbled_notes.json,然后再传给anibon-garbled-notes。
步骤 8.6b:稍后调用 anibon-garbled-notes 子 Agent(基准真值对齐与词典同步)
将 whisper_dispatcher.py 得到的声学转录结果传给 anibon-garbled-notes 子 Agent:
invoke_subagent(
"anibon-garbled-notes",
Model="flash",
Prompt=f"""Analyze the whisper.cpp transcripts in {workspace}/garbled_notes.json.
Perform sentence-level word-by-word sequence alignment between google_sentence and whisper_segment to resolve phonetic noise slots.
Resolve canonical words, validate anti-cascade rules against raw_transcript.th-orig.json3,
update {workspace}/garbled_notes.json with confirmed targets, and run update_garbled_dictionary.py."""
)
子 Agent 会更新 <workspace>/garbled_notes.json 并执行:
python3 ../cleaning-auto-transcripts/scripts/update_garbled_dictionary.py \
--from-notes ~/youtube_<id>_workspace/garbled_notes.json \
--workspace ~/youtube_<id>_workspace
# If /Users/zenithth/abss-dev exists, sync git working copy as well:
if [ -d "/Users/zenithth/abss-dev" ]; then
python3 /Users/zenithth/abss-dev/skills/cleaning-auto-transcripts/scripts/update_garbled_dictionary.py \
--from-notes ~/youtube_<id>_workspace/garbled_notes.json
fi
警告
避免在 macOS 上使用
--cookies-from-browser:提取浏览器 Cookie 会触发 GUI Keychain 密码验证提示,导致无头/命令行后台 Agent 任务挂起。使用--extractor-args "youtube:player_client=android",无需凭据即可干净地绕过 YouTube SABR HTTP 403 错误。
注意
防级联基准真值检查:始终对照
raw_transcript.th-orig.json3核查候选辨音备注。如果候选项在泰语文本中包含多词游戏/动漫标题(例如Yuri on Ice、Chaos Zero Nightmare、Where Winds Meet、SLAPP),则这是过度激进的清理规则造成的伪影。切勿将清理器伪影保存到garbled_replacements.json。
输出:
~/youtube_<id>_workspace/garbled_notes.json— 所有候选项(garbled、google_sentence、whisper_segment、correct、chunk、ts、cluster_span)resources/garbled_replacements.json— 在根目录与技能资源之间自动同步的规范分组映射(TargetWord: [patterns...])
词典为共享资源(resource_path() 会逐级向上查找到插件根目录),因此今后的每次直播都会自动加载新规则。确实无法解析的专有名词会保留 correct: null,以供人工确认。
9. 最终组装 — anibon-summarizer(替代 wrap + pack)
将完整排序后的 all_timestamps.txt 传给 anibon-summarizer 子 Agent。它会去除跨分块重复项,按宏观主题连贯性分组(避免因 3,500 字节上限而过度拆分),筛选必要的时间戳(长直播约 40–60 个时间戳),编写简朴风格的分段标题,并生成最终 Markdown。
with open("all_timestamps.txt") as f:
merged = f.read()
invoke_subagent(
"anibon-summarizer",
prompt=f"TIMESTAMPS:\n{merged}"
)
子 Agent 会直接输出完整的 output.md。将其保存到 ~/youtube_<id>_workspace/output.md。
说明
pack_timestamps.py仍可用于离线/脚本运行,或在明确要求按单条评论字节数拆分时使用。在标准会话中,应优先采用宏观主题分组并筛选必要的时间戳,以保持主题连贯性。如果明确要求限制单条评论的字节数:python3 scripts/pack_timestamps.py ~/youtube_<id>_workspace/all_timestamps.txt \ --byte-limit 2900 \ --title "<Stream Title>" \ --output ~/youtube_<id>_workspace/output.md python3 scripts/check_sections.py ~/youtube_<id>_workspace/output.md
10. 验证章节
python3 scripts/check_sections.py ~/youtube_<id>_workspace/output.md
检查项:每个章节的字节数上限 ✅,不含 ASR 错乱模式。
11. 验证主题连贯性(可选)
将时间戳中的游戏名称与 signals.json 中的真实数据进行交叉比对。标记虚构的名称或不同部分之间的主题串扰。
python3 scripts/validate_part_coherence.py ~/youtube_<id>_workspace/output.md \
--signals ~/youtube_<id>_workspace/signals.json \
--chunks ~/youtube_<id>_workspace/chunks/
11.5 验证情绪与聊天脉冲(可选)
作为 analyze_555.py 的配套工具。为每个时间戳标注其分块的情绪 + 泰语语气指导(AI 可选用的动词)。仅供指导——不会拒绝任何动词;AI 可以自由发挥动词创意。仅生成报告;退出码为 0。用于检查 PULSE 时段的时间戳是否确实体现了分块的能量。
python3 scripts/validate_mood.py \
--timestamps ~/youtube_<id>_workspace/all_timestamps.txt \
--mood ~/youtube_<id>_workspace/mood_555.json \
--livechat ~/youtube_<id>_workspace/livechat/ \
--index ~/youtube_<id>_workspace/livechat/livechat_index.json
12. 目录编目、归档与词典同步(系列结束协议)
生成并验证 output.md 后(或多部分系列运行结束后):
-
同步错乱笔记:
- 收集并汇总所有部分中分块时间戳子 Agent 发现的
GARBLED_NOTES:。 - 将其写入
resources/garbled_replacements.json的"mappings"键下(data["mappings"]),并保留version、description、note这些头部元数据键。 - 同步插件根目录和随附副本中的文件(
resources/garbled_replacements.json和skills/anibon-timestamper/resources/garbled_replacements.json)。 - 将更新后的词典提交并推送到 GitHub(
anibon-stream-synthesis.git)。
- 收集并汇总所有部分中分块时间戳子 Agent 发现的
-
导入
timestamp_workspace:- **必需子技能:**使用
backing-up-timestamps。 - 运行
python3 -X utf8 import_workspace.py ~/youtube_<id>_workspace(或批量处理~/youtube_*_workspace)。 - 自动归档结构化转录文本(
transcripts/transcript_<id>.jsonl.gz)、复制extras/<id>/、自动重建搜索索引(python3 -m anibon_search build),并在by_video_id/timestamp_<id>.md和README.md中建立条目链接。 - 将
timestamp_workspace提交并推送到 GitHub(ZenitHTH/timestamp-workspace.git)。
- **必需子技能:**使用
-
归档原始工作区:
- 将已验证的目录移至
~/youtube_workspaces/backed_up/。 - 更新
metadata/catalog.json中的workspace_path。
- 将已验证的目录移至
输出格式
单个 .md 文件,包含 ═══ 分节块:
# Title | ANIBON
═════════════════════════════════════════════════════
Part 1: Section Header (⏱ เริ่ม: HH:MM:SS)
═════════════════════════════════════════════════════
HH:MM:SS - [Tag] Description
...
═════════════════════════════════════════════════════
Part 2: Section Header (⏱ เริ่ม: HH:MM:SS)
═════════════════════════════════════════════════════
...
辅助脚本
| 脚本 | 用途 |
|---|---|
scripts/prepare_video.py | 下载 + 清理 + 分块 |
scripts/dump_chunk_text.py | 从 XML 分块中导出格式整洁的文本,供子 Agent 使用 |
scripts/anibon-analyzer.py | 预检:缺口、类别、字节大小 |
scripts/detect_signals.py | TF-IDF 信号 + 知识文件匹配 |
scripts/detect_boundaries.py | 检测主题边界(在步骤 9 中提供给 --topic-json) |
scripts/align_live_chat.py | 将 LiveChat 事件流切分为逐转录分块日志(步骤 3.5) |
scripts/analyze_555.py | 从对齐后的 LiveChat 中检测泰式笑声/梗脉冲 → 逐分块情绪判定(步骤 3.7) |
scripts/validate_mood.py | 验证带情绪的时间戳是否遵循 mood_555 判定(步骤 11.5) |
../anibon-livechat-analysis/scripts/parse_live_chat.py | 将 .live_chat.json 解析为事件流(步骤 3.5) |
../anibon-livechat-analysis/scripts/extract_visual_livechat.py | 当 .live_chat.json 缺失时,通过 Gemini 视觉代理提取烧录在画面上的 LiveChat(步骤 3.5) |
scripts/merge_timestamps.py | 合并 + 排序子 Agent 输出 |
scripts/process_chunks_local.py | 通过 LM Studio / llama.cpp OpenAI 端点运行本地 LLM,顺序处理分块 |
scripts/audit_gaps.py | 缺口审计(NO GAPS 规则)+ 缺口→分块映射(步骤 8.5) |
scripts/pack_timestamps.py | 按字节限制打包片段(支持 --break-at、--topic-json) |
scripts/check_sections.py | 验证字节上限 + ASR 错乱文本 |
scripts/validate_part_coherence.py | 交叉核对游戏名称与信号 |
scripts/validate_tags.py | 验证时间戳标签词汇 |
../cleaning-auto-transcripts/scripts/clean_garbled_english.py | 规范化 Thai-Whisper 错乱英文(步骤 3) |
../cleaning-auto-transcripts/scripts/clean_transcript.py | 清理原始 json3(由 prepare_video 调用) |
../anibon-world-identity/scripts/fetch_story_ref.py | 获取/缓存故事梗概(需用户同意进行网页搜索) |
../anibon-world-identity/scripts/align_ref_timeline.py | 将参考 SRT 时间戳与分块对齐 |
../anibon-world-identity/scripts/fetch_fgo_db.py、fetch_ygo_db.py | 构建卡牌数据库(World Identity) |
铁律
- 使用指定的 Agent — 第 7 步必须按每个分块调用
invoke_subagent("anibon-chunk-timestamper")。第 8.6 步必须调用invoke_subagent("anibon-garbled-notes")。第 9 步必须调用invoke_subagent("anibon-summarizer")。绝不能用通用 Task/自身 Agent 替代。 - 严格分批调用子 Agent(建议每批 4–6 个) — 按每批 4–6 个子 Agent 进行受控处理(使用
Model: "flash"时最多 8 个),等待完成后再开始下一批。处理繁重提示词任务时,绝不能同时启动 10 个或更多子 Agent。 - 分块任务使用 FLASH 模型层级 — 为分块时间戳子 Agent 使用
Model: "flash",以确保快速执行并避免 API 速率限制。 - 禁止启发式/正则表达式回退 — 子 Agent 遇到错误或速率限制时,绝不能回退到启发式文本生成脚本。所有时间戳都必须由真实运行的
anibon-chunk-timestamper子 Agent 读取真实的转录 XML 和 LiveChat 日志后生成。 - 使用 detect_signals.py — 仅使用 TF-IDF。不得临时使用 grep/内联扫描。
- 不要自行读取分块 — XML 由子 Agent 读取。将 signals.json 数据注入提示词。
- 单个文件 — 使用包含
═══分节块的单个.md文件。不要创建part1.md。 - 不得有时间间隙 — 时间戳之间最多间隔 10 分钟,除非已确认期间无内容。
- 拆分开场部分 — 开场部分超过 10 分钟时,按 3–5 分钟的子主题里程碑拆分。
- 禁止临时时间戳 — 只能通过子 Agent 流程 →
merge_timestamps.py→anibon-summarizer生成。 - 阅读两边内容 — 子 Agent 在编写任何时间戳之前,必须读取整个转录分块,以及对应的 LiveChat 日志(如有)。情境和情绪必须同时依据对话与聊天内容,绝不能只依据
primary_topic。 - 遵从情绪判定 — 存在
mood_555.json时,将各分块的tone指引(情绪 + 建议动词)注入子 Agent 提示词。AI 可自行选择首个动词,但不得将聊天中欢笑/亢奋的高潮平淡化成冷静客观的动词。 - 扭蛋内容禁止剧透 — 时间戳描述中绝不能透露主播抽卡是成功还是失败。重点应放在期待感、当期卡池/角色以及聊天互动上。
- 18+/RULE 34 语气完整性 — 不得将成人同人图或 Rule 34 评论轻描淡写地归入通用搞笑标签(
[Reaction] ฮา...)。应使用[Talk],给出成熟、直接且准确的概述。 - 专有名词与游戏标题完整性 — 处理乱码笔记(第 8.6 步)时,绝不能将有效的外部游戏标题(例如 MARVEL Tōkon: Fighting Souls、Alien: Isolation、TMNT: The Last Ronin)、品牌名或常见英文短语(例如 where we meet)识别为噪声模式。未经确认的专有名词必须保留为
correct: null,交由人工审核,不得强行转换成泛化的泰语词汇。 - 每个时间戳都必须包含专有名词 — 每个时间戳都必须写出具体专有名词(例如 Wuthering Waves、Zelda、น้องเนเน่ AGT、Bleach)。绝不能使用含糊的代词(“这个游戏”“那个人”“这家公司”)。摘要器绝不能删掉专有名词;应删减形容词或情绪填充语。