> Lead qualification engine with conversational intake. Asks structured questions to understand your qualification criteria, generates a reusable qualification prompt, then batch-enriches leads via Apify LinkedIn scraping and scores them with parallel processing. Outputs qualified/disqualified verdicts with confidence scores and reasoning to CSV or whatever output format the user prefers. Supports calibration mode for prompt refinement.
npx skills add https://github.com/gooseworks-ai/goose-skills --skill lead-qualification
Qualify leads against custom criteria through a structured intake process, then score lead lists in parallel with confidence ratings and reasoning.
No existing qualification prompt. Run intake to build one, save it, then qualify leads.
Trigger: User provides no qualification prompt file.
User references an existing qualification prompt file — skip intake, go straight to scoring.
Trigger: User tags or references a file in skills/lead-qualification/qualification-prompts/.
User has seen results and wants to adjust criteria. Update the saved prompt, re-run.
Trigger: User says something like "refine", "adjust", "that's wrong", or provides feedback on qualification results.
The goal is to build a complete picture of who the user considers qualified vs disqualified. Present questions in bulk rounds so the user can answer efficiently.
Present these questions as a numbered list. Tell the user: *"Answer what's relevant, skip what's not. I'll follow up on anything I need to clarify."*
Product & Campaign Context:
Company-Level Criteria:
10. Any revenue range or funding range that matters?
Person-Level Criteria:
11. What job titles or roles are your ideal buyers?
12. What titles are explicitly disqualified?
13. Does seniority level matter? (e.g., must be Director+, VP+, C-level)
14. What departments should they be in? (e.g., growth, marketing, sales, engineering)
15. Minimum tenure at current company? (e.g., 6+ months to have buying power)
16. Does total years of experience matter?
Behavioral & Situational Signals:
17. Are there tech stack signals that qualify or disqualify? (e.g., "uses Salesforce" = good fit)
18. Does recent company activity matter? (e.g., hiring spree, funding round, product launch)
19. Are there content/posting signals? (e.g., "posted about AI" = relevant)
20. Any other signals that indicate high intent or good fit?
Dealbreakers & Instant Qualifiers:
21. What are your HARD DISQUALIFIERS — things that instantly make someone a "no" regardless of other factors?
22. What are your STRONGEST QUALIFIERS — things that make someone an almost certain "yes"?
Based on the user's answers, ask 5-10 targeted follow-ups to resolve ambiguity. Examples:
Present 3-5 hypothetical lead profiles that test boundary cases. Ask "Would you qualify this person?"
Example scenarios to construct (adapt based on the user's criteria):
This round catches implicit criteria the user hasn't articulated.
After intake is complete, synthesize all answers into a structured qualification prompt. Save it to:
skills/lead-qualification/qualification-prompts/[campaign-name].md
The saved prompt MUST follow this structure:
# Qualification Prompt: [Campaign Name]
Generated: [date]
## Campaign Context
- **Product:** [one-liner]
- **Campaign Angle:** [specific angle]
- **Problem Solved:** [what and for whom]
## Hard Disqualifiers (Instant No)
- [list each with explanation]
## Hard Qualifiers (Instant Yes)
- [list each with explanation]
## Company Criteria
| Criterion | Qualified | Disqualified | Notes |
|-----------|-----------|--------------|-------|
| Size | [range] | [range] | |
| Industry | [list] | [list] | |
| Geography | [list] | [list] | |
| Stage | [list] | [list] | |
| Funding/Revenue | [range] | [range] | |
## Person Criteria
| Criterion | Qualified | Disqualified | Notes |
|-----------|-----------|--------------|-------|
| Titles | [list] | [list] | |
| Seniority | [level+] | [below level] | |
| Department | [list] | [list] | |
| Tenure | [minimum] | [below minimum] | |
| Experience | [range] | [range] | |
## Behavioral & Situational Signals
- [list signals that boost qualification]
- [list signals that reduce qualification]
## Confidence Rules
- **High Confidence:** Enough data available for company size, title, tenure, and at least one signal.
- **Medium Confidence:** Missing one or two non-critical data points but core criteria are clear.
- **Low Confidence:** Missing critical data points (e.g., no company size, unclear title). Still make a yes/no call but flag it.
## Edge Case Guidance
- [specific guidance derived from Round 3 scenarios]
- [any nuanced rules from the intake conversation]
## Qualification Reasoning Instructions
When evaluating a lead, structure your reasoning as:
1. Check hard disqualifiers first — if any match, immediately disqualify.
2. Check hard qualifiers — if any match, lean strongly toward qualifying.
3. Evaluate company criteria against thresholds.
4. Evaluate person criteria against thresholds.
5. Factor in behavioral/situational signals as tiebreakers.
6. Assign confidence based on data completeness.
7. Write 2-3 sentence reasoning summarizing the decision.
Accept any of these input formats:
Detect the format automatically based on what the user provides.
When: The input contains a linkedin_url column (or LinkedIn URLs are available).
Skip when: No LinkedIn URLs are present, or the user explicitly says to skip enrichment.
Before LLM qualification, batch-enrich all leads to gather structured profile data. This is MUCH faster and cheaper than per-lead web searches during qualification.
Run the enrichment script:
python3 skills/lead-qualification/scripts/enrich_leads.py INPUT_CSV \
--output ENRICHED_CSV \
--cache-hours 24
Use --dry-run first to show the cost estimate without calling Apify.
What this does:
enriched_title, enriched_company, enriched_industry, enriched_location, enriched_connections, enriched_education, enriched_experience_years, enriched_headline, enriched_about, enrichment_statusAfter enrichment, use the enriched CSV as input for Steps 2-4. The enriched data lets the LLM qualification step work from structured fields instead of doing web searches, dramatically improving speed and consistency.
If enrichment fails for some profiles: They'll have enrichment_status: failed in the output. The LLM qualification step should fall back to web search for those leads only.
Before processing the full list, run the first 5-10 leads and present results to the user in a table.
If batch enrichment was run (Step 1.5), use the enriched columns (enriched_title, enriched_company, etc.) as the primary data source. Only fall back to web search for leads where enrichment_status is failed or no_url.
| # | Name | Title | Company | Qualified | Confidence | Reasoning |
|---|------|-------|---------|-----------|------------|-----------|
| 1 | ... | ... | ... | Yes | High | ... |
| 2 | ... | ... | ... | No | Medium | ... |
| ... |
Ask: "Do these look right? Should I adjust any criteria before processing the full list?"
If the user flags issues:
Repeat until the user approves.
Once calibration is approved, process ALL remaining leads using parallel subagents. You MUST parallelize — do NOT process leads sequentially.
Parallelization protocol (mandatory):
For each batch, create a self-contained context package:
qualification-prompts/ file)enrichment_status=failed or no_url, do a quick web search. Spend no more than 30 seconds per lead on search."Use the Task tool to launch ALL batches simultaneously in a single message with multiple tool calls:
Task: "Qualify leads batch 1/N"
Context: [qualification prompt] + [batch 1 lead rows]
Task: "Qualify leads batch 2/N"
Context: [qualification prompt] + [batch 2 lead rows]
... (launch ALL at once — do NOT wait for batch 1 before launching batch 2)
Per-lead processing (within each batch agent):
enrichment_status: success or cached): use enriched_title, enriched_company, etc.enrichment_status: failed or no_url): do a quick web search (max 30 seconds)Default: CSV
Qualified — Yes / NoConfidence — High / Medium / LowReasoning — 2-3 sentence explanationIf the user prefers Google Sheets or another destination:
After output is complete, present a summary:
## Qualification Results: [Campaign Name]
**Total leads processed:** X
**Qualified:** X (Y%)
**Disqualified:** X (Y%)
**Confidence breakdown:**
- High: X leads
- Medium: X leads
- Low: X leads (may need manual review)
**Top disqualification reasons:**
1. [reason] — X leads
2. [reason] — X leads
3. [reason] — X leads
**Output:** [Google Sheet link or CSV path]
**Qualification prompt saved to:** skills/lead-qualification/qualification-prompts/[campaign-name].md
The qualification agent should have access to:
scripts/enrich_leads.py for batch profile enrichment before qualificationharvestapi~linkedin-profile-scraper Apify actor ($3/1k profiles, no cookies)APIFY_API_TOKEN environment variable--dry-run first to preview costQualify leads for our outbound campaign. Here's the lead list: leads.csv
→ Agent detects no saved prompt, starts intake, builds prompt, then qualifies.
Qualify these leads using @skills/lead-qualification/qualification-prompts/series-a-founders.md
— lead list: leads.csv
→ Agent skips intake, goes straight to calibration + qualification.
Using the series-a-founders qualification prompt, qualify these people:
- https://linkedin.com/in/person1
- https://linkedin.com/in/person2
- https://linkedin.com/in/person3
Those results look off — also disqualify anyone at a consulting firm, and lower the
tenure minimum to 3 months for Director+ titles.
→ Agent updates the saved prompt and re-runs.
Scrapes content based on a preset URL list, filters high-quality technical information, and generates daily Markdown reports.
Scrapes content based on a preset URL list, filters high-quality technical information, and generates daily Markdown reports.
Scrapes posts from any public Facebook Page timeline, returning structured data including post text, author info, engagement metrics (likes/comments/shares), reaction breakdowns (like/love/haha/wow/sad/angry/care), hashtags and external links, and media type. Use when user wants to scrape Facebook posts, extract Facebook page content, get Facebook post data, collect Facebook engagement stats, download Facebook posts, monitor a Facebook page, crawl Facebook timeline, get Facebook reactions, get like count/comment count/share count from Facebook, Facebook post bulk export, Facebook social media analytics. Supports date range filtering (afterTime/beforeTime) and cursor-based pagination for bulk collection.
Scrapes posts from any public Facebook Page or personal Profile timeline, returning structured data including post text, author info with profile picture, engagement metrics (likes/comments/shares), full reaction breakdown (Like/Love/Wow/Haha/Sad/Angry/Care as both array and flat counts), hashtags and external links, media assets with full thumbnail URLs and dimensions, page ad library status, and collaborators. Use when user wants to scrape Facebook posts, extract Facebook page content, get Facebook post data, collect Facebook engagement stats, download Facebook posts, monitor a Facebook page, crawl Facebook timeline, get Facebook reactions, get like count comment count share count from Facebook, Facebook post bulk export, Facebook social media analytics, get profile picture, get page ad library status, fetch Facebook collaborators. Supports date range filtering (afterTime/beforeTime) and cursor-based pagination for bulk collection.
Fetches public posts from a Threads user's profile page, extracting post text, engagement metrics, and media info from SSR-embedded JSON. Use when user asks to scrape Threads posts, get someone's Threads feed, pull posts from a Threads account, collect Threads content by username, download Threads user posts, extract Threads profile posts, monitor a Threads user's activity, retrieve recent posts from a Threads handle, gather Threads post data for a creator, or fetch all posts from a specific Threads profile.
Analyze Google Maps review data from CSV exports. Sentiment analysis, trend detection, competitor review comparison, and reputation insights — no API key needed.
微信公众号文章抓取与导出。自动处理 mp.weixin.qq.com 的登录态获取与续期, 支持按公众号搜索、抓取文章列表与正文、按日期窗口导出 Markdown / JSON / CSV。 Trigger when the user wants to crawl a WeChat public account, export recent articles, or 提到 "wcx"、"微信公众号"、"公众号文章"、"mp.weixin"、"抓公众号"、 "crawl wechat official account"、"wxmp"、"最近十天的文章"。
| web-data agents, scrapes into Delta tables, and produces an AI/BI dashboard and/or a deployed Databricks App — a table → dashboard → app workflow, for production data products or quick demos. Use whenever a request pairs live or scraped web data WITH a Databricks destination — e.g. "scrape Amazon/Walmart prices into a Delta table and build a dashboard", "load Zillow/Instagram/Maps/search results into Databricks and build a dashboard or app", "showcase Nimble + Databricks to a prospect". Prefer it over nimble-web-expert or competitor-intel when the data lands in Databricks. Do NOT use for one-off web fetches or CSV exports with no Databricks destination — use nimble-web-expert instead. Do NOT use for competitor or company research briefings — use competitor-intel or company-deep-dive instead. Do NOT use for generic Databricks work with no Nimble/web-data angle — use the official databricks-* skills instead.
Take gooseworks-ai/lead-qualification from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.