모두의포트폴리오
PE · FDE 직군을 위한 포트폴리오 밀키트
예전 판입니다 (1판)이 문서는 2026-10-02 에 새 판으로 개정됐습니다. 회사 조사 결과를 반영해 주제를 세탁기 투입 계획에서 호텔 린넨 출고 수량 확인으로 바꿨습니다.최신 판 보기 →
경력라이넨스 · [세탁공장] AX Engineer (풀스택, Forward Deployed)

공장 생산관리 담당자에게 그날 반입된 물량의 세탁기별 투입 계획표를 내주는 웹 도구입니다.

라이넨스 공고에서 뽑은 세 가지 시그널.

라이넨스는 산업용 세탁공장을 직접 운영하며 생산·품질·운송·설비 데이터로 공장 운영의 표준화와 AI 전환을 추진하고, AX Engineer 는 그 공장에 들어가 공장장과 작업자가 경험으로 하던 판단을 구조화합니다. 아침 반입 물량을 어느 세탁기에 어떤 코스로 넣을지는 세탁기 용량과 코스 제한, 병원과 호텔을 섞지 않는 금지 조합, 배송 회차 마감이 한꺼번에 걸리는 판단이라, 이 조건표를 가진 직영 공장을 운영하지 않는 회사에서는 같은 도구가 성립하지 않습니다. 계산 엔진과 공장별 규칙표를 나눠 둔 구조는 한 공장에서 푼 문제를 다른 공장으로 넓히는 멀티사이트 표준화와 곧바로 이어집니다. 다만 이 포트폴리오가 보여주는 것은 현장의 말로 된 판단을 규칙으로 옮겨 결정론적으로 계산하고 LLM 을 규칙 후보 추출 보조로만 가두는 기술이며, 산업용 세탁 공정이나 설비 보전 도메인 전문성은 주장하지 않고 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.

01

현장 판단의 구조화

공장장과 작업자가 경험으로 내리던 판단을 데이터와 시스템의 문제로 다시 세우는 일이 이 직무의 출발점입니다. 머릿속 배분 감각을 세탁기 용량·혼합 금지·회차 마감이라는 규칙표로 꺼내 놓은 이 도구가 그 지점에 직접 붙습니다.

공장장과 작업자가 경험적으로 수행하는 판단과 업무 방식을 구조화합니다반복적인 비효율, 운영 리스크, 병목 구간을 데이터와 시스템의 문제로 재정의합니다직영 세탁공장의 생산, 품질, 수배송, 설비 운영 프로세스를 직접 관찰합니다
02

AX 솔루션 설계와 빠른 구현

현장 문제를 푸는 웹 도구와 자동화 워크플로를 직접 설계하고, LLM 같은 기술을 조합해 빠르게 완결품을 냅니다. 계획 계산은 규칙 엔진이 맡고 LLM 은 공장장 메모를 규칙 후보로 바꾸는 보조만 맡는 이 구성이 그 요구와 맞물립니다.

현장 문제를 해결하기 위한 웹 도구, 대시보드, 자동화 워크플로 및 AI Agent를 직접 설계하고 구현합니다LLM, RAG, Workflow Automation 등 필요한 기술을 조합해 빠르게 MVP를 만듭니다빠르게 프로토타입을 만들고 실제 사용 결과를 바탕으로 개선하는 방식에 익숙한 분
03

멀티사이트 표준화

한 공장에서 푼 문제를 다른 공장에도 적용되게 표준화하고, 공장마다 다른 조건과 공통 구조를 나눠 재사용 가능한 제품으로 키웁니다. 계산 엔진과 공장별 규칙표를 처음부터 분리해 둔 설계가 그 방향을 따릅니다.

한 공장에서 해결한 문제를 다른 공장에도 적용할 수 있도록 표준화합니다공장별로 다른 운영 조건과 공통 구조를 구분해 재사용 가능한 제품으로 발전시킵니다기존 운영 데이터, 문서, 센서 및 외부 시스템을 연결하는 데이터 구조와 인터페이스를 설계합니다

포트폴리오 요약

