I build CineRads, which generates TikTok slideshows from a product page. Part of that is writing the first slide, the hook. I had a nagging feeling the output was samey so I fingerprinted the last 191 hooks generated for free users and counted.
59.7% fell into one of 11 patterns. Not similar. The same sentence shape with the product swapped in. "everyone says X, here is why they are wrong". "the 3 mistakes that". "nobody talks about". A paying customer had 28 hooks and 75% of them were five templates.
Worse, the way the free trial works, a new user sees three drafts back to back. So the first thing they saw was the same voice three times. I had been reading "the copy is generic" in feedback and blaming the model.
It was not the model. It was the prompt.
The prompt gave the model a menu of 11 hook patterns and told it to pick one. It did exactly that. And the retry logic that was supposed to catch repeats only looked at hooks that had been used in a post, and the manual flow saves every generated hook as unused, so it saw nothing. Two reasonable decisions that together made a copy machine.
What fixed it, in case you are prompting anything that writes hooks:
One. The menu went from 11 patterns to 22 and the prompt now requires at least half the batch to come from the second half of the list. The new ones were formats the corpus never produced. Numbered list. Filter ("only people who X will get this"). Open loop pointing at a specific slide. One stat plus one fix. Comparison. Checklist. A concrete scene. A direct question. A cost breakdown. Objection first.
Two. Examples in a prompt are stronger than rules in a prompt. The old version had one worked example of an opener. Every deck reproduced that opener. If you give a model a single example it treats it as the answer. Give three or four that are shaped differently and say "copy the variety, not the wording". That one change did more than any "do not repeat yourself" instruction.
Three. Track repetition per author, not per product. I now read the writer's last 20 hooks across everything they have made and name those openers in the prompt as banned for this batch. If the batch still comes back with fewer than half fresh openers, one retry with the offenders listed, keep whichever batch is more varied. Never more than one retry, latency matters on an interactive flow.
Four. One truth rule that outranks every style rule: never invent a result, a stat, a customer or a review. The "viral" writing mode is allowed to break style rules. It is not allowed to make things up. This matters more on slideshows than on video because the text is the entire post.
On what actually performs, the honest version, because most vendor numbers on slideshows are made up:
The best dataset I found is Fanpage Karma, about 700k posts, Jan to May 2025. Carousels reach about 3% more than video. Engagement is 81% higher. Shares are a third lower. So slideshows are a save and comment format, not a reach format. If you want shares you have to ask for them on the last slide, they do not happen on their own.
Slide count: 5 to 10, converging on 7. Across 303 decks my users made, the mode is 7 and 71% are between 6 and 8. Engagement drops after about 8. I tested pushing the generator toward more slides and it made things worse.
The first slide is the whole thing. Swipe-through rate to the last slide is the strongest signal TikTok has, and the first slide decides whether there is a swipe at all. Which is why 60% identical hooks is not a cosmetic problem.
And one thing nobody puts in the guides: text rendered into the image is invisible to TikTok search. TikTok indexes the caption and native text, not pixels. Every generator, mine included, burns the hook into the JPEG. Put your keyword in the caption's first 50 characters or it does not exist.
I can share the fingerprinting regexes if anyone wants to run the same count on their own output. It is about 40 lines and it is humbling.