모두의포트폴리오
PE · FDE 직군을 위한 포트폴리오 밀키트
예전 판입니다 (1판)이 문서는 2026-08-01 에 새 판으로 개정됐습니다. 산출물을 웹 화면 게이트에서 계획·실적 엑셀을 계산하는 CLI로 바꾸고 화면과 프런트엔드를 걷어냈습니다.최신 판 보기 →
경력에스투더블유 · FDE (AI Engineering)

위협 인텔 리포트에서 LLM으로 IOC(악성 도메인·IP·해시)와 관계를 뽑아 구조화 레코드로 적재하되, 형식(정규식)을 위반하거나 원문에 근거가 없는 지어낸 지표는 막고 애매한 건 검토로 돌리는 IOC 추출 적재 게이트

에스투더블유 공고에서 뽑은 세 가지 시그널.

에스투더블유 FDE(AI 엔지니어링)는 고객 문제를 정의부터 해결까지 끌고 가며, 비정형·반정형 데이터를 OCR/VLM/LLM 으로 처리해 구조화하고 기업의 데이터를 자산화하는 일을 핵심으로 합니다. 위협 인텔 리포트라는 비정형 문서에서 IOC 를 정규식 형식 검증과 원문 근거로 걸러 구조화 레코드로 적재하는 이 게이트는 그 핵심(문서 구조화·자산화·규칙 기반 품질 점검·LLM 추출 근거화)을 정면으로 입증합니다. 실제 위협 판정·다크웹 분석·악성 여부 같은 보안·위협 인텔 도메인 전문성은 포트폴리오로 증명되지 않으므로 합성 리포트로 기술만 보이고, 그 깊이는 면접에서 솔직히 다룹니다. 추출 IOC 를 형식 규칙·원문 근거로 잇는 사슬은 단순 LLM 추출 맥락으로는 그대로 만들 수 없습니다.

01

비정형 문서 구조화·자산화

OCR·LLM 으로 비정형·반정형 문서를 구조화 데이터로 가공해 자산화하는 일이 주요업무입니다. 리포트에서 IOC 를 뽑아 구조화 레코드로 적재하는 이 게이트가 정면으로 정렬됩니다.

비정형·반정형 데이터의 이해와 구조화OCR·문서 파싱·요약·정보 추출로 비정형 문서를 구조화 데이터로 가공해 본 경험구조화를 통해 기업의 데이터를 자산화합니다
02

규칙 기반 판정·품질 점검

Rule Engine/RBS 로 문제를 풀고 스키마·정합성·누락 등 데이터 품질을 점검합니다. 형식 규칙과 근거 대조로 적재 여부를 결정하는 게이트와 정렬됩니다.

Rule Engine/RBS품질(스키마·정합성·누락 등)을 점검실제 산업의 문제를 풀어냅니다
03

LLM 에이전틱 추출 + 근거

tool-calling·RAG·agent loop 기반 LLM 에이전트를 설계·개발하고 OCR/VLM/LLM 으로 데이터를 처리합니다. LLM 추출에 원문 근거 인용을 강제하는 이 게이트와 정렬됩니다.

LLM 기반 에이전트(tool-calling·RAG·agent loop·세션 관리)를 설계·개발데이터 처리 (OCR/VLM/LLM)재사용 가능한 모듈·매핑룰·피처를 자산화

포트폴리오 요약

위협 인텔 리포트(비정형 문서)에서 LLM 이 뽑은 IOC 후보(원본 표기·정규화 값·타입·근거 span)를 받아, 규칙(정규식 형식 위반·원문 미근거·정규화 실패·미등록 타입)으로 적재할지 검토할지 막을지 정합니다. 적재 여부는 정규식 형식 검증과 원문 substring 근거로 결정하고, LLM 은 추출·근거 인용 보조만 맡습니다. IOC 가 진짜 악성인지 판정하는 도구가 아니라, 리포트에 적힌 지표를 형식·근거 정합성으로 걸러 구조화 자산에 적재할지 정하는 게이트입니다.

고객 정의

에스투더블유 FDE(AI 엔지니어링). 위협 인텔 리포트에서 IOC 를 눈으로 하나씩 뽑아 형식이 맞는지, 원문에 실제로 있는지 대조하며 자산으로 정리하던 일을, 한 게이트에서 추출·형식·근거 결과를 함께 보고 싶은 사람입니다.

