🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度
Hugging Face Trending 这几天被 Qwen3 Coder 占据了好几格。我通过 TaoToken 来跑这次 PyPI 包结构重构:先记录原始测试,再让模型生成新实现并复跑。实验对象是 python-slugify,很多博客标题转 slug 都用它;代码集中在一个 __init__.py 里,stopwords、Unicode 转换、正则替换全混在一起。选它的理由很具体:小到能在一个上下文里完整放下,又有明确的拆分边界。把原始测试跑绿,让模型动手,最后复跑同一组测试,这个闭环比只刷排行榜更能看出开源权重在真实依赖工程里的表现。接入层换来换去容易掩盖问题,所以我只保留一个 Key 和一个 Base URL,Claude Code 里切到 Qwen3 Coder 就完事。对这篇来说,TaoToken 只是 Key、Base URL 和复现基线,不是被评测对象;被评测的是“开源权重 + 本地 pytest + 依赖 diff”这条链路。本文不含任何排行榜分数,只记录一次本机运行。
1. 为什么选 python-slugify 当 Qwen3 Coder 的重构对象
python-slugify 在 PyPI 上存活了很久,它的接口很稳定:一个 slugify() 函数,接受文章标题,返回 URL 可用的 slug。它的实现却不像接口这么收敛。拿到源码后会发现,Unicode 预转换、停用词过滤、正则替换、截断逻辑全部堆在同一个模块里,一个函数从上到下要处理五六种边界条件。这种“接口稳定、内部拥挤”的包最适合做结构重构,因为它能明确判断重构有没有破坏行为:只要输入输出不变,测试就不该变。
用 Qwen3 Coder 来做这次重构,是因为 Hugging Face Trending 上它正热,而且它属于开源权重模型,可以通过兼容 API 接进现有工具链。我不需要把整个 IDE 换成某个专用 Agent,也不用为它单独装一套 Python SDK;Claude Code 的配置里换个 Base URL 和模型 ID,就能让对话直接读到项目文件。真正要动手改的代码不在线上,而在本地工作区,这让实验可以反复重来。把原始测试结果留下来,模型生成的 diff 落盘,再跑同一份测试做对照,整个流程不需要生产环境参与。
2. 原始基线:安装、三组用例与 pytest 复跑命令
先建一个干净目录,用虚拟环境隔离版本。我用的是 Python 3.11,在 macOS 上跑;Linux 也没区别。命令如下:
mkdir -p ~/slugify-tt && cd ~/slugify-tt
python3.11 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install python-slugify pytest
安装完成后确认模块来自 PyPI,而不是本地残留:
python -c "import slugify; print(slugify.__file__)"
只要打印出的路径在虚拟环境 site-packages 下,依赖就是干净的。接着写一组尽可能小但能覆盖主路径的测试。我没有用包自带的完整测试套件,而是自己固定了三组用例:普通标点、数字段落、长句。原因很简单:重构前后必须保证这几条公共行为不变。
# tests/test_slug.py
from slugify import slugify
def test_hello_world():
assert slugify("Hello, World!") == "hello-world"
def test_numbers():
assert slugify("Foo Bar 123") == "foo-bar-123"
def test_sentence():
assert slugify("The quick brown fox jumps over the lazy dog.") == "the-quick-brown-fox-jumps-over-the-lazy-dog"
跑原始测试:
python -m pytest tests/ -q
这版跑出来的结果是 3 passed。我只记录结果,不改动这个文件。为了让复现链更完整,把输出留一份快照:
python -m pytest tests/ -q > before.log
cat before.log
至此,重构前的“原始测试结果”已经固定。接下来要做的所有事情,都是为了让 after.log 和 before.log 一致。
3. 把默认供应商切到 TaoToken:Key、Base URL 与 Claude Code 配置
接入部分只做一件小事:把模型调用的默认供应商指到 TaoToken。先去 TaoToken 创建一个 API Key,然后记下两个信息:Base URL 是 https://taotoken.net/api,模型 ID 以模型广场展示为准。这里不要照抄网上的模型名,同一个模型在广场上的 ID 可能跟 Hugging Face 仓库名不完全一样;后面排障部分会专门说这个坑。
如果你在用 Claude Code,可以直接通过环境变量切过去:
export ANTHROPIC_BASE_URL=https://taotoken.net/api
export ANTHROPIC_AUTH_TOKEN=YOUR_API_KEY
export ANTHROPIC_MODEL=YOUR_MODEL_ID
也可以写进 ~/.claude/settings.json 的 env 块,效果一样:
{
"env": {
"ANTHROPIC_BASE_URL": "https://taotoken.net/api",
"ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY",
"ANTHROPIC_MODEL": "YOUR_MODEL_ID"
}
}
如果不想动编辑器配置,TaoToken 也提供 CLI,安装后可以直接发一条补全请求验证连通性:
npm install -g @taotoken/taotoken
taotoken cc -k YOUR_API_KEY -u https://taotoken.net/api -m YOUR_MODEL_ID
注意 Base URL 末尾不要拼 /v1。我一开始填了 https://taotoken.net/api/v1,请求路径直接变成 /api/v1/v1/messages,返回 404;去掉 /v1 就正常了。CLI、Claude Code 和 Base URL 共用同一个 Key,切模型时只需要改 YOUR_MODEL_ID。
4. Qwen3 Coder 生成重构实现:Prompt、diff 与依赖变更清单
重构开始时,我没有让模型直接访问磁盘,而是把源码和测试文件内容粘进对话。这样生成结果可以人工审一遍再落盘,不会让 AI 工具直接改动项目文件。拼接命令很简单:
cat slugify/__init__.py
cat tests/test_slug.py
下面是我实际发给 Qwen3 Coder 的 Prompt,未做修改:
请重构这个 python-slugify 包:
1. 保持 slugify() 的公共参数和返回语义不变;
2. 把 __init__.py 中的 Unicode 转换、停用词集合、正则规则分别移到 _unicode.py、_stopwords.py、_rules.py;
3. 保持现有运行依赖不变;
4. 给出完整 diff 和依赖变更清单。
模型返回了一版拆分后的实现。绝大部分 diff 是把原有函数体平移到新模块,而不是重写算法,这正是我预期中的“结构重构”。下面的 diff 是原始输出的骨架,完整版有两百多行:
diff --git a/slugify/__init__.py b/slugify/__init__.py
--- a/slugify/__init__.py
+++ b/slugify/__init__.py
@@ -1,3 +1,4 @@
+from ._unicode import unicode_lookup
+from ._stopwords import STOPWORD_SET
+from ._rules import PRE_REGEX
重构后的文件布局:
slugify/
├── __init__.py
├── _unicode.py
├── _stopwords.py
└── _rules.py
__init__.py 后续只保留 slugify() 主入口、参数解析和流程编排,Unicode 映射、停用词表、正则规则各自归位。这个拆分没有改变调用方,也没有动依赖。
依赖变更清单如下。这里“无变化”也是有效结果,因为任务目标是结构,不是换库;真正需要确认的是重构后 text-unidecode 仍然被正确引用。
| 依赖项 | 重构前 | 重构后 |
|---|---|---|
| text-unidecode | >=1.3,<2 | 不变 |
| unicodedata | 间接使用 | 间接使用 |
| pytest | dev 依赖 | dev 依赖 |
| 新增运行依赖 | - | 无 |
关于模型 ID,有一点必须说清楚:TaoToken 模型广场展示的 ID 才是 API 配置里该填的东西,Hugging Face 上的仓库名可以作为对照参考,但不能直接抄进 ANTHROPIC_MODEL。模型广场入口和 Key 管理在同一个页面,以 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 展示的为准。
5. 复跑 pytest:重构前后对照表
新文件落盘后,我没有马上相信“看起来能过”,而是直接重新跑同一份测试:
python -m pytest tests/ -q
输出仍然是 3 passed。再把三个原始输入单独手跑一遍,结果和重构前完全一致。也就是说,这次重构在行为层面没有引入可见变化,公共 API、默认参数、返回格式都保住了。
为了让自己不遗漏回归,把复跑输出也留一份:
python -m pytest tests/ -q > after.log
diff before.log after.log
diff 没有任何输出,说明两份日志逐行相同。这个操作比只看终端上的 3 passed 更稳,因为它是可留档的对照证据。
下面是这次本机运行的对照表。我刻意把它和公榜类结论分开:这不是模型能力排行榜,只是同一台机器、同一把 Key、同一 Prompt 下的一次实验记录,不代表任何 Benchmark 结论。
| 项目 | 重构前 | 重构后 |
|---|---|---|
| 主实现文件 | slugify/__init__.py | __init__.py + 3 个子模块 |
| 公共 API | slugify() | slugify() |
| pytest 结果 | 3 passed | 3 passed |
| 运行依赖 | text-unidecode | 不变 |
| before/after 日志 | - | diff 为空 |
如果你也想复现这张表,直接按第 3 节的配置切到 TaoToken,再用第 4 节的 Prompt 走一遍即可;不需要额外装 Agent 框架,也不用申请第二个 Key。
6. 排障:Base URL 末尾的 /v1 与模型 ID 来源
这次实测里我只踩到两个配置层面的坑,都跟模型本身无关。第一个是 Base URL 末尾多写 /v1。很多兼容接口的文档会把 /v1 写进地址,但 TaoToken 的 Base URL 就是 https://taotoken.net/api,末尾不带 /v1。加错之后,Claude Code 会把路径拼成 /api/v1/v1/messages,请求直接 404;改成不带 /v1 的地址后马上通过。
第二个坑是模型 ID 的来源。API 配置里的模型 ID 要以 TaoToken 模型广场展示为准,不能把 Hugging Face 仓库页上的名字原样拿过来。我一开始看到的是 HF 仓库名,填进去后请求返回模型不存在;去 TaoToken 控制台看了一圈才发现广场上直接展示了 API 用的模型 ID。这个 ID 在 Key 创建页和模型广场都能看到,照抄一次就能用。排障完成后,第 3 节的配置会变成一份可复现的模板,不再依赖运气。
7. 去控制台对一下账
这次调用消耗了多少 Token,记录在哪个模型 ID 下面,去 TaoToken 控制台看用量明细就行。建议你把上面的复现命令完整跑一遍,然后回到 Qwen3 Coder 的对话里,把 before.log 和 after.log 的 diff 输出贴回去,让它再确认一遍是否有遗漏的行为变化。创建 Key 的入口和模型广场在同一个页面,复现时不必再翻文档。
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度




被折叠的 条评论
为什么被折叠?