그날 아침 공장에 반입된 거래처별 수거 로트 목록과 공장 규칙표(세탁기 용량·세탁 코스·혼합 금지 조합·배송 회차 마감)를 입력으로 받아, 거래처와 품목 표기를 규칙표 별칭으로 맞추고 품목과 오염도로 세탁 코스를 확정한 뒤 같은 코스와 같은 회차의 로트를 세탁기 용량 이하로 묶어 투입 계획표를 만들고, 인쇄해 라인에 붙이는 작업지시표와 미배정 로트 목록을 냅니다. 계량이 빠졌거나 대장에 없는 거래처거나 한 로트가 가장 큰 세탁기 용량을 넘는 경우처럼 규칙으로 하나가 정해지지 않으면 배치를 억지로 만들지 않고 사유를 적어 미배정으로 가려냅니다. 세탁기 배정·코스 확정·용량 검사는 전부 규칙 엔진이 결정하고, LLM 은 공장장이 메모로 남긴 문장을 규칙 후보 카드로 바꾸는 보조만 맡으며 그 카드는 원문 구절을 그대로 달고 나와 사람이 승인해야 규칙표에 들어갑니다.

고객 정의

라이넨스 직영 세탁공장의 생산관리 담당자입니다. 매일 아침 반입 전표를 보며 공장장 옆에서 '가운은 따로 돌려야 한다', '이 호텔 건은 1시 차에 실어야 한다' 같은 말을 받아 적어 화이트보드에 배치를 손으로 짜던 사람으로, 공장장이 자리를 비우면 같은 판단을 아무도 재현하지 못하는 게 늘 불안합니다. 오늘 들어온 물량을 넣으면 세탁기별 투입 계획이 계산돼 나오고, 애매한 물량은 왜 못 넣었는지가 같이 보이길 바랍니다.

고민 지점

반입 로트 목록과 공장 규칙표를 함께 넣으면, (a) 거래처·품목 표기 흔들림을 별칭 사전으로 맞추고 계량이 빠진 로트는 품목 단위중량으로 환산해 물량을 세우고, (b) 품목과 오염도로 세탁 코스를 확정한 뒤 같은 코스·같은 회차 로트를 세탁기 용량 이하로 묶어 투입 계획표를 만들며, (c) 규칙으로 하나가 정해지지 않는 로트는 추측하지 않고 사유를 적어 미배정으로 가려냅니다.

주차별 일정

1주차여기까지로 완성

반입 물량과 규칙표를 넣으면 세탁기별 투입 계획표가 나옵니다

그날 반입 로트 엑셀과 공장 규칙표를 올리면 거래처·품목 표기를 맞추고 세탁 코스를 확정해 세탁기별 배치 계획과 적재율을 화면에 띄우고, 라인에 붙이는 작업지시표와 미배정 로트 목록을 파일로 내려받는 웹 도구입니다. 여기에 공장장 메모 문장을 규칙 후보 카드로 바꿔 사람이 승인하면 규칙표에 반영되는 화면을 포함합니다. 데이터는 반입 전표를 받았다고 가정한 합성 로트와 규칙표로 시작하며, 설비 가동 로그 연동과 세탁물 사진 판독은 3주차 과제로 둡니다.

  1. 1일 · 반입 전표와 공장 규칙 자료 구조 세우기거래처·품목·오염도·회차가 어떤 모양으로 적혀 오는지 훑고 로트 스키마와 규칙표 스키마를 정합니다
  2. 2일 · 표기 흔들림 맞추고 물량 세우기거래처·품목 별칭 사전으로 코드를 맞추고 계량이 빠진 로트는 품목 단위중량으로 환산하며 후보가 하나로 안 정해지면 미배정으로 회수합니다
  3. 3-4일 · 세탁 코스 확정과 배치 묶기 엔진품목과 오염도로 코스를 정하고 같은 코스·같은 회차 로트를 세탁기 용량 이하로 묶으며 금지 조합과 용량 초과를 검사합니다
  4. 5일 · 계획표 화면과 작업지시표 산출세탁기별 배치와 적재율을 화면에 띄우고 라인에 붙이는 작업지시표와 미배정 목록을 파일로 냅니다
  5. 6일 · 공장장 메모를 규칙 후보 카드로메모 문장에서 대상 품목·조건·금지 조합을 뽑아 원문 인용을 단 카드로 보여 주고 승인한 것만 규칙표에 넣습니다
  6. 7일 · 심은 정답과 비교한 기준선 + 화면 녹화여기까지가 1주차 완성품입니다
2주차선택 성장

계획이 공장장 판단과 맞았는지 확인합니다

