| name | skill-omni-creation |
| description | 当用户说「从这个链接/URL生成skill」「把这个网页/教程做成skill」「从这个视频提取步骤」时触发。先读取此 SKILL.md,再按步骤调用 scripts/ 下的 Python 脚本完成:爬取网页或下载视频 → 下载图片/抽帧 → 生成标准 Skill Markdown 文件;若内容需要编程实现,自动编写并验证配套脚本(scripts/)。 |
这个 Skill 做什么
给定一个 URL(网页或视频),读取页面内容、下载相关图片或视频帧,整理成标准 Skill .md 文件,保存到 skills/<slug>/SKILL.md,图片保存到 skills/<slug>/references/;若任务需要编程实现,还会生成经过验证的脚本,保存到 skills/<slug>/scripts/。
适用请求:
- "从这个链接生成一个 Skill"
- "把这个教程做成 Skill"
- "从这个视频提取操作步骤"
执行总览(先看这里,再动手)
无论网页还是视频、无论是否走降级路径,完整流程都是固定的五段,缺一不可:
- 获取内容 —
scrape_page.py(视频走 analyze_video.py 抽帧;被反爬则按「Playwright 失败时的处理」构造 stage01.json)
- 图片环节 — 有图时
prepare_images.py → image_review.py 两层筛选 → save_images.py;无图时直接执行 save_images.py <slug> --keep
- 代码粗筛(必经) — 图片环节完成后按「代码生成(agents/)」一节判断是否需要生成脚本;命中粗筛必须读
agents/code-detector.md 细判。这一步没做完,不允许写 SKILL.md
- 【判定需要时】编写、验证并收口脚本 —
agents/code-writer.md → agents/code-verifier.md → finalize_scripts.py;验证失败只淘汰未通过脚本,不阻塞主 Skill
- 写生成的 SKILL.md — 永远是最后一步;有验证通过的脚本则引用它们,否则写一次纯文本+图片版
向用户展示执行计划时,计划里必须列出第 3 步(代码粗筛),不得省略。
网页与图片环境门禁
网页和图片依赖由 scripts/environment_gate.py 在代码层统一处理,不再要求 Agent 手工判断 .venv 路径或依次执行两个依赖检查。
门禁在任何 stage、缓存或图片目录被创建/清理之前完成,并按以下顺序执行:
- 选择已激活虚拟环境、当前虚拟环境或项目最近的
.venv;都不存在时,尝试在项目目录创建 .venv。
- 若选中的解释器不是当前解释器,自动使用该解释器重新执行当前脚本。
- 自动安装当前 profile 缺失的 Python 包:
beautifulsoup4、requests、Pillow、playwright。
- 网页 profile 自动安装并真实启动一次 Playwright Chromium。
- Debian/Ubuntu 类 Linux 在具备 root 或免密 sudo 时自动补齐 Chromium 系统库;其他 Linux 或无提权权限时返回非零并输出所需修复命令。
- 自动修复仍失败时输出
ENVIRONMENT_BLOCKED、写入 scripts/work/environment_status.json 并立即停止;不得转入网页降级、图片审核、save_images.py --keep 或最终化。
scrape_page.py、prepare_images.py、download_images.py、print_blocks.py、image_review.py 和 save_images.py 都会自动调用同一门禁,因此正常流程无需手工运行 --check-deps。
可选诊断命令:
{bootstrap_python} "{skill_directory}/scripts/environment_gate.py" --profile web-images --check
其中 {bootstrap_python} 只需是当前 shell 中任何能启动 Python 3 的命令;门禁会自行寻找或创建项目虚拟环境。去掉 --check 时,门禁会尝试自动修复环境。
ffmpeg(视频抽帧)
brew install ffmpeg
sudo apt-get update
sudo apt-get install -y ffmpeg
若未安装,analyze_video.py 会报错退出。安装后分别使用 where ffmpeg(Windows)或 command -v ffmpeg(macOS/Linux)确认路径,再执行 ffmpeg -version。
yt-dlp(视频下载)
优先安装到同一个 Python 环境:
{python} -m pip install --upgrade yt-dlp
{python} -m yt_dlp --version
也可以使用 macOS Homebrew、Linux 系统包管理器或 Windows winget/chocolatey/scoop,但脚本通过 {python} -m yt_dlp 调用时,仍以当前 Python 环境中的包为准。
可用脚本
所有脚本通过当前系统可用的 shell/code 工具调用,脚本本身不含任何 LLM 调用。
重要: skill_tool 返回的 skill_dir 即 {skill_directory}。网页/图片链路脚本允许用当前 shell 中可用的 Python 3 作为启动命令;代码门禁会自动切换到同一个项目解释器并重新执行。所有脚本仍用绝对路径调用,不要 cd、不要拼接 &&。脚本内部已将 work/ 锚定到自身目录,因此不依赖 shell 当前目录、盘符或路径中的空格。
scrape_page.py — 爬取网页
{python} "{skill_directory}/scripts/scrape_page.py" "<URL>" <slug>
stage01.json 结构:
{
"url": "...", "slug": "...", "title": "...",
"blocks": [
{"type": "heading", "level": 2, "text": "...", "source": "main"},
{"type": "text", "text": "...", "source": "main"},
{"type": "image", "url": "...", "alt": "...",
- 若 URL 是视频平台(B 站/YouTube/Vimeo/小红书),自动跳过爬取,返回
blocks=[] + video_urls=[url]
- 小红书链接(
xhslink.com 短链或 xiaohongshu.com 直链)必须通过 scrape_page.py 处理,不要直接用 fetch_webpage,脚本会自动判断是否为视频帖子
- 正文抽取覆盖标题、段落、列表、
pre/code/table/dl、常见代码编辑器、JS 文本容器及可恢复的 Canvas 文字
- stage01 在脚本内部施加整页 block、正文字符和序列化大小硬上限;超限时从整页范围保留结构与代表内容,不创建分页文件
- 只有代码门禁输出
ENVIRONMENT_READY 后,页面仍被反爬并返回空 blocks,才进入「Playwright 失败时的处理」;ENVIRONMENT_BLOCKED 必须停止,不能降级
print_blocks.py — 读取网页内容(替代 read_file 读 JSON)
{python} "{skill_directory}/scripts/print_blocks.py" <slug> --stage stage01
stage01.json、stage02.json 和 stage03.json 都不要直接读取。必须用这个脚本提取内容。
stage01/stage02/stage03 都输出一次相同全局预算的受限代表视图,不提供 offset、下一批游标或继续翻页入口;不要直接读取这些 JSON,也不要尝试补读被预算省略的内容。
prepare_images.py / image_review.py — 串行下载与单层图片审核
{python} "{skill_directory}/scripts/prepare_images.py" <slug>
只根据输出中的图片 alt 与周围文字完成一次审核,并把每张图片最终标为 KEEP 或 SKIP。无法确定图片是否有用时,一律标为 SKIP,不要调用 read_file 查看图片:
{python} "{skill_directory}/scripts/image_review.py" <slug> --first-pass KEEP SKIP SKIP
image_review.py 会把最终状态直接写入当前 stage02.json,并立即输出 KEEP_PATHS_ARGS;把其后的 --keep ... 参数原样传给 save_images.py。不要直接读取 stage02.json,不要扫描或列举整个 raw_images/,也不要使用 read_file、read_file_stream、shell、base64 或字节模式查看待审核图片。
analyze_video.py — 视频抽帧
{python} "{skill_directory}/scripts/analyze_video.py" "<video_url_or_slug>" --title "视频标题"
脚本不调用任何 LLM,只进行一次粗扫抽帧,不执行细扫。分析时只读取脚本当前打印的 5 个 review_frames/*.jpg;完成后运行同一命令并追加 --next-review-batch 获取下一批。选定关键帧后用相同编号的 frames/frame_NNNN.png 保存。
save_images.py — 保存选定图片
{python} "{skill_directory}/scripts/save_images.py" <slug> --keep raw_images/dom_000.jpg raw_images/dom_003.png
脚本会打印每张图片的最终文件名和 SKILL.md 的写入路径,例如:
[save_images] img_00.jpg <- raw_images/dom_002.jpg
[save_images] img_01.png <- raw_images/dom_005.png
[save_images] SKILL_MD_PATH: /Users/xxx/.jiuwenswarm/agent/workspace/skills/exposure_fusion_opencv/SKILL.md
生成 SKILL.md 时,用 write_file 写入 SKILL_MD_PATH 打印出的绝对路径。图片路径为 references/<文件名>,例如 references/img_00.jpg。
页面无图时也必须执行 save_images.py <slug> --keep;脚本会从 stage02(不存在则 stage01)生成 stage03,并打印同一个 SKILL_MD_PATH。
finalize_scripts.py — 验证后收口脚本
{python} "{skill_directory}/scripts/finalize_scripts.py" <slug> --keep scripts/verified_a.py scripts/verified_b.py
脚本只保留 --keep 中列出的验证通过脚本,删除其余生成脚本,并输出 SKILL_SCRIPT_MODE。无论结果是 with_scripts 还是 text_images_only,都输出 SKILL_MD_ALLOWED: true,主流程随后必须写一次最终 SKILL.md。
图片筛选标准
你正在审核从教程或指南页面提取的图片。该指南可能涵盖任意主题:软件操作、摄影、烹饪、硬件等。
只依据图片 alt 与周围文字判断,每张图必须给出以下两种最终状态之一:
KEEP:上下文已能明确证明图片直接说明步骤、概念或技巧,能帮助读者理解或复现。
SKIP:图片是小图标、Logo、广告、纯装饰图、其他页面缩略图、与指南主题无关,或者仅凭 alt 与周围文字无法可靠判断其价值。
有任何疑问时一律 SKIP。不得查看图片后再决定,也不得输出其他状态。
决策数量必须与 stage02 中图片数量完全一致,例如:
KEEP SKIP SKIP
输出格式规范(网页)
你正在为 AI 智能体构建一个 Skill 文件,用于学习和执行软件操作任务。
所有输出文字(描述、标题、步骤、说明)必须使用简体中文。
只有 YAML frontmatter 的 key(name、description)和图片路径保持原格式不变。
输入内容:
- TITLE —— 软件任务名称
- BLOCKS —— 按 DOM 顺序排列的内容块列表,每个块的类型为以下之一:
- {"type": "heading", "level": 1-4, "text": "...", "source": "main"}
- {"type": "text", "text": "...", "source": "main"}
- {"type": "image", "path": "references/img_NN.ext", "alt": "...", "source": "main"}
图片块在文字块之间按原始页面位置穿插排列。
输出格式(严格遵守):
name: <snake_case_skill_name>
description: <1-3句中文:描述这个 Skill 的用途和适用场景>
<技能名称(中文)>
Steps
分组规则(从上到下匹配,取第一条符合的):
- BLOCKS 中存在二级标题块(h2):
- 每个 h2 → ### 分组标题,每组步骤编号从 1 重新开始。
- 若该 h2 组内存在 h3 块 → 每个 h3 → #### 子节标题,每子节编号从 1 重新开始。
- BLOCKS 中只有三级标题块(h3),没有 h2:
- 每个 h3 → ### 分组标题,每组步骤编号从 1 重新开始。
- 没有 h2 也没有 h3 —— 单一连续流程:
- 平铺格式:一个编号列表,不加 ### 或 #### 标题。
格式示例:
有 h2 + h3(两级分组):
<h2 标题文字>
<h3 标题文字>
- <动词> <界面元素名>

- ...
<下一个 h3 标题文字>
- ...
<下一个 h2 标题文字>
<h3 标题文字>
- ...
只有 h2(一级分组):
<h2 标题文字>
- <动词> <界面元素名>

- ...
<下一个 h2 标题文字>
- ...
平铺格式(无 h2 无 h3):
- <动词> <界面元素名>

- ...
规则:
只输出 Skill Markdown 文件内容,不加任何前言或解释。
输出格式规范(视频)
你正在为 AI 智能体构建一个 Skill Markdown 文件,用于学习和执行视频教程中的操作任务。
所有输出文字(描述、标题、步骤、说明、图片 alt)必须使用简体中文。
只有 YAML frontmatter 的 key(name、description)和图片路径保持原格式不变。
输入内容:
- TITLE —— 视频任务名称
- BLOCKS —— 按时间顺序排列的内容块,每个块类型为以下之一:
- {"type": "text", "text": "..."} — 已从视频中提取的操作步骤(一条步骤一个 block)
- {"type": "image", "path": "references/video_frame_NN.png", "alt": "..."} — 对应时间段的截图
输出格式(严格遵守):
name: <snake_case_skill_name>
description: "<1-3句中文:描述这个 Skill 的用途和适用场景>"
<技能名称(中文)>
Steps
- <动词> <界面元素名或操作对象>

- ...
核心规则:
- YAML frontmatter 必须是输出的第一行内容。
- name 必须根据 TITLE 生成,使用英文小写 snake_case,避免 video、tutorial、skill 等空泛词。
- description 必须是 1-3 句简体中文,并用英文双引号包裹。
- 技能标题必须是简体中文,准确概括 TITLE 对应的任务。
- 只输出 Skill Markdown 文件内容,不加任何前言、解释或代码块。
依据规则:
- 每个步骤都必须有 BLOCKS 中的 text block 作为依据。
- 允许为了去重、合并和提升可读性而改写步骤表述。
- 但不得引入 BLOCKS 中没有出现的信息、工具、参数、平台、结论或建议。
- 任务范围由 TITLE 定义,与主任务无关的步骤一律跳过。
- 如果某个 text block 操作对象不清晰,且无法从相邻 block 判断其含义,则跳过。
【当前:分组版本】若视频只有单一流程可改回平铺版本(见下方注释)
分组规则:
- 若视频涵盖多个明显不同的子功能(例如:基础操作、公式使用、图表制作),
用 ### 标题划分每个子功能,每组步骤编号从 1 重新开始。
- 若视频是单一连续流程,使用平铺编号列表,不加 ### 标题。
- 不要过度分组,只在子功能之间有明确主题切换时才分组。
【平铺版本备用】如需回退,删除上方分组规则,改为以下一条:
- 使用平铺编号列表,不加 ### 或 #### 标题。
步骤规则:
- 每个编号步骤必须是可执行动作,尽量以动词开头。
- 用 粗体 标记关键界面元素、操作对象、工具名称或参数名称。
- 不保留原始时间戳。
- 不输出过细的鼠标移动、等待、浏览、片头片尾、广告、点赞订阅等无关内容。
图片规则:
- 只能引用 BLOCKS 中 path 字段确实存在的图片,不得自行发明或伪造路径。
- path 必须从 block 的 path 字段原样复制。
- 图片语法必须为:

- 图片应放在与其最相关的步骤之后。
- 不要求每个步骤都配图;无明确关联的图片可以跳过。
- 每张图片独占一行,前后各留一个空行。
- 不要连续堆叠多张与同一步骤无明显区别的图片。
合并规则:
- 重复步骤合并:
若多步描述完全相同,或仅措辞略有不同但属于同一操作,只保留一步。
- 微步骤合并:
若连续多步属于同一标准流程,例如选择路径 → 点击 Next → 点击 Install,
可合并为一步,用"并""然后""最后"连接关键动作。
- 选项展示合并:
当连续步骤逐一列举同类选项,例如"点击网页渠道、飞书渠道、Telegram 渠道",
说明视频在展示可用选项,而不是要求全部选择。
应合并为一条步骤,概述可用选项,并说明本教程实际进入或配置的是哪一个。
- 纯描述前缀合并:
若某个 text block 只描述软件功能,没有具体操作,但与下一步属于同一功能模块,
可合并到下一步,作为上下文前缀。
若与后续步骤无明确关联,则只有在有助于理解任务时才保留;否则跳过。
- 平台泛化:
若步骤中涉及特定平台或系统,但 BLOCKS 中明确提到多个平台,
不要写死为单一平台,应写成"根据操作系统选择对应安装包",并在括号中列出视频提到的平台。
若 BLOCKS 只提到一个平台,则不要自行补充其他平台。
输出要求:
- 只输出 Skill Markdown 文件内容。
- 不加解释、不加前缀、不加 Markdown 代码块。
Playwright 失败时的处理
本节只处理代码门禁已经输出 ENVIRONMENT_READY,但目标网页仍返回空内容、403 或验证页的情形。若任一脚本输出 ENVIRONMENT_BLOCKED 或返回非零,必须停止当前网页/图片流程;不得使用本节绕过环境失败。
在上述前提下,若 scrape_page.py 返回空 blocks,使用 web_fetch_webpage 获取页面原始文本,自行提取:
- 主标题
- 按顺序排列的 h2/h3 标题和步骤文字
- 图片 URL(若有)
提取后不要直接写 SKILL.md,而是把提取结果手工构造成 work/<slug>/stage01.json(结构与「scrape_page.py」一节展示的完全一致:顶层含 url/slug/title/blocks/video_urls,image block 必须带 url 字段),然后回到正常链路继续:
{python} "{skill_directory}/scripts/prepare_images.py" <slug>
- 若页面确实没有图片,可跳过 prepare_images,但必须执行
save_images.py <slug> --keep 以生成 stage03 并确定最终输出路径
- 「代码生成(agents/)」的粗筛与后续流程在此路径上同样必须执行——降级只改变内容获取方式,不改变流程本身
代码生成(agents/)
有些内容描述的任务本质上要靠代码完成,纯文字步骤不足以复现。图片环节完成后(包括无图时执行 save_images.py <slug> --keep),做一次粗筛,满足任意一条 → 读 agents/code-detector.md 细判:
- 正文含成段代码块(约 5 行以上)
- 任务本质需编程完成(批量处理、API 调用、数据转换、算法实现)
- 内容是 CLI 命令组合的教程
粗筛与细判的纪律:
- 粗筛是必经步骤:无论内容来自 scrape_page、fetch_webpage 降级还是视频帧分析,读完内容后都要先做粗筛,才能进入写 SKILL.md 的环节
- 粗筛命中后必须读
agents/code-detector.md,按文档标准细判——不得凭自身感觉替代文档判断
- 判定由你独立完成且是终局的:不询问用户要不要脚本,不提议添加内容中不存在的脚本;判定不需要就直接按原流程写 SKILL.md
detector 判定需要脚本后,严格按此顺序执行:
- 读
agents/code-writer.md,把脚本写入 {skill_directory}/../<slug>/scripts/(若本次运行过 save_images.py,以其打印的 SKILL_DIR 为准)
- 读
agents/code-verifier.md,逐个验证并记录通过名单;验证失败或依赖无法就绪时,不得中止主流程
- 调用
finalize_scripts.py <slug> --keep <验证通过的相对脚本路径...>;未列入通过名单的脚本由代码删除。没有脚本通过时只传 --keep
- 写一次生成的 SKILL.md:有幸存脚本则只引用这些脚本;没有幸存脚本则写纯文本+图片版,不写脚本依赖或调用
纯 GUI 点击教程不满足粗筛 → 跳过本节,按原流程写 SKILL.md。
执行流程参考
网页路径:
scrape_page.py
→ prepare_images.py <slug> # 内部强制 download_images.py 完成后再运行 print_blocks.py --stage stage02
→ image_review.py 根据 alt 与周围文字一次性标记 KEEP/SKIP(不确定一律 SKIP)
→ save_images.py(传 KEEP_PATHS_ARGS;无图只传 --keep) # 统一生成 stage03.json 并打印 SKILL_MD_PATH
→ print_blocks.py <slug> --stage stage03 # 输出含 path 的最终 blocks
→ 代码粗筛 # 见「代码生成(agents/)」;命中则读 agents/code-detector.md 细判
→ 【判定需要脚本时】agents/code-writer.md 编写 → agents/code-verifier.md 验证
→ finalize_scripts.py <slug> --keep <验证通过脚本...> # 失败脚本自动删除;零通过则进入纯文本+图片模式
→ write_file 写入 save_images.py 输出的 SKILL_MD_PATH(按「输出格式规范(网页)」,图片路径直接从 blocks 取;
仅在有验证幸存脚本时写「前置依赖」和脚本调用)
注意:stage01.json / stage02.json / stage03.json 不要直接读取。 三个 stage 的模型可见输出都由 print_blocks.py 施加同一全局预算;网页图片只依据 stage02 代表视图中的 alt 与周围文字审核,并只使用 image_review.py 输出的 KEEP_PATHS_ARGS,禁止扫描、列举或读取整个 raw_images/。
视频路径:
scrape_page.py → video_urls 非空(或直接识别视频 URL)
→ analyze_video.py <video_url_or_slug> --title "..."
(只执行单阶段粗扫:短视频按 0.5fps;长视频自动降低频率并均匀覆盖全片;总帧数最多 90;每批最多 5 帧)
(脚本自动复用 stage01 的 slug;Bilibili 中断后通过持久化 .part 文件续传)
→ 脚本首次只打印当前批次的 5 个精确 `review_frames/*.jpg` 绝对路径
只读取这 5 个路径;完成后运行 `analyze_video.py <slug> --next-review-batch` 获取下一批
选择后映射到同编号的 frames PNG,并记录步骤对应的帧编号
→ 【必须执行】save_images.py — 将选用帧复制到 references/ 后再写 SKILL.md
选出最能说明各步骤的帧(建议每个关键步骤 1 张),收集相对路径列表,例如:
["frames/frame_0040.png", "frames/frame_0120.png", ...]
运行:
{python} "{skill_directory}/scripts/save_images.py" <slug> --keep frames/frame_0040.png ...
脚本输出:
[save_images] video_frame_0040.png <- frames/frame_0040.png ← 保留原帧编号
[save_images] SKILL_MD_PATH: /absolute/path/to/<slug>/SKILL.md
记录 SKILL_MD_PATH(后续 write_file 用此路径)
图片路径格式:references/video_frame_NNNN.png(原帧编号,4 位)
→ 代码粗筛 # 见「代码生成(agents/)」;命中则读 agents/code-detector.md 细判
→ 【判定需要脚本时】agents/code-writer.md 编写 → agents/code-verifier.md 验证
→ write_file 写入 SKILL_MD_PATH(按「输出格式规范(视频)」,图片路径从 save_images.py 输出中取;
含脚本时「前置依赖」一节在正文最前,只引用验证幸存的脚本)
网页含嵌入视频:
先走网页路径。若 video_urls 非空,追加视频路径处理,合并步骤后写 SKILL.md。
运行环境
- Python 3.11+;网页/图片链路由
environment_gate.py 自动选择或创建项目虚拟环境,并在必要时重新执行当前脚本
- Python 依赖:
playwright、beautifulsoup4、Pillow、requests;视频另需同环境中的 yt-dlp
- Playwright Chromium 与 Linux 系统库由代码门禁尽可能自动安装;无法安全自动修复时返回非零并停止
- 外部工具:
ffmpeg、ffprobe
ENVIRONMENT_BLOCKED 后不得继续构造 stage、执行图片审核、保存空图片结果或最终化
- 无需配置 API 环境变量