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,121 @@
|
|
|
1
|
+
# 적합도 매칭 / Fit & Matching — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI(Claude/GPT/Gemini)가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
채용공고(JD)와 후보자 증거(이력서·경력) 사이의 **적합도(fit)** 를 분석하는 지식·루브릭이다. 핵심 방법론은 (1) JD를 **must-have(필수)** vs **nice-to-have(우대)** 로 분해하고 복합 요건은 낱개로 쪼개며, (2) 각 요건을 후보자의 구체적 증거(불릿·수치·기간)에 1:1로 매핑하되 **인용은 원문 부분문자열(exact substring)** 로 강제하고, (3) 충족/부분충족/미충족(gap)을 정직하게 분류하며, (4) gap은 숨기지 말고 전이가능 증거·완화 전략으로 다룬다. CareerMate에는 LLM이 없으므로 루브릭은 **LLM 없이 셀 수 있는 형태**(요건 개수, evidence 배열의 비어있음 여부, quotedBullet이 입력의 substring인가, 분수/퍼센트 패턴 존재)로 설계했다. 적합도는 단일 점수가 아니라 **요건별 분해 + must-have 충족률(맥락 신호) + 결정적 갭(critical/hard-gate) 단독 게이트**로 제시한다.
|
|
8
|
+
|
|
9
|
+
## 2. 플레이북
|
|
10
|
+
|
|
11
|
+
### 원칙
|
|
12
|
+
|
|
13
|
+
- **(must/nice 명시 라벨링 + 복합 요건 분해)** JD의 모든 요건을 must-have('자격요건'·'minimum'·'required'·'X년 이상'·자격증)와 nice-to-have('우대'·'preferred'·'a plus'·'bonus')로 명시적으로 라벨링하고, 쉼표·'및'·'and'·'or'로 묶인 한 줄(예: 'Python·SQL·통계 지식')은 **개별 요건으로 분해**한 뒤 라벨링한다. nice-to-have 미충족은 탈락 사유가 아니다. _(출처: University Career Centers; NCS 직무수행능력/직업기초능력)_
|
|
14
|
+
- **(증거 1:1 매핑 + 원문 substring 인용 강제)** 각 요건에 후보자 이력서·경력의 **구체적 증거 1개 이상**을 출처 식별자(sourceType·sourceId)와 함께 매핑하고, `quotedBullet`/`quotedMetric`은 **입력 원문의 정확한 부분문자열**로 담는다(의역·요약 금지). 매핑 증거가 없으면 그 요건은 gap이며, 증거를 지어내지 마라. substring 강제는 CareerMate가 LLM 없이 환각·수치변형을 서버측에서 거를 수 있게 하는 핵심 장치다. _(출처: STAR 성과 불릿; AGENTS.md 프라임 디렉티브)_
|
|
15
|
+
- **(의미 매칭은 AI 추론, 표면 키워드는 별도 트랙)** JD 용어와 이력서 표현이 다르면('A/B 테스트'≈'실험 설계') 동의어·상위어로 연결하되, 이 **의미 매칭의 정합성 판단은 연결된 AI의 책임**이며 CareerMate가 검증하지 못한다(루브릭에서 자가검증 항목으로 분리). 동시에 JD 핵심 키워드(고유 기술명·자격증명)가 이력서에 그대로 들어가는지 **표면 존재 O/X**로 별도 보고한다. 키워드는 ATS에서 보통 자동탈락 게이트가 아니라 랭킹·가독성 신호다(방향성만 차용; 구체 % 수치는 출처가 약해 인용하지 않음). _(출처: ATS 실증 정리; O*NET 동의어 매핑은 AI 추론 영역)_
|
|
16
|
+
- **(gap 3단계 처리 + false-negative 방지)** gap을 발견하면: (a) 인접·전이가능 증거가 있으면 **partial로 재분류**하되 '왜 full이 아닌지' 사유 1문장을 필수로 적고, (b) 진짜 없으면 **미충족**으로 정직하게 표기, (c) 미충족 must-have에는 완화 전략(전이가능 경험 강조·학습계획·커버레터 해명) 1개를 붙인다. **gap으로 분류한 must-have마다 인접 증거 탐색을 최소 1회 시도한 흔적**을 남겨, 좋은 후보를 과소평가(false-negative)하지 않는다. _(출처: O*NET KSA 위계는 전이가능성의 참고 프로파일이지 직접 판정 근거 아님 — 전이 판단은 AI 추론)_
|
|
17
|
+
- **(충족률은 맥락 신호, 결정적 갭은 단독 게이트)** must-have 충족률(분자=met인 must 개수; **partial은 분자에서 제외**, 분모=전체 must 개수)을 계산하되, 이는 **합격 신호가 아니라 맥락 신호**다. '약 50~60% 구간부터 면접 콜백이 의미있게 오른다'는 관찰은 지원자 풀의 생존편향이 섞인 상관일 뿐 인과가 아니며, must-have만으로 재정의한 임계값은 별도 캘리브레이션이 없는 휴리스틱이다. **critical(직무 핵심)·hard-gate must-have가 하나라도 gap이면 충족률·60% 무관하게 '지원 권장'을 내지 않는다.** _(출처: TalentWorks 분석(CNBC 2018) — 단일·비피어리뷰, 방향성만 차용)_
|
|
18
|
+
- **(사실·수치·고유명사 보존)** 기간·규모·도구·회사명 등 사실·수치·고유명사는 변형 없이 보존하고, 매핑 시 원문 수치를 그대로(substring) 인용한다. 추정·반올림·과장 금지. _(출처: AGENTS.md 보존 규칙; STAR 정량화)_
|
|
19
|
+
- **(하드 게이트 별도 식별 + ATS knockout 인지)** '경력 N년 이상'·국가자격증·면허·비자·근무지 같은 **하드 게이트**는 별도 표시하고 소프트 스킬로 상쇄되지 않음을 분명히 한다. 이런 binary 요건은 ATS의 knockout/스크리닝 사전질문에서 **실제로 자동탈락되는 경우가 흔하다**(키워드 자동탈락은 드물어도 구조화 사전질문 탈락은 흔하다). 따라서 '자동탈락은 드뭄'을 하드 게이트에 일반화하지 마라. _(출처: O*NET 규제요건; NCS 자격요건; ATS knockout 실무)_
|
|
20
|
+
- **(범위 한계 명시 + 오버퀄/방향 불일치)** 이 분석은 '증거로 매핑 가능한 하드 요건' 중심이며, 협업·커뮤니케이션 같은 **soft/culture fit는 다루지 않음을 명시**한다(적합도 ≠ 합격가능성). 또한 미달뿐 아니라 **오버퀄(시니어가 주니어 JD 지원)·커리어 방향 불일치**도 리스크로 표기한다. _(출처: 채용 매니저 실무; O*NET은 soft 신호 판정 도구 아님)_
|
|
21
|
+
|
|
22
|
+
### Do
|
|
23
|
+
|
|
24
|
+
- 분석 시작 전 `get_application_context`를 호출해 프로필·대표 이력서·경력·스킬·대상 공고를 한 번에 확보한다(맥락 없이 분석 금지).
|
|
25
|
+
- JD의 모든 요건을 한 줄씩 추출하고 **복합 줄은 낱개로 분해**한 뒤 표로 만든다. 각 줄에 [필수/우대], [critical 여부], [hardGate 여부], [매핑 증거 출처 ID 또는 GAP]을 단다.
|
|
26
|
+
- 각 매핑 증거는 실제 불릿·경력을 **원문 substring으로 인용**하고, 수치는 그대로 옮긴다.
|
|
27
|
+
- must-have 충족률(met must 수 / 전체 must 수, **partial 제외**)을 계산해 **맥락 신호**로 제시하되, critical·hardGate gap이 있으면 '권장 불가'를 병기한다.
|
|
28
|
+
- 미충족 must-have마다 완화 전략 1개를 적고, gap으로 분류한 must마다 인접 증거 탐색 시도 흔적을 남긴다.
|
|
29
|
+
- JD 핵심 키워드(기술명·자격증·도구)의 이력서 표면 존재 O/X를 의미 매칭과 분리해 별도 점검한다.
|
|
30
|
+
- 저장된 이력서/JD가 바뀌면 분석이 낡으므로, 분석에 **근거가 된 이력서 버전 ID·JD 식별자**를 기록해 재분석 트리거를 남긴다.
|
|
31
|
+
- 결과는 `save_fit_analysis`로 저장하고 대시보드 링크(http://127.0.0.1:4319)를 안내한다.
|
|
32
|
+
- 기술 용어(must-have, ATS, hard-gate 등)는 쉬운 한국어로 풀어 설명한다.
|
|
33
|
+
|
|
34
|
+
### Don't
|
|
35
|
+
|
|
36
|
+
- JD에 없는 요건을 추가하거나, 없는 경력·수치를 지어내 gap을 메우지 마라(환각 금지).
|
|
37
|
+
- 우대(nice-to-have) 미충족을 탈락 사유처럼 다루거나 점수를 깎지 마라.
|
|
38
|
+
- 증거 인용 없이, 또는 의역·요약 인용으로 '충족' 판정하지 마라(인용은 원문 substring).
|
|
39
|
+
- 충족률 60%를 '합격 신호'나 '권장 게이트'로 격상하지 마라 — 맥락 신호다. 100%까지 채우라고 압박하지도 마라.
|
|
40
|
+
- critical·hard-gate(면허·연차·비자·근무지·필수자격증) 미충족을 소프트 스킬로 상쇄해 '지원 권장'을 내지 마라.
|
|
41
|
+
- partial을 '왜 full이 아닌지' 사유 없이 남발해 충족률을 인위적으로 부풀리지 마라.
|
|
42
|
+
- JD의 'required' 라벨을 무비판적으로 신뢰하지 마라 — 요건 인플레이션(특히 연차·학위)을 인지하고, 의심되면 사용자에게 알린다.
|
|
43
|
+
- 사실·수치·고유명사를 반올림·과장·변형하지 마라.
|
|
44
|
+
- 데이터를 외부로 보내거나 웹에서 후보자 정보를 검색하지 마라(모든 데이터는 `~/.careermate` 로컬).
|
|
45
|
+
- gap을 숨기거나 얼버무리지 마라 — 정직하게 미충족으로 표기하고 완화책을 제안하라.
|
|
46
|
+
|
|
47
|
+
### 워크드 예시 (Before → After)
|
|
48
|
+
|
|
49
|
+
1. **Before:** JD 요건 'SQL 기반 데이터 분석 경험' → "데이터 분석 잘하실 것 같아요. 적합합니다." (증거·출처 없음, 추정)
|
|
50
|
+
**After:** 요건 'SQL 기반 데이터 분석' [필수·critical] → 충족. 근거 `{sourceType:resume, sourceId:1, quotedBullet:"주간 매출 대시보드를 SQL로 추출·집계해 12개 캠페인 ROI를 비교, 광고비 18% 재배분"}`(원문 substring). 정확 키워드 'SQL' 이력서 표면 존재(O).
|
|
51
|
+
**왜 더 나은가:** 추정·칭찬 대신 실제 불릿을 출처 ID + **원문 substring**으로 인용했다. CareerMate가 LLM 없이 'quotedBullet이 입력 이력서의 부분문자열인가'를 검증할 수 있고, 키워드 표면 존재는 별도 점검해 환각 여지가 없다.
|
|
52
|
+
|
|
53
|
+
2. **Before:** JD 'PM 3년 이상' 미충족인데 마케팅 경력을 'PM 유사 경험'으로 뭉뚱그려 '충족'으로 표기, 충족률 5/8(62%)로 '60% 상회 → 지원 권장'.
|
|
54
|
+
**After:** 요건 'PM 경력 3년 이상' [필수·hardGate] → 미충족. PM 직함 0년, 마케팅 4년. 완화: 마케팅 중 '신규 기능 베타 운영·우선순위 결정'을 인접 증거로 강조 가능하나 '3년'은 연수 게이트라 상쇄 불가. 커버레터에서 전환 의지 해명 권장. **종합 판정: hard-gate 미충족으로 권장 불가** — 충족률(5/8=62%)은 참고용 맥락 신호이며 권장 근거가 아니다.
|
|
55
|
+
**왜 더 나은가:** hard-gate를 소프트 경험으로 덮지 않았고, 60% 충족률을 '권장 근거'로 쓰지 않았다. 충족률 옆에 '권장 불가'를 강제 병기해 FM-04(충족률)와 FM-05(하드게이트)의 산술 충돌을 제거했다.
|
|
56
|
+
|
|
57
|
+
3. **Before:** "전반적으로 잘 맞습니다(80점)." (요건별 분해·근거 없음, 단일 점수)
|
|
58
|
+
**After:** 적합도 요약 — 필수 8개 중 met 6 / partial 0 / gap 2, 충족률 6/8(75%, partial 제외). 우대 4개 중 1개 충족. 충족 must: [Python(resume#2 불릿), API 설계(experience#4 불릿)]. 미충족 must: [AWS 운영경험 → GCP 경험으로 부분대체 가능(전이, partial 후보지만 'AWS 특화 운영툴 경험 없음'으로 gap 유지), 정보처리기사 → **hardGate 여부 확인 필요**: JD가 '필수'면 권장 불가/'우대'면 가점]. critical·hardGate gap 없음 가정 시에만 충족률을 권장 맥락으로 사용. 보강 1순위: AWS 키워드/경험 명시.
|
|
59
|
+
**왜 더 나은가:** 단일 점수 대신 met/partial/gap을 분해하고 partial 계수 규칙을 명시했다. 자격증의 게이트/가점 판별을 '확인 필요'로 명시해 예시 내 모순(가점 vs 하드게이트)을 제거했다.
|
|
60
|
+
|
|
61
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
62
|
+
|
|
63
|
+
| ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) |
|
|
64
|
+
|----|-----------|-----------|--------------------------------|
|
|
65
|
+
| R1 | 모든 요건에 [필수/우대] 라벨 + 복합 요건 분해 | 라벨 누락 0개; 쉼표·'및'·'and/or'로 묶인 줄이 개별 항목으로 분리됨 | 추출 항목 수를 세고 각 항목에 'must'/'nice' 토큰 존재 확인(누락==0). 원문에서 구분자 포함 줄 수 대비 분해 항목 수가 ≥ 구분자+1 인지 검사 |
|
|
66
|
+
| R2 | 충족·부분충족 판정에 출처 ID + evidence 존재 | status가 met·partial인데 evidence[] 배열이 빈 항목 0개 | (서버 검증 가능) met·partial 항목 수 대비 `evidence.length>0` 항목 수 비율 == 100% |
|
|
67
|
+
| R3 | quotedBullet/quotedMetric이 원문 substring (환각·수치변형 차단) | 인용 문자열이 해당 sourceId 입력 텍스트의 부분문자열이 아닌 항목 0개 | (서버 검증 가능) 각 evidence의 quotedBullet을 입력 이력서/경력 텍스트에 대해 indexOf/`includes` 문자열 검색 → 미발견 개수 == 0 |
|
|
68
|
+
| R4 | gap 표기 + must-have 미충족마다 완화 전략 | 미충족 must 중 mitigation 문장이 없는 항목 0개 | 미충족 must 개수 == mitigation 문장 개수 비교 |
|
|
69
|
+
| R5 | must-have 충족률 수치 제시 + partial 제외 규칙 | 'met must 수 / 전체 must 수' 분수·% 1개 이상; 분자에 partial 미포함 | 분수/% 정규식(예: `\d+/\d+`, `\d+%`)이 must 문맥과 함께 1회 이상; 분자 == status=='met' 개수와 일치 확인 |
|
|
70
|
+
| R6 | critical·hardGate gap 시 '권장 불가' 병기 (게이트 단독 우선) | hardGate 또는 critical이 gap인데 verdict가 'recommend'인 사례 0개 | (서버 검증 가능 — 경고 아닌 **거부**) `requirements`에 `hardGate&&status==gap` 또는 `critical&&status==gap`이 1개라도 있으면 `verdict=='recommend'` 금지 |
|
|
71
|
+
| R7 | 키워드 표면 존재가 의미 매칭과 분리 보고 | JD 핵심 키워드별 'O/X' 표기 1개 이상, 의미 매칭 충족 판정과 별도 필드 | 출력에 `keywordSurfacePresent` 또는 'O/X·있음/없음' 항목 카운트 ≥ 1 |
|
|
72
|
+
| R8 | partial 남용 방지 (사유 강제) | partial 항목 중 '왜 full이 아닌지' 사유 문장이 없는 항목 0개 | partial 항목 수 == partialReason 문장 수 비교 |
|
|
73
|
+
| R9 | gap 과소평가(false-negative) 방지 | gap으로 분류한 must마다 인접 증거 탐색 시도 흔적 존재 | gap must 개수 대비 `transferAttempt` 표기(예: "인접 검토: …") 항목 수 == 100% |
|
|
74
|
+
| R10 | 신선도 추적 | 분석에 근거가 된 이력서 버전 ID·JD 식별자가 기록됨 | 출력/페이로드에 `resumeVersionId`·`jobId`(또는 JD 해시) 필드 존재 여부 == 있음 |
|
|
75
|
+
|
|
76
|
+
**의미 매칭·전이가능성은 LLM 없이 검증 불가** → R2·R3·R5·R6은 CareerMate 서버가 LLM 없이 강제(존재 여부·substring·산술·게이트). 반면 '의역 동의어 매칭이 타당한가', '전이가능성 판단이 옳은가', '요건 추출이 빠짐없는가'는 **외부 AI의 셀프체크 책임**이며 서버가 보증하지 않는다(R1·R4·R8·R9는 형식 카운트만 강제, 내용 타당성은 AI 책임).
|
|
77
|
+
|
|
78
|
+
**주요 실패 모드:**
|
|
79
|
+
- (과대평가) 의역 인용으로 충족 위장 → R3 substring 강제로 차단.
|
|
80
|
+
- (충족률 조작) 복합 요건 미분해로 분모 축소(R1), partial을 분자에 넣어 부풀림(R5), partial 남발(R8).
|
|
81
|
+
- (오권장) hard-gate·critical gap을 충족률로 덮어 'recommend' → R6 서버 거부.
|
|
82
|
+
- (과소평가, 가장 비싼 실패) 전이가능 강점을 못 알아보고 gap으로 깎아 좋은 후보 자기검열 → R9.
|
|
83
|
+
- (낡은 분석) 이력서/JD 갱신 후 옛 분석 재사용 → R10.
|
|
84
|
+
|
|
85
|
+
## 4. 출처 (Provenance)
|
|
86
|
+
|
|
87
|
+
- **O*NET Content Model — U.S. DOL / National Academies** — KSA(지식·스킬·능력) 택소노미와 자격·면허 같은 규제요건 분류의 참고 프로파일. 단, '스킬 A→B 전이가능성'을 직접 판정하지는 않음(전이 판단은 AI 추론). https://www.onetcenter.org/database.html
|
|
88
|
+
- **University Career Centers (Arizona, WVU, Duke, Michigan)** — JD를 자격요건(필수)·책임·개요로 분해, 필수 vs 우대 우선순위, 키워드 미러링·고용주 우선순위 정렬. https://career.arizona.edu/resources/tailoring-your-resume/
|
|
89
|
+
- **ATS 실증 정리 (ResumeAdapter; The Interview Guys)** — '키워드는 자동탈락 게이트가 아니라 랭킹·가독성 신호'라는 **방향성만** 차용(이력서 첨삭 상품 사이트로 1차 연구 아님; '+40% 검토율'·'자동탈락 8%' 같은 구체 % 수치는 출처가 약해 본문 정량 주장으로 쓰지 않음). 단 비자·자격·근무지 같은 knockout 사전질문은 실제 자동탈락이 흔하다는 점을 하드 게이트에 반영. https://www.resumeadapter.com/ats-statistics
|
|
90
|
+
- **TalentWorks 분석 (CNBC 2018, InHerSight)** — '요건 ~50-60% 충족부터 면접 콜백이 오른다'는 관찰. 단일·비피어리뷰·생존편향 가능이라 **인과가 아닌 맥락 신호**로만 사용(must-have 전용 60% 임계값은 별도 캘리브레이션 없는 자작 휴리스틱임을 명시). https://www.cnbc.com/2018/12/12/matching-half-of-a-jobs-requirements-might-still-get-you-an-interview.html
|
|
91
|
+
- **Behavioural Insights Team — 젠더 지원격차** — 이 출처의 실제 결론은 '여성은 100% 충족 시에만 지원' **신화를 반박**한다(실제 격차는 여성 56% vs 남성 52%로 미미). 따라서 '100% 충족 압박은 불필요'의 근거로 인용하되, '여성만 자기검열' 단정은 사용하지 않음(경향성 가설로 수위 조정). https://www.bi.team/blogs/women-only-apply-when-100-qualified-fact-or-fake-news/
|
|
92
|
+
- **STAR 기반 성과 불릿 (Columbia CCE, ResumeBuilder, TopResume)** — 증거→주장 매핑, 정량화 수치 보존, 행동-결과 구조 → 증거 인용·수치 보존 원칙. https://www.resumebuilder.com/career-center/star-method-resume/
|
|
93
|
+
- **NCS 국가직무능력표준 — HRD Korea** — 직무기술서 기반 능력중심채용, **직무수행능력(능력단위)·직업기초능력 구분**(한국 맥락의 필수/우대·하드요건 분류). 'on-spec'은 NCS 표준 용어가 아니라 사용하지 않음. https://www.ncs.go.kr/index.do
|
|
94
|
+
|
|
95
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
96
|
+
|
|
97
|
+
- **MCP 도구 아이디어:** `get_fit_analysis_guide` — 연결된 AI가 적합도 분석 직전 호출하면 (1) 요건 분해·복합 요건 분리 체크리스트, (2) 증거-매핑 템플릿(substring 인용 규칙 포함), (3) R1~R10 셀프-체크 루브릭, (4) 60% '맥락 신호' 규칙·critical/hardGate 단독 게이트 규칙을 구조화 JSON으로 반환. `save_fit_analysis`는 `requirements[]` 구조를 입력받아 **LLM 없이** 충족률·갭 개수를 서버측에서 재계산·검증한다.
|
|
98
|
+
- **데이터 형태 힌트:**
|
|
99
|
+
```
|
|
100
|
+
{
|
|
101
|
+
jobId, resumeVersionId, // R10 신선도
|
|
102
|
+
fitSummary: { mustHaveTotal, mustHaveMet, // mustHaveMet = status=='met' 개수만 (partial 제외)
|
|
103
|
+
mustHaveMetRate, niceToHaveMet,
|
|
104
|
+
verdict: 'recommend'|'conditional'|'not_recommend',
|
|
105
|
+
overqualified: bool }, // 오버퀄/방향 불일치 플래그
|
|
106
|
+
requirements: [ {
|
|
107
|
+
id, text, type:'must'|'nice',
|
|
108
|
+
critical: bool, hardGate: bool, // 단독 게이트
|
|
109
|
+
status: 'met'|'partial'|'gap',
|
|
110
|
+
partialReason?, // partial이면 필수 (R8)
|
|
111
|
+
transferAttempt?, // gap must면 필수 (R9)
|
|
112
|
+
evidence: [ { sourceType:'resume'|'experience', sourceId,
|
|
113
|
+
quotedBullet, // 입력 원문의 exact substring (R3)
|
|
114
|
+
quotedMetric? } ],
|
|
115
|
+
keywordSurfacePresent: bool, // R7 표면 트랙
|
|
116
|
+
mitigation? // 미충족 must면 필수 (R4)
|
|
117
|
+
} ],
|
|
118
|
+
generatedBy: 'claude'|'gpt'|'gemini'
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
**서버측 검증(LLM 불요):** ① `status∈{met,partial}`인데 `evidence[]` 빈 항목 → **거부**(R2). ② 각 `quotedBullet`이 해당 sourceId 입력 텍스트의 부분문자열이 아니면 → **거부**(R3). ③ `mustHaveMet`를 status=='met' 개수로 재계산(클라이언트 자기보고 불신, R5). ④ `hardGate&&status==gap` 또는 `critical&&status==gap`이 1개라도 있는데 `verdict=='recommend'` → **거부**(경고 아님, R6). ⑤ partial인데 `partialReason` 없음(R8)·gap must인데 `transferAttempt` 없음(R9)·미충족 must인데 `mitigation` 없음(R4) → 거부.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# 사람처럼 쓰기 (anti-AI-slop) / Human Writing — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
커리어 문서(자기소개서·자기 PR·지원 메일·면접 답변)를 "AI가 쓴 티" 없이, 사용자 고유의 목소리로, 사실을 보존하며 쓰도록 연결된 AI를 안내한다. CareerMate의 **1차 사용자층은 한국어 자소서 작성자**이므로 이 플레이북은 한국어 슬롭(번역투·클리셰·기계적 병렬·수동태)을 1차 기준으로, 영어 마커는 영문 지원서일 때만 적용하는 **보조 기준**으로 둔다. 이 문서는 기존 `packages/prompts/src/humanize.ts`의 정성 가이드(한국어 8개 항목, `epoko77-ai/im-not-ai` 근거)를 **상위 단일 원본으로 흡수·확장**하고, 거기에 "LLM 없이 셀 수 있는" 결정론 루브릭과 채용 적합성 축을 더한 것이다. 핵심은 슬롭 제거가 아니라 **"거짓 없고 직무에 맞닿은, 사람 목소리의 글"**을 만드는 것이다 — 슬롭이 0이어도 동문서답·내용 공백이면 떨어진다.
|
|
8
|
+
|
|
9
|
+
## 2. 플레이북
|
|
10
|
+
|
|
11
|
+
### 원칙
|
|
12
|
+
|
|
13
|
+
- **(한국어 슬롭을 1차로 거른다)** 번역투("~에 대한/~을 통해/~에 있어서/~라는 점에서/가지고 있습니다/~을 진행하였습니다"), 클리셰("급변하는 시대/4차 산업혁명/끊임없는 노력/귀사의 발전에 기여/소통과 협업/성장하는 인재"), 정의문 반복("저는 ~한 사람입니다"의 남발), 수동태("~되어졌습니다"), 형식 과용(가운뎃점 `·` 남발, 불필요한 굵게/이모지, "첫째·둘째·셋째")을 제거한다 — 이것이 한국 채용 담당자가 실제로 거르는 진짜 슬롭이다. _(출처: humanize.ts / epoko77-ai/im-not-ai)_
|
|
14
|
+
- **(영어 과잉어휘는 영문 지원서에서만 보조로 차단)** delve, leverage, utilize, showcase, underscore, harness, bolster, illuminate, facilitate, intricate, meticulous, tapestry, realm, beacon, testament, foster, robust 등은 같은 의미의 일상어로 치환한다(leverage→use, utilize→use, delve into→examine). 단 단어 경계(`\b`)로 매칭하고 정당한 기술 맥락(`robust error handling`, UI `navigate`, `foster care`)은 예외로 둔다. **locale='ko'에서는 이 사전의 가중치를 낮춘다.** _(출처: Kobak et al. 2024; The Conversation 2025 — 단, "단일 지표 맹신은 과학보다 art"라는 원문 경고를 함께 적용)_
|
|
15
|
+
- **(증거로 보여준다, Show don't tell)** 열정 선언("열정을 가지고/최선을 다하겠습니다/빨리 배웁니다/I am excited to/I want to/fast learner/great fit")과 추상 성격 나열("성실·책임감·소통능력")은 **무엇을 했고 그 결과 수치가 어떻게 됐다**는 구체 사실로 대체한다. _(출처: TopResume; The Muse; Univ. of Michigan Career Center; humanize.ts 7항)_
|
|
16
|
+
- **(사실을 잠근다, Fact lock)** 숫자·고유명사·날짜·직함·회사명·기술스택은 사용자가 준 그대로 보존한다. **단, 입력 사실로부터의 명시적 파생연산(차·합·비율 환산: 월12건→월2건에서 "83% 감소")은 허용**한다. 모르면 지어내지 말고 `[확인 필요]`로 표시한다. 이 체크는 한국어 NER 한계 때문에 **결정론 게이트가 아니라 LLM 보조 플래그**로 둔다(아래 R7). _(출처: CareerMate AGENTS.md 프라임 디렉티브)_
|
|
17
|
+
- **(직무 적합성을 1차 게이트로)** 주장 1개당 **그 JD의 요구 역량과 매칭되는** 검증 가능한 사실 1개를 붙인다. `get_application_context`의 `matched_keywords`/`missing_keywords`와 산출물을 대조해, 슬롭은 없지만 동문서답인 글을 거른다. _(출처: 채용 매니저 리뷰 — job-fit 축; CareerMate get_application_context)_
|
|
18
|
+
- **(목소리 보존)** 사용자 원문·이력서를 샘플로 평균 문장길이·어휘 수준을 맞추고, 표준 코퍼레이트 톤으로 평탄화하지 않는다. 이는 분포 유사도로 측정 가능하다(R8). _(출처: The Augmented Educator; humanize.ts; get_writing_style_guide)_
|
|
19
|
+
- **(간결성, Omit needless words)** 형용사·부사로 부풀리지 않고, 초안 후 "불필요한 단어 삭제" 패스를 1회 더 돌린다. 능동태를 기본으로 한다. _(출처: Strunk & White)_
|
|
20
|
+
- **(두괄식 + STAR)** 각 문항 첫 문장에 그 문항의 핵심 결론을 두고, 본문은 상황(S)·과제(T)·행동(A)·결과(R)로 전개한다. **한국어에서 "저는 ~입니다"로 시작하는 두괄식 대표문장은 정석이므로 슬롭으로 취급하지 않는다.** _(출처: 링커리어/하이잡/대웅 STAR 가이드)_
|
|
21
|
+
|
|
22
|
+
### Do
|
|
23
|
+
|
|
24
|
+
- 문항/문단 첫 문장에 핵심 결론을 둔다(두괄식). "저는 데이터로 문제를 정의하는 사람입니다" 같은 대표문장은 권장된다.
|
|
25
|
+
- 주장 1개당 **그 JD 요구역량에 맞닿은** 검증 가능한 사실(수치·기간·도구·역할·결과)을 최소 1개 붙인다.
|
|
26
|
+
- `matched_keywords`를 산출물이 증거와 함께 다루는지 확인한다(키워드 커버리지).
|
|
27
|
+
- 능동태·단문 위주로 쓰되 문장 길이를 변주한다(짧은 문장과 긴 문장 섞기). 단 이는 신호일 뿐 목표가 아니다 — 가독성 우선.
|
|
28
|
+
- 공고/플랫폼의 글자수 상한(예: 500자/1000자)을 지킨다. 초과는 시스템에서 잘린다.
|
|
29
|
+
- 사용자 원문·이력서의 어조·어휘 수준을 샘플로 삼아 목소리를 맞춘다.
|
|
30
|
+
- 숫자·고유명사·날짜·회사명을 원본과 대조하되, 콤마/단위/한글수사 차이(1,200ms=1200ms, 12만=120,000)는 같은 값으로 정규화한다.
|
|
31
|
+
- 입력 사실에서 파생한 환산값(차·합·비율)은 계산해 써도 된다.
|
|
32
|
+
- 초안 후 "불필요한 단어 삭제" 패스를 1회 더 돌린다.
|
|
33
|
+
- 불확실한 사실은 `[확인 필요]`로 표시하고 사용자에게 되묻는다.
|
|
34
|
+
|
|
35
|
+
### Don't
|
|
36
|
+
|
|
37
|
+
- 번역투("~에 대한/~을 통해/가지고 있습니다")와 클리셰("급변하는 시대/4차 산업혁명/귀사의 발전에 기여")로 문장을 채우지 않는다.
|
|
38
|
+
- "성실·책임감·소통능력" 같은 추상 형용사를 사례 없이 나열하지 않는다.
|
|
39
|
+
- "열정을 가지고/최선을 다하겠습니다/밑거름이 되겠습니다/I am excited to/I want to(공허한 자기선언)"로 채우지 않는다.
|
|
40
|
+
- **회사명 오기재**(타 회사 자소서 복붙)를 하지 않는다 — fact-lock보다 흔하고 치명적이다.
|
|
41
|
+
- **문항 질문에 답하지 않는 동문서답**을 하지 않는다.
|
|
42
|
+
- 가운뎃점(`·`) 남발, 불필요한 굵게/이모지, 과한 마크다운, em-dash 남발을 하지 않는다.
|
|
43
|
+
- "A, B, and C / A하고 B하며 C하는" 삼단열거를 **기계적으로** 반복하지 않는다(정상적 명사 3항 나열 "디자인·개발·운영"은 허용).
|
|
44
|
+
- "it's important to note/물론 ~지만/전반적으로/어떻게 보면" 헤징·메타 코멘트를 넣지 않는다.
|
|
45
|
+
- **출처 없는 정성 우월 주장**("팀 사기를 크게 높였다/탁월한/대폭 개선")을 쓰지 않는다 — 숫자가 없어 fact-lock에도 안 걸리지만 면접에서 깨진다.
|
|
46
|
+
- 사용자가 주지 않은 수치·수상·직함을 추정·미화·반올림하지 않는다(파생 환산은 예외).
|
|
47
|
+
- 사용자 고유 표현을 표준 코퍼레이트 톤으로 평탄화하지 않는다.
|
|
48
|
+
|
|
49
|
+
### 워크드 예시 (Before → After)
|
|
50
|
+
|
|
51
|
+
1. **Before(한국어):** "저는 어떤 일이든 성실하고 책임감 있게 임하며, 끊임없는 열정으로 귀사의 무한한 가능성에 발맞춰 일익을 담당하고자 합니다. 다양한 경험을 통해 소통 능력과 문제 해결 능력을 길렀습니다."
|
|
52
|
+
**After:** "재고 데이터 정합성 문제로 월 평균 12건의 오배송이 발생하던 물류팀에서, 저는 주문-재고 대조 스크립트를 직접 만들어 야간 배치에 넣었습니다. 그 결과 오배송은 3개월 만에 월 2건으로(약 83% 감소) 줄었고, CS 문의도 40% 감소했습니다."
|
|
53
|
+
**왜 더 나은가:** Before는 추상 성격 나열·클리셰("무한한 가능성/일익을 담당")뿐이라 누구나 복붙 가능하다. After는 STAR로 상황(월12건)·행동(스크립트·야간배치)·결과(월2건, CS 40%↓)를 수치로 보여준다. "83%"는 입력 12→2의 **허용된 파생 환산**이라 fact-lock을 위반하지 않는다.
|
|
54
|
+
|
|
55
|
+
2. **Before(한국어, 번역투):** "이번 프로젝트에 있어서 저는 데이터 분석에 대한 역량을 가지고 있으며, 이를 통해 리텐션 개선을 진행하였습니다. 또한 협업 능력도 갖추고 있습니다."
|
|
56
|
+
**After:** "마케팅 로그 12만 건을 SQL로 분석해 이탈 구간을 찾았고, 리텐션을 8%p 올렸습니다. 인턴 2명을 온보딩하며 분석 대시보드 표준을 만들었습니다."
|
|
57
|
+
**왜 더 나은가:** Before는 번역투("~에 있어서/~에 대한/~을 통해/가지고 있으며/진행하였습니다")와 "~을 갖추고 있습니다" 정의문이 골격이다. After는 번역투를 걷어내고 두 개의 구체 성과(수치 포함)로 능동태 단문을 쓴다. 정보는 늘고 길이는 줄었다.
|
|
58
|
+
|
|
59
|
+
3. **Before(영문 지원서):** "I am thrilled to leverage my robust skill set to delve into new challenges and showcase my ability to navigate complex environments—driving innovation, fostering collaboration, and underscoring my passion for excellence."
|
|
60
|
+
**After:** "I led the checkout-API rewrite for 3 engineers over 4 months. We cut p95 latency from 1,200ms to 380ms and reduced payment errors by 27%. I want to bring that same focus to your payments team."
|
|
61
|
+
**왜 더 나은가:** Before는 영어 과잉어휘(leverage/delve/showcase/navigate/foster/underscore)·em-dash·삼단열거·빈 열정어가 전부라 사실이 0개다. After는 역할·기간·인원·전후 수치로 능동 단문을 쓴다. (영문일 때만 영어 lexicon이 1차로 작동한다.)
|
|
62
|
+
|
|
63
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
64
|
+
|
|
65
|
+
> **캘리브레이션 경고:** 아래 임계값(em-dash 2개, 사실토큰, 문장길이 표준편차 등)은 주로 영어 코퍼스에서 온 **잠정 수입품**이다. Phase B에서 한국어 합격 자소서 코퍼스로 percentile 캘리브레이션하고 분기별 재조정해야 한다. lexicon은 후행 지표(모델 RLHF가 tell을 학습해 회피 중)이므로 **버전·출처일자를 필수로 기록**한다. 모든 카운트 임계는 "하드 fail"이 아니라 "신호" 우선이며, 게이트로 쓰는 것은 R5·R6·R9뿐이다.
|
|
66
|
+
|
|
67
|
+
| ID | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게) |
|
|
68
|
+
|----|-----------|-----------|--------------------------------|
|
|
69
|
+
| R1 | 한국어 슬롭 사전 매칭(번역투·클리셰·수동태) | 매칭 0건(있으면 치환 제안+사람 판단). **soft** | locale='ko' 사전(번역투 "~에 대한/~을 통해", 클리셰 "급변하는 시대/4차 산업혁명/귀사의 발전에 기여", "~되어졌습니다")으로 부분문자열 매칭, 히트 카운트 |
|
|
70
|
+
| R2 | 영어 과잉어휘(영문 지원서 한정) | locale='en'일 때만 적용, 치환 제안. **soft** | 단어경계 `\b(delve|leverage|utilize|showcase|...)\b` 정규식, 기술맥락(robust error handling 등) 화이트리스트 예외. locale='ko'면 가중치↓ |
|
|
71
|
+
| R3 | 형식 tell(가운뎃점·이모지·굵게·em-dash) | 가운뎃점 남발·이모지 0, em-dash≤2(영문만 변별력). **soft** | `·` `—` 이모지 유니코드·`**` 출현 카운트. (한국어 자소서에서 em-dash 변별력은 사실상 0 — 가운뎃점이 더 중요) |
|
|
72
|
+
| R4 | 헤징/메타 코멘트 | 매칭 0건. **soft** | 사전("it's important to note/물론/전반적으로/어떻게 보면") 부분문자열 매칭 카운트 |
|
|
73
|
+
| R5 | 빈 열정어·자기선언 상투구 | 매칭 0건(있으면 각 1개를 구체 사실로 대체). **gate** | 사전("열정을 가지고/최선을 다하겠습니다/빨리 배웁니다/I am excited to/I want to/fast learner/great fit") 매칭 카운트 |
|
|
74
|
+
| R6 | 증거 밀도(주장당 사실) | 주장 1개당 사실 토큰(숫자/%/기간) ≥1. **gate**(1차 게이트) | 한국어=어절 기준, 영어=word 기준으로 분리. 숫자 `\d`, `%`, 기간 `\d+\s*(년\|개월\|주\|month\|year)` 카운트. 한국어 "대문자 고유명사"는 세지 않음 |
|
|
75
|
+
| R7 | 사실 잠금(fact-lock) | 입력에 없는 숫자·고유명사 0건(파생 환산 제외). **LLM 보조 플래그**(게이트 아님) | 숫자 정규화(콤마/단위/한글수사: 1,200ms=1200ms, 12만=120,000) 후 차집합. 차/합/비율 화이트리스트. 한국어 고유명사는 NER 없이 못 잡으므로 연결된 AI가 최종 판정 |
|
|
76
|
+
| R8 | 목소리 보존(평탄화 금지) | 산출물 평균 문장길이가 사용자 원문 샘플 ±30% 이내, TTR 유사. **soft** | 사용자 원문 샘플과 산출물의 평균 문장길이 차이·어휘다양성(TTR) 비교. 순수 산술 |
|
|
77
|
+
| R9 | 글자수 상한 | 공고/플랫폼 max_chars 이하. **gate** | `text.length` ≤ max_chars. 가장 객관적인 결정론 체크 |
|
|
78
|
+
| R10 | 직무 키워드 커버리지 | `matched_keywords` 중 산출물이 증거와 함께 다루는 비율 ≥ 목표치. **soft** | get_application_context의 keyword 집합과 산출물 토큰 교집합 비율 |
|
|
79
|
+
| R11 | 회사명 정합 | 산출물의 회사명 = 대상 공고 회사명. **gate** | 공고의 company 문자열이 산출물에 존재, 타 회사명 부재 확인(타 회사 복붙 탐지) |
|
|
80
|
+
| R12 | 문장 길이 변주(burstiness) | 문장 ≥6개일 때만 적용, 표준편차 ≥5단어. **soft(신호일 뿐 목표 아님)** | 문장 분리 후 단어수 표준편차. 짧은 문항(<6문장)은 통계 무의미하므로 미적용 |
|
|
81
|
+
|
|
82
|
+
**주요 실패 모드:**
|
|
83
|
+
1. **동문서답·직무 무관** — 슬롭이 0이어도 JD와 무관한 자랑이면 떨어진다(R6·R10·채용 1차 탈락 사유).
|
|
84
|
+
2. **회사명 오기재·글자수 초과** — 결정론으로 가장 쉽게 잡히는 치명적 실수인데 자주 누락된다(R9·R11).
|
|
85
|
+
3. **환각·출처 없는 정성 과장** — 입력에 없는 수치/수상, 또는 숫자 없는 "크게/탁월한" 정성 주장. 면접에서 즉시 발각(R7 + Don't의 정성 주장 금지).
|
|
86
|
+
4. **false-positive 오탈락** — 영어 사전을 한국어에 그대로 적용, 정상 3항 명사나열을 삼단열거로 오탐, 짧은 문항에 burstiness 강제. 이를 막으려 게이트는 R5·R6·R9·R11로 한정하고 나머지는 soft 신호로 둔다.
|
|
87
|
+
5. **사전 시효성(adversarial drift)** — 2024 'delve' 통계는 후행 지표. 버전 미기록·미캘리브레이션 lexicon은 정상 글을 오탈락시킨다.
|
|
88
|
+
|
|
89
|
+
## 4. 출처 (Provenance)
|
|
90
|
+
|
|
91
|
+
- **humanize.ts / epoko77-ai/im-not-ai** — 한국어 AI-tell 분류(번역투·클리셰·기계적 병렬·수동태·형식 과용)의 1차 근거. **이 문서의 한국어 ban-list 본체.** (`packages/prompts/src/humanize.ts`, MIT License)
|
|
92
|
+
- **Kobak et al., "Delving into LLM-assisted writing…"** — 영어 과잉어휘 사전의 실측 근거(delve +1500% 등). **단 영문 지원서 한정 보조 기준**으로만 적용. · https://arxiv.org/abs/2406.07016
|
|
93
|
+
- **The Augmented Educator, "Ten Telltale Signs of AI-Generated Text"** — 헤징·정형 템플릿(2~5배)·낮은 burstiness·장식 명사·개인 목소리 부재. dontList 다수 근거. · https://www.theaugmentededucator.com/p/the-ten-telltale-signs-of-ai-generated
|
|
94
|
+
- **The Conversation, "Too many em dashes? … Spotting text written by ChatGPT" (2025)** — em-dash 일화적 근거이자 **"단일 지표 맹신은 과학보다 art"라는 한계 경고** — R3을 soft로 강등한 근거. · https://theconversation.com/too-many-em-dashes-weird-words-like-delves-spotting-text-written-by-chatgpt-is-still-more-art-than-science-259629
|
|
95
|
+
- **Strunk & White, "The Elements of Style"** — 간결성(Omit needless words)·능동태. · https://news.cornell.edu/stories/2009/03/omit-needless-words-elements-style-turns-50
|
|
96
|
+
- **TopResume "9 Cover Letter Cliches" / The Muse / Univ. of Michigan Career Center** — 빈 열정어·자기선언 금지, Show-don't-tell. · https://topresume.com/career-advice/cliches-cut-from-cover-letter
|
|
97
|
+
- **링커리어·하이잡·대웅 뉴스룸 STAR 기법 가이드** — 한국 채용: 두괄식("저는 ~입니다" 대표문장 정석), STAR, 추상 성격 나열 금지. · https://community.linkareer.com/employment_data/4464545
|
|
98
|
+
- **CareerMate AGENTS.md** — 프라임 디렉티브("두뇌는 당신, 저장은 CareerMate"), 사실·수치·고유명사 보존, get_application_context의 matched/missing_keywords.
|
|
99
|
+
|
|
100
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
101
|
+
|
|
102
|
+
- **MCP 도구 아이디어:**
|
|
103
|
+
- `get_writing_style_guide(doc_type, locale)` 확장 — 위 원칙·Do·Don't를 locale별(ko 우선, en 보조)로 반환. 기존 humanize.ts를 이 데이터의 1차 소스로 흡수.
|
|
104
|
+
- `check_human_writing(text, locale, sourceFacts?, maxChars?, jdKeywords?, voiceSample?)` 신설 — **LLM 없이 결정론**으로 violations 배열 + pass/fail 반환. R1~R6·R9~R12는 순수 JS 카운트/정규식/집합연산. **R7(fact-lock)·R10·두괄식 본질은 "휴리스틱 플래그"로 반환하고 최종 판정은 연결된 AI에게 위임**(한국어 NER·의미 판정 불가 인정).
|
|
105
|
+
- **데이터 형태 힌트:**
|
|
106
|
+
```
|
|
107
|
+
styleGuide: { domain, locale, principles[], doList[], dontList[] }
|
|
108
|
+
lexicons: { // 버전드 JSON, 거버넌스 메타 필수
|
|
109
|
+
_meta: { version, sourceDate, calibratedOn, changelog[] },
|
|
110
|
+
slop_ko: [{term, replaceWith, regex?}], // 1차
|
|
111
|
+
aiOveruse_en: [{term, replaceWith, wordBoundary:true, contextWhitelist:[]}], // 영문 한정
|
|
112
|
+
hedging: [], emptyEnthusiasm: [], formatTells_ko: ['·','**','emoji']
|
|
113
|
+
}
|
|
114
|
+
rubric: [{ id, check, passBar, regexOrLexiconRef, locale, severity:'gate'|'soft'|'llm-flag', minSentences? }]
|
|
115
|
+
```
|
|
116
|
+
- **입력:** `{ text, locale, sourceFacts?, maxChars?, jdKeywords?, voiceSample? }`
|
|
117
|
+
- **출력:** `{ score, gatePassed, violations:[{ruleId, severity, count, matches:[{text,offset}]}], factLock:{normalizedNumbers, unmatched[], note:'LLM-confirm'}, jobFit:{coverage, missing[]}, metrics:{emDash, midDot, sentenceLenStdev, evidencePerUnit, charCount, voiceDelta} }`
|
|
118
|
+
- **거버넌스(필수):** lexicon 변경은 (a) version/sourceDate 기록, (b) 한국어 false-positive 회귀 테스트셋 통과, (c) 합격 자소서 N건 + AI 슬롭 N건 골든셋에 대한 precision/recall 리포트, (d) 분기별 재캘리브레이션 트리거를 거친다. 기술 용어 화이트리스트(robust/foster/navigate)는 contextWhitelist로 관리.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# 면접 — 행동 / Behavioral Interview — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
행동 면접은 "과거 행동이 미래 성과를 예측한다"는 행동 일관성(behavioral consistency) 원리에 기반한 구조화 면접이다. 면접관은 지원자의 과거 사례를 STAR(Situation·Task·Action·Result) 형태로 듣고, 직무 관련 역량(competency)·회사 가치에 매핑해 채점한다. CareerMate는 LLM이 없으므로, 연결된 외부 AI가 사용자의 실제 경험을 STAR로 재구성하고, 역량에 매핑하며, 실측 정량 결과를 분리해내고, **후속 질문(probing)에 견디는 스토리 뱅크**를 만들도록 돕는 지식·루브릭을 제공한다. 핵심은 ① 개인 기여를 1인칭으로 분리, ② Result를 **검증 가능한** 실측 수치로, ③ 각 스토리를 controlled vocabulary 역량 태그에 매핑, ④ 사례마다 probing 답(왜·대안·되돌아보면)을 미리 준비하는 것이다. 아래 루브릭은 어느 체크가 **결정론적으로 셀 수 있고(D)**, 어느 체크가 **외부 AI의 의미 판단을 전제로 한 보조 휴리스틱(H)**인지를 등급으로 명시 구분한다 — 전부 동급의 기계 검증인 척하지 않는다.
|
|
8
|
+
|
|
9
|
+
## 2. 플레이북
|
|
10
|
+
|
|
11
|
+
### 원칙
|
|
12
|
+
|
|
13
|
+
- **(STAR 4요소를 빠짐없이 채우되, Action에 가장 많은 분량과 '결정의 밀도'를 둔다.)** — 면접관이 평가하는 것은 Situation의 장황함이 아니라 지원자가 내린 구체적 결정·행동이다. Result가 빠지면 임팩트 평가가 불가능하다. **단, 'Action 50% / Result 25% / Situation 15% / Task 10%'라는 비율은 1차 채점 연구가 아니라 대학 커리어센터의 코칭 휴리스틱일 뿐이므로, 합격 게이트가 아니라 soft 가이드로만 쓴다.** 길이가 아니라 '구체 결정 동사 개수'가 Action 품질의 진짜 신호다. _(출처: Northwestern Career Advancement STAR Approach — 휴리스틱, 4절 신뢰도 주석 참조)_
|
|
14
|
+
- **(Action·Result는 'we'가 아니라 'I/제가'로 개인 기여를 분리해 쓴다.)** — 면접관은 팀이 아니라 지원자 개인의 역량을 채점한다. 팀 맥락은 Situation에서 한 줄로 깔고, Action에서 '제가 ~을 결정/제안/구현했다'로 본인 행동을 드러낸다. **한국어는 주어 생략이 자연스러우므로('~을 제안했습니다') 'I' 토큰 카운트가 아니라 '제가/내가' 명시 빈도 + 집단대명사(저희/우리) 대비로 측정한다.** _(출처: UVA Career Center, Bauer College STAR guide)_
|
|
15
|
+
- **(Result는 실측 수치로 정량화하되, 검증 가능성과 짝지어 쓴다.)** — 가능하면 숫자+단위(%, 시간, 금액, 인원, 순위, 기간)로 표현한다. **단, "만족도 100%"·"효율 200% 개선" 같은 분모·기간·출처 없는 숫자는 probing에서 즉시 무너진다.** 각 수치에는 측정 범위(label)와 원자료 링크(sourceRef)를 붙여 진위를 보장한다. 정량화가 불가능하면 검증 가능한 정성 결과(채택됨/재현됨/재계약)와 학습을 명시한다. _(출처: Amazon STAR guidance, UVA Career Center)_
|
|
16
|
+
- **(답변 전, 질문이 겨냥하는 역량/회사가치를 controlled vocabulary로 먼저 식별하고 매핑한다.)** — 구조화 면접의 변별력은 표준화·동일 질문·앵커드 채점표(BARS)에서 나오며, 역량 매핑은 그 일부다(역량 매핑 단독이 우수성의 원인이라는 단정은 과도 단순화). 채용공고 요구 역량에서 역으로 스토리를 고른다. **태그 인플레이션을 막기 위해 역량은 고정 enum을 쓴다(아래 택소노미).** _(출처: U.S. OPM Structured Interviews; Northwestern)_
|
|
17
|
+
- **(스토리 뱅크를 미리 8~12개 구축하고, 각 사례에 probing 답 3종을 함께 준비한다.)** — 한 사례를 여러 질문에 변주해 즉석 누락을 막는다. **Amazon 루프 등에서 후보가 떨어지는 1순위는 첫 답변이 아니라 probing 붕괴이므로, 각 사례에 '왜 그 결정을 했나 / 대안은 무엇이었나 / 되돌아보면 무엇을 바꾸겠나' 답을 미리 채운다.** _(출처: Amazon Behavioral Interview 가이드, UVA·Wisconsin 등)_
|
|
18
|
+
- **(사례는 최신성·직무관련성을 갖춰야 한다.)** — 시니어/경력직에게 8년 전 인턴·학부 프로젝트만 가득한 뱅크는 반려 사유다. 각 사례에 연도·역할단계를 기록하고, 경력직은 최근 N년 내 사례 비율을 확보한다. _(출처: 채용 실무 — recency/relevance, hiring manager review)_
|
|
19
|
+
- **(사실·수치·고유명사는 절대 지어내지 않는다. 실패 사례는 조건부로만 쓴다.)** — 면접관은 probing으로 꾸민 이야기를 검증한다. 실패 사례는 회복·재발방지 행동이 Result보다 길고 구체적일 때만 강점이 되며, 일부 문화권 면접관은 부정 신호로 받을 수 있으므로 '학습·후속 개선'이 핵심이 아닐 거면 쓰지 않는다. _(출처: CareerMate AGENTS.md, Amazon probing follow-ups, UVA)_
|
|
20
|
+
- **(키워드 스터핑을 경계한다.)** — 회사 가치에 '단어 수준으로 맞추라'는 조언은 과하면 '준비된 앵무새'로 보인다. LP/가치 키워드는 실제 사례의 행동이 그 가치를 **입증**할 때만 쓰고, 키워드를 라벨처럼 나열하지 않는다. 구조화 면접은 adverse impact를 줄이고 법적 방어가능성을 높이는 공정성 도구라는 점도 기억한다. _(출처: U.S. OPM Structured Interviews)_
|
|
21
|
+
|
|
22
|
+
### Do
|
|
23
|
+
|
|
24
|
+
- 질문을 받으면 먼저 '이 질문이 겨냥하는 역량/회사가치'를 controlled vocabulary 태그로 한 줄 명시하고 스토리를 매핑하라.
|
|
25
|
+
- STAR 4요소를 모두 채우고, Action에 '구체 결정 동사(결정/제안/설계/구현/협상/분석)' 3개 이상을 1인칭으로 담아라. Situation·Task는 각각 1~2문장으로 압축하라.
|
|
26
|
+
- Action·Result는 '제가/내가 ~했다'로 본인 기여를 분리하라(한국어는 '저희/우리' 습관을 의식적으로 '제가'로 전환).
|
|
27
|
+
- Result에 **사용자 실측** 숫자+단위를 최소 1개 넣고, 각 수치에 label(무엇을 잰 것인지)과 sourceRef(원자료)를 붙여라. 불가능하면 검증 가능한 정성 결과+학습을 명시하라.
|
|
28
|
+
- 8~12개 핵심 사례로 스토리 뱅크를 만들고, 각 사례를 여러 역량 enum에 다중 태깅하며, **사례마다 probing 답 3종을 채워라.**
|
|
29
|
+
- 각 사례에 연도·역할단계를 기록하고, 경력직은 최근 사례를 우선 배치하라.
|
|
30
|
+
- 채용공고 요구 역량에서 역으로 어떤 사례를 쓸지 고르고, 회사 고유 가치를 '키워드'가 아니라 '행동으로 입증'하는 방식으로 맞춰라.
|
|
31
|
+
- 실패/약한 결과 사례는 회복·재발방지 행동이 충분할 때만 쓰고, '내 판단의 오류'와 '배운 점·후속 개선'으로 프레이밍하라.
|
|
32
|
+
- 답변을 소리 내어 리허설해 30초~2분(영어 약 130~330단어 / 한국어 약 90~230어절)로 다듬어라.
|
|
33
|
+
|
|
34
|
+
### Don't
|
|
35
|
+
|
|
36
|
+
- Situation/배경을 장황하게 늘어놓아 Action이 묻히게 하지 마라(Situation이 답변의 25%를 넘기면 경고 신호).
|
|
37
|
+
- 팀 성과를 'we/저희'로만 서술해 본인 기여를 흐리지 마라.
|
|
38
|
+
- Result를 생략하거나 '잘 끝났다' 같은 모호한 표현으로 뭉뚱그리지 마라.
|
|
39
|
+
- **검증 불가능한 가짜 숫자('만족도 100%', '효율 200%')를 채워 넣지 마라** — probing에서 분모·기간을 묻는 순간 무너진다.
|
|
40
|
+
- 수치·날짜·고유명사를 지어내거나 과장하지 마라.
|
|
41
|
+
- 하나의 만능 사례를 모든 질문에 우겨넣지 마라(같은 스토리를 3개 이상 다른 질문에 재탕 금지).
|
|
42
|
+
- '저는 열정적이고 성실합니다' 같은 형용사 나열로 답하지 마라 — 행동·증거로 보여라.
|
|
43
|
+
- 회사 가치/LP 키워드를 행동 입증 없이 라벨처럼 나열하지 마라('준비된 앵무새' 신호).
|
|
44
|
+
- 미래 가정형('저라면 ~할 것입니다')으로만 답하지 마라 — 실제 과거 사례를 들어라.
|
|
45
|
+
- 5년 전 학부 프로젝트만으로 시니어 직무에 답하지 마라(최신성·직무관련성 결여).
|
|
46
|
+
|
|
47
|
+
### 워크드 예시 (Before → After)
|
|
48
|
+
|
|
49
|
+
> 아래 after의 모든 수치는 **사용자가 제공한 실측 데이터**이며 각 수치에 label·sourceRef가 연결되어 있다는 전제다.
|
|
50
|
+
|
|
51
|
+
1. **Before:** 질문: '갈등을 해결한 경험을 말해보세요.' 답변: "저희 팀은 의견 차이가 있었지만 서로 소통하며 잘 협력해서 결국 프로젝트를 성공적으로 마쳤습니다. 저는 항상 팀워크를 중요하게 생각하고 갈등 상황에서도 긍정적으로 대처하는 편입니다."
|
|
52
|
+
**After:** `[역량: conflict, ownership]` **S:** 작년 출시 2주 전, 디자이너와 개발자가 핵심 화면 구현 범위로 충돌해 일정이 멈췄습니다(1문장). **T:** PM이던 제가 양쪽 합의안을 도출해 일정을 지키는 것이 목표였습니다. **A:** 저는 두 사람을 따로 인터뷰해 진짜 우려(디자인 완성도 vs 공수)를 분리한 뒤, 화면을 'MVP 필수/후속' 두 단계로 쪼개는 안을 직접 와이어프레임으로 제안했고, 후속 항목의 사용 빈도가 낮음을 데이터로 보여 합의를 끌어냈습니다. **R:** 일정 지연 0일로 정시 출시했고, 분리한 후속 기능은 다음 스프린트에 반영, 해당 출시의 D+7 리텐션이 기존 대비 12%p 높았습니다(label: D+7 retention, source: 사내 대시보드). **Probing 준비:** (왜) 데이터로 설득한 이유 / (대안) 일정 연기 vs 범위 축소 비교 / (되돌아보면) 충돌 초기에 데이터를 먼저 꺼냈으면 더 빨랐을 것.
|
|
53
|
+
**왜 더 나은가:** Before는 'we'·형용사 나열·결과 무수치·미래형 혼재로 채점 불가. After는 역량 매핑 명시, S/T 압축, Action을 1인칭 구체 결정 동사로 채움, Result를 label·source 붙은 실측 수치(0일·12%p)로 정량화하고 probing 3종을 갖춰 후속 질문에 견딘다.
|
|
54
|
+
|
|
55
|
+
2. **Before:** 질문: "Tell me about a time you took ownership." 답변: "We had a production bug and we worked together to fix it. It was stressful but we managed to resolve it and customers were happy in the end."
|
|
56
|
+
**After:** `[역량: ownership, customer-focus]` **S:** 결제 API에서 0.8% 거래가 실패하는 버그가 새벽에 발생했습니다. **T:** 온콜이 아니었지만 제가 영향 범위를 끝까지 책임지기로 했습니다. **A:** I triaged logs, isolated a race condition in the retry handler, shipped a hotfix within 70 minutes, then wrote a postmortem and added a regression test + an alert so it couldn't silently recur. **R:** 영향 거래의 100%를 수동 재처리해 매출 손실 0원, 동일 클래스 장애 재발 0건(6개월 추적), 알람 덕에 평균 탐지시간을 ~40분에서 ~3분으로 단축(label: MTTD, source: 모니터링 로그). **Probing 준비:** (왜) 온콜이 아닌데 책임진 이유 / (대안) 롤백 vs 핫픽스 트레이드오프 / (되돌아보면) 알람을 사전에 뒀어야 함.
|
|
57
|
+
**왜 더 나은가:** Before는 전부 'we'·정량 결과 없음·역량 무매핑. After는 ownership/customer-focus 매핑, 1인칭 결정 동사, label·source 붙은 실측 수치(0.8%·70분·0원·40→3분)로 임팩트를 증명하고 probing 3종으로 Amazon 루프식 깊이 질문에 대응한다.
|
|
58
|
+
|
|
59
|
+
3. **Before:** 질문: '실패한 경험을 말해보세요.' 답변: "저는 큰 실패는 없었던 것 같습니다. 굳이 꼽자면 시간 관리가 조금 아쉬웠는데, 지금은 잘 관리하고 있습니다."
|
|
60
|
+
**After:** `[역량: growth-learning]` **S:** 첫 사이드프로젝트에서 사용자 검증 없이 4개월간 기능부터 만들었습니다. **T:** 출시 후 사용자를 모으는 것이 목표였습니다. **A:** 저는 가설 검증을 건너뛴 채 개발에 몰입했고, 출시 후에야 핵심 가정이 틀렸음을 알았습니다. 이후 저는 즉시 10명 인터뷰를 돌려 문제를 재정의하고, 2주짜리 프로토타입으로 다시 검증하는 방식으로 프로세스를 바꿨습니다(재발방지 행동이 Result보다 김). **R:** 원래 제품은 가입 9명에 그쳤지만, 재검증 후 만든 버전은 4주 만에 활성 사용자 120명을 모았습니다(label: WAU, source: 가입 로그). '만들기 전에 검증한다'를 이후 모든 프로젝트의 기본 규칙으로 삼았습니다. **Probing 준비:** (왜) 검증을 건너뛴 이유 / (대안) MVP를 먼저 냈다면 / (되돌아보면) 4개월→2주로 단축한 학습.
|
|
61
|
+
**왜 더 나은가:** Before는 실패를 회피해 자기인식·성장성을 증명하지 못한다. After는 진짜 실패를 정직하게 인정하고, **재발방지 행동을 Result보다 길게** 써 학습을 증명하며(조건부 실패 사례 원칙 충족), 정량 대비(9명→120명)로 회복을 보인다.
|
|
62
|
+
|
|
63
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
64
|
+
|
|
65
|
+
> **전제(중요):** 루브릭은 자유 텍스트가 아니라 **`StoryBankEntry` 구조화 레코드 배열**을 입력으로 받는다. S/T/A/R 경계는 자유 텍스트를 LLM이 의미로 갈라야 하므로, CareerMate는 먼저 `save_interview_prep`으로 STAR를 **필드 분리 저장**하게 한다. 그러면 다수 체크가 필드 non-empty / 패턴 카운트로 결정론적이 된다.
|
|
66
|
+
>
|
|
67
|
+
> **등급 표기:** `D` = LLM 없이 결정론적으로 셀 수 있음(필드 존재·정규식·카운트). `H` = 외부 AI(또는 사람)의 의미 판단을 전제로 한 보조 휴리스틱 — 자동 합격 판정 금지, `warn`/`needs_review`로만 반환. 이 구분을 흐려 전부 기계 검증인 척하지 않는다.
|
|
68
|
+
|
|
69
|
+
| ID | 등급 | 검사 항목 | 합격 기준 | 측정 방법(LLM 없이 셀 수 있게 / H는 전제 명시) |
|
|
70
|
+
|----|------|-----------|-----------|--------------------------------|
|
|
71
|
+
| R1 BI-STAR-FIELDS | **D** | STAR 4필드가 모두 채워졌는가 | 각 entry의 `star.situation/task/action/result` 4필드 모두 non-empty (특히 result 누락 0) | 4필드 `len(trim)>0` 카운트 ==4. **필드 분리 저장 전제이므로 의미 라벨링 불필요.** result 필드 boolean 별도 체크. |
|
|
72
|
+
| R2 BI-SITUATION-CAP | **D** | Situation이 과도하게 길지 않은가 (anti-pattern) | `wordCounts.s / wordCounts.total <= 0.25` | 필드별 단어/어절 수 비율 계산. **Action 비율을 합격 게이트로 강제하지 않음**(50/25/15/10은 휴리스틱) — 대신 Situation 비대만 경고. |
|
|
73
|
+
| R3 BI-ACTION-DECISIONS | **H** | Action에 구체 결정 행동이 충분한가 | Action에 결정 동사 ≥3 (길이가 아닌 밀도) | 결정 동사 사전 매칭(한: 결정/제안/설계/구현/협상/분석/주도; 영: decided/proposed/designed/built/negotiated/analyzed/led) 카운트 ≥3. 사전 밖 동의어는 외부 AI 판정(H). |
|
|
74
|
+
| R4 BI-FIRST-PERSON | **D**(언어 분기) | Action에서 개인 기여가 1인칭으로 우세한가 | 1인칭 ≥ 집단대명사 AND 1인칭 ≥1 | **영어:** `I/my/me` 토큰 수 vs `we/our/us`. **한국어:** 주어 생략이 자연스러우므로 `제가/내가` 명시 빈도 vs `저희/우리` 빈도 비교(주어 토큰 부재≠fail). `lang` 필드로 분기. |
|
|
75
|
+
| R5 BI-QUANT-RESULT | **D** | Result에 정량 수치가 있는가 | `star.result`에 단위 부착 숫자 ≥1 또는 검증 가능 정성결과 플래그 | result 텍스트에서 `\d+%`, `\d+\s*→\s*\d+`, `[+\-]\d+`, `\d+(ms|초|분|시간|원|명|건|일|위|배)` 매칭 ≥1. 연도/버전 단독은 배제. 수치 없으면 `qualitative_verified` 플래그 확인. |
|
|
76
|
+
| R6 BI-METRIC-CREDIBLE | **D** | 각 수치가 검증 가능 메타를 갖췄는가 | `metrics[]`의 각 항목에 `label` AND `sourceRef` 모두 non-empty | over-coaching/가짜수치 가드. `metrics[]` 순회하며 둘 다 채워졌는지 카운트. 비면 "검증 불가 수치" 경고 — R5와 결합해야 '숫자만 있으면 통과'를 막는다. |
|
|
77
|
+
| R7 BI-COMPETENCY-TAG | **D**(존재) / **H**(적합) | 역량 태그가 controlled vocab에서 부여됐는가 | `competencies[]` ≥1 AND 모두 고정 enum에 속함 | 태그 존재·enum 소속은 D(set 검사). **태그가 '질문 의도와 실제로 일치'하는지는 H**(의미 판단) — needs_review로 분리. |
|
|
78
|
+
| R8 BI-PROBING-READY | **D** | 사례에 probing 답 3종이 준비됐는가 | `probing.why` / `probing.alternatives` / `probing.whatIdChange` 모두 non-empty | 3필드 존재 카운트 ==3. **probing 붕괴가 탈락 1순위이므로 핵심 게이트.** 셀 수 있는 존재 검사. |
|
|
79
|
+
| R9 BI-ANSWER-LENGTH | **D**(언어 분기) | 구두 전달에 적합한 길이인가 (soft) | 영어 130~330단어 / 한국어 90~230어절 | `lang`별 분기 카운트. 한국어 어절은 영어 word보다 정보밀도가 높아 동일 발화시간에 어절 수가 적다 — **'유사 범위' 금지, 언어별 임계 분리.** 범위 밖은 warn. |
|
|
80
|
+
| R10 BI-RECENCY | **D**(soft) | 사례가 충분히 최신인가 | 경력직: 최근 5년 내 사례 비율 ≥50% | 각 entry `year`/`careerStage` 파싱 후 `현재연도(2026) - year <= 5` 비율. 학부/인턴만 가득하면 경고(하드 실패 아님, 신입은 면제). |
|
|
81
|
+
| R11 BI-BANK-COVERAGE | **D** | 뱅크가 역량 카테고리를 충분히 커버하는가 | 서로 다른 entry ≥8 AND distinct 역량(enum) ≥6 | entry 개수 + `competencies[]` 합집합 distinct 카운트. **고정 enum 전제라 태그 인플레이션 없이 distinct가 유의미.** |
|
|
82
|
+
| R12 BI-REUSE-GUARD | **D** | 한 사례를 과도하게 재탕하지 않는가 | 같은 entry를 서로 다른 질문 유형에 매핑한 횟수 ≤2 | `questionMappings[entryId]` 카운트가 entry당 ≤2인지. 만능 사례 우겨넣기 가드. |
|
|
83
|
+
| R13 BI-NO-FABRICATION | **needs_review (H)** | 수치·고유명사가 지어내지 않았는가 | **자동 합격 판정 없음 — 확인 플래그만.** | **순수 set-diff 금지**(70분≈'약 1시간', 40→3분 같은 파생값, 단위변환, NER로 거짓양성/음성 폭발). 좁힌 D 검사: 답변의 숫자 리터럴이 `metrics[].value`(사용자 입력)에 매칭되는지 literal-match. 그 외 신규 수치·고유명사는 "검토 필요" 목록으로 모아 외부 AI/사람에게 토스. |
|
|
84
|
+
|
|
85
|
+
**Controlled vocabulary (역량 enum, 태그 인플레이션 방지 — distinct 카운트의 전제):**
|
|
86
|
+
`leadership`, `ownership`, `conflict`, `failure-learning`(=growth-learning), `initiative`, `data-driven`, `customer-focus`, `collaboration`, `deadline-pressure`, `ambiguity`, `influence`, `mentoring`. 회사 고유 가치는 `companyValueTags`(예: `Amazon:Ownership`)로 별도 부여하되, 반드시 위 enum 중 하나에 연결한다.
|
|
87
|
+
|
|
88
|
+
**주요 실패 모드:**
|
|
89
|
+
- **probing 붕괴(탈락 1순위):** 첫 답변만 다듬고 '왜·대안·되돌아보면'을 준비 안 함 → R8 존재 게이트로 강제.
|
|
90
|
+
- **가짜 수치 보상:** R5가 '숫자 존재'만 보면 조작 수치도 통과 → 반드시 R6(label+sourceRef)·R13(검토)과 결합.
|
|
91
|
+
- **등급 사칭(루브릭 과대광고):** S/T/A/R 라벨링·역량 적합·고유명사 진위를 'D'인 척 자동 판정 → R13은 needs_review, R3·R7(적합)은 H로 고정.
|
|
92
|
+
- **한국어 깨짐:** 영어 'I' 카운트를 한국어에 적용해 정상 답을 fail → R4·R9는 `lang` 분기 필수.
|
|
93
|
+
- **휴리스틱의 게이트화:** 50/25/15/10 비율을 합격 기준으로 강제 → R2(Situation 상한)만 게이트, Action 비율은 비게이트.
|
|
94
|
+
- **태그 인플레이션:** enum 없이 distinct 카운트 → R11이 무의미. 고정 vocabulary 전제.
|
|
95
|
+
- **노후/만능 사례:** 8년 전 사례·재탕 → R10·R12로 카운트.
|
|
96
|
+
|
|
97
|
+
## 4. 출처 (Provenance)
|
|
98
|
+
|
|
99
|
+
> **신뢰도 주석(중요):** **예측타당도 '.51'은 Schmidt & Hunter(1998)의 수치이며, Sackett, Zhang, Berry & Lievens(2022)가 range-restriction 과대보정 오류를 지적해 사실상 하향됐다.** 보정 관행이 타당도를 과대추정했음이 드러나, 구조화 면접의 현재 최선 추정치는 **약 .42(80% credibility interval 약 .18~.66, 즉 ±.24 수준의 넓은 폭)**이고, 인지능력검사(GMA) 등 다른 도구와의 순위도 재배열됐다. **따라서 '.51로 채용 도구 중 최상위권'이라 단정하지 않는다** — 절대값은 신뢰구간으로 보고하고, 유지되는 것은 '구조화 > 비구조화'라는 **순서**뿐이다. 두 출처는 '상호 보강'이 아니라 **충돌**(후자가 전자를 보정)임을 명시한다. 또한 STAR 50/25/15/10 비율은 어느 1차 연구에도 없는 **코칭 휴리스틱**이며, 대학 커리어센터 자료는 학부생 코칭 콘텐츠이지 채용 타당도의 1차 근거가 아니다(방향성 참고용).
|
|
100
|
+
|
|
101
|
+
- **Schmidt & Hunter (1998) "The Validity and Utility of Selection Methods"** — 구조화 면접 .51 / 비구조화 .38의 **원출처(현재는 과대추정으로 간주)**. 1998년 메타분석을 2026년 정설로 인용하지 않는다.
|
|
102
|
+
- **Sackett, Zhang, Berry & Lievens (2022)** — range-restriction 보정 재분석. 구조화 면접 ~.42(80% CI 약 .18~.66), GMA ~.31로 하향, 신뢰구간 보고 관행. **본 문서의 헤드라인 수치는 이 보정치를 따른다.**
|
|
103
|
+
- **U.S. OPM — Structured Interviews** — 행동 일관성 원리, 구조화의 핵심 동인(표준화·동일 질문·앵커드 채점표 BARS), 직무관련 역량 차원 채점, adverse impact 감소·법적 방어가능성 · https://www.opm.gov/policy-data-oversight/assessment-and-selection/other-assessment-methods/structured-interviews/
|
|
104
|
+
- **Amazon Leadership Principles / STAR 면접 가이드** — Situation 압축·Result 정량화·Action 시간 집중, 인터뷰어가 가치 2~3개씩 배정 채점, probing follow-up(깊이 질문). **단, 한국 지원자 다수의 실제 타깃(국내 대기업 인성면접·스타트업 컬처핏)과는 거리가 있어 '대표 예시'가 아닌 '한 사례'로만 사용** · https://www.amazon.jobs/en/landing_pages/in-person-interview
|
|
105
|
+
- **Northwestern Career Advancement — STAR Approach** — STAR 4요소 정의, 직무기술서 기반 사례 선택 · STAR 분량 비율은 **휴리스틱**으로만 인용 · https://www.northwestern.edu/careers/jobs-internships/interviewing/the-star-approach.html _(학부 코칭 콘텐츠)_
|
|
106
|
+
- **UVA Career Center — STAR Method** — 'we 대신 I', Result 강조(학생 자주 누락), 부정적 결과를 회복탄력성으로 전환 · https://career.virginia.edu/Students/Launch/Interviews/STAR _(학부 코칭 콘텐츠)_
|
|
107
|
+
- **Bauer College (University of Houston) — STAR Behavioral Interview Technique** — 1인칭 개인 기여 강조, STAR 실무 적용 · https://careercenter.bauer.uh.edu/resources/star-behavioral-interview-technique/ _(학부 코칭 콘텐츠)_
|
|
108
|
+
- **AGENTS.md (CareerMate 프라임 디렉티브)** — 사실·수치·고유명사 보존, 과장·날조 금지 · 저장소 내부
|
|
109
|
+
|
|
110
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
111
|
+
|
|
112
|
+
- **MCP 도구 아이디어:**
|
|
113
|
+
- `get_behavioral_interview_kit({ job_id?, competency?, count? })` — `get_application_context`의 프로필·경력·스킬·대상 공고를 받아 (1) 저장된 스토리 뱅크에서 요청 역량/회사가치에 매핑되는 STAR 사례를 서빙, (2) 비어 있는 역량 카테고리·probing 누락·노후 사례를 `gap`으로 알려주고, (3) 본 루브릭(R1~R13, 등급 D/H 표기)을 함께 반환해 외부 AI가 자가검증하게 한다. read-only 지식 도구.
|
|
114
|
+
- `save_interview_prep({ job_id, stories[] })` — STAR를 **필드 분리(situation/task/action/result)** 로 강제 저장(자유 텍스트 금지 → S/T/A/R 경계 문제 해소, 루브릭 결정성 확보). `metrics[]`에 label·sourceRef를 강제해 R6/R13 가드를 데이터 구조 차원에서 건다.
|
|
115
|
+
- `lint_interview_kit(job_id?)` — R1~R13을 등급별로 실행. **D 항목은 pass/fail, H 항목(R3 적합·R7 적합·R13)은 `warn`/`needs_review`만 반환**(자동 합격 금지). `lang` 필드로 R4·R9 분기. 8단계 게이팅상 **면접 준비는 `document_passed` 이상에서만 해금.**
|
|
116
|
+
- **데이터 형태 힌트:**
|
|
117
|
+
```
|
|
118
|
+
StoryBankEntry {
|
|
119
|
+
id, title,
|
|
120
|
+
lang: 'ko' | 'en', // R4·R9 언어 분기
|
|
121
|
+
competencies: string[], // 고정 enum만 (R7·R11)
|
|
122
|
+
companyValueTags?: string[], // 예: ['Amazon:Ownership'] — enum에 연결
|
|
123
|
+
star: { situation, task, action, result }, // 필드 분리 저장 (R1·R2)
|
|
124
|
+
metrics: [{ value:number, unit, label, sourceRef }], // label+sourceRef 필수 (R6·R13)
|
|
125
|
+
probing: { why, alternatives, whatIdChange }, // 3종 필수 (R8)
|
|
126
|
+
year: number, careerStage: 'student'|'intern'|'junior'|'senior', // R10
|
|
127
|
+
questionMappings: string[], // 이 사례가 매핑된 질문 유형 (R12 재탕 가드)
|
|
128
|
+
wordCounts: { s, t, a, r, total }, // R2·R9
|
|
129
|
+
sourceRefs: string[] // 프로필/경력 항목 id — fabrication 방지 원자료 링크
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
도구 응답에는 `entries[]`, `coverage: { distinctCompetencies, count, missingCategories, recentRatio }`, `rubric: RubricCheck[]`(각 항목에 `grade: 'D'|'H'`, `status: 'pass'|'fail'|'warn'|'needs_review'`)를 함께 포함해 외부 AI가 등급을 구분해 자가검증하도록 한다.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# 면접 — 기술/시스템 디자인 / Technical & System Design Interview — CareerMate 지식 (Phase A)
|
|
2
|
+
|
|
3
|
+
> 이 문서는 CareerMate가 **연결된 AI에게 제공(serve)** 하는 지식이다. CareerMate 안에는 LLM이 없다 — 분석·작성·검증은 연결된 AI가 수행하고, 이 플레이북·루브릭은 그 AI가 **세계 최고 수준**으로 일하도록 안내한다.
|
|
4
|
+
|
|
5
|
+
## 1. 무엇을 하는가
|
|
6
|
+
|
|
7
|
+
기술/시스템 디자인 면접에서 평가자는 "정답 도달"이 아니라 **구조화된 사고 + 소통 + 트레이드오프 추론**을 본다. 이 플레이북은 연결된 AI가 (a) 후보의 직무·레벨·면접 포맷에 맞는 준비 자료를 만들고 (b) 그 자료를 자가검증하도록 트랙별 프레임·체크리스트·루브릭을 제공한다.
|
|
8
|
+
|
|
9
|
+
핵심 제약 — **CareerMate에는 LLM이 없으므로 이 문서의 루브릭은 "내용의 정확성"이 아니라 "준비 자료에 기대 구조가 존재하는가"라는 형식만 LLM 없이 측정한다.** 따라서 루브릭 통과는 **합격 신호가 아니라 최소 형식 충족(format floor)** 이며, 추론의 옳고 그름·복잡도의 정확성·소통의 실제 품질은 **연결된 AI가 별도로 판정**해야 한다. 이 한계를 사용자에게 숨기지 마라.
|
|
10
|
+
|
|
11
|
+
## 2. 플레이북
|
|
12
|
+
|
|
13
|
+
> **트랙 분리가 먼저다.** 기술 면접은 단일 포맷이 아니다. 최소 다섯 갈래로 나뉘고 평가 축이 서로 다르다: ① 온라인 코딩테스트(자동채점, 소통 0점) ② 라이브 코딩(소통 중심) ③ 백엔드 시스템 디자인 ④ FE/ML/데이터/모바일 시스템 디자인(축이 다름) ⑤ 디버깅/기존 코드 확장형. 아래 원칙은 트랙·세션 길이·레벨에 따라 **강도를 조절**해 적용한다(획일 적용 금지).
|
|
14
|
+
|
|
15
|
+
### 원칙
|
|
16
|
+
|
|
17
|
+
- **(온라인 코딩테스트는 UMPIRE를 버린다)** — 백준/프로그래머스류 1차 자동채점은 정답률·시간초과·메모리만 본다. 소통·명확화·트레이드오프가 0점이므로, 여기서는 **문제 정확 이해 → 제약(N, 시간/메모리 한계)에서 목표 복잡도 역산 → 엣지(빈입력·오버플로·경계) 처리 → 제출 전 반례 자가생성**만 한다. _(출처: 한국 채용 현실 / 실무 관찰)_
|
|
18
|
+
- **(라이브 코딩은 세션 길이로 프레임 강도를 정한다)** — 30~45분 세션에서는 **라이트 UMPIRE**(명확화 1~2개 + 접근법 1문장 합의 + 구현 + 끝나고 dry-run 1회). 60~120분(한국 라이브 코딩·페어프로그래밍)에서는 **풀 UMPIRE**(명확화 다수 + 평균/엣지 케이스 손추적 + 의사코드). 형식에 시간을 과배분해 구현 미완으로 탈락하는 것이 명확화 누락보다 더 흔한 실패다. _(출처: Tech Interview Handbook; CodePath UMPIRE — 단, 세션별 조절은 본 플레이북의 보정)_
|
|
19
|
+
- **(코딩 전 명확화·접근법 합의)** — 잘못된 가정으로 바로 코딩하면 틀린 문제를 푼다. 명확화(입력 범위·형식, 중복/음수/빈입력 허용, 반환 형식)와 접근법 합의는 빅테크 라이브 코딩에서 일관된 hire 신호다. _(출처: Tech Interview Handbook — Coding Interview Rubrics)_
|
|
20
|
+
- **(코드 작성 후 Review + Evaluate를 입으로)** — 버그가 있다고 가정하고 변수 워치리스트로 한 줄씩 추적(해피패스 → 엣지), 그다음 시간·공간 복잡도를 Big-O로 명시하고 대안 트레이드오프를 한 문장 언급한다. Testing은 4대 평가 축 중 하나다. _(출처: CodePath UMPIRE — Review/Evaluate; Tech Interview Handbook — Testing 축)_
|
|
21
|
+
- **(시스템 디자인은 다이어그램이 아니라 요구사항부터)** — FR 3개 이상 + NFR(확장성/가용성/지연/일관성) + 규모 추정을 먼저 글머리표로 적고 합의한다. "명확화 없이 아키텍처부터"는 1순위 탈락 원인이다. _(출처: Exponent System Design Guide; GeeksforGeeks — Common Mistakes)_
|
|
22
|
+
- **(45분은 기본값이며 포맷별로 재배분한다)** — Google/Meta형 45분은 *기본 타임박스*일 뿐이다. Amazon은 60분+행동결합, 한국 라이브는 60~120분, 스타트업 페어는 2~3시간이다. **세션 길이를 먼저 확인**하고, 어떤 길이든 "상위 설계에 시간을 다 쓰고 심층을 못 들어가는 것"을 피한다(심층이 변별 구간). _(출처: Exponent — time allocation; 회사별 포맷은 본 플레이북 보정)_
|
|
23
|
+
- **(모든 기술 선택에 구조적 트레이드오프)** — "X를 쓰면 A를 얻고 B를 잃는다 + 대안 1개" 형식. "무조건 좋다"식 단정은 감점. 면접관이 "10x/100x로 늘리면?"이라 밀 때 **병목이 어디로 이동하는지**(DB → 캐시 → 큐 → 샤딩) 설명한다. 최근 면접은 비용(가능하면 달러)·장애복구·운영성숙도까지 본다. _(출처: Exponent; DesignGurus — Anti-Patterns; interviewing.io 계열 기준)_
|
|
24
|
+
- **(면접은 모놀로그가 아니라 대화)** — 막히면 침묵하지 말고 현재 가설·막힌 지점을 소리 내어 말하고 힌트를 활용한다. 침묵이 가장 큰 감점이다. _(출처: Tech Interview Handbook — Communication 축)_
|
|
25
|
+
- **(과설계 금지: 단순하게 시작해 점진 확장)** — 요구사항이 정당화하지 않는 MSA/Kafka/k8s를 넣지 않는다. 정당화 사슬이 끊기면 mid-level 신호. _(출처: DesignGurus — 7 Anti-Patterns)_
|
|
26
|
+
- **(레벨로 기대치가 다르다)** — 같은 문제라도 주니어(L3/L4)는 "동작하는 설계"·"명확화 1~2개", 시니어(L5)는 "트레이드오프·실패모드·비용", 스태프(L6+)는 "요구사항 자체를 협상/축소·조직/운영 경계 설계"가 변별점이다. 준비 자료는 후보 레벨에 맞춰 기대치를 적는다. _(출처: DesignGurus — Google SD Rubric 차원; 레벨 차등은 본 플레이북 보정)_
|
|
27
|
+
|
|
28
|
+
### Do
|
|
29
|
+
|
|
30
|
+
- 코딩(라이브): 입력 형식·범위·중복/음수/빈입력·반환 형식 중 **세션 길이에 맞는 수**의 명확화 질문을 한다(짧으면 1~2개, 길면 더).
|
|
31
|
+
- 코딩(라이브): 평균 케이스 1개 + 엣지(빈입력/단일원소/최대 크기) 1개 이상을 **구체 값**으로 적고 손으로 추적한다.
|
|
32
|
+
- 코딩: 접근법을 의사코드/말로 설명하고 시간·공간 복잡도를 **미리** 말한 뒤 동의를 받고 코딩한다.
|
|
33
|
+
- 코딩(자동채점): 제출 전 N 제약에서 목표 복잡도를 역산하고, 오버플로·경계·빈입력 반례를 스스로 만들어 통과시킨다.
|
|
34
|
+
- 시스템: FR 3개+ / NFR(확장성·가용성·지연·일관성) / 규모(DAU·QPS·저장량)를 **설계 다이어그램보다 앞에** 글머리표로 합의한다.
|
|
35
|
+
- 시스템: API 시그니처와 데이터 모델(엔티티·주요 필드·인덱스/샤드 키)을 상위 설계 전에 정의한다.
|
|
36
|
+
- 시스템: **세션 길이를 먼저 확인**하고 단계별 분 배분을 명시하며, 합이 세션 길이에 맞고 심층 구간이 가장 크게 남도록 한다.
|
|
37
|
+
- 시스템: 각 컴포넌트 선택에 "얻는 것 vs 잃는 것 + 대안 1개" 트레이드오프 문장을 붙인다.
|
|
38
|
+
- 공통: 막히면 침묵하지 말고 현재 가설·막힌 지점을 소리 내어 말하고 힌트를 활용한다.
|
|
39
|
+
- 공통(가상 면접): CoderPad/공유에디터에서 화면공유 중 think-aloud를 유지하고, 시간이 부족하면 "여기까지 동작하고, 남은 부분은 이렇게 마무리할 계획"이라고 **우아하게 마무리**한다. AI 보조 도구가 허용되면 "왜 이 코드인지"를 직접 설명할 수 있어야 한다.
|
|
40
|
+
- 한국 맥락: CS 구술(자료구조·네트워크·OS·DB 인덱스/트랜잭션) 예상 질문과 답을 한국어로 준비한다. 경력직은 시스템 설계 대신 **트러블슈팅 경험 구술**이 나올 수 있으니 STAR로 정리한다.
|
|
41
|
+
|
|
42
|
+
### Don't
|
|
43
|
+
|
|
44
|
+
- 명확화 없이 곧바로 코딩하거나 다이어그램부터 그리지 않는다(가장 흔한 탈락 원인).
|
|
45
|
+
- 반대로, **짧은 세션에서 형식(명확화·손추적)에 시간을 과배분**해 구현 미완으로 끝내지 않는다.
|
|
46
|
+
- 접근법 설명 없이 정답 코드만 빠르게 타이핑하지 않는다.
|
|
47
|
+
- 복잡도 분석(Big-O)을 생략하거나 면접관이 물을 때까지 미루지 않는다.
|
|
48
|
+
- 테스트/dry-run 없이 "됐습니다"라고 선언하지 않는다.
|
|
49
|
+
- 시스템: 규모 추정 없이 SQL/NoSQL·캐시·큐를 선택하지 않는다.
|
|
50
|
+
- 시스템: 상위 설계에 시간을 다 써서 심층·트레이드오프 시간을 날리지 않는다.
|
|
51
|
+
- 시스템: 요구사항이 정당화하지 않는 MSA·Kafka·k8s로 과설계하지 않는다.
|
|
52
|
+
- 공통: 막혔을 때 오래 침묵하거나 혼자 머릿속으로만 풀지 않는다.
|
|
53
|
+
- 트레이드오프를 "무조건 좋다"식 단정으로 말하지 않는다(모든 선택에는 비용이 있다).
|
|
54
|
+
|
|
55
|
+
### 워크드 예시 (Before → After)
|
|
56
|
+
|
|
57
|
+
1. **Before:** 문제 "정렬된 배열에서 두 수의 합이 target이 되는 인덱스를 찾아라." 후보가 바로 "for 이중 루프로 모든 쌍 확인" O(n²) 코드를 타이핑.
|
|
58
|
+
**After (45분 라이브, 라이트 UMPIRE):** "명확화 먼저요 — 오름차순 맞나요? 정답이 항상 존재하나요? 중복 값 있나요?" (답 듣고) "정렬돼 있으니 투 포인터로 양 끝에서 좁히면 시간 O(n), 공간 O(1)입니다. 예: [2,7,11,15], target=9 → left=0,right=3 합 18>9 → right--… 이 접근으로 코딩할게요." (동의 후 구현, 끝나면 빈 배열·단일 원소 엣지 dry-run + Big-O 재확인.)
|
|
59
|
+
**왜 더 나은가:** Before는 명확화·접근설명·복잡도·테스트를 모두 놓치고 'sorted' 단서를 버려 차선 알고리즘을 택한다. After는 단서를 활용한 최적해와 강한 소통 신호를 짧은 세션 안에 동시에 보여준다.
|
|
60
|
+
|
|
61
|
+
2. **Before:** "URL 단축기를 설계하세요." 후보가 즉시 "LB → 웹서버 → MySQL → 캐시"를 그리고 "이렇게 하면 됩니다." 규모·읽기쓰기 비율·키 길이 언급 없음.
|
|
62
|
+
**After:** "요구사항부터요. 기능: 긴 URL→짧은 코드, 코드→리다이렉트, (선택)만료/커스텀 별칭. 비기능: 리다이렉트 p99 <100ms(캐시 히트 가정), 고가용성, 읽기:쓰기 ≈ 100:1. 규모: 쓰기 100M/월 ≈ **39 writes/s**, 읽기 ≈ **3,860 reads/s**, 5년 누적 ≈ **6B개**. 키 공간: base62 **6자 = 56.8B** 로 6B를 충분히 덮으므로 6자로 시작(여유 보려면 7자=3.5조). API: POST /shorten, GET /{code}. 데이터모델: code(PK)→long_url, 샤드키=code 해시. 읽기가 압도적이라 앞단에 캐시를 두고, 캐시 미스 시 DB. 트레이드오프: 카운터 기반 ID는 순차적이라 예측 가능 **대신** 조정 필요 ↔ 해시는 충돌 처리 필요."
|
|
63
|
+
**왜 더 나은가:** Before는 1순위 안티패턴(명확화 없이 다이어그램). After는 요구사항→추정→API→데이터모델→트레이드오프 순으로 진행하고 **숫자가 재검산되어 정확**하며(39/3,860/6B/56.8B), "읽기쓰기 비율"이 캐시 결정으로 이어지고 키 길이를 공간 계산으로 정당화한다. (이전 초안의 '4000 reads/s'·'7자가 빠듯한 듯'한 서술을 수정함.)
|
|
64
|
+
|
|
65
|
+
3. **Before:** 심층 "쓰기가 10배로 늘면요?" 후보: "서버를 늘리면 됩니다."
|
|
66
|
+
**After:** "쓰기 ≈ 390/s가 되면 병목은 단일 DB의 쓰기 처리량입니다. 순서대로 (1) code 해시 기준 수평 샤딩으로 쓰기 분산, (2) ID 충돌 회피를 위해 사전할당된 키 범위를 각 앱서버에 배분, (3) 강한 순서 보장이 필요 없는 분석 로그는 비동기 큐로 분리. 트레이드오프: 샤딩하면 쓰기는 확장되지만 범위 쿼리·재샤딩 운영 비용이 늘고, 큐는 처리량을 늘리되 최종 일관성·운영 복잡도를 더합니다."
|
|
67
|
+
**왜 더 나은가:** Before는 병목이 'DB 쓰기'임을 못 짚는다. After는 "10x 밀기"에서 평가자가 보려는 병목 식별 → 구체 전략 → 각 전략의 트레이드오프·운영 비용을 정확히 제공한다.
|
|
68
|
+
|
|
69
|
+
## 3. 검증 루브릭 (연결된 AI가 산출물을 이 기준으로 자가검증)
|
|
70
|
+
|
|
71
|
+
> **이 루브릭은 "형식 floor 검사(format lint)"다 — 합격 점수가 아니다.** 모든 검사는 키워드·개수·정규식·위치 비교로 LLM 없이 측정하므로 **구조의 존재만** 본다(예: 'O(n)'이 *맞는지*는 못 본다, 'vs'가 든 문장이 *공허한지*는 못 본다). 따라서 self_check 결과는 `passedCount/totalCount`가 아니라 **"형식 최소 요건 충족/미충족"** 으로 라벨링하고, "정확성·추론 품질은 연결된 AI가 별도 판정"이라는 경고를 반드시 함께 반환한다. 아래 임계값(≥2, ≥3 등)은 **휴리스틱 컷이며 회사/레벨/문제 난이도에 따라 조정 대상**이다(절대선 아님). R10~R11은 안티패턴을 **역검출**하는 negative-check다.
|
|
72
|
+
|
|
73
|
+
| ID | 검사 항목 | 합격 기준 (형식 floor) | 측정 방법(LLM 없이 셀 수 있게) |
|
|
74
|
+
|----|-----------|-----------|--------------------------------|
|
|
75
|
+
| R1 | 명확화 질문 존재 | 명확화 질문 ≥ 2개 (라이브 트랙 한정; 자동채점 트랙은 면제). 휴리스틱 컷 — junior 문제는 1개로 충분할 수 있음 | '?'로 끝나는 질문 문장 수 ≥ 2 **그리고** '명확화/Clarify' 섹션 헤더 존재. 트랙이 `online_coding_test`면 본 검사 skip |
|
|
76
|
+
| R2 | 테스트 케이스 구체성 | 구체 입력값 케이스 ≥ 2개, 그중 엣지 ≥ 1개 | '입력→출력' 형태 예시 수 ≥ 2 **그리고** 엣지 키워드('빈'/'empty'/'단일'/'[]'/'null'/'경계'/'오버플로') ≥ 1개 케이스에 매칭 |
|
|
77
|
+
| R3 | 복잡도 명시 (정확성 아님) | 시간·공간 각각 O(...) 표기 ≥ 1개 | 정규식 `O\([^)]+\)` 매칭 ≥ 2 **그리고** '시간/time'·'공간/space' 두 키워드 모두 등장. ※ **표기의 정확성은 미측정** — 경고 플래그 함께 반환 |
|
|
78
|
+
| R4 | 요구사항 우선 배치 | FR ≥ 3 글머리표 + NFR 키워드 ≥ 2, 그리고 요구사항 섹션이 아키텍처 섹션보다 **앞에** 위치 | '요구사항/requirements' 섹션 글머리표 수 ≥ 3; NFR 키워드(확장성·가용성·지연·일관성/scalability·availability·latency·consistency) ≥ 2; 문서 내 요구사항 섹션 시작 오프셋 < 아키텍처/설계 섹션 시작 오프셋 |
|
|
79
|
+
| R5 | 규모 추정(숫자+단위) | DAU/QPS/저장량 중 ≥ 2종에 구체 숫자+단위 | **단위가 붙은** 숫자만 카운트: 정규식 `\d+\s*(M\|K\|B\|GB\|TB\|/s\|QPS\|DAU)` **또는** 한글 수사 `(천만\|백만\|억\|만)\s*(명\|건\|개)?` / `초당\s*\d+` 매칭 ≥ 2. **단위 없는 숫자·`base62 7자`·`O(1)`·`HTTP 2` 류는 제외**(앞뒤 토큰으로 단위 검증). '추정/estimation' 섹션 헤더 동시 존재 요구 |
|
|
80
|
+
| R6 | 구조적 트레이드오프 | "얻고/잃는" 구조 트레이드오프 문장 ≥ 3개 + 대안 ≥ 1 | **좁힌 패턴만**: 한 문장에 (트레이드오프 신호 '대신'/'트레이드오프'/'↔'/'tradeoff' **또는** '얻'+'잃'/'gain'+'lose') **그리고** 기술명/명사 2개 이상 동시 출현 ≥ 3. ※ 일반 '하지만/반면'만으로는 카운트 안 함(위양성 차단) |
|
|
81
|
+
| R7 | 타임박싱이 심층을 보호 + 합이 세션 길이에 맞음 | 분 배분 단계 ≥ 4개; 분 합이 (세션 길이 ±10%) 범위; 심층 단계 분 ≥ 상위설계 단계 분 | '분/min' 숫자 붙은 단계 수 ≥ 4; **모든 단계 분의 합이 [세션×0.9, 세션×1.0] 범위에 드는지 합산 검증**(기본 세션=45, 입력으로 60/90/120 등 지정 가능); '심층/deep dive' 분 ≥ '상위/high-level' 분 |
|
|
82
|
+
| R8 | 소통/막힘 대응 가이드 존재 (자료 완비성, 후보 역량 아님) | 막힘 대응 항목 ≥ 1 | '막히면/소리 내어/think aloud/힌트/대화' 키워드 ≥ 1. ※ 이는 **준비 자료에 문장이 들어갔는지**일 뿐 실제 소통 능력이 아님 — 경고 플래그 함께 반환 |
|
|
83
|
+
| R9 | 과설계 경고 존재 | '단순하게 시작'/'요구사항 정당화' 취지 ≥ 1 | '과설계/over-engineer/단순하게 시작/점진/정당화' 키워드 ≥ 1 |
|
|
84
|
+
| R10 | **(negative)** 트레이드오프 단정 안티패턴 미검출 | "무조건/항상 좋다/best/언제나 우월" 식 단정 문장 = 0 | '무조건'/'항상 좋'/'언제나'/'always better'/'best choice' 패턴 매칭 = 0 이면 통과(존재하면 **실패 플래그**) |
|
|
85
|
+
| R11 | **(negative)** "명확화 없이 코드/다이어그램" 흔적 미검출 | 문서 첫 섹션이 코드블록/다이어그램이 아니라 요구사항·명확화 | 첫 비공백 콘텐츠 블록이 코드펜스(```)/아키텍처 키워드가 아니라 '요구사항'/'명확화' 섹션인지 위치 검사. 아니면 **실패 플래그** |
|
|
86
|
+
|
|
87
|
+
**주요 실패 모드 (게이밍·위양성 정직 고지):**
|
|
88
|
+
- **게이밍**: 의미 없는 명확화 질문 2개, 틀린 'O(n)' 2개, '대신'이 든 공허한 문장 3개만 붙여도 R1·R3·R6은 PASS한다. 루브릭은 **구조의 존재**만 보장하지 **질·정확성을 0% 보장하지 않는다.** self_check가 '전부 PASS'여도 연결된 AI는 (a) 복잡도가 실제로 맞는지 (b) 트레이드오프가 공허하지 않은지 (c) 추정 숫자가 재검산되는지를 **반드시 별도 검토**해야 한다.
|
|
89
|
+
- **proxy 한계**: 이 형식 충족도는 실제 면접 통과율과 상관관계가 **입증되지 않은 대리지표**다. "self_check 통과 = 합격"으로 사용자에게 제시하면 가짜 자신감을 준다.
|
|
90
|
+
- **위양성 예시(자료에 박제 금지)**: "캐시는 빠르지만 좋다 vs 나쁘다"(R6 통과하나 공허), "O(n)으로 정렬"(R3 통과하나 정렬은 O(n log n)) — 이런 건 연결된 AI가 잡아야 한다.
|
|
91
|
+
|
|
92
|
+
## 4. 출처 (Provenance)
|
|
93
|
+
|
|
94
|
+
- **Tech Interview Handbook — Coding Interview Rubrics** — 코딩 라이브 면접 4대 평가 축(Communication/Problem-solving/Technical competency/Testing)과 '코딩 전 명확화·접근법 설명'이 hire 신호라는 근거 · https://www.techinterviewhandbook.org/coding-interview-rubrics/
|
|
95
|
+
- **Tech Interview Handbook — Coding Interview Cheatsheet** — before/during/after 체크리스트(green light 후 코딩, 코딩하며 설명, 의미있는 변수명·함수 추출) · https://www.techinterviewhandbook.org/coding-interview-cheatsheet/
|
|
96
|
+
- **CodePath — UMPIRE Interview Strategy** — UMPIRE 6단계 구체 행동(Understand/Plan/Review/Evaluate). **단, UMPIRE는 CodePath의 교육용 니모닉이지 Google/Meta 공식 채점 루브릭이 아니다 — 빅테크는 'UMPIRE 준수'가 아니라 코드 정확성·테스트 통과·복잡도를 hidden rubric으로 채점한다.** · https://guides.codepath.org/compsci/UMPIRE-Interview-Strategy
|
|
97
|
+
- **DesignGurus — System Design Rubric 차원 / 7 Anti-Patterns** — 평가 차원(요구사항·아키텍처·기술깊이·트레이드오프), 과설계 등 안티패턴. **2차(블로그) 출처이며 실제 회사 1차 루브릭이 아님에 주의.** · https://www.designgurus.io/blog/
|
|
98
|
+
- **Exponent — System Design Interview Guide** — 45분 단계별 시간 배분의 *기본값*, 10x/100x 밀어붙이기, 심층에서 차별화. **회사별 세션 길이(Amazon 60분·한국 60~120분·스타트업 2~3h)와 레벨 차등은 본 플레이북의 보정이며 이 단일 소스에 과의존하지 말 것.** · https://www.tryexponent.com/blog/system-design-interview-guide
|
|
99
|
+
- **GeeksforGeeks / SystemDesignHandbook — Common Mistakes** — 핵심 안티패턴(명확화 없이 다이어그램, 모놀로그, 한꺼번에 다루기). 2차 출처 · https://www.geeksforgeeks.org/system-design/common-mistakes-to-avoid-in-a-system-design-interview/
|
|
100
|
+
- **본 플레이북 보정(1차 자료 없음, 실무 관찰 기반)** — 온라인 코딩테스트 vs 라이브 코딩 분리, 세션 길이별 프레임 강도(라이트/풀 UMPIRE), 레벨(L3~L6+) 차등 기대치, FE/ML/데이터/모바일·디버깅 트랙 존재, AI 보조도구 정책, 한국 채용 루프(자동채점 1차 → 라이브 2차, 경력직 트러블슈팅 구술). 이 항목들은 위 2차 출처가 직접 뒷받침하지 않으므로 회사/연도별로 재확인 대상이다.
|
|
101
|
+
|
|
102
|
+
## 5. Phase B 힌트 (아키텍처로 연결)
|
|
103
|
+
|
|
104
|
+
- **MCP 도구 아이디어:**
|
|
105
|
+
- `get_interview_prep_playbook({ track, role?, company?, level?, session_minutes?, locale? })` — `track`은 `online_coding_test | live_coding | system_design_backend | system_design_frontend | system_design_ml | debugging | behavioral` 로 확장. 트랙별 (a) 프레임(자동채점 체크 / 라이트·풀 UMPIRE / SD 타임박스), (b) do/dont, (c) 막힘·시간초과 마무리 스크립트, (d) 형식 루브릭을 반환. `level`로 passBar 분기, `session_minutes`로 R7 합산 기준 설정, `locale:'ko'`면 CS 구술 세트 + 한국어 스크립트 + 경력직 트러블슈팅 STAR 템플릿 포함.
|
|
106
|
+
- `self_format_lint_interview_prep({ artifact_text, track, session_minutes?, level? })` — **이름을 `self_check`에서 `self_format_lint`로 변경**(정직성). LLM 없이 R1~R11 패턴/개수/위치/negative만 측정. 반환에 **경고 플래그 강제 포함**: 형식 충족 여부일 뿐 합격·정확성 보장 아님.
|
|
107
|
+
- `generate_mock_questions({ track, topic })` — `get_application_context`에 **기술 스택 필드가 실제 있는지 먼저 검증**하고, 없으면 role/company로 폴백. 컨텍스트 기반 예상 질문 세트 serve.
|
|
108
|
+
- `save_interview_prep` — 기존 8단계 게이팅(**document_passed 이상에서만 해금**)을 그대로 존중. 단 **track/framework/rubric_result 필드 추가가 필요하면 스키마 확장 + 기존 데이터 마이그레이션 영향(현 스키마는 questions/star_guides/self_introduction/notes만 받음)을 Phase B에서 명시 설계**할 것.
|
|
109
|
+
- **데이터 형태 힌트:**
|
|
110
|
+
```
|
|
111
|
+
playbook = {
|
|
112
|
+
track, level, session_minutes,
|
|
113
|
+
framework: { steps: [{ name, minutes, actions: [...] }], total_minutes, frame_intensity: 'light'|'full'|'autograder' },
|
|
114
|
+
doList: [...], dontList: [...],
|
|
115
|
+
communication_scripts: [{ situation: '막힘'|'시간초과', say: '...' }],
|
|
116
|
+
rubric: [{ id, check, passBar, measure: { type: 'count'|'exists'|'ratio'|'regex'|'order'|'sum_in_range'|'negative', pattern, threshold, session_aware? } }],
|
|
117
|
+
disclaimer: '루브릭은 형식 floor — 정확성·추론 품질은 연결된 AI가 판정'
|
|
118
|
+
}
|
|
119
|
+
self_format_lint 반환 = {
|
|
120
|
+
track,
|
|
121
|
+
checks: [{ id, passed: bool, observed: number, required: number, kind: 'positive'|'negative', accuracy_unverified: bool }],
|
|
122
|
+
format_floor_met: bool, // passedCount/totalCount 대신 — '점수' 오독 방지
|
|
123
|
+
warning: 'PASS는 형식 충족일 뿐 정답·합격 보장 아님'
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
rubric의 measure는 정규식/키워드/개수/위치/합산/역검출 기반이라 외부 AI 없이 CareerMate가 산출물 텍스트에 직접 적용 가능. `session_aware`·`level` 분기로 R7 합산 기준과 R1 임계값을 조정한다.
|