인공지능팩토리
경력근거: 모호한 공공의 요구사항을 작동하는 기술로 풀어내는 빌더
인공지능팩토리는 한국항공우주연구원·한국전력·원자력통제기술원 같은 공공기관에 AI 에이전트 시스템을 납품하고 온프레미스 폐쇄망을 구축하는 회사이며, 이 자리는 제안·착수의 아키텍처 설계부터 Spring Boot 백엔드 구축과 운영 이관까지 전 주기를 주도하는 FDE 입니다. 공공 사업은 요구사항정의서 한 줄마다 산출물로 증명해야 검수가 끝나는데, 그 대조를 사람이 엑셀로 하다 보니 근거 없는 이행 표기와 누락이 남습니다. 발주처 자료를 받아 규칙으로 대조하고 담당자가 읽을 문서로 되돌려주는 이 도구는 비개발 직군과 비즈니스의 언어로 이야기해야 하는 FDE 업무와 같은 골조입니다. 다만 이 포트폴리오가 보여주는 것은 Java·Spring Boot 실행기 구현, 엑셀과 CSV 정규화, 요구사항 대조 판정 규칙, RDB 설계와 문서 산출 기술이지, 공공 SI 사업 수행 경험이나 전자정부 표준프레임워크·국정원 보안 요건에 대한 실무 전문성을 주장하지 않습니다. 실제 발주처 검수 관행과 감리 대응의 깊이는 현장에서 배워야 하고, 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
FDE 는 발주처의 모호한 요구사항과 업무 프로세스를 분석해 기술로 해결 가능한 구조로 정의하는 자리입니다. 요구사항 한 줄마다 근거 산출물을 붙여 이행 여부를 판정하는 일이 그 작업의 가장 기본 단위입니다.
공공 SI 는 분석·설계·구축·이관 전 주기를 돌면서 제안서·설계서 같은 산출물로 증명해야 끝납니다. 요구사항과 산출물을 손으로 맞추던 검수 준비를 명령 한 번으로 줄이는 도구가 그 자리에서 바로 쓰입니다.
자격요건이 Java·Spring Boot 백엔드와 RDB 설계·대용량 쿼리 튜닝입니다. 판정 실행기를 Spring Boot 로 짜고 요구사항·산출물 이력을 PostgreSQL 에 담아 회차가 쌓여도 조회가 견디는지 확인합니다.
발주처 담당자가 엑셀로 넘겨준 요구사항정의서와 우리 팀이 남긴 설계서·구현·테스트 기록을 함께 넣으면, 요구사항 ID 표기를 정규화해 대조하고 요구사항마다 이행 상태를 판정해 검수 제출용 마크다운 추적표 파일을 만드는 CLI입니다. 실행은 `java -jar rtm-check.jar --req 요구사항정의서.xlsx --records 산출물기록.csv --out 추적표_2차검수.md` 한 줄이고, 결과는 화면이 아니라 그대로 발주처에 낼 수 있는 문서 파일입니다. 이행 상태는 설계·구현·테스트 세 단계 근거가 실제로 존재하는지로 판정하고, 근거가 없는 요구사항은 이행으로 올리지 않습니다.
인공지능팩토리 FDE 로 공공기관 사업 현장에 나가 있는 사람입니다. 발주처 담당자가 준 요구사항정의서 엑셀과 우리 팀이 형상관리·테스트에 남긴 기록을 검수 때마다 손으로 맞춰 보다가, 근거 없이 이행으로 적힌 요구사항을 놓쳐 검수 자리에서 되돌려받는 일을 끝내고 싶은 사람입니다.
요구사항 ID 표기를 정규화해 산출물 기록과 대조하고 설계·구현·테스트 세 단계 근거가 모두 있는지를 규칙으로 판정하면, 요구사항마다 이행 상태와 근거를 붙인 검수용 추적표를 명령 한 번으로 만들 수 있고, 근거가 없는 요구사항이 이행으로 올라가는 것을 기계가 먼저 막을 수 있습니다.
요구사항정의서 엑셀과 산출물 기록 CSV 를 넣으면 ID 표기를 정규화해 대조하고 요구사항마다 이행 상태를 판정해 마크다운 추적표 파일을 내놓는 CLI입니다. 폐쇄망 반입을 가정해 Docker 이미지로 묶어 외부망 없이 명령 한 번으로 돌아갑니다.
요구사항 ID 가 비어 있는 산출물 기록의 연결 후보를 본문 대조로 제안하고, 직접 만든 정답지 60건 대비 상태 판정과 근거 집합이 맞는지를 규칙으로 채점하며, 검수 담당 페르소나 2명의 라벨 일치도를 함께 내는 단계입니다.
회차별 판정 이력을 PostgreSQL 에 쌓아 지난 검수 대비 바뀐 요구사항만 뽑는 델타 리포트를 내고, 요구사항·산출물이 수십만 행으로 늘었을 때 요구사항별 이력 조회를 인덱스로 튜닝하며, 변경요청으로 삭제된 요구사항을 미이행이 아니라 범위 제외로 구분해 적는 단계입니다.
요구사항 60행과 설계·구현·테스트 기록 90행을 넣으면 명령 한 번으로 검수 제출용 추적표 파일이 나오는 걸 시연합니다. 상태별 요약표, 요구사항별 근거 산출물 목록, 담당자에게 물어야 할 확인 질문을 한 문서에 담습니다
정답지 60건 대비 이행 상태 판정을 규칙으로 채점합니다. 상태가 정답과 일치한 게 52건, 근거 산출물 집합까지 정확히 맞은 게 47건입니다. 단, 요구사항정의서와 정답지를 모두 작성자가 만든 합성 기준이라 '성능 검증'이 아니라 '데모 조건 동작'임을 명시합니다
ID 표기 흔들림·병합셀 빈 분류·삭제된 요구사항·중복 요구사항·요구사항에 없는 산출물 25종을 섞어 넣어도 출력 형식(스키마)이 한 번도 안 깨지고, 근거가 하나도 없는 요구사항은 이행으로 올라가지 않습니다
위 수치는 전부 작성자가 만든 더미 요구사항정의서 자가채점이며, 실제 판정 정확도와 확인 질문의 쓸모는 인공지능팩토리가 수행하는 실 공공사업의 요구사항정의서와 발주처 검수 담당 확인이 있어야 측정 가능합니다. 이 도구는 그 검증을 바로 돌릴 수 있는 상태로 만듭니다
이건 고객·실데이터 없이 혼자 만든 포트폴리오입니다. 모든 수치는 합성 요구사항정의서 자가채점이라 '성능 증명'이 아닙니다. 면접에서 솔직히 '데모 조건 동작 + 실검증 준비 상태'로 설명합니다
정답지를 내가 만들었으니 잘 맞는 게 당연합니다. 일부러 ID 표기 흔들림·병합셀 빈 분류·삭제 요구사항·중복 요구사항·요구사항에 없는 산출물 같은 경계 케이스를 더미에 섞어, 쉬운 문서만 다루는 게 아님을 보여줘야 합니다
규칙은 근거가 있는지까지만 판정합니다. 그 설계서가 요구사항을 제대로 담았는지, 테스트가 실제로 그 기능을 검증했는지는 사람이 봐야 알 수 있어 표본 검수로만 확인하고, 도구는 확인 필요로 넘길 뿐 이행으로 올리지 않습니다
이 포트폴리오가 보여주는 것은 Java·Spring Boot 실행기 구현, 엑셀과 CSV 정규화, 대조 판정 규칙, RDB 설계와 문서 산출 기술이지 공공 SI 도메인 전문성이나 전자정부 표준프레임워크·감리 대응 경험이 아닙니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다
실제 도입 시 달라지는 것을 명시합니다. 기관마다 요구사항정의서 양식과 ID 체계가 다르고 변경요청이 수시로 들어오므로, 정규화 규칙과 상태 판정 기준을 사업마다 다시 맞춰야 합니다(도입 단계 과제로 분리)
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
발주처 담당자가 엑셀로 넘겨준 요구사항정의서를 행 단위로 추출한 표입니다. 현장 문서 그대로 ID 표기 흔들림, 병합셀로 비어 버린 분류, 변경요청으로 삭제된 요구사항, 내용이 겹치는 중복 요구사항을 일부러 섞어, 깨끗한 표만 다루는 게 아님을 보여줍니다.
| req_id | category | name | description | priority | change_status | source_row |
|---|---|---|---|---|---|---|
| SFR-001 | 산림자원 관리 | 입목벌채 허가 신청 접수 | 민원인이 입목벌채 허가 신청서를 제출하면 접수번호를 발급합니다. | 상 | 신규 | 12 |
| SFR-002 | — | 신청서 첨부파일 검증 | 벌채구역도와 사업계획서 첨부 여부를 검증하고 누락 시 반려 사유를 남… | 상 | — | 13 |
| SFR_3 | — | 허가 심사 배정 | 접수된 신청을 담당 부서와 심사자에게 배정합니다. | 중 | — | 14 |
| 기능-004 | 산림자원 관리 | 허가증 발급 | 심사가 끝난 신청 건에 대해 허가증을 발급하고 민원인에게 통지합니다. | 상 | 변경 | 15 |
| SFR-005 | 재난안전 | 재난지원금 신청 접수 | 자연재난으로 피해를 입은 세대가 재난지원금을 신청합니다. | 상 | 신규 | 31 |
아래 JSON Schema 에 맞는 공공기관 사업 요구사항정의서 행 60개를 JSON 배열로 생성. 도메인 3종(산림자원 관리·재난안전·연구지원)과 공통 비기능 요구사항을 섞고, source_row 는 엑셀 행번호처럼 증가시켜라.
{"type":"object","properties":{"req_id":{"type":"string"},"category":{"type":["string","null"]},"name":{"type":"string"},"description":{"type":"string"},"priority":{"type":["string","null"]},"change_status":{"type":["string","null"]},"source_row":{"type":"integer"}},"required":["req_id","name","description"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 문제만 푸는 함정 회피): (1) req_id 표기가 흔들리는 행 6~8건('SFR-001' 외에 'SFR_3'·'기능-004'·'sfr-011' 처럼 구분자와 접두사가 다른 것), (2) 병합셀 때문에 category 가 null 인 행 5~6건(바로 위 행의 분류를 물려받아야 하는 자리), (3) change_status 가 '삭제' 인 행 3건(미이행이 아니라 범위 제외로 판정돼야 함), (4) 이름과 설명이 사실상 같은 중복 요구사항 쌍 2쌍, (5) 설명이 한 줄뿐이라 산출물 본문과 대조하기 어려운 짧은 행 2건. JSON 배열만.{"type":"object","properties":{"req_id":{"type":"string"},"category":{"type":["string","null"]},"name":{"type":"string"},"description":{"type":"string"},"priority":{"type":["string","null"]},"change_status":{"type":["string","null"]},"source_row":{"type":"integer"}},"required":["req_id","name","description"]}우리 팀이 남긴 설계서 목차·형상관리 커밋·단위테스트 결과를 한 표로 모은 산출물 기록입니다. 요구사항 ID 를 적어 둔 기록도 있고 비워 둔 기록도 있으며 요구사항정의서에 없는 산출물도 섞여 있어, 대조가 실제로 어떤 모양인지 드러납니다.
| record_id | kind | title | ref_req_id | detail | result | updated_at |
|---|---|---|---|---|---|---|
| DSN-101 | design | 허가 신청 접수 설계서 2.1절 | SFR-001 | 접수 화면 항목 정의와 접수번호 채번 규칙을 담았습니다. | — | 2026-06-12 |
| SRC-201 | code | PermitApplicationController | SFR-001 | 신청 접수 API 와 접수번호 발급 로직을 구현했습니다. | — | 2026-06-20 |
| TST-301 | test | 입목벌채 신청 접수 단위테스트 | SFR-001 | 정상 접수와 중복 접수 방지를 검증합니다. | pass | 2026-06-21 |
| DSN-102 | design | 첨부파일 검증 규칙 설계서 2.3절 | SFR002 | 첨부 필수 항목과 반려 사유 코드를 정의했습니다. | — | 2026-06-13 |
| SRC-202 | code | AttachmentValidator | — | 벌채구역도와 사업계획서 첨부 여부를 검증하는 모듈입니다. 설계서 2.… | — | 2026-06-22 |
아래 JSON Schema 에 맞는 공공 SI 산출물 기록 90행을 JSON 배열로 생성. requirement_items 의 req_id 와 이어지도록 만들고 kind 는 design·code·test 를 섞어라.
{"type":"object","properties":{"record_id":{"type":"string"},"kind":{"type":"string","enum":["design","code","test"]},"title":{"type":"string"},"ref_req_id":{"type":["string","null"]},"detail":{"type":"string"},"result":{"type":["string","null"]},"updated_at":{"type":"string"}},"required":["record_id","kind","title","detail"]}
쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) ref_req_id 가 null 이고 detail 본문에만 근거가 있는 기록 8~10건(본문 대조로만 연결되는 자리), (2) ref_req_id 표기가 요구사항정의서와 다른 기록 6건('SFR002'·'기능004' 처럼 구분자 누락), (3) design 만 있고 code·test 가 없는 요구사항 4건과 code 만 있는 요구사항 3건, (4) result 가 'fail' 인 테스트 기록 3건(이행으로 올리면 안 되는 자리), (5) 요구사항정의서에 없는 req_id 를 참조하는 산출물 3건. JSON 배열만.{"type":"object","properties":{"record_id":{"type":"string"},"kind":{"type":"string","enum":["design","code","test"]},"title":{"type":"string"},"ref_req_id":{"type":["string","null"]},"detail":{"type":"string"},"result":{"type":["string","null"]},"updated_at":{"type":"string"}},"required":["record_id","kind","title","detail"]}요구사항마다 어떤 상태로 판정돼야 하고 어떤 산출물이 근거로 붙어야 하는지를 적은 정답지입니다. 상태 판정과 근거 집합을 규칙으로 채점하는 기준이 됩니다.
| req_id | expected_status | expected_evidence_ids | note |
|---|---|---|---|
| SFR-001 | fulfilled | ["DSN-101","SRC-201","TST-301"] | — |
| SFR-002 | partial | ["DSN-102","SRC-202"] | 설계서는 'SFR002' 로 적혀 정규화가 필요하고 구현 기록은 ID… |
| SFR_3 | partial | ["DSN-103"] | 설계서만 있고 구현·테스트 기록이 없습니다 |
| 기능-004 | partial | ["SRC-203","TST-302"] | 테스트가 실패로 남아 있어 이행으로 올리면 안 됩니다 |
| SFR-005 | missing | [] | 어떤 산출물도 이 요구사항을 참조하지 않습니다 |
아래 JSON Schema 에 맞는 요구사항 이행 판정 정답지 60행을 JSON 배열로 생성. requirement_items 의 req_id 와 deliverable_records 의 record_id 에 맞춰라.
{"type":"object","properties":{"req_id":{"type":"string"},"expected_status":{"type":"string","enum":["fulfilled","partial","missing","dropped","duplicate","out_of_scope"]},"expected_evidence_ids":{"type":"array","items":{"type":"string"}},"note":{"type":["string","null"]}},"required":["req_id","expected_status","expected_evidence_ids"]}
쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) 테스트가 실패라서 fulfilled 가 아니라 partial 인 행 3건, (2) 삭제된 요구사항이라 missing 이 아니라 dropped 인 행 3건, (3) 내용이 겹쳐 duplicate 인 행 2건(note 에 어느 요구사항과 겹치는지 적을 것), (4) 요구사항정의서에 없는 req_id 를 참조하는 산출물 때문에 out_of_scope 인 행 3건, (5) 근거가 본문 대조로만 이어져 expected_evidence_ids 에 ID 가 비어 있던 기록이 들어가는 행 6~8건. 나머지는 fulfilled 와 missing 을 고르게 섞어라. JSON 배열만.{"type":"object","properties":{"req_id":{"type":"string"},"expected_status":{"type":"string","enum":["fulfilled","partial","missing","dropped","duplicate","out_of_scope"]},"expected_evidence_ids":{"type":"array","items":{"type":"string"}},"note":{"type":["string","null"]}},"required":["req_id","expected_status","expected_evidence_ids"]}| Java / Spring Boot | 요구사항·산출물 기록을 읽어 정규화하고 대조·판정한 뒤 추적표 파일을 쓰는 CLI 실행기입니다. 서브커맨드(check·diff·score)를 나누고 단계를 배치 잡으로 묶습니다 |
| Python | 정답지 대비 판정 일치도를 세는 채점 스크립트와, 더미 요구사항정의서·산출물 기록을 만드는 생성기입니다 |
| PostgreSQL | 요구사항·산출물·회차별 판정 이력을 담는 단일 진실원이며, 회차가 쌓였을 때 요구사항별 이력 조회를 인덱스로 튜닝합니다 |
| Docker | 폐쇄망 반입을 가정해 실행기와 데이터베이스를 오프라인 이미지로 묶어 외부망 없이 실행합니다 |
| GitHub | 소스 관리와 GitHub Actions 회귀 테스트입니다. 판정 규칙을 고치면 정답지 채점이 자동으로 다시 돌아 판정이 흔들렸는지 바로 드러납니다 |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우고 싶으면 2주차(연결 후보 제안 + 판정 결정론 채점)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(회차 누적 이력 + 델타 리포트·대용량 조회 튜닝)로 진행합니다.
요구사항 한 건의 이행 상태와 근거 산출물, 그리고 추적표 문서에 그대로 실릴 한 줄을 담습니다. 근거가 규칙으로 이어졌는지 본문 대조 후보인지를 구분해, 사람이 확인해야 할 자리를 문서에서 바로 알아보게 합니다.
{"type":"object","properties":{"req_id":{"type":"string"},"normalized_req_id":{"type":"string"},"requirement_name":{"type":"string"},"status":{"type":"string","enum":["fulfilled","partial","missing","dropped","duplicate","out_of_scope"]},"evidence":{"type":"array","items":{"type":"object","properties":{"record_id":{"type":"string"},"kind":{"type":"string"},"match_rule":{"type":"string","enum":["id_exact","id_normalized","llm_suggested"]}},"required":["record_id","kind","match_rule"]}},"missing_stages":{"type":"array","items":{"type":"string"}},"report_line":{"type":"string"},"needs_owner_check":{"type":"boolean"},"owner_question":{"type":["string","null"]}},"required":["req_id","normalized_req_id","status","evidence","missing_stages","report_line","needs_owner_check"]}[
{
"input_ref": "SFR-001 · 설계·구현·테스트 근거가 모두 있는 요구사항",
"output": {
"req_id": "SFR-001",
"normalized_req_id": "SFR-1",
"requirement_name": "입목벌채 허가 신청 접수",
"status": "fulfilled",
"evidence": [
{
"record_id": "DSN-101",
"kind": "design",
"match_rule": "id_exact"
},
{
"record_id": "SRC-201",
"kind": "code",
"match_rule": "id_exact"
},
{
"record_id": "TST-301",
"kind": "test",
"match_rule": "id_exact"
}
],
"missing_stages": [],
"report_line": "SFR-001 입목벌채 허가 신청 접수: 설계서 2.1절, 접수 API 구현, 단위테스트 통과까지 근거가 모두 확인됩니다.",
"needs_owner_check": false,
"owner_question": null
}
},
{
"input_ref": "SFR-002 · ID 표기가 다르고 구현 기록은 본문으로만 이어지는 요구사항",
"output": {
"req_id": "SFR-002",
"normalized_req_id": "SFR-2",
"requirement_name": "신청서 첨부파일 검증",
"status": "partial",
"evidence": [
{
"record_id": "DSN-102",
"kind": "design",
"match_rule": "id_normalized"
},
{
"record_id": "SRC-202",
"kind": "code",
"match_rule": "llm_suggested"
}
],
"missing_stages": [
"test"
],
"report_line": "SFR-002 신청서 첨부파일 검증: 설계서는 'SFR002' 표기로 연결됐고 구현 기록 AttachmentValidator 는 본문 대조로 이어진 후보라 담당자 확인이 필요하며, 테스트 기록이 없어 부분 이행입니다.",
"needs_owner_check": true,
"owner_question": "AttachmentValidator 가 SFR-002 첨부 검증 요구사항의 구현 산출물이 맞는지 확인해 주시고, 단위테스트 기록이 있으면 알려 주시기 바랍니다."
}
},
{
"input_ref": "SFR-009 · 다른 요구사항과 내용이 겹치는 중복 행",
"output": {
"req_id": "SFR-009",
"normalized_req_id": "SFR-9",
"requirement_name": "지급 대상 자격 확인",
"status": "duplicate",
"evidence": [],
"missing_stages": [
"design",
"code",
"test"
],
"report_line": "SFR-009 지급 대상 자격 확인: SFR-006 지급 대상 자격 판정과 내용이 같아 중복으로 묶었고, 근거 산출물은 SFR-006 쪽에 달려 있습니다.",
"needs_owner_check": true,
"owner_question": "SFR-006 과 SFR-009 가 같은 요구사항인지, 검수 대상으로 어느 쪽을 남길지 확인해 주시기 바랍니다."
}
}
][자동 검증(규칙·결정론으로 채점)] 1) 스키마 통과: 출력이 위 JSON Schema 형식을 지키는지(status·evidence·missing_stages·report_line 필드 존재와 타입 확인). 2) 근거 존재: 각 evidence 의 record_id 가 deliverable_records 에 실제 있고 kind 가 그 기록의 kind 와 같은지(없는 산출물을 근거로 적는 것 차단). 3) 상태 일치: status 가 traceability_gold 의 expected_status 와 같은지, evidence 의 record_id 집합이 expected_evidence_ids 와 같은지. 4) 판정 정합: 세 단계 근거가 모두 있고 실패한 테스트가 없을 때만 fulfilled 이고, 근거가 하나도 없으면 missing 이며, change_status 가 '삭제' 인 요구사항은 missing 이 아니라 dropped 인지. 5) 후보 표시: match_rule 이 llm_suggested 인 근거가 하나라도 있으면 needs_owner_check 가 true 이고 owner_question 이 비어 있지 않은지(모델이 이어 붙인 근거가 확인 없이 이행으로 올라가지 않게 막습니다). [수동 검증(사람이 봐야 하는 것)] 6) 발주처 검수 담당 페르소나 2명이 report_line 과 확인 질문을 그대로 검수 자리에 낼 만한지 비동기 라벨 → 일치도 Cohen's κ(두 사람 판단이 우연 이상으로 일치하는 정도, 0~1) 하한 0.6 이상. 7) 부분 이행으로 판정된 요구사항 5% 표본을 사람이 열어, 설계서 내용이 실제로 그 요구사항을 담았는지 점검.