mcpField
C
candidate-sourcing

candidate-sourcing

github.com/crustdata其他11611 次安装2 周前更新
代码仓库

关于 candidate-sourcing

Candidate Sourcing Pipeline 是一项技能,可根据招聘需求为候选人生成 Gmail 草稿。它依次完成候选人发现、个人资料链接核验、邮箱查找和个性化联系内容撰写,最终由人工审核并发送。

主要功能

  1. 01明确招聘需求和候选人条件
  2. 02按技术成果寻找候选人
  3. 03通过搜索核验个人资料链接
  4. 04查找商务或个人邮箱
  5. 05创建个性化 Gmail 草稿

适用场景

  1. 01为明确的岗位搜寻候选人
  2. 02联系前核验候选人资料
  3. 03准备供审核的定制招聘邮件

MCP 相关

该技能通过 Code Mode `execute` 使用 Crustdata MCP 工具,包括 `person_search`、`person_enrich` 和 `web_search_live`,用于发现候选人、核验资料和补充联系信息。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/crustdata/skills --skill candidate-sourcing

安装后在 Claude Code 中输入/candidate-sourcing确认已加载。

附带文件evals/evals.jsonREADME.md

详细介绍

候选人寻访流程

一项端到端技能:输入招聘岗位,为优秀候选人生成可直接发送的 Gmail 草稿——在一个连续工作流中完成候选人发现、个人资料 URL 验证、邮箱信息补全、个性化文案撰写和草稿创建。

该流程分为五个阶段。每个阶段的结果都会传递给下一个阶段;此技能旨在按顺序执行这些阶段,尽可能减少人工干预。用户审核最终的 Gmail 草稿并点击发送。


阶段 1:定义搜索条件并寻找候选人

确认岗位和公司信息

搜索之前,先从用户处提取或确认以下信息。不要自行假设任何信息——如果用户未提供,务必询问:

招聘公司信息(阶段 4 外联时需要):

  • 公司名称
  • 公司业务(1–2 句话)
  • 公司发展阶段/业绩表现(例如,“A 轮融资,融资额达 $10M”或“拥有 500 名员工的上市公司”)
  • 地点/远程办公政策
  • 发件人的姓名和职位(用于邮件签名)

岗位和理想候选人信息:

  • 岗位名称(例如,“创始团队机器学习工程师”)
  • 岗位涉及的 2–3 个核心技术问题
  • 目标公司、研究实验室或要搜索的社区
  • 优先考虑的学校/校友关系(例如,“IIIT Hyderabad 校友”)
  • 地点偏好或限制
  • 用户希望本批次包含多少名候选人

理想候选人画像:

  • 职级(例如,“3–7 年经验”、“高级”、“Staff 及以上”)
  • 必备技术技能或领域专业知识
  • 加分项(开源贡献、发表论文、特定框架)
  • 排除条件或筛选标准(例如,“不考虑长期在 FAANG 工作的人”、“必须有初创公司经验”)

利用公司和岗位信息,调查这家公司对候选人的吸引力所在——通过 Crustdata MCP 的 web_search_live 工具查看公司网站、近期融资、产品发布或媒体报道。这项调查将为阶段 4 的公司简介提供信息。

根据技术成果搜索,而非职位名称

以下三项信号比工作年限或公司声望更重要:

工作成果——他们撰写的论文、实际有人使用的工具/代码仓库、具有技术深度的博客文章、开源贡献、发布的演示或基准测试。

进取心——公开发表的技术观点、博客文章和新闻通讯、会议演讲、被他人引用,以及持续参与开源项目,而不只是提交代码。

相关性——他们的具体工作与岗位中的实际问题相对应,而不只是涉及相邻领域。

搜索来源和模式

Crustdata person_search(通过 Code Mode 的 execute 工具)进行结构化搜索:

// model query: find ML engineers at Company Name
const r = await callTool("person_search", {
  filters: { op: "and", conditions: [
    { field: "experience.employment_details.current.title", type: "(.)", value: "ML Engineer" },
    { field: "experience.employment_details.current.company_name", type: "[.]", value: "Company Name" },
  ]},
  limit: 20,
});
if (!r.ok) return { error: r.message };
return r.data.profiles.map(p => ({
  name: p.basic_profile?.name,
  title: p.basic_profile?.current_title,
  url: p.social_handles?.professional_network_identifier?.profile_url,
}));

研究论文——围绕核心技术问题搜索学术论文和预印本。关注第一作者和第二作者,尤其是那些不在顶尖 5 家实验室的人。

开源代码仓库——按主题/关键词搜索代码仓库,关注有实质贡献的参与者(而不只是维护者)。

Crustdata 网页搜索(web_search_live)——"[technical problem]" site:arxiv.org、"[name]" "[company]" github、"[community]" alumni engineer ML。

阶段 1 的输出

候选人名单,每位候选人包含:全名、当前职位、当前公司、学校/社区关联信息,以及一项体现其相关性的具体工作成果(论文、代码仓库、工具或帖子)。这条“工作成果”备注至关重要——它将成为阶段 4 外联邮件开场白的依据。


阶段 2:验证个人资料 URL

绝不要猜测或拼接个人资料 URL。 这是外联中最常见的错误来源。猜测的 URL(例如 firstname-lastname 或 firstname-lastname-school)经常返回 404,或指向错误的人。真实的 slug(即 linkedin.com/in/ 后面的部分)由系统自动生成,形式类似 david-park-086833264 或 hongjunchoi92——无法根据一个人的姓名推测。

瀑布式流程

严格按照以下优先级顺序操作。获得有把握的匹配后立即停止。

步骤 1:person_search(始终首先尝试)

// model query: verify the profile URL for Person Name at Company Name
const r = await callTool("person_search", {
  filters: { op: "and", conditions: [
    { field: "basic_profile.name", type: "[.]", value: "Person Name" },
    { field: "experience.employment_details.current.company_name", type: "[.]", value: "Company Name" },
  ]},
  limit: 3,
});
if (!r.ok) return { error: r.message };
return r.data.profiles.map(p => ({
  name: p.basic_profile?.name,
  headline: p.basic_profile?.headline,
  url: p.social_handles?.professional_network_identifier?.profile_url,
}));

提取 social_handles.professional_network_identifier.profile_url — 这是经过验证的规范个人资料 URL。

提示:

  • 公司名称可能有不同写法(“Google DeepMind” 与 “DeepMind” 与 “Google”)— 先尝试较短的名称,再尝试其他写法
  • 如果结果为 0,尝试过往雇主(experience.employment_details.past.company_name),或使用姓名并扩大筛选范围
  • 如果有多个结果,请根据头衔、所在地或教育经历进行匹配
  • 为提高效率,将这些操作作为单个 execute 脚本运行:使用 parallelMap 并行执行独立查询(先对候选列表分批,再进行映射)

步骤 2:web_search_live(步骤 1 返回 0 条结果时的备用方案)

// model query: find the profile URL for Person Name at Company
const r = await callTool("web_search_live", {
  query: "Person Name Company distinctive-keyword",
  site: "linkedin.com",
});
if (!r.ok) return { error: r.message };
return r.data.results;

查看摘要,核对雇主和职位是否匹配,以验证结果。不要直接使用第一个个人资料 URL。

步骤 3:标记为未经验证(两种方法均失败时)

保留现有 URL(如有),但添加备注:“LinkedIn URL unverified.” 切勿捏造 URL。

Slug 对比

验证现有 URL 时,提取 slug(linkedin.com/in/ 后面的部分),去除末尾斜杠,并忽略大小写进行比较。Slug 不同表示 URL 错误,请改用 social_handles.professional_network_identifier.profile_url 中经过验证的 URL。

此流程可避免的真实错误

以下是生产推广活动中出现过的实际错误:

猜测的 slug实际 slug结果
david-park-princetondavid-park-086833264404 — slug 是编造的
vincent-chen-mitvincent-chen-662a031b5404 — 学校后缀无效
benoit-rostykusbenoitrostykus找错人 — 是另一个人的个人资料
hongjun-choihongjunchoi92找错人 — 是另一个人的个人资料
abhay-gupta-cmugupta-abhay找错人 — slug 格式完全不同
benedict-arockiarajbenedictflorance找错人 — 此人在 LinkedIn 上使用了不同的姓名
initeshmethaninitesh-methani-7554b3121找错人 — 猜测的 slug 中有拼写错误
URL 格式

始终使用 https://www.linkedin.com/in/{slug} — 不要使用缺少协议的裸 linkedin.com/in/。像 ü 这样的字符需要进行 URL 编码(%C3%BC)。


第 3 阶段:查找电子邮件地址

每位候选人都需要一个电子邮件地址,用于 Gmail 草稿。请按以下优先顺序查找。

3A:通过 Crustdata 补充获取工作邮箱

使用 person_enrich(通过 Code Mode execute 工具)。该工具在 professional_network_profile_urls 中接受 LinkedIn URL 数组(每次调用 ≤25 个 — 使用 chunk(urls, 25) 分块,然后通过 parallelMap 并行处理),并在 fields 中接受字段组(而非叶子字段名)。contact 组会返回电子邮件和电话号码:

// model query: enrich business emails for a batch of candidate LinkedIn URLs
const urls = ["url1", "url2", "url3"]; // from Phase 2
const batches = chunk(urls, 25);
const results = await parallelMap(batches, async (batch) => {
  const r = await callTool("person_enrich", {
    professional_network_profile_urls: batch,
    fields: ["basic_profile", "contact"],
  });
  return r.ok ? r.data : [];
});
// each match: matches[0].person_data.contact.business_emails[].email
return results.flat();

contact 字段组至关重要 — 默认响应(仅包含 basic_profile)不包含电子邮件。请通过 matched_on 将每条结果映射回对应的输入 URL。

**预期命中率:**知名公司的专业人士约为 70-80%,独立从业者约为 40-50%,处于职业过渡期的人士约为 20-30%。

3B:通过 Crustdata 联系人丰富获取个人邮箱

如果只需要联系人数据,出于成本考虑,优先使用 person_contact_enrich,而不是 person_enrich。 person_enrich 可以通过其 contact 组返回个人邮箱(+2)和电话(+2),但也会收取基础资料费用(基础 1 + 联系人层级费用,封顶 7)。person_contact_enrich 是仅处理联系人的工具——它不收取基础资料费用(封顶 5),因此只需要联系人数据时更便宜。在回退到提交记录查询(3C)之前,请先尝试此工具。

person_contact_enrich 接受相同的 professional_network_profile_urls 数组(每次调用 ≤25 个),并返回一个包含 business_emails、personal_emails 和 phone_numbers 的 contact 对象。通过带点号的 fields 选择层级:

// model query: enrich personal emails + phone for candidate LinkedIn URLs
const r = await callTool("person_contact_enrich", {
  professional_network_profile_urls: chunk(urls, 25)[0],
  fields: ["contact.personal_emails", "contact.phone_numbers"],
});
if (!r.ok) return { error: r.message };
// per match: matches[0].person_data.contact.personal_emails[].email (objects), .phone_numbers[] (bare strings)
return r.data;

响应中的 person_data.contact 对象包含一个 personal_emails 对象数组({ email, status } — 读取 .email,与 business_emails 相同;包括 Gmail、ProtonMail 等)和一个由纯字符串构成的 phone_numbers 数组。

积分费用: person_contact_enrich 不收取基础费用,按联系人层级计价——大致为 +1 个商务邮箱、+2 个个人邮箱、+2 个电话号码,每个档案最高 5 积分。这些单项层级数值是边际费用/上限估算,并非保证的封顶费用:请求单个带点号的层级并不能可靠地将账单限制在该层级的增量内——据观察,fields: ["contact.personal_emails"] 调用会按完整的 5 积分封顶费用计费,并返回全部三个层级。由于省去了基础资料费用,获取联系人数据时它仍比 person_enrich 便宜,但不要假设单个带点号的字段会将费用限制在封顶值以下。

