1实现原理 · 为什么它能做到
本 skill 的实底是两段确定性 Python:scan_repo.py 做结构/信号扫描,extract_commands.py 从 README 抽命令并分类;SKILL.md 只规定何时用、输出什么。命令抽取不是『让模型读 README 猜』,而是正则 + 标题归属 + 启发式分类的可复现流程。
"""Extract shell-like commands from README content and classify them."""
扫描范围被白名单固定:只查 9 个关键文件与 7 个高信号目录,不做全仓遍历;其结果与警告直接由脚本产出(如缺 README 会显式告警),而非模型自由描述。
KEY_FILES = [ "README.md", "README", "requirements.txt", "environment.yml", "environment.yaml", "pyproject.toml", "setup.py", "setup.cfg", "Dockerfile", ]
分类器有明确的优先级与辩解:setup/asset 语法先判(避免把安装写成推理),然后标题语义,再按入口脚本名判定(train*.py / eval*.py / sample|generate|infer*.py),最后才落到关键词扫描。
# Unambiguous setup/asset syntax outranks generic headings such as # "Basic Example", which otherwise makes installation look like inference. if lowered.startswith(SETUP_PREFIXES + ASSET_PREFIXES): return "other"
对 README 里引用的 .py 入口做结构级复核:读该脚本(≤512 KiB),按 optimizer.step(/backward(/train()/def train*/epoch 循环打分,≥4 分才把命令由原分类改判为 training,并记录 classification_source='entrypoint-structure' 与证据标签。
TRAINING_STRUCTURE_SIGNALS = [ ("optimizer-step", re.compile(r"\boptimizer\s*\.\s*step\s*\(", re.IGNORECASE), 3), ("backward-pass", re.compile(r"\.\s*backward\s*\(", re.IGNORECASE), 3), ("model-train-mode", re.compile(r"\.\s*train\s*\(", re.IGNORECASE), 2), ("train-function", re.compile(r"\bdef\s+train\w*\s*\(", re.IGNORECASE), 1), ("epoch-loop", re.compile(r"\bfor\s+\w*epoch\w*\s+in\b", re.IGNORECASE), 1), ]
『分类可以保守到承认无知』被写进 reference:证据不足时标注为 inferred,宁可记录歧义也不过度承诺;README 明确证据优先于文件名猜测。
## Conservative behavior - prefer explicit README evidence over filename guesses - mark guessed classifications as inferred - record ambiguity instead of overcommitting
职责边界被写死:只扫描与规划,不装环境、不下大资产、不跑实质命令、不决定高风险 patch;输出的是给主编排器的最小可信复现建议。
## Clear boundaries - This skill scans and plans. - This skill is helper-tier and should usually be orchestrator-invoked. - It does not install environments. - It does not prepare large assets. - It does not execute substantive reproduction commands. - It does not decide high-risk patching.
编排器真的会调用这两个脚本(不是文档里的摆设):orchestrate_repro.py 解析 skill 目录后以子进程方式跑 scan_repo.py --repo … --json,再拿 readme_path 跑 extract_commands.py --readme … --json,并把结果并入复现流程。
scan_data = run_json(scan_script, ["--repo", str(repo_path), "--json"]) readme_path = scan_data.get("readme_path") command_data: Dict[str, Any] = {"commands": [], "counts": {}, "warnings": []} if readme_path: command_data = run_json(extract_script, ["--readme", readme_path, "--json"])
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | Python 3(脚本解释器;由宿主/编排器调用,脚本自身无子进程外呼) |
4风险提醒 风险提醒:绿色 · 放心使用
- 分类结果可被恶意 README 误导 — 分类完全基于 README 文本与仓库内脚本的静态信号:一个把训练脚本命名为 eval.py、或在不相关 README 里塞入命令的攻击者能影响清单条目。缓解在于它只产出建议、不执行;但下游若不加人工确认直接照单执行,误分类(尤其 training ↔ evaluation)会绕过训练授权语义。
- SKILL.md 未文档化脚本 CLI — 模型自助使用时看不到 --repo/--json、--readme/--json 契约,可能只靠肉眼读 README 而不调用脚本,退化为『凭印象列命令』;文档与代码之间缺少一段示例。
- 启发式覆盖有限,存在静默漏检 — 只认白名单语言围栏(bash/shell/sh/zsh/powershell/cmd,无语言标签也认)与部分命令前缀;非英语 README、Makefile/CLI 型入口、或写在 prose 里的命令会漏。Reference 用『记录歧义』要求模型补位,但这依赖模型自觉。
- 读取仓库内文件内容带来理论上的解析风险 — training_structure_evidence() 会 read_text 仓库内被引用的 .py(≤512 KiB);虽有 relative_to(root) 与大小上限,仍属对不可信内容的一次读取(仅正则匹配,无执行)。
5第二遍独立确认
- [ok] skill 路径(任务书标『待定位』) — 实际相对路径 skills/repo-intake-and-plan;SKILL.md 位于该目录根。
- [ok] 『helper 脚本』确实存在且被调用(非文档装饰) — orchestrate_repro.py:1162-1167 设定 scan_script/extract_script 并在 1173-1178 以 run_json(...) 执行;_bundled/MANIFEST.json 记录两文件打包目标与 sha256;references/skill-registry.json 的 required_files 列出两者。
- [discrepancy] SKILL.md 未给出脚本调用示例 — SKILL.md 仅在 Notes 写 'Use `references/repo-scan-rules.md` and helper scripts under `scripts/`.',没有给命令行/参数示例;实际 CLI 契约(--repo/--json、--readme/--json)只能从脚本 argparse 与编排器调用点得到。对模型自助调用不够友好,属可改进项;不影响机制结论,已在 capabilities/how_it_works 中改用编排器调用点为证据。
- [ok] 无网络/无凭证/无写入 — 两脚本 import 仅 argparse/json/re/pathlib/datetime/typing(scan_repo 另有 timezone);全目录 URL/urllib/requests/socket/subprocess/os.environ 扫描零命中;无写文件调用(仅 print 到 stdout)。
- [ok] 路径越界防护 — referenced_python_script() 先 (root / path).resolve() 再 candidate.relative_to(root),越界抛 ValueError 返回 None;并有 is_file() 与 524_288 字节上限。
- [ok] 分类优先级与注释一致 — classify() 实际顺序为 setup/asset 前缀 → 章节语义 → SCRIPT_CATEGORY_HINTS → 关键词,与文件内注释 'Unambiguous setup/asset syntax outranks generic headings' 一致;command_kind() 独立返回 setup/asset/run/smoke(--help/-h → smoke)。
- [ok] README 定位与姊妹 helper 分工 — README.md:160 'Two helpers support orchestration: `repo-intake-and-plan` and `paper-context-resolver`.';tests/trigger_cases.json 中 'expected_top': 'repo-intake-and-plan' 的用例存在(repo_scan_only_en:'Do not run anything yet.'),与 SKILL.md 的『不执行实质命令』一致。
- [ok] 元数据 — 本地 git HEAD bd91195ad73199b95e24532b581ff12c07dcce09(= 任务书 pin);LICENSE MIT / Copyright (c) 2026 Chengkun Rao;gh api → stars 487、last_push 2026-09-13T13:16:25Z。
6结论
1953a875072a9f35…bd91195ad7