피에프씨테크놀로지스
경력근거: 2주 이상 걸리던 전략 설계를 하루로 단축하는 것이 제품이 만들어내는 차이죠
피에프씨테크놀로지스의 AIRPACK은 금융기관이 규칙 기반 전략부터 직접 수립하고 운영하게 만드는 제품이라, 전략을 바꾸는 주체가 개발자가 아니라 심사 담당자입니다. 담당자의 말이 실행 가능한 규칙으로 정확히 옮겨졌는지 사람이 확인하는 절차와, 대량 신청 데이터에 그 규칙을 빠르게 돌리는 처리가 동시에 필요합니다. 이 문제 구조는 전략 설계를 하루로 줄이겠다는 AIRPACK의 목표에서 그대로 나옵니다. 이 포트폴리오가 보여주는 것은 자연어를 규칙 구조로 옮기고 사람 확인을 끼워 넣으며 대량 배치를 효율적으로 돌리는 기술이며, 신용평가 모델링이나 여신 리스크 도메인 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
2주 이상 걸리던 전략 설계를 하루로 줄이는 것이 제품이 만들어내는 차이라고 명시합니다.
대규모 트래픽과 방대한 여신 데이터를 리소스 효율적으로 처리하는 설계와 검증을 제품 경쟁력으로 봅니다.
에이전트·툴 콜링과 사람 확인 절차를 신뢰성이 중요한 환경에 적용하는 경험을 우대합니다.
피에프씨테크놀로지스의 AIRPACK이 금융기관 스스로 승인 전략을 세우고 운영하도록 돕는 맥락에서, 심사 담당자가 문장으로 쓴 승인 전략을 규칙 JSON으로 바꾸고 사람이 확인해 승인한 규칙만 과거 신청 더미에 배치로 돌려 승인률·거절 사유 분포와 기존 전략 대비 변화를 보여주는 전략 시뮬레이터입니다. 신청 데이터와 전략 문장은 실 데이터 대신 더미를 가정합니다.
승인 기준을 바꾸고 싶을 때마다 개발자에게 조건을 말로 설명하고 배치 결과가 나올 때까지 며칠을 기다리던 여신 심사 담당자가, 자기가 쓴 문장이 규칙으로 바뀌는 걸 눈으로 확인하고 그 자리에서 승인률 변화를 보고 싶은 사람입니다.
전략 문장을 규칙 JSON으로 바꾸는 단계와 그 규칙을 데이터에 적용하는 단계를 분리하고 사이에 사람 확인을 두면, 담당자가 직접 전략을 고쳐가며 결과를 바로 확인할 수 있다는 가정입니다.
심사 담당자가 문장으로 쓴 승인 전략을 규칙 JSON으로 바꿔 화면에 펼쳐 보여주고, 담당자가 조건을 고치거나 승인하면 그 규칙을 과거 신청 더미에 배치로 돌려 승인률과 거절 사유 분포를 표로 내는 콘솔이 도는 완결품입니다. 변환은 사내 API 호출 대신 LLM 툴 콜링으로 시작하고, 판정은 전부 규칙 엔진이 합니다.
1주차 변환 위에 전략 문장과 기대 규칙을 짝지은 평가 셋을 붙여 변환 정확도와 사람이 고친 비율을 재고, 기존 전략과 새 전략을 같은 데이터에 나란히 돌린 비교 리포트를 냅니다.
2주차 비교 리포트 위에 신청 데이터를 10만 건 규모로 늘려 청크 처리와 인덱스를 적용하고, 적용 전후 처리 시간과 메모리 사용을 나란히 보여줍니다.
전략 문장을 입력하면 규칙 JSON 변환부터 담당자 확인, 신청 데이터 배치 실행, 승인률과 거절 사유 분포까지 한 흐름으로 도는 과정을 시연합니다.
규칙 엔진의 판정이 조건 트리대로 떨어지는지 신청 건별로 대조해 보여주되, 신청 데이터와 기대 규칙을 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
소득 결측·한도 경계값·미등록 업종 코드·거래처명 표기 흔들림 30종을 넣어도 배치가 멈추지 않고 판정과 사유를 남기는 강건성을 보여줍니다.
10만 건 신청 데이터를 청크 처리와 인덱스 적용 전후로 돌려 처리 시간과 메모리 사용 변화를 나란히 보여줍니다.
위 수치는 더미데이터 자가채점이며, 실제 변환 정확도와 전략 품질은 피에프씨테크놀로지스의 실 여신 데이터와 실 심사 담당자가 있어야 측정 가능합니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태로 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아니므로, 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 만들었으니 잘 맞는 게 당연하므로, 소득 결측·한도 경계값·미등록 업종 코드·표기 흔들림 같은 경계 케이스를 더미에 일부러 섞어 쉬운 문제만 푸는 함정을 피합니다.
이 포트폴리오가 보여주는 것은 자연어를 규칙 구조로 옮기고 사람 확인을 끼워 넣으며 대량 배치를 효율적으로 돌리는 기술이며, 신용평가 모델링이나 여신 리스크 도메인 전문성은 주장하지 않습니다. 판정은 규칙 엔진이 하고 LLM은 변환만 맡습니다.
승인률이 올랐다고 좋은 전략인 것은 아니어서 연체와 손실을 함께 봐야 하는데 더미로는 그 인과를 만들 수 없으므로, 상관과 인과를 섞지 않도록 결과 화면에 승인률만 단독으로 쓰지 않습니다.
실제 도입 때는 신청 데이터 분포와 규제 요건이 달라 규칙 필드와 거절 사유 코드가 바뀌므로, 도메인별 스키마 교체를 도입 단계 과제로 둡니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
승인 전략을 돌려볼 과거 신청 데이터로, 소득 결측·한도 경계값·미등록 업종 코드·거래처명 표기 흔들림 같은 하드 케이스를 일부러 섞어 규칙 엔진과 배치가 제대로 도는지 확인합니다.
| app_id | credit_score | annual_income | dti | employment_months | requested_amount | industry_raw | industry_code | prior_delinquency |
|---|---|---|---|---|---|---|---|---|
| A-001 | 812 | 62,000,000 | 28.4 | 46 | 20,000,000 | 소프트웨어 개발업 | J62 | false |
| A-002 | 640 | 31,000,000 | 41 | 8 | 15,000,000 | 음식점업 | I56 | true |
| A-003 | 700 | — | — | 24 | 10,000,000 | 프리랜서 | — | false |
| A-004 | 700 | 40,000,000 | 40 | 12 | 10,000,000 | 도매업 | G46 | false |
| A-005 | 899 | 250,000,000 | 5 | 240 | 100,000,000 | 의료업 | Q86 | false |
다음 JSON Schema 에 맞는 여신 신청 행을 더 생성하세요: {"type":"object","properties":{"app_id":{"type":"string"},"credit_score":{"type":["integer","null"]},"annual_income":{"type":["integer","null"]},"dti":{"type":["number","null"]},"employment_months":{"type":["integer","null"]},"requested_amount":{"type":"integer"},"industry_raw":{"type":"string"},"industry_code":{"type":["string","null"]},"prior_delinquency":{"type":"boolean"}},"required":["app_id","requested_amount","industry_raw","prior_delinquency"]} 쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: annual_income 이나 credit_score 가 null 인 소득·점수 결측, dti 와 employment_months 가 함께 null 이라 여러 조건을 못 거는 이중 결측, dti 가 정확히 40.0 이거나 credit_score 가 700 처럼 임계값과 같은 경계값, credit_score 401 과 899 같은 극단 최소·최대, requested_amount 가 0 인 극단값, industry_code 가 null 이라 업종 마스터에 매핑 안 된 미등록 업종, industry_raw 가 같은 업종의 표기 흔들림(소프트웨어 개발업 을 소프트웨어개발업 으로)이라 정규화가 필요한 경우. 승인될 만한 건과 거절될 만한 건을 골고루 섞고, 형식 깨뜨리기 시도(스키마 타입 위반) 3건은 데이터가 아니라 별도 목록으로 표시하세요.{"type":"object","properties":{"app_id":{"type":"string"},"credit_score":{"type":["integer","null"]},"annual_income":{"type":["integer","null"]},"dti":{"type":["number","null"]},"employment_months":{"type":["integer","null"]},"requested_amount":{"type":"integer"},"industry_raw":{"type":"string"},"industry_code":{"type":["string","null"]},"prior_delinquency":{"type":"boolean"}},"required":["app_id","requested_amount","industry_raw","prior_delinquency"]}| Python | 규칙 엔진과 배치 처리를 구현하고 청크 단위로 신청 데이터를 흘려 메모리를 일정하게 유지합니다. |
| FastAPI | 전략 변환·검증·배치 실행을 나눈 API를 구현합니다. |
| Next.js/React/TypeScript | 전략 문장 입력과 변환된 규칙 확인, 결과 비교를 한 화면에서 하는 콘솔을 구현합니다. |
| MySQL | 신청 데이터와 전략 이력을 저장하고 인덱스로 배치 조회 시간을 줄입니다. |
| Docker | 규칙 엔진과 배치 실행 환경을 컨테이너로 묶어 같은 조건에서 성능을 재게 합니다. |
| LLM API(Claude) 툴 콜링 | 전략 문장을 규칙 JSON으로 바꾸는 변환만 맡고, 승인·거절 판정은 규칙 엔진이 합니다. |
| 사람 확인 절차 | 변환된 규칙을 담당자가 고치거나 승인해야 배치가 도는 게이트를 둡니다. |
| JSON Schema | 규칙과 배치 결과의 모양을 강제해 필드 누락을 막고 더미 증강에 씁니다. |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차에서 변환 정확도를 평가 셋으로 잽니다.
✓ pass → 여기서 멈춰도 검증된 완결입니다. 더 키우려면 3주차에서 10만 건 배치 처리 시간과 메모리를 다룹니다.
전략 문장 한 건을 조건 트리로 옮긴 결과와 사람이 확인해야 할 지점을 함께 내보내, 담당자 의도와 다른 규칙이 그대로 배치로 넘어가지 않게 합니다.
{"type":"object","properties":{"strategy_id":{"type":"string"},"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["gte","lte","eq","in","is_null"]},"value":{"type":["string","number","boolean","array","null"]}},"required":["field","op","value"]}},"decision":{"type":"string","enum":["approve","reject","review"]},"reject_reason":{"type":["string","null"],"enum":["low_score","high_dti","short_tenure","prior_delinquency","missing_data",null]},"quote":{"type":"string"},"needs_review":{"type":"boolean"},"hedge":{"type":["string","null"]}},"required":["strategy_id","conditions","decision","quote","needs_review"]}[
{
"strategy_id": "S-001",
"conditions": [
{
"field": "credit_score",
"op": "gte",
"value": 700
},
{
"field": "dti",
"op": "lte",
"value": 40
}
],
"decision": "approve",
"reject_reason": null,
"quote": "신용점수 700점 이상이고 DTI 40% 이하면 승인",
"needs_review": false,
"hedge": null
},
{
"strategy_id": "S-002",
"conditions": [
{
"field": "employment_months",
"op": "lte",
"value": 12
},
{
"field": "prior_delinquency",
"op": "eq",
"value": true
}
],
"decision": "reject",
"reject_reason": "short_tenure",
"quote": "재직 1년 이하이면서 연체 이력이 있으면 거절",
"needs_review": false,
"hedge": null
},
{
"strategy_id": "S-003",
"conditions": [
{
"field": "annual_income",
"op": "is_null",
"value": null
}
],
"decision": "review",
"reject_reason": "missing_data",
"quote": "소득 확인이 안 되면 일단 보류하고 사람이 본다",
"needs_review": true,
"hedge": "보류 뒤 어느 부서가 확인하는지가 문장에 없어 담당자 확인이 필요합니다."
},
{
"strategy_id": "S-004",
"conditions": [
{
"field": "industry_code",
"op": "in",
"value": [
"I55",
"I56"
]
}
],
"decision": "review",
"reject_reason": null,
"quote": "숙박·음식업은 조금 더 보수적으로",
"needs_review": true,
"hedge": "보수적으로가 한도 축소인지 추가 심사인지 문장만으로 정해지지 않아 담당자가 골라야 합니다(합성 기준 추정)."
}
][자동 검증] 1. conditions 의 field 가 신청 데이터 스키마에 실제로 있는 필드인지 대조해, 없는 필드를 지어낸 변환을 거릅니다. 2. quote 가 입력한 전략 문장의 실제 부분 문자열인지 확인해, 담당자가 쓰지 않은 조건이 끼어들지 않게 합니다. 3. decision 이 review 인데 needs_review 가 false 이면 불일치로 표시합니다. 4. 규칙을 신청 데이터에 적용한 결과가 조건 비교와 일치하는지 건별로 재계산해 대조합니다. [수동 검증] 1. 보수적으로·엄격하게 같은 정도 표현을 어떤 조건으로 옮길지 심사 담당자가 정합니다. 2. 여러 조건이 동시에 걸릴 때 어느 거절 사유를 대표로 남길지 우선순위를 담당자가 정합니다. 3. DTI(총부채원리금상환비율, 소득 대비 갚아야 할 원리금 비율로 높을수록 상환 부담이 큼) 같은 지표의 임계값이 실제 심사 기준과 맞는지 확인합니다.
포트폴리오가 “무엇을 만들지”라면, 시나리오 테스트는 “현장에서 어떻게 판단·소통할지” 입니다. 실제 이 채용공고 맥락의 대본을 읽고 무엇을 물어야 할지 직접 써봅니다.