Write effective image-generation prompts: subject blocking, composition and camera terms, reusable style tokens, negative-prompt patterns, and a disciplined iterate-and-compare loop. Triggers when an agent needs to generate images, fix bad generations, or keep a series visually consistent.
./install.sh image-prompt-craftname: "image_prompt_craft" description: "Write effective image-generation prompts: subject blocking, composition and camera terms, reusable style tokens, negative-prompt patterns, and a disciplined iterate-and-compare loop. Triggers when an agent needs to generate images, fix bad generations, or keep a series visually consistent." metadata: { "includeInPrompt": true }
Turn a vague idea into a prompt that reliably produces the image you meant. This skill covers the words that go into the prompt itself: what to describe, in what order, how to lock a style across a series, which negatives earn their place, and how to iterate without burning endless generations. It is tool-neutral. It names no model flags, samplers, or parameters, because those differ by tool and change over time.
Before touching the prompt, write a single sentence: who is in the frame, doing what, where. Example: "A tired knight rests in a rainy forest clearing at dawn." If you cannot write that sentence, the idea is not ready to prompt yet.
Many generators give more weight to early text. When that holds for your tool, order matters: put what must survive first.
Abstract praise gives the generator nothing to draw. Each time you catch a word like "beautiful", "epic", or "stunning", replace it with something visible.
Before: "a beautiful epic warrior woman in a cool fantasy forest"
After: "full-body portrait of a scarred female knight in dented plate armor, sword planted tip-down in the mud, standing at ease in a rain-soaked pine clearing, low-angle shot, soft overcast dawn light, oil painting, muted earthy palette"
Negative: "extra fingers, deformed hands, watermark, text, blurry" Reason: hands and watermarks are the two most common artifacts in people shots, so these negatives target the actual failure modes instead of generic "bad quality" filler.
When several images must look like they belong together, freeze the style tokens. Write one style string, store it in a file, and paste it verbatim into every prompt in the series. Example style sheet entry: series-noir: "black and white film photography, high contrast, deep shadows, grain". When your tool supports seeds and you need reproducibility, record the seed with the prompt. Change the subject and setting per image; never paraphrase the style string.
Only when your tool supports negative prompts. Good negatives name specific artifacts and why they appear:
Do not stack negatives you have never needed. Each one is a bet about what will go wrong; keep a short list per project and grow it from your prompt log.
Keep a prompt log. One line per generation: the prompt (or the changed phrase), keep or drop, and why. The log is what turns one good image into a repeatable style.
A finished prompt-craft pass delivers:
Save the script below as ~/workspace/promptcraft.py (or anywhere on your PATH). It assembles an ordered prompt from slots, audits it for vague adjectives, text risks, and length, and keeps the prompt log.
python
#!/usr/bin/env python3
"""promptcraft: assemble and audit image-generation prompts.
Save as ~/workspace/promptcraft.py, then run:
python3 promptcraft.py build --subject "..." --action "..." --setting "..." \
--camera "..." --lighting "..." --style "..." [--quality "..."] \
[--negative "..."]
python3 promptcraft.py log --prompt "<final prompt>" --verdict keep|drop \
--note "..."
Log entries append to ./prompt-log.md as a Markdown table.
"""
import argparse
import os
import re
VAGUE = ["beautiful", "amazing", "stunning", "epic", "cool", "nice",
"awesome", "gorgeous", "incredible", "breathtaking", "fantastic"]
TEXT_HINTS = ["text", "sign saying", "words", "caption", "logo", "title"]
LOG_FILE = "prompt-log.md"
ORDER = [
("subject", "who/what is in frame"),
("action", "pose or activity"),
("setting", "where it happens"),
("camera", "framing and camera terms"),
("lighting", "light quality and direction"),
("style", "medium and style tokens"),
("quality", "quality/finish tail"),
]
def build(args):
parts = [getattr(args, name) for name, _ in ORDER]
prompt = ", ".join(p.strip() for p in parts if p and p.strip())
lines = ["PROMPT:", prompt]
if args.negative:
lines += ["", "NEGATIVE:", args.negative.strip()]
else:
lines += ["", "NEGATIVE: (none given)"]
warnings = []
low = prompt.lower()
vague_found = sorted({w for w in VAGUE if re.search(r"\b" + w + r"\b", low)})
if vague_found:
warnings.append(
"vague adjectives found (%s): pair each with something visible, "
"e.g. 'beautiful' -> 'clear skin, symmetrical face'"
% ", ".join(vague_found))
words = len(prompt.split())
if words > 75:
warnings.append(
"prompt is %d words; generators often drop late details. "
"Put the must-haves first and cut low-value adjectives." % words)
if any(h in low for h in TEXT_HINTS):
warnings.append(
"prompt asks for text or logos; keep any text to 1-3 short words "
"in quotes, or drop the text and add it later in an editor.")
if not args.negative and ("hand" in low or "person" in low
or "portrait" in low):
warnings.append(
"people in frame but no negative given; consider adding "
"'extra fingers, deformed hands, extra limbs' if your tool "
"supports negative prompts.")
if warnings:
lines += ["", "AUDIT:"]
lines += ["- " + w for w in warnings]
else:
lines += ["", "AUDIT: clean."]
print("\n".join(lines))
def log(args):
exists = os.path.exists(LOG_FILE)
with open(LOG_FILE, "a", encoding="utf-8") as f:
if not exists:
f.write("| prompt | verdict | note |\n|---|---|---|\n")
p = args.prompt.replace("|", "\\|").replace("\n", " ")
n = (args.note or "").replace("|", "\\|").replace("\n", " ")
f.write("| %s | %s | %s |\n" % (p, args.verdict, n))
print("logged to %s" % LOG_FILE)
def main():
ap = argparse.ArgumentParser(description="assemble and audit image prompts")
sub = ap.add_subparsers(dest="cmd", required=True)
b = sub.add_parser("build", help="assemble an ordered prompt and audit it")
for name, help_text in ORDER:
b.add_argument("--" + name, default="", help=help_text)
b.add_argument("--negative", default="", help="negative prompt (if supported)")
l = sub.add_parser("log", help="record a prompt and verdict in the prompt log")
l.add_argument("--prompt", required=True)
l.add_argument("--verdict", required=True, choices=["keep", "drop"])
l.add_argument("--note", default="")
args = ap.parse_args()
if args.cmd == "build":
build(args)
else:
log(args)
if __name__ == "__main__":
main()
publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.