Skip to content
Marketing
Skill

/audience-icp-filter

Filter an existing audience or lead list against your ICP and split it into ready-to-sequence segments. Use when someone already has a list of people — an audience in their sales tool, a CSV or CRM export, event or webinar attendees, registrants, a Sales Navigator import, a

From plugin
gtm-system
3813 skills
Install
$ npx -y skills add LaGrowthMachine/gtm-system --skill audience-icp-filter --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/audience-icp-filter

Context preview

The summary Claude sees to decide when to auto-load this skill.

Filter an existing audience or lead list against your ICP and split it into ready-to-sequence segments. Use when someone already has a list of people — an audience in their sales tool, a CSV or CRM export, event or webinar attendees, registrants, a Sales Navigator import, a

SKILL.md

audience-icp-filter.SKILL.md
name: audience-icp-filter
description: "Filter an existing audience or lead list against your ICP and split it into ready-to-sequence segments. Use when someone already has a list of people — an audience in their sales tool, a CSV or CRM export, event or webinar attendees, registrants, a Sales Navigator import, a newsletter or community export — and wants to know who is worth contacting. Triggers on: 'filter this audience against my ICP', 'who in this list matches my ICP', 'clean up this lead list', 'score these leads', 'qualify my signups', 'segment this audience', 'is my audience on-ICP', 'filter my webinar attendees', 'split this audience by ICP fit', 'remove the bad leads'. For SDRs, BDRs, RevOps, growth, demand gen and founders doing list qualification, ICP refinement, post-event follow-up or audience cleanup. Checks whether the data can support the ICP before filtering, sorts every lead into ICP match / needs review / no match, strips out your own team and competitors, and never silently drops anyone. Maintained by La Growth Machine."
category: fuel-my-pipeline
type: use-case
tags: [analysis, building]

Audience ICP Filter

Takes an audience that already exists and splits it into **ICP match**, **needs review** and **no match** — with the user's own team and competitors stripped out, and a reason attached to every decision.

Authority — read this first

  • **Inlined below:** the coverage gate, the ICP question set, the seniority and function tiers, the exclusion doctrine, the two-pass rule, the naming convention, the anti-patterns, and the **fixed result UI**. This covers the common ~90% of lists. Work from these tables.
  • **In `references/title-taxonomy.json`:** the full regex patterns behind seniority/function detection. **You do not need to read it** — `scripts/build.py` loads it. Consult it only if a user disputes a classification or wants to extend the taxonomy.
  • **Never classify a list by hand.** Run the script, then run your own review pass over its output. Both passes are mandatory.

Scope

This skill starts from a list that **already exists**: an audience in the user's sales tool, or a CSV. It does not import or scrape — importing is a separate job with its own timing and prerequisites, and folding it in here would make the skill slower and less reliable for no gain.

If the user hasn't imported yet, tell them to do that first, then come back with the audience.

What it does

Any audience is mostly noise: the user's own colleagues are in it, competitors are watching, and a third of the job titles are unreadable. This skill checks whether the data can support the ICP the user wants, asks what that ICP actually is, sorts the list, and writes the segments back as complementary audiences.

Execution style — fast and quiet

This skill does a lot of steps. Two rules keep it usable:

  • **Minimal narration.** Do the reasoning and the tool calls, but do **not** narrate each step to the user ("page 1 loaded", "the param is skip not offset", "wrapping the payload"…). The user wants the *result*, not a play-by-play. Stay silent through the pipeline and speak only when you present the widgets — one or two sentences of framing, no more. Think as hard as you like; just don't type it out.
  • **Parallelize and batch.** Fetch the lead pages **concurrently** (issue the `get_audience_leads` calls for all pages in one batch). Keep only the scored fields when you normalise (`leadId, jobTitle, companyName, proEmail, shortBio, location, industry`) — not all 40 columns — so the payloads stay small.
  • **Never re-read the whole audience in pass 2.** This was the measured bottleneck: reviewing 250 leads one by one took 8 minutes. Pass 1 hands you a bounded `pass2_queue` — only the genuinely suspect leads (ambiguous, bio-inferred matches, agency/freelance matches, and leads dropped on a soft geo/industry miss). **Pass 2 reviews only that queue**, typically a few dozen. If the queue is still large (60+), fan it out: a couple of parallel sub-agents on **Sonnet** splitting the queue, reserving deeper reasoning only for the final ambiguous handful. A clean, on-target audience produces a queue of ~15–25; a full re-read is never needed.

Workflow

**Step 0 — Load the list.** From an LGM audience (`list_audiences` → `get_audience_leads`) or a CSV. **Pagination: the parameter is `skip` (not `offset`), 100 max per page** — so page 2 is `skip:100`, page 3 `skip:200`. Read `total` from the first page and fire the remaining pages **in one concurrent batch**. Normalise to one object per person: `leadId` (or `firstname`+`lastname`), `jobTitle`, `companyName`, `proEmail`, plus `shortBio`, `location`, `industry` when present.

**Step 1 — Coverage gate. Run this before asking about the ICP.**

python3 scripts/build.py --coverage leads.json

It reports fill rates and names which criteria the data cannot support. There is no point offering geography filtering on an audience where `location` is empty — that just routes everyone to `review` and calls it a result. See *The coverage gate* below.

**Step 2 — ICP Q&A**, informed by step 1. Don't offer criteria the data can't support without saying enrichment is needed first.

**Step 3 — Pass 1, deterministic:**

python3 scripts/build.py spec.json > pass1.json

It refuses invalid input rather than emitting a best-effort sort. If it errors, fix the spec — never work around it by classifying manually.

**Step 4 — Pass 2, semantic. Mandatory — but bounded.** Pass 1's output carries a `pass2_queue`: the only leads worth a human/LLM look. **Review that queue, not the whole audience** (see *The pass-2 queue* below). Each queued lead has a `_flag` telling you why it's there. Resolve each into `match` or `no_match`, write the overrides with reasons, then re-validate:

python3 scripts/build.py --adjudicate review.json

**Step 5 — Present** the single result artifact (coverage + segmentation + the state-driven action zone). If a res

Read more
Ships withgtm-system

The open-source GTM toolkit for Claude: skills and an MCP server to run outbound from the chat.

Get the whole plugin

Other skills on gtm-system.