批次限制: 每次调用最多 25 个 LinkedIn URL。

推荐做法: person_contact_enrich 一次调用即可返回商务邮箱、个人邮箱和电话——同时请求所需层级,以减少往返调用。person_enrich(阶段 3A)也可以通过其 contact 组返回全部三个联系人层级,但它会额外收取基础资料费用,因此只需要联系人数据时优先使用 person_contact_enrich。

如果找到了个人邮箱,冷邮件联系时优先使用个人邮箱,而非商务邮箱(回复率更高,也不太容易被企业垃圾邮件过滤器拦截)。如果此工具未能为候选人找到个人邮箱,请继续使用下面的提交记录查询。

3C:通过公开提交历史获取个人邮箱(3B 无结果时的后备方案)

这是针对技术候选人最有力的技巧。Git 会在每次提交中记录作者的邮箱。

步骤 1:查找 GitHub 用户名

  • 优先使用原生方式:在 fields 中使用 social_handles 调用 person_enrich,可返回 dev_platform_identifier(开发者账号);添加 dev_platform_profiles(开发者附加项,+1 积分)则可返回完整的开发者档案——仓库、组织成员身份,有时还包括公开的 email。如果该 email 存在且不是 noreply 地址,就使用它并直接跳到步骤 5
  • 对已解析的人员调用 dev_platform_enrich({ crustdata_person_id }),可独立获取相同信息
  • 网页搜索:"[Name] [Company] GitHub site:github.com"
  • 查看其个人网站或社交资料简介

步骤 2:确认 GitHub 档案属于此人 以下条件至少确认 2 项:简介提及已知公司/职位、档案名称匹配、仓库主题与已知专业领域一致、网页搜索确认两者关联。

步骤 3:查找最早的非派生仓库

如果步骤 1 执行了开发者丰富查询,其 dev_platform_profiles[].repos 条目已包含 full_name、is_fork 和 github_created_at——直接选择最早的非派生仓库,无需额外调用。否则,通过 GitHub API 列出仓库:

// model query: list oldest repos for GitHub user {username}
const r = await callTool("web_enrich_live", {
  urls: ["https://api.github.com/users/{username}/repos?sort=created&direction=asc&per_page=5"],
});
if (!r.ok) return { error: r.message };
return r.data; // [{ success, url, title, content }]

选择第一个 "fork": false 的仓库。

步骤 4:从提交中提取邮箱

方法 A — Commits API:

// model query: read first commit of {owner}/{repo}
const r = await callTool("web_enrich_live", {
  urls: ["https://api.github.com/repos/{owner}/{repo}/commits?per_page=1"],
});

在获取的 content 中查找 [0].commit.author.email。

方法 B — .patch 端点:

// model query: read commit patch for {owner}/{repo}@{sha}
const r = await callTool("web_enrich_live", {
  urls: ["https://github.com/{owner}/{repo}/commit/{sha}.patch"],
});

从获取的 content 中提取 From: Name <email> 标头行。

步骤 5:验证 — 丢弃 *@users.noreply.github.com、[email protected],以及任何包含 noreply 的邮箱。

3D:网页搜索备选方案

如果 Crustdata 个人邮箱补全和提交记录查找都不起作用,请按以下顺序尝试:

  1. 代码仓库(问题、README):"[name]" "@gmail.com" site:github.com
  2. 竞赛编程:"[name]" site:codeforces.com
  3. 个人网站:"[name]" "[company]" email contact
  4. 会议演讲者页面:"[name]" "[company]" speaker email
  5. 学术档案:"[name]" site:scholar.google.com
3E:GitHub API 速率限制

