대산이노텍
경력근거: IoT 데이터, AI 기술, 그리고 고도화된 웹 기술을 융합하여 현장의 문제를 해결
※ 실제 산출물이 아닌 AI 예측 시안입니다.
공고는 IoT 데이터와 AI 기술과 웹 기술을 묶어 현장 문제를 푼다고 적고, 실시간 스트리밍과 시계열 데이터 모델링, 이상 징후 탐지와 알림을 한 사람의 업무로 나열합니다. 이 포트폴리오는 그 순서를 그대로 씁니다. 계측값을 시계열로 담고 기준 비교로 구간을 뽑아 현장 화면에 올립니다. 다만 이 포트폴리오는 시계열 판정 규칙과 화면 구현을 보여줍니다. 축산 사양 관리나 환기 설비 제어에 대한 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
공고는 실시간 데이터 스트리밍과 시각화, 대용량 시계열 데이터베이스 모델링, 현장 친화적 화면 구현을 한 자리의 업무로 묶습니다. 수집과 표시가 나뉘지 않아 데이터 모양을 정하는 판단이 그대로 화면 품질이 됩니다.
단순 모니터링을 넘어 스스로 판단하고 행동하는 AI 에이전트 기능을 서비스 전반에 적용하고, 이상 징후 탐지와 알림을 담당한다고 적혀 있습니다. 모델을 연구하는 자리가 아니라 판단 결과를 제품 흐름에 붙이는 자리입니다.
24시간 중단 없이 운영되어야 하는 서비스의 인프라를 맡고 장애 대응까지 업무로 둡니다. 값이 빠지거나 튀는 상황에서도 화면이 살아 있어야 한다는 요구가 설계 조건입니다.
축사 관리자가 하루치 계측 파일을 올리면, 온도와 습도와 암모니아 농도를 함께 읽어 환기가 필요한 구간을 골라 보여줍니다. 어느 구간이 문제인지는 기준값 비교 규칙이 정하고, 모델은 그 구간에서 어떤 계측값이 기준을 얼마나 넘었는지를 관리자가 읽을 한 줄로 요약합니다.
저는 돈사 세 동을 관리합니다. 환기 팬은 온도만 보고 도는데, 습도가 높고 암모니아가 올라오는 날은 온도가 낮아도 안이 답답합니다. 관제 화면에는 값이 흐르지만 어느 동을 먼저 봐야 하는지는 결국 감으로 정합니다.
관리자가 놓치는 이유는 값이 안 보여서가 아니라 값 하나로는 판단이 서지 않기 때문입니다. 온도와 습도와 암모니아를 함께 보고 기준을 넘은 구간을 이유별로 모아 주면, 오늘 어느 동부터 볼지가 정해집니다.
축사 관리자가 쓰는 화면 하나가 완결됩니다. 하루치 계측 파일을 올리면 기준을 넘은 구간을 동별로 모으고, 판정 근거가 된 값을 같이 보여줍니다. 실제 센서를 붙이는 일은 파일 업로드로 대신하고 3주차로 미룹니다.
관리자가 실제로 환기를 돌린 기록 90건과 규칙의 판정을 맞춰 보고, 놓친 구간과 과하게 잡은 구간을 나눠 표로 냅니다. 기준값은 그 결과를 보고 동별로 조정합니다.
계측기가 값을 직접 보내오게 붙이고, 기준을 넘은 구간이 생기면 관리자 휴대폰으로 알립니다. 파일을 올리지 않아도 순회 순서가 정해집니다.
축사 관리자가 하루치 계측 파일을 올리면 환기가 필요한 구간이 동별로 모이고, 판정 근거 값이 같이 보입니다.
센서 값이 빠지거나 물리적으로 불가능한 값이 튀거나 등록되지 않은 동 코드가 섞인 입력 30종을 올려도 화면이 죽지 않고, 계산에서 뺀 값이 표시로 남습니다.
관리자 조치 기록 90건으로 판정 일치율을 냅니다. 단, 정답과 데이터를 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
위 수치는 더미데이터 자가채점이며 실제 판정 정확도는 대산이노텍의 실 계측 데이터와 현장 조치 기록이 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태로 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 센서 결측·측정 한계 극단값·등록되지 않은 동 코드를 더미에 일부러 섞어 쉬운 문제만 푸는 함정을 피합니다.
값이 기준을 넘었다는 사실이 곧 환기가 필요하다는 뜻은 아닙니다. 사료 급이 직후나 분뇨 처리 중에도 수치가 오르므로 판정을 결론으로 읽지 않게 근거 값을 항상 같이 보여줍니다.
실제 도입에서는 동마다 사육 두수와 환기 설비 용량이 달라 기준값이 하나로 서지 않습니다. 동별 설정이 늘어나면 규칙을 코드에서 빼 설정으로 옮겨야 하며, 그것은 도입 단계 과제로 분리합니다.
환기 팬을 실제로 돌리는 제어는 설비 연동과 안전 책임이 걸려 있어 이 포트폴리오의 범위 밖입니다. 여기서는 사람이 볼 판단 근거를 내는 데까지만 다룹니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
돈사 세 동에서 10분 간격으로 올라온 계측값입니다. 판정의 입력이며 센서 결측과 측정 한계 극단값, 등록되지 않은 동 코드를 의도적으로 포함합니다.
| reading_no | measured_at | barn_code_raw | temp_c | humidity_pct | nh3_ppm | co2_ppm | fan_state | sensor_flag |
|---|---|---|---|---|---|---|---|---|
| RD-0818-001 | 2026-08-18T05:00:00 | A동 | 24.1 | 62 | 8.4 | 1,450 | low | — |
| RD-0818-002 | 2026-08-18T05:10:00 | A동 | 24.4 | 63.5 | 9.1 | 1,520 | low | — |
| RD-0818-003 | 2026-08-18T05:20:00 | A동 | 25 | 71.2 | 26.5 | 2,380 | low | — |
| RD-0818-004 | 2026-08-18T05:30:00 | A동 | 25.3 | 73 | 28.9 | 2,510 | low | — |
| RD-0818-005 | 2026-08-18T05:40:00 | B동 | 31.6 | 84 | 14.2 | 1,980 | high | — |
아래 JSON Schema 에 맞는 축사 계측 행을 더 만들어 주세요. {"type":"object","properties":{"reading_no":{"type":"string"},"measured_at":{"type":"string"},"barn_code_raw":{"type":"string"},"temp_c":{"type":["number","null"]},"humidity_pct":{"type":["number","null"]},"nh3_ppm":{"type":["number","null"]},"co2_ppm":{"type":["integer","null"]},"fan_state":{"type":"string","enum":["off","low","high","unknown"]},"sensor_flag":{"type":["string","null"]}},"required":["reading_no","measured_at","barn_code_raw","fan_state"]} 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) 계측값이 모두 null 인 통신 두절 행, (2) 온도 87도나 습도 100% 처럼 물리적으로 불가능한 극단 행, (3) 기준값 설정에 없는 barn_code_raw, (4) 10분 간격이 끊겨 시각이 건너뛴 행. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"reading_no":{"type":"string"},"measured_at":{"type":"string"},"barn_code_raw":{"type":"string"},"temp_c":{"type":["number","null"]},"humidity_pct":{"type":["number","null"]},"nh3_ppm":{"type":["number","null"]},"co2_ppm":{"type":["integer","null"]},"fan_state":{"type":"string","enum":["off","low","high","unknown"]},"sensor_flag":{"type":["string","null"]}},"required":["reading_no","measured_at","barn_code_raw","fan_state"]}| JavaScript | 관리자 화면의 언어입니다. 동별 구간 목록과 계측 그래프를 한 화면에 둡니다. |
| Python | 판정 규칙과 계측 적재를 맡습니다. 온도·습도·암모니아를 함께 읽어 구간을 뽑는 규칙이 여기 있습니다. |
| API | 계측기가 값을 보내는 접수 창구입니다. 3주차에 파일 업로드 대신 이 경로로 받습니다. |
| Docker | 화면과 판정 러너를 컨테이너로 묶어 현장 서버에서 같은 구성으로 띄웁니다. |
| CI/CD | 판정 규칙을 고칠 때마다 평가 러너를 돌려 결과가 나빠지지 않았는지 확인한 뒤 배포합니다. |
| LLM | 구간 판정이 끝난 뒤 온도·습도·암모니아 가운데 기준을 넘은 값이 무엇인지 한 줄로 요약합니다. 구간은 규칙이 정합니다. |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 판정이 관리자의 실제 조치와 같았는지 맞춰 보는 단계로 넘어갑니다.
✓ pass → 여기까지도 완결입니다. 더 키우려면 계측기 값을 직접 받아 기준 초과를 알리는 단계로 확장합니다.
위 예측 UI 는 3주차까지 완주했을 때의 화면입니다. 1주차에 실제로 만드는 것은 아래 표시된 화면 하나입니다.
advice_code사유 라벨 · reading_no + 한 줄 요약(근거 수치 포함)화면·코드·면접에서 이 단어를 그대로 씁니다. 키는 출력 스키마의 enum 과 같습니다.
ok조치 불필요nh3_high암모니아 초과heat_humid고온다습sensor_untrusted센서 확인barn_unmapped기준 미설정한 구간에 대한 환기 판단입니다. 판정 코드와 근거가 된 계측값을 함께 남깁니다.
{"type":"object","properties":{"advice_id":{"type":"string"},"reading_no":{"type":"string"},"barn_code":{"type":"string"},"advice_code":{"type":"string","enum":["ok","nh3_high","heat_humid","sensor_untrusted","barn_unmapped"]},"evidence":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"agg":{"type":["string","null"]},"value":{"type":["string","number","null"]}},"required":["field","value"]}},"summary":{"type":"string"},"hedge":{"type":["string","null"]}},"required":["advice_id","reading_no","barn_code","advice_code","evidence","summary"]}[
{
"advice_id": "ad_0001",
"reading_no": "RD-0818-001",
"barn_code": "A동",
"advice_code": "ok",
"evidence": [
{
"field": "temp_c",
"agg": null,
"value": 24.1
},
{
"field": "nh3_ppm",
"agg": null,
"value": 8.4
}
],
"summary": "온도와 암모니아가 모두 기준 안이라 조치가 필요하지 않습니다.",
"hedge": null
},
{
"advice_id": "ad_0002",
"reading_no": "RD-0818-010",
"barn_code": "C동",
"advice_code": "ok",
"evidence": [
{
"field": "temp_c",
"agg": null,
"value": 19.2
},
{
"field": "humidity_pct",
"agg": null,
"value": 54
}
],
"summary": "온도와 습도가 낮게 유지되고 있어 그대로 두어도 됩니다.",
"hedge": null
},
{
"advice_id": "ad_0003",
"reading_no": "RD-0818-003",
"barn_code": "A동",
"advice_code": "nh3_high",
"evidence": [
{
"field": "nh3_ppm",
"agg": null,
"value": 26.5
},
{
"field": "fan_state",
"agg": null,
"value": "low"
}
],
"summary": "암모니아가 기준 25ppm 을 넘었는데 팬이 약하게 돌고 있어 환기를 올려야 합니다.",
"hedge": null
},
{
"advice_id": "ad_0004",
"reading_no": "RD-0818-013",
"barn_code": "A동",
"advice_code": "nh3_high",
"evidence": [
{
"field": "nh3_ppm",
"agg": null,
"value": 31.2
},
{
"field": "reading_no",
"agg": "count",
"value": 3
}
],
"summary": "같은 동에서 암모니아 초과 구간이 세 번 이어져 순회 순서를 앞으로 당겨야 합니다.",
"hedge": null
},
{
"advice_id": "ad_0005",
"reading_no": "RD-0818-006",
"barn_code": "B동",
"advice_code": "heat_humid",
"evidence": [
{
"field": "temp_c",
"agg": null,
"value": 32.2
},
{
"field": "humidity_pct",
"agg": null,
"value": 86.5
}
],
"summary": "고온에 습도까지 높아 팬을 최대로 돌려도 체감이 떨어지지 않는 구간입니다.",
"hedge": "합성 기준 판정이라 실제 체감은 사육 두수와 바닥 상태에 따라 달라집니다."
},
{
"advice_id": "ad_0006",
"reading_no": "RD-0818-007",
"barn_code": "B동",
"advice_code": "sensor_untrusted",
"evidence": [
{
"field": "sensor_flag",
"agg": null,
"value": "통신 두절"
},
{
"field": "temp_c",
"agg": null,
"value": null
}
],
"summary": "값이 통째로 비어 있어 판단하지 않고 센서 확인 대상으로 남깁니다.",
"hedge": null
},
{
"advice_id": "ad_0007",
"reading_no": "RD-0818-011",
"barn_code": "C동",
"advice_code": "sensor_untrusted",
"evidence": [
{
"field": "temp_c",
"agg": null,
"value": 87
},
{
"field": "co2_ppm",
"agg": null,
"value": 0
}
],
"summary": "온도가 87도로 찍히고 이산화탄소가 0 이라 계측 자체를 믿지 않고 뺍니다.",
"hedge": null
},
{
"advice_id": "ad_0008",
"reading_no": "RD-0818-012",
"barn_code": "D동",
"advice_code": "barn_unmapped",
"evidence": [
{
"field": "barn_code_raw",
"agg": null,
"value": "D동"
},
{
"field": "sensor_flag",
"agg": null,
"value": "미등록 동"
}
],
"summary": "기준값 설정에 없는 동이라 비교할 기준이 없어 판단을 미룹니다.",
"hedge": null
}
][자동 검증 · 코드가 판정합니다] 1. advice_code 가 enum 다섯 값 중 하나인지 확인합니다. 2. advice_id·reading_no·barn_code·advice_code·evidence·summary 가 모두 채워졌는지 확인합니다. 3. humidity_pct 가 0 이상 100 이하이고 temp_c 가 영하 20도에서 45도 사이인지 확인합니다. 벗어나면 계산에서 빼고 센서 확인 대상으로 돌립니다. 4. evidence 의 field 이름이 계측 데이터에 실재하는 컬럼인지 대조합니다. 5. agg 가 없는 evidence 의 value 가 그 reading_no 행의 값과 같은지 확인합니다. 6. sensor_flag 가 채워져 있으면 advice_code 는 ok 가 아닌지 확인합니다. 계측에는 sensor_flag 가 빈 정상 행과 채워진 이상 행이 모두 있습니다. 7. summary 가 존댓말로 끝나는지 확인합니다. [평가 러너 · 2주차] 관리자가 실제로 환기를 올린 기록 90건과 규칙의 advice_code 를 비교해 놓친 구간과 과하게 잡은 구간을 나눠 냅니다. [수동 검증 · 사람이 봅니다] 1. 고온다습과 암모니아 초과가 겹친 구간을 어느 쪽으로 묶을지 표본 20건을 눈으로 확인합니다. 2. 사료 급이 직후처럼 수치가 일시적으로 오르는 시간대를 판정에서 뺄지는 현장 관례를 따라 관리자가 정합니다.