같은 날 물량을 두고 공장장 역할 검수자 2명이 손으로 짠 배치와 도구가 낸 배치를 맞대어 세탁기 배정 일치율과 제약 위반 건수를 재고, 어긋난 로트를 사유 유형별로 묶어 규칙표를 보강한 결과를 리포트로 냅니다.

  1. 8-9일 · 공장장 역할 검수자 2명이 같은 날 물량을 손으로 배치도구가 낸 배치와 맞대어 세탁기 배정 일치율과 제약 위반 건수를 재고 배치 판단 가이드를 만듭니다
  2. 10-11일 · 어긋난 로트를 사유 유형별로 묶어 규칙 보강일치도 측정(Cohen's κ: 두 사람 판단이 우연 이상으로 겹치는 정도, 0~1) + 별칭 누락·회차 경계 사례별 규칙 보강
  3. 12일 · 규칙 후보 카드 자동 검사카드의 인용 구절이 메모 원문에 그대로 있는지 대조 + 기존 규칙과 중복인지 검사 + 5% 사람 점검
3주차선택 성장

두 번째 공장과 설비 실적으로 넓힙니다

규칙표만 갈아끼워 두 번째 공장 프로필로 같은 계획을 돌리고, 세탁기 가동 로그를 실적으로 받아 계획 대비 실제 투입 시각과 적재율의 차이를 회차별로 대조하는 화면을 붙입니다.

  1. 15-17일 · 두 번째 공장 프로필로 같은 계획 돌리기세탁기 사양과 회차 시각만 갈아끼워 계산 엔진을 그대로 쓰고 공장별로 갈리는 부분을 규칙표 쪽으로 밀어냅니다
  2. 18-21일 · 설비 가동 로그로 계획 대비 실적 대조 + 실제 도입 계획세탁기 가동 시작·종료 기록을 받아 회차별 투입 시각과 적재율 차이를 보여 주고, 실 반입 전표와 실 공장장 검수로 갈아끼우는 계획을 포함합니다

데모 · 측정 지표

01

반입 로트 60건과 공장 규칙표를 올리면 세탁기 4대 기준 배치 계획과 적재율이 몇 초 안에 화면에 뜨고, 작업지시표와 미배정 목록이 파일로 떨어지는 걸 시연합니다

02

일부러 만든 지저분한 입력 30종(계량 누락·미등록 거래처·한 칸에 품목 둘·가장 큰 세탁기 용량을 넘는 단일 로트·이미 지난 회차·오염도 미기재)을 넣어도 출력 형식이 한 번도 안 깨지고, 용량 상한과 금지 조합과 회차 마감을 어기는 배치는 한 건도 만들지 않으며 정할 수 없는 로트는 사유를 적어 미배정으로 가려냅니다

03

더미 로트 120건 중 거래처·품목·세탁 코스 확정이 심은 정답과 모두 일치한 게 104건(약 87%)이고, 만들어진 배치의 제약 위반은 0건이며 평균 적재율은 82%입니다. 단, 로트와 규칙표와 정답을 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건에서의 동작임을 명시합니다

정직 경계선

진짜 성능 검증은 여기서 멈춥니다. 위 수치는 전부 작성자가 만든 더미 반입 전표와 규칙표 자가채점이며, 실제 배치 정확도는 라이넨스 직영 공장의 실 반입 전표와 실 세탁기 사양, 공장장 검수가 있어야 측정 가능합니다. 이 도구는 그 검증을 규칙표만 갈아끼워 바로 돌릴 수 있는 상태로 만듭니다

미리 알아둬야 할 것들

이건 실제 공장 데이터 없이 혼자 만든 포트폴리오입니다. 모든 수치는 합성 반입 전표와 규칙표 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명하는 편이 신뢰를 얻습니다

이 포트폴리오가 보여주는 것은 현장의 말로 된 판단을 규칙표로 꺼내 결정론적 계산 엔진으로 옮기고, LLM 을 규칙 후보 추출 보조로만 가둔 설계입니다. 산업용 세탁 공정 자체의 전문성, 세탁기 제어와 설비 보전, 세탁물 오염 판독 같은 깊이는 이 포트폴리오로 증명되지 않으므로 주장하지 않으며, 모르는 부분은 면접에서 모른다고 말하는 편이 낫습니다

정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 계량 누락, 미등록 거래처, 한 칸에 적힌 품목 둘, 가장 큰 세탁기 용량을 넘는 단일 로트, 이미 지난 회차, 오염도 미기재 같은 케이스를 더미에 일부러 섞어 깨끗한 전표만 통과시키는 게 아님을 보여줍니다

별칭 매칭은 표기가 조금만 달라도 놓치고 반대로 엉뚱한 거래처를 걸 위험이 있습니다. 후보가 0건이면 미배정으로 돌리고 2건 이상이면 하나를 고르지 않고 후보를 사유에 적어 내보내며, 무엇을 더 등록해야 하는지가 미배정 목록에 그대로 드러나게 둡니다

배치 묶기는 용량을 채우는 방향으로 계산하지만 공장장은 세탁기 고장 이력이나 그날 인력 배치처럼 전표에 없는 사정을 함께 봅니다. 계획을 확정으로 밀지 않고 화면에서 손으로 옮길 수 있게 두며, 실제 도입 때는 설비 가동 로그와 실 검수자 판단을 붙이는 것을 도입 단계 과제로 분리합니다

더미 데이터

① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.

intake_lotsTABLE· 15 rows

그날 아침 공장에 반입된 거래처별 수거 로트를 전표에서 읽은 원시 데이터입니다. 계획 엔진이 가장 먼저 다루는 입력이라 계량 누락, 거래처 표기 흔들림, 한 칸에 적힌 품목 둘, 지난 회차 표기를 일부러 섞고 gold_ 필드로 정답을 심어 자가채점합니다.

② intake_lots.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 15)
lot_noreceived_atclient_rawitem_rawsoil_rawweight_kgpiece_countdue_run_rawmemogold_client_idgold_item_codegold_programgold_weight_kggold_statusgold_reason
1012026-08-05T06:40그랜드호텔시트보통38.5962회차—CL-GRHITM-SHTP-WHT38.5planned—
1022026-08-05T06:42그랜드 호텔 서울타월보통221402회차—CL-GRHITM-TWLP-WHT22planned—
1032026-08-05T06:55중앙병원환자 가운—31883회차3층 병동분입니다CL-JAHITM-GWNP-INF31planned—
1042026-08-05T07:02중앙병원침대 시트—26.4703회차—CL-JAHITM-SHT—26.4needs_check오염도 칸이 비어 있어 일반 코스와 감염성 코스 중 하나를 정하지 못…
1052026-08-05T07:10GH-SEOUL베개커버낮음—2102회차계량기 점검 중이라 장수만 셌습니다CL-GRHITM-PWCP-WHT25.2planned—
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 JSON Schema 에 맞는 세탁공장 반입 로트 120건을 JSON 배열로 생성합니다. 거래처는 호텔 2~3곳, 병원 1~2곳, 공장 1곳으로 두고 품목은 시트·타월·베개커버·환자 가운·수술포·작업복을 섞습니다.