고민 지점

추출 IOC 를 한 스키마로 묶고 정규식 형식 규칙과 원문 근거 대조를 붙이면, (a) 형식이 깨진 값과 원문에 없는 지어낸 지표를 규칙으로 거르고, (b) 적재 근거를 원문 인용으로 풀며, (c) 여러 리포트를 끊김 없이 구조화 자산으로 적재합니다.

주차별 일정

1주차여기까지로 완성

IOC 추출 + 형식 검증 + 근거 대조 + 적재

위협 리포트에서 IOC 를 추출하고 정규식 형식·원문 근거·정규화를 검사해 통과만 구조화 레코드로 적재하는 동작하는 게이트입니다. 리포트는 합성 위협 리포트 더미로 시작하고, 저장은 PostgreSQL 한 곳으로 가볍게 둡니다.

  1. 1일 · IOC·추출 스키마를 정의IOC 타입 enum·타입별 정규식·원본 표기·정규화 값·근거 span·형식 통과·근거 통과 스키마(Zod) 정의
  2. 2-3일 · LLM 추출 + 형식·근거 검사LLM IOC 추출(원문 span 인용 강제) + 타입별 정규식 형식 검증 + defang 정규화 + 원문 미근거 거름 규칙
  3. 4-5일 · 근거를 들어 적재/검토/거름 결정프롬프트 v1(추출 + 원문 인용) + Zod 로 스키마 검증 + 규칙으로 결정
  4. 6일 · IOC 추출 적재 게이트 화면리포트별 추출 그리드 + 적재 카드(IOC·타입·근거 span) + 거름 사유 + PostgreSQL 적재
  5. 7일 · 7일치 시연 영상 + 심은 정답과 비교한 기준선여기까지가 1주차 완성품입니다
2주차선택 성장

적재가 맞았는지 확인

