Files
aio-01d4-stu/Lecture/78/03-STAGE3-QUALITY-MANAGEMENT.md
T

18 KiB
Raw Blame History

3단계 · 품질 관리

  • 교시: 5교시 강의 (14:0014:50) · 6교시 Lab 03 실습 5개 (15:0015:50)
  • 이 단계가 끝나면: FAQ에 박힌 규칙을 스키마(규칙을 적은 데이터)로 꺼내 다른 데이터에도 쓰고, 스키마로 되는 규칙과 안 되는 규칙을 나누고, 격리된 줄이 고쳐져 돌아오면 격리함을 비우는 되돌림 고리를 만들고, 새 데이터셋을 워크플로우를 고치지 않고 늘리고, 품질 기록으로 보고서 · 데이터셋별 품질을 정의대로 말할 수 있다.
  • 숫자: 모두 강사 노트북 실측입니다 (65일차 n8n 2.42.6, 78일차 판 데이터 API의 스키마 셋 faq · employee · ticket, 직원 CSV 9줄 · 접수 건 9줄 · FAQ 배치, 11/01 정답 워크플로우를 학생 순서대로 1회).
  • 실습 가리키기: 이 문서에서 "Lab 03 예제 1"은 6교시 Lab 03 문서의 그 절입니다. 파일 경로는 실습 폴더 ~/aio-01d4-stu/Last3Mon/78 기준입니다.
flowchart LR
  A["1. 스키마"] --> B["2. 되는 것 · 안 되는 것"] --> C["3. 되돌림 고리"] --> D["4. 설정으로 넓히기"]
  D --> E["5. 품질 보고서"] --> F["6. 데이터셋별"] --> G["7. 하루를 한 그림으로"]

0. 이 시간 (50분)

시간 절 · 개요 하는 일
14:00~14:10 1 · 개요 22장 스키마: 규칙을 데이터로
14:10~14:16 2 · 개요 23장 스키마로 되는 것 · 안 되는 것
14:16~14:22 3 · 개요 24장 격리 → 고침 → 다시 → 빼기
14:22~14:28 4 · 개요 25장 새 스키마, 스키마 변경 = 규칙 변경
14:28~14:40 5 · 6 · 개요 26~27장 품질 보고서의 정의, 데이터셋별 · 평균이 가리는 것
14:40~14:50 7 · 8 · 확인 질문 하루 정리 표, 자주 하는 실수

6교시 Lab 03에서 이어서 하는 것

6교시 실습 (시각) 이 강의의 절 실습에서 하는 일 쓰는 파일 · 명령
Lab 03 예제 1 (15:00~15:14) 1 · 2 FAQ 검사에 직원 CSV(전), 스키마 검사 call my-faq-check requests/employees-new.json, my-work/check.json (새로) → lab03 4/4, QUALITY.md 8절
Lab 03 예제 2 (15:14~15:22) 3 고친 줄을 격리함에서 빼기 my-work/faq-import.json 고치기, test cases/lab03-fix.json -v (전 3/4 → 4/4)
Lab 03 예제 3 (15:22~15:28, 에이전트 없이) 4 새 스키마 ticket call my-faq-check requests/tickets-new.json, test cases/lab03-schema.json -v
Lab 03 과제 1 (15:28~15:40) 5 품질 보고서 my-work/quality-report.json (새로), 테스트 cases/lab03-challenge.json → QUALITY.md 9절
Lab 03 과제 2 (15:40~15:50) 6 검사도 기록 · 데이터셋별 두 파일 고치기, 테스트 cases/lab03-challenge2.json

1. 스키마: 규칙을 데이터로 (6교시 Lab 03 예제 1)

일반 설명

생활 속 예 · 품목마다 다른 검수 카드. 채소는 무른 곳, 고기는 온도와 라벨, 생선은 눈 색을 봅니다. 품목마다 주방장을 따로 두지 않고 품목마다 검수 카드를 만들어 두면, 한 사람이 카드를 바꿔 들고 무엇이든 검수합니다. 새 품목이 오면 카드를 한 장 더 만듭니다.