{"type":"object","properties":{"lot_no":{"type":"integer"},"received_at":{"type":"string"},"client_raw":{"type":["string","null"]},"item_raw":{"type":["string","null"]},"soil_raw":{"type":["string","null"]},"weight_kg":{"type":["number","null"]},"piece_count":{"type":["integer","null"]},"due_run_raw":{"type":["string","null"]},"memo":{"type":["string","null"]},"gold_client_id":{"type":["string","null"]},"gold_item_code":{"type":["string","null"]},"gold_program":{"type":["string","null"]},"gold_weight_kg":{"type":["number","null"]},"gold_status":{"enum":["planned","needs_check"]},"gold_reason":{"type":["string","null"]}},"required":["lot_no","received_at","client_raw","item_raw","due_run_raw","gold_status"]}

gold 규칙(위에서부터 먼저 맞는 것을 적용): (1) client_raw 가 plant_rules 의 client 항목 aliases 에 정확히 하나 걸리면 그 code, 0건이거나 2건 이상이면 gold_client_id=null 이고 gold_status=needs_check. (2) item_raw 도 같은 방식으로 매칭하되 후보가 0건이거나 2건 이상이면 gold_item_code=null·gold_program=null 이고 needs_check. (3) gold_weight_kg 는 weight_kg 이 있으면 그 값, 없으면 piece_count × 품목 단위중량을 소수 첫째 자리까지 계산하고, 둘 다 null 이면 gold_weight_kg=null 이고 needs_check. (4) 중량과 장수가 모두 0 이면 needs_check. (5) gold_program 은 품목이 ITM-GWN·ITM-SRG 면 오염도와 무관하게 P-INF, 품목이 ITM-UNF 면 P-OIL, 그 밖의 품목은 soil_raw 가 '높음' 이면 P-STN, '낮음'·'보통' 이면 P-WHT, soil_raw 가 null 이면 코스를 정하지 못해 null 이고 needs_check. (6) due_run_raw 가 규칙표의 run 항목에 없거나 그 회차 출발 시각이 received_at 보다 앞서면 needs_check. (7) gold_weight_kg 가 가장 큰 세탁기 용량을 넘으면 needs_check. (8) 미확정 사유가 하나도 없으면 gold_status=planned 이고 gold_reason=null, 있으면 그 사유를 한 문장으로 gold_reason 에 적습니다.

쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(깨끗한 전표만 통과시키는 함정 회피): (1) 같은 거래처의 표기 별칭('그랜드호텔'·'그랜드 호텔 서울'·'GH-SEOUL')이 고르게 섞인 로트 12건 이상, (2) weight_kg 이 null 이고 piece_count 만 있는 로트 10건과 둘 다 null 인 로트 3건, (3) 별칭 사전에 없는 신규 거래처 3건과 사전에 없는 품목 3건, (4) 한 칸에 품목 두 개가 적힌 로트 2건, (5) 오염도 칸이 빈 로트 8건(그중 절반은 가운·수술포라 코스가 확정되고 절반은 needs_check), (6) 가장 큰 세탁기 용량을 넘는 단일 로트 2건과 중량·장수가 0 인 휴무 로트 2건, (7) 이미 지난 회차를 적어 온 로트 3건. gold_ 필드는 위 규칙대로 정직하게 채웁니다. JSON 배열만.
schema (3 층의 단일 출처)
{"type":"object","properties":{"lot_no":{"type":"integer"},"received_at":{"type":"string"},"client_raw":{"type":["string","null"]},"item_raw":{"type":["string","null"]},"soil_raw":{"type":["string","null"]},"weight_kg":{"type":["number","null"]},"piece_count":{"type":["integer","null"]},"due_run_raw":{"type":["string","null"]},"memo":{"type":["string","null"]},"gold_client_id":{"type":["string","null"]},"gold_item_code":{"type":["string","null"]},"gold_program":{"type":["string","null"]},"gold_weight_kg":{"type":["number","null"]},"gold_status":{"enum":["planned","needs_check"]},"gold_reason":{"type":["string","null"]}},"required":["lot_no","received_at","client_raw","item_raw","due_run_raw","gold_status"]}
plant_rulesTABLE· 23 rows

공장장이 머릿속과 메모로 지켜 온 배분 규칙을 한 표로 꺼내 놓은 공장 규칙표입니다. 거래처·품목 별칭, 세탁기 사양, 세탁 코스 조건, 같은 배치에 넣으면 안 되는 조합, 배송 회차 출발 시각을 담아 계획 결과를 규칙으로 확정하는 유일한 근거가 됩니다. 새 표준을 제정하지 않고 공장이 이미 쓰는 표기와 회차를 그대로 받습니다.

② plant_rules.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 23)
entry_kindcodelabelaliasescapacity_kgunit_weight_kgapplies_tobanned_withdepart_atsource_memoapproved_by
clientCL-GRH그랜드호텔 서울["그랜드호텔","그랜드 호텔 서울","GH-SEOUL","그랜드"]——————공장장
clientCL-JAH중앙병원["중앙병원","중앙 병원","JAH"]——————공장장
clientCL-HBH한빛호텔["한빛호텔","한빛"]—————별칭이 아직 두 개뿐이라 전표에 다르게 적혀 오면 놓칩니다공장장
clientCL-WSG우성기공["우성기공","우성 기공","WSG"]——————공장장
itemITM-SHT시트["시트","침대 시트","베드시트"]—0.4————생산관리
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 JSON Schema 에 맞는 세탁공장 규칙표 항목 40개를 JSON 배열로 생성합니다. 거래처(client)·품목(item)·세탁기(machine)·세탁 코스(program)·혼합 금지(mix_ban)·배송 회차(run) 항목을 고르게 섞습니다.

{"type":"object","properties":{"entry_kind":{"enum":["client","item","machine","program","mix_ban","run"]},"code":{"type":"string"},"label":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"capacity_kg":{"type":["number","null"]},"unit_weight_kg":{"type":["number","null"]},"applies_to":{"type":["array","null"],"items":{"type":"string"}},"banned_with":{"type":["array","null"],"items":{"type":"string"}},"depart_at":{"type":["string","null"]},"source_memo":{"type":["string","null"]},"approved_by":{"type":["string","null"]}},"required":["entry_kind","code","label","aliases"]}

코드 규칙: 거래처는 CL- 접두, 품목은 ITM- 접두, 세탁기는 용량과 일련 기호를 붙인 W-80A 형식, 코스는 P- 접두, 혼합 금지는 MB- 접두, 회차는 R 과 번호를 씁니다. capacity_kg 는 machine 에만, unit_weight_kg 는 item 에만, depart_at 은 run 에만 채우고 나머지는 null 로 둡니다. aliases 에는 전표에 실제로 적혀 오는 한글 표기와 영문 약칭을 함께 넣어 intake_lots 의 client_raw·item_raw 가 여기서 매칭되게 맞춥니다.

쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(규칙표가 완전하다는 착각 회피): (1) 별칭이 하나뿐이라 전표 표기를 못 잡는 거래처 2건과 품목 2건, (2) 한 품목의 별칭이 다른 품목 별칭의 부분 문자열인 쌍('가운'과 '환자 가운') 1쌍, (3) 코스가 같아도 함께 돌리면 안 되는 조합 3건을 source_memo 에 공장장 말투 그대로 적기, (4) 특정 코스만 받는 전용 세탁기 2대와 여러 코스를 받는 범용 세탁기 2대, (5) 회차 출발 시각이 두 시간밖에 안 벌어져 물량이 몰리는 회차 1건, (6) approved_by 가 null 이라 아직 승인되지 않은 규칙 후보 3건. JSON 배열만.
schema (3 층의 단일 출처)
{"type":"object","properties":{"entry_kind":{"enum":["client","item","machine","program","mix_ban","run"]},"code":{"type":"string"},"label":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"capacity_kg":{"type":["number","null"]},"unit_weight_kg":{"type":["number","null"]},"applies_to":{"type":["array","null"],"items":{"type":"string"}},"banned_with":{"type":["array","null"],"items":{"type":"string"}},"depart_at":{"type":["string","null"]},"source_memo":{"type":["string","null"]},"approved_by":{"type":["string","null"]}},"required":["entry_kind","code","label","aliases"]}

기술 상세 · 아키텍처·운영·출력 스키마

기술 스택 매핑
Python로트 정규화, 세탁 코스 확정과 용량·혼합 금지 검사, 배치 묶기 계산과 작업지시표 생성을 맡는 대표 언어입니다
TypeScript반입 물량 업로드, 배치 계획표와 미배정 목록, 규칙 후보 승인 화면을 만드는 웹 도구의 언어입니다
SQL로트·규칙표·배치 결과를 저장하고 회차별 적재율과 미배정 사유 분포를 집계하는 질의 계층입니다
API계획 계산을 웹 화면과 분리해 호출하는 경계이자, 공장 운영 시스템이 반입 물량을 밀어 넣을 수 있게 열어 두는 입력구입니다
데이터베이스공장별 규칙표를 버전으로 남겨 어느 날 어떤 규칙으로 계획이 나왔는지 되짚을 수 있게 하는 저장 계층입니다
클라우드공장 사무실 PC 와 현장 태블릿에서 같은 화면을 열 수 있게 웹 도구를 올려 두는 실행 환경입니다
LLM공장장이 남긴 메모 문장을 규칙 후보 카드로 바꾸는 보조 모델입니다(규칙 확정은 사람 승인과 규칙 엔진이 합니다)
RAG규칙표가 수백 항목으로 늘면 전부 프롬프트에 넣을 수 없어, 메모 문장과 가까운 기존 규칙 항목만 찾아 넣어 중복 규칙을 걸러내는 검색 계층입니다
Workflow Automation반입 전표 업로드부터 계획 계산, 작업지시표 배포까지를 아침 한 번의 실행으로 잇는 자동화 흐름입니다
MES공장 실행 시스템이 남기는 세탁기 가동 시작·종료 기록을 계획 대비 실적 대조의 입력으로 받는 연동 지점입니다(3주차)
IoT세탁기·건조기의 가동 로그를 회차별 실적으로 끌어와 계획한 투입 시각과 벌어진 차이를 보여 주는 설비 데이터원입니다(3주차)
컴퓨터 비전반입 전표를 사진으로만 받는 날을 대비해 촬영본에서 표를 읽어 같은 로트 스키마로 옮기는 문서 판독 어댑터입니다(3주차 확장 수단)
LLM 선택
model
Claude Sonnet (공장장 메모를 규칙 후보 카드로 변환) + GPT-4o-mini (후보 카드가 원문 구절을 그대로 인용했는지, 기존 규칙과 겹치는지 검사)
prompt
few-shot 4 예시 + 규칙 후보 스키마(대상 품목·조건·금지 조합·회차) 강제 + 메모 원문 substring 인용 강제 + 규칙표에 직접 쓰지 못하게 막고 후보 상태로만 반환하는 가드 + 후행 judge
rationale
세탁 코스도 세탁기 배정도 규칙표의 용량·혼합 금지·회차 마감이 결정하므로, 모델이 문장을 잘못 읽어도 계획 자체가 흔들리지 않습니다. 메모 문장에서 조건을 뽑아내는 품질에는 Sonnet 을 쓰고, 인용이 원문에 실제로 있는지와 기존 규칙과 중복인지 확인하는 후행 검사는 비용과 속도를 우선해 mini 를 씁니다. 규칙표가 수백 항목으로 늘어난 공장에서는 후보와 가까운 기존 규칙만 찾아 넣어 비교합니다.
결정 게이트
1주차 끝반입 로트 엑셀과 규칙표를 올리면 세탁기별 배치 계획과 적재율이 화면에 뜨고 작업지시표가 파일로 떨어지며, 용량 초과나 금지 조합 배치가 한 건도 만들어지지 않고 애매한 로트가 사유를 달고 미배정으로 갈립니까? 여기까지가 그 자체로 제출 가능한 완성품입니다.

✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(공장장 판단과 맞았는지 확인)로 진행합니다.

2주차 끝검수자 2명이 손으로 짠 배치와 견준 세탁기 배정 일치율이 붙고, 어긋난 로트가 사유 유형별로 정리돼 규칙표 보강으로 이어집니까?

✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(두 번째 공장 프로필과 설비 실적 대조)로 진행합니다.

재사용 레이어 · 코어 70% / 도메인 30%
core (재사용 가능)
  • 지저분한 반입 전표 로더(빈 칸 상속·소계 행·단위 혼재 정리)
  • 별칭 사전 기반 거래처·품목 매칭기(후보가 0건이거나 2건 이상이면 미배정으로 회수)
  • 용량 상한과 금지 조합을 검사하며 묶는 배치 계산 엔진
  • 규칙 후보 카드 생성과 원문 인용 대조 가드
  • 계획표·작업지시표·미배정 목록 산출과 적재율 집계 화면
  • 규칙표 버전 기록과 같은 입력에 같은 계획이 나오는지 확인하는 회귀 검증
domain (교체 대상)
  • 공장별 세탁기 사양과 세탁 코스 목록
  • 거래처 별칭 사전과 품목 단위중량표
  • 배송 회차 시각과 혼합 금지 조합
  • 세탁 코스 enum 과 미배정 사유 enum 은 공장·업종별로 갈아끼웁니다
출력 스키마 · wash_batch_plan

투입 계획표의 한 행입니다. 같은 코스와 같은 회차의 로트를 세탁기 용량 이하로 묶은 배치 하나를 담고, 어떤 규칙을 적용해 그렇게 묶였는지 근거를 함께 답니다. 규칙으로 배치가 정해지지 않은 로트는 machine_code 를 비운 채 사유를 달아 미배정 목록으로 나갑니다.