적재 판정을 심은 정답 IOC·검토자 2명 라벨과 비교해 정밀도·재현율과 일치도를 보여주는 화면입니다.

  1. 8-9일 · 검토자 2명이 적재 라벨링심은 정답 IOC 대비 정밀도·재현율 + 검토 가이드
  2. 10-11일 · 판정 신뢰도 보강일치도 측정(Cohen's κ: 두 사람 답이 우연 이상으로 일치하는 정도, 0~1) + 오적재 사례 정리
  3. 12일 · 원문 미근거 지표 자동 차단원문 span 매칭 + 별도 LLM 검사 + 5% 사람 점검
3주차선택 성장

리포트 파이프라인 + 타입별 정합성 추이

Kafka 로 들어오는 신규 리포트를 Airflow 로 수집·추출·검증·적재까지 자동화하고, Spark 로 도메인·IOC 타입별 적재 정합성과 거름 사유 분포를 집계해 약한 추출을 보여주는 화면입니다.

  1. 15-17일 · 리포트 파이프라인 자동화Kafka 유입 이벤트 + Airflow 로 수집·추출·검증·적재 오케스트레이션
  2. 18-21일 · 타입별 정합성 추이 + 통합 시연 영상Spark 로 도메인·IOC 타입별 적재 정합성·거름 사유 집계 + 실제 도입 계획(실 리포트 포맷·실 검토자 교체) 포함

데모 · 측정 지표

01

추출 시나리오 15종(정상 IOC·지어낸 지표·형식 위반·defang 표기)을 넣으면, 추출·형식 검증·근거·적재 결정이 몇 초 안에 나오는 걸 시연합니다

02

일부러 만든 악성·결측 입력 30종(defang 표기 흔들림·형식 위반·원문 미근거·미등록 타입·근거 span 결측)을 넣어도 출력 형식(스키마)이 한 번도 안 깨집니다

03

더미에 심은 정답 IOC 45건 중 적재/거름 판정이 일치한 게 40건(약 89%)입니다. 단, 정답·데이터를 모두 작성자가 만든 합성 기준이라 '성능 검증'이 아니라 '데모 조건에서의 동작'임을 명시합니다

정직 경계선

진짜 성능 검증은 여기서 멈춥니다. 위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 정밀도·재현율은 에스투더블유의 실 위협 리포트와 실 검토자가 있어야 측정 가능합니다. 이 게이트는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다

미리 알아둬야 할 것들

이건 고객·실데이터 없이 혼자 만든 포트폴리오입니다. 모든 수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명하는 게 오히려 신뢰를 줍니다

정답을 작성자가 만들었으니 잘 맞는 게 당연합니다. 그래서 defang 표기 흔들림·형식 위반·원문 미근거·미등록 타입 같은 경계 케이스를 더미에 일부러 섞어, 쉬운 추출만 통과시키는 게 아님을 보여줍니다

이 포트폴리오가 입증하는 것은 비정형 문서에서의 LLM 추출 + 정규식 형식 검증 + 원문 근거 대조 + 구조화 적재 기술입니다. 실제 위협 판정·다크웹 분석·악성 여부 결정 같은 에스투더블유의 보안·위협 인텔 도메인 전문성은 포트폴리오로 증명되지 않으므로 주장하지 않으며, 그 깊이는 실제 보안 분석가의 몫이고 면접에서 모르면 모른다고 말하는 편이 낫습니다. 데모는 합성 위협 리포트로 기술만 입증합니다

LLM 이 뽑은 IOC 는 그럴듯해도 원문에 없을 수 있습니다. IOC 마다 원문 span 인용을 달게 하고, defang 정규화 후에도 원문에서 못 찾으면 '미근거'로 걸러 구조화 자산에 적재하지 않습니다

IOC 표기가 제각각입니다(hxxp·[.]·대소문자). 정규화로 같은 값으로 묶고, 못 묶은 건 추측하지 말고 '미정규화'로 알립니다. 실제 도입 시 리포트 포맷·IOC 타입 사전이 더미와 다르므로 정규식·enum 을 다시 맞춰야 합니다(도입 단계 과제로 분리)

더미 데이터

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

ioc_extractionsTABLE· 11 rows

위협 리포트에서 뽑은 IOC 추출·적재 로그. 형식·근거 규칙이 가장 먼저 질의하는 테이블입니다. defang 표기 흔들림·형식 위반·원문 미근거·미등록 타입을 일부러 섞고, label 로 정답을 심어 자가채점합니다.

② ioc_extractions.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 11)
ioc_idreport_idraw_valuenormalized_valueioc_typeformat_validgroundedsource_spanlabelts
ioc_001rpt_01malicious-c2[.]commalicious-c2.comdomaintruetrueC2 도메인 malicious-c2[.]com 이 확인되었습니다load2026-04-02T09:00
ioc_002rpt_01203.0.113.55203.0.113.55ipv4truetrue해당 IP 203.0.113.55 로 비콘 트래픽 발생load2026-04-02T09:10
ioc_003rpt_01999.1.1.1—ipv4falsetrue출처 999.1.1.1reject2026-04-02T09:20
ioc_004rpt_02e3b0c44298fc1c149afbf4c8996fb92427ae41…e3b0c44298fc1c149afbf4c8996fb92427ae41…sha256truefalse—reject2026-04-02T10:00
ioc_005rpt_02hxxp://drop .evil-host .net/xhttp://drop.evil-host.net/xdomaintruetrue페이로드는 hxxp://drop .evil-host .net/x 에서…load2026-04-02T10:20
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 Zod 스키마에 맞는 IOC 추출 60행 JSON 배열로 생성합니다. 리포트 4~5개, IOC 타입 분포, 정상 위주에 거름·검토를 섞습니다. label 규칙: format_valid=false 또는 grounded=false → reject, ioc_type=unknown 또는 normalized_value=null(정규화 실패) → review, 그 외(형식·근거·정규화 모두 정상) → load.

z.object({ ioc_id: z.string(), report_id: z.string(), raw_value: z.string(), normalized_value: z.string().nullable(), ioc_type: z.enum(["domain","ipv4","sha256","md5","cve","email","unknown"]), format_valid: z.boolean(), grounded: z.boolean(), source_span: z.string().nullable(), label: z.enum(["load","review","reject"]), ts: z.string() })

쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 추출만 통과시키는 함정 회피): (1) defang·표기 흔들림(같은 도메인의 'evil[.]com'/'EVIL[.]COM'/'hxxp://evil .com' 처럼 normalized_value 로 같은 값이 돼야 함) 3건 이상, (2) 형식 위반: 옥텟이 255 초과인 IPv4·63자짜리 SHA256·31자짜리 MD5 등 format_valid=false 2건 이상, (3) 원문 미근거: grounded=false, source_span=null 인 지어낸 지표 2건, (4) 미등록 타입: ioc_type=unknown 2건(review), (5) 경계값: 정규화 실패(normalized_value=null)로 review 되는 케이스 1~2건. label 은 위 규칙대로 정직하게. 진짜 스키마 위반(타입 깨짐)은 데이터가 아니라 별도 '형식 깨뜨리기 시도 3건' 지시로만 재현. JSON 배열만.
schema (3 층의 단일 출처)
z.object({ ioc_id: z.string(), report_id: z.string(), raw_value: z.string(), normalized_value: z.string().nullable(), ioc_type: z.enum(["domain","ipv4","sha256","md5","cve","email","unknown"]), format_valid: z.boolean(), grounded: z.boolean(), source_span: z.string().nullable(), label: z.enum(["load","review","reject"]), ts: z.string() })

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

기술 스택 매핑
PythonIOC 추출 파서·정규식 형식 검증·원문 근거 매칭·API 를 구현하는 언어입니다(FastAPI·asyncio·Pydantic)
FastAPI리포트 업로드에서 추출·검증·적재까지 처리하는 게이트 API 서버입니다
LLM리포트 문서에서 IOC·관계 후보를 뽑고 근거 span 을 인용하는 추출 엔진입니다
PostgreSQL적재된 구조화 IOC 자산과 판정 로그를 저장하는 주 저장소입니다
MongoDB원본 비정형·반정형 위협 리포트 문서를 그대로 담는 저장소입니다
Elasticsearch적재된 IOC 와 리포트 전문을 색인해 검색·조회하는 인덱스입니다
Kafka신규 리포트 유입 이벤트를 흘려보내 추출 파이프라인을 트리거하는 스트림입니다(3주차)
Spark도메인·IOC 타입별 적재 정합성과 거름 사유 분포를 대량 집계하는 배치입니다(3주차)
Airflow수집에서 추출·검증·적재까지 리포트 파이프라인을 오케스트레이션합니다(3주차)
Kubernetes게이트 API 와 추출 워커 컨테이너를 배포·스케일하는 실행 환경입니다
Docker추출·검증 서비스를 컨테이너로 패키징합니다
Java대용량 리포트 수집을 담당하는 기존 Java 배치와 붙는 연동 어댑터입니다
ClaudeIOC·관계 추출과 근거 span 인용을 맡는 LLM 입니다
LLM 선택
model
Claude Sonnet (IOC·관계 추출·근거 span 인용) + GPT-4o-mini (LLM-as-judge 원문 미근거 IOC 검출)
prompt
few-shot 3 예시 + 출력 스키마(Zod) 강제 + IOC 마다 원문 span 인용 강제 + defang(hxxp·[.] 등 무해화 표기) 정규화 지시 + 근거 없으면 거름 가드 + 후행 judge
rationale
적재 통과 여부는 정규식 형식 검증과 원문 substring 근거 규칙이 결정하므로 LLM 환각이 구조화 자산을 오염시키지 못합니다. 추출 품질에 Sonnet 을, judge 는 비용·속도 우선으로 mini 를 씁니다. 별도 지식 검색이 필요 없어 RAG 는 리포트 원문 안에서의 근거 매칭으로 최소화합니다.
결정 게이트
1주차 끝게이트가 리포트에서 IOC 를 추출하고 정규식 형식·원문 근거·정규화를 검사해 통과만 적재하고 형식 위반·미근거를 거르는가. 여기까지가 그 자체로 제출 가능한 완성품입니다.

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

2주차 끝적재 판정이 심은 정답 IOC·검토자 라벨로 맞다고 확인되고 정밀도·재현율과 일치도가 붙는가.

✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(리포트 파이프라인 + 타입별 정합성 추이)로 진행합니다.

