<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wilco Rakhorst</title>
    <description>The latest articles on DEV Community by Wilco Rakhorst (@wilcorakhorst).</description>
    <link>https://dev.to/wilcorakhorst</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3909999%2F1af32257-632d-43e5-b0d0-51c43c8884c0.jpg</url>
      <title>DEV Community: Wilco Rakhorst</title>
      <link>https://dev.to/wilcorakhorst</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wilcorakhorst"/>
    <language>en</language>
    <item>
      <title>My GitHub Copilot Sessions Kept Degrading -- So I Built a Skill to Fix It</title>
      <dc:creator>Wilco Rakhorst</dc:creator>
      <pubDate>Fri, 08 May 2026 09:18:56 +0000</pubDate>
      <link>https://dev.to/wilcorakhorst/my-github-copilot-sessions-kept-degrading-so-i-built-a-skill-to-fix-it-23pg</link>
      <guid>https://dev.to/wilcorakhorst/my-github-copilot-sessions-kept-degrading-so-i-built-a-skill-to-fix-it-23pg</guid>
      <description>&lt;p&gt;You've probably experienced this. You're 30 minutes into a productive Copilot agent session, things are flowing well -- and then something shifts. The agent asks you to clarify something it already knows. It repeats a question from earlier. The quality of the output quietly drops. You didn't change anything. What happened?&lt;/p&gt;

&lt;p&gt;Context ran out.&lt;/p&gt;

&lt;p&gt;Every Copilot session has a fixed token budget. Once that budget fills up, the model starts compressing or dropping older context. The result isn't an error message. It's subtle degradation -- and most developers don't even realize it's happening until they're already fighting it.&lt;/p&gt;

&lt;p&gt;I built a skill to address this directly. Here's what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem isn't Copilot. It's how we use it.
&lt;/h2&gt;

&lt;p&gt;After tracking a few weeks of agent sessions, I found five recurring patterns that burned through context faster than the actual work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Re-reads&lt;/strong&gt;&lt;br&gt;
When the same instruction exists in multiple files, the agent reloads it every time it's referenced. I had rules duplicated across &lt;code&gt;copilot-instructions.md&lt;/code&gt; and individual skill files. Every time a skill loaded, it brought along content that was already in context. Fix: cross-cutting rules live in &lt;code&gt;references/*.md&lt;/code&gt; only. Skills link to them, never copy them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Reading entire files instead of snippets&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;read_file&lt;/code&gt; without &lt;code&gt;startLine&lt;/code&gt;/&lt;code&gt;endLine&lt;/code&gt; loads the full file -- every time. On a workspace with many skill files, this adds up fast. I also had &lt;code&gt;list_dir&lt;/code&gt; calls on the workspace root, which recursively indexed hundreds of paths I never needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Too many tools active&lt;/strong&gt;&lt;br&gt;
Every loaded MCP tool takes up space in the system context -- even if it's never called. In agent mode, deferred tools should only be loaded via &lt;code&gt;tool_search&lt;/code&gt; when genuinely needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Working too long in one session&lt;/strong&gt;&lt;br&gt;
After 15-20 messages, context compression begins. The agent doesn't tell you this. You notice it when output quality drops or earlier decisions get quietly reversed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Trial-and-error tool use&lt;/strong&gt;&lt;br&gt;
When an agent dives straight into tool calls without a plan, every failed attempt costs double tokens -- once for the call, once for the error. Requiring a written Plan of Action before any tool is invoked eliminates this entirely.&lt;/p&gt;


&lt;h2&gt;
  
  
  The skill I built
&lt;/h2&gt;

&lt;p&gt;I encoded all of this into a &lt;code&gt;token-hygiene&lt;/code&gt; skill:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;token-hygiene&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Guidelines&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;efficient&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Copilot&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;context&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;management.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;when&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;session&lt;/span&gt;
  &lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;slowing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;down,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;repeating&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;questions,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;context&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;filling&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;up,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;when&lt;/span&gt;
  &lt;span class="s"&gt;starting&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;complex&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;multi-step&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;task.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Triggers:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'token',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'context&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;full',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'session&lt;/span&gt;
  &lt;span class="s"&gt;cleanup',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'new&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;chat',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'load&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;skill',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'terminal&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;risk',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'plan&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;action',&lt;/span&gt;
  &lt;span class="s"&gt;'context&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;efficiency'."&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.0"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill body covers the five causes above, plus a pre-task checklist the agent can consult before starting any complex job:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Is this info already in context?&lt;/td&gt;
&lt;td&gt;Don't reload it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Which skills do I actually need?&lt;/td&gt;
&lt;td&gt;Load only those -- not preemptively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Am I reading a large file?&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;startLine&lt;/code&gt;/&lt;code&gt;endLine&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Searching with a broad term?&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;grep_search&lt;/code&gt; instead of &lt;code&gt;semantic_search&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex multi-step task?&lt;/td&gt;
&lt;td&gt;Write a Plan of Action first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Been working in this session long?&lt;/td&gt;
&lt;td&gt;Consider new chat + session memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent repeating a question?&lt;/td&gt;
&lt;td&gt;Session is full -- save and restart&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The terminal protocol: a surprise lesson
&lt;/h2&gt;

&lt;p&gt;While building this skill, I discovered something that surprised me. The &lt;code&gt;run_in_terminal&lt;/code&gt; tool has an &lt;code&gt;explanation&lt;/code&gt; parameter described as &lt;em&gt;"This will be shown to the user before the command is run."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That is not true.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;explanation&lt;/code&gt; parameter is not visible in the confirmation dialog. It's metadata for the tool system, not a user-facing message. This means if you rely on it to inform users about what a command does, they never see it.&lt;/p&gt;

&lt;p&gt;So I added a terminal protocol as a reference file. It requires the agent to write the explanation as a chat message &lt;em&gt;before&lt;/em&gt; the tool call -- not after, not inside the tool call. The message must cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the command does in plain language&lt;/li&gt;
&lt;li&gt;Which files are read or modified&lt;/li&gt;
&lt;li&gt;Whether data leaves the system&lt;/li&gt;
&lt;li&gt;Whether the action is reversible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combined with a risk classification matrix ([LOW] low / [MEDIUM] medium / [HIGH] high / [CRITICAL] critical), this makes every terminal action visible and deliberate.&lt;/p&gt;




&lt;h2&gt;
  
  
  VS Code indexing: a silent token drain
&lt;/h2&gt;

&lt;p&gt;One thing worth adding to your &lt;code&gt;.vscode/settings.json&lt;/code&gt; immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"files.exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"out/"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Output/"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"search.exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"out/"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Output/"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VS Code indexes your entire workspace for search. Generated output folders -- HTML reports, screenshots, log files -- get included in search results and can end up as irrelevant context when the agent runs a workspace search. &lt;code&gt;.gitignore&lt;/code&gt; doesn't prevent this. Only &lt;code&gt;files.exclude&lt;/code&gt; and &lt;code&gt;search.exclude&lt;/code&gt; do.&lt;/p&gt;




&lt;h2&gt;
  
  
  The skill structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.github/skills/token-hygiene/
  SKILL.md                            # Core skill -- 5 causes, checklist, VS Code tip
  references/
    terminal-protocol.md              # Required transparency rules for terminal calls
    terminal-risk-classification.md   # Risk matrix per command type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The references are loaded on demand -- the agent only reads them when it actually needs to run a terminal command. This follows the progressive disclosure pattern I described in my previous post on reusable marketing skills.&lt;/p&gt;




&lt;h2&gt;
  
  
  The most useful thing: session memory
&lt;/h2&gt;

&lt;p&gt;The fix I use most often isn't even in the skill itself. At the end of any session longer than 15 messages, I ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Summarize our progress as a short status update."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I paste that into the first message of the new chat. The agent has full context again in one message, without reloading a single file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;manage_todo_list&lt;/code&gt; also helps here -- if the agent tracks tasks as it works, you never need to scroll back through the conversation to remember where you are.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters more than you'd expect
&lt;/h2&gt;

&lt;p&gt;Token hygiene sounds like an optimization problem. It's actually a reliability problem.&lt;/p&gt;

&lt;p&gt;When context fills quietly, the agent doesn't fail loudly. It makes slightly worse decisions. It misremembers earlier choices. It starts contradicting itself in subtle ways. For short sessions, you might not notice. For longer, multi-step workflows -- publishing pipelines, multi-file refactors, anything with state -- the degradation compounds.&lt;/p&gt;

&lt;p&gt;Encoding these rules as a skill means I never have to think about them. The agent consults the checklist before complex tasks and follows the terminal protocol automatically. I just do the work.&lt;/p&gt;

&lt;p&gt;The repo: &lt;a href="https://github.com/WilcoRakhorst/copilot-context-skills" rel="noopener noreferrer"&gt;copilot-context-skills on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The previous post: &lt;a href="https://dev.to/wilcorakhorst/i-built-reusable-marketing-skills-for-github-copilot-heres-how-and-why-4l97"&gt;I Built Reusable Marketing Skills for GitHub Copilot -- Here's How and Why&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What patterns have you noticed that drain context faster than they should? I'd like to expand the skill with more real-world examples.&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built Reusable Marketing Skills for GitHub Copilot — Here's How (and Why)</title>
      <dc:creator>Wilco Rakhorst</dc:creator>
      <pubDate>Sun, 03 May 2026 08:22:49 +0000</pubDate>
      <link>https://dev.to/wilcorakhorst/i-built-reusable-marketing-skills-for-github-copilot-heres-how-and-why-4l97</link>
      <guid>https://dev.to/wilcorakhorst/i-built-reusable-marketing-skills-for-github-copilot-heres-how-and-why-4l97</guid>
      <description>&lt;p&gt;What if your code editor could do keyword research, audit your SEO, and optimize your content for AI search engines — without leaving VS Code?&lt;/p&gt;

