☰
基于Claude Code构建Agent Skill:自动生成内容社区封面图
2026/10/21 12:44:34 网站建设 项目流程

先说这个项目做了什么

我用某大厂定制版CC(就是目前很火的Claude Code模式的编程Agent,下文统一叫CC)写了一个生成内容社区封面图的Skills,输入一句主题描述,它能自动出一张长宽比为3:4的竖版封面图,可以直接拿去当某生活方式分享平台的笔记封面。项目已经开源,代码放在GitHub上,支持自定义风格、副标题、情绪色调,还内置了几套常用的版式模板。

当时做这个东西是因为身边太多做内容运营的朋友吐槽:每天要出好几张封面图,打开设计工具一张张排版太费时间,用AI绘图工具又经常把封面上的中文标题写得乱七八糟。我就在想,能不能让CC变成一个“封面设计师”,通过对话直接生成成品图。于是花了几天时间,把技能定义、渲染脚本、模板库全部封装成了一个Skill目录。现在我在CC对话里写一句“用cover skill给一篇关于新手做咖啡的笔记生成封面,主标题叫‘咖啡入门不踩坑’,副标题写‘从选豆到拉花全流程’”,它就能输出一张排版完整、文字清晰、颜色统一的封面图。

这个项目适合三类人:一是内容创作者和运营,想批量产出社区封面;二是刚开始接触Agent Skills、想知道这东西到底怎么落地的人;三是对“用代码做设计”这种生产方式感兴趣的同学。下面我按实际开发顺序,把思路、实现、踩坑全过程都写出来。

1. 为什么非得为一个“封面图”单独做Skill

1.1 封面图在内容社区里的真实作用

做内容的人都清楚,封面图不是“好看就行”的装饰品,它是内容本身的筛子。在某生活方式平台的信息流里,用户刷到一篇笔记时,第一眼看到的就是封面缩略图,封面决定点不点进来,标题决定看完不看完。封面图在这类平台的重要性,比公众号封面、网页头图要高得多,因为整个App的浏览逻辑就是“图片优先”的瀑布流。

所以运营们要的不是“随便一张好看的图”,而是符合平台调性、文字信息明确、风格统一、能快速传达主题的封面。3:4的竖版比例是这类平台的默认封面比例,顶部是主标题区,中间留白给正文信息,底部收尾放装饰元素。这些约束非常具体,用通用的大模型绘图工具很难稳定满足,因为绘图模型擅长生成“好看的画面”,却不擅长生成“排版正确的信息图”。

我试过在主流AI绘图工具里输入“生成一张带‘咖啡入门不踩坑’字样的竖版封面”,结果文字要么拼错,要么字体变形,甚至经常多出几个根本不存在的字。原因在于这些模型对文字的生成是“像素级偶合”,它不是排版出来的,是画出来的,中文笔画又复杂,出错率很高。

1.2 为什么不用设计工具模板硬拼

市面上一堆设计工具都有现成的封面模板,填文字换图就能出图,看起来很快。但实际用下来有几个问题。

第一,模板风格固化。你用的是那几套别人用了无数次的模板,读者刷到你封面时,视觉记忆是和大量同类内容重叠的,很难建立辨识度。第二,批量生成困难。设计工具适合一张张精调,不适合一次性生成10张备选方案再挑选。第三,自动化程度低。如果我想让AI根据文章内容自动提取标题和副标题,再自动生成封面,设计工具做不到,它的操作界面是给人手动点的,不是给程序调用的。

说白了,我要的不是“设计工具”,而是“设计流程的自动化”。封面设计的核心变量其实就是:标题文字、副标题、视觉风格、颜色倾向、版式布局。这些变量都可以结构化表达,完全可以写成程序逻辑。而CC这类Agent恰好擅长“根据指令写代码并执行”,那我让它直接调用脚本来渲染图片,才是最顺的思路。

1.3 用“代码渲染”做封面的核心优势

用Pillow库写渲染脚本,等于把封面变成了一组确定的参数:尺寸、背景色、渐变方向、标题文字、字号、字色、贴纸形状。同样的输入,程序永远给出同样输出,不会像AI绘图那样随机性很大。

这一点很关键。因为内容社区的封面是系列化的,今天出一篇“咖啡入门”,明天出一篇“咖啡进阶”,它们的封面的版式逻辑应该一样,只是标题和配图信息不同。如果你用AI绘图,哪怕同一个提示词,两次生成的图风格都会有偏差;而用代码渲染,只要参数一致,输出就是一致的,品牌感可以稳定下来。

