이투스교육
경력근거: 반복 운영 업무를 LLM 에이전트로 대체하기 위한 워크플로우 설계
※ 실제 산출물이 아닌 AI 예측 시안입니다.
이투스에듀는 20여 년 온·오프라인 교육사업으로 축적한 대규모 학원 운영 데이터를 보유합니다. 어떤 운영 질문이 어떤 사내 테이블로 풀리는지는 이투스에듀의 실제 데이터 카탈로그가 있어야 grounding 되고, ‘질문 → 추출 → 검증’ 으로 이어지는 사슬은 다른 회사 데이터로는 그대로 만들 수 없습니다.
‘반복 운영 업무를 LLM 에이전트로 대체’ 가 명시된 업무입니다. 질문 → 데이터 추출 → 요약 리포트 한 루프가 닫혀야 ‘대체’ 가 측정됩니다.
프롬프트·RAG·MCP 로 LLM 에이전트 파이프라인을 설계합니다. 사내 데이터 카탈로그를 검색해 질문을 grounding 하는 게 핵심입니다.
사내 임직원 대상 LLM 기반 서비스·도구를 zero to one 으로 만듭니다. 1주는 추출·요약·발송까지 끝나는 최소 완결 단위입니다.
임직원이 던진 운영 질문에 사내 데이터 카탈로그를 붙여, 어떤 테이블을 봐야 하는지 찾고 추출·요약 결과를 한 화면에서 봅니다. LLM 이 답과 근거(참조 테이블·컬럼)를 함께 내고, 매일 아침 슬랙으로 운영 리포트를 보냅니다. 1주차만으로 완성품이고, 답이 실제 데이터와 맞는지 검증(2주차)·반복 업무 에이전트 자동화(3주차)로 키웁니다.
이투스에듀 데이터 프로덕트 엔지니어입니다. ‘이 숫자 좀 뽑아줘’ 류 반복 운영 요청을 매번 손으로 처리하던 일을 끝내고, 답이 실제 데이터와 맞는지까지 근거로 보여주고 싶은 사람입니다.
운영 질문을 한 스키마로 받고 사내 데이터 카탈로그로 grounding 하면, LLM 이 (a) 참조할 테이블·컬럼을 찾고 (b) 추출·요약 결과를 근거와 함께 답하며, (c) 실제 추출값과 맞춰 그 답이 옳았는지 검증합니다.
운영 질문을 받아 사내 카탈로그에서 참조 테이블을 찾고, 추출·요약 결과를 근거와 함께 내어 매일 아침 슬랙으로 보내는 동작하는 도구입니다. 사내 실DB 대신 합성 운영 테이블과 카탈로그 메타데이터를 가정해 1주에 혼자 완성합니다.
LLM 이 만든 추출 쿼리·요약 수치를 실제 합성 테이블 집계값과 맞춰보고, 운영 검토자 2명이 답이 타당한지 라벨링해 정확도·신뢰도를 보여주는 대시보드입니다.
검증된 질의 패턴을 정기 잡으로 등록해, 보고서·알람·태스크를 사람 개입 없이 매일 자동 생성하는 단계입니다.
운영 질문 한 건을 넣으면, 참조 테이블과 추출·요약 결과가 근거와 함께 몇 초 안에 나오는 걸 시연합니다
일부러 만든 악성·결측 입력 30종(모호한 질문·미등록 테이블·별칭 표기)을 넣어도 출력 형식(Zod 스키마)이 한 번도 안 깨지는 걸 보여줍니다
매일 아침 슬랙으로 운영 리포트가 자동 발송되는 걸 14일치 시연으로 보여줍니다
내가 만든 정답 30개 중 참조 테이블이 정확히 일치한 게 26개(87%)입니다. 단, 정답과 데이터를 모두 작성자가 만든 합성 기준이라 ‘성능 검증’ 이 아니라 ‘데모 조건에서의 동작’ 임을 밝힙니다
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 추출 정확도·일치도는 이투스에듀 실 운영 데이터와 실 운영 검토자가 있어야 측정됩니다. 이 도구는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다
이건 고객·실데이터 없이 혼자 만든 포트폴리오입니다. 모든 수치는 합성 데이터 자가채점이라 ‘성능 증명’ 이 아닙니다. 면접에서 ‘데모 조건 동작 + 실검증 준비 상태’ 로 솔직히 설명합니다
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 헷갈리는 모호한 질문·미등록 테이블·경계 케이스를 더미에 일부러 섞어, 쉬운 문제만 푸는 게 아님을 보여줍니다
LLM 이 없는 테이블을 그럴듯하게 지어내는 환각 위험이 있습니다. 카탈로그 RAG 로 grounding 하고, 참조 테이블이 카탈로그에 실재하는지 자동 검사해 미실재면 차단합니다
질문의 팀명·지표 표기가 제각각입니다. 별칭 사전 + 임베딩으로 같은 대상으로 묶고, 못 묶은 건 추측하지 말고 ‘대상 불명’ 으로 알립니다
실제 도입 시 달라지는 점을 명시합니다. 실 사내DB 스키마·권한은 더미와 다르므로 카탈로그를 다시 맞춰야 하고, 운영 검토자도 실제 인력으로 교체해야 합니다(도입 단계 과제로 분리)
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
임직원이 던진 사내 운영 질문 로그입니다. 에이전트가 가장 먼저 해석하는 입력입니다. 운영 현실대로 결측(대상 테이블 불명)·모호한 질문·별칭 팀명·경계값을 일부러 섞어, 쉬운 데이터만 푸는 게 아님을 보여줍니다.
| req_id | date | requester_team_raw | requester_team_id | question | target_dataset_id | recurring | priority |
|---|---|---|---|---|---|---|---|
| rq_0001 | 2026-05-04 | 온라인사업본부 | t_online | 지난주 수강 신청 전환율 좀 뽑아줘 | d_enroll | true | high |
| rq_0002 | 2026-05-04 | 마케팅팀 | t_mkt | 5월 광고 유입 채널별 결제액 정리해줘 | d_payment | true | mid |
| rq_0003 | 2026-05-05 | 온라인본부 | t_online | 환불 사유 상위 5개 알려줘 | d_refund | false | mid |
| rq_0004 | 2026-05-05 | 콘텐츠팀 | t_content | 강의별 완강률 어떻게 돼? | d_progress | true | high |
| rq_0005 | 2026-05-06 | 신사업TF | — | 요즘 잘 나가는 거 뭐야? | — | false | low |
아래 Zod 스키마에 맞는 에듀테크 사내 운영 질문 로그 40행 JSON 배열로 생성. 팀 5~7개, 질문 유형(수강·결제·환불·완강·출결·문의) 분포 포함.
{"type":"object","properties":{"req_id":{"type":"string"},"date":{"type":"string"},"requester_team_raw":{"type":"string"},"requester_team_id":{"type":["string","null"]},"question":{"type":"string"},"target_dataset_id":{"type":["string","null"]},"recurring":{"type":"boolean"},"priority":{"type":"string","enum":["low","mid","high"]}},"required":["req_id","date","requester_team_raw","requester_team_id","question","target_dataset_id","recurring","priority"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 문제만 푸는 함정 회피): (1) 같은 팀의 별칭 표기 혼입('온라인사업본부'/'온라인본부'→requester_team_id t_online 로 정규화돼야 함), (2) 대상 테이블이 모호해 target_dataset_id=null 인 질문 3~4건('요즘 잘 나가는 거 뭐야' 류), (3) data_catalog 에 없는 orphan target_dataset_id 1건(d_settlement_unknown), (4) requester_team_id=null(미등록 신규 팀) 1~2건. JSON 배열만.{"type":"object","properties":{"req_id":{"type":"string"},"date":{"type":"string"},"requester_team_raw":{"type":"string"},"requester_team_id":{"type":["string","null"]},"question":{"type":"string"},"target_dataset_id":{"type":["string","null"]},"recurring":{"type":"boolean"},"priority":{"type":"string","enum":["low","mid","high"]}},"required":["req_id","date","requester_team_raw","requester_team_id","question","target_dataset_id","recurring","priority"]}사내 데이터 카탈로그(테이블 표준 ID + 별칭·설명·PII 등급)입니다. RAG grounding 의 진실원으로, 질문이 어떤 테이블로 풀리는지 찾는 근거입니다. menu_master 처럼 별칭과 결측·orphan 을 섞어 환각·미매핑을 만났을 때도 안 깨지는지 보여줍니다.
| dataset_id | canonical_name | aliases | owner_team_id | pii_level | description |
|---|---|---|---|---|---|
| d_enroll | 수강신청 | ["수강 신청","등록"] | t_online | low | 강의별 수강 신청·전환 로그 |
| d_payment | 결제 | ["결제내역","매출"] | t_fin | high | 결제·채널별 매출·ROAS 원천 |
| d_refund | 환불 | ["환불내역","취소"] | t_fin | high | 환불 사유·금액 로그 |
| d_progress | 수강진도 | ["완강률","진도"] | t_content | low | 강의별 학습 진도·완강률 |
| d_ticket | 문의티켓 | ["CS티켓","문의"] | t_cs | low | 고객 문의 유형·처리 로그 |
아래 Zod 스키마에 맞는 에듀테크 사내 data_catalog 30행 JSON 배열로 생성. 같은 테이블이 별칭 1~3개를 가지도록.
{"type":"object","properties":{"dataset_id":{"type":"string"},"canonical_name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"owner_team_id":{"type":["string","null"]},"pii_level":{"type":"string","enum":["none","low","high"]},"description":{"type":"string"}},"required":["dataset_id","canonical_name","aliases","owner_team_id","pii_level","description"]}
쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) owner_team_id=null(담당 미지정 테이블) 1~2건, (2) pii_level high 테이블 3건 이상(결제·환불·회원 등). 그 외 분포 자연스럽게. JSON 배열만.{"type":"object","properties":{"dataset_id":{"type":"string"},"canonical_name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"owner_team_id":{"type":["string","null"]},"pii_level":{"type":"string","enum":["none","low","high"]},"description":{"type":"string"}},"required":["dataset_id","canonical_name","aliases","owner_team_id","pii_level","description"]}| Python | ingest 파이프라인 + 에이전트 오케스트레이션(질문→추출계획→실행→요약) + eval 스크립트 |
| LLM | 운영 질문 해석 → 참조 테이블 선택 → 추출 결과 요약 생성 |
| RAG | 사내 데이터 카탈로그(테이블·컬럼·설명) 검색으로 질문을 grounding, 환각 추출 방지 |
| Claude | 생성·요약 모델(Claude Code 류 에이전트로 빠른 프로토타이핑) |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(답이 실제 데이터와 맞는지 검증)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(반복 업무 에이전트 자동화)로 진행합니다.
1) 질문별 추출 답변 카드(추출 계획·결과 요약·참조 근거), 2) 참조 테이블·컬럼 인용, 3) 다음 검증 주기 실측 집계로 추출 적중 검증. 질문→추출→검증 한 주기를 한 스키마에 담습니다.
{"type":"object","properties":{"period":{"type":"string"},"answers":{"type":"array","items":{"type":"object","properties":{"req_id":{"type":"string"},"resolved_dataset_id":{"type":["string","null"]},"extraction_plan":{"type":"string","minLength":20},"summary":{"type":"string","minLength":20},"evidence_refs":{"type":"array","items":{"type":"object","properties":{"dataset_id":{"type":"string"},"column":{"type":"string"}},"required":["dataset_id","column"]},"minItems":1},"hedge":{"type":["string","null"],"minLength":8}},"required":["req_id","resolved_dataset_id","extraction_plan","summary","evidence_refs","hedge"]},"minItems":3,"maxItems":8},"verification":{"type":["object","null"],"properties":{"prior_period":{"type":"string"},"exact_match_rate":{"type":"number"},"brier_score":{"type":"number"},"checks":{"type":"array","items":{"type":"object","properties":{"req_id":{"type":"string"},"predicted_value":{"type":"number"},"actual_value":{"type":"number"},"exact_match":{"type":"boolean"},"confidence_prob":{"type":"number"}},"required":["req_id","predicted_value","actual_value","exact_match","confidence_prob"]}}},"required":["prior_period","exact_match_rate","brier_score","checks"]}},"required":["period","answers","verification"]}[
{
"input_ref": "2026-05-11 주간 (verification 은 직전 주 답변 결과)",
"output": {
"period": "2026-05-11",
"answers": [
{
"req_id": "rq_0001",
"resolved_dataset_id": "d_enroll",
"extraction_plan": "d_enroll 에서 지난주 신청수/방문수로 전환율 집계, 강의 카테고리별 분해.",
"summary": "지난주 전환율 4.2%. 전주 3.8% 대비 +0.4%p. 입시 카테고리가 견인.",
"evidence_refs": [
{
"dataset_id": "d_enroll",
"column": "converted"
},
{
"dataset_id": "d_enroll",
"column": "visits"
}
],
"hedge": "주말 프로모션 영향 미통제. 카테고리 일반화 주의."
},
{
"req_id": "rq_0002",
"resolved_dataset_id": "d_payment",
"extraction_plan": "d_payment 와 d_ad 조인해 채널별 결제액 합산.",
"summary": "검색광고 결제액 1위(전체 38%), 다음 SNS 27%.",
"evidence_refs": [
{
"dataset_id": "d_payment",
"column": "amount"
},
{
"dataset_id": "d_ad",
"column": "channel"
}
],
"hedge": "환불 차감 전 기준. 순매출과 차이 가능."
},
{
"req_id": "rq_0005",
"resolved_dataset_id": null,
"extraction_plan": "질문이 모호해 대상 테이블 특정 불가. ‘잘 나가는 거’ 의 지표(매출/수강/완강) 확인 필요.",
"summary": "대상 불명. 어떤 지표 기준인지 되물어야 합니다.",
"evidence_refs": [
{
"dataset_id": "d_payment",
"column": "amount"
}
],
"hedge": "질문 모호. 추측 대신 재질의 권장."
}
],
"verification": {
"prior_period": "2026-05-04 ~ 2026-05-10 답변",
"exact_match_rate": 0.83,
"brier_score": 0.14,
"checks": [
{
"req_id": "rq_0001",
"predicted_value": 4.2,
"actual_value": 4.2,
"exact_match": true,
"confidence_prob": 0.85
},
{
"req_id": "rq_0002",
"predicted_value": 38,
"actual_value": 37,
"exact_match": false,
"confidence_prob": 0.7
},
{
"req_id": "rq_0004",
"predicted_value": 61,
"actual_value": 61,
"exact_match": true,
"confidence_prob": 0.8
}
]
}
}
},
{
"input_ref": "2026-05-18 주간",
"output": {
"period": "2026-05-18",
"answers": [
{
"req_id": "rq_0006",
"resolved_dataset_id": "d_ticket",
"extraction_plan": "d_ticket 에서 이번달 문의 유형별 카운트 집계.",
"summary": "결제 문의 34%, 수강 오류 22%, 환불 18% 순.",
"evidence_refs": [
{
"dataset_id": "d_ticket",
"column": "category"
}
],
"hedge": "미분류 티켓 6% 제외 집계."
},
{
"req_id": "rq_0008",
"resolved_dataset_id": null,
"extraction_plan": "‘미정산 테이블’ 이 카탈로그에 실재하지 않음. d_settlement_unknown 미등록.",
"summary": "참조 테이블이 카탈로그에 없어 답변 보류. 테이블 등록 필요.",
"evidence_refs": [
{
"dataset_id": "d_payment",
"column": "settled"
}
],
"hedge": "환각 방지로 미실재 테이블 추정 차단."
},
{
"req_id": "rq_0011",
"resolved_dataset_id": "d_payment",
"extraction_plan": "d_payment·d_ad 조인해 채널별 ROAS(매출/광고비) 산출.",
"summary": "검색광고 ROAS 420%, SNS 280%, 디스플레이 150%.",
"evidence_refs": [
{
"dataset_id": "d_payment",
"column": "amount"
},
{
"dataset_id": "d_ad",
"column": "spend"
}
],
"hedge": "기여 모델 단순 last-click. 다채널 기여 미반영."
}
],
"verification": {
"prior_period": "2026-05-11 ~ 2026-05-17 답변",
"exact_match_rate": 0.83,
"brier_score": 0.15,
"checks": [
{
"req_id": "rq_0001",
"predicted_value": 4.5,
"actual_value": 4.4,
"exact_match": false,
"confidence_prob": 0.7
},
{
"req_id": "rq_0006",
"predicted_value": 34,
"actual_value": 34,
"exact_match": true,
"confidence_prob": 0.85
},
{
"req_id": "rq_0011",
"predicted_value": 420,
"actual_value": 420,
"exact_match": true,
"confidence_prob": 0.8
}
]
}
}
},
{
"input_ref": "2026-05-25 주간",
"output": {
"period": "2026-05-25",
"answers": [
{
"req_id": "rq_0004",
"resolved_dataset_id": "d_coupon",
"extraction_plan": "d_coupon 에서 발급·사용 건수를 주차별로 집계합니다.",
"summary": "발급 대비 사용률 31%로 지난주와 같습니다.",
"evidence_refs": [
{
"dataset_id": "d_coupon",
"column": "used_at"
}
],
"hedge": "만료 쿠폰을 분모에 넣었습니다."
},
{
"req_id": "rq_0005",
"resolved_dataset_id": null,
"extraction_plan": "요청이 가리키는 데이터셋을 카탈로그에서 찾지 못했습니다.",
"summary": "대상 테이블을 확인한 뒤 다시 요청해 주십시오.",
"evidence_refs": [],
"hedge": "요청 문구만으로는 대상이 하나로 좁혀지지 않았습니다."
}
],
"verification": {
"prior_period": "2026-05-18 응답",
"resolve_rate": 0.5,
"hits": [
{
"req_id": "rq_0006",
"resolved": true,
"owner_ok": true,
"hit": true
},
{
"req_id": "rq_0008",
"resolved": false,
"owner_ok": false,
"hit": true
}
]
}
}
}
]자동: (1) Zod parse, (2) evidence_refs.dataset_id 가 data_catalog 에 실재하는지 검사(환각 테이블 차단), (3) 단정 표현 토큰 검출 + LLM-as-judge 근거 인용 평가, (4) Brier score 자동 계산. predicted_value 는 합성 기준 추정값이라 검증된 수치가 아님을 카드 hedge 에 드러냅니다. 수동: 운영 검토자 2명 비동기 라벨 → bootstrap Cohen’s κ CI 하한 ≥ 0.6, spot check 5%. verification 은 차주 실측 집계 자동 조인.
근거: 반복 운영 업무를 LLM 에이전트로 대체하기 위한 워크플로우 설계