올거나이즈코리아
경력근거: 顧客と連携し、ビジネス課題を定義した上でAI技術を基盤とした最適な解決策を設計
올거나이즈의 FDE(SW)는 고객과 함께 과제를 정의해 요구사항을 기술적 결과물로 옮기고, 현장에서 얻은 것을 프로덕트팀에 넘겨 제품을 고치는 자리입니다. 고객사 담당자가 평소 쓰는 말로 물으면 검증된 질의로 옮겨 추출본에 돌리고 근거를 찍는 이 도구는 그 일의 첫날 모습 그대로이고, Python 과 Linux 터미널에서 도는 형태라 고객사 서버에 그대로 올려 붙일 수 있습니다. 컬럼 사전 초안을 고객사의 기존 리포트 쿼리 묶음에서 뽑는 부분은 우대사항인 AI 코딩 도구로 대규모 코드베이스를 읽는 경험과 맞닿습니다. 다만 이 포트폴리오가 보여주는 것은 한국어 요청을 검증 가능한 질의로 옮겨 실행하고 근거를 남기는 기술이며, 제조 구매나 금융·공공 고객사의 업무 도메인 전문성은 주장하지 않고 그 깊이는 면접에서 솔직히 다룹니다.
고객과 함께 과제를 정의하고 요구사항을 실제로 돌아가는 결과물로 옮깁니다. 현장 질문을 그대로 받아 실행하는 도구가 여기에 정렬됩니다.
고객사 서버에 붙어 터미널에서 바로 돌리는 Python 도구입니다. 컬럼 사전 초안은 고객사의 기존 리포트 쿼리 묶음을 AI 코딩 도구로 읽어 뽑습니다.
현장에서 실제로 오간 질문과 거부·확인 사유가 그대로 로그로 쌓여 프로덕트팀에 넘길 재료가 됩니다.
고객사 ERP 에서 내려받은 발주 추출본과 컬럼 사전을 받아, 현장 담당자가 한국어로 물은 요청을 SQL 로 옮겨 실행하고 답과 근거를 터미널에 찍습니다. 실행 여부는 규칙이 정합니다. 질문의 용어가 컬럼 사전에 붙고 조립된 SQL 이 허용 컬럼·연산자를 통과할 때만 돌리고, 용어가 안 붙으면 확인 질문을, 추출본에 아예 없는 항목을 물으면 거부를 찍고 멈춥니다. LLM 은 질문을 조건 초안으로 옮기고 확인 질문 문안을 쓰는 보조만 맡습니다.
올거나이즈 고객사인 제조사의 구매팀 담당자입니다. 반려된 발주나 업체별 합계를 볼 때마다 사내 담당자에게 요청을 넣고 며칠을 기다리던 일을, 자기 자리에서 평소 쓰는 말로 물어 답과 그 답이 어떤 조건으로 나왔는지 바로 보고 싶은 사람입니다.
질문의 용어를 컬럼 사전에 붙이고 조립한 SQL 을 실행 전에 검증하면, (a) 비개발 담당자가 평소 쓰는 말로 물어도 답이 바로 나오고, (b) 답 옆에 실행한 질의·매핑·조건이 보여 결과를 믿을지 스스로 판단하며, (c) 사전에 없는 말은 지어내지 않고 확인 질문이나 거부로 떨어집니다.
한국어 질문을 받아 컬럼 사전으로 검증한 SQL 로 바꿔 추출본에 실행하고, 결과 행 위에 실행한 질의·용어 매핑·적용 조건을 같이 찍는 도구입니다. 용어가 안 붙으면 추측해서 돌리지 않고 확인 질문을, 없는 항목이면 거부를 찍고 멈춥니다.
질문 40건을 한 번에 돌려 상태(실행·확인·거부)와 결과 행 집합을 심은 정답과 대조하고, 어긋난 질문을 유형별로 모아 파일로 남기는 대조 명령입니다.
컬럼 사전만 갈아끼워 다른 헤더 체계의 추출본에 같은 질문을 돌리고, 자주 쓰는 질의에 이름을 붙여 바로 실행하는 기능입니다.
현장에서 받은 질문 40건을 한 번에 돌리면 질문마다 실행한 SQL·용어 매핑·결과 행이 터미널에 몇 초 안에 찍히는 걸 시연합니다
일부러 만든 까다로운 질문 25종(사전에 없는 항목·기간 미지정·업체 별칭·금액 결측)을 넣어도 추측 실행 없이 확인이나 거부로 떨어지고 출력 형식이 한 번도 안 깨집니다
심은 정답 질문 40건 중 상태와 결과 행 집합이 모두 일치한 게 34건(약 85%)입니다. 정답과 데이터를 모두 작성자가 만든 합성 기준이라 '성능 검증'이 아니라 '데모 조건에서의 동작'입니다
진짜 검증은 여기서 멈춥니다. 위 수치는 작성자가 만든 더미 추출본과 더미 질문의 자가채점이며, 실제 정확도는 올거나이즈 고객사의 실 추출본과 현장 담당자가 실제로 묻는 말이 있어야 측정됩니다. 이 도구는 그 검증을 첫날 바로 돌릴 수 있는 상태로 만듭니다
이건 고객사도 실데이터도 없이 혼자 만든 포트폴리오입니다. 수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다
이 포트폴리오가 보여주는 것은 한국어 요청을 검증 가능한 질의로 옮겨 실행하고 근거를 남기는 기술입니다. 제조 구매나 금융·공공 고객사의 업무 도메인 전문성은 포트폴리오로 증명되지 않으므로 주장하지 않고, 그 깊이는 면접에서 모르면 모른다고 말하는 편이 낫습니다
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 업체 별칭·부서 표기 흔들림·금액 결측·추출본에 없는 항목 질문 같은 경계 케이스를 일부러 섞어, 쉬운 질문만 통과시키는 게 아님을 보여줍니다
LLM 이 만든 조건 초안은 그럴듯해도 컬럼을 지어낼 수 있습니다. 조립된 SQL 을 허용 컬럼·연산자 목록으로 먼저 막고, 통과하지 못하면 실행하지 않고 거부로 찍습니다
'지난달'이나 '큰 건' 같은 말은 기준이 없으면 뜻이 갈립니다. 기준일은 실행 옵션으로 받고 임계가 없으면 임의로 정하지 않고 확인 질문으로 돌립니다. 실제 도입 때는 고객사가 쓰는 용어와 기준이 더미와 다르므로 컬럼 사전을 다시 맞춰야 합니다(도입 단계 과제로 분리)
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
고객사 ERP 에서 내려받은 발주 추출본. 조립된 SQL 이 실제로 도는 대상 테이블입니다. 업체 별칭·부서 표기 흔들림·금액 결측·상태 미상을 일부러 섞어, 질문이 조건으로 정확히 옮겨졌는지 결과 행으로 확인합니다.
| row_id | po_no | vendor_raw | vendor_id | dept_raw | amount_krw | status | ordered_on |
|---|---|---|---|---|---|---|---|
| r001 | PO-2026-0101 | (주)한빛산업 | v_hanbit | 구매1팀 | 12,000,000 | approved | 2026-03-04 |
| r002 | PO-2026-0102 | 한빛산업㈜ | v_hanbit | 구매1팀 | 3,400,000 | approved | 2026-03-06 |
| r003 | PO-2026-0103 | 대성정밀 | v_daesung | 구매 1팀 | 128,000,000 | rejected | 2026-03-11 |
| r004 | PO-2026-0104 | 대성정밀(주) | v_daesung | 구매2팀 | 96,500,000 | approved | 2026-03-18 |
| r005 | PO-2026-0105 | 신영텍 | — | 구매2팀 | 45,000,000 | pending | 2026-04-02 |
아래 Zod 스키마에 맞는 발주 추출본 80행을 JSON 배열로 생성합니다. 업체 4~5곳, 부서 3~4곳, 2026-03~2026-05 사이 날짜로 채웁니다.
{"type":"object","properties":{"row_id":{"type":"string"},"po_no":{"type":"string"},"vendor_raw":{"type":"string"},"vendor_id":{"type":["string","null"]},"dept_raw":{"type":"string"},"amount_krw":{"type":["number","null"]},"status":{"type":"string","enum":["approved","rejected","pending","unknown"]},"ordered_on":{"type":"string"}},"required":["row_id","po_no","vendor_raw","vendor_id","dept_raw","amount_krw","status","ordered_on"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 질문만 통과시키는 함정 회피): (1) 같은 업체의 표기 별칭('(주)한빛산업'/'한빛산업㈜'처럼 vendor_id 로 묶여야 함) 6건 이상, (2) 코드가 안 붙은 신규 업체(vendor_id=null) 4건, (3) 부서 표기 흔들림('구매1팀'/'구매 1팀') 4건, (4) 금액 결측(amount_krw=null)이면서 status='unknown' 인 행 2건, (5) 1억 경계 근처(95,000,000~105,000,000) 금액 3건, (6) 같은 달 안에서 승인·반려·대기가 섞이도록 분포. JSON 배열만.{"type":"object","properties":{"row_id":{"type":"string"},"po_no":{"type":"string"},"vendor_raw":{"type":"string"},"vendor_id":{"type":["string","null"]},"dept_raw":{"type":"string"},"amount_krw":{"type":["number","null"]},"status":{"type":"string","enum":["approved","rejected","pending","unknown"]},"ordered_on":{"type":"string"}},"required":["row_id","po_no","vendor_raw","vendor_id","dept_raw","amount_krw","status","ordered_on"]}현장 담당자가 실제로 던지는 한국어 요청 로그. 질문마다 정답 상태와 정답 조건, 나와야 할 행 목록을 심어 두어, 도구가 옮긴 조건이 맞았는지 실행 결과 행 집합으로 채점합니다. 기준일은 2026-06-01 로 고정합니다.
| req_id | asked_by | question | gold_status | gold_filter | expected_row_ids |
|---|---|---|---|---|---|
| q001 | 구매팀 담당자 | 지난달 반려된 발주 중에 1억 넘는 건만 보여주세요 | executed | status='rejected' AND amount_krw > 100… | ["r009"] |
| q002 | 구매팀장 | 한빛산업 발주 다 합치면 얼마예요 | executed | vendor_id='v_hanbit' | ["r001","r002","r006","r011"] |
| q003 | 구매팀 담당자 | 큰 건만 좀 뽑아주세요 | clarify | — | [] |
| q004 | 설비팀 담당자 | 납기 지연된 발주 보여주세요 | refused | — | [] |
| q005 | 구매팀 담당자 | 구매1팀이 올린 승인 건 알려주세요 | executed | dept='구매1팀' AND status='approved' | ["r001","r002"] |
아래 Zod 스키마에 맞는 현장 질문 60건을 JSON 배열로 생성합니다. 위 erp_extract 더미(2026-03~2026-05, 업체 4~5곳, 부서 3~4곳)를 대상으로 하고 기준일은 2026-06-01 로 고정합니다. gold_status 규칙: 용어가 컬럼 사전에 붙고 조건이 하나로 정해지면 executed(gold_filter 와 expected_row_ids 를 채움), 임계나 기간이나 분모가 정해지지 않아 뜻이 갈리면 clarify, 추출본에 아예 없는 항목(납기·반려 사유·담당자 이름 등)을 물으면 refused. clarify 와 refused 는 gold_filter=null, expected_row_ids=[].
{"type":"object","properties":{"req_id":{"type":"string"},"asked_by":{"type":"string"},"question":{"type":"string"},"gold_status":{"type":"string","enum":["executed","clarify","refused"]},"gold_filter":{"type":["string","null"]},"expected_row_ids":{"type":"array","items":{"type":"string"}}},"required":["req_id","asked_by","question","gold_status","gold_filter","expected_row_ids"]}
쉬운 질문만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: (1) 상대 기간('지난달'·'이번 분기') 8건, (2) 임계가 없는 정도 표현('큰 건'·'많이'·'좀 오래된') 6건, (3) 업체 별칭이나 부서 표기 흔들림이 섞인 지칭 6건, (4) 추출본에 없는 항목을 묻는 refused 6건, (5) 조건이 둘 이상 겹친 질문('설비팀이 4월에 올린 1억 이상 반려 건') 8건, (6) 오타·구어체가 섞인 문장 5건. 존댓말과 반말이 섞인 실제 말투 그대로 쓸 것. JSON 배열만.{"type":"object","properties":{"req_id":{"type":"string"},"asked_by":{"type":"string"},"question":{"type":"string"},"gold_status":{"type":"string","enum":["executed","clarify","refused"]},"gold_filter":{"type":["string","null"]},"expected_row_ids":{"type":"array","items":{"type":"string"}}},"required":["req_id","asked_by","question","gold_status","gold_filter","expected_row_ids"]}| Python | 질문 파서·컬럼 사전 매칭·SQL 조립·실행기를 만드는 구현 언어입니다 |
| Linux | 고객사 사내 서버에 붙어 터미널에서 바로 돌리는 실행 환경입니다 |
| AI/인공지능 | 한국어 요청을 조건 초안으로 옮기는 한 구간에만 쓰고 답은 실행 결과가 정합니다 |
| LLM | 질문을 SQL 초안으로 바꾸고 확인 질문 문안을 쓰는 보조입니다 |
| Claude Code | 고객사의 기존 리포트 쿼리 묶음을 읽어 컬럼 사전 초안을 뽑는 데 씁니다 |
| DuckDB | 엑셀·CSV 추출본을 그대로 읽어 SQL 을 실행하는 임베디드 엔진입니다 |
| K8S | 3주차에 같은 CLI 를 고객사 온프레미스 클러스터의 야간 배치 잡으로 올릴 때의 실행 형태를 가정합니다 |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(심은 정답과 대조)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(두 번째 고객사 교체와 저장된 질의)로 진행합니다.
질문 1건의 실행 기록. 상태·조립된 SQL·용어 매핑·적용 조건·결과 행을 한 스키마로 담아 터미널 출력과 실행 이력 파일에 함께 씁니다. 답이 맞았는지의 판단이 아니라 무엇을 어떤 조건으로 돌렸는지의 기록입니다.
{"type":"object","properties":{"req_id":{"type":"string"},"status":{"type":"string","enum":["executed","clarify","refused"]},"sql":{"type":["string","null"]},"term_mapping":{"type":"array","items":{"type":"object","properties":{"term":{"type":"string"},"column":{"type":["string","null"]}},"required":["term","column"]}},"applied_filters":{"type":"array","items":{"type":"string"}},"row_ids":{"type":"array","items":{"type":"string"}},"clarify_question":{"type":["string","null"]},"evidence":{"type":"string","minLength":8}},"required":["req_id","status","sql","term_mapping","applied_filters","row_ids","clarify_question","evidence"]}[
{
"input_ref": "q001 (상대 기간 + 금액 임계)",
"output": {
"req_id": "q001",
"status": "executed",
"sql": "SELECT row_id, po_no, vendor_raw, amount_krw FROM erp_extract WHERE status = 'rejected' AND amount_krw > 100000000 AND ordered_on BETWEEN '2026-05-01' AND '2026-05-31'",
"term_mapping": [
{
"term": "지난달",
"column": "ordered_on"
},
{
"term": "반려된",
"column": "status"
},
{
"term": "1억 넘는",
"column": "amount_krw"
}
],
"applied_filters": [
"status = 'rejected'",
"amount_krw > 100000000",
"ordered_on 2026-05-01 ~ 2026-05-31"
],
"row_ids": [
"r009"
],
"clarify_question": null,
"evidence": "기준일 --as-of 2026-06-01 로 '지난달'을 2026-05 로 잡았고, 금액 결측 1행은 비교에서 빠졌습니다"
}
},
{
"input_ref": "q003 (임계가 없는 정도 표현)",
"output": {
"req_id": "q003",
"status": "clarify",
"sql": null,
"term_mapping": [
{
"term": "큰 건",
"column": null
}
],
"applied_filters": [],
"row_ids": [],
"clarify_question": "'큰 건'의 기준을 정해 주세요. 금액 기준이면 얼마 이상인지, 예를 들어 1억 이상으로 볼까요",
"evidence": "'큰 건'이 컬럼 사전의 어떤 임계에도 붙지 않아 임의로 정하지 않고 멈췄습니다"
}
},
{
"input_ref": "q004 (추출본에 없는 항목)",
"output": {
"req_id": "q004",
"status": "refused",
"sql": null,
"term_mapping": [
{
"term": "납기 지연",
"column": null
}
],
"applied_filters": [],
"row_ids": [],
"clarify_question": null,
"evidence": "추출본 컬럼은 row_id·po_no·vendor_raw·vendor_id·dept_raw·amount_krw·status·ordered_on 이며 납기 관련 컬럼이 없어 실행하지 않았습니다"
}
}
][자동 검증] 1. Zod parse 로 출력 형식(필드·enum)이 스키마를 통과하는지 확인합니다. 2. 조립된 SQL 을 허용 컬럼·연산자 목록과 대조해, 사전에 없는 컬럼이나 쓰기 구문이 섞이면 실행하지 않고 refused 로 떨어뜨립니다. 3. status 가 executed 면 sql 이 반드시 있고, clarify 면 clarify_question 이 반드시 있으며, refused 면 둘 다 없어야 한다는 조건을 강제합니다. 4. 실행 결과 row_ids 를 심은 expected_row_ids 와 집합으로 비교하고, gold_status 와 status 가 같은지 함께 봅니다. [수동 검증] 1. 검토자 2명이 질문 40건의 정답 상태를 따로 라벨링해 bootstrap Cohen's κ(두 사람 답이 우연 이상으로 일치하는 정도, 0~1) 하한 0.6 이상을 봅니다. 2. 전체의 5% 를 사람이 직접 실행해 결과 행을 눈으로 확인합니다.