아이펠스
경력근거: Web/App(AOS/iOS) 기반 로봇 제어 관제 서비스의 A to Z 실행 담당
※ 실제 산출물이 아닌 AI 예측 시안입니다.
공고는 미들웨어와 로봇 플랫폼 설계에 더해 웹과 앱 기반 관제 서비스를 처음부터 끝까지 맡는 자리라고 적고, AI 가 만든 코드를 그대로 쓰지 않고 구조를 직접 제어하라고 못박습니다. 이 포트폴리오는 관제 쪽의 가장 작은 완결 조각을 골랐습니다. 로봇이 남기는 구간 기록을 판정 규칙으로 옮기고 화면 하나로 냅니다. 다만 이 포트폴리오는 구간 판정 규칙과 화면 구현을 보여줍니다. 로봇 제어나 제조 공정 설계에 대한 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
미들웨어와 로봇 플랫폼 기획·설계에 더해 웹과 앱 기반 로봇 제어 관제 서비스의 처음부터 끝까지를 담당한다고 주요업무에 적습니다. 화면과 제어 규칙이 한 사람 안에 있습니다.
AI 가 생성한 코드를 단순히 복사하지 않고 전체 구조를 이해하고 정교하게 제어·리뷰하는 업무라고 못박습니다. 만드는 속도와 코드를 책임지는 일이 함께 요구됩니다.
실제 첨단 제조 환경을 혁신하는 미들웨어와 로봇 플랫폼을 만들고 있다고 회사 소개에 적습니다. 사무실 데이터가 아니라 현장 장비가 남기는 기록을 다루는 자리입니다.
관제 담당자가 하루치 작업 기록을 열면, 작업 하나를 이동·대기·집기·투입 네 구간으로 나눠 각 구간이 표준 시간보다 얼마나 걸렸는지 보여줍니다. 늦었다는 판정은 구간별 표준 시간과 비교하는 규칙이 정하고, 모델은 어느 구간에서 얼마나 밀렸는지를 관제 담당자가 읽는 한 줄 설명으로 씁니다.
저는 공장 로봇 관제를 맡고 있습니다. 하루 작업이 밀리면 로봇이 느린 건지 앞 공정이 안 끝나 대기한 건지 알아야 하는데, 관제 화면에는 작업 시작과 종료만 남습니다. 결국 현장에 내려가 눈으로 보고 원인을 짐작합니다.
지연 원인을 못 찾는 이유는 기록이 없어서가 아니라 작업 전체 시간 하나로만 남기 때문입니다. 구간별 소요를 표준 시간과 견줘 늦은 자리만 짚어 주면, 로봇 문제와 공정 대기가 화면에서 갈립니다.
관제 담당자가 쓰는 화면 하나가 완결됩니다. 작업별 구간 기록을 표준 시간과 견줘 늦은 구간을 사유와 같이 보여주고, 판정 근거가 된 값을 같이 냅니다. 로봇에서 직접 받아 오는 연결은 기록 파일 업로드로 대신하고 3주차로 미룹니다.
지난 작업 200건의 구간 분포로 표준 시간을 다시 잡고, 새 기준으로 판정이 어떻게 달라지는지 이전 기준과 나란히 놓습니다.
로봇 미들웨어가 구간 기록을 보내오게 붙이고, 같은 구간이 연속으로 늦으면 담당자에게 알립니다. 아침에 목록을 여는 대신 알림으로 먼저 봅니다.
관제 담당자가 하루치 기록을 열면 구간별 소요가 표준 시간과 견줘지고, 늦은 구간이 근거 값과 같이 보입니다.
구간 기록이 빠지거나 순서가 뒤바뀌거나 등록되지 않은 설비 코드가 섞인 입력 30종을 올려도 화면이 죽지 않고, 판정할 수 없는 작업은 미판정으로 남습니다.
작업 200건의 구간 분포로 표준 시간을 다시 잡고 판정이 얼마나 달라지는지 냅니다. 단, 정답과 데이터를 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
위 수치는 더미데이터 자가채점이며 실제 지연 원인 적중률은 아이펠스의 실 로봇 기록이 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태로 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 구간 결측·순서 뒤바뀜·등록되지 않은 설비 코드를 더미에 일부러 섞어 쉬운 문제만 푸는 함정을 피합니다.
구간이 늦었다는 사실이 곧 로봇 문제를 뜻하지는 않습니다. 앞 공정이 밀려 대기가 길어져도 같은 자리에서 늦어 보이므로 판정을 결론으로 읽지 않게 근거 값을 항상 같이 보여줍니다.
실제 도입에서는 설비와 품목마다 표준 시간이 달라 기준이 하나로 서지 않습니다. 기준이 늘어나면 규칙을 코드에서 빼 설정으로 옮겨야 하며, 그것은 도입 단계 과제로 분리합니다.
로봇을 멈추거나 경로를 바꾸는 제어는 안전 책임이 걸려 있어 이 포트폴리오의 범위 밖입니다. 여기서는 사람이 볼 판단 근거를 내는 데까지만 다룹니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
로봇이 남긴 작업별 구간 기록입니다. 판정의 입력이며 구간 결측과 순서 누락, 등록되지 않은 설비 코드를 의도적으로 포함합니다. 표준 시간은 담기지 않아 설비별 기준표와 맞춰야 판정이 섭니다.
| stage_no | task_no | robot_code_raw | stage | seq | started_at | elapsed_sec | result | note |
|---|---|---|---|---|---|---|---|---|
| SG-0001 | TK-4101 | AMR-01 | move | 1 | 2026-08-18T08:00:00 | 42 | done | — |
| SG-0002 | TK-4101 | AMR-01 | wait | 2 | 2026-08-18T08:00:42 | 180 | done | 앞 공정 지연 |
| SG-0003 | TK-4101 | AMR-01 | pick | 3 | 2026-08-18T08:03:42 | 18 | done | — |
| SG-0004 | TK-4101 | AMR-01 | load | 4 | 2026-08-18T08:04:00 | 25 | done | — |
| SG-0005 | TK-4102 | AMR-02 | move | 1 | 2026-08-18T09:10:00 | 128 | done | 우회 경로 |
아래 JSON Schema 에 맞는 로봇 구간 기록 행을 더 만들어 주세요. {"type":"object","properties":{"stage_no":{"type":"string"},"task_no":{"type":"string"},"robot_code_raw":{"type":"string"},"stage":{"type":"string","enum":["move","wait","pick","load"]},"seq":{"type":["integer","null"]},"started_at":{"type":"string"},"elapsed_sec":{"type":["number","null"]},"result":{"type":"string","enum":["done","aborted","unknown"]},"note":{"type":["string","null"]}},"required":["stage_no","task_no","robot_code_raw","stage","started_at","result"]} 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) elapsed_sec 가 null 인 중단 행, (2) elapsed_sec 가 0 이거나 표준의 스무 배가 넘는 극단 행, (3) seq 가 null 이거나 뒤 구간이 먼저 기록된 행, (4) robot_code_raw 의 구분자와 대소문자가 흔들려 기준표에 없는 행. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"stage_no":{"type":"string"},"task_no":{"type":"string"},"robot_code_raw":{"type":"string"},"stage":{"type":"string","enum":["move","wait","pick","load"]},"seq":{"type":["integer","null"]},"started_at":{"type":"string"},"elapsed_sec":{"type":["number","null"]},"result":{"type":"string","enum":["done","aborted","unknown"]},"note":{"type":["string","null"]}},"required":["stage_no","task_no","robot_code_raw","stage","started_at","result"]}설비별 구간 표준 시간표입니다. 판정의 기준이며 아직 정해지지 않은 표준(null)과 기준표에 없는 설비를 포함합니다.
| standard_no | robot_code | stage | std_sec | line | updated_on |
|---|---|---|---|---|---|
| ST-001 | AMR-01 | move | 45 | A라인 | 2026-06-01 |
| ST-002 | AMR-01 | wait | 30 | A라인 | 2026-06-01 |
| ST-003 | AMR-01 | pick | 20 | A라인 | 2026-06-01 |
| ST-004 | AMR-01 | load | 25 | A라인 | 2026-06-01 |
| ST-005 | AMR-02 | move | 45 | A라인 | 2026-06-01 |
아래 JSON Schema 에 맞는 표준 시간표 행을 더 만들어 주세요. {"type":"object","properties":{"standard_no":{"type":"string"},"robot_code":{"type":"string"},"stage":{"type":"string","enum":["move","wait","pick","load"]},"std_sec":{"type":["number","null"]},"line":{"type":"string"},"updated_on":{"type":"string"}},"required":["standard_no","robot_code","stage","line","updated_on"]} 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) std_sec 가 null 인 미정 표준, (2) 같은 설비의 같은 구간이 라인별로 다른 행, (3) 구간 기록에 없는 robot_code, (4) 갱신일이 1년 넘게 지난 행. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"standard_no":{"type":"string"},"robot_code":{"type":"string"},"stage":{"type":"string","enum":["move","wait","pick","load"]},"std_sec":{"type":["number","null"]},"line":{"type":"string"},"updated_on":{"type":"string"}},"required":["standard_no","robot_code","stage","line","updated_on"]}| TypeScript | 판정 규칙과 화면을 함께 쓰는 언어입니다. 구간 비교 규칙을 한 곳에 두고 러너와 화면이 같은 코드를 씁니다. |
| React | 관제 담당자가 보는 화면입니다. 작업별 구간 막대와 근거 값을 한 화면에 둡니다. |
| Node.js | 기록 접수와 판정 실행을 맡는 백엔드입니다. |
| PostgreSQL | 작업과 구간 기록을 담습니다. 작업 번호와 구간 순서를 분리한 스키마가 판정의 정확도를 좌우합니다. |
| ROS | 3주차에 로봇 미들웨어가 구간 기록을 보내는 형식을 그대로 받습니다. |
| LLM | 구간 판정이 끝난 뒤 어느 구간이 얼마나 밀렸는지 한 줄 설명을 붙입니다. 늦었는지는 표준 시간 비교가 정하고 모델은 그 값을 건드리지 못합니다. |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 표준 시간을 지난 실적으로 다시 잡는 단계로 넘어갑니다.
✓ pass → 여기까지도 완결입니다. 더 키우려면 로봇이 기록을 보내오고 연속 지연을 알리는 단계로 확장합니다.
위 예측 UI 는 3주차까지 완주했을 때의 화면입니다. 1주차에 실제로 만드는 것은 아래 표시된 화면 하나입니다.
delay_code사유 라벨 · task_no + 한 줄 요약(근거 수치 포함)화면·코드·면접에서 이 단어를 그대로 씁니다. 키는 출력 스키마의 enum 과 같습니다.
on_time표준 이내wait_long대기 지연move_slow이동 지연stage_aborted구간 중단record_missing기록 결측robot_unmapped설비 미매핑구간 한 건의 지연 판정입니다. 판정 코드와 실제 소요, 그리고 기준표에서 가져온 표준 시간을 함께 남깁니다.
{"type":"object","properties":{"delay_id":{"type":"string"},"stage_no":{"type":"string"},"task_no":{"type":"string"},"delay_code":{"type":"string","enum":["on_time","wait_long","move_slow","stage_aborted","record_missing","robot_unmapped"]},"delay_sec":{"type":["number","null"]},"evidence":{"type":"array","items":{"type":"object","properties":{"source":{"type":["string","null"],"enum":["stage","standard",null]},"field":{"type":"string"},"agg":{"type":["string","null"]},"value":{"type":["string","number","null"]}},"required":["field","value"]}},"summary":{"type":"string"},"hedge":{"type":["string","null"]}},"required":["delay_id","stage_no","task_no","delay_code","evidence","summary"]}[
{
"delay_id": "dl_0001",
"stage_no": "SG-0001",
"task_no": "TK-4101",
"delay_code": "on_time",
"delay_sec": null,
"evidence": [
{
"field": "elapsed_sec",
"agg": null,
"value": 42
},
{
"field": "std_sec",
"agg": null,
"value": 45,
"source": "standard"
}
],
"summary": "이동 구간이 표준 시간 안에 끝났습니다.",
"hedge": null
},
{
"delay_id": "dl_0002",
"stage_no": "SG-0004",
"task_no": "TK-4101",
"delay_code": "on_time",
"delay_sec": null,
"evidence": [
{
"field": "elapsed_sec",
"agg": null,
"value": 25
},
{
"field": "std_sec",
"agg": null,
"value": 25,
"source": "standard"
}
],
"summary": "투입 구간이 표준 시간과 같게 끝났습니다.",
"hedge": null
},
{
"delay_id": "dl_0003",
"stage_no": "SG-0002",
"task_no": "TK-4101",
"delay_code": "wait_long",
"delay_sec": 150,
"evidence": [
{
"field": "elapsed_sec",
"agg": null,
"value": 180
},
{
"field": "std_sec",
"agg": null,
"value": 30,
"source": "standard"
}
],
"summary": "대기가 표준보다 150초 길어 앞 공정 쪽을 확인해야 합니다.",
"hedge": null
},
{
"delay_id": "dl_0004",
"stage_no": "SG-0005",
"task_no": "TK-4102",
"delay_code": "move_slow",
"delay_sec": 83,
"evidence": [
{
"field": "elapsed_sec",
"agg": null,
"value": 128
},
{
"field": "std_sec",
"agg": null,
"value": 45,
"source": "standard"
}
],
"summary": "이동이 표준보다 83초 길어 경로를 확인해야 합니다.",
"hedge": "합성 기준 판정이라 통로에 사람이 있어 감속한 경우일 수 있습니다."
},
{
"delay_id": "dl_0005",
"stage_no": "SG-0007",
"task_no": "TK-4103",
"delay_code": "stage_aborted",
"delay_sec": null,
"evidence": [
{
"field": "result",
"agg": null,
"value": "aborted"
},
{
"field": "elapsed_sec",
"agg": null,
"value": null
}
],
"summary": "집기가 중단돼 소요를 재지 못했고 작업 자체가 끝나지 않았습니다.",
"hedge": null
},
{
"delay_id": "dl_0006",
"stage_no": "SG-0012",
"task_no": "TK-4106",
"delay_code": "record_missing",
"delay_sec": null,
"evidence": [
{
"field": "seq",
"agg": null,
"value": null
},
{
"field": "result",
"agg": null,
"value": "unknown"
}
],
"summary": "구간 순서와 결과가 없어 610초가 실제 소요인지 확인하지 못합니다.",
"hedge": null
},
{
"delay_id": "dl_0007",
"stage_no": "SG-0009",
"task_no": "TK-4104",
"delay_code": "robot_unmapped",
"delay_sec": null,
"evidence": [
{
"field": "robot_code_raw",
"agg": null,
"value": "amr 04"
},
{
"field": "std_sec",
"agg": null,
"value": null,
"source": "standard"
}
],
"summary": "설비 목록에 없는 코드라 표준 시간을 잡지 못해 판정을 미룹니다.",
"hedge": null
},
{
"delay_id": "dl_0008",
"stage_no": "SG-0010",
"task_no": "TK-4105",
"delay_code": "on_time",
"delay_sec": null,
"evidence": [
{
"field": "elapsed_sec",
"agg": null,
"value": 0
},
{
"field": "std_sec",
"agg": null,
"value": 30,
"source": "standard"
}
],
"summary": "대기 없이 바로 다음 구간으로 넘어가 지연이 없습니다.",
"hedge": null
}
][자동 검증 · 코드가 판정합니다] 1. delay_code 가 enum 여섯 값 중 하나인지 확인합니다. 2. delay_id·stage_no·task_no·delay_code·evidence·summary 가 모두 채워졌는지 확인합니다. 3. elapsed_sec 와 std_sec 가 0 이상인지 확인합니다. 4. evidence 의 field 이름이 구간 기록 또는 표준 시간표에 실재하는 컬럼인지 대조합니다. std_sec 는 입력이 아니라 기준표에서 옵니다. 5. agg 가 없는 evidence 의 value 가 그 stage_no 행의 값과 같은지 확인합니다. 6. delay_sec 이 evidence 의 실제 소요와 표준 시간의 차이와 같은지 다시 계산합니다. 둘 중 하나가 비면 delay_sec 도 null 인지 확인합니다. 7. summary 가 존댓말로 끝나는지 확인합니다. [평가 러너 · 2주차] 작업 200건의 구간 분포로 표준 시간을 다시 잡고, 새 기준에서 판정이 바뀐 구간을 이전 기준과 비교해 냅니다. [수동 검증 · 사람이 봅니다] 1. 대기가 긴 구간이 앞 공정 때문인지 로봇 때문인지 표본 20건을 현장 기록과 눈으로 확인합니다. 2. 중단된 작업을 지연 통계에 넣을지 뺄지는 운영 기준을 따라 담당자가 정합니다.