关于 watch
用于分析视频链接或本地视频文件的 Claude 技能,综合抽样画面、带时间戳的转录文本和节奏指标。它生成结构化报告,并可在检测到 Obsidian 知识库时整理报告以供导入。
主要功能
- 01按场景变化抽取画面
- 02带时间戳转录及 Whisper 回退
- 03编辑节奏指标
- 04加密分析开头 10 秒
- 05适用于 Obsidian 导入的结构化报告
适用场景
- 01总结视频并回答相关问题
- 02检查指定时间点或片段
- 03分析开场钩子与剪辑节奏
- 04为 Obsidian 知识库准备视频报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ taoufik123-collab/ claude-watch --skill watch安装后在 Claude Code 中输入/watch确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.md.gitattributes.gitignoreAUTHORS.mdLICENSECHANGELOG.md.claude-plugin/marketplace.jsonplugin.json.codex-plugin/plugin.json.github/workflows/release.ymlcommands/watch.mdhooks/hooks.jsonhooks/scripts/check-setup.shscripts/hook.pypacing.pydownload.pyreport.pybuild-skill.shframes.pysetup.pywatch.pywhisper.pytranscribe.pyscripts/tests/__init__.pytest_report.pytest_pacing.pytest_frames_scene.py详细介绍
/watch — Claude 观看视频
你没有视频输入;这个技能会为你提供视频。Python 脚本会下载视频,将画面提取为 JPEG 帧(通过场景变化检测,每个镜头提取一帧),获取带时间戳的转录文本(优先使用原生字幕,失败时使用 Whisper API),运行剪辑节奏指标分析,并以更高密度检查前 10 秒。然后你通过 Read 查看每个帧路径对应的图像,结合转录文本回答用户,填写结构化的 report.md,并询问是否将分析内容导入 Taoufik 的 Second Brain。
v2 的不同之处
- 场景变化帧采样——每个检测到的镜头提取一帧,而非按固定间隔采样。长视频所需的帧数量更少,同时能捕捉每次转场。
- 剪辑节奏指标——每分钟剪辑次数、平均镜头长度、运动情况(可用时)。让你像剪辑师一样分析节奏。
- 开场显微分析——前 10 秒会自动以 2 fps 的频率提取画面,并使用 Whisper 进行逐词转录。任何视频中最值得投入精力的 10 秒,都值得细致分析。
- 结构化的
report.md——每次观看都会在<workdir>/report.md生成一份适合导入的报告,包含 TL;DR、关键时刻、开场分析、剪辑风格、值得引用的片段、实体、概念和转录文本。叙述性部分会以 `` 标记输出——你需要在提出导入前补全这些部分。 - 步骤 4.5 — 导入确认——回答用户后,只询问一次:“要将此内容导入你的 Obsidian 知识库吗?”如果用户同意且检测到了知识库,则读取
$VAULT_DIR/CLAUDE.md(如果存在),并运行该知识库的 Ingest 操作来处理报告。
以上内容均不会新增依赖——仅使用 ffmpeg、标准库和现有的 Whisper 后端。
配置 — 查找用户的 Obsidian 知识库
步骤 4.4 和 4.5 会将报告暂存到 Obsidian 知识库中,方便用户在阅读其他内容的地方查看报告。按以下顺序解析知识库目录——使用第一个匹配项,解析结果即下文中所有 $VAULT_DIR 的指向:
$WATCH_VAULT_DIR环境变量——如果已设置且路径存在,则使用该路径。这是用户可自行设置的覆盖选项。~/Second brain/——如果它是一个存在的目录。~/Documents/Obsidian/——如果它是一个存在的目录。~/Obsidian/——如果它是一个存在的目录。- 未找到——完全跳过步骤 4.4 和 4.5。在聊天中输出一行,告知用户处理结果:
📄 Report (no vault detected): <workdir>/report.md。如果用户希望自动导入,建议其设置WATCH_VAULT_DIR。
在技能中的 bash 环境里,可以用以下快捷方式解析目录:
VAULT_DIR="${WATCH_VAULT_DIR:-}"
if [ -z "$VAULT_DIR" ] || [ ! -d "$VAULT_DIR" ]; then
for candidate in "$HOME/Second brain" "$HOME/Documents/Obsidian" "$HOME/Obsidian"; do
if [ -d "$candidate" ]; then VAULT_DIR="$candidate"; break; fi
done
fi
知识库的 URL 名称(用于步骤 4.4 中的 obsidian:// URL 方案)就是路径的最后一部分——例如 $HOME/Second brain → Second brain。空格需编码为 %20。
第 0 步 — 设置预检(每次调用 /watch 时运行,成功时不输出任何内容)
**Python 解释器:**此技能中的所有 python3 ... 命令均适用于 macOS/Linux。在 Windows 上,请改用 python——Windows 上的 python3 命令是 Microsoft Store 占位程序,无法运行脚本。
每次运行 /watch 前,请确认依赖项和 API 密钥均已就绪:
python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py" --check
这是一次耗时不到 100ms 的检查。退出码为 0 时,脚本不会输出任何内容——直接继续第 1 步,无需评论。请勿向用户宣布“设置已完成”——用户不需要每一轮都收到状态消息。只有在需要修复时,才可以向用户显示第 0 步的输出。
退出码非零时,请按照下表操作:
| 退出码 | 含义 | 操作 |
|---|---|---|
2 | 缺少二进制文件(ffmpeg / ffprobe / yt-dlp) | 运行安装程序 |
3 | 缺少 Whisper API 密钥 | 运行安装程序以创建 .env 文件,然后向用户索要密钥 |
4 | 两者都缺少 | 运行安装程序,然后向用户索要密钥 |
安装程序可重复运行,不会产生副作用:
python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py"
在装有 Homebrew 的 macOS 上,它会自动安装 ffmpeg 和 yt-dlp。在 Linux/Windows 上,它会打印供用户运行的确切安装命令。它会在 ~/.config/watch/.env 中创建带注释的占位项,权限为 0600;依赖项和密钥就绪后,会写入 SETUP_COMPLETE=true,这样下次会话就知道该用户已完成设置向导。
**如果安装后仍缺少 API 密钥:**使用 AskUserQuestion 询问用户是否有 Groq API 密钥(首选——成本更低、速度更快)或 OpenAI 密钥。然后将密钥写入 ~/.config/watch/.env——设置对应的 GROQ_API_KEY=... 或 OPENAI_API_KEY=... 行。如果用户不想设置 Whisper,请使用 --no-whisper 继续,并告知他们没有原生字幕的视频将只返回帧画面。
结构化模式(可选):python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py" --json 会输出 {status, first_run, missing_binaries, whisper_backend, has_api_key, config_file, platform},其中 status 为 ready | needs_install | needs_key | needs_install_and_key 之一。当你需要根据具体情况分支处理时可使用此模式(例如,“这是用户第一次运行吗?”→ first_run: true)。
在同一会话中,后续调用 /watch 时可以跳过第 0 步——一旦 --check 返回 0,环境在不同轮次之间就不会发生变化。
适用场景
- 用户粘贴视频 URL(YouTube、Vimeo、X、TikTok、Twitch clip,以及大多数 yt-dlp 支持的网站)并询问视频内容。
- 用户提供本地视频文件(
.mp4、.mov、.mkv、.webm等)并询问文件内容。 - 用户输入
/watch <url-or-path> [question]。
建议限制
- **准确性最佳:时长在 10 分钟以内的视频。**帧覆盖率会随时长增加而降低。
- **硬性上限:总计 100 帧,且不超过 2 fps。**Token 成本会随帧数增加,因此脚本会根据时长设定帧预算(即使预算要求更高,也绝不会超过 2 fps):
- ≤30s → 约 1-2 fps(最多 30 帧)
- 30s-1min → 约 40 帧
- 1-3min → 约 60 帧
- 3-10min → 约 80 帧
- >10min → 100 帧,稀疏采样(会打印警告)
- 如果用户提供了长视频,可考虑先询问他们是否想看某个特定片段,再进行稀疏扫描,以免浪费 Token。
如何调用
步骤 1 — 解析用户输入。 将视频来源与用户提出的任何问题分开。问题(或用户之前表达的兴趣)就是意图——通过 --intent 将其传给脚本。例如:/watch https://youtu.be/abc what's the hook pattern? → source = https://youtu.be/abc,intent = what's the hook pattern?。如果用户没有提出问题,请使用简短的推断意图(“一般摘要”),让报告的 TL;DR 有一个切入角度。意图会影响第 4 步中报告的 TL;DR 和实体/概念部分的内容——同一个视频,意图为“定价策略”与“剪辑风格”时,生成的报告会有所不同。
步骤 2 — 运行 watch 脚本。 原样传入来源。除常规引号外,不要自行进行 shell 转义:
python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" "<source>" --intent "<intent string>"
只要用户提供了任何关于观看该视频原因的线索——提出的问题、说明的目标或简短的推断摘要——就传入 --intent。--intent 为空也能运行,但生成的报告章节针对性较弱。
可选标志:
--start T/--end T— 聚焦某个片段。接受SS、MM:SS或HH:MM:SS格式。设置其中任意一个时,fps 会自动调整得更密集(见下文“聚焦某个片段”)。--max-frames N— 降低上限,以便更严格地控制 token 预算(例如--max-frames 40)--resolution W— 更改帧宽度(单位:px,默认值为 512;只有在用户需要阅读屏幕文字时才调至 1024)--fps F— 覆盖自动 fps(上限为 2 fps)。设置--fps会禁用场景变化采样。--out-dir DIR— 将工作文件保存在指定位置(默认:自动生成的临时目录)--whisper groq|openai— 指定 Whisper 后端(默认:如果两个密钥都存在,优先使用 Groq)--no-whisper— 完全禁用 Whisper 回退机制(没有字幕时仅处理帧)--no-scene-change— 强制均匀采样帧(仅用于调试;通常保持启用)--no-hook-microscope— 跳过 0-10s 的密集扫描(可减少约 1 次 Whisper 调用)
聚焦某个片段(更高的帧率)
用户询问某个具体时刻时,例如“2 分钟时发生了什么?”,“放大看 0:45 到 1:00”,或“前 10 秒”,请传入 --start 和/或 --end。脚本会切换到聚焦模式的预算,采样密度高于完整视频模式(仍限制在 2 fps 以内):
- ≤5s → 2 fps(最多 10 帧)
- 5-15s → 2 fps(最多 30 帧)
- 15-30s → 约 2 fps(最多 60 帧)
- 30-60s → 约 1.3 fps(最多 80 帧)
- 60-180s → 约 0.6 fps(100 帧,设有上限)
以下情况适合使用聚焦模式:
- 用户明确指出的任何时刻/范围(“大约 2:30”、“开场部分”、“最后 30 秒”)。
- 视频时长超过约 10 分钟,且用户询问的是某个具体部分——聚焦相关片段远比稀疏扫描整段视频有用。
- 完整扫描后,某个区域的细节仍不够,需要重新运行。
转录文本会自动筛选到相同范围。帧时间戳为绝对时间(视频中的实际时间线,而非相对于起点的偏移量)。
示例:
# Last 10 seconds of a 1 minute video
python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" video.mp4 --start 50 --end 60
# Zoom into 2:15 → 2:45 at 3 fps (90 frames)
python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" "$URL" --start 2:15 --end 2:45 --fps 3
# From 1h12m to the end of the video
python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" "$URL" --start 1:12:00
步骤 3 — 阅读脚本列出的所有帧路径。 Read 工具会将 JPEG 直接渲染为图像供你查看。在一条消息中阅读所有帧(并行调用工具),以便同时查看。帧按时间顺序排列,并带有 t=MM:SS 时间戳,方便你与转录文本对齐。
步骤 4 — 回答用户,然后填写报告。 现在你有三类证据:
- 帧 — 每个时间戳屏幕上显示的内容
- 转录文本 — 每个时间戳说的话
report.md—<workdir>/report.md中带有 `` 标记的结构化产物
首先,在聊天中回答用户的问题,并注明时间戳。
然后,使用 Edit 工具填写 report.md 中的待填标记。按顺序逐一处理每个 ``:
- TL;DR — 从用户意图的角度撰写 3-5 条要点(从 frontmatter 中读取)
- 关键时刻 — 5-10 条带时间戳的要点
- 钩子显微镜解读 — 逐帧分析:画面变化 × 所说内容;识别钩子模式(疑问、反常识主张、开门见山、演示优先等)
- 编辑风格特征 — 根据节奏数据 + 主视觉帧总结风格,用一句话概括
- 值得引用的时刻 — 从转录文本中选出 3-5 条有力、独立成句的话
- 提及的实体 — 人物、公司、工具、地点 — 格式与 wiki/entities/ slug 一致(kebab-case、小写)。使用
[[wikilink]]样式。 - 呈现的概念 — 框架、心智模型、命名模式 — 每项简要概述
完整填写后的 report.md 将在第 4.5 步导入。不要跳过填写步骤——空标记无法正常导入。
第 4.4 步 — 暂存到 Obsidian 库并在 Obsidian 中打开(检测到库时)。 填写完所有标记后,根据 Configuration 部分解析 $VAULT_DIR。如果未检测到库,则跳过此步骤,并在聊天中输出 📄 Report (no vault detected): <workdir>/report.md。
解析出 $VAULT_DIR 后:
- 现在就生成 slug(不要等到第 4.5 步)。从
report.mdfrontmatter 中提取视频标题,转换为 slug(小写、仅 ASCII 字符、使用连字符,最多 60 个字符),并附加-YYYY-MM-DD。例如:karpathy-claude-md-43k-installs-2026-05-24。 - 创建暂存目录:
mkdir -p "$VAULT_DIR/raw/watched/<slug>"。 - 复制
report.md和每个主视觉帧(文件名位于报告 frontmatter 的hero_frames:下)到该目录。报告 MUST 位于库内,Obsidian 才能打开。 - 通过 URL scheme 在 Obsidian 中打开(macOS)。库的 URL 名称是
$VAULT_DIR的最后一个组件,空格需 URL 编码为%20:VAULT_NAME=$(basename "$VAULT_DIR" | sed 's/ /%20/g') open "obsidian://open?vault=${VAULT_NAME}&file=raw/watched/<slug>/report.md"file=的值是相对于库根目录的路径,不带前导斜杠。无需征求许可——用户运行 /watch 时已经选择了此操作。 - 在聊天中单独一行输出库内相对路径:
📄 Report (open in Obsidian): raw/watched/<slug>/report.md。这样,即使 Obsidian 已关闭或 URL 处理程序未能打开,用户仍可在库内手动找到该文件。
原因:报告是 /watch 的核心价值所在。如果用户在 Obsidian 中阅读所有内容,那么在 Preview 或 VS Code 中打开就违背了目的。在第 4.4 步暂存也意味着,第 4.5 步的“Yes / Stage”分支在复制操作上无需执行(文件已在库内);它们的区别仅在于是否运行 Ingest 操作。
第 4.5 步的清理说明: 如果用户在第 4.5 步选择“No, drop it”,且第 4.4 步已暂存到库中,还要执行 rm -rf "$VAULT_DIR/raw/watched/<slug>",因为我们已预先暂存。若用户选择 Yes 或 Stage,则不要删除库内副本。
第 4.5 步 — 提供导入 Obsidian 库的选项。 如果第 4.4 步未检测到库,则完全跳过此步骤。 否则,使用 AskUserQuestion 一次,并提供以下选项(如果检测到库,除非用户在运行 /watch 前明确表示“不要导入”,否则不要跳过):
问题:“要将其导入 Obsidian 库吗?”
- 是 — 相同角度(“”)
- 是 — 不同角度(用户在备注字段中指定)
- 暂存到
raw/watched/,稍后处理- 否,删除
根据回复进行路由: A. 是(相同或不同角度):
- 推导 slug:从
report.md的 frontmatter 中获取视频标题,转换为 slug(小写、仅 ASCII 字符、用连字符分隔,最多 60 个字符),再附加-YYYY-MM-DD。示例:me-at-the-zoo-2026-05-24。 - 确认暂存目录
$VAULT_DIR/raw/watched/<slug>/存在(步骤 4.4 已创建该目录)。 - 报告和主图帧已在步骤 4.4 复制到该目录。
- **如果选择“不同角度”:**在运行 ingest 之前,重新编辑复制后的报告中的 TL;DR、实体和概念部分,以体现用户指定的新角度。
- **如果
$VAULT_DIR/CLAUDE.md存在:**阅读该文件以刷新 Ingest 操作定义——该文件具有权威性;此技能不得重复其步骤。严格按照$VAULT_DIR/CLAUDE.md的定义,对raw/watched/<slug>/report.md执行 Ingest 操作。 - **如果
$VAULT_DIR/CLAUDE.md不存在:**运行通用 ingest——阅读报告,识别实体和概念,在$VAULT_DIR/log.md中追加一行条目(若文件不存在则创建),并告知用户报告已暂存到raw/watched/<slug>/report.md,他们可以自行配置 Ingest 操作。 - 在聊天中向用户反馈:哪些实体页面已被修改(如有)、暂存报告的路径,以及写入的
log.md条目。
B. 暂存到 raw/watched/,留待之后处理:
- 步骤 4.4 已完成暂存文件复制。
- 不要修改 wiki。不要向
log.md追加内容。 - 在聊天中告知用户:“已暂存到
$(basename $VAULT_DIR)/raw/watched/<slug>/。准备好后,对其运行 Ingest 操作。”
**C. 不需要,丢弃:**继续执行步骤 5(清理)——根据步骤 4.4 中关于清理的说明,运行 rm -rf "$VAULT_DIR/raw/watched/<slug>" 以撤销预暂存。
“不同角度”路径让 /watch 真正实现即插即用——用户可以出于某个原因观看视频,结束时再决定视频其实更适合另一个概念,最终生成的 wiki 条目也会相应地调整视角。
**步骤 5 — 清理。**脚本会在最后打印工作目录。如果你已执行 ingest(步骤 4.5 路径 A),主图帧和 report.md 已复制到 Second Brain——可以对原始工作目录运行 rm -rf。如果你选择暂存(路径 B),同样如此——不再需要工作目录副本。如果用户选择“不需要,丢弃”(路径 C),且不会再提出后续问题,请运行 rm -rf <dir> 删除目录。如果用户可能会提出后续问题,则保留该目录。
转录
脚本会通过以下两种方式之一获取带时间戳的转录文本:
- **原生字幕(免费,优先使用)。**如果源平台提供手动或自动生成的字幕,yt-dlp 会提取这些字幕。
- **Whisper API 备用方案。**如果没有获取到字幕(或来源是本地文件),脚本会提取音频(
ffmpeg -vn -ac 1 -ar 16000 -b:a 64k,约 0.5 MB/分钟),并上传到已配置密钥的 Whisper API:- Groq —
whisper-large-v3。首选默认方案:更便宜、速度更快。请在 console.groq.com/keys 获取密钥。 - OpenAI —
whisper-1。备用方案。请在 platform.openai.com/api-keys 获取密钥。
- Groq —
两个密钥均保存在 ~/.config/watch/.env 中。如果两个密钥都已设置,脚本优先使用 Groq;使用 --whisper openai 可强制使用 OpenAI。使用 --no-whisper 可完全跳过备用方案。
故障模式和处理方式
- 设置预检失败 → 运行
python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py"(在 macOS 上通过 brew 自动安装 ffmpeg/yt-dlp,并创建.env)。如需 API 密钥,请通过AskUserQuestion询问用户,并将密钥写入~/.config/watch/.env。 - 没有可用的转录文本 → 缺少字幕,并且(没有 Whisper 密钥或 Whisper API 调用失败)。脚本会打印提示并指向设置步骤。仅根据视频帧继续处理,并告知用户。
- 打印了长视频警告 → 在回答中说明这一点。可建议改用
--start/--end聚焦特定片段重新运行,而不是稀疏地扫描整段视频。 - 下载失败 → yt-dlp 的错误会输出到 stderr。如果视频需要登录或受到地区限制,请直接告知用户;不要继续重试。
- Whisper 请求失败 → 错误会输出到 stderr(可能是密钥无效、触发速率限制,或超长视频超过 25 MB 上传限制)。报告中会将转录文本标为“无可用内容”。如果 Groq 失败,可重试并使用
--whisper openai(反之亦然)。 - 报告中有未填写的 `` 标记 → 你跳过了步骤 4。返回并阅读报告,通过 Edit 填写每个标记,然后再提供导入选项。切勿导入未填写完整的报告——Second Brain Ingest 操作会生成内容稀疏或错误的实体页面。
- 导入中途失败 → 不要回滚。Second Brain Ingest 操作支持幂等地重新运行(它会更新现有页面,而不是重复创建)。告知用户失败之处,将暂存的产物留在
raw/watched/<slug>/,用户可以发送“ingest the staged report at<slug>”重新运行。
Token 效率
此技能消耗的 token 主要用于视频帧。数量级如下:
- 512px 宽的 80 帧大约消耗 50-80k 个图像 token,具体取决于宽高比。
- 转录文本消耗很少(10 分钟视频最多几千个 token)。
- 将
--resolution提高到 1024,单帧图像 token 大约会增加到 4 倍。仅在必要时这样做。
如果本次会话中你已经看过某个视频,而用户提出了后续问题,不要重新运行脚本——视频帧和转录文本已经在上下文中。直接根据已有内容回答。
安全与权限
此技能会执行以下操作:
- 在本地运行
yt-dlp下载视频,并在来源支持时提取原生字幕(公开数据;请求会直接发送到 URL 指向的主机) - 在本地运行
ffmpeg/ffprobe,将帧提取为 JPEG;需要使用 Whisper 时,还会提取单声道 16 kHz 音频片段 - 设置了
GROQ_API_KEY时,将提取的音频片段发送到 Groq 的 Whisper API(api.groq.com/openai/v1/audio/transcriptions)(首选 — 更便宜、速度更快) - 设置了
OPENAI_API_KEY且未设置 Groq 密钥,或强制指定--whisper openai时,将提取的音频片段发送到 OpenAI 的音频转录 API(api.openai.com/v1/audio/transcriptions) - 将下载的视频、帧、音频和中间转录稿写入系统临时目录下的工作目录(或指定的
--out-dir),以便 Claude 可以Read这些文件 - 读取 / 创建
~/.config/watch/.env(模式为0600),用于存储 Whisper API 密钥和SETUP_COMPLETE标记。作为备用方案,还会读取当前工作目录中的.env - 在编排时读取
$VAULT_DIR/CLAUDE.md(仅当请求摄取且文件存在时),以遵循该知识库的 Ingest 操作定义 - 在第 4.4 步检测到知识库时,将结构化的
report.md及精选帧副本写入$VAULT_DIR/raw/watched/<slug>/ - 获得摄取同意后:读取和写入
$VAULT_DIR/wiki/下的页面(实体、概念、来源、index.md),并向$VAULT_DIR/log.md追加内容 — 遵循该知识库 Ingest 操作中定义的操作(若不存在CLAUDE.md,则使用通用备用方案)
此技能不会执行以下操作:
- 不会将视频本身上传到任何 API — 仅当缺少原生字幕且未通过
--no-whisper禁用 Whisper 时,才会发送提取的音频 - 不会访问任何平台账号(不登录、不使用会话 Cookie、不发帖)
- 不会在服务提供商之间共享 API 密钥(Groq 密钥仅发送到
api.groq.com,OpenAI 密钥仅发送到api.openai.com) - 不会将 API 密钥记录、缓存或写入 stdout、stderr 或输出文件
- 除工作目录和
~/.config/watch/.env外,不会保留任何内容(获得摄取同意后,也会写入 Second Brain)— 完成后请清理工作目录(第 5 步) - 不会在第 4.5 步提示用户之前,未经明确同意就写入 Second Brain
- 不会悄悄覆盖知识库中的说法 — 根据 Ingest 操作约定,矛盾内容会显示为 WARN 标记
随附脚本: scripts/watch.py(入口点)、scripts/download.py(yt-dlp 封装器)、scripts/frames.py(ffmpeg 均匀抽帧 + 场景变化提取 + 精选帧选择)、scripts/pacing.py(编辑指标)、scripts/hook.py(0-10 秒显微分析)、scripts/report.py(结构化报告生成器)、scripts/transcribe.py(字幕选择 + Whisper 编排)、scripts/whisper.py(Groq / OpenAI 客户端,支持词级时间戳)、scripts/setup.py(预检 + 安装程序)
首次使用前,请检查脚本以确认其行为。