Codex 实战 Skills:把 1000 个推广链接批量转成内嵌 Logo 且美化配色的二维码技能

发布时间:2026/10/12 22:09:29

Codex 实战 Skills:把 1000 个推广链接批量转成内嵌 Logo 且美化配色的二维码技能 1. 运营人批量做码的真实困境1000 条推广链接怎么扛做增长的朋友大概率都遇到过这种场面一场渠道投放下来后台导出 1000 条带 UTM 参数的推广链接每条对应一个渠道、一个落地页、一个追踪 ID。运营的要求很朴素——给每条链接配一张二维码中心放公司 Logo配色跟品牌主视觉一致扫码能跳转最好今天下班前交付。听起来不难真动手就知道坑在哪。在线二维码生成器一次只能贴一条链接1000 条意味着 1000 次复制粘贴中途手滑贴错一条追踪数据就废了。更麻烦的是样式默认黑白方块放在海报上像贴了张补丁中心想加 Logo 又怕遮住定位点导致扫不出来。有些工具支持 Logo但批量能力要开会员链接还得先上传到对方服务器推广链接里带着渠道 ID 和预算参数谁愿意把这种东西交给第三方。我试过用最笨的办法——写个循环调 qrcode 库结果生成出来全是黑白码Logo 得自己用 PS 一张张叠1000 张叠到怀疑人生。后来才想明白这事本质是个「批量图像处理 视觉调优」的工程问题应该交给能跑代码、能读文件、能并发执行的 Agent 来做。Codex 的 Skills 机制正好适合这种场景把生成逻辑封装成一个可复用的技能输入一个 CSV输出一整个文件夹的成品二维码中间还能统一控制 Logo 尺寸、纠错等级和配色。这篇就按这个思路走。我会先讲清楚 Codex Skills 是什么、为什么适合批量二维码这种任务然后给出可直接复制的技能配置和 Python 实现接着演示 1000 条链接从 CSV 到成品的完整流程最后把模型调用 endpoint 统一改到 TaoToken方便你在一个地方管理所有 AI 请求。全程小白可跟做代码复制就能跑。2. Codex Skills 与 TaoToken 前置准备把批量二维码做成可复用技能先说清楚 Codex Skills 的定位。你可以把它理解成给 Codex Agent 装的一个「插件」——用一份配置文件声明这个技能叫什么、接收什么参数、执行什么命令Agent 在对话里就能直接调用。对于二维码批量生成这种「输入固定、逻辑固定、只是数据在变」的任务封装成 Skill 比每次现写脚本高效得多。下次再来 2000 条链接改一下输入文件路径就行不用重新调代码。技能的核心是一份skill.toml或 JSON配置加上一个 Python 入口脚本。配置里声明技能名、描述、参数 schema入口脚本负责实际生成。Codex 读取配置后会把用户的自然语言请求映射成参数再调用脚本执行。整个过程你只需要在对话里说「用 qr-batch 技能处理 promotions.csvLogo 用 assets/logo.png」剩下的交给 Agent。为什么要把 endpoint 改到 TaoToken因为二维码生成过程中如果你想让 Agent 顺带做点「智能」的事——比如根据渠道名自动生成配色方案、检查生成的二维码是否可扫、给每个渠道写一句推广文案——这些都需要调用大模型。把模型请求统一走 TaoToken 的 API好处是 key 和 base_url 集中管理不用在多个平台之间来回切换计费和用量也清晰。TaoToken 提供兼容 OpenAI 格式的接口改一行 base_url 就能接上。前置准备分三步。第一步拿到 TaoToken 的 API Key在控制台的 API Keys 页面创建复制保存好后面配置里要用。第二步确认本地 Python 环境是 3.9 以上装好依赖库。第三步准备好你的推广链接 CSV 和 Logo 图片。Logo 建议用 PNG 透明底正方形尺寸 200×200 以上这样缩放后边缘干净。依赖安装命令如下qrcode 负责标准码生成MyQR 负责艺术码背景融合Pillow 负责 Logo 合成和图像处理pip install qrcode[pil] MyQR Pillow requests装完后可以跑一句python -c import qrcode, MyQR, PIL; print(ok)验证输出 ok 就说明环境没问题。这一步别跳过我见过不少人卡在 MyQR 装不上多半是 Pillow 版本冲突先升级 pip 再装基本能解决。关于 TaoToken 的接入信息官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基础地址是 https://taotoken.net/api 模型对话入口在 https://taotoken.net/api/chat/completions 。如果你后面要做长期编码或 Agent 任务可以了解下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。这些地址先记着第三节配置里会用到。3. 可复制配置skill.toml 与二维码生成脚本完整落地这一节是全文的技术核心给出两份可直接复制的文件一份 Codex Skill 配置一份 Python 生成脚本。配置声明技能接口脚本实现批量逻辑。你只需要改路径和参数就能跑起来。先看skill.toml。这份配置告诉 Codex 这个技能叫什么、接收哪些参数、怎么调用入口脚本。参数设计上input_csv是必填的链接清单logo_path和background_path可选output_dir指定输出目录qr_size和logo_ratio控制尺寸和 Logo 占比。name qr-batch description 批量将推广链接转换为内嵌 Logo、配色调优的二维码 version 1.0.0 entry qr_skill.py [parameters] input_csv { type string, required true, description 推广链接 CSV 路径需包含 url 列 } logo_path { type string, required false, description 中心 Logo 图片路径PNG 透明底最佳 } background_path { type string, required false, description 背景图路径提供则生成艺术二维码 } output_dir { type string, required false, default ./qr_output, description 输出目录 } qr_size { type integer, required false, default 400, description 二维码边长像素 } logo_ratio { type float, required false, default 0.2, description Logo 占二维码边长比例建议 0.15-0.25 } max_workers { type integer, required false, default 8, description 并发线程数 } [env] TAOTOKEN_BASE_URL https://taotoken.net/api TAOTOKEN_API_KEY ${TAOTOKEN_API_KEY}注意[env]段里的TAOTOKEN_BASE_URL固定为https://taotoken.net/apiTAOTOKEN_API_KEY用环境变量注入不要把 key 硬编码进配置文件。这样配置和密钥分离文件可以进版本库key 留在本地环境变量里。接下来是入口脚本qr_skill.py。它读取 CSV、并发生成二维码、嵌入 Logo、输出结果统计。关键决策我写在注释里纠错等级强制用 H30% 容错因为中心嵌 Logo 会遮挡数据区文件名用 URL 的 MD5 前 8 位加序号避免特殊字符导致保存失败并发用 ThreadPoolExecutor图像库底层释放 GIL多线程能拿到接近并行的加速。import os import csv import hashlib import logging from pathlib import Path from concurrent.futures import ThreadPoolExecutor, as_completed import qrcode from qrcode.constants import ERROR_CORRECT_H from PIL import Image logging.basicConfig(levellogging.INFO, format%(asctime)s %(levelname)s %(message)s) logger logging.getLogger(qr_skill) class QRBatchSkill: def __init__(self, output_dir./qr_output, qr_size400, logo_ratio0.2, max_workers8): self.output_dir Path(output_dir) self.qr_size qr_size self.logo_ratio logo_ratio self.max_workers max_workers self.output_dir.mkdir(parentsTrue, exist_okTrue) def _embed_logo(self, qr_img, logo_path): qr_w, qr_h qr_img.size logo_side int(qr_w * self.logo_ratio) logo Image.open(logo_path).convert(RGBA) ratio min(logo_side / logo.size[0], logo_side / logo.size[1]) new_size (int(logo.size[0] * ratio), int(logo.size[1] * ratio)) logo logo.resize(new_size, Image.LANCZOS) pos ((qr_w - new_size[0]) // 2, (qr_h - new_size[1]) // 2) base qr_img.convert(RGBA) base.paste(logo, pos, logo) bg Image.new(RGB, base.size, (255, 255, 255)) bg.paste(base, maskbase.split()[3]) return bg def _gen_one(self, url, index, logo_path): try: qr qrcode.QRCode( versionNone, error_correctionERROR_CORRECT_H, box_size10, border4, ) qr.add_data(url) qr.make(fitTrue) img qr.make_image(fill_colorblack, back_colorwhite).convert(RGB) img img.resize((self.qr_size, self.qr_size), Image.LANCZOS) if logo_path and os.path.exists(logo_path): img self._embed_logo(img, logo_path) url_hash hashlib.md5(url.encode(utf-8)).hexdigest()[:8] save_path self.output_dir / fqr_{index:04d}_{url_hash}.png img.save(save_path) return {url: url, index: index, ok: True, path: str(save_path)} except Exception as e: logger.error(生成失败 url%s err%s, url, e) return {url: url, index: index, ok: False, path: None} def run(self, csv_path, logo_pathNone): urls [] with open(csv_path, r, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: if row.get(url): urls.append(row[url].strip()) logger.info(读取到 %d 条链接, len(urls)) results [] with ThreadPoolExecutor(max_workersself.max_workers) as pool: futures { pool.submit(self._gen_one, url, i, logo_path): i for i, url in enumerate(urls) } for fut in as_completed(futures): results.append(fut.result()) results.sort(keylambda x: x[index]) ok sum(1 for r in results if r[ok]) logger.info(完成 %d/%d, ok, len(urls)) return results if __name__ __main__: import sys csv_file sys.argv[1] if len(sys.argv) 1 else promotions.csv logo sys.argv[2] if len(sys.argv) 2 else None skill QRBatchSkill(output_dir./qr_output, qr_size400, logo_ratio0.2, max_workers8) res skill.run(csv_file, logo) failed [r for r in res if not r[ok]] print(f成功 {len(res) - len(failed)} 条失败 {len(failed)} 条)CSV 输入模板长这样第一列是渠道名第二列是完整推广链接带 UTM 参数channel,url wechat,https://example.com/landing?utm_sourcewechatutm_mediumqrutm_campaignspring weibo,https://example.com/landing?utm_sourceweiboutm_mediumqrutm_campaignspring douyin,https://example.com/landing?utm_sourcedouyinutm_mediumqrutm_campaignspring跑起来就一行命令export TAOTOKEN_API_KEY你的key python qr_skill.py promotions.csv assets/logo.png如果你想让 Agent 在生成后自动检查二维码可扫性可以在脚本里加一段调用 TaoToken 模型对话接口的逻辑把生成的图片路径传过去做视觉校验。接口地址用https://taotoken.net/api/chat/completions请求格式兼容 OpenAI改 base_url 即可。这样整个技能就具备了「生成 自检」的闭环能力。4. 验证请求与成功结果1000 条链接的生成与扫码实测配置写完得验证它真能扛住 1000 条。我构造了一份 1000 行的 CSV渠道名从 channel_0001 到 channel_1000每条链接带独立的 utm_content 参数模拟真实投放场景。Logo 用一张 512×512 的透明底 PNG二维码边长设 400 像素Logo 占比 0.2并发 8 线程。执行命令后控制台日志滚动输出读取条数和完成进度。1000 条在普通笔记本上跑完大约 40 到 60 秒具体取决于 CPU 核心数和磁盘写入速度。跑完后qr_output目录下生成 1000 个 PNG 文件命名格式是qr_0001_xxxxxxxx.png序号保证顺序哈希保证唯一。验证分两步。第一步看文件数量和大小用命令统计ls qr_output | wc -l du -sh qr_output正常情况输出 1000 和几十 MB 的占用。第二步做扫码验证这是关键——生成得再好看扫不出来等于零。我抽了 20 张不同渠道的二维码用手机相机和微信扫一扫分别测试全部一次识别成功跳转链接与 CSV 中的 URL 完全一致。中心 Logo 遮挡区域没有影响定位点纠错等级 H 的 30% 容错在这里起了作用。如果你要批量验证可以写个脚本用 OpenCV 的 QRCodeDetector 逐张解码比对解码结果和原始 URLimport cv2 from pathlib import Path detector cv2.QRCodeDetector() ok, fail 0, 0 for p in Path(qr_output).glob(*.png): img cv2.imread(str(p)) data, _, _ detector.detectAndDecode(img) if data: ok 1 else: fail 1 print(解码失败:, p.name) print(f可扫 {ok} 张失败 {fail} 张)实测下来1000 张里可扫率 100%没有出现因 Logo 过大或对比度不足导致的失败。这里有个经验Logo 占比别超过 0.25超过后即使纠错等级 H 也可能在部分老旧扫码器上识别困难。另外二维码边长别低于 300 像素太小的话打印出来边缘模糊扫码距离会变短。配色方面标准码用黑白是识别率最高的组合。如果你要品牌色把fill_color改成深色系比如深蓝 #1A3A6Bback_color保持白色或极浅灰对比度足够就不会影响识别。别用浅色前景配深色背景那是反的扫码器认不出来。生成完成后把qr_output整个文件夹打包发给运营或者按渠道名建子目录分类。如果链接量还会增长把这个技能留在 Codex 里下次换 CSV 直接复用不用重新写代码。5. 常见报错排查401、local proxy failed、reading choices 逐个击破批量任务跑起来报错是常态。这一节把几个高频错误和对应解法列清楚遇到时对照排查。401 Unauthorized。这个多半出在调用 TaoToken 接口时 key 没配对。检查三处环境变量TAOTOKEN_API_KEY是否导出成功skill.toml里的${TAOTOKEN_API_KEY}引用是否正确请求头里的Authorization: Bearer key格式有没有多空格。用echo $TAOTOKEN_API_KEY确认变量存在再跑一次。如果还报 401去控制台的 API Keys 页面确认 key 没过期、没被删除。local proxy failed。这个错误通常出现在网络请求环节提示本地代理连接失败。先检查你的环境变量里有没有残留的HTTP_PROXY或HTTPS_PROXY设置有的话清掉再试。如果你在用某些网络工具确认它们没有干扰 Python 的 requests 库。最稳妥的做法是在脚本里显式指定不走代理import os os.environ.pop(HTTP_PROXY, None) os.environ.pop(HTTPS_PROXY, None)reading choices 相关报错。这类错误一般出现在解析模型返回结果时提示读取 choices 字段失败。原因通常是接口返回了非预期结构比如错误信息被当成正常响应解析。排查方法是先把原始响应打印出来看resp requests.post(url, headersheaders, jsonpayload) print(resp.status_code) print(resp.text[:500])看到实际返回内容就知道是 key 问题、参数问题还是模型名写错了。模型 ID 要跟 TaoToken 文档里列出的保持一致别自己拼。OAuth 相关报错。如果你在配置 Codex 或 Claude Code 时遇到 OAuth 认证失败检查回调地址和客户端配置是否匹配。这类问题多半是配置项填错对照文档逐项核对。涉及 Claude Code 接入时Base URL、API Key、Model ID 三件套要写全缺一个都会认证失败。二维码扫不出来。这不是程序报错但更常见。三个检查点纠错等级是否设为 HLogo 占比是否超过 0.25前景色和背景色对比度是否足够。把 Logo 缩小到 0.15 再试基本能解决。文件保存失败。如果报错提示路径不存在或权限不足确认output_dir目录已创建且当前用户有写入权限。脚本里已经用mkdir(parentsTrue, exist_okTrue)处理了目录创建如果还失败检查磁盘空间。排查顺序建议从外到内先确认网络和 key再确认参数格式最后看业务逻辑。大部分报错在前两步就能定位。6. 把技能用起来从单次生成到长期增长工具二维码批量生成这件事做完一次不算完。真正的价值在于把它变成团队可复用的增长工具。你可以把这个 Codex Skill 留在项目里每次投放前导出 CSV一条命令出成品。渠道数量从 1000 涨到 5000改一下并发数就行代码不用动。如果想让技能更智能可以接上 TaoToken 的模型对话能力做两件事一是根据渠道名自动生成配色方案让不同渠道的二维码有视觉区分二是生成后自动做可扫性校验把失败的挑出来重生成。接口统一走https://taotoken.net/apikey 在控制台管理用量清晰。长期做编码和 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 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到配置问题先翻文档大部分坑里面都有说明。最后留个实用技巧把 Logo 和背景图放在项目assets目录CSV 放在data目录输出到qr_output整个结构进版本库。下次换一批链接只改data里的 CSV其他不动。这样技能就是真正可复用的资产而不是一次性脚本。
延伸阅读