schema (JSON Schema)
{"type":"object","properties":{"batch_no":{"type":["integer","null"]},"machine_code":{"type":["string","null"]},"program_code":{"type":["string","null"]},"lot_nos":{"type":"array","items":{"type":"integer"}},"total_weight_kg":{"type":["number","null"]},"fill_rate":{"type":["number","null"]},"depart_run":{"type":["string","null"]},"status":{"enum":["planned","needs_check"]},"reason":{"type":["string","null"]},"evidence":{"type":"array","items":{"type":"object","properties":{"rule_code":{"type":"string"},"quote":{"type":"string"}},"required":["rule_code","quote"]}},"hedge":{"type":["string","null"]}},"required":["lot_nos","machine_code","program_code","status","evidence"]}
모범 출력 (5)
[
  {
    "input_ref": "lot 101·102·105 (그랜드호텔 백색 린넨, 2회차)",
    "output": {
      "batch_no": 1,
      "machine_code": "W-50B",
      "program_code": "P-WHT",
      "lot_nos": [
        101,
        102,
        105
      ],
      "total_weight_kg": 85.7,
      "fill_rate": null,
      "depart_run": "R2",
      "status": "needs_check",
      "reason": "묶은 중량 85.7kg 이 W-50B 용량 50kg 을 넘어 한 배치로 만들지 못했습니다. 회차를 나누거나 대형기 배정을 사람이 정해야 합니다",
      "evidence": [
        {
          "rule_code": "W-50B",
          "quote": "50kg 중형 워셔"
        },
        {
          "rule_code": "P-WHT",
          "quote": "백색 표준 코스"
        }
      ],
      "hedge": "합성 로트 기준이라 실제 반입량 분포에서는 나뉘는 지점이 달라집니다"
    }
  },
  {
    "input_ref": "lot 101·102 (그랜드호텔 백색 린넨, 2회차)",
    "output": {
      "batch_no": 2,
      "machine_code": "W-50B",
      "program_code": "P-WHT",
      "lot_nos": [
        101,
        102
      ],
      "total_weight_kg": 60.5,
      "fill_rate": null,
      "depart_run": "R2",
      "status": "needs_check",
      "reason": "묶은 중량 60.5kg 이 W-50B 용량 50kg 을 넘어 시트 로트를 대형기로 옮겨야 합니다",
      "evidence": [
        {
          "rule_code": "W-50B",
          "quote": "50kg 중형 워셔"
        }
      ],
      "hedge": null
    }
  },
  {
    "input_ref": "lot 102·105 (그랜드호텔 타월·베개커버, 2회차)",
    "output": {
      "batch_no": 3,
      "machine_code": "W-50B",
      "program_code": "P-WHT",
      "lot_nos": [
        102,
        105
      ],
      "total_weight_kg": 47.2,
      "fill_rate": 0.94,
      "depart_run": "R2",
      "status": "planned",
      "reason": null,
      "evidence": [
        {
          "rule_code": "P-WHT",
          "quote": "백색 표준 코스"
        },
        {
          "rule_code": "R2",
          "quote": "2회차 배송"
        },
        {
          "rule_code": "ITM-PWC",
          "quote": "베개커버"
        }
      ],
      "hedge": "lot 105 중량은 장수 210 에 베개커버 단위중량 0.12kg 을 곱해 세운 합성 기준 환산값입니다"
    }
  },
  {
    "input_ref": "lot 103·115 (중앙병원 가운, 3회차)",
    "output": {
      "batch_no": 4,
      "machine_code": "W-50C",
      "program_code": "P-INF",
      "lot_nos": [
        103,
        115
      ],
      "total_weight_kg": 55.8,
      "fill_rate": null,
      "depart_run": "R3",
      "status": "needs_check",
      "reason": "감염성 전용기 W-50C 용량 50kg 을 5.8kg 넘겨 두 번 돌릴지 순서를 사람이 정해야 합니다",
      "evidence": [
        {
          "rule_code": "P-INF",
          "quote": "병원 가운과 수술포는 오염도가 어떻게 적혀 있든 이 코스입니다"
        },
        {
          "rule_code": "W-50C",
          "quote": "병원 물량은 이 기계에서만 돌립니다"
        },
        {
          "rule_code": "MB-01",
          "quote": "병원 건은 코스가 같아도 호텔 시트랑 절대 같이 돌리지 마세요"
        }
      ],
      "hedge": null
    }
  },
  {
    "input_ref": "lot 106 (별칭 사전에 없는 신규 거래처)",
    "output": {
      "batch_no": null,
      "machine_code": null,
      "program_code": "P-INF",
      "lot_nos": [
        106
      ],
      "total_weight_kg": 18,
      "fill_rate": null,
      "depart_run": "R3",
      "status": "needs_check",
      "reason": "거래처 별칭 사전에 '행복요양원' 이 없어 혼합 금지 조합을 판단하지 못했습니다",
      "evidence": [
        {
          "rule_code": "P-INF",
          "quote": "감염성 고온 코스"
        }
      ],
      "hedge": "요양원 물량이 병원과 같은 취급인지는 공장장 확인이 필요합니다"
    }
  }
]
검증 노트 (자동 vs 수동)

[자동 검증] 1. 출력 형식(필드와 enum)이 JSON Schema 를 통과하는지 확인합니다. 2. status 가 planned 인 배치의 total_weight_kg 이 machine_code 의 capacity_kg 이하인지 재계산해 대조하고, 넘으면 계획으로 내보내지 못하게 막습니다. 3. 한 배치의 로트들이 mix_ban 항목의 금지 조합에 걸리지 않는지, 같은 program_code 와 같은 depart_run 인지 검사합니다. 4. machine_code 의 applies_to 에 그 program_code 가 들어 있는지 확인합니다. 5. evidence 의 rule_code 가 규칙표에 실제로 있는 코드인지, quote 가 그 항목의 label 이나 source_memo 의 substring 인지 대조합니다. 6. status 가 needs_check 인 행은 reason 이 비어 있지 않은지 강제하고, gold_ 필드와 견줘 거래처·품목·코스 확정 일치율을 계산합니다. [수동 검증] 1. 공장장 역할 검수자 2명이 같은 날 물량을 각자 손으로 배치해 세탁기 배정 일치율과 bootstrap Cohen's κ(두 사람 판단이 우연 이상으로 겹치는 정도, 0~1) 하한 0.6 이상을 봅니다. 2. 계획 배치의 5% 를 사람이 직접 훑어 현장에서 실제로 돌릴 수 있는 묶음인지 확인합니다.