&lt;p&gt;I built a set of open-source agent skills that turn GitHub Copilot into a hands-on marketing strategist. Here's what I learned, how they work, and how you can use (or build) your own.&lt;/p&gt;

&lt;p&gt;The problem&lt;br&gt;
I run a small website. Every time I wanted to write a blog post, the workflow looked like this:&lt;/p&gt;

&lt;p&gt;Open Ahrefs/Semrush → research keywords&lt;br&gt;
Open Google Docs → write the article&lt;br&gt;
Open WordPress → publish and fill in SEO fields&lt;br&gt;
Open ChatGPT → rewrite for social media&lt;br&gt;
Repeat&lt;br&gt;
Five tools. Five context switches. And every time, I found myself giving the same SEO instructions to AI assistants: "Use the keyword in the first paragraph", "Write a meta description under 155 characters", "Structure with H2/H3 headings"...&lt;/p&gt;

&lt;p&gt;What if I could encode all that knowledge once, and have my AI assistant apply it automatically?&lt;/p&gt;

&lt;p&gt;The solution: Copilot Skills&lt;br&gt;
GitHub Copilot (in agent mode) can read SKILL.md files from your workspace. These files act as knowledge modules — they tell Copilot how to approach a domain, what rules to follow, and what frameworks to apply.&lt;/p&gt;

&lt;p&gt;I created four skills that cover the full marketing workflow:&lt;/p&gt;

&lt;p&gt;seo-keyword-research  →  Find what your audience searches for&lt;br&gt;
        ↓&lt;br&gt;
seo-strategy          →  Structure your site to rank&lt;br&gt;
        ↓&lt;br&gt;
geo-optimization      →  Get cited by AI search engines&lt;br&gt;
        ↓&lt;br&gt;
content-creator       →  Write content that ranks AND gets cited&lt;br&gt;
What's inside a skill?&lt;br&gt;
A skill is just a Markdown file with structured knowledge. Here's a simplified look at the GEO (Generative Engine Optimization) skill:&lt;/p&gt;




&lt;p&gt;name: geo-optimization&lt;br&gt;
description: "\"Optimize content for AI search engines like ChatGPT, "&lt;br&gt;
Gemini, and Perplexity. Use when the user mentions 'AI visibility', &lt;/p&gt;

&lt;h2&gt;
  
  
  'GEO', 'AI search', or 'cited by AI'."
&lt;/h2&gt;

&lt;h1&gt;
  
  
  GEO — Generative Engine Optimization
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is GEO?
&lt;/h2&gt;

&lt;p&gt;GEO = optimizing content so AI-powered search engines cite your &lt;br&gt;
brand in generated answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  GEO Scorecard (16 criteria)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Authoritative tone&lt;/td&gt;
&lt;td&gt;Expert language, no hedging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structured data&lt;/td&gt;
&lt;td&gt;Schema markup present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Anti-patterns
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Don't do this&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;td&gt;AI recognizes and skips it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The description field is key — Copilot uses it to decide when to invoke the skill. The body contains the actual knowledge the AI applies.&lt;/p&gt;

&lt;p&gt;How it works in practice&lt;br&gt;
Here's what a real session looks like:&lt;/p&gt;

&lt;p&gt;Me: "Do keyword research for a blog about home espresso machines"&lt;/p&gt;

&lt;p&gt;Copilot (automatically invokes seo-keyword-research):&lt;/p&gt;

&lt;p&gt;Searches the web for related keywords&lt;br&gt;
Classifies intent (informational, commercial, transactional)&lt;br&gt;
Analyzes SERP features&lt;br&gt;
Outputs a structured keyword map with primary/secondary keywords, difficulty estimates, and content type recommendations&lt;br&gt;
Me: "Now write the article and optimize it for AI search"&lt;/p&gt;

&lt;p&gt;Copilot (invokes content-creator + geo-optimization):&lt;/p&gt;

&lt;p&gt;Writes with proper H2/H3 structure&lt;br&gt;
Includes the keyword in the first paragraph&lt;br&gt;
Adds statistics with citations (GEO requirement)&lt;br&gt;
Uses authoritative tone&lt;br&gt;
Ends with a clear conclusion (AI search engines need this)&lt;br&gt;
Generates meta title and description within character limits&lt;br&gt;
Me: "Publish as draft to WordPress"&lt;/p&gt;