我最终确定的方案是:CC负责理解用户的需求,把自然语言转成结构化的封面参数JSON,再由一段Python脚本把JSON变成图片。CC不直接“画画”,它只是充当“传令官”。这样就把大模型不可控的图文生成问题,拆解成了可控的“代码执行”问题。

2. 动手前先拆解:封面图Skill需要哪几层结构

2.1 Agent Skill的运行机制

在开始写之前,我得先弄明白CC的Skill机制是什么。简单来说,Skill就是给Agent挂载的一套“专项技能包”,它通常是一个目录,里面包含一份能力描述文档、一些示例、可能还包括可执行脚本。

能力描述文档是核心,它告诉CC“你有一个什么技能”“这个技能在什么场景下触发”“使用者会提出什么类型的需求”“你该如何调用配套脚本”。当用户请求与技能匹配时,CC会读这份文档,然后按文档里的指引把任务拆解成具体动作。

这个机制的好处是隔离性。不把封面生成的逻辑直接塞进Agent的系统提示词里,而是放到单独的Skill目录中,需要的时候才被加载。这样既能保持Agent本身响应轻盈,又让“封面生成”作为一种可复用的能力随时被调用,并且换到别的项目里也可以继续使用,只要拷贝目录过去就行。

2.2 我设计的Skill目录结构

我把Skill做成了一个三层结构,分别对应“描述层”“参数层”“渲染层”。目录长这样:

cover_creator/ ├── SKILL.md ├── templates/ │ ├── simple_center.json │ ├── split_bottom.json │ ├── card_left.json │ └── gradient_flow.json ├── assets/ │ ├── font_bold.ttf │ ├── font_regular.ttf │ └── sticker_arrow.png ├── scripts/ │ ├── create_cover.py │ └── validate_args.py └── examples/ ├── coffee_cover.json └── travel_cover.json

SKILL.md是给CC看的说明书,它描述了这个Skill能干什么、不能干什么、怎么调用。templates目录下存放的是几种版式的JSON配置文件,每种版式定义一组基础布局参数,比如标题位置、副标题位置、背景渐变方向、装饰元素位置。scripts目录下的create_cover.py是真正干活的渲染脚本,它接收一个封面参数JSON,输出一张PNG图片。examples目录则放了一些示例JSON,方便CC参考输入格式。

这套结构是我调试了多次后确定的。最初我想把所有逻辑都塞进一个Python文件里,但发现CC在写调用参数时经常乱来,因为它不知道“到底有哪些版式可选”,每一版式的字段名也不统一。把版式拆成独立的JSON模板后,CC只需要从模板库中挑一个,再覆盖少量字段即可,参数描述变得非常清晰。

2.3 参数设计:让自然语言变成稳定JSON

封面生成最需要控制的是文字、比例和风格,因此参数JSON必须设计得足够精确。我最终定义了下面这些字段:

{ "title": "咖啡入门不踩坑", "subtitle": "从选豆到拉花全流程", "style": "modern_gradient", "template": "split_bottom", "color_scheme": { "background": ["#F7E8D8", "#E6C8A8"], "title_color": "#3A2A22", "subtitle_color": "#7B6B5E" }, "extra_tag": "新手友好", "output_size": [1440, 1920], "output_path": "cover.png" }

title是最关键的主标题,subtitle是辅助信息,style和template决定版式,color_scheme控制配色,output_size固定为3:4比例。

这里有一个细节,标题文字我要求CC必须原样输出,不允许它“润色”或“重新提炼”。因为用户指定什么标题,就是什么标题,封面文字不能被AI擅自改动。这一点是在SKILL.md里强制写死的。

3. 从零实现:封面图Skill的完整搭建过程

3.1 编写SKILL.md:怎么让CC“听懂”技能边界

SKILL.md是整个Skill的大脑,写不好后面全是扯淡。我第一版SKILL.md写得很简略,结果CC经常“自作主张”把标题改掉,或者擅自换模板。后面我总结出了一套比较稳的写法思路:告诉它触发条件、输入格式、执行步骤、硬性约束、示例。

核心是“硬性约束”部分,我写得很啰嗦,效果反而很好。比如这样:

## 硬性约束 1. 必须原样使用用户提供的主标题和副标题,不得增删改任何一个字。 2. 输出图片必须是PNG格式,尺寸必须是1440*1920(宽*高),除非用户明确要求其他尺寸。 3. 默认生成一张主封面,如果用户没有指定风格,默认使用modern_gradient风格。 4. 必须先将用户的自然语言需求转换成cover_params.json,再执行渲染脚本。 5. 如果用户提供的主题信息不完整(缺少副标题或风格),必须主动向用户询问,不得猜测。

第5条一开始没有,后来加的。因为有一次用户只说了“做一张封面”,CC直接编了个标题开始渲染,虽然流程跑通了,但内容完全不是用户想要的。加了这条之后,CC会先反问“主标题是什么副标题是什么”,这样交互体验反而更好。

接着写调用步骤。我给CC定义了一条固定的执行链:

执行步骤: 1. 分析用户需求,提取title、subtitle、style、template、color_scheme等参数。 2. 如果template未指定,从templates目录中选择一个最匹配的模板JSON。 3. 将提取到的参数与模板JSON合并,生成完整的cover_params.json。 4. 执行python scripts/create_cover.py --params cover_params.json 5. 确认生成成功后,向用户输出图片路径,并简要说明使用了什么风格。

3.2 核心渲染脚本:用代码把画面画出来

create_cover.py是项目的心脏,它做的事其实不复杂:读JSON、创建画布、画渐变背景、排版文字、贴装饰元素、导出PNG。

我选了Pillow库来实现。为什么不用SVG再转PNG?虽然SVG做排版很顺手,转换过程中容易遇到字体兼容问题,而且圆角、阴影这些效果在SVG里要写一堆语法。Pillow虽然也麻烦,但可控性强,纯本地渲染,跑一次只花不到两秒。

字体处理是我踩得比较狠的坑。Pillow默认字体不支持中文,必须引入外部中文字体。我在assets目录里放了两款免费可商用的中文字体:一款粗体,用于主标题;一款常规体,用于副标题和小标签。CC在执行时会显式传入字体路径,避免不同系统默认字体不一致导致乱码。

看一下create_cover.py的几个关键片段。

先解析参数,带基础校验:

import json import sys from PIL import Image, ImageDraw, ImageFont def load_params(path): with open(path, "r", encoding="utf-8") as f: data = json.load(f) if not data.get("title"): raise ValueError("主标题缺失") if data.get("output_size"): w, h = data["output_size"] if w / h != 3 / 4: print("警告:当前输出尺寸不是3:4比例,可能会影响平台展示") return data

然后是绘制渐变背景。很多设计工具做渐变很容易,但Pillow画渐变要自己逐像素生成。我把常见的径向渐变和线性渐变都做成函数,SKILL.md里也写明了不同风格对应哪种渐变。

def linear_gradient(draw, size, start_color, end_color): w, h = size for y in range(h): ratio = y / h r = int(start_color[0] * (1 - ratio) + end_color[0] * ratio) g = int(start_color[1] * (1 - ratio) + end_color[1] * ratio) b = int(start_color[2] * (1 - ratio) + end_color[2] * ratio) draw.line([(0, y), (w, y)], fill=(r, g, b))

这段代码虽然基础,但它是封面质感的关键。背景不是纯色,而是一层层颜色渐变的,视觉上比纯色高级很多。

接下来是文字排版。主标题的位置根据模板动态计算,如果标题超过8个字,字号自动缩小;超过12个字,自动换行。换行不是简单按字符数切,而是优先在标点处换行。这个逻辑花了不少时间调。

def draw_title(draw, title, font_path, max_width, base_size, position): font_size = base_size font = ImageFont.truetype(font_path, font_size) while font.getlength(title) > max_width and font_size > 60: font_size -= 2 font = ImageFont.truetype(font_path, font_size) draw.text(position, title, font=font, fill=(0, 0, 0))

最后把模板里的装饰元素画上去。比如“split_bottom”模板会在底部放一条圆弧色带,属于比较简单但出效果的几何元素。

3.3 模板库设计:同一个底层,四种视觉风格

模板是封面最容易让人感觉“千篇一律”的环节。我做模板的时候就一个目标:让大家拿到项目改起来简单,替换配色和字体位置即可,而不用去动渲染脚本的逻辑。

四种内置模板分别是:

  • simple_center:主标题居中,副标题在下方,强调极简留白
  • split_bottom:画面下部有一条圆弧色带,主标题在左上方,适合活泼类内容
  • card_left:主标题在左侧垂直排列,右侧留出大面积空白,适合放贴纸或品牌LOGO
  • gradient_flow:大面积渐变背景,标题居左上,适合情感类叙事

