OptionalCreativeVersion 2.0.0

Meme Generation Skill for Hermes Agent: Template PNGs with Pillow

Create meme PNGs from templates with Pillow text overlay.

Written by Neura Market from the official Hermes Agent documentation for Meme Generation. Commands, paths, and version numbers are reproduced from the source unchanged.

Read the official documentation

The Meme Generation skill lets Hermes Agent turn a topic into an actual meme image: it selects a template, writes short captions, and renders a real .png with text overlaid using Pillow. Reach for it when a user asks for a meme, wants a joke about a specific frustration or situation, or says something like "meme this". It is an optional creative skill, so it is installed on demand rather than shipping with the base runtime.

What it does

The skill wraps a Python script that does two jobs. First, it resolves a template: either one of ten curated layouts with hand-tuned text positioning, or any of the roughly one hundred popular imgflip templates by name or ID. Second, it draws the captions onto the template image and writes a .png to a path you choose. The result is a file you can hand back to the user through the agent's media delivery mechanism.

Because the script handles the rendering, the agent's job is mostly editorial: read the request, identify the joke structure, pick the template that matches that structure, and write captions short enough to look right. The skill is authored by adanaleycio, version 2.0.0, MIT licensed, and runs on linux, macos, and windows.

Before you start

This is an optional-tier skill, so it is not present until it is installed. The skill path is optional-skills/creative/meme-generation. You need Python available to run the generator script, and the script needs Pillow for the text overlay work. The source does not list any other install steps, so treat the skill's own install as the prerequisite and do not assume extra packages.

One practical detail: the script caches template images in scripts/.cache/ after the first download. That means the first run for a given template depends on fetching it, and later runs reuse the cached copy. If you are working offline or behind a restrictive network, plan for that first fetch.

Template options

Curated templates

Ten templates ship with custom text placement, which means the captions sit where the joke expects them. Each has a fixed set of fields, and you must supply captions in that field order.

IDNameFieldsBest for
this-is-fineThis is Finetop, bottomchaos, denial
drakeDrake Hotline Blingreject, approverejecting/preferring
distracted-boyfriendDistracted Boyfrienddistraction, current, persontemptation, shifting priorities
two-buttonsTwo Buttonsleft, right, personimpossible choice
expanding-brainExpanding Brain4 levelsescalating irony
change-my-mindChange My Mindstatementhot takes
woman-yelling-at-catWoman Yelling at Catwoman, catarguments
one-does-not-simplyOne Does Not Simplytop, bottomdeceptively hard things
grus-planGru's Planstep1-3, realizationplans that backfire
batman-slapping-robinBatman Slapping Robinrobin, batmanshutting down bad ideas

Dynamic templates

Anything outside the curated list can still be used by name or imgflip ID. These get smart default positioning: top and bottom for two-field templates, evenly spaced for three or more. To find one, search the template catalogue:

python "$SKILL_DIR/scripts/generate_meme.py" --search "disaster"

Use the search when the topic suggests a visual the curated ten do not cover. It is also the right move when you know the meme by name but not its ID.

Generating a classic template meme

This is the default path and the one most requests will take.

  1. Read the request and name the core dynamic: chaos, a dilemma, a preference, irony, a bad plan.
  2. Choose the template whose "Best for" description matches that dynamic, or search with --search if none of the curated ten fit.
  3. Write captions for each field. Keep each one to 8-12 words at most; shorter is better.
  4. Locate the skill's script directory:
SKILL_DIR=$(dirname "$(find ~/.hermes/skills -path '*/meme-generation/SKILL.md' 2>/dev/null | head -1)")
  1. Run the generator with the template ID, an output path, and one caption per field:
python "$SKILL_DIR/scripts/generate_meme.py" <template_id> ~/.hermes/cache/scratch/meme.png "caption 1" "caption 2" ...
  1. Return the image with MEDIA:~/.hermes/cache/scratch/meme.png.

