Lead Enrich 是做什麼的?
使用 Serper.dev Google 搜尋來研究特定個人(姓名 + 公司)。利用代理程式的內建模型進行資料萃取。無需外部 LLM API。
可獨立運作 — 僅需一組 Serper 金鑰。可與 Outreach Magic 搭配,實現額度節省的去重(當潛在客戶已有 LinkedIn/電子郵件時跳過 Serper)以及跨工作階段的持續儲存。
節省額度(使用 OM 時): 會優先檢查 outreachmagic。如果該潛在客戶在同一家公司已擁有 LinkedIn + 電子郵件,則不會消耗任何 Serper 額度。如果僅有 LinkedIn 而缺少電子郵件,則跳過 Serper — 請使用 email-finder 進行處理。僅有電子郵件的記錄仍會執行 LinkedIn 搜尋(耗費 1–2 個 Serper 額度)。若姓名相符但公司不同,則回傳
ambiguous,以避免浪費 API 調用。
設定
獨立運作(無 OM)
僅需一組 Serper 金鑰。直接執行 serper-search。結果以 JSON 格式輸出。
| 金鑰 | 用途 |
|---|---|
SERPER_API_KEY | serper.dev — Google 搜尋 API |
python3 scripts/enrich.py serper-search --query '"Acme Corp" 官方網站'
python3 scripts/enrich.py serper-search --query 'site:linkedin.com/in 王小明 Acme Corp'
# → 將結果傳給你的模型進行萃取,或使用 serper-format
在你的環境變數中設定 SERPER_API_KEY,或透過 ~/.hermes/skills/lead-enrich/config.json 設定。
搭配 Outreach Magic(去重 + 儲存)
新增前置去重(跳過已在 OM 中的潛在客戶),並將結構化的豐富資訊儲存到本機 SQLite 管道。需要 outreachmagic 技能 並執行 pipeline.py login。
| 金鑰 | 用途 |
|---|---|
| 上述獨立運作的所有金鑰 + | |
OUTREACHMAGIC_AGENT_KEY | 透過 pipeline.py login 登入 OM |
python3 scripts/enrich.py check "王小明" "Acme Corp" # 0 個額度
python3 scripts/enrich.py batch-check --workspace W input.json # 批次去重
在 Outreach Magic 入口網站 → 設定 → API 金鑰 中儲存你的 Serper 金鑰,然後執行 pipeline.py sync-secrets。使用 enrich.py config 驗證(serper_api_key_source 應為 agent_secrets)。
3. 尋找電子郵件(email-finder 技能)
電子郵件尋找功能不在 lead-enrich v2+ 中。請依照平台安裝指南安裝 email-finder 並搭配 outreachmagic 使用。或者透過 npx skills add outreachmagic/email-finder 獨立安裝。
當 Serper 豐富化儲存了 company_domain 之後,執行:
python3 ~/.hermes/skills/email-finder/scripts/email_finder.py find --name "王小明" \
--domain acme.com --linkedin "https://linkedin.com/in/wangxiaoming" --save
請參閱 references/email-finder.md 和 email-finder 技能文件。
工作區彙總(無需 Serper 額度): 儲存潛在客戶後,使用 outreachmagic workspace summary --workspace <slug> --json 來取得標籤統計和每位寄件者的 LinkedIn 接受邀請次數。對於大型工作區(超過 2,000 個潛在客戶),加上 --tags-only 以加快標籤統計速度。僅限本機資料庫 — 非必要可拉取。
常見工作流程
| 使用者表示 | 你的操作 |
|---|---|
| 「幫我研究這個人」 | Serper 搜尋 → 透過 import-profiles 儲存 |
| 「豐富我的 CSV 檔案」 | batch-check / 匯入 → 豐富缺少的欄位 → 儲存到 OM |
| 「也幫我找到他的電子郵件」 | 豐富化之後,交給 email-finder 處理 |
Sales Nav / Vayne CSV 檔案:使用 outreachmagic import-profiles --file …(會自動偵測欄位)。
CSV / 獎項清單工作流程(10 人以上時建議使用)
像 outreachmagic/imports/awards.csv 這樣的路徑是相對於你的工作區目錄(代理程式執行指令的目錄),而非技能安裝資料夾。
# 0 個額度 — 先對整個檔案進行去重(會在完整資料列上自動標記 serper_attempted)
python3 scripts/enrich.py batch-check --workspace your_workspace outreachmagic/imports/awards.csv
# 重新執行去重,跳過已標記 serper_attempted 的潛在客戶
python3 scripts/enrich.py batch-check --workspace your_workspace --skip-tagged outreachmagic/imports/awards.csv
# 僅對缺少 LinkedIn/網域的資料列執行 Serper(跳過 team_award、exists_linkedin_*、skipped_serper_attempted)
# 研究完成後 — 僅更新職稱/產業欄位(0 個 Serper 額度)
python3 scripts/enrich.py backfill --fields title,industry --workspace your_workspace outreachmagic/imports/patch.csv
batch-check 接受 .json 或 .csv 格式。backfill 的每一列都需要有 email 或 linkedin;使用分塊的 import-profiles 並透過 companion_common 處理(每塊 200 列,每塊最多 300 秒;僅填入空白欄位;加上 --overwrite 可取代現有資料)。
使用時機
- 使用者說「幫我研究這個人」/「查詢 Acme 公司的王小明」
- 使用者想要在聯絡前豐富潛在客戶清單
- 使用者在進行研究前詢問「我們已經有這個潛在客戶了嗎?」
- 使用者提供了包含姓名和公司的 CSV/JSON 檔案需要批次豐富
- 使用者提到了 Serper、潛在客戶豐富化或個人研究
代理行為規則(重要)
- 先進行去重(使用 OM 時)。 在呼叫任何 Serper API 之前,先執行
enrich.py check。如果該潛在客戶在同一家公司已有 LinkedIn + 電子郵件,則完全跳過 Serper。如果已有 LinkedIn 但缺少電子郵件,則跳過 Serper,並在使用者想要電子郵件時提供 email-finder。絕對不要在 outreachmagic 中已經完整的潛在客戶上浪費 Serper 額度。獨立運作時: 跳過檢查 — 直接執行serper-search。 - 僅限 Serper。 優先使用
enrich.py serper-search --query "..."(標準函式庫 HTTP,金鑰來自設定檔或環境變數)。或者使用curl搭配$SERPER_API_KEY— 切勿將金鑰直接寫入對話記錄中。絕對不要直接爬取 Google 或 LinkedIn。 - 僅使用內建模型。 由你(代理程式)從 Serper 結果中萃取 JSON。不使用外部 LLM API(不可使用 Gemini、OpenAI)— 你自己的推理能力就是萃取引擎。
- 完成所有研究後再儲存。 先執行完整的搜尋階梯,然後再一次性儲存。
- 透過 outreachmagic 儲存(使用 OM 時)。 對於有 LinkedIn 的潛在客戶,使用
import-profiles。在儲存時,務必在標籤中附加serper_attempted(在map-to-om的輸出中已自動包含)。對於沒有 LinkedIn 但有已知lead_id的潛在客戶,請透過stamp-attempted或帶有id+ 標籤的import-profiles來標記該標籤 — 不要只依賴備註。對於唯讀的去重檢查,請使用pipeline.py query或enrich.py check— 切勿直接執行原生INSERT/UPDATE。切勿對同一個人執行兩種儲存路徑。獨立運作時: 將 JSON 輸出儲存到檔案 — 不需要 OM。 - 豐富化後進行標記(使用 OM 時)。 每個經過 Serper 處理的潛在客戶在儲存時都必須被標記
serper_attempted。這可以防止在未來執行時被重複處理。 - 在 Serper 之前檢查標籤(使用 OM 時)。 在花費 Serper 額度之前,請檢查是否存在
serper_attempted標籤(透過enrich.py check --skip-tagged或檢查輸出中的skip_reason)。如果已存在標籤且 LinkedIn 仍然空白,則跳過,除非使用者明確要求重試(例如超過 30 天已過時)。 - 保持透明。 顯示哪些 Serper 查詢被執行了、信心水準以及儲存了什麼。使用者應該確切知道他們的額度用在哪裡。
- 明智地批次處理。 每次執行最多處理 50 人。對於 CSV/獎項清單,請在執行任何 Serper 之前,先對整個檔案(JSON 或 CSV)執行一次
batch-check。僅對狀態為缺少 LinkedIn/網域的資料列進行 Serper 處理。跳過team_award、exists_linkedin_email和skipped_serper_attempted這些資料列。 - 尋找電子郵件 — 使用 email-finder。 豐富化儲存了
company_domain之後,交給 email-finder (email_finder.py find --save)。請參閱references/email-finder.md。絕對不要在此技能中憑空捏造或猜測電子郵件格式。
快速開始
# 單一個人(最常見)
python3 scripts/enrich.py check "王小明" "Acme Corp"
# → 如果回傳 "not_found",則繼續執行下面的 Serper 搜尋組合
# 搭配工作區(將潛在客戶與你的管道工作區建立關聯)
python3 scripts/enrich.py check --workspace your_workspace "王小明" "Acme Corp"
# 從 JSON 或 CSV 批次處理(在處理清單前先執行此指令)
python3 scripts/enrich.py batch-check --workspace your_workspace outreachmagic/imports/people.json
python3 scripts/enrich.py batch-check --workspace your_workspace --skip-tagged outreachmagic/imports/awards.csv
# 在 LinkedIn 查詢失敗後標記 serper_attempted(當 lead_id 已知時)
python3 scripts/enrich.py stamp-attempted --workspace your_workspace --lead-ids 42,43 \
--notes "透過 Serper 找不到 LinkedIn"
# 在現有潛在客戶上回填職稱/產業(需要 linkedin 或 email)
python3 scripts/enrich.py backfill --fields title,industry outreachmagic/imports/patch.csv
# 從 GitHub 發行版安全地更新技能(經驗證的 checksum)
python3 scripts/enrich.py update --check
python3 scripts/enrich.py update
update 會在取代檔案前,從 update-manifest.json 驗證 SHA256 檢查碼。如果檢查碼遺失或不符,更新將會中止。
核心工作流程
第一階段 — 去重檢查(0 個額度)
針對每個人,執行:
# 不指定工作區(組織層級查詢)
python3 scripts/enrich.py check "王小明" "Acme Corp"
# 指定工作區(限定在你的管道工作區範圍內)
python3 scripts/enrich.py check --workspace your_workspace "王小明" "Acme Corp"
每個人的輸出:
| 狀態 | 含義 | 動作 |
|---|---|---|
exists_linkedin_email | 同一公司,有 LinkedIn 和電子郵件 | 跳過 Serper 和電子郵件 API |
exists_linkedin_no_email | 同一公司,有 LinkedIn,無電子郵件 | 跳過 Serper → 如果使用者想要電子郵件,使用 email-finder |
exists_no_linkedin_email | 同一公司,有電子郵件,無 LinkedIn | 僅執行 LinkedIn 的 Serper 查詢 |
exists_no_linkedin | 同一公司,兩者皆無 | 僅執行 LinkedIn 的 Serper 查詢 |
skipped_serper_attempted | 有 serper_attempted 標籤,無 LinkedIn | 跳過 Serper — 已經嘗試過 |
ambiguous | 姓名相符,公司不符 | 執行完整 Serper 組合 — 不要跳過 |
not_found | 無匹配 | 執行完整 Serper 搜尋組合 |
team_award | 團隊/群組列(非個人) | 跳過 Serper — 標記 team_award,新增聯絡備註 |
dedup_disabled | 設定檔中 dedup_before_search: false | 按照要求執行 Serper |
檢查輸出包含 tags 和可選的 skip_reason(has_linkedin 或 skipped_serper_attempted)。使用 batch-lead-lookup(本機,零 Serper 額度)。
第二階段 — Serper 搜尋組合
僅針對需要的人執行。每人 2–4 次搜尋,視結果品質而定:
Serper 額度預算估算
- 每人最低:
0個 Serper 額度(exists_linkedin_email)。 - 常見路徑:
2個額度(2a嚴格公司搜尋 +2cLinkedIn 個人檔案)。 - 每人硬上限:
4個額度(當所有備用方案都需要時:2a+2b+2c+2e)。 - 批次公式:
min=0、max=4*N,其中N是該次執行的人數。 - 批次上限範例: 當
N=50時,硬上限為200個額度(最壞情況)。
2a. 公司搜尋 — 嚴格(總是執行)
較佳做法(金鑰不會出現在 shell 歷史記錄中):
python3 scripts/enrich.py serper-search --query '"Acme Corp" 官方網站' --label company_discovery_strict
或者使用更簡單的查詢重試:
python3 scripts/enrich.py serper-search --query 'Acme Corp 網站' --label company_discovery_broad
2b. 公司搜尋 — 寬鬆(條件性執行)
僅在 2a 回傳無包含 http:// 或 https:// 網址的有機結果時才執行:
python3 scripts/enrich.py serper-search --query 'Acme Corp 官方網站' --label company_discovery_broad
(相同範本,公司名稱不加引號。)
2c. LinkedIn 個人檔案(總是執行)
建立查詢(公司名稱不加引號 — 以比對摘要中的各種雇主名稱形式):
site:linkedin.com/in 王小明 行銷經理 Acme Corp
範例:
python3 scripts/enrich.py serper-search \
--query 'site:linkedin.com/in 王小明 行銷經理 Acme Corp' \
--label linkedin_profile
第三階段 — 模型萃取
將格式化後的 Serper 結果傳遞給你自己(代理模型),並附上以下系統指令:
你是一位研究助理。使用者的訊息中包含以標籤分節的 Serper.dev Google 搜尋結果。你沒有即時的網路搜尋能力 — 請僅使用貼上的內容區塊。
任務:針對某家公司的一位特定個人,萃取以下資訊:
- company_domain:僅限可註冊的主機名稱(不含路徑、不含 www),或空字串
- company_website:完整的 https:// 首頁網址(如果支援),或空字串
- linkedin_url:該人士在此公司的 https://linkedin.com/in/… 網址,或空字串
- confidence:高 | 中 | 低
- note:針對歧義或資訊缺口的選用說明
規則:
- 每個非空的網址都必須出現在 Serper 區塊中(允許小幅的查詢字串正規化)
- LinkedIn 上的姓名可能與輸入不同(暱稱 vs. 法定姓名)— 以同一人 + 同一雇主來判斷
- 在接受 `linkedin_url` 之前,請驗證匹配品質:
- 從「全名:{full_name}」中萃取出名字和姓氏的字元(忽略標點符號)
- 所選的 `/in/` 結果必須在 `title` 或 `snippet` 中同時包含這兩個字元
- 如果沒有任何 `/in/` 結果滿足此字元要求,請將 `linkedin_url` 設為空字串,並將 `confidence` 設為「低」
- 公司的公開網站可能使用與輸入不同的橫幅名稱 — 以官方證據為準
- 解析 `company_domain` 時:
- 優先使用 `knowledgeGraph.website`(若存在)
- 拒絕常見的聚合/目錄網站(例如:naceweb.org、usnews.com、wikipedia.org、niche.com、facebook.com、instagram.com、twitter.com)
- 如果 `company_name` 似乎遺失或與人名高度相似,則回傳空字串
- 絕不憑空捏造網址或路徑
僅回傳單一 JSON 物件(不含 Markdown 圍欄):
{"company_domain":"","company_website":"","linkedin_url":"","confidence":"中","note":""}
使用以下使用者訊息範本:
### 目標人物
全名:{full_name}
提供的職稱/頭銜:{stated_role}
提供的公司:{company_name}
### 搜尋結果
{formatted_serper_sections}
### 任務
回傳系統指令中所述的 JSON 物件。
然後解析你自己的回應:移除 Markdown 圍欄,萃取 JSON 物件。
LinkedIn 結果備用方案: 如果萃取後 linkedin_url 仍為空,請掃描原始的 Serper 有機結果,尋找 title 同時包含名字和姓氏字元的 /in/ 網址。優先比對……
……(後續內容因翻譯需求而截斷)