每个JSON模板里写清楚标题的坐标、字号基准、副标题的坐标、装饰元素类型。这样CC在渲染时读的就是结构化的版式数据,而不是反复修改渲染脚本里的硬编码。我特意没有做那种“一个脚本对应一个模板”的设计,因为那样CC需要为每个模板维护一套代码,一旦模板数量增多,Skill体积会膨胀,也不利于后续扩展。

3.4 联调演示:从一句自然语言到一张封面

搭建完成后,我在CC里做了一次完整测试。对话大概是这样的:

用户输入:“用cover skill生成一张封面,主题是‘城市周末散步指南’,副标题‘五条小众路线推荐’,风格清新一点,加一个‘建议收藏’的角标。”

CC的处理过程很直观。它先判断这是封面生成需求,触发cover_creator Skill,然后读取SKILL.md。它检查了templates目录,发现gradient_flow这个模板比较适合“清新”的诉求,就把用户需求转成参数JSON。其中“清新”被映射成了一套低饱和度的蓝绿色系配色,角标被映射到extra_tag字段。最后CC运行脚本,输出一张1440x1920的PNG图片,并告诉我:“已使用gradient_flow风格生成,主标题为城市周末散步指南,副标题为五条小众路线推荐。”

这一步如果纯靠人用设计工具做,大概需要3到5分钟,而CC整个过程用了不到20秒。批量场景更明显,让CC读一个文件里的十个标题列表,它能连续生成十张风格统一但各自不同的封面。

4. 实测中踩过的坑与排查思路

4.1 中文乱码与字体缺失

最一开始,我在Mac上跑脚本时一切正常,把项目丢到Linux服务器上,再执行就直接报fatal error。原因很经典:服务器上没有安装中文字体。

Pillow在找不到指定字体文件时会抛异常,而不是自动回退到系统中的其他中文字体。我的解决办法分两层:第一,脚本启动时检查字体文件是否存在,不存在就尝试从系统字体目录自动查找可用中文字体;第二,在SKILL.md里写明“运行环境需要准备中文字体文件,否则无法渲染中文”,并给出推荐的开源字体下载地址。

自动查找的逻辑大概是:

def find_font(candidate_paths): for p in candidate_paths: if os.path.exists(p): return p raise FileNotFoundError("未找到中文字体文件")

这个坑必须写在第一行提示里,因为团队里其他人拉项目跑的时候十有八九会栽在这。

4.2 标题文字溢出与自动换行策略

第二个高频问题是标题太长。比如“一篇文章讲清楚如何做好社区运营”这个标题,如果用base_size=88的字号渲染,在1440宽的画面里一定会溢出边界。我一开始的做法是单纯缩小字号,但缩到60以下时,整张封面标题就变得很小气,失去视觉冲击力。

后来我改成“先换行、后缩字号”的策略:优先在逗号、顿号、“的”“与”“和”这类自然语义停顿处换行,最多允许两行;如果两行放不下再缩字号。这样既保证标题的大字视觉效果,又不会溢出画面。

这里还需要考虑安全边距。封面图在平台信息流里会被裁掉一部分,左右两侧和底部尤其危险。我把标题的安全边距设为左右各120像素,底部预留300像素给平台UI遮挡区域,保证标题即使被裁也裁不掉关键信息。

4.3 CC把标题改得过于“通顺”

这是AI Agent项目很容易忽略的细节。CC天然有“润色”倾向,你让它生成一个标题叫“咖啡入门不踩坑”,它可能自作聪明改成“从零开始学咖啡:入门不踩坑全攻略”,然后放到封面上。逻辑上通顺了,但用户要求的是原名,运营可能是想测试两个不同封面标题的点击率,你一改,测试就废了。

所以我在SKILL.md里加了一条最高优先级的规则:

## 最高优先级约束 用户提供的主标题、副标题内容必须逐字保留,这是不可协商的硬性要求。CC在生成参数JSON时不得修改、润色、缩写或扩写任何标题文字。

加完这条之后,CC基本不会再改标题了。

4.4 渲染脚本参数校验失误导致流程中断

还有一次调试时,CC生成的JSON里color_scheme传了一个奇数数量的数组,比如["#FF9900", "blue", "黄色"],渲染脚本直接报错退出。原因是SKILL.md里只写了颜色值格式,没有写“必须为hex格式且长度固定为6位”,CC就容易给出一堆自由格式。

解决办法是validate_args.py里写强制校验:

def check_colors(scheme): for field in ["background", "title_color", "subtitle_color"]: val = scheme.get(field) if isinstance(val, list): for c in val: if not re.match(r"^#[0-9A-Fa-f]{6}$", c): raise ValueError(f"颜色值格式错误:{c}")

同时在SKILL.md里给了一个明确的范围说明,CC从此只会输出规范的十六进制颜色。

4.5 多轮对话中模板参数互相污染

CC在连续生成多张封面时,偶尔会把上一张的参数带进下一张。比如上一张是“split_bottom”,下一次用户要“simple_center”,生成结果里还是套用了split_bottom的底边条。

这个问题的根源在于模板参数是“合并”的,而不是“重建”的。修复方法是每次生成前先清空默认参数,只从模板JSON里重新加载:

def reset_params(template_path): with open(template_path, "r", encoding="utf-8") as f: return json.load(f)

我在SKILL.md里专门注明了一句“每次渲染前必须从templates目录重新读取模板参数,禁止复用上一次的内存参数”,之后这个问题就再没出现过。

4.6 性能问题:1440x1920像素逐行渲染太慢

第一次全流程跑通时,光渐变背景渲染就花了接近3秒,加上文字抗锯齿,单张封面总耗时5秒左右,用起来不够爽快。

我做的优化是:背景渐变先在一个小尺寸的画布上生成,再用resize放大到目标尺寸。因为渐变是平滑过渡,缩小后再放大视觉上没有差别,但渲染时间可以从数秒降到0.3秒以内。实测整个封面生成流程控制在1秒上下,完全能满足连续生成需求。

5. 进阶玩法与开源之后可以怎么继续扩展

5.1 给这个Skill增加批量生产能力的思路

我目前已经加了一个batch模式。用户可以写一个标题列表,每行一个主题,CC自动读取、自动生成一组封面。这个模式特别适合做矩阵账号的内容运营,每天固定产出5到10张封面,保持账号更新频率。

批量模式的实现没有太复杂,就是让CC循环调用渲染脚本,每张封面使用不同的模板轮换,避免连续几张都长得一样。我在SKILL.md里让它“依次循环使用templates目录下的全部模板”,这样会让输出更有变化感。

5.2 多个内容平台的尺寸适配扩展

小红书风格封面是3:4竖版,但微信公众号头图是900x383的横版,视频封面又是16:9的横版,这个Skill能不能扩展?完全可以。

只要脚本里的output_size参数变成可配置项,然后不同平台预先写好各自的模板JSON就行。我计划下一步把模板逻辑从“固定尺寸”中抽离出来,让同一套视觉语言可以输出到不同尺寸的介质上。

5.3 接入内容产出流程中做自动化

我还想让这个Skill和文章写作流程联动。比如先让CC写一篇文章,再从文章中自动提炼三个候选标题,最后直接生成对应封面。整个过程只需要一句指令。这个方向已经不只是“做一张图”了,而是把内容生产链路打通:策划、写作、标题、封面全部在CC里一次完成。

开源的意义也在于这里。现在项目只是一个起点模型,它不完美,但框架是完整可扩展的。大家拿到源码后,可以按自己平台的视觉规范改模板、改配色、加字体,甚至替换成自家品牌模板。

写在最后:我对“AI干活”这件事的一点体会

做完这个项目,我最深的感受是:AI Agent最合适的角色不是“独立完成一切”,而是充当“大脑调度器”。它负责理解意图、拆解任务、调用合适的工具、检查结果,而具体的确定性工作,比如渲染像素、排版文字,应该交给传统代码来做。

以前总觉得“AI生成图片”就应该用AI绘图模型,但实际落地下来,很多场景的根本需求不是“生成一张图”,而是“生成一张内容信息正确、风格统一、符合平台规则的图”。这种需求用代码驱动反而更可控、更高效。封面图让人看起来“不那么AI”的关键,就在于它根本不是AI直接画的,而是AI编排+代码渲染的结果。

如果你是做内容运营的,你可以直接把templates目录换成自己的版式,把字体换成自己品牌字体,让CC成为一个真正贴合你需求的封面生成器。如果你是在研究Agent Skills的开发者,希望这个项目能给你提供一个参考样本:Skill不只是给Agent写提示词,更是给它配置一套可执行、可验证的工具链路。

项目已经开源,你拿到后可以随便改。我个人在写完这个Skill之后,反而不太想再去一张张手动做封面了。工具存在的意义,就是让重复劳动变得不值钱。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询