스키마(schema)는 데이터의 모양을 적은 데이터입니다. 어떤 칸이 있고, 칸마다 타입은 무엇이고, 꼭 있어야 하는지, 범위는 어떤지. 검사 코드는 칸 이름을 모르고 타입마다 판정합니다: "이 칸은 email이니 메일 꼴인지", "이 칸은 enum이니 목록 안에 있는지". 그러면 데이터가 늘어도 검사 코드는 그대로이고 스키마만 늘어납니다.

업계에서 같은 생각
JSON Schema · OpenAPI API 요청 · 응답의 모양
데이터베이스 테이블 정의 NOT NULL · CHECK · UNIQUE
Great Expectations · Soda · dbt tests 데이터셋마다 "기대값" 목록
pydantic · zod 코드 안의 모델 (스키마를 코드로 씀)

CSV. 회사 데이터는 CSV로 많이 옵니다. 첫 줄이 열 이름이고, 값은 모두 글자입니다. 그래서 날짜 · 메일도 "글자의 꼴"로 판정하고, 줄 번호는 사람이 세는 번호(열 이름 줄을 빼고 1부터)로 돌려줍니다.

오늘 실습에서

Lab 01의 FAQ 검사에 인사팀의 직원 CSV를 보내면 400 (items가 없음) — FAQ의 칸 이름과 규칙이 Code에 박혀 있습니다 (Lab 03 예제 1 고치기 전). 스키마 검사 my-check는 GET /schemas/employee를 읽어:

줄 값 코드 스키마의 규칙
3 minsu.kang@example bad_format:email email
4 마케팅팀 not_allowed:dept enum 여섯 팀
5 2026-13-01 bad_format:joined date — 실제 있는 날
6 이름 빈칸 missing:name required
8 7째와 같은 메일 duplicate_in_batch key: email
  • 9줄 중 4줄 통과. 빈 전화(2째)와 사무실 번호(7째)는 통과 — 선택 칸은 비면 형식을 보지 않습니다. 같은 워크플로우로 schema: faq B-3 → 6줄 중 5줄 (FAQ-305 too_short:answer).

2. 스키마로 되는 것 · 안 되는 것 (6교시 Lab 03 예제 1)

일반 설명

생활 속 예 · 검수 카드에 없는 칸. 카드에는 무게 · 온도 · 라벨 칸이 있습니다. 하지만 "이 업체와 이미 계약한 품목인가"는 장부를 봐야 알고, "맛이 맞나"는 맛봐야 압니다. 카드가 할 일과 다른 사람이 할 일이 나뉩니다.

스키마는 모양을 넓게, Code · LLM은 그 데이터만의 규칙을 깊게. 스키마로 거의 모든 데이터의 기본 모양(필수 · 길이 · 꼴 · 목록 · 날짜 · 중복)을 봅니다. 그러나 데이터마다 다른 규칙 — 답 안의 개인정보, 이미 있는 데이터와의 관계, 뜻 — 은 스키마의 타입으로 적기 어렵습니다. 둘 중 하나를 고르는 것이 아니라 층을 나눕니다.

층 무엇 오늘
스키마 모양 my-check (모든 데이터셋)
데이터별 Code 내용 규칙 · 이미 있는 데이터 my-faq-check (FAQ만)
LLM 뜻 Judge (FAQ 가져오기)
사람 고치기 · 기준 정하기 콘텐츠 담당자 · 팀

오늘 실습에서

FAQ를 my-check(schema: faq)로만 보면 B-3에서 Lab 01의 검사와 판정이 같았습니다 — B-3에는 개인정보 · 링크 · 이미 있는 FAQ가 없었기 때문입니다. B-2를 스키마로만 보면 FAQ-209(메일 주소)가 통과합니다. 그래서 FAQ는 Lab 01의 검사를 계속 쓰고, QUALITY.md 8절에 이 경계를 적습니다.

3. 되돌림 고리: 격리 → 고침 → 다시 → 빼기 (6교시 Lab 03 예제 2)

일반 설명

