====== AI TBM 코칭 시뮬레이터 구조 및 개발 방법 ====== ===== 1. 서론 ===== 이 문서는 AI TBM (Tool Box Meeting) 코칭 시뮬레이터의 핵심 구조와 개발 방법론을 상세히 설명합니다. 본 시뮬레이터는 실제 건설 현장의 안전 관리 역량을 강화하기 위해 설계되었으며, Google의 Gemini AI 모델을 활용하여 현실적이고 동적인 TBM 시나리오 생성 및 관리자 코칭 기능을 제공합니다. 특히, API 키 관리, 시나리오 생성의 복잡성, 대화 역학 및 코칭 시스템, 그리고 작업 결과 산출 방식에 대한 심층적인 이해를 돕는 것을 목표로 합니다. ===== 2. 시스템 개요 ===== AI TBM 코칭 시뮬레이터는 관리자가 가상의 TBM 상황에서 작업자들과 소통하며 안전 문제를 해결하는 과정을 연습하고 피드백을 받을 수 있도록 돕는 시스템입니다. ==== 1) AI TBM 코칭 시뮬레이터의 목적 ==== * **안전 역량 강화**: 건설 현장 관리자들이 실제와 유사한 TBM 상황을 경험하며 안전 의사소통 및 문제 해결 능력을 향상시킵니다. * **현실적인 시뮬레이션**: 다양한 현장 상황, 작업자 페르소나, 돌발 상황 등을 AI가 동적으로 생성하여 높은 현실감을 제공합니다. * **맞춤형 피드백**: 관리자의 소통 방식과 결정에 대해 AI 코치가 구체적이고 실용적인 피드백을 제공하여 학습 효과를 극대화합니다. * **법적 기준 반영**: 중대재해처벌법 등 실제 법규를 기반으로 재해 유형을 분류하고 결과를 산출하여 교육적 가치를 높입니다. ---- ==== 2) 주요 구성 요소 ==== 시뮬레이터는 크게 세 가지 핵심 AI 기반 기능과 이를 지원하는 Flask API로 구성됩니다. * **시나리오 생성 모듈**: TBM 시뮬레이션의 배경이 될 구체적인 현장 상황, 작업 내용, 날씨, 작업자 페르소나 및 초기 대화를 생성합니다. * **TBM 코칭 모듈**: 관리자의 입력에 따라 작업자들의 반응을 시뮬레이션하고, 관리자의 소통 방식에 대해 실시간으로 코칭 피드백을 제공합니다. * **작업 결과 생성 모듈**: 최종 TBM 진행 상황과 안전 점수를 바탕으로 실제 작업 결과를 예측하고 재해 발생 여부를 판정합니다. * **Flask API**: 위 모듈들을 외부 시스템과 연동할 수 있도록 HTTP 엔드포인트를 제공합니다. ===== 3. API 키 관리 및 설정 ===== Google Gemini API를 안정적으로 사용하기 위해 다수의 API 키를 관리하고 순환 사용하는 전략을 채택합니다. ---- ==== 1) 환경 변수를 통한 API 키 로드 ==== API 키는 보안을 위해 코드 내에 직접 명시하지 않고, 서버의 환경 변수에서 로드합니다. * ''GOOGLE_API_KEY'' * ''GOOGLE_API_KEY_SUB'' * ''GOOGLE_API_KEY_THIRD'' 이러한 환경 변수가 설정되어 있지 않으면 시스템은 심각한 오류를 보고하며 정상적으로 작동하지 않습니다. ---- ==== 2) API 키 순환 및 스레드 안전성 ==== 여러 API 키를 활용하여 API 호출 제한에 대비하고, 안정적인 서비스 운영을 도모합니다. * ''itertools.cycle'': 로드된 API 키들을 순환하며 사용하도록 합니다. * ''threading.Lock'': 여러 스레드에서 동시에 API 키를 요청할 때 발생할 수 있는 경쟁 조건을 방지하고, 키 선택의 스레드 안전성을 보장합니다. ---- ==== 3) ''get_next_api_key()'' 함수 동작 방식 ==== 이 함수는 다음 API 키를 가져오는 로직을 캡슐화합니다. * **첫 번째 호출**: 시스템이 시작된 후 첫 API 호출 시에는 로드된 키 중에서 무작위로 하나를 선택합니다. 이는 초기 다양성을 확보하기 위함입니다. * **이후 호출**: 첫 호출 이후부터는 ''api_key_cycler''를 통해 키들을 순환하며 사용합니다. 이를 통해 각 키의 사용량을 분산시킵니다. def get_next_api_key(): global first_call_made with api_key_lock: if not first_call_made: # 첫 번째 호출 시 랜덤 선택 selected_key = random.choice(api_keys) first_call_made = True print(f"첫 번째 API 호출 - 랜덤 선택된 키 (ending with ...{selected_key[-4:]})") else: # 이후 호출은 순환 방식 selected_key = next(api_key_cycler) print(f"API 키 순환 사용 (ending with ...{selected_key[-4:]})") return selected_key ===== 4. 시나리오 생성 기능 상세 ===== ''call_gemini_for_scenario_generation()'' 함수는 Gemini AI를 호출하여 TBM 시뮬레이션을 위한 시나리오를 생성합니다. 이 과정은 다양한 규칙과 제약 조건을 포함하여 현실적이고 교육적인 시나리오를 만듭니다. ---- ==== 1) ''call_gemini_for_scenario_generation()'' 함수 ==== 이 함수는 시나리오 생성의 핵심 로직을 담당합니다. * **API 키 선택**: ''get_next_api_key()''를 호출하여 사용할 Gemini API 키를 가져옵니다. * **모델 설정**: ''gemini-2.5-flash'' 모델을 사용하여 프롬프트에 기반한 시나리오를 생성합니다. * **프롬프트 구성**: 시나리오 생성에 필요한 모든 지시사항과 제약 조건이 포함된 상세한 프롬프트를 구성하여 AI에 전달합니다. * **응답 처리**: AI로부터 받은 응답을 JSON 형식으로 파싱하고, 파싱 오류 발생 시 다양한 복구 로직을 시도합니다. ---- ==== 2) 시나리오 핵심 테마 (4가지) ==== AI는 매번 시나리오 생성 시 다음 네 가지 테마 중 하나를 강제적으로 선택하고, 해당 테마의 목표와 규칙에 맞춰 시나리오를 전개합니다. * **관행 타파**: 작업자의 위험한 관행이나 인식을 관리자가 어떻게 바꾸는지에 초점을 맞춥니다. - 지정된 시작 대화 유형: ''갈등 제시형'' * **정보 발견**: 모두가 모르는 결정적 정보를 관리자가 리더십 행동으로 발견해내는 과정에 초점을 맞춥니다. - 지정된 시작 대화 유형: ''질문형 또는 중립형'' * **위험 탐색**: 상황 설명에 없는 제3의 물리적 위험을 관리자와 팀원들이 함께 탐색하고 찾아내는 과정에 초점을 맞춥니다. - 지정된 시작 대화 유형: ''관찰/감각 공유형'' * **문제 해결**: 주어진 제약 조건 속에서 관리자가 팀원들과 함께 가장 안전한 해결책을 찾아가는 과정에 초점을 맞춥니다. - 지정된 시작 대화 유형: ''상황 공유 및 요청형'' ---- ==== 3) 공통 시나리오 생성 규칙 ==== AI는 테마별 지침 외에도 다음과 같은 공통 규칙을 준수하여 시나리오를 생성합니다. - **동적 변수 조합 규칙 강화**: - **변수 재사용 제한 (쿨타임)**: 이전 2~3번의 시나리오에서 사용된 특정 '인적/관리적 변수'는 다시 사용하지 않아 시나리오의 다양성을 보장합니다. - **숨겨진 정보 및 단서 설계**: - '정보 발견'이나 '위험 탐색' 테마에서는 사용자에게 보이지 않는 '숨겨진 결정적 정보'와 그것을 발견할 '정보 흔적'(1~3개)을 설계합니다. - '관행 타파'나 '문제 해결' 테마는 숨겨진 정보가 없을 수 있으며, 이 경우 ''hidden_critical_info''는 ''null''이 됩니다. - **자기 복제 금지**: 특정 소재(예: '야간 작업팀의 전기 배선 변경')의 반복 사용을 금지하며, 매번 새로운 소재를 사용합니다. - **시나리오 구체화**: - '건설/작업 분야' 목록에서 무작위로 분야를 선택하고, 지정된 테마와 숨겨진 정보에 맞춰 구체적인 ''situation'', ''task'', ''weather'' 등을 작성합니다. - 사용자에게 보여주는 ''situation''에는 숨겨진 정보를 노출하지 않습니다. - **페르소나 생성**: - 2~3명의 작업자 페르소나를 생성하며, 각 작업자는 이름, 역할, 그리고 서로 다른 독특한 대화 성향을 가집니다. - **현실 반영 요구사항**: 시뮬레이션의 난이도와 현실감을 높이기 위해, 최소 1명 이상은 비협조적이거나 안전에 무관심한 성향을 갖도록 페르소나를 조합합니다. - **성향 키워드 풀**: ''#일정중시'', ''#안전불감증'', ''#경험과신'', ''#원칙주의(FM)'', ''#소극적/무관심'', ''#불만많음'', ''#꼼꼼함/신중함'' 등 1~2개를 조합하여 구체적인 성향을 만듭니다. - **자기 검증 및 최종 JSON 생성**: - 생성된 '숨겨진 정보'가 시나리오와 논리적으로 타당한지 스스로 검증하는 과정을 거칩니다. - 물리적, 화학적, 기계적 원리에 부합하고, 현실적으로 발생할 법한 위험인지, 작업자들이 놓칠 수 있는 위험인지 등을 체크합니다. ---- ==== 4) 동적 변수 조합 가이드 ==== 첫 대사 생성 시, AI는 다음 변수 풀에서 0개 또는 1개의 변수를 무작위로 선택하여 조합합니다. * **[환경 변수]**: ''#강풍'', ''#폭우 직후'', ''#폭염'', ''#영하의 날씨'', ''#야간 작업'', ''#심한 소음'', ''#다량의 분진'' * **[인적 변수]**: ''#작업자 피로 누적'', ''#개인사정으로 인한 집중력 저하'', ''#팀원 간의 미묘한 갈등'', ''#성과 압박으로 인한 스트레스'' * **[관리/절차적 변수]**: ''#급작스러운 작업 변경'', ''#신규 장비 최초 사용'', ''#최근 현장 내 아차사고 발생'', ''#원청의 강력한 일정 압박'', ''#보호구(PPE) 일부 부족'' 이 조합된 변수와 작업자 페르소나를 종합적으로 고려하여 첫 대사가 생성됩니다. ---- ==== 5) 실제 사고 사례 참고 및 변형 ==== AI는 현실적인 위험 상황 설정을 위해 다음과 같은 실제 사고 사례들을 참고하며, 단순히 복사하는 것이 아니라 창의적으로 변형하여 새로운 시나리오를 생성합니다. * **기계/장비 관련 사고** * **전기/감전 관련 사고** * **고소/추락 관련 사고** * **밀폐공간/가스 관련 사고** * **화재/폭발 관련 사고** * **구조물/지반 관련 사고** * **환경/건강 관련 사고** * **해상/수중 관련 사고** * **교통/운반 관련 사고** 창의적 변형 가이드를 통해 장비, 전기 위험, 고소작업, 밀폐공간 위험, 화학적 위험, 구조물 위험, 환경적 위험, 시간적 요인, 인적 요인, 조직적 요인 등을 다양하게 변형하여 시나리오를 풍부하게 만듭니다. ---- ==== 6) 최종 JSON 출력 형식 ==== 시나리오 생성 결과는 다음과 같은 엄격한 JSON 형식으로 출력됩니다. {{ "scenario": {{ "situation": "string - 구체적인 TBM 상황 설명 (분야, 작업, 위험요소 포함, 200자 이내)", "task": "string - 오늘의 주요 작업 (구체적인 작업 내용, 100자 이내)", "weather": "string - 오늘의 날씨 및 환경 (작업에 영향을 주는 환경요인, 100자 이내)", "personnel_count": "number - 투입 인력 수 (예: 5)", "work_area_diagram": "string - 텍스트 기호로 만든 작업 구역 도면. 여러 줄일 경우 \\n으로 구분. (예: |----E----|\\n| |\\n| W |\\n|_________|) - 고정폭 폰트로 정렬되도록 주의", "diagram_legend": "string - 도면에 사용된 기호들의 설명. 여러 항목일 경우 \\n으로 구분. (예: W: 작업자\\nE: 장비\\n#: 벽\\n!!: 위험!)", "hidden_critical_info": "string - 숨겨진 결정적 정보 (테마 2, 3에만 해당, 다른 테마는 null)" }}, "workers": [ {{ "name": "string - 작업자 이름 (한국인 이름, 2-4글자)", "role": "string - 작업자 역할 (구체적인 분야와 경험 포함, 60자 이내)", "personality": "string - 구체적인 대화 성향 (안전의식, 경험, 성격 등을 종합적으로 표현, 100자 이내)" }}, {{ "name": "string - 작업자 이름 (한국인 이름, 2-4글자)", "role": "string - 작업자 역할 (구체적인 분야와 경험 포함, 60자 이내)", "personality": "string - 구체적인 대화 성향 (안전의식, 경험, 성격 등을 종합적으로 표현, 100자 이내)" }}, {{ "name": "string - 작업자 이름 (한국인 이름, 2-4글자)", "role": "string - 작업자 역할 (구체적인 분야와 경험 포함, 60자 이내)", "personality": "string - 구체적인 대화 성향 (안전의식, 경험, 성격 등을 종합적으로 표현, 100자 이내)" }} ], "initial_message": {{ "speaker_name": "string - 첫 대사를 말하는 작업자 이름", "text": "string - 첫 대사 내용 (현실적이고 구체적인 상황 반영, 반드시 관리자 호칭 포함, 200자 이내)" }} }} ===== 5. TBM 코칭 및 대화 기능 상세 ===== ''call_gemini_for_tbm_coaching()'' 함수는 관리자와 작업자 간의 대화를 진행하고, 관리자의 소통 방식에 대한 피드백을 제공합니다. ---- ==== 1) ''call_gemini_for_tbm_coaching()'' 함수 ==== 이 함수는 대화 및 코칭의 핵심 로직을 수행합니다. * **API 키 선택**: ''get_next_api_key()''를 호출하여 사용할 Gemini API 키를 가져옵니다. * **모델 설정**: ''gemini-2.5-flash'' 모델을 사용하여 대화 응답 및 코칭 피드백을 생성합니다. * **프롬프트 구성**: 현재 시나리오, 작업자 정보, 대화 기록, 관리자 메시지, 현재 안전 점수, 그리고 '숨겨진 결정적 정보'를 포함한 상세한 프롬프트를 구성합니다. * **응답 처리**: AI 응답을 JSON 형식으로 파싱하고, 오류 발생 시 다양한 복구 로직을 시도합니다. 특히 ''worker_responses'' 필드가 비어있지 않은지 검증합니다. ---- ==== 2) AI의 다중 페르소나 역할 ==== AI는 두 가지 주요 역할을 동시에 수행합니다. * **건설 작업자들**: 시나리오에 정의된 페르소나(예: 경험 많지만 안전 수칙 간과, 신중하지만 주도성 부족, 열정적이지만 경험 부족 신입)에 따라 관리자의 말에 현실적으로 반응합니다. * **전문 안전 리더십 코치**: 관리자의 소통 방식을 분석하고 개선점을 제시하는 역할을 합니다. ---- ==== 3) 대화 역학(Dynamics) 심층 가이드 ==== AI는 단순한 질의응답을 넘어, 예측 불가능하고 현실적인 대화 흐름을 만듭니다. 다음 행동 패턴 중 가장 현실적인 것을 선택하여 대사를 생성합니다. * **A. 주도적 발언자의 '의견 강화' 또는 '무시'**: 관리자의 지적에도 불구하고 자기주장을 반복하거나 무시하려 시도. * **B. 소극적 동조 또는 '전략적 침묵'**: 관리자 의견에 동의하지만, 상위 직급 작업자 앞에서 직접 반박 주저. * **C. 제3자의 '주제 이탈' 또는 '물타기'**: 대화가 불편한 방향으로 흐를 때, 관련 없는 질문이나 농담으로 분위기 전환 시도. * **D. 예상 밖 인물의 '돌발 발언'**: 조용하던 인물이 갑자기 핵심을 찌르는 순수한 질문으로 새로운 위험 요소 발견. * **E. 감정적 반응 또는 '태도 문제'**: 관리자의 지적을 자신의 역량 비판으로 받아들여 감정적으로 반응. ---- ==== 4) 정보 잠금 해제: 리더십 행동 기반 규칙 ==== '숨겨진 정보'와 '정보 흔적'은 관리자가 올바른 리더십 행동을 보였을 때만 단계적으로 공개됩니다. 단순히 특정 단어를 언급하는 것만으로는 정보를 얻을 수 없습니다. * **1. 심리적 안전감 조성**: 개방적이고 안전한 분위기를 조성했을 때 작업자가 첫 단서를 말합니다. (예: "혹시 평소와 다르다고 느껴지는 점이 있나요?") * **2. 논리적 진단 및 절차 확인**: 문제의 근원을 파고드는 구체적인 '검증 절차'를 지시했을 때 정보가 자연스럽게 드러납니다. (예: "표준 수신호를 맞춰보는 시연을 한번 하죠.") * **3. 현장 관찰 및 물리적 확인 지시**: 다 같이 작업장을 둘러보거나 이상 징후에 대해 즉시 확인을 지시했을 때 단서를 발견합니다. (예: "방금 그 소리, 크레인에서 난 것 같은데 즉시 확인해봅시다.") ---- ==== 5) 돌발 상황 연출 ==== 아주 낮은 확률(5~10%)로 대화 내용과 관련 있는 '돌발 상황'이 발생하여 시뮬레이션의 긴장감을 높입니다. * 예시: 강풍, 자재 결속 로프 헐거움, 경고음, 전기 스파크, 지반 미세 진동, 가스 냄새, 비계 흔들림 소리, 장비 이상 소리 등. * 돌발 상황은 현재 작업과 관련된 현실적인 위험 요소여야 합니다. ---- ==== 6) 코칭 평가 및 피드백 시스템 ==== 관리자의 발언을 분석하고 현재 안전 점수와 대화 맥락을 고려하여 3가지 유형의 피드백을 제공합니다. 피드백 텍스트에는 직접적인 점수 언급을 피합니다. * **''good'' (따봉 👍)**: - **조건**: 관리자의 발언이 구체적이고, 완전하며, 즉각적인 긍정적 변화를 이끌어냈을 때. (예상 점수 변화: +10 ~ +15) - **피드백 텍스트**: "훌륭합니다.", "결정적인 지시였습니다." 등 극찬. * **''mixed'' (체크 ✔️)**: - **조건**: 방향은 맞지만, 구체성이 부족하거나 추가적인 행동이 더 필요한 경우. (예상 점수 변화: +1 ~ +9) - **피드백 텍스트**: "좋은 지적입니다. 다만...", "핵심을 파악하셨습니다. 이제..."와 같이 칭찬과 개선점을 함께 언급. * **''suggestion'' (전구 💡)**: - **조건**: 관리자의 발언이 상황을 악화시키거나, 중요한 단서를 놓치거나, 안전에 부정적인 영향을 미쳤을 때. (예상 점수 변화: 0 또는 음수) - **피드백 텍스트**: "이런 방식보다는...", "더 나은 방법은..." 등 대안 제시. * **평가 핵심 원칙**: 단순히 위험 요소를 '언급'하는 것이 아니라, 관리자의 발언이 작업자의 태도나 발언, 행동 계획에 '실질적인 변화'를 일으켰을 때만 긍정적으로 평가합니다. ---- ==== 7) 최종 JSON 출력 형식 ==== TBM 코칭 및 대화 기능의 결과는 다음과 같은 JSON 형식으로 출력됩니다. {{ "worker_responses": [ {{ "speaker_name": "string - 첫 번째 발언자 이름", "text": "string - 첫 번째 발언 내용 (150자 이내)" }}, {{ "speaker_name": "string - (선택사항) 두 번째 발언자 이름", "text": "string - (선택사항) 두 번째 발언 내용 (150자 이내)" }} ], "sudden_event": "string - 발생한 돌발 상황 텍스트 (없으면 null)", "safety_score_change": "number - 안전도 점수 변화 (-15에서 +15 사이의 정수)", "coach_feedback": {{ "type": "string - 피드백 유형 ('good', 'mixed', 또는 'suggestion' 중 하나)", "text": "string - 관리자의 발언에 대한 구체적이고 실용적인 코칭 내용 (점수 언급 없이, 300자 이내)" }}, "critical_info_revealed": "boolean - 숨겨진 정보가 공개되었는지 여부 (true/false)" }} ===== 6. 작업 결과 생성 기능 상세 ===== ''call_gemini_for_work_result()'' 함수는 TBM 시뮬레이션의 최종 안전 점수와 대화 내용을 바탕으로 실제 작업 결과를 시뮬레이션합니다. ---- ==== 1) ''call_gemini_for_work_result()'' 함수 ==== 이 함수는 작업 결과 생성의 핵심 로직을 수행합니다. * **API 키 선택**: ''get_next_api_key()''를 호출하여 사용할 Gemini API 키를 가져옵니다. * **모델 설정**: ''gemini-1.5-flash'' 모델을 사용하여 작업 결과 시나리오를 생성합니다. * **프롬프트 구성**: 최종 안전 점수, 시나리오 정보, 작업자 정보, 전체 대화 기록, 그리고 '숨겨진 정보 발견 여부'를 포함한 상세한 프롬프트를 구성합니다. * **재해 확률 설정**: 안전 점수에 따라 기본 재해 유형(완벽한 성공, 교훈이 있는 성공, 일반재해 발생, 중대재해 발생)을 설정합니다. * **응답 처리**: AI 응답을 JSON 형식으로 파싱하고, 오류 발생 시 기본 실패 메시지를 반환합니다. ---- ==== 2) 재해자 수치 산정 최종 규칙 ==== AI는 대한민국 '중대재해처벌법' 기준에 따라 재해 유형을 엄격하게 분류하고, 서사 내용과 숫자가 반드시 일치하도록 합니다. * **중대재해**: 다음 중 하나에 해당하는 경우 - 사망자가 1명 이상 발생 - 동일 사고로 6개월 이상 치료가 필요한 부상자가 2명 이상 발생 - 동일 유해요인으로 급성중독 등 직업성 질병자가 1년 이내에 3명 이상 발생 - (시뮬레이션 단순화를 위해) '심정지', '의식불명', '주요 신체 부위 절단' 등 사망에 이를 수 있는 치명상은 '사망'에 준하는 것으로 간주. * **일반재해**: '중대재해'에 해당하지 않는 모든 부상 (예: 단순 골절, 찰과상, 염좌, 일시적인 쇼크 등). * **규칙**: 먼저 ''narrative'' 부분에 사고의 전개 과정과 피해자들의 개별적인 부상 상태를 구체적으로 서술한 후, 서술된 피해자 한 명 한 명을 위 법적 정의에 대입하여 '중대재해'인지 '일반재해'인지 분류하고, 그 결과를 바탕으로 ''casualties'' 항목의 중대재해 및 일반재해 수를 정확하게 집계합니다. ---- ==== 3) 사고 시나리오의 인과관계 및 개연성 강화 규칙 ==== 사고 경위를 서술할 때 단순한 결과 나열이 아닌, 논리적인 인과관계를 명확히 합니다. * **전제조건의 명시**: 사고가 일어날 수밖에 없었던 환경적/물리적 전제조건을 먼저 구체적으로 언급합니다. * **인과관계의 논리적 연결**: '전제조건 → 원인(숨겨진 정보) → 결과(사고)'의 순서로 모든 사건이 논리적 사슬처럼 연결되도록 서술합니다. ---- ==== 4) 결과 보고서 작성 규칙 (우선순위) ==== 결과 판정은 다음 규칙들을 **반드시 순서대로, 그리고 최우선으로 적용하여** 이루어집니다. - **황금률: 완벽한 점수 = 완벽한 결과**: - **최종 안전 점수가 90점 이상**이라면, 다른 모든 규칙과 서사적 가능성을 무시하고, 반드시 ''result_type: success'' 및 ''casualties: 중대재해 0명, 일반재해 0명''으로 결론 내립니다. - ''narrative''는 관리자의 뛰어난 리더십으로 모든 잠재적 위험을 완벽하게 예방하고 성공적으로 작업을 마쳤다는 긍정적인 내용으로만 작성됩니다. - **최우선 원칙: 관리자의 마지막 행동 존중**: - (황금률에 해당하지 않을 경우) 관리자가 마지막에 명확하고 안전한 조치를 지시했다면, 반드시 '사고 예방 성공' 또는 '교훈이 있는 성공' 수준의 긍정적인 결과가 나옵니다. - 관리자의 올바른 지시를 무효로 만드는 새로운 부정적 상황을 결과 서사에서 창작하지 않습니다. - 중대재해는 오직 관리자가 위험을 인지하지 못했거나, 무시했거나, 혹은 불분명하고 위험한 지시를 내렸을 경우에만 발생합니다. - **1순위 판정 기준: 숨겨진 정보 발견 여부**: - 위 '최우선 원칙'에 해당하지 않는 경우, ''critical_info_uncovered''가 ''false''라면, 안전 점수와 관계없이 '중대재해'가 발생합니다. - 사고 서사는 TBM 과정의 '좋은 과정'에도 불구하고 '결정적 실수'로 인해 사고가 났음을 명확히 서술합니다. - **2순위 판정 기준: 안전 점수**: - '최우선 원칙'과 '1순위 판정 기준'에 해당하지 않을 때만, 안전 점수에 따라 결과의 질을 결정합니다. - **90점 이상**: ''success'' (완벽한 성공) - **70점 ~ 89점**: ''success_with_lessons'' (교훈이 있는 성공). 물리적 사고는 발생하지 않고, TBM의 '사소한 흠결'이 '교훈'이 되었음을 서술합니다. - **70점 미만**: ''near_miss'' 또는 ''minor_accident''. TBM의 실패가 어떻게 물리적인 위험 상황이나 실제 사고로 이어졌는지 인과관계를 명확히 서술합니다. ---- ==== 5) 최종 JSON 출력 형식 ==== 작업 결과 생성 기능의 결과는 다음과 같은 JSON 형식으로 출력됩니다. {{ "result_type": "string - 'success', 'success_with_lessons', 'near_miss', 'minor_accident', 'major_accident' 중 하나", "narrative": "string - AI가 생성한 구체적인 작업 결과 이야기", "casualties": "string - 최종 재해자 수 (예: 중대재해 0명, 일반재해 1명)" }} ===== 7. Flask API 엔드포인트 ===== Flask 애플리케이션은 다음 API 엔드포인트를 통해 시뮬레이터의 기능을 제공합니다. 모든 엔드포인트는 ''@token_required'' 데코레이터로 보호되어 인증된 사용자만 접근할 수 있습니다. ---- ==== 1) ''/api/tbm/scenario'' (GET) ==== * **기능**: 새로운 TBM 시나리오를 생성하고 반환합니다. * **메서드**: GET * **''tbm_simulator_bp'' 정의**: Blueprint의 URL 접두사로 인해 실제 경로는 ''/api/tbm/scenario''가 됩니다. * **내부 호출**: ''call_gemini_for_scenario_generation()'' 함수를 호출합니다. ---- ==== 2) ''/api/tbm/chat'' (POST) ==== * **기능**: TBM 대화를 진행하고, 작업자 응답 및 관리자 코칭 피드백을 반환합니다. * **메서드**: POST * **요청 데이터**: 시나리오 정보 (''scenario''), 작업자 정보 (''workers''), 대화 기록 (''history''), 관리자 메시지 (''message''), 현재 안전 점수 (''currentSafetyScore''), 숨겨진 결정적 정보 (''hidden_critical_info'')를 JSON 형식으로 받습니다. * **내부 호출**: ''call_gemini_for_tbm_coaching()'' 함수를 호출합니다. ---- ==== 3) ''/api/tbm/result'' (POST) ==== * **기능**: 최종 안전 점수를 바탕으로 작업 결과를 생성하고 반환합니다. * **메서드**: POST * **요청 데이터**: 최종 안전 점수 (''safetyScore''), 시나리오 정보 (''scenario''), 작업자 정보 (''workers''), 전체 대화 기록 (''conversationHistory''), 숨겨진 정보 발견 여부 (''criticalInfoUncovered'')를 JSON 형식으로 받습니다. * **내부 호출**: ''call_gemini_for_work_result()'' 함수를 호출합니다. ===== 8. 결론 ===== AI TBM 코칭 시뮬레이터는 Google Gemini AI의 강력한 생성 능력을 활용하여 건설 현장 안전 관리자들에게 실질적인 훈련 기회를 제공합니다. 다중 API 키 관리, 정교한 시나리오 및 페르소나 생성, 동적인 대화 역학 및 리더십 기반 정보 공개 시스템, 그리고 법적 기준을 반영한 현실적인 작업 결과 산출에 이르기까지, 이 시뮬레이터는 안전 교육의 질을 한 단계 높이는 데 기여할 것입니다. 지속적인 개선과 확장을 통해 더욱 다양한 현장 상황과 복잡한 문제 해결 시나리오를 지원하며, 궁극적으로는 실제 현장의 안전사고 감소에 이바지할 수 있을 것으로 기대됩니다.