재사용 레이어 · 코어 70% / 도메인 30%
core (재사용 가능)
  • IOC 추출 파서 + 출력 스키마(Zod) 강제
  • 정규식 형식 검증 + 원문 근거 substring 대조 규칙 엔진
  • defang·별칭 정규화기(원본 표기와 정규화 값 분리)
  • 리포트별 추출 그리드·적재 카드·거름 사유 컴포넌트
  • 근거 없는 지어낸 지표 차단 가드 + LLM-as-judge 원문 매칭
  • 5% 사람 spot-check 샘플러 + 거름 알림·정합성 리포트 봇
domain (교체 대상)
  • IOC 타입 enum(domain·ipv4·sha256·md5·cve 등)과 타입별 정규식 사전
  • 검토자 페르소나·라벨 가이드
  • 추출 대상 문서 포맷과 정규화 규칙은 도메인별로 갈아끼웁니다
출력 스키마 · ioc_load_decision

IOC 1건의 적재 결정 카드. 결정·요인·근거를 한 스키마로 담아 화면 카드에 씁니다. 악성 여부 판정이 아니라 형식·근거 정합성 게이트입니다.

schema (JSON Schema)
z.object({ ioc_id: z.string(), report_id: z.string(), decision: z.enum(["load","review","reject"]), factors: z.array(z.enum(["format_invalid","ungrounded","unnormalized","unknown_type","ambiguous_defang"])), reason: z.string().min(20), evidence: z.string().min(8), hedge: z.string().nullable() })
모범 출력 (3)
[
  {
    "input_ref": "ioc_003 (IPv4 형식 위반)",
    "output": {
      "ioc_id": "ioc_003",
      "report_id": "rpt_01",
      "decision": "reject",
      "factors": [
        "format_invalid"
      ],
      "reason": "999.1.1.1 은 옥텟이 255 를 넘어 IPv4 정규식을 통과하지 못합니다. 형식이 깨진 값은 구조화 자산에 적재하지 않고 거릅니다.",
      "evidence": "raw_value=999.1.1.1, format_valid=false",
      "hedge": "형식이 유효하지 않아 적재하지 않습니다"
    }
  },
  {
    "input_ref": "ioc_004 (원문 미근거)",
    "output": {
      "ioc_id": "ioc_004",
      "report_id": "rpt_02",
      "decision": "reject",
      "factors": [
        "ungrounded"
      ],
      "reason": "해당 SHA256 값이 리포트 원문에서 근거 span 으로 확인되지 않아 LLM 이 지어냈을 수 있습니다. 근거 없는 지표는 자산에 적재하지 않습니다.",
      "evidence": "grounded=false, source_span=null",
      "hedge": "원문 근거가 없어 적재하지 않습니다"
    }
  },
  {
    "input_ref": "ioc_009 (미등록 타입)",
    "output": {
      "ioc_id": "ioc_009",
      "report_id": "rpt_03",
      "decision": "review",
      "factors": [
        "unknown_type",
        "unnormalized"
      ],
      "reason": "TA-0xNova 는 등록된 IOC 타입 정규식에 맞지 않아 형식으로 확정할 수 없습니다. 위협 행위자명으로 보이나 자동 판정 대상이 아니라 사람 검토로 돌립니다.",
      "evidence": "ioc_type=unknown, normalized_value=null",
      "hedge": "타입 미등록이라 적재하지 않고 검토로 둡니다"
    }
  }
]
검증 노트 (자동 vs 수동)

[자동 검증] 1. Zod parse 로 출력 형식(필드·enum)이 스키마를 통과하는지 확인합니다. 2. decision 이 형식·근거 규칙(형식 위반/원문 미근거→reject·미등록 타입/정규화 실패→review·통과→load)과 일치하는지 봅니다. 3. evidence 가 입력 IOC 의 실제 값·플래그 인용인지 토큰 매칭으로 확인하고, grounded=false 면 load 가 되지 않게 강제합니다. 4. decision 을 심은 정답 label 과 비교해 정밀도·재현율을 계산합니다. [수동 검증] 1. 검토자 2명이 비동기로 적재를 라벨링해 정밀도·재현율과 bootstrap Cohen's κ(두 사람 일치가 우연 이상인 정도, 0~1) 하한 0.6 이상을 봅니다. 2. 전체의 5% 를 사람이 직접 점검합니다.