&lt;p&gt;Copilot (uses REST API knowledge from seo-strategy):&lt;/p&gt;

&lt;p&gt;Creates the post via wp-json/wp/v2/posts&lt;br&gt;
Sets Yoast SEO meta fields&lt;br&gt;
Outputs the draft URL&lt;br&gt;
Total time: ~15 minutes. From zero to published draft with SEO metadata.&lt;/p&gt;

&lt;p&gt;The GEO angle: why AI search changes everything&lt;br&gt;
Here's something most developers don't think about: when someone asks ChatGPT "what's the best espresso machine for beginners?", the answer comes from somewhere. That somewhere could be your website — but only if your content is structured in a way AI models can parse and trust.&lt;/p&gt;

&lt;p&gt;This is called Generative Engine Optimization (GEO). It's like SEO, but for AI search engines. The research (Aggarwal et al., 2024) shows that GEO techniques can boost visibility in AI-generated answers by up to 40%.&lt;/p&gt;

&lt;p&gt;My geo-optimization skill includes:&lt;/p&gt;

&lt;p&gt;A 16-criterion scorecard for AI-readiness&lt;br&gt;
Writing guidelines that balance human readability and AI parseability&lt;br&gt;
Anti-patterns (things that make AI skip your content)&lt;br&gt;
E-E-A-T implementation (Experience, Expertise, Authoritativeness, Trust)&lt;br&gt;
What I learned building these skills&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Skills need evidence, not opinions
AI assistants hallucinate. If your skill says "meta descriptions should be 155 characters" without a source, Copilot might second-guess it or contradict itself later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I added a sources file with links to Moz, Ahrefs, Google Search Central, and peer-reviewed papers. This makes the skill more reliable and more trustworthy for users.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The description field is your trigger
Copilot decides which skill to invoke based on the description in the YAML frontmatter. Be specific about trigger words:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;description: "Use when the user mentions 'SEO', 'search engine &lt;br&gt;
optimization', 'Google rankings', 'rank higher', 'meta tags'..."&lt;br&gt;
The more trigger phrases you include, the more reliably it activates.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Structure &amp;gt; prose&lt;br&gt;
Tables, bullet lists, and clear headings work better than long paragraphs. The AI parses structured content faster and applies it more consistently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Skills should reference each other&lt;br&gt;
My skills cross-link: the SEO strategy skill says "for keyword research, see seo-keyword-research". This helps Copilot chain skills together in multi-step workflows.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Installation (30 seconds)&lt;br&gt;
git clone &lt;a href="https://github.com/WilcoRakhorst/helder-ai-marketing-skills.git" rel="noopener noreferrer"&gt;https://github.com/WilcoRakhorst/helder-ai-marketing-skills.git&lt;/a&gt;&lt;br&gt;
That's it. Open VS Code with Copilot agent mode, and start asking marketing questions. Copilot auto-discovers the skills.&lt;/p&gt;

&lt;p&gt;Or as a Git submodule (stays updatable):&lt;/p&gt;

&lt;p&gt;git submodule add &lt;a href="https://github.com/WilcoRakhorst/helder-ai-marketing-skills.git" rel="noopener noreferrer"&gt;https://github.com/WilcoRakhorst/helder-ai-marketing-skills.git&lt;/a&gt; .github/skills/marketing&lt;br&gt;
Build your own skills&lt;br&gt;
The pattern works for any domain knowledge:&lt;/p&gt;

&lt;p&gt;Create a SKILL.md in .github/skills/your-skill/&lt;br&gt;
Add YAML frontmatter with name and description (include trigger words)&lt;br&gt;
Write structured knowledge — tables, checklists, decision trees&lt;br&gt;
Add references for any factual claims&lt;br&gt;
Test it — ask Copilot questions in the skill's domain and see if it gets invoked&lt;br&gt;
Domains that would benefit from this approach:&lt;/p&gt;

&lt;p&gt;Accessibility (WCAG guidelines as a skill)&lt;br&gt;
Security (OWASP Top 10 as actionable checklists)&lt;br&gt;
API design (REST/GraphQL conventions)&lt;br&gt;
Legal/compliance (GDPR, cookie consent rules)&lt;br&gt;
Brand guidelines (tone of voice, terminology)&lt;br&gt;
The repo&lt;br&gt;
GitHub: helder-ai/marketing-skills&lt;/p&gt;

&lt;p&gt;Licensed CC BY-NC 4.0 — free to use, adapt, and learn from.&lt;/p&gt;

&lt;p&gt;If you find it useful: ⭐ the repo, or open a PR if you have improvements. I'd especially love contributions from SEO practitioners who want to encode their expertise.&lt;/p&gt;

&lt;p&gt;What domain knowledge would you encode as a Copilot skill? Let me know in the comments!&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
