Skip to content

Fix/#60 change interview score - #61

Merged
2-dayeon merged 46 commits into
mainfrom
fix/#60-change-interview-score
Oct 21, 2026
Merged

2-dayeon merged 46 commits into
mainfrom
fix/#60-change-interview-score

Conversation

@2-dayeon

Copy link
Copy Markdown
Contributor

No description provided.

@kimwuju kimwuju left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

competency-v1 채점 경로를 봤습니다. 매핑·근거 슬롯·등급 상한·집계, 전 직무(15개) solo/multi 시스템 프롬프트의 v4 기준 교체, strict 도구 스키마 제약, API 서버(#121) 콜백 수신 형식은 확인했고 문제를 찾지 못했습니다. 남은 문제 2건을 인라인으로 남깁니다.

]
breakdown = compute_breakdown(owned)
if owned and isinstance(owned[0], QuestionScore):
scores = summarize_competency_session([cast("QuestionScore", item) for item in owned], None, persona=True)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동기 문항만 맡은 면접관은 답을 잘해도 면접관 점수가 0점으로 나갑니다

MOTIVATION은 WEIGHTS에 없어서 종합 가중 평균에 들어가지 않고, summarize_session은 관측된 축이 없으면 total_score를 0으로 돌려줍니다. 세션 전체에는 기술 문항이 있어 괜찮지만, 면접관별 점수는 그 면접관이 맡은 문항만 넣기 때문에 문제가 됩니다.

N:1 HR 면접관은 권장 카테고리가 motivation·growth·collaboration이고 question_count가 1일 수 있어서, 동기 문항 하나만 받는 경우가 실제로 생깁니다. 이때 콜백은 score: 0, axes 전부 null, motivation.score: 100이 됩니다. 화면에는 "HR 면접관 0점"으로 보입니다. 미분류 문항에서 inferred_primary가 null로 온 경우도 같습니다.

재현: resolve_targets("motivation", "BACKEND", "HR") 문항 하나를 response 4, motivation 근거 4로 만들어 summarize_session([q], None, persona=True)를 부르면 total_score == 0, payload["motivation"]["score"] == 100입니다.

기존 코드는 "0점"과 "평가 대상 없음"을 구분하려고 담당 답변이 없는 면접관을 null로 보냈습니다. 같은 이유로, 가중 축이 하나도 관측되지 않은 면접관은 score를 null로 보내는 게 맞아 보입니다(scoreBreakdown은 남겨서 동기·응답 점수는 보이게).

Comment thread evaluation/run_feedback.py Outdated
@@ -94,6 +99,11 @@ def parse_result(case: dict[str, Any], content_blocks: list[dict[str, Any]], too
expected = {question["id"] for question in case["questions"]}
if set(by_id) != expected or len(feedbacks) != len(expected):
raise ValueError("질문별 피드백 id 불일치")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

competency-v1 평가 실행에서는 문항 누락 재시도가 일어나지 않아, 전환 기준의 실패율 비교가 v1에 불리하게 나옵니다

feedback_attempts.evaluate는 IncompleteGradingError일 때만 재시도합니다. axis-v4는 parse 전에 validate_legacy가 운영 파서를 먼저 돌려서, 문항이 빠지면 IncompleteGradingError가 나고 재시도됩니다. competency-v1은 그 단계가 없어서 여기 parse_result의 id 검사가 먼저 걸리고, ValueError("질문별 피드백 id 불일치")로 바로 실패합니다. 운영 parse_submission은 같은 응답에 IncompleteGradingError를 내고 한 번 더 부르므로, 평가 결과와 운영 동작이 다릅니다.

그래서 competency_gate의 "재시도 후 실패율 ≤ 기존 및 2%"는 v4는 재시도 후, v1은 재시도 없이 잰 값을 비교합니다. 운영 전환 판단이 이 값에 걸려 있어 결과가 틀리게 나옵니다.

competency-v1일 때는 이 id 검사보다 먼저 competency_run.parse_result(운영 parse_submission)를 돌리거나, 이 검사 실패를 IncompleteGradingError로 바꿔야 할 것 같습니다.

@danjee2009 danjee2009 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요청·응답 계약, competency-v1 채점/근거 검증, SOLO·MULTI 디스패치, 평가 도구와 테스트 변경을 검토했습니다. 확인된 실질적인 문제는 없습니다. GitHub의 behavior 및 checks 작업은 통과했습니다. 실제 LLM 반복 평가와 사람 평가 절차는 코드 리뷰에서 실행하지 않았으며, 문서에 적힌 대로 운영 전환 전 별도 검증이 필요합니다.

@kimwuju kimwuju left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 리뷰했습니다. 머지를 막을 버그는 찾지 못했습니다.

확인한 내용

  • docs/feedback-scoring-contract-v2.md와 구현이 일치합니다: 응답 등급별 주 역량 상한, 보조 역량은 등급 1 이상만 집계, 관측된 축만으로 가중 평균, 면접관 점수 null 조건, 답변이 1개면 consistency/reliability null, v4 문항 피드백에는 새 필드 미포함.
  • category: 형식이 틀린 값은 422 대신 미분류로 처리하고, FOLLOW는 부모 카테고리를 이어받습니다. MULTI 질문 DTO도 FeedbackQuestion을 상속하므로 category가 빠지지 않고 전달됩니다.
  • MULTI 질문 생성의 category enum(비기술 5종)은 비TECH 면접관 질문에만 적용됩니다. TECH 질문은 tech_questions로 따로 들어오므로 개발 카테고리 매핑이 그대로 유지됩니다.
  • 실패 콜백에는 result 키가 없어서, debug 로그 분기의 .get("result", {}) 체인에서 예외가 나지 않습니다.
  • API 서버의 ScoreBreakdownReader와 reliabilityScore(nullable Integer)도 새 페이로드 모양을 받을 수 있습니다.

uv run pytest 결과 1535개 통과, 22개 건너뜀입니다.

@kimwuju kimwuju left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앞선 리뷰에서 확인한 내용으로 승인합니다.

@2-dayeon
2-dayeon merged commit c48f01f into main Oct 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants