履歷素材的追蹤與去重:用 JD ID 建立關聯
履歷素材的追蹤與去重:用 JD ID 建立關聯
當你為多個職位投遞履歷時,如何避免重複使用相同素材?如何追蹤哪些素材來自哪次生成?本文分享三個關鍵功能的設計與實作。
問題場景
投遞 10 家公司時,你可能會遇到:
- 素材重複使用 - 同一個案例被用在 5 份履歷,面試時容易露餡
- 不知道素材來源 - 這個優化好的素材是從哪個 JD 生成的?
- 無法追蹤歷史 - 哪些素材已經給過 Google?
我們需要一個關聯系統來追蹤素材的使用歷史。
Schema 設計
在 resume_chunks 表添加兩個欄位:
class ResumeChunk(BaseModel):
id: str
text: str
skills: list[str]
# ... 其他欄位
# 🆕 JD 關聯欄位
used_in_jobs: list[str] = [] # 已用於哪些 JD
created_from_jd: Optional[str] # 來源 JD ID
三大功能
1. --created-from-jd:標記素材來源
當你從 AI 生成的履歷中提取優質素材回寫時,記錄它的來源:
uv run career-kb ingest \
--text "Designed GraphQL schema supporting 10K TPS..." \
--type project \
--skills "GraphQL,API Design" \
--role Lead \
--impact 4 \
--created-from-jd "abc123" # 👈 標記來源
用途:
- 追蹤素材的「出生證明」
- 評估哪個 JD 產生最多優質素材
- 避免循環引用(用 A JD 產生的素材再給 A JD)
2. --exclude-used-in:排除已用素材
搜尋時排除已經用過的素材,確保每份履歷獨特:
uv run career-kb search \
--focus "distributed systems" \
--exclude-used-in "abc123,def456" # 👈 排除這兩個 JD 用過的
過濾邏輯:
# 搜尋結果後過濾
if exclude_jd_ids:
results = [
r for r in results
if not any(jd_id in exclude_jd_ids
for jd_id in (r.get("used_in_jobs") or []))
]
用途:
- 避免同一素材被多個履歷重複使用
- 面試時不會因為重複案例被發現「套版」
- 強迫自己挖掘更多獨特經驗
3. --mark-used:自動標記使用
生成履歷時,自動標記哪些素材被使用了:
uv run career-kb generate \
--jd-id "abc123" \
--mark-used # 👈 自動標記
--output resume.md
更新邏輯:
def mark_materials_as_used(material_ids: list[str], jd_id: str):
for material_id in material_ids:
record = get_record(material_id)
used_in = record.get("used_in_jobs", [])
if jd_id not in used_in:
used_in.append(jd_id)
update_record(material_id, {"used_in_jobs": used_in})
用途:
- 自動建立使用歷史
- 下次搜尋時可以排除這些素材
- 統計每個素材被使用的次數
完整工作流程
┌─────────────────────────────────────────────────────────────────┐
│ JD 分析流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ save-jd ─────────→ jd_id: "abc123" │
│ │ │ │
│ │ ▼ │
│ │ verify ─→ 技能落差分析 │
│ │ │ │
│ │ ▼ │
│ │ search --exclude-used-in "other-jd-ids" │
│ │ │ │
│ │ ▼ │
│ │ generate --mark-used ─→ resume.md │
│ │ │ │
│ │ ▼ 標記 used_in_jobs: ["abc123"] │
│ │ │
│ │ 優質素材提取 │
│ │ │ │
│ │ ▼ │
│ └──────→ ingest --created-from-jd "abc123" │
│ │
└─────────────────────────────────────────────────────────────────┘
實際效果
場景:投遞 3 家公司
# 第一家:Google
save-jd -c Google -p "AI PM" -f google.txt # → jd_id: "goog1"
generate --jd-id "goog1" --mark-used
# 第二家:Meta(排除 Google 用過的素材)
save-jd -c Meta -p "PM" -f meta.txt # → jd_id: "meta1"
search --focus "product management" --exclude-used-in "goog1"
generate --jd-id "meta1" --mark-used
# 第三家:Apple(排除 Google + Meta 用過的)
save-jd -c Apple -p "TPM" -f apple.txt # → jd_id: "appl1"
search --focus "technical PM" --exclude-used-in "goog1,meta1"
generate --jd-id "appl1" --mark-used
每份履歷都有獨特的素材組合!
LanceDB 更新的挑戰
LanceDB 不支援原地更新(in-place update),需要 delete + add:
def update_record(table, material_id, updates):
# 1. 讀取現有記錄
records = table.search().where(f"id = '{material_id}'").to_list()
record = records[0]
# 2. 合併更新
record.update(updates)
record.pop("_distance", None) # 移除搜尋結果的額外欄位
# 3. 刪除舊記錄
table.delete(f"id = '{material_id}'")
# 4. 新增更新後的記錄
table.add([record])
這是 LanceDB 基於 Arrow 的限制,未來版本可能會支援更優雅的 update() 方法。
進階應用
統計熱門素材
# 找出被使用最多次的素材
SELECT id, text, array_length(used_in_jobs) as usage_count
ORDER BY usage_count DESC
LIMIT 10
找出閒置素材
# 從未被使用的高影響力素材
SELECT *
WHERE impact_level >= 4
AND array_length(used_in_jobs) = 0
清理過期關聯
# 移除超過 6 個月的 JD 關聯
# (那些公司應該已經不會再聯繫了)
總結
| 功能 | 參數 | 解決的問題 |
|---|---|---|
| 標記來源 | --created-from-jd |
追蹤素材從哪來 |
| 排除已用 | --exclude-used-in |
避免重複使用 |
| 標記使用 | --mark-used |
記錄使用歷史 |
這三個功能組合起來,讓你的履歷系統從「一次性工具」升級為「可追蹤的知識庫」。
Career Knowledge Base 是一個本地優先的履歷知識庫系統,使用 Python + LanceDB + Voyage AI 建構。
- ← Previous
用 LanceDB 儲存 JD 分析:避開 Arrow 巢狀結構的陷阱 - Next →
GraphRAG 效能解放:用 NetworkX + RAPIDS cuGraph 實現 GPU 加速圖檢索