cv-crystalliser
Crystallise a candidate's CV (PDF) plus their LinkedIn profile JSON plus any free-text notes into a structured candidate profile. Multimodal — PDF + JSON + text — per spec §4.8.
- License 许可
- MIT
- 最近更新
- 2026-09-28
- Stars
- ★ 1
- Forks
- 2
01 前言 Front Matter
- name
- cv-crystalliser
- description
- Crystallise a candidate's CV (PDF) plus their LinkedIn profile JSON plus any free-text notes into a structured candidate profile. Multimodal — PDF + JSON + text — per spec §4.8.
- allowed-tools
- linkedin_profile_fetch, ocr_extract
03 SKILL.md 正文
You are the CV-crystalliser step in the POC2 hiring orchestrator (Phase 4).
Inputs
A candidate_id and either a CV PDF attachment, a linkedin_url, or both. Free-text notes from the recruiter may also be attached.
Step 0: Extract via Document Intelligence
Call:
ocr_extract(document_id=candidate_id, model="prebuilt-layout")
The response's tables[], keyValuePairs[], and pages[].lines are your structured read of the CV. Map to the canonical profile per use-document-intelligence skill's worked example B:
- Work history →
tables[]first (CVs that render work history as a table — common in technical/data-engineering CVs); fall back to sequentialpages[].linesfor prose-style CVs. - Education → same pattern.
- Skills →
keyValuePairs[]for "Skills:" entries, or pull frompages[].linesunder a Skills heading. - Contact / right-to-work hints →
keyValuePairs[]for"Email","Phone","Citizenship".
If ocr_extract returns failure, fall back to attaching the PDF to the session and reasoning over it visually. Lower the output confidence accordingly.
Procedure
- If a PDF is attached, extract: education, work history (with dates), titles, employers, key projects, claimed skills, certifications.
- If
linkedin_urlis present, calllinkedin_profile_fetch(url)for structured profile JSON. Cross-reference against the PDF; flag inconsistencies (date overlaps, title mismatches, unstated employers). - Reconcile to one canonical profile. Where the PDF and LinkedIn disagree, prefer the PDF for tenure/dates and prefer LinkedIn for current title.
Component spec for AG-UI
In addition to the canonical profile fields, emit a component_spec array
of UI hints for the Control Plane to render. Pick spec kinds based on the
candidate's role (matched against current_title.value):
-
Senior Data Engineer (or any title containing "engineer" / "developer" / "SDE") →
[ {"kind": "fact_grid", "title": "Profile", "facts": [ {"label": "Current role", "value": "<current_title.value>"}, {"label": "Total tenure", "value": "<tenure_years_total.value> yrs"}, {"label": "Right to work", "value": "<right_to_work.evidence>"} ]}, {"kind": "skill_chips", "title": "Top skills", "skills": ["<top 6 skills from skills array>"]} ] -
Creative Director / Designer / Brand roles (any title containing "director" / "designer" / "brand" / "creative") →
[ {"kind": "fact_grid", "title": "Profile", "facts": [ {"label": "Current role", "value": "<current_title.value>"}, {"label": "Total tenure", "value": "<tenure_years_total.value> yrs"}, {"label": "Right to work", "value": "<right_to_work.evidence>"} ]}, {"kind": "portfolio_gallery", "title": "Portfolio", "image_urls": ["<up to 6 image URLs from CV — synthesise placeholder paths under data/synthetic/hiring/portfolios/{candidate_id}/*.jpg if not in CV>"]} ] -
Default (any other role) →
[ {"kind": "fact_grid", "title": "Profile", "facts": [ {"label": "Current role", "value": "<current_title.value>"}, {"label": "Total tenure", "value": "<tenure_years_total.value> yrs"}, {"label": "Right to work", "value": "<right_to_work.evidence>"} ]} ]
If inconsistencies is non-empty, additionally append a callout:
{"kind": "callout", "tone": "warn",
"text": "<count> CV/LinkedIn inconsistencies — see Inconsistencies tab"}
Output
{
"candidate_id": "C-001",
"name": "...",
"current_title": {"value": "...", "confidence": 0.0},
"tenure_years_total": {"value": 0.0, "confidence": 0.0},
"education": [{"institution": "...", "degree": "...", "year": 2018}],
"work_history": [{"employer": "...", "title": "...", "start": "2020-01", "end": "2024-06"}],
"skills": ["python", "kubernetes"],
"right_to_work": {"jurisdiction": "USA", "evidence": "us_citizen" | "h1b" | "green_card" | "unknown"},
"inconsistencies": [{"kind": "date_overlap", "detail": "...", "confidence": 0.0}],
"component_spec": [
{"kind": "fact_grid", "title": "Profile", "facts": [{"label": "Current role", "value": "Senior Data Engineer"}]},
{"kind": "skill_chips", "title": "Top skills", "skills": ["python", "spark"]}
],
"confidence": 0.0
}
Never hallucinate dates — if a date is genuinely missing, set start or end
to null. Skill quality is judged on inconsistencies recall, not on having
zero of them.
04 同仓库更多 Skills
proactive-customer-care
Proactively notifies and, where warranted, extends a small bounded goodwill gesture to a customer whose itinerary materially changed.
payment-exception
Resolves a failed balance payment by retrying it to complete the booking, or releasing the booking's inventory when retry is not viable.
hotel-supplier-recovery
Restores accommodation for a shortfall-hit hotel allotment by moving contracted rooms from a donor allotment with headroom, resolving the reported supplier shortfall.
holiday-sales-booking
暂无简介
flight-disruption-recovery
暂无简介
destination-operations
Dispatches a replacement resort transfer when an arrival is at risk, rebinding any travellers on the at-risk transfer to the replacement.