생활 속 예 · 보류 칸의 쪽지 떼기. 업체가 라벨을 붙여 다시 가져온 고기를 냉장고에 넣었습니다. 그런데 보류 칸의 옛 상자에 "라벨 없음" 쪽지가 그대로라면, 다음 날 아침 주방장은 "아직 해결 안 됐네" 하고 또 전화합니다.

격리함은 "사람이 볼 일"의 목록입니다. 해결된 줄이 남아 있으면 목록을 믿을 수 없습니다. 그래서 고쳐서 다시 넣은 줄은 격리함에서 뺍니다. 다만 넣은 줄만 뺍니다 — 고쳤는데 또 틀린 줄은 다시 사람에게 가야 합니다. 이 고리(격리 → 사람이 고침 → 다시 넣음 → 격리함 비우기)가 품질 관리의 한 바퀴이고, 76일차 DLQ의 replay와 같은 모양입니다.

flowchart LR
  Q[("격리함")] -.->|사람이 고침| F(["고친 배치"]) --> I["가져오기<br/>검사 · LLM · 넣기"] --> X["넣은 id만 뺌"] --> Q
  I --> L["품질 기록"]

오늘 실습에서

고치기 전 (Lab 02 과제 2까지) 고친 뒤 (Release fixed)
B-2-fix 두 줄 넣기 됨 · score 1 · FAQ 16 같음
격리함 2 (해결된 FAQ-209 · 210이 남음) 0
품질 기록 B-2 0.8 → B-2-fix 1 같음
  • 고친 배치의 이름이 B-2-fix라 "같은 배치 · 같은 id면 바꿈"에도 걸리지 않습니다. 격리함을 비우는 일은 저절로 되지 않습니다.

4. 설정으로 넓히기: 스키마만 바꾸면 (6교시 Lab 03 예제 3)

일반 설명

생활 속 예 · 생크림 카드 한 장. 식당이 디저트를 시작해 생크림이 들어옵니다. 주방장을 새로 뽑지 않고 "생크림 카드"를 한 장 더 만들면 내일부터 같은 사람이 검수합니다. 단, 카드에 "냉장 3도 이하"를 잘못 "30도"로 쓰면 그날부터 상한 크림이 들어옵니다.

규칙을 데이터로 두면, 새 데이터셋은 설정 한 장입니다 (configuration over code). 워크플로우를 고쳐 push하지 않고 스키마 파일만 더합니다. 그만큼 스키마 변경 = 규칙 변경입니다. 스키마 파일도 저장소에 두고 리뷰 · 테스트를 거쳐 바꿉니다 (74일차 배포 관문과 같은 생각). 업계에서는 스키마 레지스트리(schema registry)로 버전을 관리합니다.

오늘 실습에서

데이터 API에 세 번째 스키마 ticket이 있습니다. 예제 1의 my-check를 고치지 않고 접수 건 9줄을 보내면 (Lab 03 예제 3):

FAQ 검사 (my-faq-check) 스키마 검사 (my-check, 그대로)
통과 0줄 — 칸이 달라 모두 id_format · answer_missing 2줄
이유 9줄 모두 같은 세 코드 + 빈 id 중복 8 T-12 · urgent · 2026-02-30 · 3자 제목 · 010-12-3456 · 중복 · 요청자 빈칸 — 줄마다 다름
  • 선택 칸 contact가 없는 9째 줄은 통과, 있는데 꼴이 틀린 6째 줄은 bad_format:contact. "없어도 된다"와 "아무거나 돼도 된다"는 다릅니다.

5. 품질 보고서: 품질도 정의가 먼저 (6교시 Lab 03 과제 1)

일반 설명

생활 속 예 · 월말 검수 일지 정리. 사장님이 묻습니다: "이번 달 납품은 어땠어? 제일 나빴던 날은? 반품 이유는 뭐가 제일 많았어? 나아지고 있어?" 일지를 넘기며 말로 답하면 사람마다 답이 다릅니다.