GitHub REST API 有速率限制。如果请求返回速率限制消息(“API rate limit exceeded”),请停止本批次剩余候选人的提交记录查找。将这些候选人转到 3D,或将其记录为 no_contact,在限制重置前不要重试。

邮箱优先级

如果某位候选人有多个邮箱,请按以下顺序优先选择:

  1. 个人 Gmail/ProtonMail——冷启动外联的回复率最高
  2. 大学邮箱——如果他们仍在学术界
  3. 工作邮箱——冷启动外联的最后选择(通常会被企业垃圾邮件过滤器拦截)

第 4 阶段:撰写个性化外联邮件

唯一重要的规则

赞扬具体作品,而不是职位或暗示的能力。

“在 Mistral 领导应用科学工作,说明你知道如何将机器学习从研究推向生产”读起来就像是“我看了你的 LinkedIn 职位,然后套用了模板”。相反,要找到他们实际做过的一件事,并真诚地谈谈。

邮件结构

每封邮件都遵循以下固定模板:

Hi {first_name},

[1-sentence opener: say what impressed you — casual, no analysis]

[1-sentence pitch: role + company + location]

[3-line company blurb]

{sender_name},
{sender_title}

简短即可。不要加标题、项目符号或多段解释。如果用户尚未提供,请向用户询问姓名、职位、公司名称,以及 2-3 行的公司简介。

撰写开场白

使用第 1 阶段的“成果证明”记录——在发现候选人时找到的具体论文、仓库、工具或帖子。

好的开场白示例:

  • “读了你关于[具体论文/项目]的作品——[真诚的感想]。”
  • “你的[具体工具/仓库]很[具体且诚恳的评价]。”
  • “从[具体经历节点 A]到[B]的历程令人印象深刻。”

糟糕的开场白示例(切勿使用):

  • [他们的作品] + [与我们也做 X 相关]——把赞美变成推销
  • [在公司的职位] + [因此具备 X 技能]——依据职位而非作品
  • [他们的研究] + [正是我们需要的思维方式]——替对方评价自己
  • 过长的括号补充说明——破坏轻松自然的行文节奏
推介内容

“我们正在[地点]为[公司]招聘一名[职位]。你有兴趣吗?”

直接明了即可。开场白已经起到了作用。

公司简介

如果用户尚未提供,请向用户索要 2-3 行的公司简介。内容应突出业务进展、使命以及当前时机的重要性。在一批邮件中略微变换措辞,避免邮件完全相同。

主题行

默认:"[Role] @ [Company]"


第 5 阶段:创建 Gmail 草稿并记录到跟踪表

创建 Gmail 草稿

对于每位有已验证邮箱的候选人,使用 gmail_create_draft:

  • to:候选人的邮箱地址
  • subject:主题行
  • body:完整邮件(开场白 + 推介内容 + 公司简介 + 签名)

这是最后一步。Gmail 的 MCP 会创建草稿,但无法发送——用户需要检查后手动点击发送。

记录到外联跟踪表

创建每份草稿后,将一行追加到该职位专用的 CSV 跟踪表:

/sessions/{session}/mnt/outputs/outreach_tracker_{role_slug}.csv

其中,role_slug 为小写并以连字符连接(例如,“Founding ML Engineer” → founding_ml_engineer)。

CSV 标题行:

date,role_hiring_for,candidate_name,current_role,company,school_connection,linkedin_url,email,channel,subject,message_opener,status,notes,message_body
import csv, datetime, os

tracker_path = "outreach_tracker_{role_slug}.csv"
fields = ["date","role_hiring_for","candidate_name","current_role","company",
          "school_connection","linkedin_url","email","channel","subject",
          "message_opener","status","notes","message_body"]

row = {
    "date": datetime.date.today().isoformat(),
    "role_hiring_for": "<role name>",
    "candidate_name": "<full name>",
    "current_role": "<title>",
    "company": "<company>",
    "school_connection": "<school or empty>",
    "linkedin_url": "<verified linkedin url>",
    "email": "<email address>",
    "channel": "email",
    "subject": "<subject line>",
    "message_opener": "<first sentence of email body>",
    "status": "drafted",
    "notes": "<email type + source: e.g. Personal Gmail via commit history>",
    "message_body": "<full email body>"
}

