1. 从三件家务说起AtomGit 开源大赛里的 Python Skill 实战复盘先交代背景。AtomGit 和 OpenClaw 联合办的第一季开发大赛主题叫「破壳·进化」赛道分 Agent 提效专家、AI 创意生活、技能高手三个方向。我报的是技能高手赛道要求很朴素一个 Python 文件加一个 config 文件能跑通就能提交。当时报名 76 人一等奖 1 个、二等奖 2 个、三等奖 3 个一共 6 个奖位我最后拿了三等奖总分 8.2。我做的项目叫「三务管家 TriHub」把三件每天都要重复处理的「家务」塞进一个 AI Skill 里查快递、记账、家庭日程。这三件事单独看都不难难的是它们分散在三四个 App 里每天都要来回切。快递要在淘宝、京东、拼多多之间跳记账 App 下了好几个没一个坚持过两周老婆说「周六交电费」我转头就忘。它们的共同点是轻量、高频、事务性不需要重量级应用一个 Skill 就能兜住。这篇文章不是获奖感言是一份可以照着搭的复盘。我会把 Skill 的目录结构、config.json 配置片段、本地跑通命令、提交前的验证步骤都写清楚你照着做就能搭出一个同款参赛项目。适合谁看写过一点 Python、想参加 AtomGit 这类开源大赛、或者单纯想把日常重复事务交给 AI 的人。核心检索词就三个AtomGit 开源大赛、Python Skill SDK、OpenClaw Skill 开发。技术栈上没什么高深的。Skill SDK 负责把接口描述清楚模型负责理解用户那句模糊的自然语言业务逻辑我自己写。模型我用的是 MiMo-V2-Pro它在解析「SF123456 到哪了」这种输入时能准确识别出 track 意图并提取单号。下面按「问题场景 → 前置准备 → 可复制配置 → 验证请求 → 错排查 → 后续」的顺序展开每一步都有命令和结果说明。2. 前置准备OpenClaw 环境与 Skill SDK 接入配置动手之前先把环境理清楚。Skill 赛道对运行环境的要求不高Python 3.10 以上、能装依赖、有一个能调模型的入口就行。我本地是 macOSLinux 和 Windows 的 WSL 同样适用。整个项目最终只有三个文件skill_trihub.py、config.json、README.md核心代码 15KB 出头。第一步是确认 OpenClaw 已经跑起来。我之前为了做 Hermes 集成装过一次所以这次直接复用。如果你还没装按官方文档走一遍即可这里不展开安装细节重点讲 Skill SDK 的接入。Skill SDK 的设计比我想象的简单你绑好参数、写好接口描述模型自己会去理解用户意图并调度。开发者只需要关注业务逻辑本身。第二步是准备模型调用入口。Skill 要能解析自然语言就得有一个稳定的模型 API。我用的是 TaoToken 提供的接口它的好处是 Base URL、Key、Model ID 三件套清晰配置进 config.json 就能用不用改代码。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。第三步是建仓库。AtomGit 上新建一个公开仓库目录结构建议直接照抄我下面这份评委看 README 和目录的第一眼就决定了他会不会认真读你的代码skill_trihub/ ├── skill_trihub.py # 核心代码三个模块的入口都在这里 ├── config.json # 参数配置模型、API、预算阈值等 └── README.md # 说明书功能、用法、示例对话这里有个踩过的坑很多人把三个功能写成三个文件结果提交时不符合「1 个 Python 文件」的硬性要求。正确做法是在skill_trihub.py里用三个函数或三个类区分模块对外只暴露一个 Skill 入口。快递、财务、日程各自独立互不依赖这样任何一个模块出问题都不会拖垮整体。依赖方面只需要requests和python-dateutil前者调接口后者处理「周六前」这类模糊日期。装依赖pip install requests python-dateutil到这一步环境、模型入口、仓库骨架都齐了。接下来进入最关键的部分把 config.json 和 Skill 入口写对。3. 可复制配置config.json 与 Skill 入口片段这一节是全文最该抄的部分。先给 config.json 的完整片段路径就是仓库根目录下的config.json字段名和 Skill SDK 的约定保持一致你直接改 Key 和 Model ID 就能用{ skill_name: trihub, version: 1.0.0, model: { base_url: https://taotoken.net/api, api_key: sk-你的Key, model_id: MiMo-V2-Pro, timeout: 30 }, modules: { express: { enabled: true, carriers: [SF, ZTO, YTO, JD], abnormal_keywords: [滞留, 派送失败, 退回] }, finance: { enabled: true, budget_monthly: 5000, alert_ratio: 0.8, categories: [餐饮, 交通, 购物, 居家, 其他] }, schedule: { enabled: true, default_remind_hour: 9, birthday_repeat_yearly: true } } }三件套在这里体现得很清楚Base URL 是https://taotoken.net/apiKey 填你自己的Model ID 是MiMo-V2-Pro。这三个值缺一不可后面排障章节会专门讲它们各自报什么错。接着是 Skill 入口。skill_trihub.py的结构我拆成三层意图识别层、模块分发层、业务实现层。意图识别层把用户那句话交给模型让它返回一个结构化结果比如{intent: track, params: {no: SF123456}}。模块分发层根据 intent 路由到对应函数。业务实现层干实际的活。意图识别的核心片段长这样import json import requests def parse_intent(user_text, cfg): prompt ( 你是三务管家的意图解析器。把用户输入解析为 JSON intent 只能是 track / finance / schedule 之一。 track 提取单号 nofinance 提取金额 amount 和备注 note schedule 提取事项 title 和时间 time。只输出 JSON。 ) resp requests.post( f{cfg[model][base_url]}/v1/chat/completions, headers{Authorization: fBearer {cfg[model][api_key]}}, json{ model: cfg[model][model_id], messages: [ {role: system, content: prompt}, {role: user, content: user_text}, ], temperature: 0, }, timeoutcfg[model][timeout], ) content resp.json()[choices][0][message][content] return json.loads(content)这段代码有两个设计点值得说。一是temperature设为 0意图解析要的是稳定不是创意同样的输入必须给同样的结果。二是强制「只输出 JSON」这样json.loads不会因为模型多说了句「好的我来帮你解析」而崩掉。如果模型偶尔不听话可以在解析前做一次content.strip().strip().replace(json, ) 的清洗。财务模块的自动分类也依赖模型。用户写「星巴克」模型归到餐饮写「地铁」归到交通。分类结果写进本地 JSON 文件按月汇总时再让模型生成一段自然语言洞察比如「这个月外卖花了 1200比上月多了 30%主要原因是……」而不是甩一张干巴巴的表格。日程模块用dateutil处理「周六前」这类相对时间转成绝对日期后存下来每年生日用birthday_repeat_yearly标记循环提醒。配置写完先别急着提交本地跑一遍再说。4. 验证请求本地跑通与提交前自检命令配置写对不等于能跑通。我习惯先写一个最小验证脚本单独测模型调用确认三件套没问题再去测业务逻辑。这样出错时能快速定位是配置问题还是代码问题。最小验证脚本test_model.pyimport json import requests cfg json.load(open(config.json)) resp requests.post( f{cfg[model][base_url]}/v1/chat/completions, headers{Authorization: fBearer {cfg[model][api_key]}}, json{ model: cfg[model][model_id], messages: [{role: user, content: SF123456 到哪了}], }, timeout30, ) print(resp.status_code) print(resp.json()[choices][0][message][content])跑python test_model.py如果返回 200 并且 content 里能看出模型识别出了快递单号说明模型入口通了。这一步过了再跑完整的 Skillpython skill_trihub.py --input 帮我看看这个月花了多少钱 python skill_trihub.py --input 提醒我周六前交电费 python skill_trihub.py --input SF123456 到哪了三条命令分别对应财务、日程、快递三个模块。实测下来只要意图解析的 prompt 写清楚三条路径都能正常走通。快递模块还会额外做一次异常检测把轨迹里的「滞留」「派送失败」这些关键词交给模型判断命中就给出处理建议比如「联系派件员」或「申请理赔」。提交前我做了三件事建议你也照做。第一检查文件数量确认仓库里只有一个.py和一个config.json多一个都算违规。第二把config.json里的 Key 换成占位符别把真实 Key 提交上去评委不需要你的 Key 也能看代码。第三README 里写清楚三件事这个 Skill 解决什么问题、怎么装依赖、三条示例对话分别是什么。评委看 README 的时间可能比看代码还长。提交到 AtomGit 的命令git init git add skill_trihub.py config.json README.md git commit -m feat: TriHub 三务管家 skill git remote add origin 你的 AtomGit 仓库地址 git push -u origin main推送成功后去大赛页面确认作品已经出现在列表里。到这里一个能参赛的 Skill 就完成了。5. 常见错排查401、local proxy failed 与 reading choices这一节按真实报错来。我在开发和提交过程中踩过的坑基本都集中在这几类你遇到时可以直接对照。401 Unauthorized。最常见几乎都是 Key 的问题。要么 Key 填错要么 Key 前后带了空格要么把Bearer拼成了bearer。检查config.json里的api_key字段确认没有多余字符。还有一种情况是 Key 过期或额度用尽去控制台看一眼余额即可。控制台入口在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。local proxy failed。这个报错通常出现在请求根本没发出去的时候说明 Base URL 写错了或者网络层被拦了。先确认base_url是https://taotoken.net/api注意结尾不要多加/v1路径拼接在代码里做。如果确认地址没错还是报这个检查本地是否有环境变量HTTP_PROXY、HTTPS_PROXY指向了不可用的地址清掉再试。reading choices of undefined。这是 JS 风格的报错在 Python 里对应的是KeyError: choices或TypeError: NoneType object is not subscriptable。根因是resp.json()里没有choices字段说明返回的不是标准结构。打印完整的resp.text看看到底返回了什么通常是模型名写错、请求体格式不对或者触发了限流返回了错误信息。确认model_id和请求体里的model字段一致。OAuth 相关报错。如果你用的是需要 OAuth 的客户端比如某些 CLI 工具报错会提示 token 无效或回调失败。这类问题的排查思路是先确认 OAuth 流程是否走完再确认拿到的 token 有没有正确写进配置。如果你只是调 API不走 OAuth那这个报错一般不会出现。模型返回的不是 JSON。意图解析时json.loads崩了。原因是模型多说了话。解决办法是在 prompt 里强调「只输出 JSON不要任何解释」并在解析前做一次清洗。如果还是不稳定把temperature降到 0或者换一个更听话的模型。提交后作品不显示。检查仓库是不是公开的私有仓库评委看不到。再检查文件是不是推到了默认分支有些平台只读 main 分支。把这几类错排掉你的 Skill 基本就能稳定运行了。排障过程中如果需要查接口文档文档入口在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。6. 后续把 Skill 用起来比拿奖更重要比赛结果出来那天我其实没太关注在做别的事后来收到短信才知道获奖了。8.2 分三等奖华为充电宝一个。分数拆开看创新性 30%、完成度 30%、实用性 30%、社区投票 10%。我给自己实用性打高分因为这三个功能我到现在还在用不是做完就扔在那里吃灰的那种。社区投票那 10% 我拿得不多因为没去拉票下次再参赛会多花点精力在这块。比拿奖更有意思的是参赛本身。你的作品放在那里被评分、被人看这会逼你把 README 写清楚、把代码写规范、把功能跑通。以前总觉得比赛是学生的事工作了就没时间也没心思这次纯粹是看到「1 个 Python 文件」的门槛忍不住手痒。如果你也想搭一个同款我的建议是先跑通最小验证脚本再往里加模块别一上来就写三个功能。模型入口用 TaoToken 的三件套配好Base URL、Key、Model ID 对齐后面就只剩业务逻辑。想验证模型效果可以去模型对话页面直接试 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 如果你打算长期做编码类或 Agent 类项目Coding Plan 会更划算 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite Key 的申请和管理在 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。项目开源在 AtomGit欢迎 star、fork、提 PR。真要加功能的话「水电煤缴费」这类倒是挺实用。华为充电宝还在路上等到了我拍个开箱发评论里。