feat(eval): E.6 runner + 평가셋 main 복원 (from feat/eval-infra)
selective checkout (not cherry-pick): - scripts/run_eval_ask.py (RESULT_FIELDS 21 고정, X-Source:eval 헤더) - evals/ask_analyze_v1.jsonl (300 case = ask 220 + analyze 80) E.3/E.6 측정 진입점. feat/eval-infra 의 원본은 유지. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,300 @@
|
|||||||
|
{"id": "ask_def_001", "type": "ask", "category": "정의", "query": "산업안전보건법의 목적은?", "expected_behavior": "answered", "critical_keywords": ["근로자", "안전", "보건"], "must_not": ["출처 없음", "무근거 단정"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_def_002", "type": "ask", "category": "정의", "query": "위험성평가가 정확히 무엇인지 내 자료 기준으로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["유해·위험요인", "평가", "개선대책"], "must_not": ["조문만 나열"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_def_003", "type": "ask", "category": "정의", "query": "안전보건관리체계가 뭘 의미하는지 쉽게 설명해줘", "expected_behavior": "answered", "critical_keywords": ["체계", "관리", "안전보건"], "must_not": ["전문용어만 반복"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_def_004", "type": "ask", "category": "정의", "query": "중대재해라는 표현은 내 문서 기준으로 어떤 의미야?", "expected_behavior": "answered", "critical_keywords": ["중대재해", "정의"], "must_not": ["법조문 인용만"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_def_005", "type": "ask", "category": "정의", "query": "TBM이 뭔지 현장 작업자도 이해할 수 있게 설명해줘", "expected_behavior": "answered", "critical_keywords": ["TBM", "작업 전", "공유"], "must_not": ["약어만 설명"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_def_006", "type": "ask", "category": "정의", "query": "작업허가제는 왜 필요한 제도인지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["작업허가", "위험 작업", "사전 확인"], "must_not": ["필요성 설명 없음"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_def_007", "type": "ask", "category": "정의", "query": "개인보호구의 의미를 단순 구매 목록 말고 관리 관점에서 설명해줘", "expected_behavior": "answered", "critical_keywords": ["개인보호구", "선정", "착용", "관리"], "must_not": ["품목 나열만"], "notes": ["조문 회피 집중", "현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_def_008", "type": "ask", "category": "정의", "query": "안전교육이 법정교육이라는 말이 정확히 무슨 뜻이야?", "expected_behavior": "answered", "critical_keywords": ["안전교육", "법정", "의무"], "must_not": ["추상적 설명만"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_001", "type": "ask", "category": "절차", "query": "위험성평가 절차를 단계별로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["유해·위험요인 파악", "위험성 결정", "감소대책", "기록"], "must_not": ["단계 누락"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_002", "type": "ask", "category": "절차", "query": "신규 공정 도입 전에 위험성평가를 어떤 순서로 해야 하는지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["사전 검토", "위험요인", "대책"], "must_not": ["현장 적용 빠짐"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_003", "type": "ask", "category": "절차", "query": "작업허가가 필요한 작업은 현장에서 어떤 순서로 승인받아야 해?", "expected_behavior": "answered", "critical_keywords": ["신청", "검토", "승인", "작업 전 확인"], "must_not": ["순서 불명확"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_004", "type": "ask", "category": "절차", "query": "사고 발생 후 재발방지대책 수립 절차를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["원인 분석", "대책 수립", "재발방지"], "must_not": ["원인 분석 없음"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_005", "type": "ask", "category": "절차", "query": "정기 안전점검은 어떤 흐름으로 운영해야 하는지 내 자료 기준으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["점검 계획", "실시", "조치", "추적"], "must_not": ["조치 후 추적 누락"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_006", "type": "ask", "category": "절차", "query": "신규 입사자 안전교육 절차를 준비부터 기록까지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["교육 계획", "실시", "기록"], "must_not": ["기록 관리 누락"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_007", "type": "ask", "category": "절차", "query": "협력업체 작업 전 안전협의 절차를 단계별로 알려줘", "expected_behavior": "answered", "critical_keywords": ["사전 협의", "위험 공유", "책임 구분"], "must_not": ["협의 절차 누락"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_proc_008", "type": "ask", "category": "절차", "query": "고소작업 전 점검 절차를 현장 체크 흐름으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["작업 전 점검", "추락 방지", "장비 확인"], "must_not": ["체크 흐름 없음"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_001", "type": "ask", "category": "적용", "query": "위험성평가 절차를 현장에 바로 활용 가능하게 정리해줘", "expected_behavior": "answered", "critical_keywords": ["현장", "실행", "점검"], "must_not": ["조문만 나열"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_002", "type": "ask", "category": "적용", "query": "용접 작업 전에 뭘 확인해야 하는지 체크리스트처럼 정리해줘", "expected_behavior": "answered", "critical_keywords": ["화재", "가연물", "소화기", "감시자"], "must_not": ["법령만 인용"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_003", "type": "ask", "category": "적용", "query": "끼임 위험이 있는 설비 작업에서 관리자와 작업자가 각각 뭘 해야 하는지 나눠서 설명해줘", "expected_behavior": "answered", "critical_keywords": ["관리자", "작업자", "끼임"], "must_not": ["역할 구분 없음"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_004", "type": "ask", "category": "적용", "query": "추락 위험 작업을 시작하기 전에 반장이 팀원들에게 어떻게 설명하면 좋은지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["추락", "작업 전 공유", "주의사항"], "must_not": ["현장 언어 부재"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_005", "type": "ask", "category": "적용", "query": "신규 작업자 교육용으로 위험성평가를 쉽게 풀어서 설명해줘", "expected_behavior": "answered", "critical_keywords": ["쉽게", "교육용", "위험요인"], "must_not": ["전문 용어만"], "notes": ["조문 회피 집중", "현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_006", "type": "ask", "category": "적용", "query": "작업허가제 문서를 실제 현장 승인 흐름에 맞게 요약해줘", "expected_behavior": "answered", "critical_keywords": ["신청", "검토", "승인", "작업 중 관리"], "must_not": ["문서 제목만 반복"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_007", "type": "ask", "category": "적용", "query": "밀폐공간 작업 기준을 작업 시작 전 브리핑용으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["밀폐공간", "산소", "가스측정", "감시"], "must_not": ["브리핑 포맷 부재"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_apply_008", "type": "ask", "category": "적용", "query": "안전점검 결과를 보고 바로 조치할 수 있게 우선순위 중심으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["우선순위", "위험도", "즉시 조치"], "must_not": ["우선순위 없음"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ask_cmp_001", "type": "ask", "category": "비교", "query": "위험성평가와 작업 전 안전회의(TBM)의 차이를 비교해줘", "expected_behavior": "answered", "critical_keywords": ["위험성평가", "TBM", "차이"], "must_not": ["한쪽만 설명"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_cmp_002", "type": "ask", "category": "비교", "query": "법정 안전교육과 사내 교육의 차이를 내 자료 기준으로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["법정", "사내", "차이"], "must_not": ["비교 구조 없음"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_cmp_003", "type": "ask", "category": "비교", "query": "정기점검과 수시점검은 어떻게 다른지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["정기점검", "수시점검"], "must_not": ["비교표현 없음"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_cmp_004", "type": "ask", "category": "비교", "query": "작업중지와 작업연기는 현장에서 어떤 차이로 이해하면 돼?", "expected_behavior": "answered", "critical_keywords": ["작업중지", "작업연기"], "must_not": ["현장 맥락 없음"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_cmp_005", "type": "ask", "category": "비교", "query": "사고조사와 위험성평가가 각각 언제 필요한지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["사고조사", "위험성평가", "시점"], "must_not": ["언제 필요한지 누락"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_cmp_006", "type": "ask", "category": "비교", "query": "관리감독자와 안전관리자의 역할 차이를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["관리감독자", "안전관리자", "역할"], "must_not": ["역할 혼동"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_cmp_007", "type": "ask", "category": "비교", "query": "개인보호구 착용 점검과 설비 안전점검은 왜 다르게 운영해야 하는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["개인보호구", "설비", "점검"], "must_not": ["차별점 설명 부족"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_cmp_008", "type": "ask", "category": "비교", "query": "사내 기준서와 법령 요구사항의 차이를 어떻게 봐야 하는지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["사내 기준", "법령", "차이"], "must_not": ["우선순위 혼동"], "notes": ["비교 구조 명확성"], "golden": true}
|
||||||
|
{"id": "ask_part_001", "type": "ask", "category": "partial_refused", "query": "OSHA 기준까지 포함해서 국내 기준과 완전히 비교해줘", "expected_behavior": "partial", "critical_keywords": ["국내 기준"], "must_not": ["허구 비교", "없는 자료 단정"], "notes": ["partial 적절성 확인"], "golden": true}
|
||||||
|
{"id": "ask_part_002", "type": "ask", "category": "partial_refused", "query": "우리 회사 실제 현장 사고사례를 구체적으로 다 알려줘", "expected_behavior": "partial", "critical_keywords": ["사례"], "must_not": ["없는 사례 단정"], "notes": ["partial 적절성 확인"], "golden": true}
|
||||||
|
{"id": "ask_part_003", "type": "ask", "category": "partial_refused", "query": "최신 법 개정 내용까지 반영해서 설명해줘", "expected_behavior": "partial", "critical_keywords": ["현재 자료 기준"], "must_not": ["최신성 단정"], "notes": ["partial 적절성 확인"], "golden": true}
|
||||||
|
{"id": "ask_part_004", "type": "ask", "category": "partial_refused", "query": "문서에 없는 해외 모범사례까지 포함해서 교육안을 짜줘", "expected_behavior": "partial", "critical_keywords": ["문서 근거"], "must_not": ["외부 지식 혼입"], "notes": ["partial 적절성 확인"], "golden": true}
|
||||||
|
{"id": "ask_part_005", "type": "ask", "category": "partial_refused", "query": "우리 공장의 특정 설비 사진을 보고 판단한 것처럼 설명해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["보지 못한 정보 단정"], "notes": ["refused 근거 없음 판단"], "golden": true}
|
||||||
|
{"id": "ask_part_006", "type": "ask", "category": "partial_refused", "query": "이 자료를 근거로 법적 책임 여부를 최종 판정해줘", "expected_behavior": "partial", "critical_keywords": ["근거", "판정 한계"], "must_not": ["법적 단정"], "notes": ["partial 적절성 확인"], "golden": true}
|
||||||
|
{"id": "ask_part_007", "type": "ask", "category": "partial_refused", "query": "현재 자료 기준으로는 없는 세부 수치까지 정확히 채워줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["수치 추정"], "notes": ["refused 근거 없음 판단"], "golden": true}
|
||||||
|
{"id": "ask_part_008", "type": "ask", "category": "partial_refused", "query": "이 문서와 무관한 인사평가 기준까지 같이 설명해줘", "expected_behavior": "partial", "critical_keywords": ["범위 한계"], "must_not": ["무관 내용 확장"], "notes": ["partial 적절성 확인"], "golden": true}
|
||||||
|
{"id": "ana_sum_001", "type": "analyze", "category": "전체요약", "doc_id": 3853, "query": "이 문서의 핵심 내용을 전체 흐름 중심으로 요약해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["핵심 메시지", "문서 전체 흐름"], "must_not": ["앞부분만 요약"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_sum_002", "type": "analyze", "category": "전체요약", "doc_id": 3853, "query": "이 문서가 무엇을 위한 문서인지 한 번에 이해되게 정리해줘", "expected_layers": ["summary"], "critical_points": ["문서 목적"], "must_not": ["세부만 나열"], "notes": ["조문 회피 집중"], "golden": true}
|
||||||
|
{"id": "ana_sum_003", "type": "analyze", "category": "전체요약", "doc_id": 3853, "query": "이 문서의 핵심 내용을 4문장 안팎으로 압축해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["핵심 내용"], "must_not": ["문서 목적 누락"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_sum_004", "type": "analyze", "category": "전체요약", "doc_id": 3853, "query": "이 문서를 처음 보는 관리자에게 전체 개요를 설명하듯 정리해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["개요", "관리자 관점"], "must_not": ["세부 조항만 반복"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ana_sum_005", "type": "analyze", "category": "전체요약", "doc_id": 3853, "query": "문서 전체를 기준으로 중요한 순서대로 핵심을 정리해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["우선순위"], "must_not": ["무순서 나열"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_core_001", "type": "analyze", "category": "핵심정리", "doc_id": 3853, "query": "이 문서에서 꼭 챙겨야 할 핵심 항목만 뽑아줘", "expected_layers": ["evidence", "summary"], "critical_points": ["핵심 항목"], "must_not": ["주변 설명만"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_core_002", "type": "analyze", "category": "핵심정리", "doc_id": 3853, "query": "실무자가 놓치기 쉬운 포인트 중심으로 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["놓치기 쉬운 포인트"], "must_not": ["일반론만"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ana_core_003", "type": "analyze", "category": "핵심정리", "doc_id": 3853, "query": "이 문서의 필수 요구사항과 권고사항이 구분된다면 나눠서 설명해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["필수", "권고"], "must_not": ["구분 실패"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_core_004", "type": "analyze", "category": "핵심정리", "doc_id": 3854, "query": "문서 전반에서 반복되는 중요한 메시지가 무엇인지 정리해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["반복되는 메시지"], "must_not": ["단편 요약"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_core_005", "type": "analyze", "category": "핵심정리", "doc_id": 3854, "query": "이 문서를 3개의 핵심 주제로 묶어서 설명해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["주제 3개"], "must_not": ["주제 구조 없음"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_apply_001", "type": "analyze", "category": "현장적용", "doc_id": 3854, "query": "이 문서를 현장에서 바로 활용할 수 있게 실행 포인트 중심으로 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["실행 포인트", "현장 활용"], "must_not": ["조문/원문 나열"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ana_apply_002", "type": "analyze", "category": "현장적용", "doc_id": 3854, "query": "반장 브리핑용으로 이 문서를 쉽게 풀어 설명해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["브리핑용", "쉬운 설명"], "must_not": ["전문 용어만"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ana_apply_003", "type": "analyze", "category": "현장적용", "doc_id": 3854, "query": "현장 점검 체크 관점에서 이 문서를 읽으면 무엇을 봐야 하는지 정리해줘", "expected_layers": ["explanation", "evidence"], "critical_points": ["점검 포인트"], "must_not": ["체크 포인트 없음"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ana_apply_004", "type": "analyze", "category": "현장적용", "doc_id": 3854, "query": "이 문서 내용을 작업자 교육에 쓴다면 어떤 메시지를 강조해야 하는지 알려줘", "expected_layers": ["explanation", "summary"], "critical_points": ["교육", "강조 메시지"], "must_not": ["교육 맥락 없음"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ana_apply_005", "type": "analyze", "category": "현장적용", "doc_id": 3854, "query": "실제 운영 절차로 옮기려면 어떤 순서로 적용하면 좋을지 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["운영 절차", "적용 순서"], "must_not": ["실행 순서 없음"], "notes": ["현장 적용성 집중"], "golden": true}
|
||||||
|
{"id": "ana_layer_001", "type": "analyze", "category": "층구조", "doc_id": 3888, "query": "이 문서를 근거, 해설, 사례, 요약 구조로 나눠 설명해줘", "expected_layers": ["evidence", "explanation", "summary"], "critical_points": ["구조화"], "must_not": ["층 구분 없음"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_layer_002", "type": "analyze", "category": "층구조", "doc_id": 3888, "query": "문서에서 사실 정보와 해석 정보를 구분해서 정리해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["사실", "해석"], "must_not": ["구분 실패"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_layer_003", "type": "analyze", "category": "층구조", "doc_id": 3888, "query": "사례가 있다면 사례를 따로 빼고, 없다면 그 이유를 포함해 설명해줘", "expected_layers": ["examples", "summary"], "critical_points": ["사례 여부"], "must_not": ["사례 날조"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_layer_004", "type": "analyze", "category": "층구조", "doc_id": 3853, "query": "왜 중요한지까지 포함해서 계층적으로 정리해줘", "expected_layers": ["evidence", "explanation", "summary"], "critical_points": ["왜 중요한지"], "must_not": ["중요성 부재"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ana_layer_005", "type": "analyze", "category": "층구조", "doc_id": 3853, "query": "핵심 근거와 현장 해설을 분리해서 읽기 쉽게 정리해줘", "expected_layers": ["evidence", "explanation", "summary"], "critical_points": ["근거", "해설 분리"], "must_not": ["혼합 서술"], "notes": ["층 구조 구분 능력"], "golden": true}
|
||||||
|
{"id": "ask_def_009", "type": "ask", "category": "정의", "query": "화학물질관리법에서 말하는 유해화학물질이란 무엇인지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["유해화학물질", "화관법"], "must_not": ["법조문만 인용"], "golden": false}
|
||||||
|
{"id": "ask_def_010", "type": "ask", "category": "정의", "query": "MSDS가 무엇이고 왜 중요한지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["MSDS", "물질안전보건자료"], "must_not": ["약어만 설명"], "golden": false}
|
||||||
|
{"id": "ask_def_011", "type": "ask", "category": "정의", "query": "특별관리물질이 일반 유해물질과 어떻게 다른지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["특별관리물질", "관리"], "must_not": ["목록만 나열"], "golden": false}
|
||||||
|
{"id": "ask_def_012", "type": "ask", "category": "정의", "query": "발암성 물질을 다루는 작업장에서 '노출기준'이 의미하는 바를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["노출기준", "발암성"], "must_not": ["수치만 제시"], "golden": false}
|
||||||
|
{"id": "ask_def_013", "type": "ask", "category": "정의", "query": "중대산업재해가 정확히 어떤 경우를 말하는지 내 자료 기준으로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["중대산업재해", "사망", "부상"], "must_not": ["법조문 나열만"], "golden": false}
|
||||||
|
{"id": "ask_def_014", "type": "ask", "category": "정의", "query": "중대시민재해는 중대산업재해와 어떻게 구분되는지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["중대시민재해", "구분"], "must_not": ["한쪽만 설명"], "golden": false}
|
||||||
|
{"id": "ask_def_015", "type": "ask", "category": "정의", "query": "경영책임자라는 용어가 중대재해처벌법에서 어떤 의미인지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["경영책임자", "중대재해처벌법"], "must_not": ["직위명만 나열"], "golden": false}
|
||||||
|
{"id": "ask_def_016", "type": "ask", "category": "정의", "query": "산업재해율을 어떻게 이해해야 하는지 실무 관점에서 정리해줘", "expected_behavior": "answered", "critical_keywords": ["산업재해율", "지표"], "must_not": ["계산식만"], "golden": false}
|
||||||
|
{"id": "ask_def_017", "type": "ask", "category": "정의", "query": "밀폐공간이란 무엇인지 현장 작업자가 이해할 수 있게 설명해줘", "expected_behavior": "answered", "critical_keywords": ["밀폐공간", "산소결핍"], "must_not": ["정의문만 인용"], "golden": false}
|
||||||
|
{"id": "ask_def_018", "type": "ask", "category": "정의", "query": "고소작업이 왜 위험 작업으로 분류되는지 의미를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["고소작업", "추락"], "must_not": ["높이 수치만"], "golden": false}
|
||||||
|
{"id": "ask_def_019", "type": "ask", "category": "정의", "query": "중량물 취급 작업의 기준이 무엇인지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["중량물", "취급"], "must_not": ["무게만 제시"], "golden": false}
|
||||||
|
{"id": "ask_def_020", "type": "ask", "category": "정의", "query": "화기작업이라는 용어가 현장에서 어떻게 쓰이는지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["화기작업", "용접"], "must_not": ["종류 나열만"], "golden": false}
|
||||||
|
{"id": "ask_def_021", "type": "ask", "category": "정의", "query": "안전모의 용도와 선택 기준을 관리 관점에서 설명해줘", "expected_behavior": "answered", "critical_keywords": ["안전모", "선택"], "must_not": ["브랜드만"], "golden": false}
|
||||||
|
{"id": "ask_def_022", "type": "ask", "category": "정의", "query": "안전대가 언제 필요한 보호구인지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["안전대", "추락방지"], "must_not": ["종류 나열만"], "golden": false}
|
||||||
|
{"id": "ask_def_023", "type": "ask", "category": "정의", "query": "안전화가 일반 작업화와 뭐가 다른지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["안전화", "보호"], "must_not": ["소재만 설명"], "golden": false}
|
||||||
|
{"id": "ask_def_024", "type": "ask", "category": "정의", "query": "방진마스크와 방독마스크의 용도 구분을 내 자료 기준으로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["방진마스크", "방독마스크", "구분"], "must_not": ["제품명만"], "golden": false}
|
||||||
|
{"id": "ask_def_025", "type": "ask", "category": "정의", "query": "관리감독자 정기교육이 무엇을 의미하는지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["관리감독자", "정기교육"], "must_not": ["교육시간만"], "golden": false}
|
||||||
|
{"id": "ask_def_026", "type": "ask", "category": "정의", "query": "특별안전보건교육의 취지를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["특별교육", "취지"], "must_not": ["대상만 나열"], "golden": false}
|
||||||
|
{"id": "ask_def_027", "type": "ask", "category": "정의", "query": "정기 안전보건교육이 법정교육인 이유를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["정기교육", "법정"], "must_not": ["주기만 설명"], "golden": false}
|
||||||
|
{"id": "ask_def_028", "type": "ask", "category": "정의", "query": "채용 시 교육과 작업내용 변경 시 교육은 각각 무엇을 의미해?", "expected_behavior": "answered", "critical_keywords": ["채용 시 교육", "작업내용 변경"], "must_not": ["한쪽만 설명"], "golden": false}
|
||||||
|
{"id": "ask_def_029", "type": "ask", "category": "정의", "query": "안전보건관리책임자의 역할이 어떤 것인지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["안전보건관리책임자", "역할"], "must_not": ["직무 나열만"], "golden": false}
|
||||||
|
{"id": "ask_def_030", "type": "ask", "category": "정의", "query": "관리감독자라는 직책이 현장에서 뭘 책임지는지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["관리감독자", "책임"], "must_not": ["법조문 인용만"], "golden": false}
|
||||||
|
{"id": "ask_def_031", "type": "ask", "category": "정의", "query": "산업안전보건위원회가 어떤 기능을 하는 조직인지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["산업안전보건위원회", "협의"], "must_not": ["구성원만 나열"], "golden": false}
|
||||||
|
{"id": "ask_def_032", "type": "ask", "category": "정의", "query": "안전보건 협의체가 왜 필요한 제도인지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["협의체", "필요성"], "must_not": ["설치만 설명"], "golden": false}
|
||||||
|
{"id": "ask_def_033", "type": "ask", "category": "정의", "query": "유해인자가 무엇을 의미하는지 현장 관점에서 설명해줘", "expected_behavior": "answered", "critical_keywords": ["유해인자", "노출"], "must_not": ["목록만"], "golden": false}
|
||||||
|
{"id": "ask_def_034", "type": "ask", "category": "정의", "query": "작업환경측정이 어떤 활동을 가리키는지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["작업환경측정", "노출"], "must_not": ["측정 장비만"], "golden": false}
|
||||||
|
{"id": "ask_def_035", "type": "ask", "category": "정의", "query": "특수건강진단과 일반건강진단의 의미 차이를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["특수건강진단", "일반건강진단"], "must_not": ["주기만"], "golden": false}
|
||||||
|
{"id": "ask_def_036", "type": "ask", "category": "정의", "query": "노출기준(TWA)이 무엇을 뜻하는지 실무 관점에서 알려줘", "expected_behavior": "answered", "critical_keywords": ["노출기준", "TWA"], "must_not": ["수치만"], "golden": false}
|
||||||
|
{"id": "ask_def_037", "type": "ask", "category": "정의", "query": "도급과 위탁이 법적으로 어떻게 구분되는 개념인지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["도급", "위탁", "구분"], "must_not": ["계약서만"], "golden": false}
|
||||||
|
{"id": "ask_def_038", "type": "ask", "category": "정의", "query": "원청과 하청이 안전보건 맥락에서 어떻게 정의되는지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["원청", "하청", "책임"], "must_not": ["사업구조만"], "golden": false}
|
||||||
|
{"id": "ask_def_039", "type": "ask", "category": "정의", "query": "공동 수행 작업이 무엇을 의미하는지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["공동 수행", "작업"], "must_not": ["분담 방식만"], "golden": false}
|
||||||
|
{"id": "ask_def_040", "type": "ask", "category": "정의", "query": "일괄 도급과 부분 도급 개념을 자료 기준으로 구분해줘", "expected_behavior": "answered", "critical_keywords": ["일괄 도급", "부분 도급"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_def_041", "type": "ask", "category": "정의", "query": "응급조치에 해당하는 행동이 어떤 것들인지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["응급조치", "초기대응"], "must_not": ["연락처만"], "golden": false}
|
||||||
|
{"id": "ask_def_042", "type": "ask", "category": "정의", "query": "비상대피 계획이 왜 필요한지 의미를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["비상대피", "계획"], "must_not": ["도면만"], "golden": false}
|
||||||
|
{"id": "ask_def_043", "type": "ask", "category": "정의", "query": "재해 예방이라는 표현이 어떤 범주의 활동을 포함하는지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["재해 예방", "활동"], "must_not": ["추상적 문구만"], "golden": false}
|
||||||
|
{"id": "ask_def_044", "type": "ask", "category": "정의", "query": "산업재해 신고 의무의 취지를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["산업재해 신고", "의무"], "must_not": ["절차만"], "golden": false}
|
||||||
|
{"id": "ask_def_045", "type": "ask", "category": "정의", "query": "작업중지권이 근로자에게 어떤 권리를 부여하는지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["작업중지권", "근로자"], "must_not": ["조문만"], "golden": false}
|
||||||
|
{"id": "ask_def_046", "type": "ask", "category": "정의", "query": "순회점검의 목적이 무엇인지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["순회점검", "목적"], "must_not": ["주기만"], "golden": false}
|
||||||
|
{"id": "ask_def_047", "type": "ask", "category": "정의", "query": "안전문화라는 용어가 실제 현장에서 무엇을 뜻하는지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["안전문화", "현장"], "must_not": ["추상론만"], "golden": false}
|
||||||
|
{"id": "ask_def_048", "type": "ask", "category": "정의", "query": "작업환경 개선이라는 표현이 포함하는 활동 범위를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["작업환경 개선", "활동"], "must_not": ["예산만"], "golden": false}
|
||||||
|
{"id": "ask_def_049", "type": "ask", "category": "정의", "query": "위험기계·기구 등록 관리가 무엇을 의미하는지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["위험기계", "등록"], "must_not": ["장비명만"], "golden": false}
|
||||||
|
{"id": "ask_def_050", "type": "ask", "category": "정의", "query": "안전검사와 자율검사는 각각 어떤 제도인지 정의해줘", "expected_behavior": "answered", "critical_keywords": ["안전검사", "자율검사"], "must_not": ["주기만"], "golden": false}
|
||||||
|
{"id": "ask_proc_009", "type": "ask", "category": "절차", "query": "위험성평가를 재검토해야 할 시점과 그 절차를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["재검토", "변경", "시점"], "must_not": ["주기만"], "golden": false}
|
||||||
|
{"id": "ask_proc_010", "type": "ask", "category": "절차", "query": "공정 변경이 있을 때 안전 변경관리 절차를 단계별로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["변경관리", "절차", "검토"], "must_not": ["단계 누락"], "golden": false}
|
||||||
|
{"id": "ask_proc_011", "type": "ask", "category": "절차", "query": "위험성평가를 언제 실시해야 하는지 시점별로 알려줘", "expected_behavior": "answered", "critical_keywords": ["위험성평가", "시점"], "must_not": ["현장 적용 없음"], "golden": false}
|
||||||
|
{"id": "ask_proc_012", "type": "ask", "category": "절차", "query": "평가 결과 문서화 절차를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["문서화", "기록"], "must_not": ["양식만"], "golden": false}
|
||||||
|
{"id": "ask_proc_013", "type": "ask", "category": "절차", "query": "화기작업 허가를 받을 때 어떤 절차를 따라야 해?", "expected_behavior": "answered", "critical_keywords": ["화기작업", "허가", "소화"], "must_not": ["신청서만"], "golden": false}
|
||||||
|
{"id": "ask_proc_014", "type": "ask", "category": "절차", "query": "밀폐공간 작업허가 절차를 현장 관점으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["밀폐공간", "가스측정", "감시인"], "must_not": ["서류만"], "golden": false}
|
||||||
|
{"id": "ask_proc_015", "type": "ask", "category": "절차", "query": "전기작업 허가에서 차단과 잠금 절차를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["전기작업", "차단", "잠금"], "must_not": ["개념만"], "golden": false}
|
||||||
|
{"id": "ask_proc_016", "type": "ask", "category": "절차", "query": "중량물 취급 작업 허가 절차를 단계별로 알려줘", "expected_behavior": "answered", "critical_keywords": ["중량물", "허가", "확인"], "must_not": ["무게만"], "golden": false}
|
||||||
|
{"id": "ask_proc_017", "type": "ask", "category": "절차", "query": "신규 입사자 안전교육을 언제 어떻게 실시해야 하는지 절차 정리해줘", "expected_behavior": "answered", "critical_keywords": ["신규 입사자", "교육", "실시"], "must_not": ["주제만"], "golden": false}
|
||||||
|
{"id": "ask_proc_018", "type": "ask", "category": "절차", "query": "보직이 바뀐 근로자에게 실시할 교육 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["보직변경", "교육", "절차"], "must_not": ["시간만"], "golden": false}
|
||||||
|
{"id": "ask_proc_019", "type": "ask", "category": "절차", "query": "특별교육 실시 절차를 준비부터 기록까지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["특별교육", "실시", "기록"], "must_not": ["대상만"], "golden": false}
|
||||||
|
{"id": "ask_proc_020", "type": "ask", "category": "절차", "query": "정기교육을 운영하는 절차를 월간 단위로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["정기교육", "운영", "월간"], "must_not": ["주기만"], "golden": false}
|
||||||
|
{"id": "ask_proc_021", "type": "ask", "category": "절차", "query": "일일 안전점검 절차를 현장 흐름으로 알려줘", "expected_behavior": "answered", "critical_keywords": ["일일점검", "현장", "흐름"], "must_not": ["항목만"], "golden": false}
|
||||||
|
{"id": "ask_proc_022", "type": "ask", "category": "절차", "query": "주간 안전점검 계획 수립부터 보고까지 절차를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["주간점검", "계획", "보고"], "must_not": ["보고서만"], "golden": false}
|
||||||
|
{"id": "ask_proc_023", "type": "ask", "category": "절차", "query": "정밀점검이 필요한 경우 절차를 단계별로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["정밀점검", "단계"], "must_not": ["정의만"], "golden": false}
|
||||||
|
{"id": "ask_proc_024", "type": "ask", "category": "절차", "query": "순회점검을 효과적으로 하는 절차를 관리자 관점에서 알려줘", "expected_behavior": "answered", "critical_keywords": ["순회점검", "관리자"], "must_not": ["체크 없음"], "golden": false}
|
||||||
|
{"id": "ask_proc_025", "type": "ask", "category": "절차", "query": "산업재해 발생 시 신고 절차를 시간 흐름대로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["산업재해", "신고", "시간"], "must_not": ["연락처만"], "golden": false}
|
||||||
|
{"id": "ask_proc_026", "type": "ask", "category": "절차", "query": "사고 조사를 수행하는 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["사고조사", "조사", "분석"], "must_not": ["조사자만"], "golden": false}
|
||||||
|
{"id": "ask_proc_027", "type": "ask", "category": "절차", "query": "근본 원인 분석 절차를 체계적으로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["근본 원인", "분석", "체계"], "must_not": ["결과만"], "golden": false}
|
||||||
|
{"id": "ask_proc_028", "type": "ask", "category": "절차", "query": "재발방지대책 수립 후 이행 확인 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["재발방지", "이행", "확인"], "must_not": ["수립만"], "golden": false}
|
||||||
|
{"id": "ask_proc_029", "type": "ask", "category": "절차", "query": "협력업체와 계약 전에 해야 할 안전 협의 절차를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["계약 전", "협력업체", "협의"], "must_not": ["계약서만"], "golden": false}
|
||||||
|
{"id": "ask_proc_030", "type": "ask", "category": "절차", "query": "협력업체 작업 시작 전 공동 점검 절차를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["작업 시작", "공동 점검"], "must_not": ["일방 점검만"], "golden": false}
|
||||||
|
{"id": "ask_proc_031", "type": "ask", "category": "절차", "query": "원청이 하청 작업을 함께 점검할 때 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["원청", "하청", "점검"], "must_not": ["책임 일방"], "golden": false}
|
||||||
|
{"id": "ask_proc_032", "type": "ask", "category": "절차", "query": "도급 업무 종료 후 안전 확인 절차를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["도급", "종료", "확인"], "must_not": ["계약 해지만"], "golden": false}
|
||||||
|
{"id": "ask_proc_033", "type": "ask", "category": "절차", "query": "화재 발생 시 초기 대응 절차를 현장 흐름으로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["화재", "초기대응", "신고"], "must_not": ["소화기만"], "golden": false}
|
||||||
|
{"id": "ask_proc_034", "type": "ask", "category": "절차", "query": "폭발 사고 발생 시 대응 절차를 단계별로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["폭발", "대응", "대피"], "must_not": ["설명 추상"], "golden": false}
|
||||||
|
{"id": "ask_proc_035", "type": "ask", "category": "절차", "query": "부상자 발생 시 응급조치 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["부상자", "응급조치", "신고"], "must_not": ["119만"], "golden": false}
|
||||||
|
{"id": "ask_proc_036", "type": "ask", "category": "절차", "query": "중대재해 발생 시 초동 대응 절차를 시간 순으로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["중대재해", "초동", "대응"], "must_not": ["법 신고만"], "golden": false}
|
||||||
|
{"id": "ask_proc_037", "type": "ask", "category": "절차", "query": "개인보호구 지급 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["보호구", "지급"], "must_not": ["구매만"], "golden": false}
|
||||||
|
{"id": "ask_proc_038", "type": "ask", "category": "절차", "query": "보호구 착용 점검 절차를 관리자 관점에서 정리해줘", "expected_behavior": "answered", "critical_keywords": ["보호구", "착용", "점검"], "must_not": ["개인 책임만"], "golden": false}
|
||||||
|
{"id": "ask_proc_039", "type": "ask", "category": "절차", "query": "보호구 교체 주기와 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["보호구", "교체", "주기"], "must_not": ["외부 기준만"], "golden": false}
|
||||||
|
{"id": "ask_proc_040", "type": "ask", "category": "절차", "query": "손상된 보호구 폐기 절차를 자료 기준으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["보호구", "폐기", "손상"], "must_not": ["버리기만"], "golden": false}
|
||||||
|
{"id": "ask_proc_041", "type": "ask", "category": "절차", "query": "유해화학물질 저장 절차를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["저장", "화학물질", "분리"], "must_not": ["창고만"], "golden": false}
|
||||||
|
{"id": "ask_proc_042", "type": "ask", "category": "절차", "query": "위험물 운반 절차에서 필수 확인 사항을 알려줘", "expected_behavior": "answered", "critical_keywords": ["운반", "위험물", "확인"], "must_not": ["차량만"], "golden": false}
|
||||||
|
{"id": "ask_proc_043", "type": "ask", "category": "절차", "query": "폐유해물 폐기 절차를 단계별로 설명해줘", "expected_behavior": "answered", "critical_keywords": ["폐기", "유해물", "처리"], "must_not": ["위탁만"], "golden": false}
|
||||||
|
{"id": "ask_proc_044", "type": "ask", "category": "절차", "query": "MSDS 게시 및 교육 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["MSDS", "게시", "교육"], "must_not": ["출력만"], "golden": false}
|
||||||
|
{"id": "ask_proc_045", "type": "ask", "category": "절차", "query": "신규 기계 시운전 전 안전 확인 절차를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["시운전", "기계", "확인"], "must_not": ["전원만"], "golden": false}
|
||||||
|
{"id": "ask_proc_046", "type": "ask", "category": "절차", "query": "설비 정비 작업 시 안전 절차를 단계별로 알려줘", "expected_behavior": "answered", "critical_keywords": ["설비 정비", "안전", "절차"], "must_not": ["정비 내용만"], "golden": false}
|
||||||
|
{"id": "ask_proc_047", "type": "ask", "category": "절차", "query": "설비 해체 작업의 안전 절차를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["해체", "안전", "절차"], "must_not": ["도구만"], "golden": false}
|
||||||
|
{"id": "ask_proc_048", "type": "ask", "category": "절차", "query": "공정 변경 시 안전 검토 절차를 내 자료 기준으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["공정 변경", "검토"], "must_not": ["변경점만"], "golden": false}
|
||||||
|
{"id": "ask_proc_049", "type": "ask", "category": "절차", "query": "설비 이전 작업에서 필수 안전 절차를 알려줘", "expected_behavior": "answered", "critical_keywords": ["이전", "설비", "안전"], "must_not": ["운반만"], "golden": false}
|
||||||
|
{"id": "ask_proc_050", "type": "ask", "category": "절차", "query": "안전검사 신청부터 결과 확인까지 절차를 설명해줘", "expected_behavior": "answered", "critical_keywords": ["안전검사", "신청", "결과"], "must_not": ["기관만"], "golden": false}
|
||||||
|
{"id": "ask_apply_009", "type": "ask", "category": "적용", "query": "철골 작업 시작 전 브리핑용으로 안전 포인트를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["철골", "추락", "안전대"], "must_not": ["장비 나열만"], "golden": false}
|
||||||
|
{"id": "ask_apply_010", "type": "ask", "category": "적용", "query": "용단 작업 전 TBM에서 강조할 내용을 알려줘", "expected_behavior": "answered", "critical_keywords": ["용단", "화재", "가연물"], "must_not": ["추상 원칙만"], "golden": false}
|
||||||
|
{"id": "ask_apply_011", "type": "ask", "category": "적용", "query": "그라인딩 작업 시 안전 브리핑 내용을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["그라인딩", "비산", "보안경"], "must_not": ["공구만"], "golden": false}
|
||||||
|
{"id": "ask_apply_012", "type": "ask", "category": "적용", "query": "아크용접 시작 전 점검 포인트를 브리핑용으로 알려줘", "expected_behavior": "answered", "critical_keywords": ["아크용접", "감전", "연기"], "must_not": ["용접봉만"], "golden": false}
|
||||||
|
{"id": "ask_apply_013", "type": "ask", "category": "적용", "query": "크레인 사용 전 체크리스트를 현장 언어로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["크레인", "점검", "하중"], "must_not": ["매뉴얼만"], "golden": false}
|
||||||
|
{"id": "ask_apply_014", "type": "ask", "category": "적용", "query": "지게차 운행 전 확인해야 할 사항을 체크리스트로 만들어줘", "expected_behavior": "answered", "critical_keywords": ["지게차", "타이어", "적재"], "must_not": ["이론만"], "golden": false}
|
||||||
|
{"id": "ask_apply_015", "type": "ask", "category": "적용", "query": "고소작업대 사용 전 체크 포인트를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["고소작업대", "아웃트리거", "안전대"], "must_not": ["기종만"], "golden": false}
|
||||||
|
{"id": "ask_apply_016", "type": "ask", "category": "적용", "query": "사다리 사용 시 체크리스트를 현장 반장용으로 정리해줘", "expected_behavior": "answered", "critical_keywords": ["사다리", "미끄럼", "지지"], "must_not": ["이론만"], "golden": false}
|
||||||
|
{"id": "ask_apply_017", "type": "ask", "category": "적용", "query": "야간 작업 관리자에게 전달할 안전 지침을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["야간", "조명", "확인"], "must_not": ["일반론만"], "golden": false}
|
||||||
|
{"id": "ask_apply_018", "type": "ask", "category": "적용", "query": "혹서기 옥외 작업에서 관리자가 조치해야 할 사항을 알려줘", "expected_behavior": "answered", "critical_keywords": ["혹서기", "열사병", "수분"], "must_not": ["온도만"], "golden": false}
|
||||||
|
{"id": "ask_apply_019", "type": "ask", "category": "적용", "query": "혹한기 옥외 작업자 안전을 위해 현장에서 지켜야 할 사항을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["혹한기", "동상", "보온"], "must_not": ["날씨만"], "golden": false}
|
||||||
|
{"id": "ask_apply_020", "type": "ask", "category": "적용", "query": "우천 시 작업 지속 여부 판단 기준을 현장 언어로 알려줘", "expected_behavior": "answered", "critical_keywords": ["우천", "판단", "미끄럼"], "must_not": ["강우량만"], "golden": false}
|
||||||
|
{"id": "ask_apply_021", "type": "ask", "category": "적용", "query": "신입 작업자 입문 교육에서 안전 메시지를 어떻게 전달할지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["신입", "입문", "안전"], "must_not": ["PPT만"], "golden": false}
|
||||||
|
{"id": "ask_apply_022", "type": "ask", "category": "적용", "query": "작업 시작 전 5분 점검을 어떻게 구성하면 좋을지 알려줘", "expected_behavior": "answered", "critical_keywords": ["작업 전", "점검", "5분"], "must_not": ["구성 없음"], "golden": false}
|
||||||
|
{"id": "ask_apply_023", "type": "ask", "category": "적용", "query": "공구 사용법 교육을 현장 시연 형태로 짜줘", "expected_behavior": "answered", "critical_keywords": ["공구", "사용법", "시연"], "must_not": ["이론만"], "golden": false}
|
||||||
|
{"id": "ask_apply_024", "type": "ask", "category": "적용", "query": "위험 인지 훈련을 현장 작업자에게 어떻게 진행하면 좋은지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["위험 인지", "훈련", "현장"], "must_not": ["퀴즈만"], "golden": false}
|
||||||
|
{"id": "ask_apply_025", "type": "ask", "category": "적용", "query": "가스 누출이 감지됐을 때 즉시 해야 할 조치를 우선순위로 알려줘", "expected_behavior": "answered", "critical_keywords": ["가스 누출", "즉시", "대피"], "must_not": ["연락만"], "golden": false}
|
||||||
|
{"id": "ask_apply_026", "type": "ask", "category": "적용", "query": "화재 초기 징후를 발견했을 때 현장 대응 순서를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["화재", "초기", "소화"], "must_not": ["대피만"], "golden": false}
|
||||||
|
{"id": "ask_apply_027", "type": "ask", "category": "적용", "query": "근로자 부상 발생 시 현장 관리자가 즉시 해야 할 행동을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["부상", "즉시", "조치"], "must_not": ["병원만"], "golden": false}
|
||||||
|
{"id": "ask_apply_028", "type": "ask", "category": "적용", "query": "기계 이상음이 들릴 때 작업자가 취해야 할 행동 순서를 알려줘", "expected_behavior": "answered", "critical_keywords": ["기계 이상", "중지", "보고"], "must_not": ["계속 운전"], "golden": false}
|
||||||
|
{"id": "ask_apply_029", "type": "ask", "category": "적용", "query": "협력업체 입문 교육에서 전달할 핵심 메시지를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["협력업체", "입문", "핵심"], "must_not": ["규정만"], "golden": false}
|
||||||
|
{"id": "ask_apply_030", "type": "ask", "category": "적용", "query": "원청과 하청이 함께 작업할 때 역할을 나눠서 브리핑해줘", "expected_behavior": "answered", "critical_keywords": ["원청", "하청", "공동"], "must_not": ["일방적"], "golden": false}
|
||||||
|
{"id": "ask_apply_031", "type": "ask", "category": "적용", "query": "협력업체 차량이 현장에 반입될 때 확인 사항을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["차량", "반입", "확인"], "must_not": ["출입만"], "golden": false}
|
||||||
|
{"id": "ask_apply_032", "type": "ask", "category": "적용", "query": "협력업체 작업 완료 후 현장 정리 점검 리스트를 만들어줘", "expected_behavior": "answered", "critical_keywords": ["작업 완료", "정리", "점검"], "must_not": ["일방적"], "golden": false}
|
||||||
|
{"id": "ask_apply_033", "type": "ask", "category": "적용", "query": "복수 위험이 동시에 있을 때 작업 우선순위 판단 기준을 알려줘", "expected_behavior": "answered", "critical_keywords": ["복수 위험", "우선순위", "판단"], "must_not": ["모호"], "golden": false}
|
||||||
|
{"id": "ask_apply_034", "type": "ask", "category": "적용", "query": "긴급한 생산 지시와 안전 조치가 충돌할 때 판단 기준을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["생산", "안전", "충돌"], "must_not": ["생산 우선만"], "golden": false}
|
||||||
|
{"id": "ask_apply_035", "type": "ask", "category": "적용", "query": "현장 순찰 중 여러 개선사항이 발견됐을 때 우선순위 판단법을 알려줘", "expected_behavior": "answered", "critical_keywords": ["순찰", "개선", "우선순위"], "must_not": ["순번만"], "golden": false}
|
||||||
|
{"id": "ask_apply_036", "type": "ask", "category": "적용", "query": "안전 지시 사항 중 즉시 조치와 계획 조치를 구분해서 정리해줘", "expected_behavior": "answered", "critical_keywords": ["즉시 조치", "계획 조치", "구분"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_apply_037", "type": "ask", "category": "적용", "query": "열사병이 의심될 때 현장에서 즉시 취해야 할 행동을 알려줘", "expected_behavior": "answered", "critical_keywords": ["열사병", "즉시", "응급"], "must_not": ["수분만"], "golden": false}
|
||||||
|
{"id": "ask_apply_038", "type": "ask", "category": "적용", "query": "동상 의심 증상이 있는 작업자 조치법을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["동상", "조치", "보온"], "must_not": ["병원만"], "golden": false}
|
||||||
|
{"id": "ask_apply_039", "type": "ask", "category": "적용", "query": "장마철 감전 예방을 위한 현장 점검 사항을 알려줘", "expected_behavior": "answered", "critical_keywords": ["장마", "감전", "누전"], "must_not": ["우비만"], "golden": false}
|
||||||
|
{"id": "ask_apply_040", "type": "ask", "category": "적용", "query": "미세먼지가 심한 날 옥외 작업 관리 포인트를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["미세먼지", "마스크", "관리"], "must_not": ["지표만"], "golden": false}
|
||||||
|
{"id": "ask_apply_041", "type": "ask", "category": "적용", "query": "야간 단독 작업 시 확인 사항을 관리자 관점에서 알려줘", "expected_behavior": "answered", "critical_keywords": ["야간", "단독", "확인"], "must_not": ["제한만"], "golden": false}
|
||||||
|
{"id": "ask_apply_042", "type": "ask", "category": "적용", "query": "고압 설비 점검 시 현장 작업자가 지켜야 할 규칙을 정리해줘", "expected_behavior": "answered", "critical_keywords": ["고압", "점검", "차단"], "must_not": ["전압만"], "golden": false}
|
||||||
|
{"id": "ask_apply_043", "type": "ask", "category": "적용", "query": "저온 환경 작업에서 관리자가 조치할 수 있는 방안을 알려줘", "expected_behavior": "answered", "critical_keywords": ["저온", "관리", "보온"], "must_not": ["온도만"], "golden": false}
|
||||||
|
{"id": "ask_apply_044", "type": "ask", "category": "적용", "query": "단독 작업자 안전 관리 방안을 현장 관점에서 정리해줘", "expected_behavior": "answered", "critical_keywords": ["단독", "관리", "연락"], "must_not": ["제한만"], "golden": false}
|
||||||
|
{"id": "ask_apply_045", "type": "ask", "category": "적용", "query": "신설 공정 가동 전 안전 확인 체크를 관리자용으로 알려줘", "expected_behavior": "answered", "critical_keywords": ["신설", "가동", "확인"], "must_not": ["도면만"], "golden": false}
|
||||||
|
{"id": "ask_apply_046", "type": "ask", "category": "적용", "query": "공정 이설 후 재가동 시 점검 포인트를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["이설", "재가동", "점검"], "must_not": ["위치만"], "golden": false}
|
||||||
|
{"id": "ask_apply_047", "type": "ask", "category": "적용", "query": "공정 개조 후 작업자에게 브리핑할 내용을 알려줘", "expected_behavior": "answered", "critical_keywords": ["개조", "브리핑", "변경점"], "must_not": ["변경 목록만"], "golden": false}
|
||||||
|
{"id": "ask_apply_048", "type": "ask", "category": "적용", "query": "설비 해체 작업에 투입되는 작업자에게 전달할 안전 메시지를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["해체", "안전", "메시지"], "must_not": ["공구만"], "golden": false}
|
||||||
|
{"id": "ask_apply_049", "type": "ask", "category": "적용", "query": "정비 후 재가동 전 안전 확인 절차를 반장 관점에서 정리해줘", "expected_behavior": "answered", "critical_keywords": ["정비", "재가동", "확인"], "must_not": ["정비 내용만"], "golden": false}
|
||||||
|
{"id": "ask_apply_050", "type": "ask", "category": "적용", "query": "시운전 단계에서 안전 모니터링 포인트를 알려줘", "expected_behavior": "answered", "critical_keywords": ["시운전", "모니터링", "이상"], "must_not": ["출력값만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_009", "type": "ask", "category": "비교", "query": "산업재해와 산업사고는 어떻게 구분되는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["재해", "사고", "구분"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_010", "type": "ask", "category": "비교", "query": "유해와 위험이라는 용어는 어떤 차이가 있는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["유해", "위험", "차이"], "must_not": ["유사어 처리"], "golden": false}
|
||||||
|
{"id": "ask_cmp_011", "type": "ask", "category": "비교", "query": "법령과 기준은 어떤 관점에서 다른지 정리해줘", "expected_behavior": "answered", "critical_keywords": ["법령", "기준", "차이"], "must_not": ["정의 혼동"], "golden": false}
|
||||||
|
{"id": "ask_cmp_012", "type": "ask", "category": "비교", "query": "안전교육과 안전훈련은 각각 어떤 목적을 갖는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["교육", "훈련", "목적"], "must_not": ["동의어"], "golden": false}
|
||||||
|
{"id": "ask_cmp_013", "type": "ask", "category": "비교", "query": "안전관리자와 보건관리자의 직무 차이를 알려줘", "expected_behavior": "answered", "critical_keywords": ["안전관리자", "보건관리자", "직무"], "must_not": ["직위만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_014", "type": "ask", "category": "비교", "query": "산업보건의와 일반 의료인이 현장에서 어떻게 다른지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["산업보건의", "의료인", "차이"], "must_not": ["자격만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_015", "type": "ask", "category": "비교", "query": "협력업체와 도급업체 용어는 어떻게 다른지 자료 기준으로 비교해줘", "expected_behavior": "answered", "critical_keywords": ["협력업체", "도급업체", "비교"], "must_not": ["동의어"], "golden": false}
|
||||||
|
{"id": "ask_cmp_016", "type": "ask", "category": "비교", "query": "원청과 하청 사이의 안전 책임 구분을 비교해줘", "expected_behavior": "answered", "critical_keywords": ["원청", "하청", "책임"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_017", "type": "ask", "category": "비교", "query": "즉시 조치와 계획 조치의 판단 기준을 비교해줘", "expected_behavior": "answered", "critical_keywords": ["즉시", "계획", "기준"], "must_not": ["용어만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_018", "type": "ask", "category": "비교", "query": "임시 조치와 영구 조치는 각각 언제 쓰는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["임시", "영구", "시점"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_019", "type": "ask", "category": "비교", "query": "예방과 대응은 안전 관리에서 어떻게 구분되는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["예방", "대응", "구분"], "must_not": ["혼용"], "golden": false}
|
||||||
|
{"id": "ask_cmp_020", "type": "ask", "category": "비교", "query": "경고와 작업중지 명령은 어떤 차이가 있는지 알려줘", "expected_behavior": "answered", "critical_keywords": ["경고", "작업중지", "차이"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_021", "type": "ask", "category": "비교", "query": "중대재해처벌법과 산업안전보건법은 어떤 점에서 다른지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["중대재해처벌법", "산안법", "차이"], "must_not": ["동일시"], "golden": false}
|
||||||
|
{"id": "ask_cmp_022", "type": "ask", "category": "비교", "query": "공단 점검과 자체 점검은 각각 어떤 역할을 하는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["공단", "자체 점검", "역할"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_023", "type": "ask", "category": "비교", "query": "외부 감사와 내부 감사의 차이를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["외부 감사", "내부 감사", "차이"], "must_not": ["동일시"], "golden": false}
|
||||||
|
{"id": "ask_cmp_024", "type": "ask", "category": "비교", "query": "법정 교육과 자율 교육의 의미 차이를 알려줘", "expected_behavior": "answered", "critical_keywords": ["법정 교육", "자율 교육"], "must_not": ["주제만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_025", "type": "ask", "category": "비교", "query": "기준서와 지침서는 어떤 용도 차이가 있는지 설명해줘", "expected_behavior": "answered", "critical_keywords": ["기준서", "지침서", "용도"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_026", "type": "ask", "category": "비교", "query": "매뉴얼과 체크리스트는 언제 어떻게 쓰는지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["매뉴얼", "체크리스트", "용도"], "must_not": ["유사어"], "golden": false}
|
||||||
|
{"id": "ask_cmp_027", "type": "ask", "category": "비교", "query": "보고서와 일지 중 어느 쪽을 어떤 상황에 써야 하는지 알려줘", "expected_behavior": "answered", "critical_keywords": ["보고서", "일지", "상황"], "must_not": ["용어만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_028", "type": "ask", "category": "비교", "query": "공문과 내부 문서의 관리 방식 차이를 정리해줘", "expected_behavior": "answered", "critical_keywords": ["공문", "내부 문서", "관리"], "must_not": ["형식만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_029", "type": "ask", "category": "비교", "query": "작업 전 점검과 작업 중 점검의 역할 차이를 비교해줘", "expected_behavior": "answered", "critical_keywords": ["작업 전", "작업 중", "점검"], "must_not": ["시점만"], "golden": false}
|
||||||
|
{"id": "ask_cmp_030", "type": "ask", "category": "비교", "query": "일상 관리와 비상 대응은 어떤 맥락에서 다른지 비교해줘", "expected_behavior": "answered", "critical_keywords": ["일상", "비상", "맥락"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ask_part_009", "type": "ask", "category": "partial_refused", "query": "ILO 기준까지 포함해서 우리 기준과 전부 비교해줘", "expected_behavior": "partial", "critical_keywords": ["국내 기준"], "must_not": ["ILO 내용 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_010", "type": "ask", "category": "partial_refused", "query": "ISO 45001 기준을 우리 자료 기준과 완전히 매핑해줘", "expected_behavior": "partial", "critical_keywords": ["자료 근거"], "must_not": ["ISO 내용 추정"], "golden": false}
|
||||||
|
{"id": "ask_part_011", "type": "ask", "category": "partial_refused", "query": "일본 산업안전법 기준으로 비교까지 해줘", "expected_behavior": "partial", "critical_keywords": ["국내 근거"], "must_not": ["해외법 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_012", "type": "ask", "category": "partial_refused", "query": "EU CE 인증 기준까지 포함해 보호구 요건을 전체 비교해줘", "expected_behavior": "partial", "critical_keywords": ["국내 요건"], "must_not": ["CE 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_013", "type": "ask", "category": "partial_refused", "query": "현장 사진을 본 것처럼 설명해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["사진 판단 가장"], "golden": false}
|
||||||
|
{"id": "ask_part_014", "type": "ask", "category": "partial_refused", "query": "CCTV 영상을 확인한 듯이 상황을 요약해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["영상 판단 가장"], "golden": false}
|
||||||
|
{"id": "ask_part_015", "type": "ask", "category": "partial_refused", "query": "도면을 본 것처럼 설비 배치를 분석해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["도면 판단 가장"], "golden": false}
|
||||||
|
{"id": "ask_part_016", "type": "ask", "category": "partial_refused", "query": "설비 실물을 확인한 것처럼 이상 유무를 판단해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["실물 판단 가장"], "golden": false}
|
||||||
|
{"id": "ask_part_017", "type": "ask", "category": "partial_refused", "query": "2027년 개정될 내용까지 반영해서 알려줘", "expected_behavior": "partial", "critical_keywords": ["현재 자료"], "must_not": ["미래 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_018", "type": "ask", "category": "partial_refused", "query": "차년도 시행 예정인 조항까지 포함해 설명해줘", "expected_behavior": "partial", "critical_keywords": ["현재 기준"], "must_not": ["시행 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_019", "type": "ask", "category": "partial_refused", "query": "최근 판례를 기반으로 해석해줘", "expected_behavior": "partial", "critical_keywords": ["자료 범위"], "must_not": ["판례 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_020", "type": "ask", "category": "partial_refused", "query": "향후 개정 방향을 예측해서 알려줘", "expected_behavior": "partial", "critical_keywords": ["예측 한계"], "must_not": ["추정을 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_021", "type": "ask", "category": "partial_refused", "query": "사고율을 정확한 퍼센트까지 알려줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["수치 조작"], "golden": false}
|
||||||
|
{"id": "ask_part_022", "type": "ask", "category": "partial_refused", "query": "각 위험 항목의 위험도 숫자를 확정해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["수치 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_023", "type": "ask", "category": "partial_refused", "query": "보호구별 구매 가격을 구체 금액까지 알려줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["가격 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_024", "type": "ask", "category": "partial_refused", "query": "정기 교육 시간을 분 단위로 정확히 알려줘", "expected_behavior": "partial", "critical_keywords": ["자료 근거"], "must_not": ["수치 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_025", "type": "ask", "category": "partial_refused", "query": "특정 사고에 대한 법원 판례를 찾아서 알려줘", "expected_behavior": "partial", "critical_keywords": ["자료 범위"], "must_not": ["판례 날조"], "golden": false}
|
||||||
|
{"id": "ask_part_026", "type": "ask", "category": "partial_refused", "query": "이 자료로 소송 승패 여부를 예측해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["법적 예측"], "golden": false}
|
||||||
|
{"id": "ask_part_027", "type": "ask", "category": "partial_refused", "query": "형사 처벌 수위를 구체적으로 알려줘", "expected_behavior": "partial", "critical_keywords": ["근거 범위"], "must_not": ["양형 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_028", "type": "ask", "category": "partial_refused", "query": "과태료 금액을 케이스별로 확정해줘", "expected_behavior": "partial", "critical_keywords": ["자료 근거"], "must_not": ["금액 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_029", "type": "ask", "category": "partial_refused", "query": "타사 사고 사례를 구체적으로 알려줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["타사 정보 날조"], "golden": false}
|
||||||
|
{"id": "ask_part_030", "type": "ask", "category": "partial_refused", "query": "다른 회사 안전 기준을 모두 보여줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["외부 정보 날조"], "golden": false}
|
||||||
|
{"id": "ask_part_031", "type": "ask", "category": "partial_refused", "query": "업계 평균 안전 성과를 숫자로 알려줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["통계 날조"], "golden": false}
|
||||||
|
{"id": "ask_part_032", "type": "ask", "category": "partial_refused", "query": "경쟁사 안전 수준과 우리를 비교해줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["경쟁사 판단"], "golden": false}
|
||||||
|
{"id": "ask_part_033", "type": "ask", "category": "partial_refused", "query": "인사 평가 기준까지 같이 알려줘", "expected_behavior": "partial", "critical_keywords": ["범위 한계"], "must_not": ["범위 이탈"], "golden": false}
|
||||||
|
{"id": "ask_part_034", "type": "ask", "category": "partial_refused", "query": "급여 기준을 안전 맥락과 엮어서 설명해줘", "expected_behavior": "partial", "critical_keywords": ["범위 한계"], "must_not": ["급여 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_035", "type": "ask", "category": "partial_refused", "query": "복리후생 제도까지 같이 안내해줘", "expected_behavior": "partial", "critical_keywords": ["범위 한계"], "must_not": ["복리 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_036", "type": "ask", "category": "partial_refused", "query": "회사 경영 방침을 안전 측면에서 평가해줘", "expected_behavior": "partial", "critical_keywords": ["범위 한계"], "must_not": ["경영 평가"], "golden": false}
|
||||||
|
{"id": "ask_part_037", "type": "ask", "category": "partial_refused", "query": "홍길동 작업자의 교육 이수 기록을 알려줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["개인정보 생성"], "golden": false}
|
||||||
|
{"id": "ask_part_038", "type": "ask", "category": "partial_refused", "query": "특정 직원의 병력을 알려줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["병력 단정"], "golden": false}
|
||||||
|
{"id": "ask_part_039", "type": "ask", "category": "partial_refused", "query": "작년 부상 이력이 있는 직원 명단을 보여줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["명단 생성"], "golden": false}
|
||||||
|
{"id": "ask_part_040", "type": "ask", "category": "partial_refused", "query": "특정 사고의 직원 진술 내용을 그대로 알려줘", "expected_behavior": "refused", "critical_keywords": [], "must_not": ["진술 단정"], "golden": false}
|
||||||
|
{"id": "ana_sum_006", "type": "analyze", "category": "전체요약", "doc_id": 3854, "query": "이 문서의 핵심을 작업자 관점에서 전체 흐름으로 요약해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["작업자", "흐름"], "must_not": ["앞부분만"], "golden": false}
|
||||||
|
{"id": "ana_sum_007", "type": "analyze", "category": "전체요약", "doc_id": 3855, "query": "이 문서 목적과 주요 대상을 간결히 정리해줘", "expected_layers": ["summary"], "critical_points": ["목적", "대상"], "must_not": ["세부 나열만"], "golden": false}
|
||||||
|
{"id": "ana_sum_008", "type": "analyze", "category": "전체요약", "doc_id": 3856, "query": "이 문서 전체를 관리자 관점에서 개요만 뽑아줘", "expected_layers": ["summary", "explanation"], "critical_points": ["개요", "관리자"], "must_not": ["조항만"], "golden": false}
|
||||||
|
{"id": "ana_sum_009", "type": "analyze", "category": "전체요약", "doc_id": 3888, "query": "문서 전반의 핵심 메시지를 우선순위 순으로 요약해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["우선순위"], "must_not": ["무순서"], "golden": false}
|
||||||
|
{"id": "ana_sum_010", "type": "analyze", "category": "전체요약", "doc_id": 3917, "query": "이 문서가 다루는 범위를 3문장 안팎으로 압축해줘", "expected_layers": ["summary"], "critical_points": ["범위", "압축"], "must_not": ["세부"], "golden": false}
|
||||||
|
{"id": "ana_sum_011", "type": "analyze", "category": "전체요약", "doc_id": 3981, "query": "이 문서가 무엇을 위한 문서인지 관리자 관점에서 요약해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["목적"], "must_not": ["조항 나열"], "golden": false}
|
||||||
|
{"id": "ana_sum_012", "type": "analyze", "category": "전체요약", "doc_id": 4041, "query": "이 문서 전체를 처음 읽는 사람에게 설명하듯 정리해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["입문", "개요"], "must_not": ["조문 인용만"], "golden": false}
|
||||||
|
{"id": "ana_sum_013", "type": "analyze", "category": "전체요약", "doc_id": 3853, "query": "이 문서의 중심 주제와 그 이유를 짧게 요약해줘", "expected_layers": ["summary"], "critical_points": ["중심 주제"], "must_not": ["나열"], "golden": false}
|
||||||
|
{"id": "ana_sum_014", "type": "analyze", "category": "전체요약", "doc_id": 3854, "query": "이 문서에서 가장 많이 반복되는 핵심 원칙을 요약해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["반복 원칙"], "must_not": ["단편"], "golden": false}
|
||||||
|
{"id": "ana_sum_015", "type": "analyze", "category": "전체요약", "doc_id": 3855, "query": "문서 전체를 팀장에게 보고하듯 요약해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["보고", "핵심"], "must_not": ["조항만"], "golden": false}
|
||||||
|
{"id": "ana_sum_016", "type": "analyze", "category": "전체요약", "doc_id": 3856, "query": "이 문서에서 꼭 기억해야 할 포인트를 요약해줘", "expected_layers": ["summary"], "critical_points": ["기억 포인트"], "must_not": ["모든 조항"], "golden": false}
|
||||||
|
{"id": "ana_sum_017", "type": "analyze", "category": "전체요약", "doc_id": 3888, "query": "이 문서 요지를 체크리스트 느낌으로 정리해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["요지", "체크"], "must_not": ["서술만"], "golden": false}
|
||||||
|
{"id": "ana_sum_018", "type": "analyze", "category": "전체요약", "doc_id": 3917, "query": "이 문서의 맥락과 배경을 포함해 개요를 정리해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["맥락", "배경"], "must_not": ["조문만"], "golden": false}
|
||||||
|
{"id": "ana_sum_019", "type": "analyze", "category": "전체요약", "doc_id": 3981, "query": "문서 전체를 신입자에게 소개하듯 요약해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["소개"], "must_not": ["전문용어만"], "golden": false}
|
||||||
|
{"id": "ana_sum_020", "type": "analyze", "category": "전체요약", "doc_id": 4041, "query": "이 문서가 전체적으로 어떤 흐름으로 구성돼 있는지 요약해줘", "expected_layers": ["summary"], "critical_points": ["흐름"], "must_not": ["조각 요약"], "golden": false}
|
||||||
|
{"id": "ana_core_006", "type": "analyze", "category": "핵심정리", "doc_id": 3854, "query": "이 문서에서 꼭 챙겨야 할 실무 포인트만 뽑아줘", "expected_layers": ["evidence", "summary"], "critical_points": ["실무 포인트"], "must_not": ["일반론"], "golden": false}
|
||||||
|
{"id": "ana_core_007", "type": "analyze", "category": "핵심정리", "doc_id": 3855, "query": "이 문서에서 자주 놓치는 포인트를 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["놓치는 포인트"], "must_not": ["서론만"], "golden": false}
|
||||||
|
{"id": "ana_core_008", "type": "analyze", "category": "핵심정리", "doc_id": 3856, "query": "이 문서의 필수 요구사항만 추려줘", "expected_layers": ["evidence"], "critical_points": ["필수"], "must_not": ["권고"], "golden": false}
|
||||||
|
{"id": "ana_core_009", "type": "analyze", "category": "핵심정리", "doc_id": 3888, "query": "이 문서의 권고사항과 강제사항을 구분해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["권고", "강제"], "must_not": ["구분 실패"], "golden": false}
|
||||||
|
{"id": "ana_core_010", "type": "analyze", "category": "핵심정리", "doc_id": 3917, "query": "이 문서에서 가장 중요하게 강조되는 부분이 무엇인지 정리해줘", "expected_layers": ["evidence", "summary"], "critical_points": ["강조"], "must_not": ["중요도 혼동"], "golden": false}
|
||||||
|
{"id": "ana_core_011", "type": "analyze", "category": "핵심정리", "doc_id": 3981, "query": "문서에서 실무자에게 직접 영향을 주는 항목을 추려줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["실무 영향"], "must_not": ["배경만"], "golden": false}
|
||||||
|
{"id": "ana_core_012", "type": "analyze", "category": "핵심정리", "doc_id": 4041, "query": "이 문서에서 관리자가 반드시 기억해야 할 조항을 뽑아줘", "expected_layers": ["evidence"], "critical_points": ["관리자 필수"], "must_not": ["일반 조항 혼재"], "golden": false}
|
||||||
|
{"id": "ana_core_013", "type": "analyze", "category": "핵심정리", "doc_id": 3853, "query": "이 문서를 3가지 핵심 주제로 분류해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["주제 3"], "must_not": ["주제 없음"], "golden": false}
|
||||||
|
{"id": "ana_core_014", "type": "analyze", "category": "핵심정리", "doc_id": 3854, "query": "이 문서를 신입 담당자에게 넘길 때 꼭 전달할 요점을 정리해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["인수인계"], "must_not": ["형식만"], "golden": false}
|
||||||
|
{"id": "ana_core_015", "type": "analyze", "category": "핵심정리", "doc_id": 3855, "query": "이 문서 전반에서 반복되는 핵심 메시지를 추출해줘", "expected_layers": ["summary", "explanation"], "critical_points": ["반복 메시지"], "must_not": ["단편"], "golden": false}
|
||||||
|
{"id": "ana_core_016", "type": "analyze", "category": "핵심정리", "doc_id": 3856, "query": "이 문서를 실무 체크리스트로 전환할 핵심 항목을 정리해줘", "expected_layers": ["evidence", "summary"], "critical_points": ["체크리스트화"], "must_not": ["서술만"], "golden": false}
|
||||||
|
{"id": "ana_core_017", "type": "analyze", "category": "핵심정리", "doc_id": 3888, "query": "이 문서의 의무사항을 실무자 관점에서 뽑아줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["의무"], "must_not": ["권고 혼재"], "golden": false}
|
||||||
|
{"id": "ana_core_018", "type": "analyze", "category": "핵심정리", "doc_id": 3917, "query": "이 문서에서 경영진이 확인해야 할 포인트를 추려줘", "expected_layers": ["evidence", "summary"], "critical_points": ["경영진"], "must_not": ["실무 중심만"], "golden": false}
|
||||||
|
{"id": "ana_core_019", "type": "analyze", "category": "핵심정리", "doc_id": 3981, "query": "이 문서를 요약 카드 3장으로 만든다면 어떤 내용을 담을지 알려줘", "expected_layers": ["summary"], "critical_points": ["요약 3"], "must_not": ["한 장만"], "golden": false}
|
||||||
|
{"id": "ana_core_020", "type": "analyze", "category": "핵심정리", "doc_id": 4041, "query": "이 문서에서 근로자 관점의 핵심 권리와 의무를 정리해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["근로자", "권리/의무"], "must_not": ["한쪽만"], "golden": false}
|
||||||
|
{"id": "ana_apply_006", "type": "analyze", "category": "현장적용", "doc_id": 3853, "query": "이 문서를 신규 작업자 입문 교육용으로 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["신규", "교육"], "must_not": ["전문용어만"], "golden": false}
|
||||||
|
{"id": "ana_apply_007", "type": "analyze", "category": "현장적용", "doc_id": 3855, "query": "이 문서를 협력업체에게 설명할 때 어떤 포인트를 강조할지 알려줘", "expected_layers": ["explanation", "summary"], "critical_points": ["협력업체", "강조"], "must_not": ["원청 중심만"], "golden": false}
|
||||||
|
{"id": "ana_apply_008", "type": "analyze", "category": "현장적용", "doc_id": 3856, "query": "이 문서를 현장 관리감독자 관점에서 실행 가능한 포인트로 정리해줘", "expected_layers": ["explanation", "evidence"], "critical_points": ["관리감독자"], "must_not": ["규정만"], "golden": false}
|
||||||
|
{"id": "ana_apply_009", "type": "analyze", "category": "현장적용", "doc_id": 3888, "query": "이 문서를 보호구 담당자 업무 매뉴얼로 전환해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["담당자", "매뉴얼"], "must_not": ["일반론"], "golden": false}
|
||||||
|
{"id": "ana_apply_010", "type": "analyze", "category": "현장적용", "doc_id": 3917, "query": "이 문서를 안전보건 담당 임원 관점에서 실행 사항으로 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["임원"], "must_not": ["실무만"], "golden": false}
|
||||||
|
{"id": "ana_apply_011", "type": "analyze", "category": "현장적용", "doc_id": 3981, "query": "이 문서를 화학물질 담당자에게 체크리스트로 만들어줘", "expected_layers": ["explanation", "evidence"], "critical_points": ["화학물질 담당"], "must_not": ["일반론"], "golden": false}
|
||||||
|
{"id": "ana_apply_012", "type": "analyze", "category": "현장적용", "doc_id": 4041, "query": "이 문서를 인사 담당자 관점에서 실무 적용 포인트로 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["인사 담당"], "must_not": ["규정만"], "golden": false}
|
||||||
|
{"id": "ana_apply_013", "type": "analyze", "category": "현장적용", "doc_id": 3854, "query": "이 문서를 설비 보전 팀이 활용할 체크 항목으로 정리해줘", "expected_layers": ["explanation", "evidence"], "critical_points": ["설비 보전"], "must_not": ["규정만"], "golden": false}
|
||||||
|
{"id": "ana_apply_014", "type": "analyze", "category": "현장적용", "doc_id": 3853, "query": "이 문서를 매월 정기교육 자료로 쓸 수 있게 요점을 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["정기교육", "자료"], "must_not": ["서술만"], "golden": false}
|
||||||
|
{"id": "ana_apply_015", "type": "analyze", "category": "현장적용", "doc_id": 3855, "query": "이 문서를 현장 도급 책임자에게 전달할 메시지로 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["도급 책임자"], "must_not": ["원청 일방"], "golden": false}
|
||||||
|
{"id": "ana_apply_016", "type": "analyze", "category": "현장적용", "doc_id": 3856, "query": "이 문서를 기계 안전 담당자의 실무 가이드로 변환해줘", "expected_layers": ["explanation", "evidence"], "critical_points": ["기계 안전"], "must_not": ["일반론"], "golden": false}
|
||||||
|
{"id": "ana_apply_017", "type": "analyze", "category": "현장적용", "doc_id": 3888, "query": "이 문서를 보호구 지급 담당자의 일일 업무 점검 리스트로 재구성해줘", "expected_layers": ["explanation", "evidence"], "critical_points": ["일일 점검"], "must_not": ["서술만"], "golden": false}
|
||||||
|
{"id": "ana_apply_018", "type": "analyze", "category": "현장적용", "doc_id": 3917, "query": "이 문서를 경영진 보고용 한 장 요약으로 만들어줘", "expected_layers": ["summary", "explanation"], "critical_points": ["경영진 보고"], "must_not": ["실무만"], "golden": false}
|
||||||
|
{"id": "ana_apply_019", "type": "analyze", "category": "현장적용", "doc_id": 3981, "query": "이 문서를 현장에서 바로 활용할 수 있는 작업 지침으로 정리해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["작업 지침"], "must_not": ["규정 나열"], "golden": false}
|
||||||
|
{"id": "ana_apply_020", "type": "analyze", "category": "현장적용", "doc_id": 4041, "query": "이 문서를 근로자 입문 오리엔테이션 자료로 변환해줘", "expected_layers": ["explanation", "summary"], "critical_points": ["오리엔테이션"], "must_not": ["조항 인용만"], "golden": false}
|
||||||
|
{"id": "ana_layer_006", "type": "analyze", "category": "층구조", "doc_id": 3854, "query": "이 문서의 사실, 해석, 사례 유무를 구분해서 정리해줘", "expected_layers": ["evidence", "explanation", "examples"], "critical_points": ["구분"], "must_not": ["혼재"], "golden": false}
|
||||||
|
{"id": "ana_layer_007", "type": "analyze", "category": "층구조", "doc_id": 3855, "query": "이 문서의 근거 조항과 해설을 나눠줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["근거", "해설"], "must_not": ["서술만"], "golden": false}
|
||||||
|
{"id": "ana_layer_008", "type": "analyze", "category": "층구조", "doc_id": 3856, "query": "이 문서를 핵심 요약과 세부 근거로 층 분리해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["층 분리"], "must_not": ["혼재"], "golden": false}
|
||||||
|
{"id": "ana_layer_009", "type": "analyze", "category": "층구조", "doc_id": 3888, "query": "이 문서에서 실무 사례가 있다면 따로 빼서 보여줘", "expected_layers": ["examples", "summary"], "critical_points": ["사례 분리"], "must_not": ["사례 날조"], "golden": false}
|
||||||
|
{"id": "ana_layer_010", "type": "analyze", "category": "층구조", "doc_id": 3917, "query": "이 문서의 원칙과 세부 규정을 계층적으로 정리해줘", "expected_layers": ["summary", "evidence"], "critical_points": ["원칙", "세부"], "must_not": ["한 레벨만"], "golden": false}
|
||||||
|
{"id": "ana_layer_011", "type": "analyze", "category": "층구조", "doc_id": 3981, "query": "이 문서를 사실 정보와 해석 정보로 분리해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["사실", "해석"], "must_not": ["혼재"], "golden": false}
|
||||||
|
{"id": "ana_layer_012", "type": "analyze", "category": "층구조", "doc_id": 4041, "query": "이 문서를 핵심 원칙과 예외 조항으로 구분해서 설명해줘", "expected_layers": ["evidence", "explanation", "summary"], "critical_points": ["원칙", "예외"], "must_not": ["혼재"], "golden": false}
|
||||||
|
{"id": "ana_layer_013", "type": "analyze", "category": "층구조", "doc_id": 3853, "query": "이 문서의 교육 과목별 구조를 층으로 설명해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["과목 구조"], "must_not": ["뭉뚱그림"], "golden": false}
|
||||||
|
{"id": "ana_layer_014", "type": "analyze", "category": "층구조", "doc_id": 3854, "query": "이 문서의 조항을 주제별로 그룹핑해서 층으로 설명해줘", "expected_layers": ["evidence", "summary"], "critical_points": ["그룹핑"], "must_not": ["조항 나열만"], "golden": false}
|
||||||
|
{"id": "ana_layer_015", "type": "analyze", "category": "층구조", "doc_id": 3855, "query": "이 문서를 절차와 예외로 나눠 계층 구조로 보여줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["절차", "예외"], "must_not": ["뒤섞임"], "golden": false}
|
||||||
|
{"id": "ana_layer_016", "type": "analyze", "category": "층구조", "doc_id": 3856, "query": "이 문서의 조항을 중요도 레벨별로 나눠서 설명해줘", "expected_layers": ["evidence", "summary"], "critical_points": ["중요도"], "must_not": ["순서만"], "golden": false}
|
||||||
|
{"id": "ana_layer_017", "type": "analyze", "category": "층구조", "doc_id": 3888, "query": "이 문서의 보호구 유형별로 근거와 해설을 분리해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["유형별"], "must_not": ["혼재"], "golden": false}
|
||||||
|
{"id": "ana_layer_018", "type": "analyze", "category": "층구조", "doc_id": 3917, "query": "이 문서를 정의와 책임 주체별로 층 나눠줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["정의", "책임 주체"], "must_not": ["혼재"], "golden": false}
|
||||||
|
{"id": "ana_layer_019", "type": "analyze", "category": "층구조", "doc_id": 3981, "query": "이 문서를 적용 범위와 관리 조치로 층 분리해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["적용 범위", "조치"], "must_not": ["뭉뚱"], "golden": false}
|
||||||
|
{"id": "ana_layer_020", "type": "analyze", "category": "층구조", "doc_id": 4041, "query": "이 문서의 근로자 의무와 사업주 의무를 층별로 정리해줘", "expected_layers": ["evidence", "explanation"], "critical_points": ["근로자", "사업주"], "must_not": ["한쪽만"], "golden": false}
|
||||||
Executable
+443
@@ -0,0 +1,443 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Phase E 묶음 B — ask/analyze 평가 runner.
|
||||||
|
|
||||||
|
evals/ask_analyze_v1.jsonl 을 읽어 /ask (GET) + /{doc_id}/analyze (POST)
|
||||||
|
엔드포인트에 호출하고 원시 측정값을 JSONL 로 기록한다.
|
||||||
|
|
||||||
|
집계(E.5)는 별도 스크립트에서 수행. 이 runner 는 "raw 값만" 저장한다.
|
||||||
|
|
||||||
|
X-Source: eval 헤더를 박아 DB ask_events/analyze_events 에 source='eval' 로 분리 기록됨.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# 결과 JSONL 스키마 (순서 고정 — E.5 집계가 이 스키마 기준으로 동작)
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
RESULT_FIELDS: list[str] = [
|
||||||
|
"id", "type", "category", "golden", "doc_id",
|
||||||
|
"query", "response", "latency_ms", "error", "error_code",
|
||||||
|
"answer_length", "citation_count", "completeness", "refused",
|
||||||
|
"critical_keywords_hit",
|
||||||
|
"layers_count", "expected_layers_hit", "truncated", "cached",
|
||||||
|
"prompt_version", "model_name",
|
||||||
|
] # 21 fields, order locked
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# Normalize (critical_keywords_hit 계산용)
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
_NORMALIZE_REMOVE = re.compile(r"[\s·()\[\]{}.,;:!?\"'`]")
|
||||||
|
|
||||||
|
|
||||||
|
def normalize(text: str) -> str:
|
||||||
|
"""공백/중점/괄호/구두점 제거 + 소문자화. 형태소 분석은 하지 않음.
|
||||||
|
|
||||||
|
예: "유해·위험요인 (risk)" → "유해위험요인risk"
|
||||||
|
"""
|
||||||
|
return _NORMALIZE_REMOVE.sub("", text).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def keywords_hit(answer: str, keywords: list[str]) -> dict[str, bool]:
|
||||||
|
"""각 키워드가 normalize 후 answer 내에 substring 매칭되는지 dict 반환."""
|
||||||
|
norm_answer = normalize(answer or "")
|
||||||
|
return {kw: normalize(kw) in norm_answer for kw in keywords}
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# HTTP status → analyze error_code 추정 (DB 와 정확히 동일하진 않음, 근사)
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
def analyze_error_code_from_status(status: int) -> str | None:
|
||||||
|
"""/analyze HTTP status → error_code 근사. 정확 값은 DB analyze_events 참조."""
|
||||||
|
if status == 404:
|
||||||
|
return "not_found_or_no_text" # 404 는 문서 미존재 또는 텍스트 없음
|
||||||
|
if status == 504:
|
||||||
|
return "timeout"
|
||||||
|
if status == 502:
|
||||||
|
return "llm"
|
||||||
|
if status == 422:
|
||||||
|
return "parse_or_missing_summary"
|
||||||
|
if status >= 500:
|
||||||
|
return "server_error"
|
||||||
|
if status >= 400:
|
||||||
|
return f"http_{status}"
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# API 호출 (재시도 포함)
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApiResult:
|
||||||
|
status: int
|
||||||
|
body: Any
|
||||||
|
latency_ms: float
|
||||||
|
error: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
async def call_ask(
|
||||||
|
client: httpx.AsyncClient, base_url: str, token: str, source: str,
|
||||||
|
query: str,
|
||||||
|
) -> ApiResult:
|
||||||
|
url = f"{base_url.rstrip('/')}/api/search/ask"
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {token}",
|
||||||
|
"X-Source": source,
|
||||||
|
}
|
||||||
|
params = {"q": query}
|
||||||
|
start = time.perf_counter()
|
||||||
|
try:
|
||||||
|
resp = await client.get(url, headers=headers, params=params, timeout=60.0)
|
||||||
|
latency_ms = (time.perf_counter() - start) * 1000
|
||||||
|
try:
|
||||||
|
body = resp.json()
|
||||||
|
except Exception:
|
||||||
|
body = None
|
||||||
|
return ApiResult(status=resp.status_code, body=body, latency_ms=latency_ms)
|
||||||
|
except Exception as exc:
|
||||||
|
latency_ms = (time.perf_counter() - start) * 1000
|
||||||
|
return ApiResult(status=0, body=None, latency_ms=latency_ms, error=f"{type(exc).__name__}: {exc}")
|
||||||
|
|
||||||
|
|
||||||
|
async def call_analyze(
|
||||||
|
client: httpx.AsyncClient, base_url: str, token: str, source: str,
|
||||||
|
doc_id: int,
|
||||||
|
) -> ApiResult:
|
||||||
|
url = f"{base_url.rstrip('/')}/api/documents/{doc_id}/analyze"
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {token}",
|
||||||
|
"X-Source": source,
|
||||||
|
}
|
||||||
|
start = time.perf_counter()
|
||||||
|
try:
|
||||||
|
# analyze 는 서버 내부 timeout 60s (ANALYZE_TIMEOUT_S). client 는 여유 두고 130s.
|
||||||
|
resp = await client.post(url, headers=headers, timeout=130.0)
|
||||||
|
latency_ms = (time.perf_counter() - start) * 1000
|
||||||
|
try:
|
||||||
|
body = resp.json()
|
||||||
|
except Exception:
|
||||||
|
body = None
|
||||||
|
return ApiResult(status=resp.status_code, body=body, latency_ms=latency_ms)
|
||||||
|
except Exception as exc:
|
||||||
|
latency_ms = (time.perf_counter() - start) * 1000
|
||||||
|
return ApiResult(status=0, body=None, latency_ms=latency_ms, error=f"{type(exc).__name__}: {exc}")
|
||||||
|
|
||||||
|
|
||||||
|
async def call_with_retry(
|
||||||
|
fn, *args, retries: int = 1, retry_delay: float = 5.0,
|
||||||
|
) -> ApiResult:
|
||||||
|
"""timeout/5xx 1회 재시도. 4xx 는 재시도 안 함."""
|
||||||
|
attempt = 0
|
||||||
|
while True:
|
||||||
|
result: ApiResult = await fn(*args)
|
||||||
|
# 성공 (2xx) 이거나 클라이언트 에러 (4xx) 면 그대로 반환
|
||||||
|
if result.error is None and 200 <= result.status < 400:
|
||||||
|
return result
|
||||||
|
if result.status and 400 <= result.status < 500:
|
||||||
|
return result
|
||||||
|
# 네트워크 에러 or 5xx — 재시도
|
||||||
|
if attempt >= retries:
|
||||||
|
return result
|
||||||
|
attempt += 1
|
||||||
|
await asyncio.sleep(retry_delay)
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# 단일 아이템 처리 → RESULT_FIELDS dict 생성
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
def build_row_ask(item: dict, api: ApiResult) -> dict:
|
||||||
|
body = api.body or {}
|
||||||
|
answer = body.get("ai_answer") if isinstance(body, dict) else None
|
||||||
|
citations = body.get("citations") if isinstance(body, dict) else None
|
||||||
|
completeness = body.get("completeness") if isinstance(body, dict) else None
|
||||||
|
refused = body.get("refused") if isinstance(body, dict) else None
|
||||||
|
|
||||||
|
# error 판정: network error 또는 non-2xx
|
||||||
|
error_msg = api.error
|
||||||
|
if error_msg is None and api.status and not (200 <= api.status < 300):
|
||||||
|
error_msg = f"http_{api.status}"
|
||||||
|
|
||||||
|
row = {
|
||||||
|
"id": item["id"],
|
||||||
|
"type": "ask",
|
||||||
|
"category": item.get("category"),
|
||||||
|
"golden": item.get("golden", False),
|
||||||
|
"doc_id": None,
|
||||||
|
"query": item["query"],
|
||||||
|
"response": answer,
|
||||||
|
"latency_ms": round(api.latency_ms, 1),
|
||||||
|
"error": error_msg,
|
||||||
|
"error_code": None, # ask 는 DB refused/completeness 로 판단, 별도 error_code 없음
|
||||||
|
"answer_length": len(answer or "") if isinstance(answer, str) else None,
|
||||||
|
"citation_count": len(citations) if isinstance(citations, list) else None,
|
||||||
|
"completeness": completeness,
|
||||||
|
"refused": refused,
|
||||||
|
"critical_keywords_hit": keywords_hit(answer or "", item.get("critical_keywords", []) or []),
|
||||||
|
"layers_count": None,
|
||||||
|
"expected_layers_hit": None,
|
||||||
|
"truncated": None,
|
||||||
|
"cached": None,
|
||||||
|
# prompt_version / model_name 은 API 응답에 노출 안 됨.
|
||||||
|
# 집계 시 DB ask_events 와 join 해서 결합 (X-Source=eval 필터).
|
||||||
|
"prompt_version": None,
|
||||||
|
"model_name": None,
|
||||||
|
}
|
||||||
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
def build_row_analyze(item: dict, api: ApiResult) -> dict:
|
||||||
|
body = api.body or {}
|
||||||
|
layers = body.get("layers") if isinstance(body, dict) else None
|
||||||
|
truncated = body.get("truncated") if isinstance(body, dict) else None
|
||||||
|
cached = body.get("cached") if isinstance(body, dict) else None
|
||||||
|
|
||||||
|
# 응답의 layers 에서 type 리스트 추출
|
||||||
|
layers_returned: list[str] = []
|
||||||
|
if isinstance(layers, list):
|
||||||
|
for la in layers:
|
||||||
|
if isinstance(la, dict) and la.get("layer"):
|
||||||
|
layers_returned.append(la["layer"])
|
||||||
|
|
||||||
|
# 전체 response 문자열 = 각 layer content 이어붙이기 (answer_length 용)
|
||||||
|
response_text = ""
|
||||||
|
if isinstance(layers, list):
|
||||||
|
parts = []
|
||||||
|
for la in layers:
|
||||||
|
if isinstance(la, dict):
|
||||||
|
parts.append(la.get("content") or "")
|
||||||
|
response_text = "\n\n".join(p for p in parts if p)
|
||||||
|
|
||||||
|
# expected_layers_hit 계산
|
||||||
|
expected_layers = item.get("expected_layers") or []
|
||||||
|
layers_hit = {el: (el in layers_returned) for el in expected_layers}
|
||||||
|
|
||||||
|
error_msg = api.error
|
||||||
|
if error_msg is None and api.status and not (200 <= api.status < 300):
|
||||||
|
error_msg = f"http_{api.status}"
|
||||||
|
error_code = analyze_error_code_from_status(api.status) if api.status else None
|
||||||
|
|
||||||
|
row = {
|
||||||
|
"id": item["id"],
|
||||||
|
"type": "analyze",
|
||||||
|
"category": item.get("category"),
|
||||||
|
"golden": item.get("golden", False),
|
||||||
|
"doc_id": item.get("doc_id"),
|
||||||
|
"query": item["query"],
|
||||||
|
"response": response_text or None,
|
||||||
|
"latency_ms": round(api.latency_ms, 1),
|
||||||
|
"error": error_msg,
|
||||||
|
"error_code": error_code,
|
||||||
|
"answer_length": len(response_text) if response_text else None,
|
||||||
|
"citation_count": None,
|
||||||
|
"completeness": None,
|
||||||
|
"refused": None,
|
||||||
|
"critical_keywords_hit": None,
|
||||||
|
"layers_count": len(layers_returned) if layers_returned else 0,
|
||||||
|
"expected_layers_hit": layers_hit,
|
||||||
|
"truncated": truncated,
|
||||||
|
"cached": cached,
|
||||||
|
"prompt_version": None,
|
||||||
|
"model_name": None,
|
||||||
|
}
|
||||||
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# 필터링
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
def load_items(
|
||||||
|
path: Path,
|
||||||
|
only_golden: bool,
|
||||||
|
only_type: str | None,
|
||||||
|
start_from: str | None,
|
||||||
|
limit: int | None,
|
||||||
|
) -> list[dict]:
|
||||||
|
items: list[dict] = []
|
||||||
|
started = start_from is None
|
||||||
|
with path.open(encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
d = json.loads(line)
|
||||||
|
if only_golden and not d.get("golden"):
|
||||||
|
continue
|
||||||
|
if only_type and d.get("type") != only_type:
|
||||||
|
continue
|
||||||
|
if not started:
|
||||||
|
if d.get("id") == start_from:
|
||||||
|
started = True
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
items.append(d)
|
||||||
|
if limit is not None and len(items) >= limit:
|
||||||
|
break
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# 메인 루프
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
async def run_eval(
|
||||||
|
items: list[dict], base_url: str, token: str, source: str,
|
||||||
|
output_path: Path, min_interval: float, retries: int, retry_delay: float,
|
||||||
|
) -> None:
|
||||||
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
total = len(items)
|
||||||
|
errors = 0
|
||||||
|
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
with output_path.open("w", encoding="utf-8") as out:
|
||||||
|
last_request_ts = 0.0
|
||||||
|
for idx, item in enumerate(items, start=1):
|
||||||
|
# min-interval 유지
|
||||||
|
gap = time.perf_counter() - last_request_ts
|
||||||
|
if gap < min_interval:
|
||||||
|
await asyncio.sleep(min_interval - gap)
|
||||||
|
|
||||||
|
iid = item.get("id", "?")
|
||||||
|
itype = item.get("type", "?")
|
||||||
|
icat = item.get("category", "?")
|
||||||
|
|
||||||
|
last_request_ts = time.perf_counter()
|
||||||
|
if itype == "ask":
|
||||||
|
api = await call_with_retry(
|
||||||
|
call_ask, client, base_url, token, source, item["query"],
|
||||||
|
retries=retries, retry_delay=retry_delay,
|
||||||
|
)
|
||||||
|
row = build_row_ask(item, api)
|
||||||
|
elif itype == "analyze":
|
||||||
|
doc_id = item.get("doc_id")
|
||||||
|
if doc_id is None:
|
||||||
|
row = {
|
||||||
|
**{k: None for k in RESULT_FIELDS},
|
||||||
|
"id": iid, "type": "analyze", "category": icat,
|
||||||
|
"golden": item.get("golden", False),
|
||||||
|
"query": item.get("query"),
|
||||||
|
"error": "doc_id_missing", "latency_ms": 0.0,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
api = await call_with_retry(
|
||||||
|
call_analyze, client, base_url, token, source, doc_id,
|
||||||
|
retries=retries, retry_delay=retry_delay,
|
||||||
|
)
|
||||||
|
row = build_row_analyze(item, api)
|
||||||
|
else:
|
||||||
|
row = {
|
||||||
|
**{k: None for k in RESULT_FIELDS},
|
||||||
|
"id": iid, "type": itype, "category": icat,
|
||||||
|
"golden": item.get("golden", False),
|
||||||
|
"query": item.get("query"),
|
||||||
|
"error": f"unknown_type:{itype}", "latency_ms": 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
if row.get("error"):
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
# RESULT_FIELDS 순서로 직렬화
|
||||||
|
ordered = {k: row.get(k) for k in RESULT_FIELDS}
|
||||||
|
out.write(json.dumps(ordered, ensure_ascii=False) + "\n")
|
||||||
|
out.flush()
|
||||||
|
|
||||||
|
latency = row.get("latency_ms") or 0
|
||||||
|
err_mark = " ERR" if row.get("error") else ""
|
||||||
|
print(
|
||||||
|
f"[{idx}/{total}] {iid} ({itype}/{icat}) "
|
||||||
|
f"{latency:.0f}ms{err_mark}",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"\nDone. total={total}, errors={errors}", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
# CLI
|
||||||
|
# ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser(description="ask/analyze 평가 runner (Phase E 묶음 B)")
|
||||||
|
parser.add_argument("--eval-file", type=Path, required=True, help="평가셋 JSONL 경로")
|
||||||
|
parser.add_argument("--base-url", type=str, required=True, help="Document Server base URL")
|
||||||
|
parser.add_argument(
|
||||||
|
"--token", type=str, default=os.environ.get("DOCSRV_TOKEN"),
|
||||||
|
help="Bearer 토큰 (env DOCSRV_TOKEN)",
|
||||||
|
)
|
||||||
|
parser.add_argument("--source", type=str, default="eval", help="X-Source 헤더 값 (default: eval)")
|
||||||
|
parser.add_argument("--concurrency", type=int, default=1, help="동시 요청 수 (현재 1 고정)")
|
||||||
|
parser.add_argument("--min-interval", type=float, default=0.3, help="요청 간 최소 간격(초)")
|
||||||
|
parser.add_argument("--retries", type=int, default=1, help="timeout/5xx 재시도 횟수")
|
||||||
|
parser.add_argument("--retry-delay", type=float, default=5.0, help="재시도 delay(초)")
|
||||||
|
parser.add_argument("--output", type=Path, required=True, help="결과 JSONL 출력 경로")
|
||||||
|
parser.add_argument("--start-from", type=str, default=None, help="이 ID 부터 실행 (resume)")
|
||||||
|
parser.add_argument("--only-golden", action="store_true", help="golden: true 만 필터")
|
||||||
|
parser.add_argument(
|
||||||
|
"--only-type", type=str, default=None, choices=["ask", "analyze"],
|
||||||
|
help="type 필터 (ask 또는 analyze)",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--limit", type=int, default=None,
|
||||||
|
help="처리 아이템 수 상한 (smoke test 용)",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if not args.token:
|
||||||
|
print("ERROR: --token 또는 env DOCSRV_TOKEN 필요", file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
if args.concurrency != 1:
|
||||||
|
print("NOTE: concurrency != 1 은 현재 미지원. 1로 동작합니다.", file=sys.stderr)
|
||||||
|
|
||||||
|
items = load_items(
|
||||||
|
args.eval_file,
|
||||||
|
only_golden=args.only_golden,
|
||||||
|
only_type=args.only_type,
|
||||||
|
start_from=args.start_from,
|
||||||
|
limit=args.limit,
|
||||||
|
)
|
||||||
|
if not items:
|
||||||
|
print("ERROR: 필터 조건에 맞는 아이템 없음", file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"Loaded {len(items)} items from {args.eval_file} "
|
||||||
|
f"(golden={args.only_golden}, type={args.only_type or 'all'}, start_from={args.start_from or '-'})",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
|
||||||
|
asyncio.run(
|
||||||
|
run_eval(
|
||||||
|
items, args.base_url, args.token, args.source,
|
||||||
|
args.output, args.min_interval, args.retries, args.retry_delay,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in New Issue
Block a user