<!-- title: 从零造重复代码检测Skill -->

# Claude Code Skills 开发实战：从零造一个重复代码检测 Skill

## 概述

本教程面向已经装好 Claude Code、能跑通基本对话与文件操作的读者，目标是用一个真实可运行的项目——**重复代码检测 Skill（duplicate-code-detector）**——带你完整走完自定义 Skill 的开发全流程。读完你将掌握：SKILL.md 的标准结构与 frontmatter 写法、渐进式披露（Progressive Disclosure）三层加载机制、`scripts/` + `references/` + `assets/` 三类捆绑资源的取舍、动态上下文注入（`!`command``）、用 skill-creator 做 eval 验证触发准确率，以及把 Skill 装到个人级 / 项目级 / 插件级三个位置的最佳实践。适用人群：想把自己的重复劳动沉淀成"可复用能力"的后端 / 前端 / 全栈工程师，以及希望给团队制定统一工程规范的 Tech Lead。

## 前置条件

- 已安装 Claude Code（`claude --version` 能输出版本号，建议 v2.1.145+，以使用 `/run`、`/verify` 等较新捆绑技能）
- Python 3.8+（本教程的扫描脚本用 Python 实现；若改用 Node/Go 亦可，思路一致）
- 一个待检测的真实代码仓库（任何语言都行，自带 `node_modules` 或 `vendor` 也无所谓，脚本会自动忽略）
- 了解 Markdown 与 YAML 基本语法

---

## 第 0 步：理解 Skill 到底是什么

Skill 的官方定义非常直白：**一个文件夹，里面放一份 `SKILL.md` 加可选的脚本与资源**。它和你在 `CLAUDE.md` 里写一大段"项目记忆"的区别在于——`CLAUDE.md` 每次会话都全量加载，而 Skill 的正文**只在被触发时才进入上下文**。

这一点是整个 Skill 体系的灵魂，官方给了它一个正式名字：**Progressive Disclosure（渐进式披露）**。它分三层：

| 层级 | 内容 | 何时进入上下文 | 典型体积 |
|------|------|----------------|----------|
| Tier 1 | `name` + `description` 元数据 | **始终在**（系统提示里） | ~100 词 / 个 |
| Tier 2 | `SKILL.md` 正文 | 命中触发时 | 目标 1500–2000 词 |
| Tier 3 | `scripts/` `references/` `assets/` | 执行中按需读取 | 无上限（脚本可不读入直接执行） |

也就是说，你装 50 个 Skill，常驻上下文成本只有"50 条 description"，几十 KB 而已。这正是 Skill 能让你"既拥有大量能力、又不撑爆上下文窗口"的根本原因。

判断"该不该做成 Skill"的一句话标准：**当你反复把同一段指令、检查清单、多步流程粘进对话，或者 `CLAUDE.md` 里某一节已经从"事实陈述"长成了"操作步骤"时**——它就该被抽成 Skill。检测重复代码这件事完美命中：每次重构前你都要跑扫描、读结果、生成报告、给重构建议，流程固定、可脚本化、适合"只在重构时加载"。

---

## 第 1 步：规划 Skill 的内容结构

官方的 skill-development 指南给出 6 步法，前两步是"用具体例子理解 Skill"和"规划可复用内容"。我们直接落地。

**1.1 列出触发场景（这些会写进 description）**

- 中文："检测重复代码""代码重复检测""找出抄来的代码""这段是不是抄过来的""重构前帮我查重复"
- 英文："find duplicate code""refactor duplication""dedupe code blocks""duplication audit"

**1.2 拆解可复用资源**

| 重复出现的动作 | 沉淀成什么 | 为什么 |
|----------------|-----------|--------|
| 扫描源码、归一化、哈希、聚类 | `scripts/find_duplicates.py` | 确定性强、每次都重写、可不读入直接执行（省 token） |
| 窗口大小、忽略目录、语言扩展等调参说明 | `references/heuristics.md` | 长、查阅型，不该污染 SKILL.md 正文 |
| 报告长什么样 | `examples/sample-report.md` | 给 Claude 一个输出格式锚点 |

**1.3 确定目录结构**

```
duplicate-code-detector/
├── SKILL.md                 # 入口（必需）
├── scripts/
│   └── find_duplicates.py   # 核心扫描脚本
├── references/
│   └── heuristics.md        # 调参/CI 集成说明
└── examples/
    └── sample-report.md     # 输出示例
```

注意：只建你真正需要的子目录。`assets/`（用于产出的模板、图片、字体）这次用不到，就不要建——官方明确强调"删除用不到的示例目录，只建实际需要的"。

---

## 第 2 步：先写脚本（确定性的东西交给代码，而不是模型）

Skill 设计有一条黄金法则：**能交给脚本的就别让模型即兴写**。脚本省 token、可复用、结果确定。我们先把这个 Skill 最重的部分——扫描脚本——写出来。

在 `duplicate-code-detector/scripts/find_duplicates.py` 写入：

```python
#!/usr/bin/env python3
"""按归一化哈希定位重复 / 近似重复的代码块。"""
import argparse, hashlib, os, re, json
from collections import defaultdict

DEFAULT_EXT = (".py", ".js", ".ts", ".tsx", ".jsx", ".go", ".java", ".c", ".h", ".cs", ".rb")

def normalize(lines):
    """把变量名/数字/字符串/注释抹平，让"换个名字的复制粘贴"也能命中。"""
    out = []
    strip_str = re.compile(r'"[^"]*"|\'[^\']*\'')
    strip_cmt = re.compile(r'#.*$|//.*$')
    for ln in lines:
        ln = strip_str.sub('"S"', ln)          # 字符串 -> S
        ln = strip_cmt.sub('', ln)             # 去注释
        ln = re.sub(r'\b\d+\b', 'N', ln)       # 数字 -> N
        ln = re.sub(r'\b[A-Za-z_]\w*\b', 'I', ln)  # 标识符 -> I
        ln = re.sub(r'\s+', '', ln)            # 去空白
        if ln:
            out.append(ln)
    return out

def iter_files(root, exts, ignore):
    for dp, dn, fn in os.walk(root):
        dn[:] = [d for d in dn if d not in ignore]
        for f in fn:
            if f.endswith(exts):
                yield os.path.join(dp, f)

def windows(norm, size):
    for i in range(len(norm) - size + 1):
        yield hashlib.md5("\n".join(norm[i:i+size]).encode()).hexdigest(), i + 1

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--root", default=".")
    ap.add_argument("--window", type=int, default=6, help="每个块多少行")
    ap.add_argument("--min-cluster", type=int, default=2, help="至少重复几处才报告")
    ap.add_argument("--ext", default=",".join(DEFAULT_EXT))
    ap.add_argument("--json", action="store_true")
    a = ap.parse_args()
    exts = tuple(a.ext.split(","))
    ignore = {"node_modules", ".git", "vendor", "dist", "build", ".venv"}
    clusters = defaultdict(list)
    for path in iter_files(a.root, exts, ignore):
        raw = open(path, encoding="utf-8", errors="ignore").read().splitlines()
        norm = normalize(raw)
        seen = set()
        for h, line in windows(norm, a.window):
            if h in seen:           # 同一文件内的滑动重叠只记一次
                continue
            seen.add(h)
            clusters[h].append((path, line))
    dups = {h: l for h, l in clusters.items() if len(l) >= a.min_cluster}
    if a.json:
        print(json.dumps(dups, indent=2)); return
    print(f"# 重复代码报告\n\n扫描目录: `{a.root}` | 窗口: {a.window} 行 | 命中聚类: {len(dups)}\n")
    for rank, (h, locs) in enumerate(sorted(dups.items(), key=lambda x: -len(x[1])), 1):
        print(f"## #{rank} 重复 {len(locs)} 处")
        for p, line in locs:
            print(f"- `{p}:{line}`")
        print()
    print(f"---\n共 {len(dups)} 个重复聚类，建议优先重构重复 ≥3 处的块。")

if __name__ == "__main__":
    main()
```

**操作说明**：给脚本可执行权限并自测。