The field count matters. A two-field template takes two captions; expanding-brain takes four; grus-plan takes four as well (three steps plus the realization). Passing the wrong number is the most common way a run goes wrong, so check the table before you write the command.

Generating a custom AI image meme

When no classic template fits, or the user wants something original, the skill can overlay text on an image you generate first. This path needs image_generate to be available.

  1. Write the captions before you generate anything. The joke drives the scene, not the other way around.

  2. Use image_generate to create a scene matching the concept. Do not put text in the image prompt; the script adds text afterwards. Describe only the visual scene.

  3. Get the generated image path from the image_generate result URL, downloading it locally if needed.

  4. Run the script with --image to overlay text. There are two modes.

    Overlay puts text directly on the image, white with a black outline:

python "$SKILL_DIR/scripts/generate_meme.py" --image /path/to/scene.png ~/.hermes/cache/scratch/meme.png "top text" "bottom text"

Bars puts black bars above and below the image with white text, which is cleaner and always readable:

python "$SKILL_DIR/scripts/generate_meme.py" --image /path/to/scene.png --bars ~/.hermes/cache/scratch/meme.png "top text" "bottom text"

Choose --bars when the scene is busy or detailed and overlaid text would be hard to read.

  1. If vision_analyze is available, check the result before delivering it:
vision_analyze(image_url="~/.hermes/cache/scratch/meme.png", question="Is the text legible and well-positioned? Does the meme work visually?")

If the vision model reports problems such as unreadable text or poor placement, switch modes (overlay to bars or back) or regenerate the scene.

  1. Return the image with MEDIA:~/.hermes/cache/scratch/meme.png.

Worked examples

These show the caption style the skill expects: short, punchy, matched to the template's structure.

"debugging production at 2 AM":

python generate_meme.py this-is-fine ~/.hermes/cache/scratch/meme.png "SERVERS ARE ON FIRE" "This is fine"

"choosing between sleep and one more episode":

python generate_meme.py drake ~/.hermes/cache/scratch/meme.png "Getting 8 hours of sleep" "One more episode at 3 AM"

"the stages of a Monday morning":

python generate_meme.py expanding-brain ~/.hermes/cache/scratch/meme.png "Setting an alarm" "Setting 5 alarms" "Sleeping through all alarms" "Working from bed"

Notice that the drake example has two captions (reject, approve) and the expanding-brain example has four, one per level. That is the field-count rule in action.

Listing templates

To see every template the script knows about:

python generate_meme.py --list

Run this when you are unsure whether a template name is recognised, or when you want to browse before choosing.

When not to use it

The source does not name a direct alternative for this task, but it does point at a related skill: ascii-art. If the request is for text-based visual output rather than a rendered image, that is the neighbouring option. For anything that needs a real .png with captions on a photographic or illustrated template, this skill is the one to use.

Limits and gotchas

The source is explicit about what makes a meme fail:

  • Keep captions short. Long text looks terrible on a meme.
  • Match the number of text arguments to the template's field count.
  • Pick the template that fits the joke structure, not just the topic. A topic can map to several templates; the structure is what decides.
  • Do not generate hateful, abusive, or personally targeted content.
  • Template images are cached in scripts/.cache/ after the first download, so the first use of a template is the one that fetches.

Verifying the result

The output is correct when all of these hold:

  • A .png file exists at the output path.
  • The text is legible, white with a black outline, on the template.
  • The joke lands: the caption matches the template's intended structure.
  • The file can be delivered through the MEDIA: path.

If any of those fail, the fix is usually editorial (shorter captions, a different template) rather than technical.

What pairs with it

The source lists ascii-art as a related skill. Both are creative-output skills, and ascii-art covers the case where the user wants something visual but text-based. Beyond that, the custom-image path depends on image_generate and optionally vision_analyze, so those capabilities are the natural companions when you want original scenes rather than stock templates.

Skills the docs pair this with

More Creative skills