품질 지표도 77일차 지표처럼 정의가 먼저입니다. 업계에서는 데이터 품질 점수 · 데이터 품질 대시보드라고 부르고, 데이터 관측(data observability) 도구(Monte Carlo · Bigeye 등)가 같은 일을 합니다. 정해야 할 것은 이렇습니다.

정해야 할 것 오늘의 정의 (AGENTS.md 3절) 정하지 않으면
거절을 평균에 넣나 넣음 (보내온 배치의 품질) 0.6583과 0.8778 중 무엇인지 모름
같으면 무엇을 먼저 나온 배치 · 코드 글자순 실행마다 순서가 바뀜
추세 마지막 − 첫, ±0.05 "좋아진 것 같다"
0건 평균 0, null 아님 다음 계산이 깨짐

숫자는 Code가 세고, 그 숫자를 무엇과 무엇을 비교했는지와 함께 말하는 것은 사람입니다.

오늘 실습에서

테스트가 B-1(거절) · B-2 · B-3 · B-2-fix를 차례로 가져온 기록 네 줄 (Lab 03 과제 1):

칸 값
avg_score 0.6583 = (0 + 0.8 + 0.8333 + 1) / 4
worst_batch B-1 · 거절 1
top_codes 1위 pii 2 (B-1 FAQ-109 전화 + B-2 FAQ-209 메일)
trend 좋아짐 (0 → 1)
  • trend의 함정: 13줄짜리 거절 배치와 고친 2줄짜리 배치를 같은 무게로 비교한 것입니다. 숫자는 정의대로 맞지만, 회의에서는 "첫 배치는 거절, 마지막은 고친 두 줄"을 함께 말합니다 (77일차 표본 크기와 같은 이야기).

6. 데이터셋별: 평균이 가리는 것 (6교시 Lab 03 과제 2)

일반 설명

생활 속 예 · 업체별 성적표. 한 달 평균만 보면 "괜찮다"인데 업체별로 나누면 채소 가게는 늘 좋고 생선 가게만 절반이 반품입니다. 사장님이 전화할 곳은 생선 가게입니다.

같은 기록 모양을 쓰면 다른 워크플로우의 품질도 한 보고서에서 봅니다. 검사(스키마 검사)도 가져오기와 같은 모양으로 기록을 남기면, 보고서는 고치지 않고도 직원 · 접수 건 데이터셋을 셉니다. 그리고 전체 평균은 나눠 봐야 할 것을 가립니다 — 77일차에 두 주 오류율이 월요일 09시를 가렸듯이.

추세는 같은 데이터셋 안에서. 서로 다른 데이터셋(직원 → FAQ)을 이어 "좋아졌다"고 말하면 뜻이 없습니다.

오늘 실습에서

데이터셋 기록 avg_score top_code
employee HR-1 0.4444 (4/9) bad_format:email
ticket TK-1 0.2222 (2/9) → worst_dataset bad_format:contact
faq B-3 0.8333 (5/6) answer_too_short
전체 0.5
  • 전체 0.5는 "절반쯤 괜찮다"지만 나누면 접수 건이 가장 손볼 곳 — 헬프데스크 팀에 "옮기기 전에 일곱 줄을 고쳐 달라"고 말할 근거입니다. top_code는 1건씩 같은 수 중 글자순 첫째라는 것도 함께 말합니다.
  • 전체 trend가 좋아짐(0.4444 → 0.8333)으로 나오지만 직원과 FAQ를 비교한 것이라 버립니다.

7. 식당 주방으로 본 오늘 하루

오늘 식당 주방 단계
데이터 품질 · 차원 아침 식재료 검수 1
품질 규칙 · 오류 코드 검수 기준표 · 반품 사유 스티커 1
경계 냉장고 온도 딱 5도 1
이미 있는 데이터 · 오류와 경고 냉장고 먼저 열기 1
고침 목록 · 데이터 계약 반품 사유서 1
배치 게이트 · 격리함 트럭째 반품 · 보류 칸 2
LLM 검사 한 숟가락 맛보기 (상한 것은 안 맛봄) 2
기준을 바꾸면 반품 기준을 풀면 · 조이면 2
품질 기록 · 알림 검수 일지 · 사장님 호출 2
LLM 호출 수 · 늘 같은가 맛보기 횟수 · 맛보는 사람 2
스키마 · 새 스키마 품목별 검수 카드 · 생크림 카드 3
되돌림 고리 보류 칸의 쪽지 떼기 3
품질 보고서 · 데이터셋별 월말 일지 정리 · 업체별 성적표 3