```bash
chmod +x duplicate-code-detector/scripts/find_duplicates.py
python3 duplicate-code-detector/scripts/find_duplicates.py --root . --window 6
```

**预期结果**：

```
# 重复代码报告

扫描目录: `.` | 窗口: 6 行 | 命中聚类: 4

## #1 重复 5 处
- ./src/auth/login.py:42
- ./src/auth/signup.py:38
- ./src/api/user.py:120
...

---
共 4 个重复聚类，建议优先重构重复 ≥3 处的块。
```

**常见问题**：

- **误报太多**：把标识符抹平后，`for i in range(n):` 这类样板会被全员命中。解法是调大 `--window`（如 8–10），或对热点目录单独跑。
- **该报的没报**：变量改名后的复制粘贴靠"归一化"已经能抓；若是"换函数顺序"的结构性克隆，需要把窗口再加大或改用 AST 比对——这种进阶策略放进 `references/heuristics.md`，不塞进 SKILL.md。

---

## 第 3 步：写 SKILL.md（最容易踩坑的一步）

SKILL.md 决定 Skill **会不会被触发**以及**触发后怎么执行**。它有两部分：YAML frontmatter（决定触发）+ Markdown 正文（决定执行）。先看完整文件，再逐段拆解。

在 `duplicate-code-detector/SKILL.md` 写入：

```markdown
---
name: duplicate-code-detector
description: Detects duplicated and near-duplicated code blocks across a codebase and produces a refactor report. This skill should be used when the user asks to "find duplicate code", "检测重复代码", "代码重复检测", "找出抄来的代码", "refactor duplication", or wants a duplication audit before refactoring.
allowed-tools: Bash, Read, Glob, Grep
---

# 重复代码检测

## 用途
扫描指定目录，按归一化哈希定位"几乎相同"的代码块，输出按重复次数排序的报告，用于重构前锁定最值得抽取公共方法的高频重复。

## 何时使用
- 用户问"哪些代码重复了 / 能不能抽公共方法 / 这段是不是抄过来的"
- 重构、合并、技术债清理前需要一份重复清单

## 执行步骤
1. 运行内置扫描脚本（默认 6 行窗口、跨文件去重）：
   ```bash
   python3 scripts/find_duplicates.py --root . --window 6 --min-cluster 2
   ```
2. 对重复 ≥3 处的聚类，优先建议抽取为公共函数 / 组件 / Hook。
3. 调参与多语言支持见 `references/heuristics.md`：缩小窗口抓短片段、放大窗口只留长克隆；`--ext` 限定语言；`--json` 便于接入 CI。

## 报告规范
- 先给总数与最严重的 3 个聚类
- 每个聚类列出 `文件:行号`
- 末尾给一句重构建议；不要直接改代码，除非用户明确要求

## 当前仓库规模
!`find . -type f \( -name '*.py' -o -name '*.js' -o -name '*.ts' \) -not -path '*/node_modules/*' | wc -l`
```

### 3.1 frontmatter 四个关键字段

- **`name`**：必填，必须与目录名一致，也是 `/duplicate-code-detector` 这个斜杠命令的名字。
- **`description`**：必填，**这是触发准确率的命脉**。官方建议三条规则——① 用第三人称（"This skill should be used when…"）；② 塞入用户真实会说的触发短语（中英文都给）；③ 控制在 100 词以内。**坏例子** vs **好例子**：

  ```yaml
  # ❌ 坏：人称错、没触发词、太泛
  description: Use this skill when working with code duplication.
  # ✅ 好：第三人称 + 具体触发短语
  description: This skill should be used when the user asks to "find duplicate code", "检测重复代码", ...
  ```

- **`allowed-tools`**：可选，预先批准这个 Skill 能用的工具，免去每次执行都要你按 `y` 放行。这里给 `Bash, Read, Glob, Grep` 已经够用。

- **`disable-model-invocation`**：可选，设为 `true` 时模型**不能自动触发**，只能你手敲 `/duplicate-code-detector`。本例不需要，但做"危险操作"类 Skill 时强烈建议开启。

### 3.2 动态上下文注入（一行魔法）

