마키나락스
경력근거: LLM 실적용 성공 사례를 지속적으로 늘려나가고 전체 수행 과정 효율을 개선할 수 있는 체계를 함께 고민하여 반영합니다.
마키나락스 FDE본부는 실제 현장의 데이터로 풀어야 할 문제를 정의하고, 제조·산업 데이터(설비 로그·이미지·문서)를 기반으로 LLM/VLM 분석·자동화 시스템을 만들며, 축적한 문제 해결 경험을 솔루션으로 자산화합니다. 이 도구는 고객사 공장에서 실제로 나오는 두 기록(작업자 점검 일지 엑셀과 설비 알람 로그)을 받아 어긋난 지점을 문제로 정의하고, 규칙으로 대조해 사람이 읽는 주간 리포트까지 잇는 과정을 그대로 담았습니다. 자유 문장 추출은 LLM 이, 짝짓기 판정은 규칙이 맡도록 경계를 분명히 둔 점이 현장에 들고 들어갈 수 있는 근거입니다. 다만 이 포트폴리오가 보여주는 것은 기록 대조와 추출 스키마 고정, 리포트 생성 기술이며 제조 설비·보전 도메인 전문성은 주장하지 않습니다. 어떤 알람이 정말 위험한지 가리는 깊이는 현장 엔지니어의 지식이라, 모르는 부분은 면접에서 모른다고 말하는 편이 낫습니다.
제조·산업 데이터(설비 로그·이미지·문서)를 기반으로 LLM/VLM 분석·자동화 시스템을 개발합니다. 설비 로그와 작업자 문서를 함께 다루는 이 도구가 정면으로 정렬됩니다.
현장 데이터를 분석해 풀어야 할 문제를 정의하고 수행 효율을 개선하는 체계를 만듭니다. 두 기록의 어긋남을 찾아 리포트로 내는 흐름이 그 일과 정렬됩니다.
LLM/VLM 으로 실제 사용 가능한 수준의 산출물을 만들고 데이터 파이프라인을 설계·운영합니다. 한 줄 명령으로 파일을 내놓는 도구가 그 수준과 정렬됩니다.
제조 고객사 보전팀에게서 받은 점검 일지 엑셀과 설비 알람 로그 CSV, 설비 대장을 함께 읽어 같은 설비·같은 시간대끼리 짝을 짓고, 짝이 없는 기록만 모아 주간 대조 리포트 마크다운으로 내는 1주 FDE PoC 입니다. 짝짓기 판정은 설비 대장 매칭과 시간창 규칙이 정하고, LLM 은 작업자가 자유 문장으로 적은 일지 본문에서 설비와 증상을 뽑는 일만 맡습니다.
제조 고객사 공장의 보전팀 반장입니다. 작업자 다섯 명이 각자 엑셀에 적어 둔 점검 일지와 설비에서 내려받은 알람 로그를 매주 눈으로 번갈아 보며, 적혀 있는데 알람이 없는 건과 알람이 떴는데 아무도 적지 않은 건을 골라 주간 보고를 만들고 있습니다.
점검 일지와 알람 로그를 설비 대장으로 같은 이름에 묶고 시간창으로 짝을 지으면, (a) 일지에만 있는 건과 알람에만 있는 건을 규칙으로 가려내고, (b) 판정마다 원본 행 번호와 시각 차이를 근거로 남기며, (c) 짝을 지을 수 없는 행은 추측하지 않고 확인 필요로 모아 리포트 끝에 붙입니다.
점검 일지 엑셀과 알람 로그 CSV, 설비 대장을 한 줄 명령으로 넣으면 어긋난 건과 확인 필요 목록을 담은 주간 대조 리포트 마크다운이 나오는 CLI입니다.
어긋난 건마다 설비 매뉴얼에서 해당 점검 항목을 찾아 조항으로 인용하고, 직접 만든 정답 라벨과 대조해 판정 일치도를 잰 기록입니다.
설비 대장과 시간창 설정만 바꿔 다른 라인의 일지·로그에 그대로 도는지 확인하고 주차별 반복 항목을 누적한 이식 기록입니다.
일지 엑셀 120행과 알람 로그 400행을 한 줄 명령으로 넣으면 주간 대조 리포트 마크다운 한 편이 나오는 걸 시연합니다
일부러 섞은 날짜 서식 흔들림·설비 표기 별칭·한 줄 두 설비·미등록 설비 30종을 넣어도 도구가 멈추지 않고 확인 필요로 가려냅니다
심은 정답 라벨 대비 대조 판정 일치도 88% 입니다
측정: 규칙 판정과 라벨 비교, 표본: 일지 120행·알람 400행, 2주차
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 제가 만든 더미 일지를 제가 채점한 결과이고, 실제 대조 정확도는 마키나락스가 들어간 고객사 공장의 실제 일지와 알람 로그가 있어야 측정됩니다. 이 포트폴리오는 그 확인을 바로 돌릴 수 있는 상태로 만듭니다.
이건 고객사도 실데이터도 없이 혼자 만든 포트폴리오입니다. 더미 일지와 알람 로그를 제가 만들고 제가 채점했으니 수치는 성능 증명이 아닙니다. 면접에서는 도구가 도는 모습과 검증 준비 상태로 솔직히 설명합니다
이 포트폴리오가 보여주는 것은 흩어진 기록을 규칙으로 대조해 사람이 읽을 문서로 만드는 기술과 자유 문장을 고정 스키마로 뽑아내는 기술입니다. 제조 설비·보전 도메인 전문성은 주장하지 않습니다. 어떤 알람이 실제로 위험한지 가리는 깊이는 현장 엔지니어의 지식이라, 모르는 부분은 면접에서 모른다고 말하는 편이 낫습니다
LLM 은 본문에 없는 설비명을 그럴듯하게 지어낼 수 있습니다. 추출은 설비 대장에 있는 이름으로만 확정하고, 문장에서 설비를 특정하지 못하면 추측하지 않고 확인 필요로 남깁니다
짝짓기 시간창 4시간은 더미 기준입니다. 실제 현장은 교대 주기와 알람 지연에 따라 폭이 달라지므로 도입할 때 보전팀과 함께 다시 맞춰야 하고, 이 조정은 도입 단계 과제로 분리합니다
날짜가 비어 있거나 한 줄에 두 설비가 적힌 행은 짝을 지을 수 없습니다. 추측해서 채우면 틀린 리포트가 되므로 확인 필요로 남기고, 이 목록이 길어지면 도구보다 기록 양식을 먼저 손봐야 한다는 신호로 읽습니다
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
고객사 보전팀이 엑셀로 관리하는 작업자 점검 일지를 그대로 내려받은 표입니다. 날짜 서식 흔들림·설비 표기 별칭·한 줄 두 설비·빈 본문·소계 행을 일부러 섞고, label 에 기대 판정을 심어 자가채점합니다.
| note_id | date_raw | line_raw | equip_raw | writer | body | has_photo | label |
|---|---|---|---|---|---|---|---|
| n_001 | 2026-05-11 08:20 | 1라인 | PRESS-2 | 김보전 | 프레스 2호기 유압 압력이 평소보다 낮아 밸브 조인 뒤 재기동했습니다 | false | matched |
| n_002 | 5/11 | 1라인 | 프레스2호기 | 박정비 | 오후에 같은 설비 압력 경고 다시 떠서 필터 교체함 | false | matched |
| n_003 | 26.05.11 오후 | 1 라인 | cv11 | 이현장 | 컨베이어 벨트 사행 확인해서 텐션 조정했습니다 | false | note_without_alarm |
| n_004 | 2026-05-12 | 2라인 | WELD-05 | 최용접 | 용접 팁 마모가 심해 교체했습니다 | true | matched |
| n_005 | 2026-05-12 | 2라인 | 절단기1호기 / 컴프레서7 | 최용접 | 절단기 날 교체하고 컴프레서 소음도 확인했습니다 | false | split_needed |
아래 Zod 스키마에 맞는 작업자 점검 일지 120행을 JSON 배열로 생성합니다. 설비는 equip_master 의 10대 안에서 고르고, 한 주(월~금) 분량으로 시간이 흩어지게 씁니다.
{"type":"object","properties":{"note_id":{"type":"string"},"date_raw":{"type":"string"},"line_raw":{"type":"string"},"equip_raw":{"type":"string"},"writer":{"type":"string"},"body":{"type":"string"},"has_photo":{"type":"boolean"},"label":{"type":"string","enum":["matched","note_without_alarm","routine","unmapped_equip","undated","split_needed","empty_body","non_data_row"]}},"required":["note_id","date_raw","line_raw","equip_raw","writer","body","has_photo","label"]}
label 규칙: 이상 징후가 적혀 있고 같은 설비 알람이 ±4시간 안에 있으면 matched, 징후는 적혔는데 알람이 없으면 note_without_alarm, '이상 없음' 같은 정기 점검 기록이면 routine, 설비 대장에 없는 이름이면 unmapped_equip, 날짜 칸이 비었으면 undated, 한 칸에 설비가 둘 이상이면 split_needed, 본문이 비었으면 empty_body, 소계·머리글 행이면 non_data_row 입니다.
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: 날짜 표기 흔들림(2026-05-11 · 5/11 · 26.05.11 오후 · 5월 11일) 8건 이상, 같은 설비의 표기 별칭(PRESS-2 · 프레스2호기 · press 2호기, cv11 · 컨베이어11) 10건 이상, 한 칸에 설비 둘을 적은 행 3건, 날짜 빈 행 3건, 본문 빈 행 2건, 시트 중간에 다시 나오는 머리글과 소계 행 4건, 설비 대장에 없는 신규 설비 2건, 존재하지 않는 날짜 1건. 작성자는 5명 안에서 돌리고 문체도 사람마다 다르게 하라. JSON 배열만.{"type":"object","properties":{"note_id":{"type":"string"},"date_raw":{"type":"string"},"line_raw":{"type":"string"},"equip_raw":{"type":"string"},"writer":{"type":"string"},"body":{"type":"string"},"has_photo":{"type":"boolean"},"label":{"type":"string","enum":["matched","note_without_alarm","routine","unmapped_equip","undated","split_needed","empty_body","non_data_row"]}},"required":["note_id","date_raw","line_raw","equip_raw","writer","body","has_photo","label"]}설비 제어반에서 내려받은 알람 로그 CSV 입니다. 점검 일지의 반대편 기록이라 대조 엔진이 시간창으로 짝지을 상대이며, 아무도 일지에 적지 않은 알람과 무시해도 되는 정보성 알람을 함께 담습니다.
| ev_id | ts | equip_id | code | severity | value | cleared_at | label |
|---|---|---|---|---|---|---|---|
| a_001 | 2026-05-11T08:35 | PR-02 | HYD_LOW | warn | 41.2 | 2026-05-11T09:10 | matched |
| a_002 | 2026-05-11T14:05 | PR-02 | HYD_LOW | warn | 39.8 | 2026-05-11T14:40 | matched |
| a_003 | 2026-05-12T09:12 | WD-05 | TIP_WEAR | warn | 0.62 | — | matched |
| a_004 | 2026-05-12T10:40 | CT-01 | BLADE_CHG | info | — | 2026-05-12T10:45 | info_ignored |
| a_005 | 2026-05-12T13:20 | AC-07 | PRS_DROP | fault | 4.1 | 2026-05-12T15:00 | alarm_without_note |
아래 Zod 스키마에 맞는 설비 알람 로그 400행을 JSON 배열로 생성합니다. equip_id 는 equip_master 의 10대만 쓰고, 같은 주(2026-05-11~05-15) 안에서 야간 시간대도 포함해 흩어지게 씁니다.
{"type":"object","properties":{"ev_id":{"type":"string"},"ts":{"type":"string"},"equip_id":{"type":"string"},"code":{"type":"string"},"severity":{"type":"string","enum":["info","warn","fault"]},"value":{"type":["number","null"]},"cleared_at":{"type":["string","null"]},"label":{"type":"string","enum":["matched","alarm_without_note","info_ignored"]}},"required":["ev_id","ts","equip_id","code","severity","value","cleared_at","label"]}
label 규칙: severity 가 info 면 info_ignored, warn·fault 인데 같은 설비 점검 일지가 ±4시간 안에 있으면 matched, 없으면 alarm_without_note 입니다.
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: 같은 설비에서 5분 간격으로 연달아 터진 중복 알람 20건 이상, value 가 null 인 행 15건, cleared_at 이 비어 아직 안 풀린 알람 10건, 자정을 넘겨 이어지는 야간 알람 6건, 일지가 하나도 없는 주말 알람 8건, 같은 code 가 심각도만 다르게 반복되는 행 10건. JSON 배열만.{"type":"object","properties":{"ev_id":{"type":"string"},"ts":{"type":"string"},"equip_id":{"type":"string"},"code":{"type":"string"},"severity":{"type":"string","enum":["info","warn","fault"]},"value":{"type":["number","null"]},"cleared_at":{"type":["string","null"]},"label":{"type":"string","enum":["matched","alarm_without_note","info_ignored"]}},"required":["ev_id","ts","equip_id","code","severity","value","cleared_at","label"]}고객사 설비관리팀이 이미 쓰고 있는 설비 대장을 엑셀로 받은 것입니다. 새 체계를 만드는 게 아니라 받은 대장의 별칭 열을 그대로 써서 일지의 흔들린 표기를 하나로 묶는 데만 씁니다.
| equip_id | line_id | name_official | aliases | manual_doc |
|---|---|---|---|---|
| PR-02 | L1 | 프레스 2호기 | ["PRESS-2","프레스2호기","press 2호기"] | PR-02_보전매뉴얼_v4.pdf |
| PR-03 | L1 | 프레스 3호기 | ["PRESS-3","프레스3호"] | PR-03_보전매뉴얼_v4.pdf |
| CV-11 | L1 | 컨베이어 11 | ["CONV-11","컨베이어11","cv11"] | CV-11_점검표_v2.pdf |
| FL-06 | L1 | 필터 유닛 6 | ["FILT-6","필터6"] | FL-06_점검표_v1.pdf |
| WD-05 | L2 | 용접기 5호 | ["WELD-05","용접기5호기"] | WD-05_보전매뉴얼_v1.pdf |
아래 Zod 스키마에 맞는 고객사 설비 대장 30행을 JSON 배열로 생성합니다. 라인은 L1~L3 셋으로 나누고, 실제 대장처럼 별칭 열이 사람마다 다르게 적혀 있게 씁니다.
{"type":"object","properties":{"equip_id":{"type":"string"},"line_id":{"type":"string"},"name_official":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"manual_doc":{"type":"string"}},"required":["equip_id","line_id","name_official","aliases","manual_doc"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: 영문 코드와 한글 이름이 섞인 별칭 각 2개 이상, 공백·하이픈 유무만 다른 별칭(PRESS-2 · PRESS 2 · press2), 서로 다른 설비인데 별칭이 한 글자만 다른 쌍 3건, 별칭이 아예 없는 설비 4건, manual_doc 파일명이 비어 있는 설비 2건. JSON 배열만.{"type":"object","properties":{"equip_id":{"type":"string"},"line_id":{"type":"string"},"name_official":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"manual_doc":{"type":"string"}},"required":["equip_id","line_id","name_official","aliases","manual_doc"]}| Python | 엑셀·CSV 적재와 설비 표기 정규화, 시간창 대조 규칙, 마크다운 리포트 렌더링을 전부 맡습니다 |
| LLM | 작업자가 자유 문장으로 적은 일지 본문에서 설비와 증상, 조치를 뽑아 고정 스키마로 바꿉니다 |
| RAG | 설비 매뉴얼 PDF에서 어긋난 건에 해당하는 점검 항목을 찾아 리포트에 조항으로 인용합니다 |
| VLM | 일지에 붙은 현장 사진에서 계기판 값을 읽는 일은 3주차 선택 과제로 두고 1주차에는 사진 첨부 여부만 표시합니다 |
| 데이터 파이프라인 | 파일 적재부터 추출·정규화·대조·리포트까지를 한 명령으로 잇고 단계마다 중간 산출물을 파일로 남깁니다 |
| Agent | 추출·정규화·대조·인용을 각각 도구 호출 단계로 나누고 실패한 단계만 다시 실행합니다 |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(매뉴얼 조항 인용과 판정 검증)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(두 번째 라인 이식)로 진행합니다.
주간 대조 리포트에 실리는 항목 한 건입니다. 어느 기록과 어느 기록이 짝이 됐는지, 짝이 없다면 왜 없는지를 원본 행 번호와 시각 차이로 남깁니다. 설비가 위험한지 판단하는 게 아니라 두 기록이 맞는지만 가립니다.
{"type":"object","properties":{"finding_id":{"type":"string"},"equip_id":{"type":["string","null"]},"kind":{"type":"string","enum":["matched","note_without_alarm","alarm_without_note","needs_check"]},"check_reason":{"type":["string","null"],"enum":["unmapped_equip","undated","split_needed","empty_body","non_data_row"]},"note_ref":{"type":["string","null"]},"alarm_ref":{"type":["string","null"]},"gap_min":{"type":["number","null"]},"summary":{"type":"string","minLength":20},"evidence":{"type":"string","minLength":8},"manual_ref":{"type":["string","null"]},"hedge":{"type":["string","null"]}},"required":["finding_id","equip_id","kind","check_reason","note_ref","alarm_ref","gap_min","summary","evidence","manual_ref","hedge"]}[
{
"input_ref": "n_003 (일지에만 있는 건)",
"output": {
"finding_id": "f_003",
"equip_id": "CV-11",
"kind": "note_without_alarm",
"check_reason": null,
"note_ref": "n_003",
"alarm_ref": null,
"gap_min": null,
"summary": "5월 11일 오후 컨베이어 11 벨트 사행으로 텐션을 조정한 기록이 있는데, 같은 설비의 알람은 앞뒤 4시간 안에 없습니다.",
"evidence": "n_003 body='컨베이어 벨트 사행 확인해서 텐션 조정했습니다' / CV-11 알람 0건(±4h)",
"manual_ref": null,
"hedge": "작업자가 알람 전에 먼저 잡았을 수도 있어 조치 시각을 확인해야 합니다"
}
},
{
"input_ref": "a_005 (알람에만 있는 건)",
"output": {
"finding_id": "f_009",
"equip_id": "AC-07",
"kind": "alarm_without_note",
"check_reason": null,
"note_ref": null,
"alarm_ref": "a_005",
"gap_min": null,
"summary": "5월 12일 13시 20분 공압 컴프레서 7 압력 강하 고장 알람이 100분간 떠 있었는데 같은 날 점검 일지가 없습니다.",
"evidence": "a_005 severity=fault, value=4.1, cleared_at=2026-05-12T15:00 / AC-07 일지 0건(당일)",
"manual_ref": null,
"hedge": "같은 설비의 날짜 없는 일지 n_006 이 있어 날짜를 확인하면 짝이 될 수 있습니다"
}
},
{
"input_ref": "n_005 (한 줄에 설비 둘)",
"output": {
"finding_id": "f_012",
"equip_id": null,
"kind": "needs_check",
"check_reason": "split_needed",
"note_ref": "n_005",
"alarm_ref": null,
"gap_min": null,
"summary": "한 칸에 절단기 1호와 공압 컴프레서 7 두 설비가 함께 적혀 있어 어느 조치가 어느 설비 것인지 나눌 수 없습니다.",
"evidence": "n_005 equip_raw='절단기1호기 / 컴프레서7'",
"manual_ref": null,
"hedge": "설비별로 나눠 적어 주시면 다음 주 리포트에서 자동으로 짝이 지어집니다"
}
}
][자동 검증] 1. 스키마 파싱으로 출력 형식(필드·enum)이 맞는지 확인합니다. 2. kind 가 needs_check 일 때만 check_reason 이 차고, matched 일 때는 note_ref·alarm_ref·gap_min 이 모두 채워지는지 강제합니다. 3. evidence 에 적힌 값이 원본 행에 실제로 있는 값인지 토큰 매칭으로 확인하고, 설비 대장에 없는 equip_id 는 절대 채우지 않습니다. 4. kind 를 더미에 심은 label 과 비교해 일치도를 계산하고, 어긋난 건을 사유별로 뽑아 규칙을 고칩니다. [수동 검증] 1. 보전 담당 역할 2명이 리포트를 읽고 어긋난 건 판정에 동의하는지 표시합니다. 2. 확인 필요 목록 전체를 사람이 직접 읽어 추측으로 채운 항목이 없는지 점검합니다.