8. 자주 하는 실수

실수 결과 바로잡기
필드 이름을 검사 코드에 씀 새 데이터셋마다 워크플로우 수정 스키마의 fields를 돌며 타입마다
날짜를 꼴(YYYY-MM-DD)만 봄 13월 · 2월 30일이 통과 실제 있는 날인지
빈 선택 칸에 형식 검사 멀쩡한 줄이 bad_format 비었으면 required만
스키마만으로 FAQ를 검사 메일 주소 FAQ가 통과 내용 규칙은 Code로 따로
고친 줄을 넣고 격리함을 그대로 해결된 일이 "할 일"로 남음 넣은 id만 뺌
스키마를 리뷰 없이 바꿈 규칙이 몰래 바뀜 스키마도 저장소 · 리뷰 · 테스트
거절을 평균에서 뺌 (말없이) 품질이 좋아 보임 정의를 정하고 함께 말함
전체 평균 · 섞은 추세만 봄 손볼 데이터셋이 가려짐 데이터셋별로, 추세는 그 안에서

확인 질문

1. 스키마 검사를 만들었으니 Lab 01의 FAQ 검사는 지워도 되나요?

아닙니다. 스키마는 모양(필수 · 길이 · 꼴 · 중복)을 보고, FAQ 검사는 FAQ만의 내용 규칙(답 안의 개인정보 · 바깥 링크)과 이미 있는 FAQ와의 관계를 봅니다. B-2를 스키마로만 보면 메일 주소 FAQ-209가 통과합니다. 모양은 스키마로 넓게, 내용은 Code로 깊게.

2. 고친 배치를 다시 넣었는데 격리함에서 빼지 않으면 무엇이 문제인가요? 넣기는 됐잖아요.

격리함은 "사람이 볼 일"의 목록입니다. 해결된 FAQ-209 · 210이 남아 있으면 다음 사람이 또 고치려 하거나, 목록 전체를 믿지 않게 됩니다. 넣은 줄만 빼고, 또 틀린 줄은 남겨 다시 사람에게 보냅니다.

3. 새 스키마를 더할 때 워크플로우를 고치지 않아도 된다면, 스키마는 누구나 바꿔도 되나요?

반대입니다. 워크플로우를 고치지 않고 판정이 바뀐다는 것은, 스키마 한 줄이 곧 규칙이라는 뜻입니다. min: 4를 min: 40으로 잘못 쓰면 그날부터 모든 접수 건이 막힙니다. 스키마도 코드처럼 저장소에 두고 리뷰 · 테스트를 거쳐 바꿉니다.

4. 품질 보고서의 평균은 0.6583입니다. 거절된 B-1을 빼면 0.8778인데, 어느 쪽을 보고해야 하나요?

무엇을 보고 싶은지에 따라 정하고, 정의에 적어 둡니다. 오늘은 콘텐츠 담당자가 보내오는 배치의 품질을 보므로 거절도 넣습니다(0.6583). "받은 배치의 품질"이 궁금하면 뺀 숫자(0.8778)를 따로 말합니다. 정하지 않고 그때그때 고르면 숫자를 비교할 수 없습니다.

5. 데이터셋별로 나누니 접수 건이 0.2222로 가장 나쁩니다. 그런데 기록이 한 배치씩뿐입니다. 이 결론을 믿어도 되나요?

"이번 배치는 접수 건이 가장 나쁘다"까지는 말할 수 있습니다. "접수 건 데이터가 늘 나쁘다"는 배치가 쌓여야 말할 수 있습니다 (77일차 표본 크기). 9줄 중 7줄이 줄마다 다른 이유로 나쁘다는 것은 옮기기 전에 원본을 손봐야 한다는 신호로는 충분합니다.