正文最后一行 `` !`find ... | wc -l` `` 是 Skill 的杀手锏：**Claude Code 在把正文交给模型之前，会先执行反引号里的命令，把输出原位替换进去**。于是模型每次看到 SKILL.md 时，里面已经是"当前仓库有 1342 个源文件"这样的实时数字，而不是一句干巴巴的指令。这和官方第一个示例 Skill 用 `` !`git diff HEAD` `` 把实时 diff 注入是同一个机制。

### 3.3 写作风格的硬性要求

官方对正文风格的措辞非常明确：**全程用祈使句/动词原形开头，不要用第二人称"你应该"**。

```markdown
# ✅ 推荐
运行扫描脚本，得到聚类结果。
对重复 ≥3 处的聚类，优先抽取为公共函数。

# ❌ 避免
你应该运行扫描脚本。
如果你需要调参，可以看 heuristics.md。
```

### 3.4 保持 SKILL.md 苗条

正文目标 **1500–2000 词**。任何超过这个量的内容（详细调参、CI 集成、多语言 AST 策略）一律下沉到 `references/`。原则是：**信息要么在 SKILL.md，要么在 references，绝不在两边各放一份**。

---

## 第 4 步：补齐 references 与 examples

在 `references/heuristics.md` 写调参与集成说明（节选）：

```markdown
# 调参与进阶

## 窗口大小（--window）
- 4–6 行：抓短克隆（重复的工具函数、相似的校验逻辑），噪声偏高
- 8–12 行：只留结构完整的克隆块，适合做"抽取公共方法"的决策
- >12 行：仅命中大段复制粘贴，几乎无误报

## 多语言
默认覆盖 .py/.js/.ts/.go/.java 等。仅扫描 Go：--ext .go
新增语言只需把扩展名加进 --ext，归一化是语言无关的。

## CI 集成
--json 输出机器可读结果，在 CI 里判定：
dups=$(python3 scripts/find_duplicates.py --json --min-cluster 3)
test "$(echo "$dups" | jq 'length')" -lt 5 || exit 1   # 重复块超过 5 个则失败
```

在 `examples/sample-report.md` 放一份理想输出，给模型一个格式锚点（内容即第 2 步的"预期结果"）。这两类文件**默认不进上下文**——只有当 SKILL.md 正文里指向它们、且模型判断当前需要时，才会被读入。这就是 Tier 3 的价值。

---

## 第 5 步：装到合适的位置

Skill 的存放位置决定"谁能用"。官方定义了四个层级，优先级从高到低：

| 层级 | 路径 | 作用范围 |
|------|------|----------|
| Enterprise | 受管设置 | 全组织所有人 |
| **Personal** | `~/.claude/skills/duplicate-code-detector/SKILL.md` | **你的所有项目** |
| **Project** | `<repo>/.claude/skills/duplicate-code-detector/SKILL.md` | **仅本项目（可随 git 分享给团队）** |
| Plugin | `<plugin>/skills/duplicate-code-detector/SKILL.md` | 启用该插件处 |

把整个 `duplicate-code-detector/` 目录拷到目标位置即可：

```bash
# 装成个人级：所有项目可用
cp -r duplicate-code-detector ~/.claude/skills/

# 装成项目级：随仓库分享给同事
cp -r duplicate-code-detector your-repo/.claude/skills/
```

**关键特性：实时变更检测**。你修改 `~/.claude/skills/` 或项目 `.claude/skills/` 下的 `SKILL.md` 后，**无需重启 Claude Code**，当前会话立刻生效——非常适合边改边测。

---

## 第 6 步：测试与 eval（用 skill-creator 打磨触发准确率）

### 6.1 手工两路验证

进入任意仓库，启动 `claude`，分别用两种方式触发：

```text
# 方式 A：让模型自动触发
> 重构前帮我查一下哪些代码重复了，给个清单

# 方式 B：直接喊命令
> /duplicate-code-detector
```

两者都应输出一份带文件:行号的报告。若方式 A 没触发——大概率是 `description` 触发词不够，回第 3 步加短语。

### 6.2 用 skill-creator 跑 eval（批量验证触发率）

