- name
- phdtaketaketake
- description
- Score a PhD applicant's profile and rank candidate advisors using a connection-first 4.0-scale scoring system. Best-supported for physics / HEP and materials science (MSE), with the scoring engine extensible to chemistry, biology, CS, math, EE, ChemE, earth science (each with field-specific caveats — see references/journal_tiers.md). Use when the user wants to evaluate their PhD application chances, find matching advisors at top US programs, score a CV for graduate school, or compare candidate professors. Also triggers when the user mentions phdtaketaketake or its connection-first philosophy of valuing advisor network over h-index.
# phdtaketaketake — Connection-first PhD advisor matcher
## ⚠️ CARDINAL RULE — REAL DATA ONLY
**Every connection edge, every candidate fact, every signal value MUST trace
back to a real source you actually fetched via web search.** Fabrication is
strictly forbidden — students use these rankings to decide where they spend
years of their life. Made-up data is worse than no data.
**The contract:**
- ✅ Verified via web search → record value + structured `EvidenceSource`
(URL + source_type + claim + supports_fields)
- ✅ Searched but found nothing → leave the field empty / set signal to `"missing"`
- ❌ Guessed from training memory → **NOT ALLOWED**
- ❌ Inferred from name patterns / school proximity / "feels likely" → **NOT ALLOWED**
- ❌ Estimated without any web search → **NOT ALLOWED**
**Two enforcement layers:**
1. **Risk-adjusted ranking** — wide confidence bands move candidates
*down* the sort order. The agent literally cannot get a top rank with
unsourced claims; the band widens and `risk_adjusted_strength = strength
− band/2` drops below better-evidenced peers.
2. **`--strict-evidence` flag** — when run with this flag, `scripts/match.py`
rejects any candidate that has *unsourced* claims (a value set without an
`EvidenceEntry`). Missing signals (no value, no evidence) are still
allowed — they're honest "I couldn't verify" states. Use this when the
user is making real application decisions.
The matcher's confidence band (±0.2 / 0.4 / 0.6 / 0.8 — see §Confidence
calibration below) handles missing data gracefully, AND the risk-adjusted
ranking subtracts band/2 from the sort key — so wide bands move candidates
down the list. A wide band on **real** data is far more useful than a narrow
band on **made-up** data.
Full allowed-source list and forbidden-behavior catalog:
[`references/data_integrity.md`](references/data_integrity.md). Read it
before doing any connection research.
---
This skill ranks candidate PhD advisors using a **5-layer deterministic
pipeline** — each layer composes the layer below; every score traces
back to cited evidence:
```
1. CAPEG match_score = w_C·C + w_A·A + w_P·P + w_E·E + w_G·G
(tier-adaptive weights; w_C > w_A in every tier
— connection-first invariant)
2. application_strength = clip(match_score + opportunity_adj, 0, 4.0)
3. risk_adjusted_strength = application_strength − band/2
4. difficulty_adjusted_strength = max(0, risk_adjusted_strength − program_penalty)
← PRIMARY SORT KEY (post-#5)
5. strategy bucket = bucket(difficulty_adjusted, evidence, …)
→ priority / target / reach / only_if_space / drop
(purely derivative — never modifies any score)
```
5 CAPEG pillars on a 4.0 scale:
- **Connection (C)** — verified path between candidate PI ↔ student's
current advisor: small-team coauthor, big-collab paper overlap,
working group, analysis contact, genealogy, shared grant,
co-mentored student, committee/exam, same center, prior-institution
overlap, conference session. v2 aggregation: `strongest +
0.10·second_strongest`, capped at 1.0, scaled by recency.
- **Advisor influence (A)** — PI **reputation only** (post-#6a):
`0.40·influence + 0.30·elite_status + 0.30·grad_placement_quality`.
Funding and recruiting moved to **Opportunity (O)**.
- **Publication (P)** — field-aware tier × author-role × status ×
recency × contribution-bonus, with big-collab and consortium
guardrails (`min(0.10, n/100)` cap on alphabetical co-authorship).
- **Experience (E)** — `0.20·lab_prestige + 0.30·duration +
0.50·output`, strongest single experience.
- **GPA (G)** — direct on 4.0; 4.3 / 4.5 / 100 / UK honours normalized.
3 non-CAPEG dimensions:
- **Opportunity (O)** — admit-cycle availability: `recruiting_health
+ active_funding_quality + lab_capacity + grant_timing +
availability`. Drives `opportunity_adj` (replaces v1 `pi_adj`);
`not_recruiting` forces `application_strength=0`.
- **Program difficulty (D)** — per-program penalty 0–0.8 from school-
tier admit rate + cohort size + admission model + funding structure
+ faculty count + international friendliness. Subtracted from
`risk_adjusted_strength` to form `difficulty_adjusted_strength`
(the **primary sort key**, replaces v1 `tier_adj`).
- **Research fit (R)** — structured 6-axis tie-breaker: `0.30·topic
+ 0.20·method + 0.15·system + 0.15·temporal + 0.10·grant +
0.10·background`. Never a 6th pillar; sorts ties only.
Pipeline diagram: [`docs/scoring_pipeline.md`](docs/scoring_pipeline.md).
Full formulas: [`docs/scoring.md`](docs/scoring.md). Per-feature
references in [`references/`](references/).
## How users actually invoke this skill (natural language)
Users on QClaw / Claude Code / any agent platform will not write JSON
themselves. The expected entry shape is conversational:
> "我是 2027 fall 申请 Physics PhD,方向是 ATLAS Higgs / detector ML。
> 本科 UCI,GPA 3.85/4.0,有两篇 ATLAS big-collab paper,导师是 Prof. X。
> 请帮我找美国 top 10–30 的匹配 PI,并按 phdtaketaketake 的 evidence-first
> 规则给出排序和申请策略。"
> *"I'm applying for biology PhDs this fall, focusing on cancer
> immunology. Berkeley undergrad, GPA 3.9, one first-author Cell paper,
> advisor is Prof. Y. Find me 8 advisors at top US programs."*
**Your job as the agent**: translate this into the structured
StudentProfile + candidate-discovery workflow below. Do **not** ask
the user to fill JSON. Do **not** ask for the schema upfront. Ask for
*missing* facts in plain English, one round at a time.
### Required information to ask for (if not given)
If the user's first message is missing any of these, ask before doing
deep research — running the pipeline without them produces low-confidence
output:
1. **Field / subfield** (e.g. "physics / HEP" → resolves to FieldProfile)
2. **Undergrad institution + GPA** (with scale: `4.0` / `4.3` / `4.5` / `100` / UK honours)
3. **Research direction** (1–2 sentences — the matcher uses this for research_fit)
4. **Current advisor(s)** (name + institution — drives the C pillar; **without this, connection-first matching is degraded** and the matcher prints a stderr warning)
5. **Target school tier or list** (top_10 / top_11_30 / top_31_60 / top_60_plus, OR a list of school names)
### Optional but improves output quality
- **Papers**: title, venue, status (`published` / `accepted` / `submitted` / `preprint` / `in_prep`), author position, total authors. Without this, P pillar floors out; user gets an honest "no publication evidence" rather than a guess.
- **Experiences**: lab name, duration months, output (paper / poster / thesis). Without this, E pillar floors.
- **Specific candidate PIs**: if the user already has a target list, skip Step 3 (discovery_plan) and feed candidates straight to `collect_evidence`. If not, run discovery_plan first.
- **Theory / experiment crossover preferences** (physics-specific): affects research_fit.theory_experiment_fit signal.
- **International friendliness needs** (visa / funding constraints): affects program_difficulty interpretation.
### Minimum viable run
The smallest run that produces useful output:
```
field + undergrad + gpa + research_direction + 1 current_advisor
+ target tier (e.g. "top_10")
```
Even with no candidate list, the agent can run `discovery-plan` to
generate per-school search queries, then `collect-evidence` on
agent-discovered candidates, then `match`. Missing optional fields
widen the confidence band but do not crash.
### Two-layer output contract
What the user sees vs what power users / strict-mode auditors get:
- **Per-candidate cards** (rendered by you, the agent) — the human-
readable presentation. Format defined in §"How to present results
to the user" below.
- **Full `match.json`** (raw MatchResult JSON) — kept as power-user
appendix; never the primary user-facing artifact.
## Step 0 — Load the FieldProfile
Before running any deep-research, **load the FieldProfile for the user's
discipline**. This is the per-field calibration layer that tells you
which databases to search, how to bucket papers, and what caveats to
surface. Bundled profiles:
| field id | aliases | notable rules |
|----------|---------|---------------|
| `physics` | `hep`, `hep-ex`, `hep-ph`, `hep-th`, `astrophysics`, `condensed matter` | `journal_first`; big_collab_threshold=10; INSPIRE-HEP primary |
| `mse` | `materials`, `nano`, `nanotechnology` | `journal_first`; big_collab_threshold=8; senior author = last |
| `cs` | `ml`, `machine learning`, `ai`, `nlp`, `cv`, `systems`, `theory`, `hci` | **`conference_first`**; co-first supported; CSRankings, not US News |
| `biology` | `bio`, `genetics`, `neuroscience`, `immunology`, `microbiology`, `biochemistry` | `journal_first`; co-first common; PubMed/bioRxiv; HHMI strong signal |
| `chemistry` | `chem`, `organic`, `inorganic`, `physical chemistry` | `journal_first`; senior author = last |
| `math` | `mathematics`, `applied math`, `pure math`, `statistics` | **`preprint_first`**; arXiv often canonical; Math Genealogy authoritative |
The matcher resolves aliases (e.g., user types `"hep"` → loads
`physics.yaml`). The resolved profile flows into the result as
`field_profile_id` and `field_caveats`; **always surface the caveats in
your result presentation** — they are how the matcher tells the user
"this discipline has the following gotchas".
For an unbundled field (e.g., `"materials_chemistry"`), the matcher
returns `field_profile_id: null` — fall back to the cross-field guidance
in `references/journal_tiers.md` and your domain knowledge, and tell the
user explicitly "no profile bundled for this field".
## Architecture: no static cache, always real-time research
There is **no bundled candidate cache**. PhD advisor data is too dynamic
(people change institutions, retire, take new students, pivot subfields) and
too vast (millions of PIs across STEM) for any static dataset to be useful.
Instead, the split:
- **You (the agent)** — do the deep research. Use web search + page fetch +
whatever tools you have to find candidates and verify connection edges.
- **`scripts/match.py`** — pure Python. Takes the profile + candidates you
built and runs the deterministic scoring (Pub/GPA/Experience/Connection
combination, tier-adaptive weights, application_strength with confidence band).
This makes the skill universal across STEM fields and always-fresh.
## Workflow
### Step 1 — Gather student profile
Required fields (must ask if missing):
- `field` — any STEM string (`"physics"`, `"chemistry"`, `"biology"`, etc.)
- `undergrad_institution`
- `gpa_raw` + `gpa_scale`
- `research_direction` — short paragraph (≥30 words is best)
Recommended (each materially changes ranking — **proactively ask**):
- `current_advisors[]` — `{id, name, institution}`. Without this, the entire
Connection score collapses to candidate's field strength only.
- `papers[]` — `{title, journal, journal_tier, author_position, status, year}`.
Without this, P score floors at 3.0.
**Paper-status weights**: `published` / `accepted` / `in_press` get full
credit; `submitted` / `preprint` get 0.7×; `in_prep` gets 0.3×. List
status honestly. Default is `"published"`. **Schema is strict** —
unknown status values raise. Field-specific overrides apply (e.g.,
math sets `preprint=0.9` because arXiv is often the canonical record).
**Optional P1 fields** (use when you can):
- `venue_type`: `journal` / `conference` / `workshop` / `preprint` /
`clinical_trial` — useful for CS where conferences = top venues
- `author_role`: `first` / `co_first` / `middle` / `senior` /
`corresponding` / `consortium`. When set, **`co_first` /
`corresponding` / `senior` are scored as 1st-author equivalent
regardless of byline position**. Use `co_first` for biology
"These authors contributed equally" cases.
- `total_authors`: total author count on the paper. Use the
`classify_coauthorship(total_authors, field_profile)` helper to
bucket `path_edge.small_team_coauthor_5y` vs `big_collab_papers_5y`
with the right per-field threshold (physics 10, mse/cs 8,
biology/chemistry 6, math 4).
- `experiences[]` — `{lab_pi_name, lab_tier, duration_months, output_type}`.
Without this, E score defaults to 2.0.
Source priority:
1. CV / resume pasted or attached → parse it, then **show the inferred
profile back to the user for confirmation** before continuing.
2. Existing profile JSON → use directly.
3. Prose description → ask brief targeted batches for missing fields. Don't
dump a 10-question list at once.
For mappings (`gpa_scale`, `journal_tier`, `lab_tier`, `output_type`,
`author_position` for big-collab papers): see `references/profile_schema.md`
and `references/journal_tiers.md`. When uncertain about a journal tier,
ask the user or default to tier `4`.
### Step 2 — Determine target programs (with cited ranking source)
Ask the user where they want to apply. Acceptable inputs:
- Specific schools (e.g., MIT, Stanford, Princeton)
- A tier ("top 10 physics", "top 30 chemistry")
- Specific professors they have in mind ("I'm interested in Prof. X")
- Open-ended ("show me the best matches")
**Per the cardinal data-integrity rule**, school tier is now a sourced
signal — not memorized. **Fetch the field-appropriate ranking page**.
The right source depends on field; use the loaded FieldProfile's
`ranking_source_url_template` first:
| field | preferred ranking source |
|-------|--------------------------|
| `physics` / `mse` / `chemistry` / `biology` / `math` | US News field-specific page (URL template in profile) |
| `cs` | **CSRankings** (`https://csrankings.org/`) — community-maintained, more reliable than US News for CS subfields |
Generic US News science page is a fallback only when no profile applies.
Record the URL in `evidence["school_tier"].items` for every candidate
you generate, with `supports_fields=["school_tier"]`:
```jsonc
"evidence": {
"school_tier": {
"items": [{
"url": "https://www.usnews.com/best-graduate-schools/...",
"source_type": "us_news",
"claim": "MIT physics ranked top 10 in 2024",
"supports_fields": ["school_tier"]
}]
}
}
```
Without claim-level evidence (or in strict mode without items at all),
Ver en GitHub