file_exists = os.path.isfile(tracker_path)
with open(tracker_path, "a", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fields)
    if not file_exists:
        writer.writeheader()
    writer.writerow(row)

状态值: drafted(已创建 Gmail 草稿)、sent(用户已点击发送)、replied(已回复)、no_contact(未找到邮箱)。

渠道值: email

没有邮箱的候选人

如果完成整个信息补全流程后仍未找到邮箱,请将候选人记录到跟踪表中,设置 status: "no_contact",并添加说明,解释尝试过哪些方法。用户可以决定是否手动通过其他渠道跟进。

提高效率的批量工作流

处理大量候选人(>5)时,按以下顺序操作以尽量节省时间:

  1. 搜索并收集候选人(第 1 阶段)——先建立完整名单
  2. 批量验证个人资料 URL(第 2 阶段)——在一个 execute 脚本中,使用 parallelMap 并行调用 person_search 查找;失败时回退到网页搜索(web_search_live)
  3. 批量补充邮箱信息(第 3A + 3B 阶段)——先调用 person_enrich(fields: ["basic_profile", "contact"])获取个人资料和工作邮箱,再调用 person_contact_enrich(fields: ["contact.personal_emails", "contact.phone_numbers"])获取个人邮箱和电话号码(仅补充联系方式时成本更低——跳过基础个人资料费用)。每次调用最多批量处理 25 个 LinkedIn URL(chunk(urls, 25),再使用 parallelMap)
  4. 筛选需查找提交记录的候选人(第 3C 阶段)——找出仍缺少邮箱、且作为工程师很可能拥有 GitHub 个人资料的候选人;优先通过提交记录提取邮箱
  5. 批量查找提交记录(第 3C 阶段)——每次调用 web_enrich_live 时传入多个 GitHub URL(urls: [...])
  6. 网页搜索回退(第 3D 阶段)——适用于 Crustdata 信息补充和提交记录查找均失败的候选人
  7. 撰写所有邮件文案(第 4 阶段)——一次性拟好所有开场白,并使用第 1 阶段的工作成果证明记录
  8. 创建所有 Gmail 草稿(第 5 阶段)——创建草稿并记录到跟踪表
处理大型 API 响应

Crustdata 信息补充和 person_search 调用可能会返回大型负载。在 Code Mode 中,应在 execute 脚本内部缩减响应后再返回——只有 return 的内容才会传递给模型。使用 project/pick/compact 仅保留所需字段,以免后续再次解析完整负载:

// model query: search candidates and return a slim projection
const r = await callTool("person_search", { filters, limit: 25 });
if (!r.ok) return { error: r.message };
return r.data.profiles.map(p => ({
  name: p.basic_profile?.name,
  url: p.social_handles?.professional_network_identifier?.profile_url,
}));

始终在脚本内部缩减响应(返回 ID/URL/邮箱,而不是完整个人资料),不要直接返回原始响应。


工具依赖项

此技能需要:

  • Crustdata MCP 服务(install.crustdata.com/mcp):一个提供 list_tools、get_schema 和 execute 的 Code Mode MCP。所有 Crustdata 数据工具都通过 execute({ code }) 中的纯 JavaScript 脚本调用:await callTool(name, params)——根据 get_schema 提供的 TypeScript 类型接口编写代码,但不要在代码主体中添加类型注解。此处使用的工具:person_search、person_enrich(个人资料 + 工作邮箱)、person_contact_enrich(个人邮箱 + 电话号码)、company_enrich、dev_platform_enrich(Dev Platform:开发者个人资料 + 仓库)、web_search_live、web_enrich_live
  • Gmail MCP:gmail_create_draft
  • Python(搭配用于电子表格 I/O 的 openpyxl 和用于跟踪表的 csv)
  • 网页搜索(Crustdata web_search_live):用于回退式邮箱查找