手工测一两条不够，真正可靠的做法是用捆绑的 `/skill-creator` 跑 eval 基准。流程：

1. 准备一份测试用例文件，每条包含"用户输入"和"期望是否触发本 Skill"：
   ```yaml
   # eval_cases.yaml
   - input: "帮我把这几段相似的校验逻辑抽成一个函数"
     expect_trigger: true
   - input: "解释一下 Python 的 GIL 是什么"
     expect_trigger: false
   - input: "find duplicate code in src/"
     expect_trigger: true
   - input: "把这个函数改名叫 validateEmail"
     expect_trigger: false
   ```
2. 在 Claude Code 里运行 `/skill-creator`，选择"评估现有 Skill" → 指向 `duplicate-code-detector` 与用例文件。
3. skill-creator 会逐条模拟触发，输出命中率与误报/漏报清单。
4. 反复把漏报的真实说法补进 `description`，把误报场景用更精确的措辞排除——直到命中率稳定在 90% 以上。

**常见问题**：

- **触发太频繁（误报）**：`description` 太宽（如"代码分析"）。改成更窄的动词与名词组合。
- **从不触发（漏报）**：检查是否放错了目录（`skills` 拼成 `skill`）、`name` 与目录名是否一致、description 是否被截断（超长会被截）。
- **脚本找不到**：SKILL.md 里用了绝对路径或 `~/`，应改为相对 Skill 目录的相对路径 `scripts/find_duplicates.py`。

---

## 实战案例：一次真实的重构前审计

假设你的团队有个 Python + TypeScript 混合仓库 `monorepo/`，后端 3 个微服务都在各自复制了一套"参数校验 + 错误码返回"的逻辑。目标：重构前生成一份优先级清单。

**操作**：

```bash
cd monorepo
claude
# 在交互里输入：
> /duplicate-code-detector
```

模型会执行 SKILL.md 的步骤：调用 `scripts/find_duplicates.py --root . --window 8 --min-cluster 2`（窗口放大到 8，避免短样板噪声），读取 `references/heuristics.md` 确认参数合理，最后按"报告规范"输出：

```text
## 概览
扫描 1247 个源文件，命中 7 个重复聚类，其中 3 个重复 ≥4 处。

## 优先级 1（重复 6 处，跨 services/auth、services/order、services/pay）
- services/auth/handlers.py:88
- services/order/handlers.py:51
- services/pay/handlers.py:73
- ...
建议：抽取 validate_and_respond(payload, schema) 到 common/http.py，6 处统一替换。

## 优先级 2（重复 4 处，TS 侧用户校验）
- ...

---
建议本周先处理优先级 1，预计减少 ~180 行重复代码。需要我直接动手重构吗？
```

整个过程从"打开仓库"到"拿到可执行的重构清单"不到 1 分钟，且报告基于脚本的真实扫描结果，而非模型的猜测。把 SKILL.md 放进项目 `.claude/skills/` 并提交到 git，全团队任何人 `claude` 一开就能复用同一套审计标准——这就是 Skill 把"个人经验"变成"团队标准库"的方式。

---

## 整体工作流图

```mermaid
flowchart TD
    U([用户提问: 哪些代码重复了?]) --> T1{"Tier 1 元数据\n始终在上下文"}
    T1 --> DEC{description 命中?}
    DEC -- 否 --> N[正常对话回复]
    DEC -- 是 --> T2["Tier 2\n加载 SKILL.md 正文"]
    T2 --> INJ["动态注入\n!find...wc -l\n实时文件数"]
    INJ --> RUN["执行脚本\nscripts/find_duplicates.py"]
    RUN --> NEED{需要调参说明?}
    NEED -- 是 --> T3["Tier 3\n按需读 references/heuristics.md"]
    NEED -- 否 --> RPT[按规范生成报告]
    T3 --> RPT
    RPT --> OUT([输出 文件:行号 + 重构建议])
```

