whosellm 0.1.1a4__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.bumpversion.toml +1 -1
- whosellm-0.2.0/.claude/commands/interview.md +11 -0
- whosellm-0.2.0/.claude/skills/code-review/SKILL.md +240 -0
- whosellm-0.2.0/.claude/skills/create-skill/SKILL.md +211 -0
- whosellm-0.2.0/.claude/skills/e2e-metadata/SKILL.md +532 -0
- whosellm-0.2.0/.claude/skills/evolve/SKILL.md +273 -0
- whosellm-0.2.0/.claude/skills/fix-review/SKILL.md +209 -0
- whosellm-0.2.0/.claude/skills/release/SKILL.md +162 -0
- whosellm-0.2.0/.claude/skills/review-provider-model/SKILL.md +203 -0
- {whosellm-0.1.1a4/.claude/skills/update-provider-model → whosellm-0.2.0/.claude/skills/review-provider-model}/providers/alibaba.md +6 -0
- {whosellm-0.1.1a4/.claude/skills/update-provider-model → whosellm-0.2.0/.claude/skills/review-provider-model}/providers/anthropic.md +7 -1
- {whosellm-0.1.1a4/.claude/skills/update-provider-model → whosellm-0.2.0/.claude/skills/review-provider-model}/providers/deepseek.md +7 -1
- whosellm-0.2.0/.claude/skills/review-provider-model/providers/gemini.md +65 -0
- {whosellm-0.1.1a4/.claude/skills/update-provider-model → whosellm-0.2.0/.claude/skills/review-provider-model}/providers/openai.md +6 -0
- {whosellm-0.1.1a4/.claude/skills/update-provider-model → whosellm-0.2.0/.claude/skills/review-provider-model}/providers/others.md +13 -2
- {whosellm-0.1.1a4/.claude/skills/update-provider-model → whosellm-0.2.0/.claude/skills/review-provider-model}/providers/vidu.md +6 -0
- {whosellm-0.1.1a4/.claude/skills/update-provider-model → whosellm-0.2.0/.claude/skills/review-provider-model}/providers/zhipu.md +6 -0
- whosellm-0.2.0/.claude/skills/update-provider-model/SKILL.md +299 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.gitignore +3 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/CLAUDE.md +51 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/PKG-INFO +90 -25
- {whosellm-0.1.1a4 → whosellm-0.2.0}/README.md +89 -24
- whosellm-0.2.0/docs/spec_model_family_redesign.md +236 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/pyproject.toml +1 -1
- whosellm-0.2.0/tests/e2e/conftest.py +32 -0
- whosellm-0.2.0/tests/e2e/test_anthropic.py +204 -0
- whosellm-0.2.0/tests/e2e/test_google.py +220 -0
- whosellm-0.2.0/tests/e2e/test_openai.py +238 -0
- whosellm-0.2.0/tests/e2e/test_zhipu.py +223 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_anthropic.py +2 -2
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_gemini.py +2 -2
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_glm45v.py +9 -5
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_glm46.py +5 -5
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_glm5.py +11 -11
- whosellm-0.2.0/tests/models/families/test_gpt3_5.py +35 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_gpt4_1.py +30 -12
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_gpt5.py +131 -43
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_o1.py +22 -27
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_o3.py +9 -7
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_o4.py +7 -5
- whosellm-0.2.0/tests/models/families/test_qwen_ollama.py +109 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/test_auto_register.py +8 -8
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/test_llmeta.py +11 -11
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/test_model_version.py +22 -24
- whosellm-0.2.0/tests/test_registry_merge.py +327 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/test_variant_priority_config.py +33 -70
- {whosellm-0.1.1a4 → whosellm-0.2.0}/uv.lock +1 -1
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/__init__.py +1 -1
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/base.py +30 -19
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/config.py +33 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/alibaba.py +4 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/anthropic.py +14 -4
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/gemini.py +16 -6
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/__init__.py +11 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/openai_gpt_3_5.py +4 -24
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/openai_gpt_4.py +16 -6
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/openai_gpt_4_1.py +12 -8
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/openai_gpt_4o.py +2 -2
- whosellm-0.2.0/whosellm/models/families/openai/openai_gpt_5.py +153 -0
- whosellm-0.2.0/whosellm/models/families/openai/openai_gpt_5_1.py +101 -0
- whosellm-0.2.0/whosellm/models/families/openai/openai_gpt_5_2.py +89 -0
- whosellm-0.2.0/whosellm/models/families/openai/openai_gpt_5_3.py +51 -0
- whosellm-0.2.0/whosellm/models/families/openai/openai_gpt_5_4.py +137 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/openai_o1.py +3 -18
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/openai_o3.py +2 -7
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/openai/openai_o4.py +10 -3
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/zhipu.py +37 -22
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/registry.py +76 -7
- whosellm-0.2.0/whosellm/py.typed +0 -0
- whosellm-0.1.1a4/.claude/skills/update-provider-model/SKILL.md +0 -174
- whosellm-0.1.1a4/whosellm/models/families/openai/openai_gpt_5.py +0 -395
- whosellm-0.1.1a4/whosellm/models/families/openai/openai_gpt_5_1.py +0 -40
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.claude/projects/-Users-jqq-PycharmProjects-llmeta/memory/MEMORY.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.claude/projects/-Users-jqq-PycharmProjects-llmeta/memory/feedback_use_uv.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.claude/skills/update-provider-model/testing.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.coveragerc +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.github/workflows/publish.yml +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.github/workflows/tests.yml +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.windsurf/workflows/addmodel.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.windsurf/workflows/arch.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/.windsurf/workflows/testllmeta.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/CHANGELOG.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/LICENSE +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/docs/add_new_model_family.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/docs/refactor_proposal.md +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/examples/advanced_usage.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/examples/basic_usage.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/mypy.ini +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/pytest.ini +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/ruff.toml +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/__init__.py +0 -0
- /whosellm-0.1.1a4/whosellm/py.typed → /whosellm-0.2.0/tests/e2e/__init__.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/__init__.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/__init__.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_deepseek.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_deepseek_tencent.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_glm46v.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_gpt4o.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_qwen.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_qwen3_vl_models.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/models/families/test_qwen_plus.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/test_provider.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/tests/test_specific_patterns.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/capabilities.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/model_version.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/__init__.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/dynamic_enum.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/__init__.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/deepseek/__init__.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/deepseek/deepseek_official.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/deepseek/tencent.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/others.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/families/vidu.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/models/patterns.py +0 -0
- {whosellm-0.1.1a4 → whosellm-0.2.0}/whosellm/provider.py +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Interview me about the plan
|
|
3
|
+
argument-hint: [plan]
|
|
4
|
+
model: opus
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Read this plan file $1 and interview me in detail using the AskUserQuestionTool about
|
|
8
|
+
literally anything: technical implementation, UI & UX, concerns, tradeoffs, etc.
|
|
9
|
+
but make sure the questions are not obvious.
|
|
10
|
+
|
|
11
|
+
Be very in-depth and continue interviewing me continually until it’s complete, then write the spec to the file.
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-review
|
|
3
|
+
description: 对代码变更进行全面 Review,覆盖设计规范、测试完备性、DRY 原则和封装合理性。当用户提交变更或请求代码审查时使用。
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: [file|branch|PR-url|--staged]
|
|
6
|
+
allowed-tools: Read, Grep, Glob, Bash, Agent
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Code Review — 全面代码审查
|
|
10
|
+
|
|
11
|
+
对代码变更进行系统性审查,输出结构化的审查报告。
|
|
12
|
+
|
|
13
|
+
输入:$ARGUMENTS
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 核心原则
|
|
18
|
+
|
|
19
|
+
1. **以项目规范为准绳** — 审查标准来自 [CLAUDE.md](../../../CLAUDE.md) 和项目现有代码模式,不套用外部通用规范
|
|
20
|
+
2. **指出问题而非重写** — 报告中说明"什么有问题、为什么、建议如何改",不直接输出大段替换代码
|
|
21
|
+
3. **区分严重等级** — 阻塞发布的问题 vs 建议改进,不混为一谈
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 第一步:确定审查范围
|
|
26
|
+
|
|
27
|
+
### 1.1 解析输入
|
|
28
|
+
|
|
29
|
+
根据输入类型获取变更内容:
|
|
30
|
+
|
|
31
|
+
| 输入类型 | 操作 |
|
|
32
|
+
|---------|------|
|
|
33
|
+
| `--staged` 或无参数 | `git diff --cached` 获取暂存区变更;若为空则 `git diff` 获取工作区变更 |
|
|
34
|
+
| 文件路径 | 直接读取指定文件,结合 `git diff` 查看该文件的变更 |
|
|
35
|
+
| 分支名 | `git diff main...{branch}` 获取分支全部变更 |
|
|
36
|
+
| PR URL | `gh pr diff {number}` 获取 PR 完整变更 |
|
|
37
|
+
|
|
38
|
+
### 1.2 生成变更清单
|
|
39
|
+
|
|
40
|
+
列出所有变更文件,标注变更类型:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
| 文件 | 变更类型 | 影响范围 |
|
|
44
|
+
|------|---------|---------|
|
|
45
|
+
| whosellm/models/families/xxx.py | 新增 | 模型配置 |
|
|
46
|
+
| tests/models/families/test_xxx.py | 新增 | 测试 |
|
|
47
|
+
| whosellm/models/registry.py | 修改 | 核心逻辑 |
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 第二步:设计规范审查
|
|
53
|
+
|
|
54
|
+
逐项检查变更是否符合项目设计规范。
|
|
55
|
+
|
|
56
|
+
### 2.1 核心概念一致性
|
|
57
|
+
|
|
58
|
+
对照 [CLAUDE.md](../../../CLAUDE.md) 中定义的 Family / Provider / Version / Variant 四个核心概念:
|
|
59
|
+
|
|
60
|
+
- **Family 划分**:新模型的 Family 归属是否正确?判断依据是命名模式,不是供应商营销定位
|
|
61
|
+
- **版本解析**:version 是否正确解析为 `(major, minor)` 元组?
|
|
62
|
+
- **变体分类**:variant 属于尺寸等级还是功能特化?`variant_priority` 是否合理?
|
|
63
|
+
- **比较边界**:同 Family 内可比较,跨 Family 应抛出 `ValueError`
|
|
64
|
+
|
|
65
|
+
### 2.2 配置驱动模式
|
|
66
|
+
|
|
67
|
+
检查变更是否遵循配置驱动的设计模式:
|
|
68
|
+
|
|
69
|
+
- 新模型是否通过 `ModelFamilyConfig` / `SpecificModelConfig` 定义,而非在代码中添加 if-else 分支?
|
|
70
|
+
- `patterns` 列表是否按优先级排序(更具体的在前)?
|
|
71
|
+
- `specific_models` 的键是否为小写模型名?
|
|
72
|
+
- 子 `patterns` 是否为父 `patterns` 的子集?
|
|
73
|
+
|
|
74
|
+
### 2.3 注册表模式
|
|
75
|
+
|
|
76
|
+
- 新增配置是否通过 `ModelFamilyConfig.__post_init__` 自动注册?
|
|
77
|
+
- 是否需要利用 Registry Merge 机制(同一 `(family, provider)` 的多个配置自动合并)?
|
|
78
|
+
- 如果新增了 `ModelFamily` 或 `Provider` 枚举值,是否通过 `add_member()` 扩展?
|
|
79
|
+
|
|
80
|
+
### 2.4 宽容设计
|
|
81
|
+
|
|
82
|
+
- 对未知输入是否返回 `UNKNOWN` 而非抛出异常?
|
|
83
|
+
- 新功能是否向后兼容,不破坏已有的公共 API?
|
|
84
|
+
|
|
85
|
+
### 2.5 代码风格
|
|
86
|
+
|
|
87
|
+
- Ruff 规则:行长 120、双引号、Python 3.11 目标
|
|
88
|
+
- MyPy 严格模式:类型注解完备、无隐式 Optional
|
|
89
|
+
- 运行 `uv run poe check` 和 `uv run poe typecheck` 验证
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 第三步:测试覆盖审查
|
|
94
|
+
|
|
95
|
+
### 3.1 功能性测试
|
|
96
|
+
|
|
97
|
+
对照 `tests/` 目录中已有模式,检查新增代码是否有对应测试:
|
|
98
|
+
|
|
99
|
+
**模型配置变更**必须覆盖:
|
|
100
|
+
- 模式匹配测试 — `match_model_pattern("model-name")` 返回正确的 family / version / variant
|
|
101
|
+
- `LLMeta` 端到端测试 — `LLMeta("model-name")` 的字段值正确
|
|
102
|
+
- 带日期后缀的模式匹配 — `model-name-YYYY-MM-DD` 格式正确解析
|
|
103
|
+
- 变体优先级排序 — 同版本不同变体间的比较关系正确
|
|
104
|
+
|
|
105
|
+
**能力字段变更**必须覆盖:
|
|
106
|
+
- 每个 `supports_*` 布尔字段的断言
|
|
107
|
+
- `max_tokens` 和 `context_window` 数值断言
|
|
108
|
+
- 特定模型覆盖父级默认值的场景
|
|
109
|
+
|
|
110
|
+
**核心逻辑变更**必须覆盖:
|
|
111
|
+
- 正向测试(正常输入 → 正确输出)
|
|
112
|
+
- 边界测试(空字符串、极长名称、特殊字符等)
|
|
113
|
+
- 异常测试(跨 Family 比较 → `ValueError`)
|
|
114
|
+
|
|
115
|
+
### 3.2 业务数据验证
|
|
116
|
+
|
|
117
|
+
检查测试中的断言值是否与配置一致:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# 好 — 测试值与配置中的实际值匹配
|
|
121
|
+
assert m.capabilities.context_window == 200000 # 与 anthropic.py 中的配置一致
|
|
122
|
+
|
|
123
|
+
# 坏 — 测试值与配置不符,测试通过只是因为使用了错误的值
|
|
124
|
+
assert m.capabilities.context_window == 128000 # 配置中实际是 200000
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 3.3 参数化测试
|
|
128
|
+
|
|
129
|
+
对于同一家族的多个模型/变体,检查是否使用了 `@pytest.mark.parametrize` 减少重复:
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
# 好 — 参数化覆盖多个模型
|
|
133
|
+
@pytest.mark.parametrize("model_name,expected_version,expected_variant", [...])
|
|
134
|
+
def test_family_version_variant(model_name, expected_version, expected_variant): ...
|
|
135
|
+
|
|
136
|
+
# 坏 — 每个模型一个独立函数,逻辑完全重复
|
|
137
|
+
def test_model_a_version(): ...
|
|
138
|
+
def test_model_b_version(): ...
|
|
139
|
+
def test_model_c_version(): ...
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 3.4 测试命名与标记
|
|
143
|
+
|
|
144
|
+
- 测试文件位于 `tests/models/families/test_{family}.py`
|
|
145
|
+
- 测试函数命名清晰描述测试意图
|
|
146
|
+
- 适当使用 `@pytest.mark.unit` / `@pytest.mark.integration` 标记
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 第四步:DRY 原则与封装合理性审查
|
|
151
|
+
|
|
152
|
+
### 4.1 重复代码检测
|
|
153
|
+
|
|
154
|
+
在变更文件和相关文件中查找以下模式:
|
|
155
|
+
|
|
156
|
+
- **同一能力配置重复声明** — 多个 `SpecificModelConfig` 定义了完全相同的 `ModelCapabilities`,应提取为共享变量或利用家族默认值
|
|
157
|
+
- **同一测试逻辑重复** — 多个测试函数的断言列表完全相同,应使用参数化测试或提取辅助函数
|
|
158
|
+
- **同一模式匹配逻辑重复** — 应复用 `parse_pattern` 而非自行实现匹配
|
|
159
|
+
|
|
160
|
+
### 4.2 未使用已有封装
|
|
161
|
+
|
|
162
|
+
检查变更是否绕过了项目已有的封装:
|
|
163
|
+
|
|
164
|
+
| 应该使用 | 而非 |
|
|
165
|
+
|---------|------|
|
|
166
|
+
| `ModelFamilyConfig` + `SpecificModelConfig` | 直接操作 `MODEL_REGISTRY` |
|
|
167
|
+
| `match_model_pattern()` | 自行编写正则匹配 |
|
|
168
|
+
| `infer_variant_priority()` | 手动硬编码优先级元组 |
|
|
169
|
+
| `parse_pattern()` | 直接调用 `parse.parse()` |
|
|
170
|
+
| `Provider.add_member()` / `ModelFamily.add_member()` | 修改枚举类定义 |
|
|
171
|
+
|
|
172
|
+
### 4.3 "半重复"封装
|
|
173
|
+
|
|
174
|
+
检查是否存在以下情况:
|
|
175
|
+
|
|
176
|
+
- **功能相似但接口不同的函数** — 例如两个函数都在做"从模型名解析版本"但实现路径不同
|
|
177
|
+
- **部分提取的抽象** — 例如提取了一个辅助函数但只用了一半参数,另一半仍在调用处硬编码
|
|
178
|
+
- **跨文件的逻辑耦合** — 例如两个文件各自维护一份相似的映射表
|
|
179
|
+
|
|
180
|
+
发现后建议:统一到一处实现,或说明为何需要两套。
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 第五步:输出审查报告
|
|
185
|
+
|
|
186
|
+
按以下格式输出结构化报告:
|
|
187
|
+
|
|
188
|
+
```markdown
|
|
189
|
+
## Code Review 报告
|
|
190
|
+
|
|
191
|
+
### 审查范围
|
|
192
|
+
{变更文件列表}
|
|
193
|
+
|
|
194
|
+
### 阻塞项(必须修复)
|
|
195
|
+
|
|
196
|
+
| # | 文件:行号 | 类别 | 问题描述 | 建议 |
|
|
197
|
+
|---|----------|------|---------|------|
|
|
198
|
+
| 1 | xxx.py:42 | 设计规范 | ... | ... |
|
|
199
|
+
|
|
200
|
+
### 建议项(推荐改进)
|
|
201
|
+
|
|
202
|
+
| # | 文件:行号 | 类别 | 问题描述 | 建议 |
|
|
203
|
+
|---|----------|------|---------|------|
|
|
204
|
+
| 1 | xxx.py:88 | DRY | ... | ... |
|
|
205
|
+
|
|
206
|
+
### 通过项
|
|
207
|
+
- 设计规范:{通过的检查项}
|
|
208
|
+
- 测试覆盖:{通过的检查项}
|
|
209
|
+
- DRY / 封装:{通过的检查项}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 类别标签
|
|
213
|
+
|
|
214
|
+
| 标签 | 含义 |
|
|
215
|
+
|------|------|
|
|
216
|
+
| 设计规范 | 不符合 CLAUDE.md 定义的核心概念或设计模式 |
|
|
217
|
+
| 测试缺失 | 缺少必要的测试用例 |
|
|
218
|
+
| 测试数据 | 测试断言值与配置不一致 |
|
|
219
|
+
| DRY | 存在可消除的重复 |
|
|
220
|
+
| 封装 | 未使用已有封装或存在半重复封装 |
|
|
221
|
+
| 风格 | 不符合 Ruff / MyPy 规则 |
|
|
222
|
+
| 兼容性 | 可能破坏现有 API 或行为 |
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 第六步:验证(可选)
|
|
227
|
+
|
|
228
|
+
如果审查发现了风格或类型问题,可运行自动化工具确认:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
uv run poe check # Ruff 检查
|
|
232
|
+
uv run poe typecheck # MyPy 类型检查
|
|
233
|
+
uv run poe test # 运行测试
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
如果变更涉及特定模型家族,运行针对性测试:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
uv run python -m pytest tests/models/families/test_{family}.py -v
|
|
240
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-skill
|
|
3
|
+
description: 创建符合项目规范的新 Claude Skill。当用户需要新增技能、为 Claude Code 添加自动化工作流时使用。
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: <skill-name> [description]
|
|
6
|
+
allowed-tools: Read, Write, Glob, Bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Create Skill — 创建新技能
|
|
10
|
+
|
|
11
|
+
根据用户描述创建符合本项目规范的 Claude Skill。
|
|
12
|
+
|
|
13
|
+
输入:$ARGUMENTS
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 核心原则
|
|
18
|
+
|
|
19
|
+
1. **代码胜于文档** — SKILL.md 中能引用现有文件的,直接用 Markdown 链接,不要摘录代码
|
|
20
|
+
2. **讲清为何,示例为何** — 先阐述模式与概念,再引用示例文件说明具体操作
|
|
21
|
+
3. **无实践不成技** — 如果项目中尚无该技能涉及的实际案例或代码,说明它未经验证,拒绝创建
|
|
22
|
+
4. **分步即模式** — SKILL 主体是分步执行流程,模式与最佳实践自然渗透在步骤中,而非堆砌独立章节
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 第一步:需求理解与可行性验证
|
|
27
|
+
|
|
28
|
+
### 1.1 解析用户意图
|
|
29
|
+
|
|
30
|
+
从 `$ARGUMENTS` 中提取:
|
|
31
|
+
- **技能名称**:小写字母 + 连字符(如 `update-provider-model`)
|
|
32
|
+
- **功能描述**:这个技能解决什么问题,什么场景触发
|
|
33
|
+
|
|
34
|
+
### 1.2 验证项目中有无实践基础
|
|
35
|
+
|
|
36
|
+
在项目中查找该技能涉及的实际文件、代码模式或已有工作流:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# 查找相关代码或文档
|
|
40
|
+
# 如果找不到任何相关实践,说明该技能尚未经项目验证
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**关键判断**:如果项目中没有该技能所需的代码示例或实际操作案例,则**拒绝创建**,并向用户说明原因——未经实践验证的技能只会产生空洞的文档。
|
|
44
|
+
|
|
45
|
+
### 1.3 检查是否与现有技能重叠
|
|
46
|
+
|
|
47
|
+
现有技能清单:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
ls .claude/skills/*/SKILL.md
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
如果新技能与已有技能功能重叠,建议扩展现有技能而非新建。
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 第二步:确定技能结构
|
|
58
|
+
|
|
59
|
+
### 2.1 选择参考模板
|
|
60
|
+
|
|
61
|
+
根据技能类型选择最接近的现有技能作为参考:
|
|
62
|
+
|
|
63
|
+
| 技能类型 | 参考 | 特点 |
|
|
64
|
+
|---------|------|------|
|
|
65
|
+
| 外部信息采集 + 代码变更 | [update-provider-model]({baseDir}/../update-provider-model/SKILL.md) | 多步骤、有子资源目录、委托 Agent |
|
|
66
|
+
| 配置校验 + 可选修复 | [review-provider-model]({baseDir}/../review-provider-model/SKILL.md) | 比对报告、分级处理 |
|
|
67
|
+
| 需求分析 + 方案评审 + 执行 | [evolve]({baseDir}/../evolve/SKILL.md) | 核心原则前置、必须用户确认 |
|
|
68
|
+
| CI/CD 操作流 | [release]({baseDir}/../release/SKILL.md) | 参数驱动、前置检查链、状态监控 |
|
|
69
|
+
|
|
70
|
+
### 2.2 确定目录布局
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
.claude/skills/{skill-name}/
|
|
74
|
+
├── SKILL.md # 必需:技能入口
|
|
75
|
+
├── {resource}.md # 可选:辅助资源(如 testing.md)
|
|
76
|
+
└── {subdir}/ # 可选:按类别组织的子资源(如 providers/)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
子资源仅在技能确实需要外部参考材料时创建,不要预设空目录。
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 第三步:编写 SKILL.md
|
|
84
|
+
|
|
85
|
+
### 3.1 Frontmatter
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
---
|
|
89
|
+
name: {skill-name} # 小写 + 连字符,不超过 64 字符
|
|
90
|
+
description: {中文描述,说明功能和触发场景} # 不超过 1024 字符
|
|
91
|
+
user-invocable: true
|
|
92
|
+
argument-hint: {参数格式提示}
|
|
93
|
+
allowed-tools: {技能需要的工具列表}
|
|
94
|
+
---
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**description 要点**:
|
|
98
|
+
- 使用中文(与本项目交互语言一致)
|
|
99
|
+
- 说清两件事:(1) 做什么 (2) 什么时候用
|
|
100
|
+
- 参考现有技能的 description 风格
|
|
101
|
+
|
|
102
|
+
### 3.2 正文结构
|
|
103
|
+
|
|
104
|
+
遵循本项目已有技能的统一风格——**分步编号工作流**:
|
|
105
|
+
|
|
106
|
+
```markdown
|
|
107
|
+
# 技能标题
|
|
108
|
+
|
|
109
|
+
一句话概括技能职责。
|
|
110
|
+
|
|
111
|
+
输入:$ARGUMENTS
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 核心原则(可选,仅当技能有重要的决策边界时)
|
|
116
|
+
|
|
117
|
+
## 第一步:{动作}
|
|
118
|
+
### 1.1 {子步骤}
|
|
119
|
+
### 1.2 {子步骤}
|
|
120
|
+
|
|
121
|
+
## 第二步:{动作}
|
|
122
|
+
...
|
|
123
|
+
|
|
124
|
+
## 快速参考(可选)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 3.3 编写要领
|
|
128
|
+
|
|
129
|
+
**每一步应包含**:
|
|
130
|
+
1. 这一步的目标(做什么、为什么)
|
|
131
|
+
2. 具体操作(引用项目文件,或给出命令模板)
|
|
132
|
+
3. 输出判断(成功 / 失败的标准,下一步的分支条件)
|
|
133
|
+
|
|
134
|
+
**引用而非摘录**:
|
|
135
|
+
|
|
136
|
+
```markdown
|
|
137
|
+
# 好 — 链接到实际文件
|
|
138
|
+
详细的测试指南见 [testing.md](testing.md)。
|
|
139
|
+
|
|
140
|
+
# 坏 — 在 SKILL 中复制代码
|
|
141
|
+
\```python
|
|
142
|
+
# 从 testing.md 复制的 50 行测试代码...
|
|
143
|
+
\```
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**在步骤中自然体现模式**:
|
|
147
|
+
|
|
148
|
+
```markdown
|
|
149
|
+
## 第四步:验证
|
|
150
|
+
|
|
151
|
+
运行全量 QA 确保无回归:
|
|
152
|
+
|
|
153
|
+
\```bash
|
|
154
|
+
uv run poe qa
|
|
155
|
+
\```
|
|
156
|
+
|
|
157
|
+
所有检查必须通过。如有失败,修复后重新运行。
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
而不是单独设置一个"最佳实践"章节罗列"应该跑 QA"。
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 第四步:创建文件
|
|
165
|
+
|
|
166
|
+
### 4.1 写入 SKILL.md
|
|
167
|
+
|
|
168
|
+
使用 Write 工具创建 `.claude/skills/{skill-name}/SKILL.md`。
|
|
169
|
+
|
|
170
|
+
### 4.2 创建子资源(如需要)
|
|
171
|
+
|
|
172
|
+
仅当技能确实需要辅助材料时才创建。
|
|
173
|
+
|
|
174
|
+
### 4.3 验证清单
|
|
175
|
+
|
|
176
|
+
创建完成后逐项检查:
|
|
177
|
+
|
|
178
|
+
- [ ] SKILL.md 位于 `.claude/skills/{skill-name}/` 目录
|
|
179
|
+
- [ ] Frontmatter 包含 name、description、user-invocable、argument-hint、allowed-tools
|
|
180
|
+
- [ ] name 使用小写字母和连字符
|
|
181
|
+
- [ ] description 使用中文,说清功能和触发场景
|
|
182
|
+
- [ ] 正文是分步编号工作流,与现有技能风格一致
|
|
183
|
+
- [ ] 引用了项目中实际存在的文件,而非摘录代码
|
|
184
|
+
- [ ] 没有空洞的"最佳实践"堆砌,模式融入步骤中
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 命名规范
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
update-provider-model # 动词-名词,清晰的功能描述
|
|
192
|
+
review-provider-model # 同上
|
|
193
|
+
create-skill # 同上
|
|
194
|
+
release # 单词足够清晰时可省略
|
|
195
|
+
|
|
196
|
+
# 避免
|
|
197
|
+
SkillCreator # 不要大写
|
|
198
|
+
skill_creator # 不要下划线
|
|
199
|
+
my-awesome-skill # 不要修饰词
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 常见错误
|
|
205
|
+
|
|
206
|
+
| 错误 | 原因 | 修正 |
|
|
207
|
+
|------|------|------|
|
|
208
|
+
| SKILL 内容空洞,全是抽象原则 | 没有结合项目实际操作 | 每一步引用具体文件和命令 |
|
|
209
|
+
| 大段代码摘录 | 复制了源文件内容 | 改为 Markdown 链接到源文件 |
|
|
210
|
+
| 与现有技能功能重叠 | 没有先检查已有技能 | 扩展现有技能,不要新建 |
|
|
211
|
+
| 创建了项目中无实践基础的技能 | 跳过了可行性验证 | 先有实践,再提炼技能 |
|