업스테이지
경력근거: 顧客企業の業務・組織・社内システムを深く理解し、解決すべき課題を明確化する。
※ 실제 산출물이 아닌 AI 예측 시안입니다.
공고가 이 자리의 일로 '顧客企業の業務・組織・社内システムを深く理解し、解決すべき課題を明確化する' 와 '顧客の業務プロセスを再設計' 를 적었습니다. 문서 처리에서 그 재설계의 첫 결정이 어느 문서를 자동으로 넘기고 어느 문서를 사람에게 남길지이고, 이 포트폴리오는 그 결정을 규칙표와 단가로 옮깁니다. 회사 소개가 '煩雑な文書処理の自動化・効率化を推進する' 와 'コストを削減すること' 를 나란히 적은 것도, 경로마다 단가를 달리 두고 비용을 함께 내는 이 설계와 맞습니다. 이 포트폴리오가 보여주는 것은 처리 경로를 데이터로 두고 문서와 맞춰 배정과 비용을 내는 기술이며, 문자 인식 모델 자체를 만드는 능력이나 일본 회계·법무 도메인 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
'顧客の業務プロセスを再設計し'. 어느 문서를 어디로 보낼지 정하는 일이 그 재설계의 첫 결정입니다.
'煩雑な文書処理の自動化・効率化を推進する'. 자동화 대상과 사람이 볼 대상을 가르는 층입니다.
'コストを削減することで'. 경로마다 단가가 달라 배정이 곧 비용입니다.
받은 문서를 문자 인식만으로 끝낼지, 모델 추출까지 돌릴지, 사람이 직접 읽을지 정합니다. 서식별 경로 규칙에 최소 스캔 품질과 장수 상한, 페이지 단가를 두고 문서 목록과 맞춰 경로를 배정하고, 배정된 경로의 단가로 예상 비용을 함께 냅니다. 품질 점수가 빈 문서는 배정하지 않고 근거가 없다고 표시하며, 장수가 상한을 넘거나 규칙에 없는 서식은 각각 초과·미선언으로 남겨 사람이 먼저 정하게 합니다. 문서 목록은 실 고객 문서 대신 지원자가 공개 서식으로 만든 것을 가정합니다.
일본 고객사에 문서 처리 자동화를 넣는 자리에 앉는 FDE 입니다. 어떤 문서까지 모델에 넣어도 되는지 물으면 매번 표본을 몇 장 열어 보고 감으로 답하다가, 도입 뒤 청구서를 받고 나서야 비용을 다시 세던 사람입니다.
서식마다 최소 품질과 장수 상한, 페이지 단가를 규칙으로 두고 문서 목록과 맞추면, 문서마다 갈 경로와 드는 비용이 도입 전에 나온다는 가정입니다. 규칙에 없는 서식은 미선언으로 빠지므로 처리 방식을 아직 정하지 않은 문서 종류가 그대로 드러납니다.
문서 목록과 경로 규칙을 받아 문서마다 경로를 배정하고 예상 비용을 계산하며, 배정하지 못한 문서는 품질 부족·장수 초과·서식 미선언 중 어느 쪽인지 붙여 서식별로 묶은 배정 리포트를 터미널과 Markdown 파일로 내는 CLI 가 도는 완결품입니다.
공개 서식으로 만든 문서 400건에 손으로 붙인 정답 경로와 대조해 일치율을 내고, 미선언이 몰리는 서식을 모아 규칙이 없는 문서 종류를 목록으로 냅니다.
최소 품질과 장수 상한을 조금씩 바꿔 가며 경로별 문서 수와 합계 비용이 어떻게 달라지는지 표로 내고, 사람 확인이 몰리는 서식을 짚어 내는 단계입니다.
FDE 가 문서 목록과 경로 규칙을 넣으면 문서마다 갈 경로와 예상 비용이 서식별로 묶여 나오는 과정을 시연합니다.
공개 서식으로 만든 문서 400건과 손으로 붙인 정답 경로를 대조해 일치율을 냅니다. 단, 정답과 문서 목록을 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
품질이 비었거나 서식 표기가 흔들리거나 규칙에 없는 서식이 섞인 입력 30종을 넣어도 출력 형식이 안 깨지고 사유별로 빠지는 비율을 보여줍니다.
최소 품질과 장수 상한을 바꿨을 때 경로별 문서 수와 합계 비용이 어떻게 움직이는지 회귀로 확인합니다.
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 작성자가 만든 문서 목록의 자가채점이며, 실제 배정 정확도와 절감액은 업스테이지 고객사의 실 문서와 실 단가가 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아니므로, 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 붙였으니 잘 맞는 게 당연하므로, 품질 결측과 상한 초과, 규칙에 없는 서식을 일부러 섞어 쉬운 문서만 푸는 함정을 피합니다.
이 포트폴리오가 보여주는 것은 처리 경로를 데이터로 두고 문서와 맞춰 배정과 비용을 내는 기술이며, 문자 인식 모델 자체를 만드는 능력이나 일본 회계·법무 도메인 전문성은 주장하지 않습니다. 배정은 임계 비교와 곱셈이 하고 LLM 은 담당자가 읽을 사유 문장만 맡습니다.
스캔 품질 점수는 사전 판별기가 내는 값이라, 그 점수가 흔들리면 배정도 흔들립니다. 그래서 점수를 판정에 함께 실어 담당자가 보게 둡니다.
실제 도입 때는 고객사마다 서식과 단가가 다르므로, 규칙표를 새로 채우는 일을 도입 단계 과제로 둡니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
고객사에서 받은 문서 목록입니다. 문서번호와 서식 표기, 언어 표기, 장수, 스캔 품질 점수, 표 포함 여부, 손글씨 포함 여부, 접수일을 한 행에 둡니다. 언어 표기는 보내는 쪽 설정에 따라 'ja'와 'JA'처럼 흔들립니다. 품질이나 장수가 빈 행, 상한을 넘는 장수, 규칙에 없는 서식을 일부러 섞어 두어 사유가 갈리게 둡니다.
| doc_no | form_raw | lang_raw | page_count | scan_score | has_table | has_handwriting | received_at |
|---|---|---|---|---|---|---|---|
| DC-3001 | 請求書 | ja | 2 | 0.94 | true | false | 2026-08-18 |
| DC-3002 | 請求書 | JA | 1 | 0.88 | true | false | 2026-08-18 |
| DC-3003 | 見積書 | ja | 3 | 0.61 | true | true | 2026-08-19 |
| DC-3004 | 見積書 | en | 2 | 0.91 | false | false | 2026-08-19 |
| DC-3005 | 契約書 | ja | 48 | 0.9 | false | false | 2026-08-20 |
아래 JSON Schema 를 그대로 만족하는 문서 행을 400개 더 만들어 주세요. 서식을 청구서·견적서·계약서·신청서·납품서로 섞고 언어 표기는 몇 행에서 대문자로 둡니다. 스캔 품질은 0.3 에서 0.99 사이로 흩어 놓고, 2할은 장수나 품질을 비우며, 몇 행은 40장이 넘는 문서와 규칙에 없는 서식을 넣으세요. 배정 결과나 비용은 넣지 마세요.
{"type": "object", "properties": {"doc_no": {"type": "string"}, "form_raw": {"type": "string"}, "lang_raw": {"type": "string"}, "page_count": {"type": ["integer", "null"]}, "scan_score": {"type": ["number", "null"]}, "has_table": {"type": "boolean"}, "has_handwriting": {"type": "boolean"}, "received_at": {"type": "string"}}, "required": ["doc_no", "form_raw", "lang_raw", "page_count", "scan_score", "has_table", "has_handwriting", "received_at"]}{"type": "object", "properties": {"doc_no": {"type": "string"}, "form_raw": {"type": "string"}, "lang_raw": {"type": "string"}, "page_count": {"type": ["integer", "null"]}, "scan_score": {"type": ["number", "null"]}, "has_table": {"type": "boolean"}, "has_handwriting": {"type": "boolean"}, "received_at": {"type": "string"}}, "required": ["doc_no", "form_raw", "lang_raw", "page_count", "scan_score", "has_table", "has_handwriting", "received_at"]}서식별 처리 경로 규칙표입니다. 규칙 번호와 서식, 경로 이름, 최소 스캔 품질, 장수 상한, 표 필요 여부, 페이지 단가, 담당을 한 행에 둡니다. 한 서식에 경로가 여럿 있고 최소 품질이 달라, 품질이 떨어지면 단가가 비싼 경로로 내려갑니다. 문서 목록에 나오는 서식 중 일부는 일부러 넣지 않아 미선언이 도출되게 둡니다.
| policy_no | form_raw | route_name | min_scan_score | max_pages | needs_table | yen_per_page | owner_name |
|---|---|---|---|---|---|---|---|
| RP-201 | 請求書 | ocr_only | 0.85 | 5 | true | 3 | 経理 |
| RP-202 | 請求書 | human_review | 0 | 5 | — | 180 | 経理 |
| RP-203 | 見積書 | llm_extract | 0.8 | 10 | — | 12 | 営業 |
| RP-204 | 見積書 | human_review | 0 | 10 | — | 180 | 営業 |
| RP-205 | 契約書 | llm_extract | 0.85 | 20 | — | 12 | 法務 |
아래 JSON Schema 를 그대로 만족하는 경로 규칙 행을 30개 더 만들어 주세요. 한 서식에 경로를 둘 이상 두고 최소 품질을 다르게 정하며, 문자 인식은 페이지당 3엔대, 모델 추출은 12엔대, 사람 확인은 180엔대로 단가를 둡니다. 문서 목록에 나오는 서식 중 일부는 일부러 넣지 마세요 — 미선언이 있어야 규칙표의 구멍이 드러납니다. 배정 결과는 넣지 마세요.
{"type": "object", "properties": {"policy_no": {"type": "string"}, "form_raw": {"type": "string"}, "route_name": {"type": "string", "enum": ["ocr_only", "llm_extract", "human_review"]}, "min_scan_score": {"type": "number"}, "max_pages": {"type": "integer"}, "needs_table": {"type": ["boolean", "null"]}, "yen_per_page": {"type": "number"}, "owner_name": {"type": "string"}}, "required": ["policy_no", "form_raw", "route_name", "min_scan_score", "max_pages", "yen_per_page", "owner_name"]}{"type": "object", "properties": {"policy_no": {"type": "string"}, "form_raw": {"type": "string"}, "route_name": {"type": "string", "enum": ["ocr_only", "llm_extract", "human_review"]}, "min_scan_score": {"type": "number"}, "max_pages": {"type": "integer"}, "needs_table": {"type": ["boolean", "null"]}, "yen_per_page": {"type": "number"}, "owner_name": {"type": "string"}}, "required": ["policy_no", "form_raw", "route_name", "min_scan_score", "max_pages", "yen_per_page", "owner_name"]}| Python | 문서 목록과 경로 규칙을 맞춰 품질·장수를 견주고 비용을 계산하는 배정기를 맡습니다. |
| PyTorch | 스캔 품질 점수를 내는 사전 판별기를 붙일 자리로 둡니다. 배정 판단 자체는 규칙이 합니다. |
| AWS | 2주차부터 문서 목록과 배정 결과를 객체 저장소에 두고 배치로 돌립니다. |
| Markdown | 서식별로 묶은 배정 리포트와 비용 표를 파일로 냅니다. |
✗ fail → 미선언이 절반을 넘으면 규칙표를 먼저 채웁니다.
✓ pass → 2주차 정답 대조로 넘어갑니다.
✗ fail → 어긋난 서식을 모아 최소 품질과 상한을 다시 봅니다.
✓ pass → 3주차 비용 민감도 표로 넘어갑니다.
문서 하나마다 갈 경로와 예상 비용을 정합니다. 배정하지 못하면 품질 부족·장수 초과·서식 미선언 중 어느 쪽인지 싣습니다. 화면과 리포트는 이 경로 코드로 묶습니다.
{"type": "object", "properties": {"assign_no": {"type": "string"}, "doc_no": {"type": "string"}, "form_raw": {"type": "string"}, "policy_no": {"type": ["string", "null"]}, "route_code": {"type": "string", "enum": ["ocr_only", "llm_extract", "human_review", "quality_too_low", "oversize", "form_undeclared"]}, "est_cost_yen": {"type": ["number", "null"], "description": "page_count 에 그 경로의 yen_per_page 를 곱한 값입니다. 경로가 정해진 문서에만 채웁니다."}, "yen_per_page": {"type": ["number", "null"]}, "owner_name": {"type": ["string", "null"]}, "evidence": {"type": "array", "items": {"type": "object", "properties": {"field": {"type": "string"}, "agg": {"type": ["string", "null"]}, "value": {}}, "required": ["field", "value"]}}, "summary": {"type": "string"}, "hedge": {"type": ["string", "null"]}}, "required": ["assign_no", "doc_no", "form_raw", "route_code", "evidence", "summary"]}[
{
"assign_no": "RA-001",
"doc_no": "DC-3001",
"form_raw": "請求書",
"policy_no": "RP-201",
"route_code": "ocr_only",
"est_cost_yen": 6,
"yen_per_page": 3,
"owner_name": "経理",
"evidence": [
{
"field": "page_count",
"agg": null,
"value": 2
},
{
"field": "yen_per_page",
"agg": null,
"value": 3
}
],
"summary": "스캔 품질이 기준을 넘고 표가 있어 문자 인식만으로 끝냅니다.",
"hedge": null
},
{
"assign_no": "RA-002",
"doc_no": "DC-3002",
"form_raw": "請求書",
"policy_no": "RP-201",
"route_code": "ocr_only",
"est_cost_yen": 3,
"yen_per_page": 3,
"owner_name": "経理",
"evidence": [
{
"field": "lang_raw",
"agg": null,
"value": "JA"
},
{
"field": "scan_score",
"agg": null,
"value": 0.88
}
],
"summary": "언어 표기를 대문자로 적어 보냈으나 접으면 같은 값이라 같은 경로로 보냅니다.",
"hedge": null
},
{
"assign_no": "RA-003",
"doc_no": "DC-3003",
"form_raw": "見積書",
"policy_no": "RP-204",
"route_code": "human_review",
"est_cost_yen": 540,
"yen_per_page": 180,
"owner_name": "営業",
"evidence": [
{
"field": "scan_score",
"agg": null,
"value": 0.61
},
{
"field": "min_scan_score",
"agg": null,
"value": 0.8
}
],
"summary": "손글씨가 섞이고 품질이 기준에 못 미쳐 사람이 직접 읽는 편이 쌉니다.",
"hedge": null
},
{
"assign_no": "RA-004",
"doc_no": "DC-3006",
"form_raw": "契約書",
"policy_no": "RP-205",
"route_code": "llm_extract",
"est_cost_yen": 144,
"yen_per_page": 12,
"owner_name": "法務",
"evidence": [
{
"field": "page_count",
"agg": null,
"value": 12
},
{
"field": "max_pages",
"agg": null,
"value": 20
}
],
"summary": "장수가 상한 안이고 품질도 기준을 넘어 모델 추출로 보냅니다.",
"hedge": "손글씨가 섞여 있어 추출 결과를 담당이 한 번 봅니다."
},
{
"assign_no": "RA-005",
"doc_no": "DC-3005",
"form_raw": "契約書",
"policy_no": null,
"route_code": "oversize",
"est_cost_yen": null,
"yen_per_page": null,
"owner_name": null,
"evidence": [
{
"field": "page_count",
"agg": null,
"value": 48
},
{
"field": "max_pages",
"agg": null,
"value": 20
}
],
"summary": "48장은 계약서 상한 20장을 넘어 나눠 넣을지 먼저 정해야 합니다.",
"hedge": null
},
{
"assign_no": "RA-006",
"doc_no": "DC-3007",
"form_raw": "申込書",
"policy_no": "RP-208",
"route_code": "human_review",
"est_cost_yen": 180,
"yen_per_page": 180,
"owner_name": "営業",
"evidence": [
{
"field": "scan_score",
"agg": null,
"value": 0.42
},
{
"field": "min_scan_score",
"agg": null,
"value": 0.9
}
],
"summary": "품질 0.42 는 문자 인식 기준 0.90 에 한참 못 미쳐 사람에게 넘깁니다.",
"hedge": null
},
{
"assign_no": "RA-007",
"doc_no": "DC-3012",
"form_raw": "納品書",
"policy_no": null,
"route_code": "quality_too_low",
"est_cost_yen": null,
"yen_per_page": null,
"owner_name": null,
"evidence": [
{
"field": "scan_score",
"agg": null,
"value": null
},
{
"field": "page_count",
"agg": null,
"value": 2
}
],
"summary": "품질 점수가 비어 있어 어느 경로로 보낼지 정할 근거가 없습니다.",
"hedge": null
},
{
"assign_no": "RA-008",
"doc_no": "DC-3010",
"form_raw": "稟議書",
"policy_no": null,
"route_code": "form_undeclared",
"est_cost_yen": null,
"yen_per_page": null,
"owner_name": null,
"evidence": [
{
"field": "form_raw",
"agg": null,
"value": "稟議書"
},
{
"field": "policy_no",
"agg": "count",
"value": 12
}
],
"summary": "품의서는 경로 규칙 열두 행에 없어 처리 방식을 먼저 정해야 합니다.",
"hedge": null
}
][자동 검증 · 코드가 판정합니다] 1. route_code 가 enum 여섯 값 중 하나인지 확인합니다. 2. assign_no·doc_no·form_raw·route_code·evidence·summary 가 모두 채워졌는지 확인합니다. 3. doc_no 가 문서 목록에 실재하는 번호인지 대조합니다. 4. policy_no 가 있으면 규칙표에 실재하는 행 번호인지 대조합니다. 5. policy_no 가 있으면 yen_per_page·owner_name 이 그 규칙 행의 값과 같은지 대조합니다. 6. form_raw·lang_raw 를 대소문자를 접어 규칙표와 맞추고, 맞는 행이 없으면 route_code 가 form_undeclared 인지 확인합니다. 7. est_cost_yen 을 page_count 에 yen_per_page 를 곱해 다시 계산해 같은지 확인합니다. 8. route_code 가 ocr_only·llm_extract·human_review 중 하나이면 scan_score 가 그 규칙의 min_scan_score 이상인지 다시 확인합니다. 9. 같은 서식에 규칙이 여럿이면 조건을 만족하는 것 중 yen_per_page 가 가장 낮은 행이 골렸는지 다시 계산합니다. 10. route_code 가 oversize 이면 page_count 가 그 서식 규칙의 max_pages 를 넘는지 다시 확인합니다. 11. scan_score 나 page_count 가 비어 있으면 route_code 가 quality_too_low 인지 확인합니다. 12. evidence 의 field 이름이 문서 목록과 규칙표에 실재하는 컬럼인지 대조합니다. 13. agg 가 없는 evidence 의 value 가 그 컬럼에 수록된 행 값과 같은지 확인합니다. 14. summary 가 존댓말로 끝나는지 확인합니다. [평가 러너 · 2주차] 공개 서식으로 만든 문서 400건에 손으로 붙인 정답 경로와 대조해 일치율과 경로 코드별 분포를 내고, 미선언이 몰리는 서식을 모아 규칙이 없는 문서 종류를 목록으로 냅니다. [수동 검증 · 사람이 봅니다] 1. 최소 품질을 어디로 정할지 담당 조직이 정합니다. 2. 상한을 넘는 긴 문서를 나눠 넣을지 사람이 정합니다.