```mermaid
flowchart LR
    subgraph 开发循环
      A[1 列触发场景] --> B[2 写脚本 find_duplicates.py]
      B --> C[3 写 SKILL.md frontmatter+正文+动态注入]
      C --> D[4 补 references/examples]
      D --> E[5 装到 personal/project 位置]
      E --> F[6 skill-creator 跑 eval]
      F -->|命中率不足| C
      F -->|达标| G([发布])
    end
```

---

## 进阶：从 Skill 升级成 Plugin

当你的重复检测 Skill 长出更多配套能力（比如一个 PreToolUse hook 在每次提交前自动跑检测、一个子代理做深度 AST 克隆分析），就可以把它打包成 **Plugin**。官方机制：在 Skill 文件夹里加一个 `.claude-plugin/plugin.json`，它就以 `<name>@skills-dir` 的形式作为插件加载，可以同时捆绑 hooks、agents、MCP 服务器。Plugin 还支持 `plugin-name:skill-name` 的命名空间，不会和其他层级的同名 Skill 冲突，适合在组织内分发。

另一个值得记住的能力是 **把 Skill 放进子代理执行**：对于大型仓库的全面扫描，可以在 SKILL.md 里指示用 Explore 子代理并行收集文件清单，主代理只负责汇总——这是控制上下文膨胀的常用招数。

---

## 延伸阅读

- **Claude Code 官方 Skills 文档**：`code.claude.com/docs/en/skills` ——frontmatter 字段、动态注入、子代理执行、skill-creator eval 的权威来源
- **anthropics/claude-code 仓库的 skill-development SKILL.md**：官方"如何写 Skill"的元指南，6 步法的出处
- **anthropics/skills**：Anthropic 官方第一方 Skill 源码（pptx、docx、pdf、xlsx、skill-creator），最好的学习样本
- **Agent Skills 开放标准**（`platform.claude.com/docs/en/agents-and-tools/agent-skills/overview`）：Skill 是跨工具的开放标准，理解它有助于把同一份 Skill 复用到 Claude Desktop、Agent SDK
- **Progressive Disclosure 工程实践**：社区博客对三层加载机制、`CLAUDE.md / Sub-Agents / Hooks / Skills` 四件套何时取用的对比

## 训练营适用性评估

- **AI 工程实战营（中高级）**：高度契合，建议作为"能力沉淀"模块的标杆实验，教学时长 **90–120 分钟**（含现场写脚本 + 跑 eval）。学员产出：一个可提交到自己 `~/.claude/skills/` 的真实 Skill。
- **企业内训 / Tech Lead 工作坊**：契合度高，重点放在"项目级 Skill 随 git 分发""用 eval 守住团队触发标准"两节，教学时长 **60 分钟**，可要求学员把团队现有的一页编码规范改写成 Skill。
- **零基础入门营**：契合度中等，本教程假设读者已会基本文件操作与 Python；建议放在课程第 2 天，作为"安装与认证"之后的第一个动手实验，教学时长 **150 分钟**（需补讲 YAML、argparse、正则归一化）。
- **不适合**：纯前端无后端背景且不愿接触命令行的学员——可改用 Node 版脚本平替，思路完全一致。

## 参考来源

1. [Extend Claude with skills — Claude Code Docs](https://code.claude.com/docs/en/skills) — 官方权威：Skill 结构、frontmatter、动态上下文注入、存放位置、skill-creator eval
2. [anthropics/claude-code · skill-development/SKILL.md](https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/skill-development/SKILL.md) — 官方"如何开发 Skill"元指南，含 6 步法、三类捆绑资源、写作风格规范
3. [anthropics/skills (GitHub)](https://github.com/anthropics/skills) — Anthropic 第一方 Skill 仓库（pptx/docx/pdf/xlsx/skill-creator），最佳学习样本
4. [Agent Skills Overview — Claude Platform Docs](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) — Skill 作为跨工具开放标准的定义与机制说明
5. [Claude Code Skills 2026 — Progressive Disclosure (AnhTu.dev)](https://anhtu.dev/claude-code-skills-2026-progressive-disclosure-and-how-to-standardise-workflow-for-engineering-teams-1062) — 三层加载机制深度解读与 CLAUDE.md/Sub-Agents/Hooks/Skills 四件套取舍对比

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