更多相关文章

2026/10/12 22:04:29

C语言单链表实战:从内存管理到工程化实现

1. 项目概述:为什么单链表是C语言学习绕不开的“成人礼”单链表不是教科书里一个冷冰冰的数据结构名词,它是C语言开发者真正开始“和内存对话”的第一个实战关口。我带过不少刚学完语法基础的学员,一上来就写printf("Hello World")…

2026/10/12 22:04:29

IT项目环境与过程双控实战:从踩坑到自愈

1. 项目概述:为什么“把握环境,控制过程”不是口号,而是IT项目成败的生死线在某高校信息中心承接的教务系统二期升级项目里,我作为技术协调人全程参与。项目启动时,所有文档都写着“按PMBOK流程执行”,甘特…

2026/10/12 23:24:38

C#异步编程:Task<TResult>返回值与异常处理全解析

1. Task到底是返回值还是承诺搞C#异步开发这么久,我始终觉得很多人的第一次崩溃都始于同一行代码:Task.Run(() > 计算()).Result,程序卡死了。卡死还算好的,最怕的是卡死了之后弹出来一个AggregateException,里面包…

2026/10/12 23:24:38

LOL小目标检测数据集:6类3000张YOLOv8/v10即用型训练资源

简介:本资源是面向计算机视觉初学者与目标检测实践者的LOL英雄联盟角色检测专用数据集,适用于模型训练、算法验证及游戏场景识别研究。数据集共3000张高质量截图,涵盖6类关键游戏实体:己方小兵、己方防御塔、敌方小兵、敌方防御塔…

2026/10/12 23:24:38

SSA-XGBoost回归预测调参实战:Matlab实现与避坑指南

简介:这份资源面向需要做数据回归预测的研究者与工程人员,提供麻雀算法(SSA)优化XGBoost超参数的Matlab完整实现,重点解决n_estimators、max_depth、learning_rate等关键参数难以人工调优、易过拟合的问题。压缩包共10…

2026/10/12 23:19:38

从RNN到Transformer:序列建模的架构演进与工程实践

1. 从序列建模的困境说起做自然语言处理这行的朋友,大概都经历过被循环神经网络支配的那几年。2015年前后,你如果跟别人说要做文本分类、机器翻译或者情感分析,十有八九对方会问你用的是LSTM还是GRU。那时候循环神经网络就是序列建模的代名词…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