Customer Hunter
输入行业 / 城市 / Top N,输出三有评估(有钱 / 有需求 / 合作意愿)+ 推荐产品的 HTML 报告。
ℹ️ 版本号、依赖范围、外部 URL 等所有可变常量统一记在
manifest.toml,由scripts/lib/manifest.py加载,scripts 不再硬编码。维护者修改请见references/packaging.md。
数据源与依赖
| 数据源 | 接入方式 | 用途 | |---|---|---| | 企查查 | HTTPS 直连远程 MCP(Bearer Token) | 公司搜索、工商信息、上市/异常/资质/融资 | | 百度百科 | HTTPS 直连远程 MCP(Bearer Token) | 公司背景、成熟度信号 | | BOSS 直聘 | OpenCLI + Chrome 扩展 | 招聘岗位、云需求信号 |
本地依赖(具体版本范围见 manifest.toml):Python ≥ 3.9 / Node.js ≥ 21 / OpenCLI / Chrome + OpenCLI 扩展。
硬规则(Hard Rules — 触发后无条件遵守)
这些是 skill 的安全契约。完整文本见 references/rules.md,下面是必须默认加载到 Claude 上下文的最小红线集合。任一被违反 = bug,不是优化空间。
R1. 不得编造或绕过数据源
- 数据来源只能是企查查 MCP、百度百科 MCP、BOSS 直聘 OpenCLI 三家
- 被禁工具:WebSearch / WebFetch / curl / wget / requests / httpx / playwright,不得用于补数据或替代失败的数据源
- 数据源失败 → 如实报告 + 停下,不许用训练知识、缓存、或推测填充
R2. 不得用 Agent 训练知识或用户口头话作为评分证据
- "我知道这家公司上市了" → ❌
- 用户在 chat 里说"他们有 200 人" → ❌(即便用户是销售本人,也只能写到
备注,不进评分) - 评分依据只能来自三个数据源的原始 API 响应
R3. 合作意愿维度严禁 AI 自动打分
- 三维评分中,「合作意愿」维度只由销售本人手填 checklist(见
references/willingness_checklist.md) - 不许用 WebSearch 找客户高管和腾讯的关系、爬社交媒体、用训练知识里的"是腾讯系"
- 报告里这个维度只渲染 checklist 占位,不输出 AI 推断的"合作意愿分"
R4. 触发后的执行时序(不许跳步)
- 先发引导提示告知用户即将打开浏览器表单。模板:
已为你启动「目标客户挖掘」流程 🎯 接下来会在浏览器里打开一个信息收集表单(4 个 Tab:环境准备 / BOSS 直聘登录 / MCP 接入指引 / 任务配置),请按提示填写后点击"提交"。表单提交后,我会自动从企查查、百度百科、BOSS 直聘抓取数据并生成 HTML 报告。 ⏳ 表单未提交前请勿关闭终端;如长时间未弹出浏览器,请检查 Chrome 是否被杀进程。
- 跑 Step 0 环境预检;若退出码非 0 立刻停下并把建议透传给用户。
- 跑 Step 1 启动表单 + 同回合内立即阻塞轮询
.hunter-input.json,未落盘前绝对不允许进入 Step 2。 - 表单是唯一可信输入通道;表单内为空时按表单默认值,不擅自从 chat 推测。
R5. 失败必走 cleanup
无论 pipeline 在哪一步失败或中断(配额耗尽 / 登录过期 / 用户取消 / 异常退出码),都必须执行 Step 6 python3 scripts/cleanup.py 后再向用户报告结果。这是关闭 skill 打开的 Chrome 的唯一可靠保障,跳过会导致僵尸 Chrome 进程残留。
退出码与暂停协议
非零退出码不是错误日志,是结构化的暂停信号。Claude 必须按下表分支处理:
| Exit | 含义 | Claude 必做动作 |
|---|---|---|
| 0 | 正常完成 | 进入下一步 |
| 2 | 缺 API Key | 让用户重跑表单填 Key |
| 6 | QCC 配额耗尽 + 0 候选 | 走"配额耗尽 4 选 1"(见下) |
| 7 | 行业关键词无候选 | 让用户换行业关键词重跑 |
| 20 | Cloudflare / JS 挑战 | 读 .hunter-pause.json,用 AskUserQuestion 把 hint 转述给用户,等用户手动过完后重跑当前步骤 |
| 21 | BOSS 登录失效 | 同上:读 pause file → AskUserQuestion → 用户重登 → 重跑 boss_enrich |
| 22 | 限流且 fallback 也失败 | 同上:让用户选 等/切/跳 |
.hunter-pause.json 协议(exit 20/21/22 触发):
- 文件在 cwd,schema_version=1,含
primary_kind(challenge/login/throttled)+entries[](每条带 site/op/hint/context) - Claude 读这个文件,把每条 hint 用人话转述(不直接 cat 文件)
- 用户处理完,从对应 step 重跑(不重跑整条 pipeline,避免重复消耗配额)
配额耗尽 4 选 1(exit 6 触发,详见 scripts/lib/quota.py 的 print_quota_advice):
- 💰 充值续费:QCC
agent.qcc.com/console/recharge/ 千帆console.bce.baidu.com/qianfan - 🌅 改天再跑:多数套餐次日 0 点重置每日配额
- 🔁 换 Key 重试:在表单 Tab 3 重填备用账号 Key
- 🪫 兜底降级:仅用已抓数据继续,报告必须如实标注哪些维度缺数据(不得伪装成"该维度无加分项")
执行流程
Step 0:环境预检
bash scripts/preflight.sh
检测 Python / Node / OpenCLI / Chrome 扩展,对照 npm + GitHub 最新版判定 OpenCLI verdict(ok_baseline / block_min / caution_breaking / not_installed / unknown),结果写入 stdout 的 ENV_CHECK_JSON_START...END JSON 块。block_min / not_installed 退出码 1(阻塞)。
🆕 首次冷启动 badcase 修复:当 Chrome 扩展未连接时,preflight 自动调用 scripts/install_extension_helper.py,做三件事:
- 终端打印分步图文指引(Chrome 应用商店 + GitHub Release 两条路)
- 用 AppleScript /
open -ga在已运行的 Chrome 里直接打开应用商店搜索页(不抢焦点、不冷启动新实例) - 在 cwd 落一份
extension-install-guide.html,离线可看,URL 打印到终端
verdict 语义、breaking change 清单、扩展引导触发条件见 references/troubleshooting.md。
Step 1:HTML 表单收集输入
# ① 后台启动表单
Bash(command="rm -f .hunter-input.json && python3 scripts/generate_form.py",
run_in_background=True, timeout=650000)
# ② 同一回合内立刻阻塞轮询
Bash(command="for i in $(seq 1 120); do \
[ -f .hunter-input.json ] && cat .hunter-input.json && exit 0; \
sleep 5; \
done; exit 1", timeout=650000)
调用约定:
- ❌ 禁止用
preview_url(会跑到 WB 内置浏览器,丢 Chrome 登录态) - ✅ 必须
run_in_background=True,启动后立刻发起阻塞轮询(同一回合内) - ✅ 用文件落盘信号驱动,不用
BashOutput/sleep 600
.hunter-input.json 结构:
{
"city": "深圳",
"industry": "游戏",
"criteria": {
"min_scale": "中型",
"exclude_top": true,
"exclude_companies": [],
"exclude_keywords": ["贸易", "批发", "餐饮"]
},
"count": 5,
"products": {"游戏": ["GME", "EdgeOne", "ACE"]},
"mcp": {"qcc_api_key": "...", "baike_api_key": "..."}
}
industry 支持逗号 / 顿号 / 斜杠 / 加号分隔的多子行业(如 漫剧,短剧 / 游戏,社交),qcc_search.py 会拆分后分别生成 query 与并集匹配关键词。详见 references/architecture.md 的「多行业输入支持」。
exclude_keywords 在 qcc_search.py 中分两道实施:① 候选阶段先按公司名快速过滤;② enrich 完成后按 (公司名 + 注册行业 + 经营简介 + 经营范围) 联合 blob 二次过滤,命中则记录"用户排除关键词命中:<kw>"原因。
详细时序坑、Tab 内容、API Key 加载优先级见 references/troubleshooting.md。
Step 2:企查查搜索目标企业
python3 scripts/qcc_search.py --max 15
行业关键词扩展 + 城市拼接 → get_company_by_query → 一层过滤(剔非企业主体 / 异地 / 头部 / 用户排除关键词)→ 并发拉详情(registration / profile / contact / listing / risk×2 / qualifications / financing)→ 二层行业相关性过滤(正向 + 反向词典,命中原因写入 industry_match_reason)→ 输出 qcc-companies.json,被剔除写入 rejected-companies.json。
行业词典扩展、多行业拆分、上市信号解析、is_listed 真伪判定见 references/architecture.md。
Step 3:并行数据采集
# 3a. BOSS 直聘
python3 scripts/boss_enrich.py --input qcc-companies.json --output boss-results.json
# 3b. 百度百科
python3 scripts/baike_enrich.py
BOSS 底层:opencli boss search <短名> --city <城市> --limit 10 --site-session ephemeral。OpenCLI 适配版本范围见 manifest.toml 的 [runtime.opencli]。命令名是 search(非 company-jobs),query 是位置参数,必须 --site-session ephemeral,用"短名"绕反爬,Bash 超时 600000ms。exit 21 → BOSS 登录过期,引导用户重登后重跑。
百度百科调 listLemmaByTitle + queryLemmaContent,输出 baike-results.json。中小公司无词条属正常。query_content 的 card 数组会被拍平 + 同义字段标准化(成立时间 / 员工数 / 年营业额 / 上市信息等),详见 references/architecture.md。
Step 4:评分
python3 scripts/score.py --products '<用户自定义产品映射 JSON>'
读三个 JSON 按 references/money.md + references/need.md 评分,输出 scored.json。关键 schema、自定义产品契合度推理(PRODUCT_FIT_KEYWORDS + 行业默认 + 云场景 + 通用兜底四级)见 references/architecture.md。
Step 5:生成 HTML 报告
python3 scripts/report.py --top N --industry "行业" --city "城市" --w-money <用户设置的w_money值,默认0.5>
读 scored.json 生成 top-customers.html。--w-money 值从 .hunter-input.json 的 w_money 字段获取(用户通过表单"评分侧重"滑块设置,范围 0.3~0.7,默认 0.5)。卡片渲染固定 10 块(公司名+排名 / 数据源+综合分 / 有钱指数 / 需求指数 / 推荐产品 / 有钱判断依据表 / 需求判断依据表 / 有钱证据 / 需求证据 / 合作意愿 checklist),不允许因数据缺失而缺块——空数据时也展示占位文案。详见 references/architecture.md 的「报告卡片渲染顺序」。
Step 6:收尾清理(强制,无论成功或失败都必须执行)
python3 scripts/cleanup.py
⚠️ 无条件执行:无论前面哪个 Step 成功或失败(包括配额耗尽 exit 6、行业无候选 exit 7、BOSS 登录过期 exit 21 等任何异常退出码),都必须在向用户报告结果之前执行本步骤。这是关闭 skill 冷启动的 Chrome 的唯一可靠保障。
四层清理:① 8 个已知 hunter session OpenCLI close ② AppleScript 按 URL 模式扫 Chrome tab 关闭 ③ 仅含空白 tab 的 Chrome 窗口归并关闭 ④ 若 Chrome 是本次冷启动 + 当前已无任何用户 tab,则整体 quit。详见 references/architecture.md。
配额耗尽降级(机制层)
scripts/lib/quota.py 识别 QCC 300008 / 百科 200115/300114/调用次数已达上限/quota exhausted 等错误(错误码字典在 manifest.toml 的 [mcp.qcc] / [mcp.baike]),标记 provider 已耗尽 → 同 provider 后续调用跳过 → 主流程末尾汇总提示。
用户处理选项见上文「退出码与暂停协议」的 4 选 1;选项 4「兜底降级」时,报告必须如实标注哪些维度缺数据(per R1 + 报告验收 #4)。
输入输出
| 字段 | 必填 | 默认 | 说明 |
|------|------|------|------|
| 行业 | 是 | — | 单行业或逗号分隔多行业(游戏 / 社交 / 漫剧,短剧 / 电商+直播 等) |
| 城市 | 否 | 全国 | 深圳 / 上海 / 北京 等 |
| 标的要求 | 否 | — | 规模偏好、排除条件 |
| 数量 | 否 | 5 | Top N,最大 10 |
| 产品映射 | 否 | — | {"行业": ["产品名", ...]} |
最终产物:top-customers.html
报告验收标准
报告生成后向用户交付前,对照下面 4 条自检;任何一条不达标都必须显式向用户说明,不要静默成功。
- 结构完整:每张公司卡固定 10 块(公司名+排名 / 数据源+综合分 / 有钱指数 / 需求指数 / 推荐产品 / 有钱判断依据表 / 需求判断依据表 / 有钱证据 / 需求证据 / 合作意愿 checklist),缺数据时用占位文案而不是删块。
- 三有分有据:每个非零得分都能在「判断依据表」里指回一条 raw 数据;如果某维度全 0 但 raw 有数据,多半是评分规则没命中——不要伪装成"该维度没什么可说的"。
- 来源标记可见:每条判断依据应能区分「事实 / 推断 / 评分」三类(见下节)。如果用户问"这家为什么排第一",能在 30 秒内指着报告里的具体行回答,不需要打开 JSON。
- 失败如实呈现:候选数不足 N、QCC 配额耗尽、BOSS 登录过期、百科无词条等情况,不许用 WebSearch / WebFetch / 编造数据填充。退化为"已知 K 家,缺 N-K 家因 XX"明示。
信任校准:事实 / 推断 / 评分 三层来源
报告里展示的每一条数据都属于以下三类之一。混着展示是销售场景里的最大风险("我跟客户说他们融资了 B 轮,结果是 BOSS 上一个 JD 说『B 轮在投』,闹笑话")。
| 类别 | 来源 | 例子 | 报告中的徽章颜色 |
|---|---|---|---|
| 事实 | 企查查工商接口直接字段 | 注册资本 1000 万、上市代码 300xxx、经营异常 0 条、自身风险 3 条 | 蓝(#0ea5e9)|
| 推断 | BOSS 招聘信号、百科条目存在性、JD 文本解析 | "在招云开发岗 → 推测有云需求"、"百科无词条 → 推测知名度低"、"成立 < 2 年 → 推测 早期阶段" | 黄(#a16207)|
| 评分 | score.py 阈值规则 + 加权 | "注册资本 ≥ 500 万 → +3 分"、综合分 = 0.5×有钱 + 0.5×需求 | 灰(#9ca3af)|
写报告或回答用户时:
- 提到「事实」类数据 → 直接陈述("该公司经营异常 0 条")
- 提到「推断」类数据 → 必须带前缀("根据 BOSS 在招岗位推测...")
- 提到「评分」类数据 → 说明是启发式("按内置评分规则得 8/10,规则定义在 references/money.md")
不要做的事:
- 把 BOSS 推断说成"该公司有云业务"(事实化)
- 把 score.py 启发式分说成"该公司值得跟进"(结论化)
- 在没有 raw 数据时仍然给出"该维度评 7 分"(无中生有)
进一步阅读
manifest.toml—— 版本、依赖、URL、打包白名单的单一事实源(SSOT)references/architecture.md—— MCP 直连原理 / 行业过滤词典 / 多行业拆分 / 产品契合度推理 / Chrome 生命周期 / cleanup 四层 / 报告卡片渲染顺序 / scored.json schemareferences/troubleshooting.md—— 常见错误 + 表单时序坑 + OpenCLI verdict 维护 + Chrome 扩展首装引导 + API Key 加载优先级 + 配额耗尽与退出码references/money.md—— "有钱"维度评分规则references/need.md—— "有需求"维度评分规则references/willingness_checklist.md—— "合作意愿" checklist 项references/rules.md—— 综合评分阈值与排序规则references/packaging.md—— 维护者专用:基于 manifest 的一键打包流程 + secret 反向扫描
Scan to join WeChat group