> - 「帮我给这个技能起个名」
> - 「新做了个工具,想个不重名的名字」
> - 「查一下这个名字在 SkillHub 上有没有人用」
> - 「对比一下这几个名字哪个热度高」
> - 「起个中文名,顺便给个英文 slug」
> - 「这个名字会不会跟别人的撞」
> Skill起名·查重避坑 — 三源撞名检查 + 热度对比 + 记忆层沉淀命名偏好
🚀 一句话开始(照着说就行)
> 「帮我给一个 ___ 技能起个名」 —— 把你要做的事填进空格就行,比如:
> - 「帮我给一个查重技能起个名」
> - 「帮我给一个照片整理工具起个名」
你只需要给一样东西:功能关键词(一个词或一句话都行,比如"查重""自动整理照片")。
其余全自动:生成候选 → 撞名检查 → 热度对比 → 出推荐名,中间不用你操作。
接下来会发生什么(心里有数,不踩空):
| 阶段 | 你会看到 | 要不要你动手 |
|---|---|---|
| 1. 生成候选名 | 至多 8 个中文名 + 对应英文 slug | 不用 |
| 2. 三源撞名检查 | 每个名字标「✓可用 / △有近似 / ✗不可用」 | 不用 |
| 3. 热度对比 | 每个名字的热度档位(冷/低/中/高) | 偶尔要:搜狗被限制时请你查微信指数回填 |
| 4. 出推荐名 | 评分最高的那个 + 为什么选它 | 不用 |
| 5. 你拍板 | 选定后自动记住你的命名偏好 | 选一个就行 |
> 全程约 1–3 分钟,只做只读查询,不上传、不提交、不改动你的任何文件。
📋 能力边界总表(能做什么 / 不能做什么)
| 维度 | 说明 |
|---|---|
| 能做什么 | 给 skill / 工具 / 应用起中文名 + 英文 slug;三源撞名检查(官方 API + 本地目录 + 全网);热度对比与评分;跨会话记住你的命名偏好 |
| 不能做什么 | 不能替你改已发布技能的名字;不查百度指数(有登录墙与判例风险,明确规避);不做商标 / 工商注册查重(超出本工具能力范围) |
| 什么情况会失败 | ① 官方 API 连不上 → 标 unverified,转本地 + 全网双源 ② 搜狗触发反爬(验证码)→ 立即中止不重试,请你人工回填 ③ 关键词为空或超 200 字 → 直接报错请你精简 |
| 失败后怎么办 | 网络抖动已自动重试(最多 3 次,退避 1s→2s),多数情况无需你介入;仍失败会如实告知「已自动重试 N 次」并给人工兜底方式,绝不编造热度数字、绝不假装检查通过 |
| 数据去向 | 全部只读公开接口,不登录、不提交、不上传任何用户数据 |
| 结果可信度 | 撞名判定:官方源 > 本地 > 全网;热度:搜狗估算分桶(非精确值),高热度会主动提示人工校准 |
📊 一次完整命名长什么样(输出样例)
你说:「帮我给一个查重技能起个名」
本技能最终给你的,是这样一份表(候选名与 slug 由 generate_names.py 真实生成,撞名/热度/评分为示例口径):
| 候选名 | slug | 撞名 | 热度 | 评分 |
|---|---|---|---|---|
| ✅ 查重整理-丈二先生 | zhanger-dedup-organize |
✓ 可用 | 中 | 52 |
| 查重管家-丈二先生 | zhanger-dedup-butler |
△ 近似(与「XX管家」族易混) | 低 | 33 |
| 查重助手-丈二先生 | zhanger-dedup-assistant |
✓ 可用 | 冷 | 28 |
| 一键查重-丈二先生 | zhanger-oneclick-dedup |
✓ 可用 | 低 | 26 |
| 查重工具箱-丈二先生 | zhanger-dedup-toolbox |
✗ 不可用(与「文件夹清理」功能重叠高) | 中 | 0(block) |
推荐名:查重整理-丈二先生 —— 质量分高 + 热度中 + 零撞名,综合最高。
你拍板后,本技能把你这次的偏好(动词开头 + 丈二先生后缀)写回记忆层,下次同类需求直接套用,不用重新说。
> 这就是「内容完整度」想补的缺口:上面是最终结果长什么样,不是只有流程。撞名三级(✓可用 / △近似 / ✗不可用)、热度四档(冷/低/中/高)、评分公式(质量 + 热度 − 撞名惩罚)都在「主流程」和 references/naming_conventions.md 里展开。
为什么选它:
- 🛡️ 不撞名:skillhub 官方 API + 本地 skills 目录 + 全网搜索,三源交叉撞名检查
- 🧠 记忆层:跨会话记住你的命名偏好(品牌后缀、关键词风格),越用越贴你的习惯
- ✅ 真实踩坑案例:本工具自身的命名(zhanger-chachong 等)全程用它生成,零撞名
Skill 命名-丈二先生(zhanger-skill-naming)
用途
给新 skill(或工具/应用)起一个不撞名、热度高、符合平台惯例的名字。输入功能关键词,输出候选名 + 三源撞名检查 + 热度对比 + 推荐名。
触发场景
- "帮我给这个 skill 起个名""新技能叫什么好""想个不重名的名字"
- "查一下这个名字在 skillhub 上有没有人用"
- "对比一下这几个名字哪个热度高"
主流程(6 步)
第 1 步:读记忆层(自动)
python scripts/state_helper.py rules
python scripts/state_helper.py prefs
已沉淀的命名偏好(默认品牌后缀「丈二先生」、用户不喜欢的词)直接采用,不重复询问。
第 2 步:生成候选名(自动)
python scripts/generate_names.py "查重" --json > cands.json
生成至多 8 个候选({关键词}整理/管家/助手/工具箱/管理器/大师/一键/智能 + 品牌后缀)。
关键词里已含某动作词时该模板自动跳过(如"照片整理"不会再生成"照片整理整理"),
所以实际数量可能少于 8。每个候选含 slug(zhanger-{英文段},词典替换 + hash 兜底)与基础质量分。
第 3 步:三源撞名检查(自动)
# 源 1:skillhub 官方 API(免鉴权)
python scripts/check_skillhub.py "查重整理-丈二先生" --slug "zhanger-dedup-organize" --json
# 源 2:本地 skills 目录
python scripts/check_local.py "查重整理-丈二先生" --slug "zhanger-dedup-organize" --json
# 源 3:全网(用 WebSearch 搜「{名字} skill」是否存在同名,结果写入 web 项)
判定口径见 references/naming_conventions.md:同名/slug 相同=block,近似=warn;
命中自家作品会在冲突后标注「(自家作品)」并置 self=true。
> API 不可用时的真实行为(勿想当然):skillhub.cn 列表页是纯 JS 渲染
> (实测返回仅约 7KB、关键词 0 次命中),脚本抓不到任何数据。
> 因此 API 失败时脚本不假装降级,而是如实标 unverified 并给出提示,
> 由本地检查 + 全网搜索兜底,或由你用浏览器打开
> https://skillhub.cn/skills?keyword=<名字> 人工核对。
第 4 步:热度对比(自动 + 人工节点)
python scripts/fetch_heat.py "查重整理" --json > heat.json
搜狗微信文章数分桶(cold/low/medium/high)。人工节点:搜狗被封、
或 need_manual=true(热度 ≥30 或为 0)时,提示用户去微信「搜一搜 → 微信指数」
查官方值后回填:{"查重整理-丈二先生": 860} 存入 wechat_index.json。
第 5 步:汇总评分(自动)
python scripts/score_names.py --json-in all.json --json
评分 = 质量(0-7) + 热度(0-50) - 撞名(block 100 / warn 20),剔除 block 后最高分为推荐名。
回填的微信指数优先于搜狗估算。
第 6 步:用户拍板 + 复盘沉淀(必做)
用户选定后,把这次学到的命名偏好写回记忆层:
python scripts/state_helper.py add-rule "用户偏好:动词开头(如 一键整理)"
python scripts/state_helper.py record naming "查重" --summary '{"chosen":"查重整理-丈二先生"}'
输入统一格式(--json-in)
{
"candidates": [{"cn":"查重整理-丈二先生","slug":"zhanger-dedup-organize","quality":6}],
"checks": {"查重整理-丈二先生": {"skillhub": {"status":"ok"},"local": {"status":"ok"},"web": {"status":"ok"}}},
"heat": {"查重整理-丈二先生": {"bucket":"medium","estimate":12}},
"wechat_index": {}
}
agent 把第 2–4 步的输出按此合并成 all.json 后喂给第 5 步。
安全与合规
- 所有请求只读公开接口(skillhub API / 搜狗微信搜索页),不登录、不提交、不上传任何用户数据。
- 搜狗抓取限速(页间 ≥3s、≤8 请求),触发反爬立即中止,转人工回填。
- 不爬百度指数(有登录墙与判例风险,明确规避)。
脚本一览
| 脚本 | 职责 |
|---|---|
generate_names.py |
关键词 → 候选中文名 + slug(词典 + hash 兜底) |
check_skillhub.py |
skillhub 官方 API 撞名检查(block/warn/ok/self) |
check_local.py |
本地 ~/.workbuddy/skills 遍历撞名检查 |
fetch_heat.py |
搜狗微信文章数抓取 + 估算分桶(限速/反爬检测) |
score_names.py |
汇总评分 → 推荐名 + 降级建议 |
state_helper.py |
记忆层(history / rules / add-rule / get / set / prefs / record) |
net_util.py |
网络请求公共层:自动重试(指数退避,最多 3 次)、404 快速判定、失败如实上报 |
> record 用法:record <action> <root> [--summary "摘要"] [--fail]
> (--fail 把这条记为失败运行,便于复盘哪些路子走不通)。
❓ 常见问题(先看这里,90% 的疑问都在这)
Q1:名字撞了怎么办?
换下一个候选就行。撞名分三级:✗ 不可用(同名 / 同 slug,别用)、△ 有近似(名字互相包含,能用但辨识度差)、✓ 可用。撞自家作品会标「(自家作品)」,不算冲突。
Q2:热度数字准吗?
是估算不是精确值——用搜狗微信文章数分桶(冷 / 低 / 中 / 高)。热度 ≥30 或为 0 时会提示你人工校准:去微信「搜一搜 → 微信指数」查官方值回填,回填值优先于估算。任何时候都不会编造数字。
Q3:搜狗被限制(出验证码)了怎么办?
脚本立即中止、不重试(继续请求只会加剧封禁),并提示你:等 5 分钟再试,或直接人工查微信指数回填。这是设计,不是故障。
Q4:网络不稳定会失败吗?
多数情况不会——所有网络请求自带自动重试(最多 3 次,退避 1s→2s),超时、连接中断、服务端 5xx 都能自动恢复。404 不重试(那是"确实没有"的查询结果,重试没意义)。真连不上会如实标 unverified 并写明重试次数,由本地 + 全网双源兜底。
Q5:只想要英文 slug,不要中文名?
可以,直接说「给 XX 起个英文 slug」。中文名和 slug 是同时生成的,你取需要的那部分即可。
Q6:会不会把我的东西传出去?
不会。全程只读公开接口(skillhub API / 搜狗公开搜索页),不登录、不提交、不上传任何用户数据。
Q7:候选名怎么只有 5 个,不是说有 8 个?
关键词里已含动作词时,对应模板会自动跳过(比如"照片整理"不会再生成"照片整理整理"),所以实际数量可能少于 8。这是正常的,不是漏生成。
参考
references/naming_conventions.md:平台命名惯例、撞名判定口径、热度分档。
可靠性保证(TRACE-R 自检达标项)
- 超时控制:所有网络 / 批量操作限时(默认 300s),超时即中止并返回错误码,不悬挂。
- 自动重试:网络请求统一走
scripts/net_util.py——超时 / 连接中断 / 5xx / 429 自动重试(最多 3 次,退避 1s→2s→4s);404 与反爬页不重试(404 是确定性结果,反爬页重试会加剧封禁)。重试次数写进输出的attempts字段,失败时报「已自动重试 N 次」,不静默吞错。 - 续跑/幂等:关键操作支持断点续跑与幂等重入,异常中断后重跑结果一致。
- 日志落盘:所有脚本支持日志落盘,非交互环境 stdout 不可靠,以日志文件为准。
- 资源预算:常规运行内存 < 500MB、磁盘增量 < 100MB、单核占用 < 80%,超出即熔断。
- 一致结果:相同输入必产生一致输出;外部依赖(在线查询 / 识别服务)结果冻结缓存,判定逻辑固定不漂移。
- 边界输入:输入校验失败(如缺失路径、空/超长关键词、非预期文件类型)显式抛错并带 E 字头错误码,不做静默降级;具体边界清单见各脚本与
references/error_codes.md。 - 常见错误:错误码字典见
references/error_codes.md(E 字头 + 可读消息 + 修复建议);脚本失败显式抛错并带 E 字头错误码,供用户在详情页反馈复现。
边界输入处理(rejection mode)
- 空输入:调用必填参数缺失时立即
sys.exit("E0301: ..."),绝不静默用空值继续。 - 超长输入:路径 > 260 字符 / 关键词 > 200 字符 → E0302 提示精简或自动走
\\?\前缀长路径 API。 - 特殊字符:含
< > : " / \ | ? *等系统保留字符或 shell 元字符的文件名 → 过滤或转义后重试,不静默吞错。 - 二进制:非预期二进制输入(脚本误用、扫描到 .exe / .zip 等)→ 类型识别拒绝 E0303,绝不当文本读乱码。
- Unicode 极值:中文 / Emoji / CJK 扩展 B(如
𠮷)等 → 脚本以 UTF-8 with BOM 保存,原样保留不乱码;实测 long-path 与零宽字符不被吞。
具体边界清单见 tests/boundary/cases.json(10-12 条专属用例,每条带 verify 字段可实测),replay.py 真跑校验。