careermate 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +33 -0
- package/INSTALL.md +230 -0
- package/LICENSE +21 -0
- package/README.md +532 -0
- package/THIRD_PARTY_NOTICES.md +57 -0
- package/bin/careermate.mjs +77 -0
- package/dist/career-os/README.md +78 -0
- package/dist/career-os/eop/cover-letter.md +46 -0
- package/dist/career-os/eop/fit-analysis.md +48 -0
- package/dist/career-os/eop/interview-prep.md +39 -0
- package/dist/career-os/eop/job-analysis.md +42 -0
- package/dist/career-os/eop/profile-extraction.md +37 -0
- package/dist/career-os/knowledge/ats.md +131 -0
- package/dist/career-os/knowledge/company-research.md +137 -0
- package/dist/career-os/knowledge/cover-letter.md +135 -0
- package/dist/career-os/knowledge/fit-matching.md +121 -0
- package/dist/career-os/knowledge/human-writing.md +118 -0
- package/dist/career-os/knowledge/interview-behavioral.md +132 -0
- package/dist/career-os/knowledge/interview-technical.md +126 -0
- package/dist/career-os/knowledge/linkedin-profile.md +152 -0
- package/dist/career-os/knowledge/networking-referrals.md +166 -0
- package/dist/career-os/knowledge/offer-evaluation-decision.md +121 -0
- package/dist/career-os/knowledge/onboarding-first-90-days.md +126 -0
- package/dist/career-os/knowledge/portfolio.md +121 -0
- package/dist/career-os/knowledge/recruiter-screen.md +105 -0
- package/dist/career-os/knowledge/rejection-triage-iteration.md +115 -0
- package/dist/career-os/knowledge/resume.md +123 -0
- package/dist/career-os/knowledge/salary-negotiation.md +123 -0
- package/dist/career-os/knowledge/verifiers/ats-compat.md +64 -0
- package/dist/career-os/knowledge/verifiers/consistency.md +61 -0
- package/dist/career-os/knowledge/verifiers/human-voice.md +82 -0
- package/dist/career-os/knowledge/verifiers/recency-staleness.md +72 -0
- package/dist/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
- package/dist/career-os/knowledge/verifiers/truthfulness.md +67 -0
- package/dist/doctor.mjs +79094 -0
- package/dist/mcp.mjs +96108 -0
- package/dist/migrate.mjs +4735 -0
- package/dist/pdf.worker.min.mjs +28 -0
- package/dist/public/app.js +150 -0
- package/dist/public/fonts/PretendardVariable.woff2 +0 -0
- package/dist/public/icon-180.png +0 -0
- package/dist/public/index.html +52 -0
- package/dist/public/lib.js +394 -0
- package/dist/public/pages/applications.js +107 -0
- package/dist/public/pages/documents.js +467 -0
- package/dist/public/pages/home.js +261 -0
- package/dist/public/pages/interview.js +227 -0
- package/dist/public/pages/jobs.js +493 -0
- package/dist/public/pages/profile.js +556 -0
- package/dist/public/pages/settings.js +240 -0
- package/dist/public/styles.css +498 -0
- package/dist/site/analytics.js +97 -0
- package/dist/site/favicon.svg +1 -0
- package/dist/site/fonts/PretendardVariable.woff2 +0 -0
- package/dist/site/icon-180.png +0 -0
- package/dist/site/icon-512.png +0 -0
- package/dist/site/index.html +598 -0
- package/dist/site/landing.js +54 -0
- package/dist/site/llms-install.txt +217 -0
- package/dist/site/robots.txt +4 -0
- package/dist/site/sitemap.xml +21 -0
- package/dist/site/start.html +326 -0
- package/dist/site/style.css +550 -0
- package/dist/site/vercel.json +20 -0
- package/dist/web.mjs +46852 -0
- package/docs/FAQ.md +101 -0
- package/docs/MCP_TOOLS.md +311 -0
- package/docs/README.md +28 -0
- package/docs/START_WORKFLOW.md +137 -0
- package/docs/SUPPORTED_AI_APPS.md +112 -0
- package/docs/WORKFLOWS.md +202 -0
- package/docs/career-os/README.md +78 -0
- package/docs/career-os/eop/cover-letter.md +46 -0
- package/docs/career-os/eop/fit-analysis.md +48 -0
- package/docs/career-os/eop/interview-prep.md +39 -0
- package/docs/career-os/eop/job-analysis.md +42 -0
- package/docs/career-os/eop/profile-extraction.md +37 -0
- package/docs/career-os/knowledge/ats.md +131 -0
- package/docs/career-os/knowledge/company-research.md +137 -0
- package/docs/career-os/knowledge/cover-letter.md +135 -0
- package/docs/career-os/knowledge/fit-matching.md +121 -0
- package/docs/career-os/knowledge/human-writing.md +118 -0
- package/docs/career-os/knowledge/interview-behavioral.md +132 -0
- package/docs/career-os/knowledge/interview-technical.md +126 -0
- package/docs/career-os/knowledge/linkedin-profile.md +152 -0
- package/docs/career-os/knowledge/networking-referrals.md +166 -0
- package/docs/career-os/knowledge/offer-evaluation-decision.md +121 -0
- package/docs/career-os/knowledge/onboarding-first-90-days.md +126 -0
- package/docs/career-os/knowledge/portfolio.md +121 -0
- package/docs/career-os/knowledge/recruiter-screen.md +105 -0
- package/docs/career-os/knowledge/rejection-triage-iteration.md +115 -0
- package/docs/career-os/knowledge/resume.md +123 -0
- package/docs/career-os/knowledge/salary-negotiation.md +123 -0
- package/docs/career-os/knowledge/verifiers/ats-compat.md +64 -0
- package/docs/career-os/knowledge/verifiers/consistency.md +61 -0
- package/docs/career-os/knowledge/verifiers/human-voice.md +82 -0
- package/docs/career-os/knowledge/verifiers/recency-staleness.md +72 -0
- package/docs/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
- package/docs/career-os/knowledge/verifiers/truthfulness.md +67 -0
- package/package.json +89 -0
- package/packages/core/src/context.ts +74 -0
- package/packages/core/src/index.ts +8 -0
- package/packages/core/src/onboarding.ts +81 -0
- package/packages/core/src/services.ts +187 -0
- package/packages/core/src/summary.ts +104 -0
- package/packages/db/src/connection.ts +76 -0
- package/packages/db/src/index.ts +23 -0
- package/packages/db/src/paths.ts +52 -0
- package/packages/db/src/repositories.ts +891 -0
- package/packages/db/src/runtime.ts +58 -0
- package/packages/db/src/schema.ts +307 -0
- package/packages/exporters/src/html.ts +110 -0
- package/packages/exporters/src/index.ts +364 -0
- package/packages/exporters/src/markdown.ts +178 -0
- package/packages/knowledge/src/index.ts +168 -0
- package/packages/mcp-tools/src/bridge.ts +106 -0
- package/packages/mcp-tools/src/index.ts +17 -0
- package/packages/mcp-tools/src/result.ts +49 -0
- package/packages/mcp-tools/src/tools.ts +747 -0
- package/packages/mcp-tools/src/update.ts +330 -0
- package/packages/parsers/src/documents.ts +533 -0
- package/packages/parsers/src/html.ts +86 -0
- package/packages/parsers/src/index.ts +231 -0
- package/packages/parsers/src/keywords.ts +151 -0
- package/packages/prompts/src/humanize.ts +59 -0
- package/packages/prompts/src/index.ts +82 -0
- package/packages/prompts/src/install.ts +43 -0
- package/packages/prompts/src/onboarding.ts +35 -0
- package/packages/prompts/src/system.ts +57 -0
- package/packages/shared/src/build-info.ts +22 -0
- package/packages/shared/src/enums.ts +142 -0
- package/packages/shared/src/index.ts +19 -0
- package/packages/shared/src/schemas.ts +453 -0
- package/packages/workflows/src/definitions.ts +109 -0
- package/packages/workflows/src/index.ts +39 -0
- package/scripts/init.ts +371 -0
- package/tsconfig.json +32 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# 연봉 협상 / Salary Negotiation — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
연봉 협상에서 협상력은 개인 사정이 아니라 **데이터(시장 벤치마크)와 BATNA(대안)**에서 나온다. 이 플레이북은 연결된 AI가 (1) 직무·지역·레벨·통화·시점이 일치하는 시장 데이터로 요구액을 정당화하고, (2) total comp을 구성요소(base/bonus/equity/sign-on/relocation, 한국은 +사이닝·직책수당·성과급 비중)로 분해해 협상하며, (3) **BATNA 강도와 지원자 연차·시장 수급에 맞게 협상 강도를 캘리브레이션**하도록 안내한다. 무리한 앵커는 오퍼 철회 리스크를 키우므로, 업사이드뿐 아니라 **하방 리스크와 안전 한계선**도 함께 가르친다. 한국 맥락(포괄임금제·연봉 일원화·스톡옵션 과세·원천징수영수증 관행)을 반영하되 글로벌 베스트프랙티스를 우선한다.
|
|
8
|
+
|
|
9
|
+
## 2. 플레이북
|
|
10
|
+
|
|
11
|
+
### 원칙
|
|
12
|
+
|
|
13
|
+
- **(요구액은 시장 데이터로 정당화한다 — 개인 사정 금지)** 매 요구 금액 옆에 명명된 벤치마크 출처와 **직무·지역·레벨·통화·수집 시점(연도)**을 함께 붙인다. 개인 사정(대출·생활비)은 회사가 통제 불가하고 설득력이 없다. _(출처: Levels.fyi Negotiation Guide; UH Bauer Rockwell Career Center)_
|
|
14
|
+
- **(시장 앵커 출처에는 정밀도 위계가 있다)** 시장 앵커는 **levels.fyi·회사별 실데이터(직무·레벨·지역·equity 반영)를 1순위**로 쓴다. BLS OEWS·정부 통계는 광역 직업분류 평균이라 테크 직무에 과소·지연 집계되므로 **하한 참고·보조**로만 강등한다. 한국은 사람인·잡코리아·원티드 직무 통계와 동종업계 레인지를 1차로 쓴다. _(출처: Levels.fyi Guide; BLS OEWS May 2025 한계)_
|
|
15
|
+
- **(임금 투명성이 기본 환경이다 — 공개 레인지를 디폴트로 다룬다)** NYC/CA/CO/WA 공고 레인지 의무공개, EU Pay Transparency Directive(2026 시행)로 회사 레인지가 이미 공개된 경우가 많다. **공개 레인지가 있으면 그것을 즉시 앵커 기준으로 활용**한다. 단 한국은 일반 임금공개 의무가 없으므로, 한국 시장에서는 역질문으로 레인지를 끌어내는 전략을 디폴트로 둔다. _(출처: NYC Local Law 32; EU Directive 2023/970)_
|
|
16
|
+
- **(정보가 충분하면 먼저 앵커, 부족하면 디플렉션 — 조건부 규칙)** "먼저 숫자 말하면 진다"는 과도한 일반화다. 협상학 실증(Galinsky & Mussweiler 2001)은 **시장 정보를 충분히 확보했을 때 먼저 데이터 기반으로 앵커하는 쪽이 결과가 좋음**을 보인다. 따라서 (a) 시장가·레벨 구조를 충분히 알면 먼저 데이터 앵커를, (b) 정보 비대칭이 크면 회사 레인지를 먼저 끌어내는 역질문을 쓴다. _(출처: Galinsky & Mussweiler, JPSP 2001; Harvard PON)_
|
|
17
|
+
- **(하향 범위가 아니라 단일 앵커로 핵심 요구액을 제시한다)** 핵심 요구 base는 자기 양보를 내포한 **하향 범위(X에서 Y, X~Y where X<Y)로 제시하지 않는다** — 상대는 항상 하단으로 점프한다. 단일 숫자로 타깃의 **+5~15%** 위를 앵커하되 **인용된 시장 p75를 넘지 않게**(최대 p90), 그 차이를 정당화할 근거를 준비한다. **total comp 구성 시나리오(A/B/C로 분해된 여러 숫자)는 이 규칙의 예외**다 — 분해는 양보가 아니라 경로 제시다. _(출처: UT Dallas Career Center; UH Bauer; Anchoring 이론)_
|
|
18
|
+
- **(total comp을 구성요소로 분해해 협상한다)** base / annual bonus / equity / sign-on / relocation으로 나누고, 동일 타깃 총액을 만드는 **2~3개 구성 시나리오**를 제시한다. "올려달라"(쉽게 'no')가 아니라 "어느 구성이 내부적으로 가능한가"로 질문을 바꾼다. sign-on은 밴드·내부 형평성에 걸리지 않아 base보다 양보받기 쉽다. annual bonus는 레벨 고정인 회사가 많지만, **타깃 보너스 %·첫 해 비례지급(proration)·보장 보너스(guaranteed first-year)**는 협상 가능한 경우가 흔하므로 무조건 빼지 않는다. _(출처: Levels.fyi Guide; The Salary Negotiator Total Comp guide)_
|
|
19
|
+
- **(equity는 구성요소 1개가 아니라 별도 전장으로 다룬다)** **베스팅 스케줄(4년·1년 클리프)·refresh(리프레셔)·RSU vs 옵션·409A/행사가·비상장 유동성·세금**을 분해해 평가한다. 시니어·스태프급은 base보다 **equity refresh·베스팅·레벨(다운레벨 방지)**이 진짜 협상 포인트다. 한국 스톡옵션은 **적격/비적격 행사이익 과세·행사 요건**이 실질이며, 4년 베스팅이 표준이 아닌 관행도 확인한다. _(출처: The Salary Negotiator; 한국 벤처기업법 스톡옵션 과세특례)_
|
|
20
|
+
- **(BATNA를 명시하고 강도에 따라 협상 강도를 분기한다)** 협상 전 BATNA(다른 오퍼·현직 유지·다음 사이클 대기)를 한 문장으로 정의하고 워크어웨이 라인을 정한다. **(a) 강한 BATNA(검증 가능한 서면 오퍼)만 금액 레버리지로 사용**한다. **(b) 약/무 BATNA(주니어·단일 오퍼·이직 절박)면 경쟁 오퍼 언급 자체를 금지**하고 시장 데이터만으로 협상한다 — 모호한 경쟁 오퍼는 리크루터가 "어느 회사 어느 단계냐, 그 타임라인에 맞춰주겠다"로 5분이면 무너뜨린다. _(출처: Fisher & Ury, Getting to Yes; Harvard PON; 리크루터 역이용 시나리오)_
|
|
21
|
+
- **(협상 강도를 BATNA·연차·시장 수급에 매핑하고 오퍼 리스크를 관리한다)** 공격적 단일 앵커 + 타깃 위 + exploding offer 연장이 겹치면 — 특히 주니어·평범한 BATNA에서 — **오퍼가 식거나 철회될 실제 리스크**가 있다. p90 초과 앵커, 밴드 상한 무시, "서면 전엔 신뢰 안 함"식 압박은 위험 신호다. 강한 BATNA·시니어·수급 우위면 세게, 약한 BATNA·주니어·수급 열위면 시장 중앙값~p75 안에서 부드럽게 민다. _(출처: 채용 매니저 오퍼 철회 리스크; UH Bauer 캘리브레이션)_
|
|
22
|
+
- **(거짓·검증 불가 경쟁 오퍼를 만들지 않는다)** 강한 BATNA가 있을 때만 사실 범위 안에서 활용한다. 없는 오퍼를 지어내거나 검증 불가능한 모호한 오퍼를 언급하면, 오퍼레터 요구 한 번에 신뢰가 붕괴되고 협상이 무너진다. _(출처: Levels.fyi Guide; 리크루터 검증 압박)_
|
|
23
|
+
- **(즉답 금지 → 24~48시간 검토 → 서면 확인)** 감사+열의를 표한 뒤 검토 시간을 요청하고, 모든 합의(금액·구성·시작일·조건)는 오퍼레터·이메일로 서면화한다. _(출처: UMD/UW Career Center; Levels.fyi Guide)_
|
|
24
|
+
- **(한국 맥락: 포괄임금제와 base 외 레버를 본다)** **포괄임금제(고정OT)는 base가 같아도 실수령·근로시간이 다른 진짜 함정**이므로 먼저 확인한다. **연봉계약서 vs 근로계약서**, 인센티브의 **확정 vs 변동**, 직책수당·연봉테이블 등급 조정·사이닝(스타트업·유니콘은 점점 흔함)을 분해 대상으로 삼는다. **원천징수영수증/현재 연봉 요구**는 처우협의 단계에서 강하게 들어올 수 있으므로 단순 회피가 아니라 "희망연봉은 시장가 기준"으로 프레이밍하고, 강하게 요구될 때의 대응 스크립트를 준비한다. _(출처: 글로벌 원칙의 한국 적용; 근로기준법 포괄임금 판례)_
|
|
25
|
+
- **(비금전 레버와 합법성/형평성을 협상 표면에 올린다)** 시작일·재택/하이브리드·직책/타이틀·교육비·리뷰 주기 앞당기기·재협상 시점 합의 등 비금전 레버를 활용한다. 회사 거절 사유 1위는 보통 **밴드 상한·내부 형평성(internal equity)**이므로, "왜 안 되는지"를 이해하고 형평성에 안 걸리는 sign-on으로 우회한다. 반경쟁조항·전 직장 연봉 질문의 지역별 합법성도 확인한다. _(출처: 채용 매니저 밴드/형평성; 지역별 salary history ban)_
|
|
26
|
+
|
|
27
|
+
### Do
|
|
28
|
+
|
|
29
|
+
- 작업 전 levels.fyi·회사별 실데이터(또는 한국이면 사람인·잡코리아·원티드·동종업계 레인지)에서 **직무·지역·레벨·통화·수집 연도**별 p25/p50/p75를 수집하고 출처를 기록한다. BLS OEWS는 하한 보조로만.
|
|
30
|
+
- 요구 금액마다 "시장가 $X(출처·직무·지역·레벨·연도) + 차별화 요소(즉시 기여·무 램프업·희소 스킬) → 따라서 $Y"의 데이터 문장으로 정당화한다.
|
|
31
|
+
- 공개 레인지가 있으면 즉시 앵커 기준으로 쓰고, 없으면(한국 디폴트) 역질문으로 회사 레인지를 먼저 끌어낸다.
|
|
32
|
+
- 핵심 요구 base는 단일 숫자로, 타깃의 +5~15% 위를 앵커하되 인용된 p75(최대 p90)를 넘지 않게 한다.
|
|
33
|
+
- total comp을 base/bonus/equity/sign-on/relocation으로 분해하고 동일 총액의 2~3개 구성 시나리오를 만든다.
|
|
34
|
+
- equity는 베스팅·refresh·RSU/옵션·행사가·세금까지 분해해 평가한다. 시니어면 레벨·refresh를 핵심 협상 포인트로 둔다.
|
|
35
|
+
- 협상 전 BATNA를 한 문장으로 명시하고, **강도에 따라 협상 강도를 분기**한다(강하면 금액 레버리지, 약하면 시장 데이터만).
|
|
36
|
+
- 오퍼 수신 시 감사+열의 표현 후 24~48시간 검토를 요청하고, 최종 합의를 서면 확인한다.
|
|
37
|
+
- 한국이면 포괄임금제·연봉계약서·확정/변동 인센티브·사이닝·직책수당·연봉등급을 별도 협상 포인트로 식별한다.
|
|
38
|
+
- 비금전 레버(시작일·재택·타이틀·교육비·재협상 시점)와 밴드 상한·내부 형평성 현실을 함께 고려한다.
|
|
39
|
+
|
|
40
|
+
### Don't
|
|
41
|
+
|
|
42
|
+
- 생활비·대출·집세·부양 등 **개인 사정으로 요구액을 정당화하지 않는다**.
|
|
43
|
+
- 핵심 요구 base를 **하향 범위(X에서 Y, X<Y)로 제시하지 않는다** — 상대는 하단으로 점프한다. (단 total comp 구성 시나리오의 다중 숫자는 예외)
|
|
44
|
+
- 정보가 부족한데 먼저 구체적 숫자를 던지지 않는다(반대로 정보가 충분하면 먼저 앵커한다).
|
|
45
|
+
- 현재/전 직장 연봉을 묻기 전에 자발적으로 노출하지 않는다.
|
|
46
|
+
- 오퍼를 받자마자 그 자리에서 수락·거절하지 않는다.
|
|
47
|
+
- **약/무 BATNA에서 경쟁 오퍼를 언급하지 않는다**(주니어·단일 오퍼·이직 절박 시 순손실).
|
|
48
|
+
- 존재하지 않거나 검증 불가능한 모호한 경쟁 오퍼를 지어내거나 암시하지 않는다.
|
|
49
|
+
- 인용된 시장 p90을 초과하는 무리한 앵커로 오퍼 철회 리스크를 자초하지 않는다.
|
|
50
|
+
- base 한 숫자에만 집중해 sign-on·equity·포괄임금·기타 구성요소를 놓치지 않는다.
|
|
51
|
+
- annual bonus를 "레벨 고정"이라며 무조건 협상에서 빼지 않는다(타깃 %·비례·보장 보너스 협상 여지).
|
|
52
|
+
- "당장 이 오퍼가 꼭 필요하다"는 절박함을 드러내지 않는다.
|
|
53
|
+
- 출처 없는 단일 블로그·커뮤니티 숫자나 통화·지역·시점이 안 맞는 데이터를 시장가 근거로 쓰지 않는다.
|
|
54
|
+
- 구두 합의를 서면 확인 없이 신뢰하지 않는다.
|
|
55
|
+
|
|
56
|
+
### 워크드 예시 (Before → After)
|
|
57
|
+
|
|
58
|
+
1. **Before:** "기대 연봉이 어떻게 되세요?" → "음, 한 6천에서 7천5백만 원 사이면 좋을 것 같아요. 지금 전세 대출도 있고 해서요."
|
|
59
|
+
**After:** "이 역할에 대해 책정하신 연봉 레인지가 있으실 텐데 먼저 공유해 주실 수 있을까요? 저는 동일 직무·서울·시니어 기준, 2026년 사람인·동종업계 데이터를 반영해 말씀드리겠습니다." (회사가 6천~7천5백 제시 시) "해당 직무 75 백분위가 7천2백 수준이고, 저는 온보딩 램프업 없이 첫 분기부터 X를 바로 맡을 수 있어 **base 7천5백**을 기준으로 보고 있습니다."
|
|
60
|
+
**왜 더 나은가:** After는 (1) 한국 디폴트인 역질문으로 정보를 먼저 확보하고, (2) 하향 범위 대신 단일 앵커(7천5백)를 제시하며, (3) 개인 대출이 아니라 직무·지역·레벨·시점이 명시된 시장 백분위+차별화 요소로 정당화한다. 앵커는 인용 p75 안에 있어 무리하지 않다. Before는 범위·개인사정·하단 노출로 협상력을 모두 잃는다.
|
|
61
|
+
|
|
62
|
+
2. **Before:** "제안하신 base 9천만 원 좋습니다. 혹시 조금만 더 올려주실 수 있을까요?"
|
|
63
|
+
**After:** "감사합니다, 팀과 미션에 매우 끌립니다. 검토를 위해 이틀만 시간을 주시면 좋겠습니다. total comp 기준으로 보면 levels.fyi 동일 레벨·지역 중앙값(2026)이 1억1천(base+equity+bonus)인데, 제 타깃은 1억2천입니다. 세 가지 구성안을 드릴게요: **(A) base 1억500 + 사이닝 1천**, **(B) base 1억 + 사이닝 1천5백 + equity 상향(베스팅·refresh 포함)**, **(C) base 1억1천 + 성과급 비중 확대**. sign-on은 밴드·형평성에 안 걸려 양보가 쉬울 텐데, 어느 쪽이 내부적으로 가능할까요?"
|
|
64
|
+
**왜 더 나은가:** After는 단일 base가 아니라 total comp으로 앵커하고, "올려달라"(쉽게 'no')가 아니라 "어느 구성이 가능한가"로 질문을 바꾸며, 검토 시간을 확보하고, sign-on이 형평성에 안 걸리는 이유를 짚어 회사가 yes하기 쉬운 경로를 연다. 다중 시나리오의 여러 숫자는 양보가 아니라 경로 제시이므로 단일-앵커 규칙의 예외다.
|
|
65
|
+
|
|
66
|
+
3. **Before:** (다른 오퍼가 없는데) "사실 다른 데서 1억3천 오퍼 받았어요. 맞춰주세요."
|
|
67
|
+
**After (강한 BATNA가 있을 때만):** "현재 한 곳에서 서면 오퍼를 받았고 그 타임라인이 이번 주입니다. 객관적으로 동일 직무 75 백분위가 약 1억2천이라, **base 1억2천 또는 동등 total comp면 바로 진행**하고 싶습니다. 결정 타임라인을 맞추기 위해 이번 주 내 확정 가능할까요?"
|
|
68
|
+
**After (약/무 BATNA일 때):** (경쟁 오퍼를 언급하지 않는다) "이 역할에 대한 확신이 큽니다. 다만 시장 데이터를 보면 동일 직무·레벨 중앙값이 1억1천이라, base 1억1천~total comp 기준에서 합의했으면 합니다. 검토 시간을 이틀만 주시겠어요?"
|
|
69
|
+
**왜 더 나은가:** 강한 BATNA 버전은 거짓 금액을 지어내지 않고(오퍼레터 요구 시 신뢰 붕괴 회피) 검증 가능한 서면 오퍼+시장 백분위로 레버리지를 만든다. 약/무 BATNA 버전은 **경쟁 오퍼를 아예 꺼내지 않고** 시장 데이터만으로 협상해 역이용 리스크를 차단한다. Before는 검증 요청 한 번에 신뢰를 잃고 협상이 붕괴된다.
|
|
70
|
+
|
|
71
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
72
|
+
|
|
73
|
+
루브릭은 **순수 카운트·존재·패턴**으로 닫히게 설계했다(의미 이해 없이 판정 가능). "정당화 문맥" 같은 의미 조건은 제거하고 토큰 비교로 환원했다. **치명(critical)** 항목은 하나라도 실패하면 산출물 반려, **권고(advisory)** 항목은 점수 차감.
|
|
74
|
+
|
|
75
|
+
| ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) | 가중 |
|
|
76
|
+
|----|-----------|-----------|--------------------------------|------|
|
|
77
|
+
| R1 | market_anchor_cited — 요구액에 시장 출처가 동반되는가 | 명명된 출처 토큰 수 ≥ 통화금액 토큰 수, 그리고 출처 ≥ 1 | 통화/금액 토큰(`₩`·`$`·`만원`·`억`·`base`·`사이닝` + 4자리↑ 숫자) 개수와 출처 토큰(`levels.fyi`·`Glassdoor`·`사람인`·`잡코리아`·`원티드`·`BLS`·`고용노동부`) 개수를 세어 `sources_count >= amount_tokens_count` 확인 | critical |
|
|
78
|
+
| R2 | anchor_quality — 인용 금액에 직무·지역·레벨·통화·시점이 공존하는가 | 같은 출력 안에 4개 토큰군 중 ≥3 공존 + 연도 토큰 ≥1 | 토큰군 {직무명, 지역(서울/SF/remote 등), 레벨(주니어/시니어/L5 등), 통화기호} distinct 등장 수 ≥3, 그리고 `20\d\d` 패턴 ≥1 존재 | advisory |
|
|
79
|
+
| R3 | no_downward_range — 핵심 요구액이 하향 범위로 제시되지 않는가 | 하향 범위 패턴 0건(구성 시나리오 제외) | "A/B/C 시나리오" 블록을 제외한 영역에서 `숫자 (에서|~|-|to|between) 숫자` 매칭 후, 좌측<우측인 경우만 카운트 → 0이면 통과. (분해 시나리오는 `+`/`,`/`(A)` 마커로 식별해 제외) | critical |
|
|
80
|
+
| R4 | anchor_within_market — 앵커가 인용 시장 상단을 넘지 않는가 | 앵커 금액 ≤ 인용된 p75(없으면 p90) | 산출물에 `p75`/`p90`/`75 백분위` 수치가 명시되고, 핵심 앵커 금액 토큰이 그 값 이하인지 수치 비교 | advisory |
|
|
81
|
+
| R5 | total_comp_decomposed — base 외 구성요소로 분해됐는가 | 구성 카테고리 ≥2 distinct | 키워드 집합 {base/기본급, bonus/성과급, equity/스톡/주식, sign-on/사이닝, relocation/이주} 중 distinct 카테고리 수 ≥2 | critical |
|
|
82
|
+
| R6 | batna_present_and_branched — BATNA가 명시되고 강도 분기가 있는가 | BATNA 문장 ≥1 그리고 강/약 분기 표현 ≥1 | 패턴 {BATNA, 대안, 다른 오퍼, 워크어웨이, walk away, 현직 유지, 차선책} ≥1 **그리고** {강한 BATNA, 약한 BATNA, 검증 가능, 서면 오퍼, 언급 금지} ≥1 | critical |
|
|
83
|
+
| R7 | no_personal_justification — 개인 사정 단어가 등장하지 않는가 | 개인사정 패턴 0건 | 패턴 {대출, 전세, 월세, 생활비, 집세, 빚, 부양, mortgage, rent, bills} 등장 횟수 == 0 (의미 판정 없이 단순 부재 확인) | critical |
|
|
84
|
+
| R8 | no_unverifiable_competing_offer — 검증 불가 경쟁 오퍼 블러핑이 없는가 | 거짓/모호 오퍼 안티패턴 0건, 또는 "서면/검증 가능" 한정어 동반 | "다른 데서 ... 받았" 류 패턴이 등장하면 같은 문장 30토큰 내 {서면, 검증 가능, 오퍼레터} 동반 여부 확인 → 미동반 0건이면 통과 | critical |
|
|
85
|
+
| R9 | first_number_strategy — 정보 수준에 따른 앵커/디플렉션 전략이 있는가 | 역질문 또는 선제 앵커 조건 문장 ≥1 | 패턴 {레인지 공유, 책정 레인지, 먼저 여쭤, salary range, 공개 레인지, 정보가 충분하면 먼저 앵커} ≥1 | advisory |
|
|
86
|
+
| R10 | review_time_requested — 검토 시간 요청이 있는가 | 검토 시간 표현 ≥1 | 패턴 {24시간, 48시간, 이틀, 며칠, 검토 시간, 다음 주, get back to you, time to review} 매칭 ≥1 | advisory |
|
|
87
|
+
| R11 | written_confirmation — 서면 확인 안내가 있는가 | 서면화 언급 ≥1 | 패턴 {서면, 오퍼레터, 이메일로 확인, in writing, written} 존재 | advisory |
|
|
88
|
+
| R12 | kr_context_depth — 한국 맥락의 실질 함정을 다루는가(한국 시장 시) | 한국 특수 항목 ≥2 distinct | 패턴 집합 {포괄임금, 고정OT, 연봉계약서, 원천징수, 스톡옵션 과세, 사이닝, 직책수당, 연봉등급} distinct ≥2 | advisory |
|
|
89
|
+
| R13 | offer_risk_calibrated — 오퍼 철회/협상 강도 캘리브레이션이 있는가 | 리스크·강도 매핑 문장 ≥1 | 패턴 {오퍼 철회, 철회 리스크, 협상 강도, 캘리브레이션, 밴드 상한, 너무 세게} ≥1 | advisory |
|
|
90
|
+
|
|
91
|
+
**종합 판정 규칙:** critical(R1·R3·R5·R6·R7·R8) 6개 전부 통과해야 "승인". 하나라도 실패면 "반려". advisory는 통과 개수를 점수로 환산(7개 중 N개 → N/7)해 품질 등급(상/중/하)을 매긴다.
|
|
92
|
+
|
|
93
|
+
**주요 실패 모드:**
|
|
94
|
+
- **출처 게이밍:** 출처 "이름"만 박고 통화·지역·레벨·시점이 안 맞음 → R1(카운트 비교)+R2(공존+연도)+R4(상단 초과)로 다층 방어.
|
|
95
|
+
- **범위 오탐:** total comp 시나리오(A/B/C)를 하향 범위로 오인 → R3에서 분해 마커(`+`/`(A)`)로 명시 제외, 좌<우 조건만 카운트.
|
|
96
|
+
- **체크리스트 채우기:** 키워드만 박아 통과 → critical에 부재 확인(R7·R8)과 강도 분기(R6) 같은 게임하기 어려운 안티패턴 가드 배치.
|
|
97
|
+
- **약 BATNA에서 블러핑:** 없는 경쟁 오퍼 암시 → R6(강/약 분기)+R8(서면 한정어 동반)으로 차단.
|
|
98
|
+
- **무리한 앵커:** p90 초과로 오퍼 철회 자초 → R4(상단 이하)+R13(강도 캘리브레이션)로 경고.
|
|
99
|
+
|
|
100
|
+
## 4. 출처 (Provenance)
|
|
101
|
+
|
|
102
|
+
- **Roger Fisher & William Ury, 『Getting to Yes』 / Harvard Program on Negotiation (PON)** — BATNA 정의, 워크어웨이 기준, 협상력의 원천 · https://www.pon.harvard.edu/daily/batna/
|
|
103
|
+
- **Galinsky & Mussweiler, "First Offers as Anchors", JPSP (2001)** — 정보가 충분할 때 선제 앵커가 유리하다는 협상학 실증(플레이북의 "먼저 말하면 진다" 단정 교정 근거) · https://psycnet.apa.org/record/2001-05428-005
|
|
104
|
+
- **Levels.fyi Ultimate Negotiation Guide** — 데이터 앵커링, total comp 구성요소별 협상, 경쟁 오퍼·exploding offer, 현재 연봉 노출 회피, equity 디스카운트(1순위 시장 데이터) · https://www.levels.fyi/blog/ultimate-negotiation-guide.html
|
|
105
|
+
- **The Salary Negotiator — What is Total Compensation** — total comp 구성요소(base/bonus/equity/sign-on) 정의 및 equity 베스팅·refresh 평가 · https://www.thesalarynegotiator.com/resource-center/totalcompensation
|
|
106
|
+
- **NYC Local Law 32 / EU Pay Transparency Directive 2023/970(2026 시행)** — 공개 레인지를 디폴트로 다루는 근거(임금 투명성 환경) · https://eur-lex.europa.eu/eli/dir/2023/970
|
|
107
|
+
- **UH Bauer Rockwell Career Center — Salary Negotiation** — 타깃 위 앵커링, 90일 가치창출 브리프, 협상 강도 캘리브레이션 · https://careercenter.bauer.uh.edu/salary-negotiation/
|
|
108
|
+
- **UMD & University of Washington Career Centers** — 오퍼 수신 시 감사+열의, 24~48시간 검토 요청, 오퍼 평가 절차 · https://careers.umd.edu/find-jobs-internships/offers-salary-negotiation
|
|
109
|
+
- **BLS OEWS May 2025 (보조·하한 참고로 강등)** — 정부 임금 통계. 테크 직무는 광역 분류·집계 지연으로 과소평가되므로 1차 앵커로 부적합 · https://www.bls.gov/oes/
|
|
110
|
+
- **한국 맥락 — 벤처기업법 스톡옵션 과세특례·근로기준법 포괄임금 판례·사람인/잡코리아/원티드 직무 통계** — 포괄임금·스톡옵션 과세·연봉계약서·사이닝 등 한국 실무 함정의 근거
|
|
111
|
+
|
|
112
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
113
|
+
|
|
114
|
+
- **MCP 도구 아이디어:**
|
|
115
|
+
- `get_salary_negotiation_playbook(stage?, market?, batna_strength?)` — 단계(prep/first_number/counter/closing)·시장(global|kr)·BATNA 강도(strong|weak|none)에 맞는 원칙·스크립트·루브릭 서브셋을 반환하는 read-only 지식 도구. `batna_strength`로 경쟁 오퍼 전술 노출 여부를 분기.
|
|
116
|
+
- `save_compensation_benchmark(role, location, level, source, currency, p25, p50, p75, captured_at)` — 사용자가 수집한 시장 데이터를 저장. **captured_at·currency·region 필수**.
|
|
117
|
+
- `save_offer_breakdown(job_id, currency, base, annual_bonus, equity_annualized, sign_on, relocation, total_comp, batna_note)` — 오퍼를 구성요소별로 구조화 저장.
|
|
118
|
+
- `evaluate_offer(job_id)` — 저장된 오퍼 vs 벤치마크 vs BATNA를 표로 반환. **신선도 검사**: `captured_at`이 N개월(예: 6) 초과면 "stale" 플래그, 오퍼 통화·지역과 벤치마크가 불일치하면 "mismatch" 플래그를 함께 반환(LLM 없이 규칙으로).
|
|
119
|
+
- **데이터 형태 힌트:**
|
|
120
|
+
- `playbook: { principles:[{rule,rationale,source,weight:'critical'|'advisory'}], doList:[str], dontList:[str], scripts:[{situation, batna_strength, line}], rubricChecks:[{id,check,passBar,howToMeasure,weight}] }`
|
|
121
|
+
- `benchmark: { role, location, level, source, currency, p25, p50, p75, captured_at }` — 신선도/통화/지역 검증 가능하게 평탄화.
|
|
122
|
+
- `offerBreakdown: { job_id, currency, base, annual_bonus, equity_annualized, sign_on, relocation, total_comp, batna_note, batna_strength }`
|
|
123
|
+
- 루브릭은 LLM 없이 셀 수 있게 카운트/존재/패턴 필드로 평탄화: `cited_sources_count`, `amount_tokens_count`, `is_downward_range:boolean`, `anchor_within_p75:boolean`, `comp_components:[enum]`, `batna_strength:enum`, `kr_context_components:[enum]`, `check_weight:'critical'|'advisory'`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ATS 호환성 (ATS-compatibility) — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 커리어 산출물(이력서·자소서·면접 답변·LinkedIn 등)을 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사는 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
## 1. 목적
|
|
6
|
+
|
|
7
|
+
이 검증기는 커리어 산출물이 **Applicant Tracking System(ATS)에 의해 정확히 파싱되고, 채용공고(JD)의 핵심 키워드를 충분히 담고 있는지**를 보장한다. 산업 조사에 따르면 채용 담당자의 대다수(Jobscan 조사 기준 ~99.7%)가 ATS로 지원서를 1차 필터링한다. ATS는 대부분 텍스트 레이어를 **선형(좌→우, 위→아래)**으로 읽기 때문에, 표·다단·헤더/푸터·이미지·아이콘처럼 읽기 순서를 깨는 요소가 있으면 사람이 보기엔 멀쩡한 문서도 "단어 샐러드(word salad)"가 되어 검색에서 누락된다.
|
|
8
|
+
|
|
9
|
+
따라서 이 루브릭은 두 축을 본다.
|
|
10
|
+
1. **파싱 안전성(parse-safety)** — ATS가 텍스트를 깨뜨리지 않고 구조를 인식할 수 있는가(표준 헤더·단일 컬럼·연락처 위치·날짜 형식·폰트/아이콘·파일형식).
|
|
11
|
+
2. **JD 키워드 커버리지(keyword coverage)** — JD에서 반복·강조된 하드스킬/직무명/필수요건 용어가 산출물 본문에 실제로 존재하는가, 과도한 키워드 스터핑 없이.
|
|
12
|
+
|
|
13
|
+
핵심 설계 원칙: 모든 항목은 **LLM 없이도 셀 수 있는 형태(개수·존재여부·비율·정규식 패턴)**로 환원해 두어, 연결된 AI가 기계적으로 카운트해 합격/불합격을 판정하고 루프를 돌 수 있게 한다. 이력서·LinkedIn·자소서(텍스트 본문 기준)에 공통 적용한다.
|
|
14
|
+
|
|
15
|
+
## 2. 검사 항목
|
|
16
|
+
|
|
17
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게) |
|
|
18
|
+
|----|------|-----------|------------------------|
|
|
19
|
+
| C1 | 표준 섹션 헤더 존재 | 핵심 섹션이 표준 라벨로 존재 (이력서: Experience/Work Experience/Professional Experience, Education, Skills 중 최소 2개 일치; LinkedIn: About/Experience/Skills) | 산출물에서 헤더 라인을 추출해 표준 라벨 화이트리스트와 정확/근접 일치(대소문자 무시)한 **개수 ≥ 2**. "My Journey"·"내 이야기"·"The Toolkit" 같은 창의적 헤더는 0으로 카운트 |
|
|
20
|
+
| C2 | 비표준/창의적 헤더 부재 | 표준 화이트리스트에 없는 섹션 헤더 = 0개 | 헤더 라인 중 화이트리스트 밖 라벨 개수. **0이면 합격** |
|
|
21
|
+
| C3 | 단일 컬럼(다단 금지) | 다단 레이아웃 신호 없음 | 한 줄에 큰 공백(탭/2칸 이상 스페이스 ≥3개) 또는 좌우 분리 패턴이 있는 라인 비율 **< 10%**. 마크다운/플레인텍스트 추출본에서 같은 줄에 두 개의 독립 항목이 나란히 오는 라인 = 0 목표 |
|
|
22
|
+
| C4 | 표·텍스트박스 부재 | 표 구조 0개 | 마크다운 표 구분자(`\|---\|`)·HTML `<table>`·텍스트박스 마커 출현 횟수 **= 0** |
|
|
23
|
+
| C5 | 이미지·아이콘·스킬바 부재 | 그래픽 요소 0개 | 이미지 마크업(`![]`, `<img`)·이모지/심볼로 표기된 연락처 아이콘·"skill bar" 채움문자(예: ●●●○○, █) 출현 횟수 **= 0** |
|
|
24
|
+
| C6 | 연락처가 본문 상단에 위치 | 이메일·전화가 헤더/푸터가 아닌 본문 첫 영역에 존재 | 본문 텍스트 첫 15% 구간(또는 첫 5줄) 안에서 이메일 정규식(`[\w.+-]+@[\w-]+\.[\w.]+`) 매치 **≥ 1** 그리고 전화 패턴 매치 **≥ 1** |
|
|
25
|
+
| C7 | 일관된 날짜 형식 | 경력/학력 기간이 ATS가 인식하는 형식으로 통일 | 날짜 토큰을 추출해 허용 패턴(`MMM YYYY`, `Month YYYY`, `MM/YYYY`, `YYYY.MM`, `YYYY-MM`) 중 **단일 패턴 비율 ≥ 90%**. 혼용·"현재/Present" 외 자유서술 날짜 비율 < 10% |
|
|
26
|
+
| C8 | JD 하드스킬 키워드 커버리지 | JD 상위 키워드의 충분 비율을 본문이 포함 | JD에서 추출한 상위 하드스킬/도구/자격 키워드 집합 N개 대비, 산출물 본문에 (어형 정규화 후) 존재하는 개수 M → **M/N ≥ 0.75** (Jobscan 권장 75%+, 스위트스폿 80%). JD 미제공 시 본 항목은 N/A 처리하고 사유 기록 |
|
|
27
|
+
| C9 | 직무명(target job title) 일치 | JD의 핵심 직무명이 본문에 등장 | JD 헤드라인 직무명을 본문(이력서 요약/타이틀, LinkedIn 헤드라인)에서 정확/근접 일치로 탐색 → 매치 **≥ 1** |
|
|
28
|
+
| C10 | 키워드 스터핑 방지(과최적화) | 특정 키워드 반복이 과하지 않음 | C8 키워드 각각의 본문 등장 횟수 중 **어떤 단일 키워드도 6회 초과 금지**, 그리고 키워드 토큰이 전체 토큰에서 차지하는 비율 **< 6%**. 위반 키워드 개수 = 0 목표 |
|
|
29
|
+
| C11 | 약어·풀네임 병기 | 핵심 약어가 풀네임과 함께 1회 이상 병기 | JD/본문 공통 약어(예: ATS, SQL, PM) 중 본문에 약어만 단독 등장하고 풀네임 동반이 0인 항목 개수 → **0 목표**(파서/사람 양쪽 매칭 보장) |
|
|
30
|
+
| C12 | 파일 형식 안전 | 제출 형식이 `.docx` 또는 텍스트 레이어 있는 `.pdf` | 산출물 export 시 형식이 `.docx`/`.pdf`(텍스트 레이어 존재) 중 하나. 스캔 이미지 PDF·`.hwp`만 단독 제출 = 불합격 신호 |
|
|
31
|
+
|
|
32
|
+
> 측정 주체 안내: 위 패턴/카운트는 연결된 AI가 본문 텍스트(이미 추출된 플레인/마크다운)에 대해 직접 세면 된다. CareerMate는 원문 추출(`read_document`)과 본 루브릭만 제공한다.
|
|
33
|
+
|
|
34
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
35
|
+
|
|
36
|
+
불합격 항목이 하나라도 있으면, 연결된 AI는 **저장(`save_*`)·내보내기(`export_cover_letter`) 전에** 아래 순서로 수정하고 재검증(C1–C12 재실행)한다. 통과까지 반복하되, 사실·수치·고유명사는 절대 변경하지 않는다.
|
|
37
|
+
|
|
38
|
+
- **C1/C2 (헤더):** 창의적 헤더를 표준 라벨로 치환한다(예: "내 이야기" → "Experience", "보유 역량" → "Skills"). 누락된 표준 섹션은 기존 내용을 재배치해 신설.
|
|
39
|
+
- **C3/C4/C5 (레이아웃·표·그래픽):** 다단/표/텍스트박스/이미지/스킬바를 제거하고 **단일 컬럼 + 불릿 텍스트**로 평탄화한다. 아이콘은 텍스트 라벨("Email:", "Phone:")로 대체.
|
|
40
|
+
- **C6 (연락처):** 헤더/푸터에 있던 연락처를 본문 최상단으로 이동.
|
|
41
|
+
- **C7 (날짜):** 가장 많이 쓰인 단일 날짜 형식으로 전부 통일하고, 자유서술 기간을 표준 패턴으로 재작성.
|
|
42
|
+
- **C8/C9 (키워드/직무명):** JD에서 누락된 상위 키워드와 직무명을, **실제 경험이 있는 항목에 한해** 자연스럽게 본문에 통합한다. 경험이 없는 키워드는 넣지 않고 갭으로 보고만 한다(허위 금지).
|
|
43
|
+
- **C10 (스터핑):** 6회 초과·비율 초과 키워드의 등장 횟수를 줄이고 동의어/맥락 문장으로 분산.
|
|
44
|
+
- **C11 (약어):** 첫 등장 시 풀네임 병기(예: "ATS(Applicant Tracking System)") 추가.
|
|
45
|
+
- **C12 (형식):** `export_cover_letter` 등으로 `.docx`/텍스트 PDF로 내보내도록 안내. 스캔 PDF는 텍스트 레이어 버전으로 재생성.
|
|
46
|
+
|
|
47
|
+
재검증 후에도 C8이 JD 미제공으로 N/A면, 사용자에게 대상 공고를 `save_job_posting`으로 저장하도록 안내하고 커버리지 측정을 보류한다. 모든 항목 통과 시에만 "ATS 호환 확인됨"으로 표시하고 대시보드 링크(`http://127.0.0.1:4319`)를 안내한다.
|
|
48
|
+
|
|
49
|
+
## 4. 출처 (Provenance)
|
|
50
|
+
|
|
51
|
+
- **Jobscan — ATS Formatting Mistakes / Match Rate Guidance** — 표·다단·헤더/푸터·아이콘 금지, 연락처 본문 배치, 표준 헤더, 매치율 권장 75%+(스위트스폿 80%), 채용담당자 ~99.7% ATS 사용 통계 근거 · https://www.jobscan.co/blog/ats-formatting-mistakes/ , https://support.jobscan.co/hc/en-us/articles/41334833854099-What-match-rate-should-I-aim-for
|
|
52
|
+
- **Jobscan — Tables & Columns Break Parsing** — 선형 파싱·다단/표가 텍스트 순서를 깨 "word salad"가 되는 메커니즘 근거 · https://www.jobscan.co/blog/resume-tables-columns-ats/
|
|
53
|
+
- **Indeed Career Advice — How To Write an ATS Resume** — 표준 섹션 헤더(Work Experience/Education/Skills), 역연대기 형식, JD 키워드 자연 통합, 표준 폰트 권장 근거 · https://www.indeed.com/career-advice/resumes-cover-letters/ats-resume-template
|
|
54
|
+
- **Ohio Northern University Career Center — ATS Resume Guide (PDF)** — 대학 커리어센터 1차 자료: 표준 헤더·다단/헤더푸터/텍스트박스 회피·연락처 본문 배치 근거 · https://my.onu.edu/sites/default/files/applicant_tracking_system_resume_guide.pdf
|
|
55
|
+
- **프레임워크 근거:** 위 항목들의 공통 합의(single-column, standard headings, body-placed contact, JD keyword coverage)를 셀 수 있는 카운트/비율 체크로 환원함. 날짜 형식·약어 병기·스터핑 임계치는 Jobscan/Indeed 권고를 정규식·카운트 규칙으로 운영화한 것.
|
|
56
|
+
|
|
57
|
+
## 5. Phase B 힌트
|
|
58
|
+
|
|
59
|
+
- **MCP 도구 아이디어:** `get_verifier({ id: "ats-compat" })` — 본 루브릭(JSON 형태의 C1–C12 + 패턴/임계치)을 연결된 AI에게 그대로 serve. 보조로 `get_jd_keywords({ job_id })`가 저장된 공고에서 상위 하드스킬/직무명 키워드 집합(N)을 추출해 C8/C9/C10 카운트의 입력으로 제공.
|
|
60
|
+
- **데이터 형태 힌트:**
|
|
61
|
+
- 루브릭 항목: `{ id, check, pass_rule, measure: { type: "count"|"ratio"|"presence"|"regex", target, threshold, pattern } }` 배열.
|
|
62
|
+
- JD 키워드 페이로드: `{ job_id, hard_skills: string[], job_titles: string[], abbreviations: [{ short, long }] }` — C8(분모 N), C9, C11 입력.
|
|
63
|
+
- 검증 결과 로그: `{ artifact_id, results: [{ id, passed, observed, threshold }], overall_pass, revised: boolean }` — 루프 재검증 추적용. `save_fit_analysis`/버전 메타에 첨부 가능.
|
|
64
|
+
- 표준 헤더 화이트리스트와 허용 날짜 패턴은 도구가 상수로 보유해 클라이언트별 일관성 확보.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 교차 산출물 일관성 (Cross-artifact consistency) — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 커리어 산출물(이력서·자소서·면접 답변·LinkedIn 등)을 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사는 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
## 1. 목적
|
|
6
|
+
|
|
7
|
+
지원자의 여러 산출물(resume ↔ cover letter ↔ 면접 스토리 ↔ LinkedIn)이 **하나의 일관된 사실 서사**를 말하도록 보장한다. 채용 담당자는 "triangulation(삼각 대조)" — 즉 이력서를 LinkedIn·자소서·공개 데이터와 교차 대조해 진위를 확인한다. 따라서 **날짜·직함·회사명·학력·수치·핵심 서사**가 산출물 간에 모순되면 즉시 의심·탈락·평판 손상으로 이어진다.
|
|
8
|
+
|
|
9
|
+
이 검증기가 보장하는 것:
|
|
10
|
+
|
|
11
|
+
- **단일 진실 원천(single source of truth):** 이력서를 기준으로 다른 산출물이 이력서와 **모순되지 않음**(확장·강조는 허용, 변조·충돌은 불가).
|
|
12
|
+
- **사실 앵커의 동일성:** 같은 사실(입·퇴사 월/년, 직함, 회사명, 학위·졸업년도, 정량 수치)이 모든 산출물에서 **같은 값**으로 나타남.
|
|
13
|
+
- **서사의 무모순:** 면접 스토리·자소서가 이력서의 타임라인·역할과 충돌하지 않음(예: 이력서엔 없는 "팀 리드" 주장 등).
|
|
14
|
+
|
|
15
|
+
이 검증기는 *문장이 좋은가*(품질)가 아니라 *서로 어긋나지 않는가*(정합성)만 본다. LLM 없이도 값 비교·존재 여부·개수로 다수 항목을 셀 수 있게 설계했다.
|
|
16
|
+
|
|
17
|
+
## 2. 검사 항목
|
|
18
|
+
|
|
19
|
+
> 측정 단위: "사실 앵커(fact anchor)" = (회사명, 직함, 시작 월/년, 종료 월/년, 정량 수치, 학위명, 졸업년도) 같은 **비교 가능한 토큰**. 검사는 산출물별로 앵커를 추출해 **쌍대 비교(pairwise)** 한 뒤 불일치 개수를 센다.
|
|
20
|
+
|
|
21
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게) |
|
|
22
|
+
|----|------|-----------|------------------------|
|
|
23
|
+
| C1 | 회사명 일치 | 모든 산출물에서 동일 회사를 **같은 표기**(정규화 후)로 지칭. 불일치 0건 | 각 산출물의 회사명 토큰을 추출→소문자·법인접미사(Inc/Ltd/㈜) 정규화 후 집합 비교. 다른 표기로 같은 시기를 지칭하는 쌍 개수 = 0 |
|
|
24
|
+
| C2 | 직함 일치 | 같은 재직 기간의 직함이 산출물 간 동일하거나 명시적 승진 progression. 모순 0건 | (회사, 기간)별 직함 문자열 비교. 동일 (회사,기간)에 서로 다른 직함이 매핑된 쌍 개수 = 0 |
|
|
25
|
+
| C3 | 입·퇴사 날짜 일치 | **월/년 단위**까지 동일. 허용 오차 0개월(채용 배경조사 기준 권장) | 각 경력의 (start MM/YYYY, end MM/YYYY)를 산출물 간 비교. 월 단위 차이가 있는 쌍 개수 = 0. (연도만 적힌 산출물이 있으면 "월 누락" 경고 1건 카운트) |
|
|
26
|
+
| C4 | 타임라인 무모순(중복/공백) | 경력 구간이 산출물 간 동일한 정렬·중복 여부. 한 산출물에만 존재하는 미설명 공백/중복 0건 | 경력 구간을 시간순 정렬 후 산출물 간 구간 집합 차이(set difference) 개수 = 0. 6개월 이상 미설명 공백은 별도 플래그(개수) |
|
|
27
|
+
| C5 | 학력 일치 | 학위명·전공·학교·졸업년도가 모든 산출물에서 동일. 불일치 0건 | (학교, 학위, 졸업년도) 튜플을 산출물 간 비교. 불일치 튜플 쌍 개수 = 0 |
|
|
28
|
+
| C6 | 정량 수치 일치 | 같은 성과의 수치(%, 금액, 인원, 기간)가 산출물 간 동일. 충돌 0건 | 각 산출물에서 숫자+단위 패턴(`\d+%`, 금액, `\d+명` 등) 추출→같은 성과에 매핑된 수치쌍 비교. 값이 다른 쌍 개수 = 0 |
|
|
29
|
+
| C7 | 면접 스토리 앵커 정합 | 면접 STAR 스토리의 회사·역할·시기·수치가 이력서 앵커에 **존재**. 이력서에 없는 신규 사실 0건 | 면접 답변에서 추출한 (회사/역할/수치) 앵커 중 이력서 앵커 집합에 없는 항목 개수 = 0 |
|
|
30
|
+
| C8 | 핵심 스킬/키워드 정합 | 자소서·면접에서 강조한 핵심 역량 상위 N개가 이력서 스킬 섹션에 존재. 누락 ≤ 1 | 자소서/면접 빈출 역량 토큰 상위 N(기본 5)을 이력서 스킬 토큰 집합과 대조→미존재 개수 ≤ 1 |
|
|
31
|
+
| C9 | 연락처/식별자 일치 | 이름·이메일·전화·LinkedIn URL 등 식별 정보가 산출물 간 동일. 불일치 0건 | 정규식으로 식별자 추출 후 정확 일치 비교. 불일치 필드 개수 = 0 |
|
|
32
|
+
| C10 | 산출물 커버리지 | 비교 가능한 산출물이 **2종 이상** 존재해야 교차검증이 의미. 1종이면 "교차검증 불가" 경고 | 입력으로 제공된 산출물 종류 개수 ≥ 2 (미달 시 검사 skip + 경고 1건) |
|
|
33
|
+
|
|
34
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
35
|
+
|
|
36
|
+
검사 결과는 **불일치 앵커 목록**으로 반환한다. 각 항목은 `{check_id, artifact_a, artifact_b, value_a, value_b, severity}` 형태.
|
|
37
|
+
|
|
38
|
+
- **C1·C2·C3·C5·C9 불일치(critical):** 즉시 **이력서를 진실 원천으로 고정**하고, 충돌하는 다른 산출물을 이력서 값에 맞춰 수정 지시. 단, 이력서 자체가 사실과 다르다는 사용자 확인이 있으면 이력서를 먼저 정정한 뒤 전 산출물 동기화. 수정 후 **C1~C9 재검증**(불일치 0 될 때까지 루프).
|
|
39
|
+
- **C4 공백/중복(warning):** 6개월+ 미설명 공백은 사용자에게 설명(연수·육아·창업 등) 요청 → 모든 산출물에 동일 문구로 반영. 재검증.
|
|
40
|
+
- **C6 수치 충돌(critical):** 어느 수치가 사실인지 사용자에게 확인 → 단일 값으로 통일(과장 금지). 사실·고유명사·수치는 보존이 원칙이므로 임의 평균·추정 금지. 재검증.
|
|
41
|
+
- **C7 신규 사실(critical):** 면접 스토리에만 등장하는 사실은 (a) 이력서에 추가하거나 (b) 스토리에서 제거. 두 산출물이 같은 앵커를 공유할 때까지 루프.
|
|
42
|
+
- **C8 키워드 누락(warning):** 핵심 역량을 이력서 스킬 섹션에 추가하거나, 자소서/면접에서 과대 강조를 완화. 재검증.
|
|
43
|
+
- **C10 커버리지 부족:** 검사를 막지 말고 "교차검증 불가, 산출물 1종만 존재"를 사용자에게 안내. 다른 산출물 추가 시 재실행.
|
|
44
|
+
- **종료 조건:** critical 불일치 0건 + warning은 사용자 확인 완료. 통과 시 `save_fit_analysis`/`save_cover_letter_version` 등 다음 단계로 진행, 대시보드 링크 안내.
|
|
45
|
+
|
|
46
|
+
## 4. 출처 (Provenance)
|
|
47
|
+
|
|
48
|
+
- **Triangulation / 단일 진실 원천 원칙** — 채용 담당자가 이력서를 LinkedIn·자소서·공개 데이터와 교차 대조해 진위 확인. Washington State University, Carson College of Business 커리어 가이드 · https://business.wsu.edu/resumes-references-and-cover-letters/
|
|
49
|
+
- **Resume·Cover Letter·LinkedIn 동기화(직함/날짜/회사명/수치 일치)** — The Interview Guys, "Resume, Cover Letter, and LinkedIn Profile Synchronization" · https://blog.theinterviewguys.com/resume-cover-letter-and-linkedin-profile-synchronization/
|
|
50
|
+
- **월/년 단위 날짜 일치, 수치 충돌(40% vs 75%) 신뢰 훼손** — Resume Worded, "Should Your LinkedIn Match Your Resume?" · https://resumeworded.com/should-linkedin-match-resume-key-advice
|
|
51
|
+
- **Employment verification(직함·재직기간·역할 확인)** — LinkedIn Business, HR Glossary: Employment Verification · https://business.linkedin.com/in/en/hire/resources/hr-glossary/employment-verification
|
|
52
|
+
- **STAR 프레임워크(Situation·Task·Action·Result)와 정량 결과** — MIT Career Advising & Professional Development(CAPD), "The STAR Method for Behavioral Interviews" · https://capd.mit.edu/resources/the-star-method-for-behavioral-interviews/
|
|
53
|
+
- **이력서/자소서 STAR bullet과 면접 스토리 정합(같은 정량 성과 재사용)** — San Francisco State University, Career & Leadership Development: Resume/Cover Letter/LinkedIn · https://career.sfsu.edu/resume-cv-cover-letter-linkedin
|
|
54
|
+
|
|
55
|
+
## 5. Phase B 힌트
|
|
56
|
+
|
|
57
|
+
- **MCP 도구 아이디어:** `get_verifier({ id: "consistency" })` — 이 루브릭(JSON 직렬화) 반환. `run_consistency_check({ artifacts })` — 연결된 AI가 추출한 앵커 배열을 받아 C1~C10 쌍대 비교를 코드로 수행(LLM 불필요)하고 불일치 목록 반환.
|
|
58
|
+
- **데이터 형태 힌트:**
|
|
59
|
+
- 입력: `{ artifacts: [{ type: "resume"|"cover_letter"|"interview"|"linkedin", anchors: { companies, titles, dates, education, metrics, identifiers, skills } }] }`. 앵커 추출(자연어→구조화)은 연결된 AI 담당, 비교 로직은 결정적 코드.
|
|
60
|
+
- 출력: `{ pass: bool, criticals: [...], warnings: [...], mismatches: [{check_id, artifact_a, artifact_b, value_a, value_b}] }`.
|
|
61
|
+
- 저장: `get_application_context`가 이미 프로필·대표 이력서·기존 자소서를 반환하므로, 그 앵커를 캐시해 두면 신규 산출물만 추가 비교 가능. 결과는 `save_fit_analysis`의 일부 메타로 보관 가능.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# 사람 목소리 (Human-voice) — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 커리어 산출물(이력서·자소서·면접 답변·LinkedIn 등)을 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사는 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
## 1. 목적
|
|
6
|
+
|
|
7
|
+
이 검증기는 커리어 산출물이 **"AI가 쓴 티"가 나지 않고 사람의 목소리로 읽히는지**를 보장한다. 채용 담당자는 천편일률적인 자동 생성 글을 즉시 알아채고 신뢰를 거둔다. 구체적으로 다음 네 가지를 본다.
|
|
8
|
+
|
|
9
|
+
1. **슬롭 구문 밀도** — `delve`, `leverage`, `tapestry`, "오늘날과 같은", "~에 대한 열정" 같은 LLM 상투어·필러가 과하게 깔려 있지 않은가.
|
|
10
|
+
2. **문장 길이 다양성 (burstiness)** — 짧은 문장과 긴 문장이 섞여 사람처럼 들숨날숨이 있는가, 아니면 비슷한 길이로 단조롭게 흐르는가.
|
|
11
|
+
3. **목소리 일관성** — 어조·인칭·격식 수준이 글 전체에서 한 사람의 것으로 유지되는가, 짜깁기처럼 튀는 구간이 있는가.
|
|
12
|
+
4. **사실·숫자·고유명사 보존** — 사람 목소리로 다듬는 과정에서 원본의 수치·날짜·회사명·기술명이 누락·왜곡되지 않았는가(절대 손상 금지 항목).
|
|
13
|
+
|
|
14
|
+
핵심: 이 루브릭의 검사 항목은 **LLM 없이도 세거나(개수)·존재 여부 확인·비율 계산·패턴 매칭으로 판정**할 수 있게 설계되었다. 연결된 AI는 직접 세고, CareerMate는 원본/대상 텍스트와 이 기준표를 제공한다.
|
|
15
|
+
|
|
16
|
+
## 2. 검사 항목
|
|
17
|
+
|
|
18
|
+
> 적용 단위: 한 산출물(자소서 1편, 이력서 1부, 면접 답변 1세트 등). "문장"은 종결부호(`.`, `!`, `?`, `다.`, `요.`) 기준으로 분할한다. 한국어/영어 혼용 글도 동일 규칙을 적용한다.
|
|
19
|
+
|
|
20
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게) |
|
|
21
|
+
|----|------|-----------|------------------------|
|
|
22
|
+
| C1 | 슬롭 단어 밀도 | 슬롭 사전 단어가 **100단어당 1.5개 이하**, 그리고 동일 슬롭 단어가 **3회 초과 반복 없음** | 아래 §슬롭 사전과 대조해 일치 토큰 수를 센다 → (일치 수 ÷ 전체 단어 수) × 100. 단어별 등장 횟수도 집계 |
|
|
23
|
+
| C2 | 슬롭 상투 구문 존재 | 금지 상투 구문 **0건** | 아래 §상투 구문 목록을 부분 문자열로 탐색, 매칭 건수 카운트 |
|
|
24
|
+
| C3 | 문장 길이 다양성 (burstiness) | 문장 길이의 **표준편차 ≥ 5단어**, 그리고 **최단 문장 ≤ 8단어**인 문장이 1개 이상 존재 | 각 문장 단어 수 배열 → 표준편차 계산, 최솟값 확인 |
|
|
25
|
+
| C4 | 문장 시작어 반복 | 동일 단어로 시작하는 문장이 **전체의 30% 미만**, 같은 시작어 **연속 3문장 금지** | 각 문장 첫 단어(조사 제외)를 모아 빈도 집계, 연속 동일 여부 확인 |
|
|
26
|
+
| C5 | 단락 구조 단조성 (rule-of-three 남용) | "A, B, and/그리고 C" 형태 3단 병렬이 **단락당 1회 이하**, 글 전체 **3회 이하** | 3항 병렬 패턴(쉼표 2개 + 접속사) 매칭 수를 센다 |
|
|
27
|
+
| C6 | 과장 형용사·부사 밀도 | "혁신적/seamless/robust/cutting-edge/획기적" 류 과장어가 **100단어당 1개 이하** | §과장어 사전과 대조해 일치 수 카운트 → 비율 계산 |
|
|
28
|
+
| C7 | 인칭·어조 일관성 | 주 인칭(1인칭/3인칭)·문체(평서 "~다" vs 경어 "~습니다") 혼용이 **전체 문장의 10% 미만**, 격식 급변 구간 0 | 종결어미 유형을 문장별 태깅해 소수 유형 비율 계산 |
|
|
29
|
+
| C8 | 사실·숫자 보존 | 원본의 모든 숫자(수치·퍼센트·연도·금액)가 대상 텍스트에 **100% 존재** | 원본에서 숫자 토큰 집합 추출 → 대상에 모두 포함되는지 집합 비교(누락 0) |
|
|
30
|
+
| C9 | 고유명사 보존 | 원본의 회사명·제품명·기술명·자격증명 등 고유명사가 **100% 보존**, 철자 변형 0 | 원본 고유명사 목록 추출 → 대상에서 정확 일치 확인(누락·오타 0) |
|
|
31
|
+
| C10 | 빈말 채움(filler) 문장 | 정보 없는 채움 문장("~에 대한 저의 열정은 남다릅니다" 류)이 **전체 문장의 5% 미만** | §filler 패턴과 매칭되거나 숫자·고유명사·동사 목적어가 전혀 없는 문장 수를 센다 |
|
|
32
|
+
| C11 | 구체 증거(수치·사례) 존재 | 본문에 **정량 근거(숫자/기간/규모/성과 지표)가 최소 2개** 이상 | 숫자+단위/퍼센트/"N배"/"N명"/"N개월" 패턴 매칭 수가 2 이상인지 확인 |
|
|
33
|
+
|
|
34
|
+
### 슬롭 사전 (C1 — 부분 일치로 카운트)
|
|
35
|
+
|
|
36
|
+
영어: `delve, leverage, utilize, harness, streamline, underscore, robust, seamless(ly), pivotal, comprehensive, multifaceted, holistic, tapestry, landscape, realm, synergy, testament, beacon, paradigm, embark, navigate, unlock, unleash, empower, bespoke, foster, showcase, intricate, meticulous, vibrant, furthermore, moreover, additionally`
|
|
37
|
+
|
|
38
|
+
한국어: `오늘날과 같은, 급변하는, 빠르게 변화하는, ~의 세계, 핵심적인 역할, 다양한 측면, 총체적, ~을(를) 통해 ~을(를) 도모, ~에 대한 깊은 이해, 가교 역할, 등불, 여정, 발돋움, 시너지, ~을 도모하고자`
|
|
39
|
+
|
|
40
|
+
### 상투 구문 목록 (C2 — 0건이어야 함)
|
|
41
|
+
|
|
42
|
+
`In today's [digital] age / In the fast-paced world of / It's important to note / It's worth noting / I hope this message finds you well / Let's dive in / embark on a journey / game changer / 오늘날과 같이 급변하는 / 본 지원자는 / 귀사의 무궁한 발전을 / 지원하게 되어 영광입니다 / 위에서 언급한 바와 같이 / 결론적으로 말씀드리자면`
|
|
43
|
+
|
|
44
|
+
### 과장어 사전 (C6)
|
|
45
|
+
|
|
46
|
+
`혁신적, 획기적, 탁월한, 압도적, 독보적, seamless, robust, cutting-edge, innovative, transformative, groundbreaking, world-class, game-changing, 최고의, 완벽한`
|
|
47
|
+
|
|
48
|
+
### filler 패턴 (C10)
|
|
49
|
+
|
|
50
|
+
문장 안에 (a) 숫자, (b) 고유명사, (c) 구체적 행위 동사+목적어 가운데 **하나도 없으면** 빈말 후보로 카운트. 예: "저는 이 일에 대한 열정이 누구보다 큽니다.", "최선을 다하겠습니다.", "많은 것을 배웠습니다."
|
|
51
|
+
|
|
52
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
53
|
+
|
|
54
|
+
연결된 AI는 위 항목을 채점해 **불합격 항목 ID + 근거(센 수치/매칭된 문자열/위치)** 를 모은다. 그다음 항목별로 아래 수정 지시를 적용해 **재작성 → 동일 루브릭 재검증**한다. 재검증 통과까지 반복하되, **C8·C9(사실·고유명사 보존)는 단 1건이라도 위반 시 즉시 하드 실패**로 처리하고 다른 어떤 개선보다 우선해 복구한다.
|
|
55
|
+
|
|
56
|
+
- **C1·C2·C6 위반(슬롭/상투/과장)**: 매칭된 단어·구문을 나열하고, 각각을 그 사람의 실제 경험·맥락에서 나온 **구체 표현으로 1:1 치환**한다. 일반론을 사실로 바꾼다. 치환 후 밀도를 다시 센다.
|
|
57
|
+
- **C3·C4·C5 위반(단조로움)**: 긴 문장 1~2개를 쪼개 **짧은 강조 문장(≤8단어)** 을 삽입하고, 연속으로 같은 시작어를 쓴 문장의 도입부를 바꾼다. 3단 병렬을 1개로 줄이거나 문장 형태를 비대칭으로 푼다. 표준편차·시작어 분포를 재측정한다.
|
|
58
|
+
- **C7 위반(목소리 불일치)**: 다수 종결어미·인칭으로 **전체를 통일**한다. 격식이 튀는 구간을 주변 톤에 맞춰 다시 쓴다.
|
|
59
|
+
- **C10·C11 위반(빈말/근거 부족)**: 빈말 문장을 삭제하거나, 원본 데이터(`get_application_context`로 받은 경력·성과·스킬)에서 **수치·사례를 끌어와** 구체화한다. 없으면 지어내지 말고 사용자에게 해당 수치를 묻는다.
|
|
60
|
+
- **C8·C9 위반(사실/고유명사 손상)**: 원본에서 누락·왜곡된 숫자·고유명사를 **원문 그대로 복원**한다. 추정·대체 금지. 복원 후 집합 비교를 재수행해 100%를 확인한다.
|
|
61
|
+
|
|
62
|
+
재검증 종료 조건: **C1~C7·C10·C11 전부 합격 + C8·C9 위반 0건**. 한 항목이라도 불합격이면 루프를 멈추지 않는다.
|
|
63
|
+
|
|
64
|
+
## 4. 출처 (Provenance)
|
|
65
|
+
|
|
66
|
+
- **Perplexity & Burstiness (AI 텍스트 탐지 프레임워크)** — 사람 글은 문장 길이·구조의 변동성(burstiness)이 크고 AI 글은 균일하다는 1차적 구분 신호. C3·C4의 근거. · https://quillbot.com/blog/ai-writing-tools/burstiness-and-perplexity/ , https://www.tryleap.ai/learn/perplexity-vs-burstiness
|
|
67
|
+
- **Wikipedia: Signs of AI writing** — 셀 수 있는 AI 작성 신호 목록(과용 단어, rule of three, "not only X but also Y" 병렬, title-case, em-dash·곡선 따옴표). C1·C2·C5의 근거. · https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing
|
|
68
|
+
- **ChatGPT 과용 단어 목록 (Walter Writes AI / Alston Antony)** — `delve, leverage, tapestry, robust, seamless` 등 슬롭 사전과 상투 구문의 1차 근거. C1·C2·C6. · https://walterwrites.ai/most-common-chatgpt-words-to-avoid/ , https://alstonantony.com/seo-strategy/chatgpt-overused/
|
|
69
|
+
- **Harvard FAS Mignone Center for Career Success — Resume & Cover Letter Guide** — 의무가 아닌 성과, 측정 가능한 수치·구체 사례로 뒷받침하라는 권고. C10·C11의 근거. · https://careerservices.fas.harvard.edu/resources/harvard-college-guide-to-resumes-cover-letters/
|
|
70
|
+
- **STAR 방법 + 정량 성과 (Resume.io / Teal 클리셰 가이드)** — "excellent communication skills" 같은 빈말을 "20% 향상" 같은 수치로 대체. C10·C11·C2. · https://resume.io/blog/star-method-resume , https://www.tealhq.com/post/resume-buzzwords-and-cliches
|
|
71
|
+
|
|
72
|
+
## 5. Phase B 힌트
|
|
73
|
+
|
|
74
|
+
- **MCP 도구 아이디어:**
|
|
75
|
+
- `get_verifier({ id: "human-voice" })` — 이 루브릭(검사 항목·사전·기준)을 구조화 JSON으로 연결 AI에 제공.
|
|
76
|
+
- `get_verifier_dictionaries({ lang })` — 슬롭/과장/상투 사전을 언어별로 분리 제공(한·영). 사전은 데이터로 두고 버전 관리해 신어 추가가 쉽게.
|
|
77
|
+
- (선택) `precount_human_voice({ text, original })` — LLM 없이 결정적으로 셀 수 있는 항목(C1, C3, C8, C9, C11)을 CareerMate가 로컬에서 미리 카운트해 후보 위반을 표시(연결 AI는 판단만). 단, 두뇌는 외부 AI라는 원칙상 "측정 보조"로만 한정.
|
|
78
|
+
- **데이터 형태 힌트:**
|
|
79
|
+
- 검사 항목: `{ id, label, pass_rule, measure, severity: "soft"|"hard" }`. C8·C9는 `severity:"hard"`.
|
|
80
|
+
- 사전: `{ lang, category: "slop"|"hype"|"cliche"|"filler", terms: string[], match: "substring"|"regex" }`.
|
|
81
|
+
- 결과 리포트: `{ outcome: "pass"|"fail", failed_checks: [{ id, observed, threshold, evidence: string[] }], loop: "rewrite"|"done" }` — 루프 오케스트레이션이 `failed_checks`만 보고 재작성 지시를 생성.
|
|
82
|
+
- 임계값(1.5/100단어, σ≥5 등)은 코드 상수가 아니라 설정값으로 두어 산출물 유형(이력서 vs 자소서)별 프로파일을 허용.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# 신선도·시의성 / Recency & Staleness — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 커리어 산출물(이력서·자소서·면접 답변·LinkedIn·분석 등)을 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사는 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
## 1. 목적
|
|
6
|
+
|
|
7
|
+
이 검증기는 **모든 커리어 산출물이 "충분히 최신인 입력 위에서, 그 입력의 수집·기준 시점을 정직하게 드러내며" 만들어졌음**을 보장한다. 즉 적합도 분석은 *현재 버전*의 이력서·JD에 근거했고, 연봉 협상은 *아직 stale하지 않은* 시장 데이터에 근거했으며, 회사 리서치의 "최근 뉴스"가 *실제로 최근*이고, 모든 시점 민감 주장에 **as-of 날짜(기준일)** 가 붙어 있음을 검사한다. 이것은 데이터 품질의 표준 차원인 **timeliness(필요 시점 가용성)·currency(현실 반영 최신성)** 를 커리어 산출물에 적용한 게이트다(DAMA DDQ).
|
|
8
|
+
|
|
9
|
+
이 검증기가 막으려는 5가지 실패 모드:
|
|
10
|
+
|
|
11
|
+
- **stale 시장데이터로 협상(stale benchmark):** 6개월·12개월 지난 연봉 벤치마크를 "현재 시세"처럼 인용해 협상 앵커를 잘못 잡음.
|
|
12
|
+
- **낡은 뉴스를 "최근"으로 표기(false recency):** 12~18개월 지난 사건을 "최근 출시/투자/조직개편"으로 면접에서 인용 → 준비 부족 노출.
|
|
13
|
+
- **버전 드리프트(version drift):** 이력서·JD가 바뀐 뒤에도 옛 버전에 근거한 적합도 분석·자소서를 그대로 사용(재분석 트리거 없음).
|
|
14
|
+
- **날짜 없는 시점주장(undated temporal claim):** "최근", "현재", "요즘"이라 하면서 기준일이 없어 검증·갱신 불가능.
|
|
15
|
+
- **만료 자격·기간 미갱신(expired credential / open-ended tenure):** 만료된 자격증·인증, "현재 재직 중"인데 종료된 포지션, 미래 졸업/이수 예정을 완료로 표기.
|
|
16
|
+
|
|
17
|
+
> 경계 원칙: **이 검증기는 "사실이 참인가"(진실성)가 아니라 "그 사실이 아직 유효·최신이고, 시점이 드러나 있는가"(시의성)만 본다.** 사실은 참이어도 6개월 전 데이터면 협상에서는 위험하고, "최근"이라는 라벨은 시점이 붙어야만 검증된다. 이는 진실성(`truthfulness.md`)·일관성(`consistency.md`)과 **독립 축**이다 — 그 둘은 "값이 저장 데이터와 일치/무모순한가"를 보지만, 이 검증기는 "그 값·입력이 *언제* 것이고 *지금도 유효한가*"라는 시간 축을 단독으로 본다.
|
|
18
|
+
|
|
19
|
+
핵심 제약상 "6개월"의 적정성·뉴스의 실제 최신성 같은 의미 판단은 결정론으로 100% 셀 수 없다. 따라서 항목을 **(가) LLM 없이 날짜 비교·존재여부로 셀 수 있는 결정론 게이트**와 **(나) 연결된 AI가 라벨·맥락을 판정하는 항목**으로 나눠 설계하고, 각 항목에 어느 쪽인지 표시한다.
|
|
20
|
+
|
|
21
|
+
## 2. 검사 항목
|
|
22
|
+
|
|
23
|
+
표기: **[det]** = CareerMate가 LLM 없이 셀 수 있는 결정론 체크(날짜 차이·존재여부·정규식·비율). **[ai]** = 연결된 AI가 라벨·의미를 판정(개수로 환원해 보고). 기준일 `now`는 검증 실행 시각(예: 2026-06-17).
|
|
24
|
+
|
|
25
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게; det/ai 구분) |
|
|
26
|
+
|----|------|-----------|------------------------|
|
|
27
|
+
| C1 **[det]** | **시장데이터 신선도(benchmark staleness)** — 연봉·보상 벤치마크의 `captured_at`이 임계(기본 6개월) 이내인가 | stale 벤치마크 사용 = **0** (또는 stale 표기 후에만 참고치로 사용) | 협상/오퍼평가에 쓰인 각 benchmark의 `captured_at`과 `now`의 개월차 계산 → `months_diff > 6` 건수 보고. `> 6`인데 산출물에 `stale` 라벨이 없으면 FAIL. `> 12`는 critical |
|
|
28
|
+
| C2 **[ai]** | **"최근 뉴스" 스테일 FAIL** — '최근'으로 라벨된 회사 리서치 fact의 출처 날짜가 6개월 이내인가 | 6개월 초과를 "최근"으로 표기 = **0** | `label=='recent'`인 fact의 `dated`(YYYY-MM)와 `now`의 개월차 계산 → `months_diff > 6` 건수 보고. AI는 산문 속 "최근/요즘/현재"가 어느 fact를 가리키는지 매핑. 12~18개월 초과는 `stale`로 강제 라벨 |
|
|
29
|
+
| C3 **[det]** | **분석 입력 버전 추적(version provenance)** — 적합도 분석·자소서가 근거한 이력서 버전 ID·JD 식별자가 기록되어 있는가 | `resumeVersionId`·`jobId`(또는 JD 해시) 둘 다 존재 | 산출물 메타에 `resumeVersionId != null && jobId != null` 여부. 하나라도 null이면 FAIL(재분석 트리거 불능) |
|
|
30
|
+
| C4 **[det]** | **버전 드리프트 감지(stale analysis)** — 분석이 근거한 이력서·JD 버전이 *현재* 저장 버전과 동일한가 | 드리프트 = **0** | 산출물의 `resumeVersionId`·JD 해시를 저장된 *최신* 버전 ID·해시와 비교 → 불일치 건수 보고. 불일치면 "근거 데이터가 바뀜 → 재분석 필요" 플래그 |
|
|
31
|
+
| C5 **[det]** | **시점주장 날짜 부착(dated temporal claims)** — 시점 민감 표현("최근/현재/요즘/올해/지난 분기/now")에 기준일(as-of)이 붙어 있는가 | 날짜 없는 시점주장 = **0** | 정규식 `(최근\|요즘\|현재\|올해\|작년\|지난\s?(분기\|해\|달)\|recent\|currently\|as of\|latest)`로 시점표현 토큰 수 `N_temporal`를 센다 → 같은 절(clause) 내 또는 출처 메타에 `YYYY`/`YYYY-MM` 동반 비율 계산 → 날짜 미동반 건수 보고 |
|
|
32
|
+
| C6 **[ai]** | **자격·인증 유효기간(credential expiry)** — 만료일이 있는 자격증·인증(예: AWS/PMP/어학성적 2년 유효)이 `now` 기준 유효한가 | 만료된 자격을 유효처럼 표기 = **0** | 자격 항목의 `expires_at`(또는 취득일+유효기간 규칙)을 `now`와 비교 → 만료 건수 보고. 만료된 항목은 "취득(만료)"로 표기하거나 갱신 안내. 만료일 미상은 `[유효기간 확인 필요]` 1건 |
|
|
33
|
+
| C7 **[det]** | **재직·진행 종료시점 정합(open-ended tenure)** — "현재 재직/진행 중(present/현재)"으로 표기된 항목이 실제로 진행 중인가, 미래 완료를 완료로 적지 않았는가 | 모순 = **0** | `현재\|present\|재직 중\|진행 중` 표기 항목 중 저장 타임라인에 `end_date`가 이미 있는 건수, 그리고 `start_date`나 졸업/이수 예정일이 `now`보다 미래인데 "완료/수료"로 표기된 건수 보고 |
|
|
34
|
+
| C8 **[ai]** | **시한성 정보 만료(time-bound facts)** — 직무·시장·기술 언급이 더는 유효하지 않은 옛 사실이 아닌가(폐기된 제품/지난 펀딩라운드를 "최신"으로, 단종 기술스택을 "현재 트렌드"로) | 만료된 시한 사실 = **0** | AI가 "최신/현재/지금 뜨는/state-of-the-art" 류 시한성 주장 토큰을 센 뒤, 각 주장에 출처 날짜가 있고 그 날짜가 임계 이내인지 판정 → 날짜 없거나 임계 초과 건수 보고 |
|
|
35
|
+
| C9 **[det]** | **신선도 커버리지/비율(freshness ratio)** — 시점 민감 주장 전체 중 (a)날짜가 붙고 (b)임계 이내인 비율 | freshness_ratio = **1.0** | `freshness_ratio = (N_temporal − N_undated − N_stale) / N_temporal`. C1·C2·C5·C8의 분자/분모를 합산해 단일 수치로 보고. 1.0 미만이면 불합격 |
|
|
36
|
+
|
|
37
|
+
> critical 등급: **C1(>12개월 벤치마크)·C2(12~18개월+ 뉴스를 "최근")·C4(버전 드리프트)** 는 발견 시 해당 산출물을 즉시 불합격 처리(낡은 입력으로 한 협상·리서치·분석 차단). C3은 게이트(없으면 추적 불능 → 불합격). C5·C6·C7·C8은 건수 누적으로 판단하되 0을 목표로 하고, C9는 게이트(1.0이어야 합격). 임계 개월수(6/12/18)는 직무·시장에 따라 조정 가능한 파라미터로 둔다(빠르게 변하는 시장은 더 짧게).
|
|
38
|
+
|
|
39
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
40
|
+
|
|
41
|
+
연결된 AI는 아래 순서로 **수정 → 재검증**한다. 재검증은 동일 루브릭 전 항목을 다시 돌려 **C1·C2·C4 critical = 0 이고 C3 존재 = true 이며 C9 freshness_ratio = 1.0** 일 때만 통과로 본다.
|
|
42
|
+
|
|
43
|
+
1. **분류 먼저.** 각 불합격 항목을 (a) stale 입력 (b) false recency 라벨 (c) 버전 드리프트 (d) 날짜 누락 (e) 만료 자격/기간 중 하나로 라벨링한다.
|
|
44
|
+
2. **(a) stale 입력 → 재수집 또는 강등.** stale한 연봉 벤치마크(C1)는 사용자가 **새로 수집**해 `save_compensation_benchmark`로 갱신한 뒤 재분석한다. 즉시 재수집이 불가하면 그 수치를 협상 앵커에서 빼고 "기준일 YYYY-MM, 신선도 주의(참고치)"로 강등 표기한다 — 낡은 수치를 현재 시세로 단정하지 않는다.
|
|
45
|
+
3. **(b) false recency → 라벨 정정 또는 교체.** 6개월 초과 뉴스(C2)는 "최근" 라벨을 떼고 날짜를 명시(`2025-08 발표`)하거나, 라이브로 더 최신 뉴스를 찾아 교체한다. 12~18개월 초과는 `stale`로 표기해 면접 인용에서 제외한다.
|
|
46
|
+
4. **(c) 버전 드리프트 → 재분석 트리거.** 분석의 `resumeVersionId`·JD 해시가 최신과 다르면(C4), 최신 버전으로 적합도 분석·자소서를 **다시 생성**한다. 사용자에게 "이력서/공고가 바뀌어 이전 분석이 낡았다 → 다시 분석한다"를 쉬운 한국어로 안내한다.
|
|
47
|
+
5. **(d) 날짜 누락 → as-of 부착.** 날짜 없는 "최근/현재"(C5)에는 출처 기준일(`YYYY-MM`)을 붙인다. 기준일을 모르면 그 시점 주장을 정성 표현으로 일반화하거나 `[기준일 확인 필요]`로 표시한다(추측 날짜 금지 — 진실성 검증기와 연동).
|
|
48
|
+
6. **(e) 만료 자격/기간 → 갱신 또는 표기.** 만료된 자격증(C6)은 "취득(만료, 갱신 필요)"로 표기하거나 사용자에게 갱신 여부를 묻는다. 종료된 포지션의 "현재 재직 중"(C7)은 실제 `end_date`로 정정하고, 미래 졸업/이수 예정은 "YYYY-MM 졸업예정"으로 표기한다.
|
|
49
|
+
7. **재검증 게이트.** 수정본을 다시 C1~C9에 통과시킨다. critical(C1>12mo·C2 stale·C4 드리프트) 중 하나라도 남으면 루프를 반복한다. 시장 데이터 재수집이 사용자 액션을 요구하면(2회 시도 후에도 미해결), 해당 보상 수치를 산출물에서 보류하고 사용자에게 수집을 요청한다(낡은 값으로 무한 진행 금지).
|
|
50
|
+
8. **저장.** 통과한 산출물만 저장 도구(`save_fit_analysis`·`save_cover_letter_version`·`save_interview_prep`·`save_compensation_benchmark` 등)로 보관한다. 검증 결과 요약(`freshness_ratio=1.0`, `stale=0`, `as_of=YYYY-MM`, 근거 버전 ID)을 산출물 메타에 함께 남겨 다음 재분석 트리거의 기준으로 삼는다.
|
|
51
|
+
|
|
52
|
+
## 4. 출처 (Provenance)
|
|
53
|
+
|
|
54
|
+
- **DAMA DDQ — Dimensions of Data Quality (timeliness / currency)** (1차/표준, 신뢰 높음) — 데이터 품질의 표준 차원으로 **timeliness**(필요 시점에 가용)와 **currency**(현실을 얼마나 최신으로 반영) 정의. 이 검증기를 "커리어 데이터의 timeliness·currency 게이트"로 정초하는 1차 근거. · DAMA-NL, "Dimensions of Data Quality (DDQ) Research Paper v1.2" https://www.dama-nl.org/wp-content/uploads/2020/09/DDQ-Dimensions-of-Data-Quality-Research-Paper-version-1.2-d.d.-3-Sept-2020.pdf
|
|
55
|
+
- **timeliness vs freshness vs currency 구분** (2차/벤더, 보강) — "timeliness=필요 시점 가용, freshness=사용 순간의 최신성, currency=현실과의 최신 일치(6개월 전 이사면 currency 결여)"라는 실무 정의. C5(as-of)·C1·C2 설계의 보강 근거. · Soda, "Data Quality Dimensions: The No-BS Guide" https://soda.io/blog/guide-to-data-quality-dimensions
|
|
56
|
+
- **연봉 시장데이터의 stale 위험·갱신 주기** (2차/벤더, 정성적 방향성) — 보상 밴드가 통상 1년 이상 묵은 데이터로 구축되고, 시장이 빠르게 움직여 stale data가 임금 격차·salary inversion을 낳음. 제공자는 monthly/quarterly, 최신은 weekly/daily 갱신 — **데이터 recency를 반드시 검증하라**는 실무 권고. C1(6개월 임계·stale 플래그)의 직접 근거. · JobsPikr, "Pay Equity Analytics: Stop Using Outdated Salary Data" https://www.jobspikr.com/blog/pay-equity-analytics-compensation-benchmarking/ · Ravio, "How to use market pricing for compensation" https://ravio.com/blog/market-pricing-compensation
|
|
57
|
+
- **연봉 협상 데이터 시의성** (2차/업계, 보조) — 의사 등 빠르게 변하는 직무 시장은 연 1회 서베이로는 부족, 협상엔 더 current한 자료가 필요. C1의 시장별 임계 조정(빠른 시장=짧은 임계) 근거. · American Medical Association, "Must-have dataset for physician salary negotiations" https://www.ama-assn.org/medical-residents/transition-resident-attending/check-out-must-have-dataset-physician-salary
|
|
58
|
+
- **회사 리서치의 "최근 뉴스" 시의성** (대학 커리어센터/2차, 신뢰 높음) — 구체적·최근 동향 언급은 면접 최강 신뢰 신호이며, 낡은 "최근"은 준비 부족을 드러냄. C2의 직접 근거. · UF Career Connections Center, "Four Steps for Researching an Employer" https://career.ufl.edu/four-steps-for-researching-an-employer/ · Ohio State ECS, "How to Research a Company for an Interview" https://www.ecs.osu.edu/news/2025/02/how-research-company-interview
|
|
59
|
+
- **CareerMate 내부 앵커(1차)** — 신선도 우려를 흩어진 채로 두지 않고 횡단 검증기로 승격한 근거: `salary-negotiation.md`(`evaluate_offer`의 `captured_at` 6개월 초과 시 **stale 플래그**·통화/지역 mismatch 규칙) → C1; `company-research.md` **R3**(최근뉴스 `dated` 6개월 이내, 12~18개월 초과 stale, 날짜 날조 금지) → C2·C5; `fit-matching.md` **R10**(분석 근거 `resumeVersionId`·`jobId` 기록으로 재분석 트리거) → C3·C4. · CareerMate `docs/career-os/knowledge/{salary-negotiation,company-research,fit-matching}.md`; `AGENTS.md`(추측 금지·확인 우선)
|
|
60
|
+
|
|
61
|
+
> 로케일 분기: **글로벌(테크)** 은 levels.fyi류 데이터에 `갱신 YYYY-Qn`이 붙어 신선도 추적이 쉽고 시장이 빠르므로 임계를 더 짧게(예: 3~6개월) 둘 수 있다. **한국**은 공채·자사양식 중심에 LinkedIn 침투가 낮아 외부 실시간 신호가 희소하고, 보상 참고치는 잡플래닛 연봉 제보·DART 사업보고서가 주된데 **DART는 연 1회 공시(전사 평균)** 라 본질적으로 최대 ~12개월 묵을 수 있다 → 한국 보상 데이터는 "수집일+공시 회계연도"를 함께 표기하고 6개월 임계를 *경고*로, 12개월을 *critical*로 적용한다(공시 주기 한계를 인정하되 stale를 숨기지 않음).
|
|
62
|
+
|
|
63
|
+
## 5. Phase B 힌트
|
|
64
|
+
|
|
65
|
+
- **MCP 도구 아이디어:**
|
|
66
|
+
- `get_verifier({ id: "recency-staleness" })` — 이 루브릭(JSON: 항목·합격기준·det/ai 플래그·임계 개월수 파라미터·정규식 패턴·critical 등급)을 연결된 AI에게 그대로 serve.
|
|
67
|
+
- `check_staleness({ artifact_id, now })` — det 항목을 CareerMate가 LLM 없이 계산: 저장된 benchmark `captured_at`, fact `dated`, `resumeVersionId`/JD 해시 vs 최신 버전을 `now`와 비교해 `{ stale_benchmarks[], stale_news[], version_drift: bool, undated_temporal_count, freshness_ratio }` 반환. 시점표현 정규식 카운트(C5)도 여기서 수행.
|
|
68
|
+
- `get_freshness_anchors({ scope })` — 신선도 비교용 기준 집합 제공: `{ latest_resume_version_id, latest_jd_hashes[], benchmarks: [{..., captured_at}], credentials: [{name, expires_at}], timeline: [{role, start, end|null}], now }`. C1·C3·C4·C6·C7의 비교 대상으로 직접 사용.
|
|
69
|
+
- **데이터 형태 힌트:**
|
|
70
|
+
- 모든 시점 민감 값에 `as_of`(YYYY-MM 또는 YYYY-Qn)와 `source_dated`를 1급 필드로 강제. benchmark는 `captured_at`(필수)+`region`+`currency`로 평탄화해 신선도/통화/지역을 한 번에 규칙 검증.
|
|
71
|
+
- 산출물 메타에 `freshness: { ratio: 1.0, stale_count: 0, version: { resumeVersionId, jobId|jd_hash }, checked_at, as_of }`를 저장해 (a) `applied`/협상 단계 전환 전 통과 필수 게이팅, (b) 대시보드의 "근거 데이터가 낡음 → 재분석" 배지 표시, (c) 저장된 이력서·JD가 갱신되면 의존 산출물의 `version` 불일치를 감지해 **자동 재분석 큐**에 올리는 트리거로 활용.
|
|
72
|
+
- 임계 개월수(news 6/12·benchmark 6/12)는 시장·로케일별 파라미터 테이블(`thresholds: { news_recent: 6, news_stale: 18, benchmark_warn: 6, benchmark_critical: 12 }`)로 외부화해 빠른 시장은 더 짧게 조정.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# 질문-응답 적합성 / Responsiveness & On-target — CareerMate 교차검증 루브릭 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 검증기는 연결된 AI가 커리어 산출물(이력서·자소서·면접 답변·LinkedIn·분석 등)을 점검할 때 적용하는 **크리틱 루브릭**이다. CareerMate는 루브릭을 제공하고, 실제 검사는 연결된 AI가 수행한다(내부 LLM 없음).
|
|
4
|
+
|
|
5
|
+
## 1. 목적
|
|
6
|
+
|
|
7
|
+
이 검증기는 산출물이 **던져진 질문·요건에 실제로 응답했는가**를 보장한다. 자소서 문항·면접 질문·JD(job description) 요건은 명시적인 "질문"이다. 글이 아무리 매끄럽고(human-voice) 사실에 충실하며(truthfulness) 산출물 간 모순이 없어도(consistency), **묻지 않은 것을 답하면(동문서답) 즉시 탈락**한다. `human-writing` 지침이 경고한 "슬롭 0이어도 동문서답이면 탈락"을 잡는 **마지막 방어선**이다.
|
|
8
|
+
|
|
9
|
+
구체적으로 다음 네 가지 실패 모드를 막는다.
|
|
10
|
+
|
|
11
|
+
- **동문서답(off-target):** 문항이 "지원동기"를 물었는데 성장과정을 쓰거나, 면접관이 "갈등 해결 경험"을 물었는데 일반론으로 답함.
|
|
12
|
+
- **부분 응답(partial coverage):** 한 문항에 여러 하위 질문(예: "경험과 그로부터 배운 점, 그리고 입사 후 계획")이 있는데 일부만 답함.
|
|
13
|
+
- **형식 미충족(format miss):** 문항이 요구한 응답 형식(경험 서술 / 이유 / 향후 계획 / 글자 수)을 충족하지 못함.
|
|
14
|
+
- **요건 미커버(JD gap):** JD가 명시한 필수 요건·키워드가 이력서·자소서에서 한 번도 다뤄지지 않음.
|
|
15
|
+
|
|
16
|
+
> **독립 축 선언:** 이 검증기는 truthfulness(사실이 데이터로 추적되는가)·consistency(산출물 간 모순이 없는가)·ats-compat(기계가 파싱하는가)·human-voice(사람 목소리인가)와 **겹치지 않는 별개의 축**이다. 그 넷은 모두 "답이 좋은가/참인가/일관되는가"를 보지만, 이 검증기만이 **"그게 던져진 질문에 대한 답이긴 한가"(응답성)** 를 본다. 좋은 글이 잘못된 질문에 답하는 경우를 다른 어떤 검증기도 잡지 못한다.
|
|
17
|
+
|
|
18
|
+
핵심: 검사 항목은 가능한 한 **LLM 없이 셀 수 있게**(키워드 교집합 개수·요구 행동 커버리지 비율·형식 토큰 존재 여부·글자 수 비교) 설계했고, 의미 판단이 필요한 항목은 `ai`로 정직하게 표시한다.
|
|
19
|
+
|
|
20
|
+
## 2. 검사 항목
|
|
21
|
+
|
|
22
|
+
> 적용 단위: **(질문, 응답) 쌍** 1개. 질문 = 자소서 문항 1개 / 면접 질문 1개 / JD 요건 블록 1개. 응답 = 그에 대응하는 답변 텍스트.
|
|
23
|
+
> 측정 보조 개념:
|
|
24
|
+
> - **질문 키워드(Q-keyword):** 질문에서 추출한 핵심어(불용어 제거 후 명사·동사·고유명사). 한국어는 조사 분리.
|
|
25
|
+
> - **요구 행동 동사(directive verb):** 질문이 요구하는 응답 행위. 예: "설명하라/서술하라"(경험), "이유는"(근거), "어떻게 하겠는가/계획은"(계획), "배운 점"(교훈).
|
|
26
|
+
> - **det** = LLM 없이 결정론으로 셀 수 있음 · **ai** = 연결된 AI의 의미 판정 필요. 등급 **D**(결정론 게이트) / **H**(휴먼/AI 판정).
|
|
27
|
+
|
|
28
|
+
| ID | 검사 | 합격 기준 | 측정 방법(셀 수 있게; det/ai 구분) |
|
|
29
|
+
|----|------|-----------|------------------------|
|
|
30
|
+
| C1 | 질문↔응답 매핑 존재 | 모든 질문에 **대응 응답 블록이 1:1 존재**. 미응답 문항 0개 | det/D · 입력된 질문 개수 = 응답 블록 개수인지 비교. 매핑 안 된 질문 ID 개수 = 0 |
|
|
31
|
+
| C2 | 요구 행동 커버리지 | 질문이 요구한 directive 행동을 **모두** 충족(예: "경험+배운점+계획" 3요소면 3개 모두). 충족률 = 100% | det/D · 질문에서 directive 동사 목록 추출 → 응답에서 각 요소 대응 문장 존재 여부 태깅 → (충족 요소 수 ÷ 요구 요소 수). 1.0 미만이면 미충족 요소 나열 |
|
|
32
|
+
| C3 | 질문 키워드 교집합 | 응답이 Q-keyword 상위 N개(기본 5) 중 **≥ 60%** 를 본문에서 다룸(동의어 허용) | det/D(정확 일치) + ai/H(동의어·환언 판정) · 교집합 토큰 수 ÷ N. 미달 시 누락 키워드 목록 출력 |
|
|
33
|
+
| C4 | 첫 문장 온타깃 | 응답 **첫 1~2문장**이 질문 주제어를 직접 언급(두괄식·결론 우선). 서론만 길고 본론 없는 "워밍업" 금지 | det/D · 첫 1~2문장에 Q-keyword가 1개 이상 등장하는가(존재 여부) |
|
|
34
|
+
| C5 | 형식 토큰 충족 | 문항이 명시한 형식 요소가 모두 존재. 예: STAR 면접이면 Situation·Task·Action·Result 4요소, "구체적 사례" 요구면 사례 1건+ | det/D · 형식 체크리스트별 대응 토큰/구간 존재 카운트 → 누락 요소 수 = 0 |
|
|
35
|
+
| C6 | 글자 수/분량 준수 | 자소서 문항의 **글자 수 상·하한**을 지킴(한국 공채 자사양식의 핵심 탈락 사유). 범위 내 | det/D · 응답 길이(공백 포함/제외 둘 다) vs 문항 제한. 초과·미달 글자 수 출력 |
|
|
36
|
+
| C7 | 질문 직접 응답성 | 응답이 질문에 **직접** 답하고 우회·일반론으로 빠지지 않음(off-target/회피 0건) | ai/H · 연결 AI가 "이 응답이 이 질문에 답하는가"를 Y/N 판정. N이면 빗나간 지점 명시 |
|
|
37
|
+
| C8 | JD 필수 요건 커버리지 | JD의 **필수(required) 요건** 항목 중 산출물(이력서+자소서)에서 다뤄진 비율 **≥ 80%**, 필수 요건 미커버 **0개** | det/D · JD에서 필수/우대 요건 분리 추출 → 각 요건 키워드가 산출물에 존재하는지 매칭 → (커버 요건 ÷ 전체 필수). 미커버 필수 요건 나열 |
|
|
38
|
+
| C9 | JD 우대 요건 커버리지 | **우대(preferred)** 요건 커버 비율 보고(차단 아님, 경고). 권장 ≥ 50% | det/D · C8과 동일 로직을 우대 요건에 적용. 비율만 리포트, 미달은 warning |
|
|
39
|
+
| C10 | 과잉/딴소리 비율 | 응답 중 질문과 무관한 문장(Q-keyword·directive 어느 것과도 무관) 비율 **< 20%** | det/D + ai/H · 각 문장을 질문 관련/무관으로 태깅(키워드 매칭=det, 환언 무관 판정=ai) → 무관 문장 비율 |
|
|
40
|
+
| C11 | 질문 전제·제약 준수 | 질문이 건 제약(예: "**팀** 경험", "**실패** 사례", "최근 3년 내")을 응답이 위반하지 않음 | ai/H · 질문의 한정어(팀/개인, 성공/실패, 기간) 추출 → 응답 사례가 그 한정과 일치하는지 판정. 위반 사례 개수 = 0 |
|
|
41
|
+
|
|
42
|
+
### Locale 분기 (한국 vs 글로벌)
|
|
43
|
+
|
|
44
|
+
- **한국(공채·자사양식):** C5·C6이 1차 게이트. 자사양식 문항은 **글자 수 제한이 엄격**하고(C6), "성장과정/지원동기/직무역량/입사 후 포부" 같은 **정형 문항 유형**이 directive를 규정한다(C2). 자소서에 별도 문항이 없고 "자유 기술"이면 C1·C2는 **인재상·직무기술서 키워드**를 질문 대용으로 사용. 포괄임금·공채 특성상 JD가 느슨할 수 있어 C8은 **채용공고+직무기술서+인재상**을 합쳐 요건 풀로 만든다.
|
|
45
|
+
- **글로벌(JD 중심·LinkedIn):** C8·C9가 1차 게이트. JD의 required/preferred 분리와 키워드 커버리지(ATS 정합)가 핵심. 면접은 STAR(C5) 중심. cover letter는 보통 단일 자유 양식이라 C6 대신 **JD 요건 응답성(C8)** 이 주 축.
|
|
46
|
+
|
|
47
|
+
## 3. 불합격 시 처리(루프 연결)
|
|
48
|
+
|
|
49
|
+
연결된 AI는 위 항목을 채점해 **불합격 항목 ID + 근거(미응답 문항 ID·미충족 directive·누락 키워드·초과 글자 수·미커버 요건 목록)** 를 모은다. 그다음 항목별로 아래 수정 지시를 적용해 **보강 재작성 → 동일 루브릭 재검증**한다. 통과까지 반복.
|
|
50
|
+
|
|
51
|
+
- **C1 미응답 문항(critical):** 빠진 문항에 대응하는 답변 블록을 **새로 작성**한다. 데이터가 없으면 지어내지 말고 `get_application_context`/사용자 확인으로 재료를 모은 뒤 작성. 재검증.
|
|
52
|
+
- **C2 directive 미충족(critical):** 누락된 요구 요소(예: "배운 점", "입사 후 계획")를 응답에 **명시적으로 추가**한다. 한국 정형 문항은 해당 문항 유형의 필수 요소표를 적용. 재측정.
|
|
53
|
+
- **C3·C4 온타깃 부족(critical):** 두괄식으로 **첫 문장을 질문 핵심어로 다시 쓰고**, 누락 Q-keyword를 본문에 자연스럽게 반영(키워드 스터핑 금지, 실제 경험 맥락으로). human-voice·truthfulness와 충돌하지 않게 사실 보존. 재측정.
|
|
54
|
+
- **C5 형식 미충족(critical):** 누락 형식 요소를 채운다. STAR면 빠진 S/T/A/R 단계를 보강, "구체적 사례" 요구면 실제 사례 1건을 데이터에서 끌어와 삽입. 없으면 사용자에게 사례를 묻는다. 재검증.
|
|
55
|
+
- **C6 글자 수 위반(critical, 한국):** 초과면 빈말·중복부터 **삭제 우선**(human-voice의 filler 제거와 연계), 미달이면 구체 수치·사례로 **증거 보강**. truthfulness를 깨지 않는 선에서. 범위 안에 들 때까지 루프.
|
|
56
|
+
- **C7·C10·C11 위반(critical):** 질문과 무관한 구간을 **삭제하거나 질문에 맞게 재초점화**한다. C11 전제 위반(예: 성공 사례를 물었는데 실패담)은 **올바른 전제의 사례로 교체**. 재판정.
|
|
57
|
+
- **C8 필수 요건 미커버(critical):** 미커버 필수 요건 각각에 대해 (a) 사용자에게 해당 경험이 있는지 확인 → 있으면 산출물에 반영, (b) 없으면 인접 역량으로 보완하고 갭을 사용자에게 정직히 고지(없는 경험 날조 금지 — truthfulness 게이트 준수). 재검증.
|
|
58
|
+
- **C9 우대 요건(warning):** 차단하지 않고 커버율을 사용자에게 안내. 보유 우대 요건이 있는데 누락됐으면 추가 권유.
|
|
59
|
+
- **종료 조건:** **C1·C2·C5·C7·C8·C11 = 합격(critical 0건)** + C3·C4·C6 합격 + C9·C10은 사용자 확인 완료. 한 critical이라도 불합격이면 루프를 멈추지 않는다. 통과 시 `save_cover_letter_version`/`save_fit_analysis`/`save_interview_prep` 등 다음 단계로 진행하고 대시보드(`http://127.0.0.1:4319`) 링크를 안내한다.
|
|
60
|
+
|
|
61
|
+
## 4. 출처 (Provenance)
|
|
62
|
+
|
|
63
|
+
- **STAR 프레임워크(Situation·Task·Action·Result) — 면접 응답 형식 요건(C5)** — (1차/대학 커리어센터) UVA Career Center · https://career.virginia.edu/Students/Launch/Interviews/STAR ; Northwestern Career Advancement · https://www.northwestern.edu/careers/jobs-internships/interviewing/the-star-approach.html
|
|
64
|
+
- **면접 비응답(off-target)·우회·횡설수설이 부정적 인상과 탈락으로 직결 — 직접 응답성(C7·C10)** — (1차/정부·표준) U.S. DOL/ILAB Enumerator Training: Interviewing Techniques(질문에 직접·간결 응답, 드리프트 시 probing으로 복귀) · https://www.dol.gov/sites/dolgov/files/ILAB/Section%202%20-%20ILAB%20Enumerator%20Training%20Manual%20-%20Interviewing%20Techniques.pdf
|
|
65
|
+
- **응답이 질문과 불일치하는 현상의 측정 가능성(2~4% 반복 비응답) — 응답성을 독립 축으로 계량 가능 근거** — (1차/연구기관) Pew Research Center, "Answers that did not match the question" · https://www.pewresearch.org/methods/2020/02/18/answers-that-did-not-match-the-question-were-concentrated-in-opt-in-polls/
|
|
66
|
+
- **JD 키워드 커버리지·매치율(필수/우대 분리, 섹션 가중, 60~85% 타깃) — JD 요건 응답성(C8·C9)** — (2차/벤더) Jobscan Resume Scanner · https://www.jobscan.co/resume-scanner ; Scale.jobs, "Match Resume Keywords to Job Descriptions" · https://scale.jobs/blog/how-to-match-resume-keywords-to-job-descriptions
|
|
67
|
+
- **한국 자소서 정형 문항 유형(지원동기·성장과정·직무역량·입사 후 포부)과 문항별 요구 요소·평가표 — directive 커버리지(C2)·locale 분기** — (2차/공공·취업지원) 광주광역시 서구 일자리센터, "자기소개서의 이해 및 문항유형" · https://www.seogu.gwangju.kr/menu.es?mid=b70502010200 ; HAIJOB, "자소서 항목별 작성법" · https://www.haijob.co.kr/blog/how-to-prepare-for-each-item-of-cover-letter-motivation-for-application-growth-process-job-competency-aspiration-after-joining-the-company-etc/
|
|
68
|
+
- **한국 자사양식 자소서 글자 수 제한 준수 — 분량 게이트(C6)** — (2차/취업지원) 인크루트, "자소서 직무역량 전략적 작성 TIP" · https://news.incruit.com/news/newsview.asp?newsno=436828
|
|
69
|
+
|
|
70
|
+
## 5. Phase B 힌트
|
|
71
|
+
|
|
72
|
+
- **MCP 도구 아이디어:**
|
|
73
|
+
- `get_verifier({ id: "responsiveness-on-target" })` — 이 루브릭(검사 항목·directive 맵·locale 분기)을 구조화 JSON으로 연결 AI에 제공.
|
|
74
|
+
- `extract_questions({ source })` — 자소서 문항/면접 질문/JD 텍스트에서 질문 단위와 directive·형식·글자 수 제약·전제를 구조화해 추출(추출은 연결 AI, 스키마는 CareerMate가 제공).
|
|
75
|
+
- `precount_responsiveness({ qa_pairs, jd })` — LLM 없이 결정론으로 셀 수 있는 항목(C1 매핑, C2 directive 토큰, C3 키워드 교집합, C4 첫 문장, C5 형식 토큰, C6 글자 수, C8/C9 요건 커버리지)을 로컬에서 미리 카운트해 후보 위반 표시. 의미 판정(C7·C10·C11)은 연결 AI 몫. 두뇌는 외부 AI라는 원칙상 "측정 보조"로만 한정.
|
|
76
|
+
- `get_kr_question_schema({ question_type })` — "지원동기/성장과정/직무역량/입사 후 포부" 등 한국 정형 문항별 필수 요소표(directive 체크리스트)를 데이터로 제공·버전 관리.
|
|
77
|
+
- **데이터 형태 힌트:**
|
|
78
|
+
- 질문: `{ id, source: "cover_letter"|"interview"|"jd", text, directives: ["experience"|"reason"|"plan"|"lesson"], format: ["star"|"example"|...], char_limit: { min, max } | null, constraints: ["team"|"failure"|"recent_3y"], keywords: string[] }`.
|
|
79
|
+
- JD 요건: `{ requirements: [{ text, level: "required"|"preferred", keywords: string[] }] }`.
|
|
80
|
+
- 응답: `{ question_id, text }` (질문과 1:1 매핑).
|
|
81
|
+
- 결과 리포트: `{ outcome: "pass"|"fail", failed_checks: [{ id, observed, threshold, evidence: { unanswered_qids?, missing_directives?, missing_keywords?, char_overflow?, uncovered_requirements? } }], loop: "rewrite"|"gather_data"|"done" }` — 루프 오케스트레이션이 `failed_checks`만 보고 보강 지시를 생성.
|
|
82
|
+
- 임계값(키워드 60%, JD 필수 80%·우대 50%, 딴소리 <20%, 글자 수 등)은 코드 상수가 아니라 설정값으로 두어 산출물 유형·locale(KR/global)별 프로파일을 허용.
|