Generate voice guide
Generate a personal voice guide for X (Twitter) and/or LinkedIn by scanning a user's past posts and iteratively refining with sample-and-feedback loops.
How to use it
- Hit Copy SKILL.md — or use the Claude Code line below to get every file.
- Claude: ⋯ → Download .md, then Customize → Skills → Add → Upload skill.
ChatGPT: make a Project and paste it into Instructions.
Neither? Paste it at the top of a new chat — it works for that chat. - Describe your job in plain words. The AI follows the skill from there.
npx degit gooseworks-ai/goose-skills/skills/brand/capabilities/generate-voice-guide#main ~/.claude/skills/generate-voice-guideFor one project only, change the path to .claude/skills/generate-voice-guide. This skill also uses voice-x.md, voice-linkedin.md — copying SKILL.md alone won't be enough. See the folder on GitHub.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Show the full text183 lines
Generate Voice Guide
Turn a real person's past posts into a structured voice guide that other skills can use to draft in-voice content. Produces one guide per platform (X, LinkedIn, or both) with persona, dos/don'ts, banned phrases, hook patterns, format rules, and example posts.
This is an agent-executed skill — the agent handles scraping, analysis, drafting, and iteration via the tools available in the session. No bundled Python script.
When to use
- A user wants to build a personal voice guide for social content
- Another skill (e.g.
create-x-content,create-linkedin-content,social-kit) needs a voice guide and one doesn't exist - The user wants to mimic someone else's public voice (for ghostwriting, parody, or study)
When NOT to use: For analysing a company's blog/landing-page voice, use brand-voice-extractor instead. That's for corporate marketing voice; this one is for individual social voice.
Quick Start
Interactive:
/generate-voice-guide
Args mode:
/generate-voice-guide --profile @GooseworksAI --platforms x,linkedin --output ~/.goose-skills/voice-guides
Discovery Questions (front-loaded)
Ask these up front if not supplied via flags:
- Whose voice? "Paste an X/Twitter handle (e.g.
@GooseworksAI), a LinkedIn profile URL, or both. You can mimic your own voice or someone else's." - Which platforms? "Generate a voice guide for X, LinkedIn, or both?"
- How many posts to scan? "Default: 50 X posts / 25 LinkedIn posts. Higher = more signal, more tokens, slower."
- Save location? "Default:
~/.goose-skills/voice-guides/voice-{x,linkedin}.md. Ok to use that, or prefer a different path?"
Workflow
Phase 1 — Scrape past posts
For X:
- Use Apify actor
apidojo/twitter-user-tweets-scraper(or whichever X scraper is available in the session) keyed to the handle. - Fetch the target count (default 50). Exclude replies, retweets, and quote tweets unless the user specifies otherwise — we want original voice.
- Requires
APIFY_API_TOKENenv var. If missing, surface a clear error with the setup link.
For LinkedIn:
- Use Apify actor
harvestapi/linkedin-profile-postskeyed to the profile URL. - Fetch the target count (default 25). Include only original posts (no reshares).
Fallback (no scraper available or posts paywalled): ask the user to paste 15–25 posts as plain text.
Store raw post text, engagement metrics (likes, views if available), and timestamps.
Phase 2 — Generate v1 voice guide
Use voice-x.md / voice-linkedin.md template references (see "Template Skeleton" below) to produce v1 of the guide. Do NOT copy content from them — only the structure.
Analyse the scraped posts for:
- Persona — inferred role, audience, credentials, tone spectrum
- The "meat" principle — what concrete substance typically appears: tools, numbers, builds, steps, links
- Dos — observed hook patterns, connective phrases, list style, casual asides, emoji usage, CTA patterns
- Don'ts — patterns the author conspicuously avoids (no threads, no engagement bait, etc.)
- Banned phrases — common LLM-speak the author never uses (
excited to share,leverage,game-changing,thrilled, etc.). List 10–20. - Hook patterns — 5–8 distinct opening-line templates drawn from real posts
- Format rules — word count ranges, bullet style, density, line-break rhythm
- Tone calibration — educator vs conversational ratio; when each applies
- Example posts with analysis — pull 4–6 real posts and explain why each works, what pattern it exemplifies
Phase 3 — Sample + feedback loop (5+ iterations)
This is where voice-guide quality is made. Do NOT skip iterations.
Each iteration:
- Generate 3 sample posts from the current guide, each using a different hook pattern from the guide. Use topics from the user's own posting history so they're easy to judge (e.g. if they post about AI agents, draft on AI agents).
- Show the user:
- Which hook pattern each sample used
- The 3 sample posts
- 1–2 lines from the current guide that most influenced the samples
- Ask for feedback — specific prompts:
- "Which samples sound like you? Which don't?"
- "What's the most off-sounding phrase or pattern?"
- "What's missing — a hook you use, a rule you follow?"
- Apply feedback — revise the guide. Update dos/don'ts, hook patterns, banned phrases, examples. Note what changed in a short changelog at the top of the guide during iteration.
- Repeat.
Stopping rule: continue until the user explicitly says "this is good" AND at least 5 iterations have completed. 5 is a floor, not a ceiling. If the user says "good enough" at iteration 2, push back: "Voice guides need at least 5 rounds to actually lock in. Can we do 3 more?"
Phase 4 — Save + register
- Write the final guide to the resolved output path (default
~/.goose-skills/voice-guides/voice-<platform>.md). - Strip the iteration changelog — only keep the final clean guide.
- Update
~/.goose-skills/config.json:
Create the directory/file if missing. Merge with existing config if present (don't overwrite other keys).{ "voice_guides": { "x": "<absolute path to voice-x.md>", "linkedin": "<absolute path to voice-linkedin.md>" } } - Print a confirmation with the saved paths and a next-step suggestion: "You can now run
/create-x-content --brief \"...\"and it'll use this voice guide automatically."
Template Skeleton
Every generated voice guide should have these top-level sections, in order:
# Voice Guide: <Platform> — <Handle or Name>
## Persona
## The "Meat" Principle
## Dos
## Don'ts
## Banned Phrases
## Hook Patterns
## CTA Guidelines
## Format Rules
## Tone Calibration
## Example Posts That Exemplify The Voice
Match the depth and specificity of a well-written voice guide — prose for persona, numbered lists for dos/don'ts, quoted examples with analysis. Aim for 120–250 lines.
Config File
~/.goose-skills/config.json is a lightweight cross-skill config. Schema:
{
"voice_guides": {
"x": "/absolute/path/to/voice-x.md",
"linkedin": "/absolute/path/to/voice-linkedin.md"
}
}
Sibling skills read this to discover voice guide paths. Always use absolute paths.
Inputs
| Input | Required | Default |
|---|---|---|
--profile |
Yes (one of X handle, LinkedIn URL, or both) | — |
--platforms |
No | x,linkedin if both profiles given, else matches supplied profiles |
--posts-x |
No | 50 |
--posts-linkedin |
No | 25 |
--output |
No | ~/.goose-skills/voice-guides |
--iterations-min |
No | 5 |
Outputs
<output>/voice-x.mdand/or<output>/voice-linkedin.md- Updated
~/.goose-skills/config.jsonwith voice guide paths - Stdout summary: paths written + quick-start command for next step
Dependencies
- Apify API token (
APIFY_API_TOKEN) for scraping - No other paid services required
- Voice guide structural references (open via
WebFetchor read locally if the user has them) — not required to run
Tips
- 5+ iterations is the floor. If the user pushes to stop early, explain that voice guides are only good after ~5 rounds.
- Use the user's own topics for samples. Draft samples on subjects they've posted about — makes it much easier for them to spot an off-key line.
- Quote real posts in the examples section. Never paraphrase — use direct verbatim quotes with a source link.
- Call out ghost-writing or assistant-authored posts. If some posts feel dramatically different, flag it: "These 3 posts read differently — worth checking if they're yours or ghost-written."
- Don't lean on LLM clichés in the banned-phrases list. Derive bans from actual absence in the user's writing, not a generic blocklist.
| 1 | |
| 2 | name generate-voice-guide |
| 3 | description > |
| 4 | Generate a personal voice guide for X (Twitter) and/or LinkedIn by scanning a user's |
| 5 | past posts and iteratively refining with sample-and-feedback loops. Produces a |
| 6 | structured markdown voice guide that sibling skills (create-x-content, |
| 7 | create-linkedin-content) consume to draft in-voice posts. Different from |
| 8 | brand-voice-extractor, which analyses company blogs/landing pages — this skill is |
| 9 | for personal social voice. |
| 10 | tags [content, social] |
| 11 | |
| 12 | |
| 13 | # Generate Voice Guide |
| 14 | |
| 15 | Turn a real person's past posts into a structured voice guide that other skills can use to draft in-voice content. Produces one guide per platform (X, LinkedIn, or both) with persona, dos/don'ts, banned phrases, hook patterns, format rules, and example posts. |
| 16 | |
| 17 | **This is an agent-executed skill** — the agent handles scraping, analysis, drafting, and iteration via the tools available in the session. No bundled Python script. |
| 18 | |
| 19 | ## When to use |
| 20 | |
| 21 | A user wants to build a personal voice guide for social content |
| 22 | Another skill (e.g. `create-x-content`, `create-linkedin-content`, `social-kit`) needs a voice guide and one doesn't exist |
| 23 | The user wants to mimic someone else's public voice (for ghostwriting, parody, or study) |
| 24 | |
| 25 | **When NOT to use:** For analysing a company's blog/landing-page voice, use `brand-voice-extractor` instead. That's for corporate marketing voice; this one is for individual social voice. |
| 26 | |
| 27 | ## Quick Start |
| 28 | |
| 29 | Interactive: |
| 30 | |
| 31 | /generate-voice-guide |
| 32 | |
| 33 | |
| 34 | Args mode: |
| 35 | |
| 36 | /generate-voice-guide --profile @GooseworksAI --platforms x,linkedin --output ~/.goose-skills/voice-guides |
| 37 | |
| 38 | |
| 39 | ## Discovery Questions (front-loaded) |
| 40 | |
| 41 | Ask these up front if not supplied via flags: |
| 42 | |
| 43 | **Whose voice?** "Paste an X/Twitter handle (e.g. `@GooseworksAI`), a LinkedIn profile URL, or both. You can mimic your own voice or someone else's." |
| 44 | **Which platforms?** "Generate a voice guide for X, LinkedIn, or both?" |
| 45 | **How many posts to scan?** "Default: 50 X posts / 25 LinkedIn posts. Higher = more signal, more tokens, slower." |
| 46 | **Save location?** "Default: `~/.goose-skills/voice-guides/voice-{x,linkedin}.md`. Ok to use that, or prefer a different path?" |
| 47 | |
| 48 | ## Workflow |
| 49 | |
| 50 | ### Phase 1 — Scrape past posts |
| 51 | |
| 52 | **For X:** |
| 53 | Use Apify actor `apidojo/twitter-user-tweets-scraper` (or whichever X scraper is available in the session) keyed to the handle. |
| 54 | Fetch the target count (default 50). Exclude replies, retweets, and quote tweets unless the user specifies otherwise — we want original voice. |
| 55 | Requires `APIFY_API_TOKEN` env var. If missing, surface a clear error with the setup link. |
| 56 | |
| 57 | **For LinkedIn:** |
| 58 | Use Apify actor `harvestapi/linkedin-profile-posts` keyed to the profile URL. |
| 59 | Fetch the target count (default 25). Include only original posts (no reshares). |
| 60 | |
| 61 | **Fallback (no scraper available or posts paywalled):** ask the user to paste 15–25 posts as plain text. |
| 62 | |
| 63 | Store raw post text, engagement metrics (likes, views if available), and timestamps. |
| 64 | |
| 65 | ### Phase 2 — Generate v1 voice guide |
| 66 | |
| 67 | Use `voice-x.md` / `voice-linkedin.md` template references (see "Template Skeleton" below) to produce v1 of the guide. Do NOT copy content from them — only the *structure*. |
| 68 | |
| 69 | Analyse the scraped posts for: |
| 70 | |
| 71 | **Persona** — inferred role, audience, credentials, tone spectrum |
| 72 | **The "meat" principle** — what concrete substance typically appears: tools, numbers, builds, steps, links |
| 73 | **Dos** — observed hook patterns, connective phrases, list style, casual asides, emoji usage, CTA patterns |
| 74 | **Don'ts** — patterns the author conspicuously avoids (no threads, no engagement bait, etc.) |
| 75 | **Banned phrases** — common LLM-speak the author never uses (`excited to share`, `leverage`, `game-changing`, `thrilled`, etc.). List 10–20. |
| 76 | **Hook patterns** — 5–8 distinct opening-line templates drawn from real posts |
| 77 | **Format rules** — word count ranges, bullet style, density, line-break rhythm |
| 78 | **Tone calibration** — educator vs conversational ratio; when each applies |
| 79 | **Example posts with analysis** — pull 4–6 real posts and explain *why* each works, what pattern it exemplifies |
| 80 | |
| 81 | ### Phase 3 — Sample + feedback loop (5+ iterations) |
| 82 | |
| 83 | This is where voice-guide quality is made. Do NOT skip iterations. |
| 84 | |
| 85 | Each iteration: |
| 86 | |
| 87 | **Generate 3 sample posts** from the current guide, each using a different hook pattern from the guide. Use topics from the user's own posting history so they're easy to judge (e.g. if they post about AI agents, draft on AI agents). |
| 88 | **Show the user:** |
| 89 | Which hook pattern each sample used |
| 90 | The 3 sample posts |
| 91 | 1–2 lines from the current guide that most influenced the samples |
| 92 | **Ask for feedback** — specific prompts: |
| 93 | "Which samples sound like you? Which don't?" |
| 94 | "What's the most off-sounding phrase or pattern?" |
| 95 | "What's missing — a hook you use, a rule you follow?" |
| 96 | **Apply feedback** — revise the guide. Update dos/don'ts, hook patterns, banned phrases, examples. Note what changed in a short changelog at the top of the guide during iteration. |
| 97 | **Repeat.** |
| 98 | |
| 99 | **Stopping rule:** continue until the user explicitly says "this is good" AND at least 5 iterations have completed. 5 is a floor, not a ceiling. If the user says "good enough" at iteration 2, push back: "Voice guides need at least 5 rounds to actually lock in. Can we do 3 more?" |
| 100 | |
| 101 | ### Phase 4 — Save + register |
| 102 | |
| 103 | Write the final guide to the resolved output path (default `~/.goose-skills/voice-guides/voice-<platform>.md`). |
| 104 | Strip the iteration changelog — only keep the final clean guide. |
| 105 | Update `~/.goose-skills/config.json`: |
| 106 | |
| 107 | { |
| 108 | "voice_guides": { |
| 109 | "x": "<absolute path to voice-x.md>", |
| 110 | "linkedin": "<absolute path to voice-linkedin.md>" |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | Create the directory/file if missing. Merge with existing config if present (don't overwrite other keys). |
| 115 | Print a confirmation with the saved paths and a next-step suggestion: "You can now run `/create-x-content --brief \"...\"` and it'll use this voice guide automatically." |
| 116 | |
| 117 | ## Template Skeleton |
| 118 | |
| 119 | Every generated voice guide should have these top-level sections, in order: |
| 120 | |
| 121 | |
| 122 | # Voice Guide: <Platform> — <Handle or Name> |
| 123 | |
| 124 | ## Persona |
| 125 | ## The "Meat" Principle |
| 126 | ## Dos |
| 127 | ## Don'ts |
| 128 | ## Banned Phrases |
| 129 | ## Hook Patterns |
| 130 | ## CTA Guidelines |
| 131 | ## Format Rules |
| 132 | ## Tone Calibration |
| 133 | ## Example Posts That Exemplify The Voice |
| 134 | |
| 135 | |
| 136 | Match the depth and specificity of a well-written voice guide — prose for persona, numbered lists for dos/don'ts, quoted examples with analysis. Aim for 120–250 lines. |
| 137 | |
| 138 | ## Config File |
| 139 | |
| 140 | `~/.goose-skills/config.json` is a lightweight cross-skill config. Schema: |
| 141 | |
| 142 | |
| 143 | { |
| 144 | "voice_guides": { |
| 145 | "x": "/absolute/path/to/voice-x.md", |
| 146 | "linkedin": "/absolute/path/to/voice-linkedin.md" |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | |
| 151 | Sibling skills read this to discover voice guide paths. Always use absolute paths. |
| 152 | |
| 153 | ## Inputs |
| 154 | |
| 155 | | Input | Required | Default | |
| 156 | |-------|----------|---------| |
| 157 | | `--profile` | Yes (one of X handle, LinkedIn URL, or both) | — | |
| 158 | | `--platforms` | No | `x,linkedin` if both profiles given, else matches supplied profiles | |
| 159 | | `--posts-x` | No | 50 | |
| 160 | | `--posts-linkedin` | No | 25 | |
| 161 | | `--output` | No | `~/.goose-skills/voice-guides` | |
| 162 | | `--iterations-min` | No | 5 | |
| 163 | |
| 164 | ## Outputs |
| 165 | |
| 166 | `<output>/voice-x.md` and/or `<output>/voice-linkedin.md` |
| 167 | Updated `~/.goose-skills/config.json` with voice guide paths |
| 168 | Stdout summary: paths written + quick-start command for next step |
| 169 | |
| 170 | ## Dependencies |
| 171 | |
| 172 | Apify API token (`APIFY_API_TOKEN`) for scraping |
| 173 | No other paid services required |
| 174 | Voice guide *structural* references (open via `WebFetch` or read locally if the user has them) — not required to run |
| 175 | |
| 176 | ## Tips |
| 177 | |
| 178 | **5+ iterations is the floor.** If the user pushes to stop early, explain that voice guides are only good after ~5 rounds. |
| 179 | **Use the user's own topics for samples.** Draft samples on subjects they've posted about — makes it much easier for them to spot an off-key line. |
| 180 | **Quote real posts in the examples section.** Never paraphrase — use direct verbatim quotes with a source link. |
| 181 | **Call out ghost-writing or assistant-authored posts.** If some posts feel dramatically different, flag it: "These 3 posts read differently — worth checking if they're yours or ghost-written." |
| 182 | **Don't lean on LLM clichés in the banned-phrases list.** Derive bans from actual absence in the user's writing, not a generic blocklist. |
| 183 |