创始人排除规则

不要联系现任创始人、联合创始人、CEO 或 CTO——这些人正在运营自己的公司。他们不太可能离职,联系他们既浪费名额,也可能显得不合时宜。

如何识别创始人

在第 1 阶段查看候选人的当前职位。若职位包含以下任一字样,请将其标记:Founder、Co-Founder、Co-founder、CEO、CTO,或同时包含 “Chief” 和 “Officer”(例如 Chief Technology Officer)。

公司规模收缩例外

唯一值得联系现任创始人的情况,是他们的公司正明显走向失败。以下三个条件必须全部满足:

  1. 员工人数正在减少 — 使用 company_enrich 和公司的域名:

    // model query: check headcount trend for example.com
    const r = await callTool("company_enrich", {
      domains: ["example.com"],
      fields: ["basic_info", "headcount", "web_traffic"],
    });
    if (!r.ok) return { error: r.message };
    // per match: matches[0].company_data.headcount.{ total, growth_percent }
    return r.data;
    

    检查 headcount.growth_percent(键为 mom、qoq、six_months、yoy、two_years)——关注月环比(mom)和季环比(qoq)增长为负的情况。

  2. 网站流量正在下降 — 检查月访客量是否呈下降趋势。

    从 company_enrich 中读取 web_traffic.domain_traffic(请求 fields: ["web_traffic"]),查看月访客量趋势;seo 和 news 分组也可用相同方式获取。

  3. 员工离职速度超过公司可承受的程度 — 过去 3 个月离职的前员工人数超过当前员工人数。这表明公司正在流失员工,而不只是停滞不前。

如果三个条件全部满足,创始人可能愿意考虑新的机会。如果任一条件不满足(例如,公司规模较小但正在增长),就跳过该候选人,并在跟踪表中将其标记为 status: "skipped",附上类似 "Excluded — active founder (company not shrinking)" 的备注。

处理增强数据响应

company_enrich 会返回一个 { matched_on, match_type, matches: [{ confidence_score, company_data }] } 数组。在 execute 脚本中对其进行精简,只返回所需的员工人数信号:

// model query: project headcount growth signals for founder-company check
const r = await callTool("company_enrich", { domains: ["example.com"], fields: ["basic_info", "headcount"] });
if (!r.ok) return { error: r.message };
return r.data.map(m => {
  const cd = m.matches?.[0]?.company_data;
  const hc = cd?.headcount ?? {};
  const g = hc.growth_percent ?? {};
  return { name: cd?.basic_info?.name, total: hc.total, mom: g.mom ?? 0, qoq: g.qoq ?? 0 };
});
实际示例
候选人公司结果
Di Jin(联合创始人)Eigen AI(12 名员工,月环比 -7.7%)略有下降,但离职的前员工人数不足 → 跳过
Sai Surbehera(联合创始人/CTO)Lapis Labs(5 名员工,月环比 +25%)公司正在增长 → 跳过
Aayush Anand(联合创始人)Level.game(9 名员工,稳定)公司运营正常 → 跳过

不要这样做

  • 切勿猜测个人资料 URL — 始终通过 Crustdata 验证。猜测的 URL 曾在一场仅有 91 人的活动中导致 12 次错误。
  • 切勿发送电子邮件 — Gmail MCP 只会创建草稿。用户会审核并手动发送。
  • 切勿使用基于职位头衔的开场白 — 始终提及候选人做过的具体工作。
  • 切勿跳过电子邮件验证 — 丢弃 noreply 地址,并确认 GitHub 个人资料属于正确的人。
  • 切勿重复使用同一条开场白 — 根据每位候选人做过的具体工作,为其撰写独特的开场白。
  • 切勿联系活跃的创始人 — 跳过现任创始人/联合创始人/CEO/CTO,除非其公司明显走向失败(员工人数下降、流量下降,且员工离职速度超过公司可承受的程度)。参见上文“创始人排除规则”一节。

评论

支持 Markdown