78일차 데이터 품질 검증 자동화: 실습 15개(Q) · 기준 둘 · 강의(개요 30장 · 단계 문서 · 4단계 정리 · 05 바이브) · 요청서와 VIBE-Q(tcheck), 정답은 수업 뒤
This commit is contained in:
1 parent
fbed1b22f6
commit
4ec7ae123b
76 files changed
+11631
No files matched your search
@@ -0,0 +1,451 @@
|
||||
# 78일차 개요 · 데이터 품질 검증 자동화와 품질 관리 Workflow
|
||||
|
||||
> 노코드 멀티 에이전트 워크플로우 설계 및 운영 · 2026-11-03
|
||||
> 30장 · 각 장은 가로줄(`---`)로 나뉩니다. 1교시에는 1~6장을 보고, 나머지 장은 각 단계 강의(1 · 3 · 5교시) 때 함께 띄웁니다.
|
||||
> 숫자는 모두 강사 노트북 실측입니다 (65일차 n8n 2.42.6, 78일차 판 데이터 API의 FAQ 배치 셋 · 직원 CSV · 접수 건, OpenAI `gpt-4.1-mini`(LLM 검사, temperature 0), 11/01 정답 워크플로우를 학생 순서대로 1회).
|
||||
|
||||
| 장 | 범위 | 띄우는 때 |
|
||||
| --- | --- | --- |
|
||||
| 1~6 | 표지 · 목표 · 시간표 · 같은 배치, 다른 판정 · 일하는 순서 · 실습 15개 | 1교시 시작 |
|
||||
| 7~14 | 1단계 · 품질 규칙 | 1교시 강의 |
|
||||
| 15~21 | 2단계 · 품질 게이트 | 3교시 강의 |
|
||||
| 22~28 | 3단계 · 품질 관리 | 5교시 강의 |
|
||||
| 29~30 | 바이브 코딩 · 정리와 예고 (8교시 35분 정리는 [04-STAGE4-WRAPUP](04-STAGE4-WRAPUP.md)) | 7교시 · 8교시 |
|
||||
|
||||
---
|
||||
|
||||
## 1 / 30 · 표지
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
B[("들어오는 데이터<br/>FAQ · 직원 · 접수 건")] --> R["규칙<br/>무엇이 나쁜가"] --> G["게이트<br/>막기 · 격리 · 알림"] --> M["관리<br/>스키마 · 고쳐서 다시 · 추세"]
|
||||
classDef d fill:#0F3D3E,stroke:#0F3D3E,color:#fff
|
||||
classDef o fill:#F2A541,stroke:#F2A541,color:#fff
|
||||
class B d
|
||||
class R,G,M o
|
||||
```
|
||||
|
||||
**78일차**
|
||||
|
||||
# 데이터 품질 검증 자동화와 품질 관리 Workflow
|
||||
|
||||
규칙은 말로 정하고 · 나쁜 데이터는 막고 알리고 · 고치는 것은 사람이
|
||||
|
||||
<sub>노코드 멀티 에이전트 워크플로우 설계 및 운영 · 2026-11-03</sub>
|
||||
|
||||
---
|
||||
|
||||
## 2 / 30 · 오늘 할 수 있게 될 세 가지
|
||||
|
||||
| | 목표 | 내용 |
|
||||
| --- | --- | --- |
|
||||
| 1 | **규칙을 세운다** | 나쁜 데이터를 눈으로 찾고, 규칙과 오류 코드로 바꾸고, 경계에서 시험하고, 이미 있는 데이터와 맞춰 보고, 보낸 사람에게 고칠 것을 돌려준다 |
|
||||
| 2 | **막는다** | 검사를 불러 나쁜 배치는 거절하고 나쁜 줄은 격리하고, 규칙으로 못 잡는 것은 LLM에게, 기준의 대가를 재고, 기록 · 알림을 남기고, LLM 호출을 숫자로 본다 |
|
||||
| 3 | **관리한다** | 규칙을 스키마(데이터)로 꺼내 넓히고, 고친 줄을 다시 넣어 격리함을 비우고, 새 스키마로 늘리고, 품질 보고서 · 데이터셋별 품질을 본다 |
|
||||
|
||||
---
|
||||
|
||||
## 3 / 30 · 오늘의 시간표
|
||||
|
||||
| 교시 | 시간 | 내용 |
|
||||
| --- | --- | --- |
|
||||
| 1 | 09:00~09:50 | 개요 · **1단계 강의** · 품질 규칙 |
|
||||
| 2 | 10:00~10:50 | **Lab 01 실습 5개** · 눈으로 · 기준 검사 · 검사 워크플로우 · 경계 · 이미 있는 데이터 · 고침 목록 |
|
||||
| 3 | 11:00~11:50 | **2단계 강의** · 품질 게이트 |
|
||||
| 4 | 12:00~12:50 | **Lab 02 실습 5개** · 배치 게이트 · 격리 · LLM 검사 · 기준을 바꾸면 · 기록 · 알림 · LLM 호출 수 |
|
||||
| - | 13:00~14:00 | 점심 |
|
||||
| 5 | 14:00~14:50 | **3단계 강의** · 품질 관리 |
|
||||
| 6 | 15:00~15:50 | **Lab 03 실습 5개** · 스키마 검사 · 고쳐서 다시 · 새 스키마 · 품질 보고서 · 데이터셋별 |
|
||||
| 7 | 16:00~16:50 | 바이브 코딩 `tcheck`: 요청서 → TODO → SPEC → IMP-PLAN → 만들기 → 설치 |
|
||||
| 8 | 17:00~17:50 | 발표 · **4단계 정리** (의미 · 효과 · 회사에서 쓰는 법) · 79일차 예고 |
|
||||
|
||||
---
|
||||
|
||||
## 4 / 30 · 오늘의 출발점: 같은 배치, 다른 판정
|
||||
|
||||
77일차에 와이파이 FAQ 한 줄이 답 못 한 질문 34건을 풀었습니다. 그래서 콘텐츠 담당자가 FAQ를 배치로 보내기 시작했습니다. 첫 배치 B-1, 13줄.
|
||||
|
||||
| 질문 | 규칙표를 들고 눈으로 | 팀의 기준 검사 · 가져오기 |
|
||||
| --- | --- | --- |
|
||||
| 넣어도 되는 줄? | **2줄** (분명히 나쁜 8 · 판단 보류 3) | **10줄** 통과 |
|
||||
| 개인 전화번호 FAQ-109 | 나쁨 | 통과 |
|
||||
| 바깥 링크 FAQ-110 | 나쁨 | 통과 |
|
||||
| 실제로 FAQ에 들어간 것 | — | **12줄** (FAQ-003이 둘, 전화번호 · 단축 링크까지) |
|
||||
|
||||
나쁜 FAQ는 **답을 못 하는 것보다 나쁩니다** — 틀린 답을 자신 있게 보여 줍니다.
|
||||
|
||||
---
|
||||
|
||||
## 5 / 30 · 일하는 순서 (오늘은 "규칙 → 요청문 → 검사 → 확인")
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["① 먼저 보기<br/>눈 · call · test(전)"] --> B["② 규칙 · 요청문"] --> C["③ 에이전트<br/>my-work · check"] --> D["④ 내가<br/>push · test -v · quality"]
|
||||
D -->|"✘ has none of [코드]"| C
|
||||
D -->|✔| E["⑤ QUALITY.md 한 줄"]
|
||||
```
|
||||
|
||||
| 누가 | 무엇을 |
|
||||
| --- | --- |
|
||||
| 나 | 나쁜 데이터를 찾고 규칙으로 정하기, 기준 정하기, 나쁜 데이터를 **고치기** |
|
||||
| CLI 에이전트 | `AGENTS.md`대로 워크플로우 JSON, `check` |
|
||||
| `flow.py` | `test --webhook`(기준과 비교), `quality`(FAQ · 격리함 · 기록 · 알림), `diff` |
|
||||
|
||||
---
|
||||
|
||||
## 6 / 30 · 실습 15개 (Lab마다 예제 3 · 과제 2)
|
||||
|
||||
| | 예제 1 | 예제 2 | 예제 3 | 과제 1 | 과제 2 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Lab 01 | 눈으로 검사 · 기준 검사 (에이전트 없이) | 검사 워크플로우 | 경계에서 재 보기 (에이전트 없이) | 이미 있는 데이터 | 고침 목록 |
|
||||
| Lab 02 | 배치 게이트 · 격리 | LLM 검사 | 기준을 바꾸면 (에이전트 없이) | 품질 기록 · 알림 | LLM 호출 수 · 늘 같은가 |
|
||||
| Lab 03 | 스키마 검사 | 고쳐서 다시 넣기 | 스키마만 바꾸면 (에이전트 없이) | 품질 보고서 | 데이터셋별 품질 |
|
||||
|
||||
---
|
||||
|
||||
## 7 / 30 · 1단계 · 데이터 품질이란
|
||||
|
||||
> 생활 속 예: 식당 주방의 아침 식재료 검수 — 상자가 비어 있지 않다고 받는 게 아니라, 라벨 · 온도 · 날짜 · 주문한 물건인지를 본다.
|
||||
|
||||
| 품질 차원 (업계에서 쓰는 말) | 뜻 | 오늘 B-1에서 |
|
||||
| --- | --- | --- |
|
||||
| 완전성 (completeness) | 빠진 칸이 없나 | 빈 제목 · 빈 답 · 빈 키워드 |
|
||||
| 유효성 (validity) | 꼴 · 길이 · 값의 범위 | id 두 자리 · 300자 넘는 답 |
|
||||
| 고유성 (uniqueness) | 겹치지 않나 | 같은 배치에 FAQ-102가 둘 |
|
||||
| 일관성 (consistency) | 이미 있는 데이터와 맞나 | 이미 있는 FAQ-003 · 같은 제목 |
|
||||
| 정확성 (accuracy) | 내용이 맞나 | 토너 제목에 메일함 답 (LLM) |
|
||||
| 안전 (보안 · 개인정보) | 내보내도 되나 | 개인 휴대전화 · 단축 링크 |
|
||||
|
||||
---
|
||||
|
||||
## 8 / 30 · 규칙은 말이 먼저
|
||||
|
||||
> 생활 속 예: 벽에 붙은 검수 기준표 — "라벨 없는 고기는 반품, 냉장품은 5도 이하". 주방장이 바뀌어도 판정이 같다.
|
||||
|
||||
| | 기준 검사 (`base-faq-check`) | 오늘의 규칙 (AGENTS.md 3절) |
|
||||
| --- | --- | --- |
|
||||
| 규칙 수 | 3 (빈 값만) | 10 (+ 과제에서 이미 있는 데이터 · LLM) |
|
||||
| B-1 통과 | 10/13 | **5/13** — 눈으로 찾은 8줄과 같은 줄이 나쁨 |
|
||||
| 목록이 아닌 본문 | 500 (Code가 터짐) | **400** |
|
||||
| `lab01` 테스트 | 1/5 | **5/5** |
|
||||
|
||||
- 기준이 틀린 계산을 한 게 아니라 **규칙이 없었습니다.** 규칙을 요청문에 적으면 에이전트도 같은 판정을 냅니다.
|
||||
|
||||
---
|
||||
|
||||
## 9 / 30 · 오류 코드: 기계와 사람이 함께 읽는다
|
||||
|
||||
> 생활 속 예: 반품 상자에 붙이는 사유 스티커 — "온도"라고 짧게 붙여 두면 월말에 셀 수 있고, 납품업체에는 사유서로 풀어 쓴다.
|
||||
|
||||
| 같은 줄 | 코드 (기계가 셈) | 말 (사람이 고침, 과제 2) |
|
||||
| --- | --- | --- |
|
||||
| FAQ-103 | `title_missing` | 제목을 써 주세요 |
|
||||
| FAQ-109 | `pii` | 개인 전화번호 · 메일 주소를 빼고 IT 포털 안내로 바꿔 주세요 |
|
||||
| FAQ-003 | `exists_id` | 이미 있는 id입니다. 새 id를 쓰거나 … |
|
||||
|
||||
- 코드는 짧고 바뀌지 않음 → `codes`로 세고 Lab 03 보고서의 "가장 흔한 문제"가 됩니다. 말은 표 하나에서 — LLM으로 만들지 않습니다.
|
||||
|
||||
---
|
||||
|
||||
## 10 / 30 · 규칙은 Code가 확인한다
|
||||
|
||||
> 생활 속 예: 온도는 온도계가, 무게는 저울이 — 주방장의 감으로 재지 않는다.
|
||||
|
||||
| 판정 | 누가 | 까닭 |
|
||||
| --- | --- | --- |
|
||||
| 빈 값 · 길이 · 꼴 · 중복 · 전화번호 꼴 | **Code** | 정해진 답, 늘 같게, 0.1초 |
|
||||
| 이미 있는 데이터 | Code + 데이터 API | 목록을 읽어 비교 |
|
||||
| 답이 질문에 맞나 | **LLM** (Lab 02) | 뜻은 규칙으로 못 잼 |
|
||||
|
||||
- 13줄 검사 0.1초, LLM 없음. LLM에게 "이 FAQ 괜찮아?"를 물으면 날마다 판정이 다를 수 있고 줄마다 돈이 듭니다 (75일차).
|
||||
|
||||
---
|
||||
|
||||
## 11 / 30 · 경계에서 재 보기 (Lab 01 예제 3)
|
||||
|
||||
> 생활 속 예: 냉장고 온도 딱 5도 — 4도와 8도는 누구나 판정하지만, 5도와 5.1도는 기준표의 말("이하")이 정한다.
|
||||
|
||||
| 경계 | 규칙의 말 | 내 검사 | 기준 |
|
||||
| --- | --- | --- | --- |
|
||||
| 제목 40자 · 41자 | 40자 **넘으면** | ✔ 통과 · 막음 | ✘ 둘 다 통과 |
|
||||
| 공백만 있는 제목 | 공백 = 빈 값 | ✔ 막음 | ✘ 통과 |
|
||||
| `01012345678` · `02-123-4567` | 하이픈 **없어도** 휴대전화 | ✔ 막음 · 통과 | ✘ 둘 다 통과 |
|
||||
| `intra.example.com.evil.io` | 호스트가 **정확히** | ✔ 막음 | ✘ 통과 |
|
||||
|
||||
- **6/6 대 0/6.** 강사의 첫 판도 `evil.io`를 통과시켰습니다 — "앞이 같나"만 보고 "끝나나"를 안 봄.
|
||||
|
||||
---
|
||||
|
||||
## 12 / 30 · 이미 있는 데이터와 맞춰 보기 (Lab 01 과제 1)
|
||||
|
||||
> 생활 속 예: 상자를 받기 전에 냉장고를 연다 — 어제 받은 우유가 그대로면 같은 칸에 넣지 않는다.
|
||||
|
||||
| 줄 | 배치 안만 보면 | 이미 있는 FAQ와 맞추면 |
|
||||
| --- | --- | --- |
|
||||
| FAQ-003 "VPN 접속 오류 (새 판)" | 통과 | `exists_id` (오류) |
|
||||
| FAQ-112 "VPN 접속 오류" | 통과 | `same_title` (오류) + `keyword_used:vpn` (**경고**) |
|
||||
| B-1 통과 | 5줄 | **3줄** |
|
||||
|
||||
- 오류는 막고, 경고는 알리고 통과. 모든 것을 막으면 아무것도 못 넣고, 다 통과시키면 검사가 의미 없습니다 (참조 무결성).
|
||||
|
||||
---
|
||||
|
||||
## 13 / 30 · 보낸 사람에게 돌려준다 (Lab 01 과제 2)
|
||||
|
||||
> 생활 속 예: 반품 사유서 — "3번 상자 · 라벨 없음". 다음 납품이 나아지는 것은 사유서 덕분이다.
|
||||
|
||||
```text
|
||||
"message": "B-1: 13줄 중 3줄 통과, 10줄 고칠 것"
|
||||
{"row": 3, "id": "FAQ-103", "codes": ["title_missing"], "fix": ["제목을 써 주세요"]}
|
||||
{"row": 9, "id": "FAQ-109", "codes": ["pii"], "fix": ["개인 전화번호 · 메일 주소를 빼고 IT 포털 안내로 바꿔 주세요"]}
|
||||
```
|
||||
|
||||
- 업계 이름: **데이터 계약**(data contract) — 보내는 쪽과 받는 쪽이 모양 · 규칙을 미리 약속하고, 어기면 이유와 함께 돌려보냄.
|
||||
- 워크플로우는 **고쳐 주지 않습니다.** 빈 제목을 짐작해 채우면 틀린 FAQ가 "검사를 통과한 FAQ"가 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 14 / 30 · 1단계 정리 · 규칙
|
||||
|
||||
| 정한 것 | 오늘 |
|
||||
| --- | --- |
|
||||
| 무엇이 나쁜가 | 차원 여섯 · 코드 열둘 (AGENTS.md 3절) |
|
||||
| 경계의 말 | 넘으면 · 공백 · 꼴 · 정확히 |
|
||||
| 막을 것 · 알릴 것 | 오류 vs 경고 |
|
||||
| 누구에게 무엇을 | 기계에는 코드, 사람에게는 말 |
|
||||
|
||||
- 숫자: 기준 1/5 → 5/5, 경계 6/6 대 0/6, B-1 통과 10 → 5 → 3, 고침 목록 10줄.
|
||||
|
||||
---
|
||||
|
||||
## 15 / 30 · 2단계 · 검사와 게이트는 다른 일
|
||||
|
||||
> 생활 속 예: 검수(무엇이 상했나)와 반품 결정(그래서 트럭을 돌려보내나)은 다른 일이다.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
W(["배치"]) --> C["검사<br/>my-faq-check 를 부름"] --> G{"나쁜 줄 비율<br/>≤ 기준?"}
|
||||
G -->|아니오| R(["422 · 아무것도 안 넣음"])
|
||||
G -->|예| S["줄마다<br/>ok → FAQ · 아니면 → 격리함"]
|
||||
```
|
||||
|
||||
- 규칙을 다시 쓰지 않고 **검사를 부릅니다** — 규칙은 한 벌 (77일차 요약이 보고서를 부른 것처럼).
|
||||
|
||||
---
|
||||
|
||||
## 16 / 30 · 배치 게이트 · 줄 게이트 · 격리 (Lab 02 예제 1)
|
||||
|
||||
> 생활 속 예: 열에 일곱이 상했으면 트럭째 반품, 대부분 괜찮으면 좋은 것만 냉장고에, 이상한 것은 보류 칸에 사유를 붙여.
|
||||
|
||||
| 배치 | 기준 가져오기 | 내 가져오기 |
|
||||
| --- | --- | --- |
|
||||
| B-1 (나쁜 줄 10/13) | 12줄 넣음 | **422** · 0.7692 > 0.3 |
|
||||
| B-2 (메일 주소 1) | 10줄 넣음 | 9줄 · FAQ-209 격리 · `score` 0.9 |
|
||||
| B-3 (답 "짧") | 6줄 넣음 | 5줄 · FAQ-305 격리 |
|
||||
|
||||
- 격리함 = 버리지 않고 **이유와 함께** 보관 (76일차 DLQ와 같은 생각). 업계 이름: quarantine · dead-letter.
|
||||
|
||||
---
|
||||
|
||||
## 17 / 30 · LLM 검사 · 뜻은 LLM이 (Lab 02 예제 2)
|
||||
|
||||
> 생활 속 예: 무게 · 온도는 기준표로, "주문한 맛이 맞나"는 주방장이 한 숟가락 — 단, 이미 상한 것은 맛보지 않는다.
|
||||
|
||||
| | 규칙만 | + LLM |
|
||||
| --- | --- | --- |
|
||||
| FAQ-210 "모니터 밝기" · 답은 연차 휴가 | 넣음 | **격리** `llm_mismatch` |
|
||||
| B-2 결과 | 9줄 · 0.9 | 8줄 · 0.8 |
|
||||
| B-2 시간 | 1.4초 | **9.3초** (규칙을 통과한 9줄 × 1번) |
|
||||
|
||||
- 판정을 읽을 수 없으면 **넣지 않음** (fail-closed, 73일차). LLM이 막은 줄은 FAQ-210 **하나** — 드문 줄을 위해 줄마다 1초.
|
||||
|
||||
---
|
||||
|
||||
## 18 / 30 · 기준은 고르는 값 (Lab 02 예제 3)
|
||||
|
||||
> 생활 속 예: 반품 기준을 "열에 여덟까지"로 풀면 보류 칸이 넘치고, "하나도 안 돼"로 조이면 트럭이 다 돌아간다.
|
||||
|
||||
| 배치 | 기준 | 결과 |
|
||||
| --- | --- | --- |
|
||||
| B-1 | 0.3 | 거절 |
|
||||
| B-1 | 0.8 | 받음 — 넣음 **2** · 격리 **11** (사람이 11줄을 봄) |
|
||||
| B-2 | 0.05 | 거절 — 멀쩡한 9줄도 돌아감 |
|
||||
| B-2 | 0.1 | 받음 — **같으면 통과** |
|
||||
|
||||
- 앞 배치가 넣은 FAQ가 다음 배치의 판정을 바꿉니다 (`same_title` · `exists_id`) — 실험은 하나씩 떼어서.
|
||||
|
||||
---
|
||||
|
||||
## 19 / 30 · 품질 기록 · 알림 (Lab 02 과제 1)
|
||||
|
||||
> 생활 속 예: 검수 일지와 사장님 호출 — 일지가 쌓여야 "요즘 그 업체가 나빠졌다"를 말하고, 트럭째 반품한 날은 바로 전화한다.
|
||||
|
||||
| 배치 | 응답 | 기록 | 알림 |
|
||||
| --- | --- | --- | --- |
|
||||
| B-1 | 422 | `rejected: true` · 0 | `batch_rejected` |
|
||||
| B-2 | 200 · 0.8 | 8 · 2 · 0.8 | `low_quality` (0.9 미만) |
|
||||
|
||||
- 거절도 기록해야 보고서에 "가장 나쁜 배치"가 생깁니다. 알림은 곁가지 — 응답은 그대로 (`Result again`).
|
||||
|
||||
---
|
||||
|
||||
## 20 / 30 · LLM을 몇 번 · 늘 같은가 (Lab 02 과제 2)
|
||||
|
||||
> 생활 속 예: "오늘 맛보기 몇 번 했지? 상한 것까지 맛본 건 아니지? 어제와 오늘 판정이 같나?"
|
||||
|
||||
| 배치 | 줄 | `llm_calls` | 세 번 |
|
||||
| --- | --- | --- | --- |
|
||||
| B-1 (거절) | 13 | **0** | 같음 |
|
||||
| B-2 | 10 | **9** | FAQ-210만 · 9.4 · 8.1 · 7.6초 |
|
||||
| B-3 | 6 | **5** | 같음 |
|
||||
|
||||
- `--repeat`로 같은 배치를 연달아 보내면 2/6 — 판정이 흔들린 게 아니라 이미 넣은 FAQ 때문에 `exists_id`. "늘 같은가"는 **처음 상태에서** 세 번.
|
||||
|
||||
---
|
||||
|
||||
## 21 / 30 · 2단계 정리 · 게이트
|
||||
|
||||
| 정한 것 | 오늘 |
|
||||
| --- | --- |
|
||||
| 배치 · 줄의 두 관문 | 0.3 · `ok` |
|
||||
| 버리지 않기 | 격리함 + 이유 |
|
||||
| LLM은 어디에 | 규칙을 통과한 줄에만, 모르면 넣지 않음 |
|
||||
| 기준의 대가 | 거절 ↔ 격리 ↔ 사람의 일 |
|
||||
| 남기기 | 품질 기록 · 알림 · `llm_calls` |
|
||||
|
||||
- 숫자: 기준 0/6 → 5/6 → 6/6, B-1 12줄 → 0줄, FAQ-210 격리, 격리 13, LLM 9 · 5 · 0.
|
||||
|
||||
---
|
||||
|
||||
## 22 / 30 · 3단계 · 스키마: 규칙을 데이터로
|
||||
|
||||
> 생활 속 예: 품목마다 다른 검수 카드 — 채소 · 고기 · 생선마다 주방장을 두지 않고, 카드를 바꿔 들면 한 사람이 다 검수한다.
|
||||
|
||||
```json
|
||||
{"name": "employee", "key": "email", "fields": {
|
||||
"dept": {"type": "enum", "required": true, "values": ["영업팀", "재무팀", "인사팀", "개발팀", "IT팀", "총무팀"]},
|
||||
"joined": {"type": "date", "required": true}, "phone": {"type": "phone", "required": false}, …}}
|
||||
```
|
||||
|
||||
- 직원 CSV 9줄 → **4줄 통과** (메일 꼴 · `마케팅팀` · `2026-13-01` · 이름 빈칸 · 메일 중복). 같은 워크플로우로 FAQ B-3 → 5/6.
|
||||
- 업계 이름: JSON Schema · 테이블 정의 · Great Expectations의 "기대값".
|
||||
|
||||
---
|
||||
|
||||
## 23 / 30 · 스키마로 되는 것 · 안 되는 것
|
||||
|
||||
> 생활 속 예: 검수 카드에는 무게 · 온도 · 라벨 칸이 있지만, "이 납품업체와 이미 계약한 품목인가"는 장부를 봐야 안다.
|
||||
|
||||
| 규칙 | 스키마로 | 따로 |
|
||||
| --- | --- | --- |
|
||||
| 필수 · 길이 · 꼴 · 목록 · 날짜 · 중복 | ✔ | |
|
||||
| 답 안의 개인정보 · 바깥 링크 | | Code (Lab 01) |
|
||||
| 이미 있는 데이터 | | Code + 데이터 API |
|
||||
| 답이 질문에 맞나 | | LLM |
|
||||
|
||||
- 모양은 스키마로 **넓게**, 그 데이터만의 규칙은 Code로 **깊게**.
|
||||
|
||||
---
|
||||
|
||||
## 24 / 30 · 되돌림 고리 (Lab 03 예제 2)
|
||||
|
||||
> 생활 속 예: 라벨을 붙여 다시 가져온 고기를 받았으면 보류 칸의 옛 쪽지를 뗀다 — 안 떼면 내일 또 전화한다.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Q[("격리함<br/>FAQ-209 · 210")] -.->|사람이 고침| F(["B-2-fix"]) --> I["가져오기"] --> X["넣은 id만<br/>격리함에서 뺌"] --> Q
|
||||
```
|
||||
|
||||
| | 고치기 전 | 고친 뒤 |
|
||||
| --- | --- | --- |
|
||||
| 넣기 | 2줄 · `score` 1 | 같음 |
|
||||
| 격리함 | **2** (해결된 줄이 남음) | **0** |
|
||||
|
||||
---
|
||||
|
||||
## 25 / 30 · 스키마만 바꾸면 (Lab 03 예제 3)
|
||||
|
||||
> 생활 속 예: 디저트를 시작해 생크림이 들어온다 — 주방장을 새로 뽑지 않고 "생크림 카드" 한 장.
|
||||
|
||||
| 접수 건 9줄 | FAQ 검사 | 스키마 검사 (고치지 않음) |
|
||||
| --- | --- | --- |
|
||||
| 통과 | 0줄 (칸이 달라 모두 나쁨) | **2줄** |
|
||||
| 이유 | `id_format` · `answer_missing` 9 | `T-12` · `urgent` · **2월 30일** · 3자 제목 · 연락처 꼴 · 중복 · 요청자 빈칸 |
|
||||
|
||||
- 워크플로우를 한 줄도 고치지 않았습니다 — `ticket.json` 한 장. 그래서 **스키마 변경 = 규칙 변경**, 리뷰가 필요 (74일차 관문).
|
||||
|
||||
---
|
||||
|
||||
## 26 / 30 · 품질 보고서 · 품질도 정의가 먼저 (Lab 03 과제 1)
|
||||
|
||||
> 생활 속 예: 월말 검수 일지 정리 — "이번 달 어땠어?"에 늘 같은 방식으로 답한다.
|
||||
|
||||
| 칸 | 값 | 정한 것 |
|
||||
| --- | --- | --- |
|
||||
| 배치 · 평균 | 4 · **0.6583** | 거절(0)도 넣음 (빼면 0.8778) |
|
||||
| 가장 나쁜 배치 | B-1 | 같으면 먼저 나온 것 |
|
||||
| 가장 흔한 문제 | `pii` 2 | 같으면 코드 글자순 |
|
||||
| 추세 | 좋아짐 | 마지막 − 첫 > 0.05 |
|
||||
|
||||
- 함정: 추세가 "13줄 거절 → 고친 2줄"을 비교한 것 — 숫자는 정의대로지만 **무엇을 비교했는지** 함께 말한다.
|
||||
|
||||
---
|
||||
|
||||
## 27 / 30 · 데이터셋별 · 평균이 가리는 것 (Lab 03 과제 2)
|
||||
|
||||
> 생활 속 예: 한 달 평균은 "괜찮다"인데 업체별로 나누면 생선 가게만 절반이 반품 — 전화할 곳은 생선 가게.
|
||||
|
||||
| 데이터셋 | 평균 | 가장 흔한 문제 |
|
||||
| --- | --- | --- |
|
||||
| employee (HR-1) | 0.4444 | `bad_format:email` |
|
||||
| ticket (TK-1) | **0.2222** ← 가장 손볼 곳 | `bad_format:contact` |
|
||||
| faq (B-3) | 0.8333 | `answer_too_short` |
|
||||
| 전체 | 0.5 | — |
|
||||
|
||||
- 검사도 같은 모양으로 기록하니 보고서를 고치지 않고 셋이 보임. 섞은 추세는 뜻이 없음 — 추세는 데이터셋 안에서.
|
||||
|
||||
---
|
||||
|
||||
## 28 / 30 · 식당 주방으로 본 오늘 하루
|
||||
|
||||
> 생활 속 예: 오늘 만든 것이 모두 식당 주방에 있다 (3단계 8절 표).
|
||||
|
||||
| 오늘 | 주방 |
|
||||
| --- | --- |
|
||||
| 품질 규칙 · 오류 코드 | 검수 기준표 · 반품 사유 스티커 |
|
||||
| 경계 | 냉장고 온도 딱 5도 |
|
||||
| 이미 있는 데이터 · 고침 목록 | 냉장고 먼저 열기 · 반품 사유서 |
|
||||
| 배치 게이트 · 격리 · 기준 | 트럭째 반품 · 보류 칸 · 반품 기준 |
|
||||
| LLM 검사 · 호출 수 | 맛보기 · 맛보기 횟수 |
|
||||
| 품질 기록 · 알림 | 검수 일지 · 사장님 호출 |
|
||||
| 스키마 · 새 스키마 · 되돌림 | 품목별 검수 카드 · 생크림 카드 · 보류 칸 쪽지 떼기 |
|
||||
| 보고서 · 데이터셋별 | 월말 일지 정리 · 업체별 성적표 |
|
||||
|
||||
---
|
||||
|
||||
## 29 / 30 · 7교시 바이브 코딩 · `tcheck`
|
||||
|
||||
요청서(인사팀 · 콘텐츠 담당의 말 ①~⑫) → `Doc/TODO.md` → `SPEC.md` → `IMP-PLAN.md` → 단계별로 → `uv tool install`.
|
||||
|
||||
| 오늘 n8n에서 | `tcheck`로 터미널에서 (보내기 전에) |
|
||||
| --- | --- |
|
||||
| `my-check` (스키마) | `tcheck check` — **같은 배치면 같은 판정** |
|
||||
| 배치 게이트 | `tcheck gate --max-invalid 0.3` — 거절이면 종료 코드 4 |
|
||||
| 격리 | `--out` 깨끗한 줄 · `--rejects` 나쁜 줄 + 이유 |
|
||||
| 내용 규칙 · 고침 목록 · 품질 기록 | `--content answer` · `--fix` · `--log` (나중 단계) |
|
||||
| (없음) | CSV · JSON · 요청 파일, TUI 탭 · 거르기 · 내보내기 |
|
||||
|
||||
- 강사 본: 직원 · 접수 건 · FAQ B-3의 `rows` · `codes`가 `my-check` 응답과 **모두 같음**, 직원 `tcheck gate` → 종료 코드 4, 테스트 22개 3초 (n8n 없이).
|
||||
|
||||
---
|
||||
|
||||
## 30 / 30 · 오늘의 정리 · 79일차 예고
|
||||
|
||||
| 단계 | 오늘 숫자 |
|
||||
| --- | --- |
|
||||
| 규칙 | 기준 10/13 통과 · 1/5 → 규칙대로 5/13 · 5/5, 경계 6/6 대 0/6, 이미 있는 데이터 3/13, 고침 목록 10줄 |
|
||||
| 게이트 | 기준 가져오기 12줄 넣음 → B-1 거절 · B-2 9줄 · LLM이 FAQ-210, 기준 0.8이면 격리 11, LLM 호출 9 · 5 · 0 |
|
||||
| 관리 | 직원 4/9 · 접수 건 2/9 (워크플로우 그대로), 격리 2 → 0, 평균 0.6583, ticket 0.2222가 가장 손볼 곳 |
|
||||
|
||||
- 8교시 [4단계 정리](04-STAGE4-WRAPUP.md): 의미 · 효과 · 업계 이름 · 면접 · 최종 프로젝트 체크리스트.
|
||||
- 79일차 (11/4): **운영 데이터 기반 Workflow Ops Assistant** — 77일차 실행 기록 · 78일차 품질 기록 · 76일차 알림을 한데 모아, 운영자가 "지금 무엇이 문제야?"라고 물으면 숫자로 답하는 도우미를 만든다.
|
||||
@@ -0,0 +1,91 @@
|
||||
# 78일차 실습 준비 · 수업 전에 미리 해 두면 좋은 것
|
||||
|
||||
- 수업일: 2026-11-03 (78일차) · 데이터 품질 검증 자동화와 품질 관리 Workflow
|
||||
- 준비 시간: 약 10분
|
||||
- 먼저 WSL에서 `cd ~/aio-01d4-stu && git pull`로 오늘 자료를 받습니다 (수강생 저장소: https://gl.isitsoft.kr/publicproj/aio-01d4-stu).
|
||||
- **수업 전날까지** 1~2절을 끝내 주세요.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["1. n8n · 데이터 API 켜기<br/>(78일차 판)"] --> B["2. quality ·<br/>doctor ready"] --> C["3. 미리 읽기"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. n8n과 데이터 API 켜기 (전날 필수, 3분)
|
||||
|
||||
오늘은 **78일차 판 데이터 API**(77일차 + 격리함 · 스키마 · 품질 기록)를 씁니다. 같은 이름이라 이 폴더에서 다시 만들면 바뀝니다.
|
||||
|
||||
```bash
|
||||
sudo systemctl disable --now ollama 2>/dev/null # WSL에 설치한 Ollama가 있으면 끄고 자동 시작도 끔
|
||||
cd ~/aio-01d4-stu/Last3Mon/65/n8n
|
||||
docker compose rm -sf ollama # Ollama 컨테이너가 있으면 지움 (없으면 그냥 지나감)
|
||||
docker compose start
|
||||
cd ~/aio-01d4-stu/Last3Mon/78/data-api
|
||||
docker compose up -d --force-recreate
|
||||
curl -s localhost:8800/schemas/employee | head -c 80 # {"name": "employee", "key": "email", ...
|
||||
```
|
||||
|
||||
- **66일차부터 LLM은 OpenAI API 키(`Last3Mon/.env`, Credential `OpenAI (.env)`)만 씁니다.** Ollama는 쓰지 않습니다.
|
||||
- `network day65-n8n_default not found` → n8n이 켜져 있지 않음. 위 n8n 부분부터 다시.
|
||||
|
||||
## 2. 상태 보기와 준비 확인 (전날 필수, 3분)
|
||||
|
||||
```bash
|
||||
cd ~/aio-01d4-stu/Last3Mon/78
|
||||
uv run tools/flow.py push reference/baseline-faq-check.json reference/baseline-faq-import.json # 팀의 기준 (Lab 01 · 02에서 비교용)
|
||||
uv run tools/flow.py quality
|
||||
uv run tools/flow.py doctor
|
||||
```
|
||||
|
||||
```text
|
||||
FAQ: 6 (nothing added)
|
||||
quarantine: 0
|
||||
quality log: 0
|
||||
alerts: 0
|
||||
...
|
||||
✔ schemas faq · employee · ticket, quarantine, quality log (day 78 data API)
|
||||
✔ credential 'OpenAI (.env)' (openAiCourse0001)
|
||||
✔ CLI coding agent: codex, claude, agy
|
||||
ready
|
||||
```
|
||||
|
||||
| ✘ 항목 | 할 일 |
|
||||
| --- | --- |
|
||||
| n8n container · data API | 1절 |
|
||||
| schemas | 데이터 API가 예전 판 → 1절 `--force-recreate` |
|
||||
| credential | `cd ~/aio-01d4-stu/Last3Mon/65/n8n && bash register-credentials.sh` |
|
||||
| CLI coding agent | [67일차 준비](../67/00-DAY67-PREP.md) 2절 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 미리 읽어 오면 좋은 내용 (선택, 약 5분)
|
||||
|
||||
### 3.1 "AI가 틀린 답을 자신 있게 했어요"
|
||||
|
||||
77일차에 FAQ 한 줄이 문제를 풀었습니다. 그런데 그 FAQ가 틀렸다면? 답을 못 하는 헬프데스크보다 **틀린 답을 하는** 헬프데스크가 더 위험합니다. 워크플로우가 믿고 쓰는 데이터는 들어오는 곳에서 검사해야 합니다. `requests/faq-batch-1.json`을 열어 넣으면 안 되는 줄을 찾아보세요.
|
||||
|
||||
### 3.2 용어
|
||||
|
||||
| 용어 | 한 줄 설명 |
|
||||
| --- | --- |
|
||||
| 품질 규칙 | "깨끗하다"를 누가 봐도 같게 판단하는 규칙 (예: 답 10자 이상) |
|
||||
| 오류 코드 | 줄이 걸린 이유를 짧은 이름으로 (`pii`, `bad_format:email`) |
|
||||
| 게이트 | 기준을 넘지 못하면 들여보내지 않는 곳 (74일차 릴리스 게이트와 같은 생각) |
|
||||
| 격리함 | 나쁜 줄을 버리지 않고 이유와 함께 두는 곳 (76일차 DLQ와 같은 생각) |
|
||||
| 스키마 | 데이터의 모양(필드 · 타입 · 필수)을 적은 문서 |
|
||||
| 경계 | 기준선 바로 위 · 아래의 값 (딱 40자, 공백만, 하이픈 없는 번호) |
|
||||
| 기준 검사 · 기준 가져오기 | 팀이 지난달 급히 만든 워크플로우 (`base-faq-check` · `base-faq-import`) — 오늘 내 것과 비교할 상대 |
|
||||
|
||||
## 4. 당일 준비물
|
||||
|
||||
- 충전된 노트북과 충전기, WSL의 Docker, Windows Terminal(WSL) 창 **두 개**, 웹 브라우저
|
||||
- 77일차 `~/vibe/tlog` (지우지 않기, 79일차에 씀)
|
||||
- 7교시 [요청서](../../Last3Mon/78/VIBE-REQ-TCHECK.md)를 미리 한 번 읽어 오면 좋습니다
|
||||
|
||||
## 확인
|
||||
|
||||
- [ ] `curl -s localhost:8800/schemas/employee`에 `"key": "email"`
|
||||
- [ ] `flow.py push`로 `base-faq-check` · `base-faq-import` 게시
|
||||
- [ ] `flow.py quality`가 FAQ 6 · 격리 0을 보여 줌
|
||||
- [ ] `uv run tools/flow.py doctor` → 마지막 줄 `ready`
|
||||
@@ -0,0 +1,256 @@
|
||||
# 1단계 · 품질 규칙
|
||||
|
||||
- 교시: 1교시 강의 (09:00~09:50) · 2교시 [Lab 01](../../Last3Mon/78/LAB-01-Q-QUALITY-RULES.md) 실습 5개 (10:00~10:50)
|
||||
- 이 단계가 끝나면: 들어오는 데이터의 "나쁨"을 품질 차원으로 나눠 말하고, 그것을 **말로 정한 규칙과 오류 코드**로 바꾸고, 규칙을 Code로 확인하는 검사를 만들고, 경계(딱 기준선 · 공백 · 꼴 · 비슷한 주소)에서 재 보고, 이미 있는 데이터와 맞춰 보고, 보낸 사람에게 고칠 것을 돌려줄 수 있다.
|
||||
- 숫자: 모두 강사 노트북 실측입니다 (65일차 n8n 2.42.6, 78일차 판 데이터 API, FAQ 배치 B-1 13줄 · B-2 10줄 · 경계 배치 10줄, 11/01 실습을 5개로 늘린 뒤 정답 워크플로우를 학생 순서대로 1회). 규칙 판정은 누가 돌려도 같습니다. 출력 전부는 수업 뒤 공개되는 `Last3Mon/78/answers/LAB-TEST-RESULT.md`에 있습니다.
|
||||
- 실습 가리키기: 이 문서에서 "Lab 01 예제 1"은 2교시 [Lab 01 문서](../../Last3Mon/78/LAB-01-Q-QUALITY-RULES.md)의 그 절입니다. 파일 경로(`cases/` · `requests/` · `my-work/` · `reference/`)는 실습 폴더 `~/aio-01d4-stu/Last3Mon/78` 기준입니다.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["1. 데이터 품질"] --> B["2. 규칙은 말이 먼저"] --> C["3. 오류 코드"] --> D["4. 규칙은 Code가"] --> E["5. 경계"]
|
||||
E --> F["6. 이미 있는 데이터"] --> G["7. 보낸 사람에게"] --> H["8. 요청문으로"]
|
||||
```
|
||||
|
||||
## 0. 이 시간 (50분)
|
||||
|
||||
| 시간 | 절 · 개요 | 하는 일 |
|
||||
| --- | --- | --- |
|
||||
| 09:00~09:06 | 개요 1~6장 | 오늘 하루, 같은 배치 다른 판정, 실습 15개 |
|
||||
| 09:06~09:13 | 1 · 개요 7장 | 데이터 품질의 차원 |
|
||||
| 09:13~09:20 | 2 · 3 · 개요 8~9장 | 규칙은 말이 먼저, 오류 코드 |
|
||||
| 09:20~09:26 | 4 · 개요 10장 | 규칙은 Code가 |
|
||||
| 09:26~09:33 | 5 · 개요 11장 | 경계 |
|
||||
| 09:33~09:43 | 6 · 7 · 개요 12~14장 | 이미 있는 데이터 · 오류와 경고, 고침 목록 · 데이터 계약 |
|
||||
| 09:43~09:50 | 8 · 9 · 확인 질문 | 요청문, 자주 하는 실수 |
|
||||
|
||||
### 2교시 Lab 01에서 이어서 하는 것
|
||||
|
||||
| 2교시 실습 (시각) | 이 강의의 절 | 실습에서 하는 일 | 쓰는 파일 · 명령 |
|
||||
| --- | --- | --- | --- |
|
||||
| 시작 (10:00) | — | 품질 규칙표 복사 | `cp templates/QUALITY-RULES-TEMPLATE.md my-work/QUALITY.md` (오늘의 판정을 모두 여기에) |
|
||||
| Lab 01 예제 1 (10:00~10:10, 에이전트 없이) | 1 · 2 | B-1을 눈으로 검사, 같은 배치를 기준 검사에 | `call base-faq-check requests/faq-batch-1.json` → `QUALITY.md` 1절 |
|
||||
| Lab 01 예제 2 (10:10~10:25) | 2 · 3 · 4 | 규칙대로 판정하는 내 검사 | `my-work/faq-check.json` (새로), 테스트 `cases/lab01.json` (전: `--webhook base-faq-check`) |
|
||||
| Lab 01 예제 3 (10:25~10:32, 에이전트 없이) | 5 | 경계에서 두 검사를 재 보기 | `test cases/lab01-edges.json -v` · `--webhook base-faq-check` → `QUALITY.md` 3절 |
|
||||
| Lab 01 과제 1 (10:32~10:40) | 6 | 이미 있는 FAQ와 맞춰 보기 | 테스트 `cases/lab01-challenge.json` |
|
||||
| Lab 01 과제 2 (10:40~10:50) | 7 | 보낸 사람에게 돌려줄 고침 목록 | 테스트 `cases/lab01-challenge2.json` → `QUALITY.md` 4절 |
|
||||
|
||||
## 1. 데이터 품질: 무엇이 "나쁜" 데이터인가 (2교시 Lab 01 예제 1)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 식당 주방의 아침 검수.** 아침마다 납품 트럭이 오면 주방장이 상자를 엽니다. 무른 채소, 라벨 없는 고기, 주문하지 않은 물건, 유통기한이 지난 우유를 골라냅니다. "상자가 비어 있지 않으면 받는다"로는 식당이 망합니다. 워크플로우가 믿고 쓰는 데이터(오늘은 FAQ)가 이 식재료이고, 오늘은 검수를 자동으로 하는 날입니다.
|
||||
|
||||
**데이터 품질(data quality)은 "이 데이터를 믿고 써도 되나"입니다.** 77일차까지는 실행 기록을 **믿고** 셌습니다. 그런데 워크플로우가 읽는 데이터(FAQ · 직원 목록 · 접수 건)가 틀리면, 워크플로우는 틀린 답을 **자신 있게** 냅니다 — 답을 못 하는 것보다 나쁩니다. 업계에서는 "나쁨"을 몇 가지 **차원**으로 나눠 말합니다.
|
||||
|
||||
| 차원 | 묻는 것 | 예 |
|
||||
| --- | --- | --- |
|
||||
| 완전성 (completeness) | 꼭 있어야 할 칸이 있나 | 빈 제목 · 빈 답 |
|
||||
| 유효성 (validity) | 꼴 · 길이 · 값의 범위가 맞나 | id 꼴, 300자 넘는 답, 없는 날짜 |
|
||||
| 고유성 (uniqueness) | 겹치지 않나 | 같은 id가 둘 |
|
||||
| 일관성 (consistency) | 다른 데이터와 맞나 | 이미 있는 id · 같은 제목 |
|
||||
| 정확성 (accuracy) | 내용이 사실 · 질문과 맞나 | 토너 제목에 메일함 답 |
|
||||
| 적시성 (timeliness) | 지금도 맞나 | 지난 정책의 답 (오늘은 다루지 않음) |
|
||||
|
||||
여기에 FAQ처럼 **사람에게 그대로 보여 주는** 데이터는 안전(개인정보 · 위험한 링크)도 품질입니다. 업계 도구로는 Great Expectations · Soda · dbt tests · Deequ 같은 "데이터 검사" 도구가 있고, 데이터 파이프라인(ETL)의 한 단계로 검사를 둡니다. 오늘은 n8n 워크플로우로 같은 일을 합니다.
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
B-1 13줄을 AGENTS.md 3절 규칙표를 들고 눈으로 읽으면 (Lab 01 예제 1):
|
||||
|
||||
| 판정 | 줄 | 차원 |
|
||||
| --- | --- | --- |
|
||||
| 분명히 나쁨 (8) | FAQ-103 빈 제목 · FAQ-105 빈 답 · FAQ-108 빈 키워드 | 완전성 |
|
||||
| | FAQ-10 id 두 자리 · FAQ-106 300자 넘는 답 | 유효성 |
|
||||
| | 둘째 FAQ-102 | 고유성 |
|
||||
| | FAQ-109 개인 휴대전화 · FAQ-110 단축 링크 | 안전 |
|
||||
| 판단 보류 (3) | FAQ-003 · FAQ-112 (이미 있는 FAQ와 겹침), FAQ-113 (답이 다른 이야기) | 일관성 · 정확성 |
|
||||
| 좋음 (2) | FAQ-101 · FAQ-102 | |
|
||||
|
||||
- 같은 배치를 팀의 기준 검사에 보내면 **10줄 통과** — 빈 값 셋만 잡았습니다 (2절).
|
||||
|
||||
## 2. 규칙은 말이 먼저: 같은 배치, 다른 판정 (2교시 Lab 01 예제 1 · 2)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 벽에 붙은 검수 기준표.** 주방장마다 보는 눈이 다르면 같은 상자가 어떤 날은 받히고 어떤 날은 반품됩니다. 그래서 식당은 "라벨 없는 고기는 반품, 냉장품은 5도 이하"처럼 기준표를 벽에 붙입니다. 사람이 바뀌어도 판정이 같아지는 것은 기준표 덕분입니다.
|
||||
|
||||
**검사 = 규칙 + 판정.** "나쁜 FAQ를 걸러 줘"라는 말만으로는 판정이 하나로 정해지지 않습니다. 77일차의 "지표는 정의가 먼저"와 같습니다. 규칙은 적어도 이것을 정해야 합니다.
|
||||
|
||||
| 정해야 할 것 | 예 | 정하지 않으면 |
|
||||
| --- | --- | --- |
|
||||
| 무엇을 보나 | 제목 · 답 · 키워드 · id | 한두 칸만 봄 |
|
||||
| 꼴 · 범위 | `FAQ-` + 숫자 3자리, 답 10~300자 | 사람마다 다름 |
|
||||
| 경계 | 40자 **넘으면**, 공백은 빈 값 | 딱 기준선의 줄이 날마다 다르게 |
|
||||
| 판정의 단위 | 줄마다 · 배치마다 | "B-1은 나쁘다"로 끝남 |
|
||||
| 오류와 경고 | 막을 것 · 알릴 것 (6절) | 모든 것을 막거나 모두 통과 |
|
||||
|
||||
규칙이 요청문에 없으면 에이전트도 자기 방식으로 판정합니다 — 오늘 팀의 기준 검사처럼요.
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
| | 기준 검사 (`base-faq-check`) | 내 검사 (`my-faq-check`, Lab 01 예제 2) |
|
||||
| --- | --- | --- |
|
||||
| 규칙 | 빈 제목 · 빈 답 · 빈 키워드 | AGENTS.md 3절 열 가지 |
|
||||
| B-1 | 13줄 중 **10줄** 통과 | **5줄** 통과 — 눈으로 찾은 8줄과 같은 줄이 나쁨 |
|
||||
| B-2 | 10줄 모두 통과 | 9줄 (FAQ-209 메일 주소), 사내 링크 FAQ-207은 통과 |
|
||||
| `items`가 목록이 아님 | **500** (Code가 터짐) | **400** `{"error": "items must be a list"}` |
|
||||
| `cases/lab01.json` | **1/5** | **5/5** |
|
||||
|
||||
- 기준이 틀린 계산을 한 것이 아니라 **규칙이 셋뿐**이었습니다. "버그 찾기"가 아니라 "규칙을 정해 그대로 대기"가 고치는 일입니다.
|
||||
|
||||
## 3. 오류 코드: 기계와 사람이 함께 읽는다 (2교시 Lab 01 예제 2)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 반품 사유 스티커.** 주방장은 반품 상자에 "온도" · "라벨"처럼 짧은 스티커를 붙입니다. 월말에 스티커를 세면 "이번 달 반품의 절반이 온도"가 보입니다. 납품업체에는 스티커를 풀어 쓴 사유서를 보냅니다. 짧은 표시와 긴 설명을 나눠 두는 것입니다.
|
||||
|
||||
**줄마다 이유를 코드로 붙입니다.** "B-1은 나쁘다"로는 아무도 고칠 수 없습니다. "FAQ-109는 `pii`"라고 해야 그 줄을 고칩니다. 코드는 짧고 바뀌지 않는 영어(`title_missing` · `pii`)로 정해 두고, 사람이 읽는 말은 따로 붙입니다 (7절). 코드가 같아야 배치마다 몇 번 나왔는지 세고(`codes`), 품질 보고서에서 "가장 흔한 문제"를 고를 수 있습니다 (3단계).
|
||||
|
||||
| 코드의 성질 | 까닭 |
|
||||
| --- | --- |
|
||||
| 짧고 정해진 이름 | 기계가 셈 · 비교 (`codes.pii`) |
|
||||
| 한 줄에 여럿 | 제목도 비고 키워드도 비면 둘 다 |
|
||||
| 판정과 따로 | `ok`는 `errors`가 비었을 때만 — 규칙을 더해도 판정 방식은 그대로 |
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
B-1을 내 검사로 보면 `codes`에 여덟 가지가 1건씩입니다: `title_missing` · `id_format` · `answer_missing` · `answer_too_long` · `duplicate_in_batch` · `keywords_missing` · `pii` · `external_link`. 결과의 `rows`는 들어온 줄과 같은 순서 · 같은 수입니다 (AGENTS.md 4절) — 테스트가 `rows.8.errors`처럼 줄 번호로 봅니다.
|
||||
|
||||
## 4. 규칙은 Code가 확인한다 (2교시 Lab 01 예제 2)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 온도는 온도계로.** 냉장고 온도를 주방장의 손등으로 재지 않습니다. 온도계는 누가 들어도 같은 숫자를 줍니다. 대신 "이 소스, 맛이 맞나?"는 온도계로 잴 수 없어 사람이 맛봅니다.
|
||||
|
||||
**정해진 답이 있는 판정은 Code로.** 빈 값 · 길이 · 꼴(정규식) · 중복 · 전화번호 꼴은 같은 줄에 늘 같은 판정이 나와야 합니다. Code는 그렇게 하고, 빠르고(13줄 0.1초), 돈이 들지 않습니다. LLM에게 "이 FAQ 괜찮아?"를 물으면 그럴듯하지만, 날마다 판정이 다를 수 있고 줄마다 비용 · 시간이 듭니다 (75일차). LLM은 규칙으로 알 수 없는 것(답이 질문에 맞나)에만 씁니다 — 2단계에서.
|
||||
|
||||
| 판정 | 누가 |
|
||||
| --- | --- |
|
||||
| 꼴 · 길이 · 빈 값 · 중복 · 전화 · 링크 | Code |
|
||||
| 이미 있는 데이터와 겹침 | Code + 데이터 API (6절) |
|
||||
| 뜻 (답이 질문에 맞나) | LLM (2단계) |
|
||||
| 고치기 | 사람 |
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
내 검사는 `Check webhook` → `Is a list?`(IF) → `Check rows`(Code 하나) → `Send result`. Code에 들어가기 **전에** 모양을 봅니다: `items`가 목록이 아니면 400으로 돌려보내야 부른 쪽이 "내 본문이 틀렸다"를 압니다. 기준 검사처럼 Code 안에서 터지면 500 — "서버가 고장났다"로 읽힙니다.
|
||||
|
||||
## 5. 경계: 규칙은 기준선에서 시험받는다 (2교시 Lab 01 예제 3)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 냉장고 온도 딱 5도.** 기준표에 "냉장품 5도 이하"라고 적혀 있습니다. 4도와 8도는 누구나 판정합니다. 하지만 딱 5도는? "이하"라는 한 글자가 정합니다. 온도계 없이 "차갑네"로 판정하면 5.1도도 받습니다.
|
||||
|
||||
**경계(edge)는 기준선 바로 위 · 아래 · 위에 있는 값입니다.** 검사의 실수는 대부분 경계에서 나옵니다. 보통 줄(빈 제목, 아주 긴 답)만 시험하면 "잘 된다"고 믿게 됩니다. 규칙에는 경계의 **말**이 들어가야 합니다.
|
||||
|
||||
| 경계 | 정해야 할 말 | 말이 없으면 |
|
||||
| --- | --- | --- |
|
||||
| 딱 기준 길이 | "넘으면" / "이상이면" | 40자 제목이 막히거나 41자가 들어감 |
|
||||
| 공백만 있는 값 | "공백은 빈 값" | `" "`가 "있음"으로 통과 |
|
||||
| 꼴의 변형 | "하이픈 · 점 · 공백이 없어도" | `01012345678`이 그대로 나감 |
|
||||
| 비슷한 주소 | "호스트가 **정확히**" | `intra.example.com.evil.io`가 사내 주소로 (피싱이 쓰는 수법, 73일차) |
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
경계 배치(`requests/faq-edges.json`, 10줄)를 두 검사에 (Lab 01 예제 3):
|
||||
|
||||
| 경계 | 내 검사 | 기준 |
|
||||
| --- | --- | --- |
|
||||
| 40자 · 41자 제목 | ✔ 통과 · `title_too_long` | ✘ 둘 다 통과 |
|
||||
| 공백만 있는 제목 | ✔ `title_missing` | ✘ 통과 |
|
||||
| 10자 · 9자 답 | ✔ 통과 · `answer_too_short` | ✘ 둘 다 통과 |
|
||||
| `01012345678` · `02-123-4567` | ✔ `pii` · 통과 | ✘ 둘 다 통과 |
|
||||
| 사내 주소 · `evil.io` | ✔ 통과 · `external_link` | ✘ 둘 다 통과 |
|
||||
| `faq-410` | ✔ `id_format` | ✘ 통과 |
|
||||
|
||||
- **6/6 대 0/6.** 강사의 첫 판도 `evil.io`를 통과시켰습니다 — 정규식이 "뒤에 `intra.example.com`이 오나"만 보고 거기서 **끝나는지**는 보지 않았기 때문입니다. 테스트에 경계 줄을 넣어 두면 이런 실수를 미리 잡습니다.
|
||||
|
||||
## 6. 이미 있는 데이터: 오류와 경고 (2교시 Lab 01 과제 1)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 냉장고를 먼저 연다.** 납품 상자만 보면 멀쩡한 우유입니다. 그런데 냉장고에 어제 받은 우유가 그대로라면 같은 칸에 넣으면 안 됩니다. 반면 "같은 회사 제품"인 것은 흔하고 괜찮습니다 — 알아만 두면 됩니다.
|
||||
|
||||
**들어오는 데이터만이 아니라 이미 있는 데이터와의 관계도 봅니다.** 데이터베이스에서는 참조 무결성(referential integrity) · 유일 제약(unique constraint)이라고 부릅니다. 같은 id로 들어오면 기존 데이터를 덮어쓰거나 두 벌이 되고, 같은 제목이 둘이면 검색이 어느 답을 줄지 모릅니다.
|
||||
|
||||
그리고 **막을 것과 알릴 것**을 나눕니다. 모든 것을 오류로 막으면 아무것도 들어가지 못하고, 모두 통과시키면 검사가 의미 없습니다.
|
||||
|
||||
| | 오류 (`errors`) | 경고 (`warnings`) |
|
||||
| --- | --- | --- |
|
||||
| 뜻 | 들어가면 안 됨 | 사람이 보고 판단 |
|
||||
| 판정 | `ok: false` | `ok`에 영향 없음 |
|
||||
| 예 | 이미 있는 id · 같은 제목 | 이미 쓰는 키워드 |
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
검사 앞에 `Get FAQ`(`GET /faq-all`, 처음 6개 + 오늘 더한 것)를 두면 (Lab 01 과제 1): FAQ-003 `exists_id`, FAQ-112 `same_title` + 경고 `keyword_used:vpn`, B-1 통과 5 → **3**줄. 테스트가 막 더한 FAQ-201도 `exists_id` — "이미 있는 데이터"는 파일이 아니라 **지금** 데이터 API에 있는 것입니다.
|
||||
|
||||
## 7. 보낸 사람에게: 고침 목록 · 데이터 계약 (2교시 Lab 01 과제 2)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 반품 사유서.** "안 받아요"만 말하면 납품업체는 무엇이 잘못됐는지 모릅니다. "3번 상자 · 라벨 없음, 7번 상자 · 냉장 온도 9도"라고 적어 주면 다음 납품이 나아집니다.
|
||||
|
||||
**검사의 결과는 기계와 사람이 둘 다 읽습니다.** 다음 워크플로우(가져오기)는 `rows` · `codes`를 읽고, 보낸 사람(콘텐츠 담당자)은 사람의 말을 읽습니다. 고칠 것이 코드마다 정해져 있으면 표 하나로 충분합니다 — LLM으로 만들면 같은 코드에 날마다 다른 말이 나오고 돈이 듭니다.
|
||||
|
||||
업계에서는 보내는 쪽과 받는 쪽이 데이터의 모양 · 규칙을 미리 약속하는 것을 **데이터 계약**(data contract)이라고 부릅니다. 약속을 어긴 데이터는 받지 않고 **이유와 함께** 돌려보냅니다. 오늘의 AGENTS.md 3절이 작은 데이터 계약이고, 고침 목록이 돌려보내는 이유입니다.
|
||||
|
||||
그리고 워크플로우는 **고쳐 주지 않습니다.** 빈 제목을 짐작해 채우면 틀린 FAQ가 "검사를 통과한 FAQ"로 들어가고, 아무도 그 사실을 모릅니다.
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
결과에 `fix_list` · `message`를 더하면 (Lab 01 과제 2): B-1 → `"B-1: 13줄 중 3줄 통과, 10줄 고칠 것"`, 고칠 줄 10개(3째 FAQ-103 "제목을 써 주세요" … 12째 FAQ-112 "같은 제목의 FAQ가 이미 있습니다 …"), B-2 → FAQ-209 하나. `row`는 1부터, 줄 순서 그대로 — 보낸 사람이 자기 파일에서 바로 찾게.
|
||||
|
||||
## 8. 요청문(프롬프트)으로 에이전트에게 맡기기
|
||||
|
||||
검사 요청문은 "나쁜 FAQ를 걸러 줘"가 아니라 **규칙**을 적습니다 (AGENTS.md 1절: 에이전트는 먼저 "무엇을 보고 어떤 코드를 붙이는지"를 표로 보여 줌).
|
||||
|
||||
| 넣을 것 | 예 |
|
||||
| --- | --- |
|
||||
| 파일 · 웹훅 · 이름 | "`my-work/faq-check.json`, 웹훅 `my-faq-check`, 이름 `78 FAQ check (my)`" |
|
||||
| 모양이 틀린 본문 | "`items`가 목록이 아니면 400" |
|
||||
| 규칙과 경계 | "AGENTS.md 3절 규칙대로, 공백만 있는 값은 빈 값, 글자 수는 앞뒤 공백을 뺀 뒤" |
|
||||
| 헷갈리는 규칙 | "pii는 하이픈 없는 휴대전화도, external_link는 호스트가 정확히 intra.example.com이 아니면" |
|
||||
| 결과 모양 · 하지 않을 것 | "`rows`는 들어온 순서 그대로, LLM은 쓰지 않는다" |
|
||||
| 기대 결과 | "`cases/lab01.json`, 앞의 테스트도 그대로" |
|
||||
|
||||
## 9. 자주 하는 실수
|
||||
|
||||
| 실수 | 결과 | 바로잡기 |
|
||||
| --- | --- | --- |
|
||||
| "나쁜 FAQ 걸러 줘"만 씀 | 에이전트마다 다른 규칙 | 규칙 표를 요청문에 |
|
||||
| 공백을 값으로 봄 | `" "` 제목이 통과 | 앞뒤 공백을 뺀 뒤 판정 |
|
||||
| `>`와 `>=`를 섞음 | 딱 40자 제목이 막힘 | "넘으면"을 말로 |
|
||||
| 전화번호를 `010-` 꼴만 찾음 | `01012345678`이 나감 | 구분자가 없어도 되는 꼴 |
|
||||
| 주소를 "앞이 같나"로 봄 | `evil.io`가 통과 | 호스트가 정확히 · 끝나는지까지 |
|
||||
| Code 안에서 본문 모양을 봄 | 500 | Code 앞에 IF → 400 |
|
||||
| 겹치는 키워드도 오류로 | 넣을 수 있는 FAQ가 없음 | 오류와 경고를 나눔 |
|
||||
| 나쁜 줄을 고쳐서 넣음 | 틀린 데이터가 "통과"로 | 고침 목록을 돌려주고 사람이 고침 |
|
||||
| 규칙을 LLM에게 판정시킴 | 날마다 다르고 비쌈 | 규칙은 Code, 뜻만 LLM |
|
||||
|
||||
## 확인 질문
|
||||
|
||||
<details><summary>1. 기준 검사는 B-1을 10줄 통과, 내 검사는 5줄 통과라고 합니다. 기준 검사가 "틀린" 건가요?</summary>
|
||||
|
||||
계산은 맞습니다. 기준은 빈 값 세 가지만 보는 **규칙**으로 판정했고, 그 규칙대로라면 10줄이 통과입니다. 문제는 그 규칙으로 FAQ에 개인 전화번호와 단축 링크가 들어간다는 것입니다. 무엇을 막을지는 팀이 정하고(AGENTS.md 3절), 모든 검사가 그 규칙을 씁니다.
|
||||
</details>
|
||||
|
||||
<details><summary>2. 오류 이유를 "제목이 비었어요" 같은 문장 대신 `title_missing` 같은 코드로 붙이는 까닭은?</summary>
|
||||
|
||||
코드는 짧고 바뀌지 않아 기계가 셀 수 있습니다 (`codes`, 품질 보고서의 가장 흔한 문제). 문장은 사람마다 · 날마다 달라 셀 수 없습니다. 사람에게 보여 줄 말은 코드마다 표로 정해 따로 붙입니다 (과제 2).
|
||||
</details>
|
||||
|
||||
<details><summary>3. 경계 테스트에서 기준 검사가 0/6이었습니다. 보통 배치(B-1)에서는 1/5를 맞혔는데, 경계에서는 왜 하나도 못 맞혔나요?</summary>
|
||||
|
||||
경계 배치의 줄은 빈 값이 아닌 것들입니다 (41자 · 공백 · 하이픈 없는 번호 · 비슷한 주소 · 소문자 id). 기준이 가진 규칙(빈 값)에 걸릴 줄이 하나도 없으니 모두 통과입니다. 보통 배치에서 맞힌 1/5는 "빈 값" 케이스가 마침 기준의 규칙과 같았기 때문입니다.
|
||||
</details>
|
||||
|
||||
<details><summary>4. 이미 쓰는 키워드(`vpn`)를 오류가 아니라 경고로 둔 까닭은?</summary>
|
||||
|
||||
키워드가 겹치는 것은 흔하고 나쁘지 않습니다 (VPN 관련 FAQ가 여럿일 수 있음). 오류로 막으면 새 FAQ를 거의 넣을 수 없습니다. 반면 같은 id · 같은 제목은 덮어쓰거나 검색이 헷갈리므로 막습니다. 막을 것과 알릴 것을 나누는 것도 규칙입니다.
|
||||
</details>
|
||||
|
||||
<details><summary>5. 고침 목록을 만들 수 있다면, 워크플로우가 아예 고쳐서 넣으면 더 편하지 않나요?</summary>
|
||||
|
||||
빈 제목을 워크플로우가 짐작해 채우면, 틀린 내용이 "검사를 통과한 FAQ"로 들어가고 아무도 모릅니다. 보낸 사람도 무엇이 틀렸는지 배우지 못해 다음 배치도 같습니다. 워크플로우는 막고 알리고, 고치는 것은 사람입니다 (오늘의 원칙). 공백 정리처럼 뜻이 바뀌지 않는 "다듬기"와 내용을 바꾸는 "고치기"는 다릅니다.
|
||||
</details>
|
||||
@@ -0,0 +1,239 @@
|
||||
# 2단계 · 품질 게이트
|
||||
|
||||
- 교시: 3교시 강의 (11:00~11:50) · 4교시 [Lab 02](../../Last3Mon/78/LAB-02-Q-QUALITY-GATE.md) 실습 5개 (12:00~12:50)
|
||||
- 이 단계가 끝나면: 검사(무엇이 나쁜가)와 게이트(그래서 무엇을 하나)를 나누고, 나쁜 배치는 통째로 거절 · 나쁜 줄은 이유와 함께 격리하는 가져오기를 만들고, 규칙으로 못 잡는 줄만 LLM에게 묻고, 거절 기준의 대가를 재고, 배치마다 품질 기록 · 알림을 남기고, LLM 호출을 숫자로 볼 수 있다.
|
||||
- 숫자: 모두 강사 노트북 실측입니다 (65일차 n8n 2.42.6, 78일차 판 데이터 API, FAQ 배치 B-1 · B-2 · B-3, OpenAI `gpt-4.1-mini` temperature 0, 11/01 정답 워크플로우를 학생 순서대로 1회 · Lab 02 과제 2는 세 번). 규칙 판정은 늘 같고, 시간과 LLM 판정은 실행마다 다를 수 있습니다.
|
||||
- 실습 가리키기: 이 문서에서 "Lab 02 예제 1"은 4교시 [Lab 02 문서](../../Last3Mon/78/LAB-02-Q-QUALITY-GATE.md)의 그 절입니다. 파일 경로는 실습 폴더 `~/aio-01d4-stu/Last3Mon/78` 기준입니다.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["1. 검사와 게이트"] --> B["2. 배치 · 줄 · 격리"] --> C["3. LLM 검사"] --> D["4. 기준은 고르는 값"]
|
||||
D --> E["5. 기록 · 알림"] --> F["6. LLM 호출 수 · 늘 같은가"] --> G["7. 요청문으로"]
|
||||
```
|
||||
|
||||
## 0. 이 시간 (50분)
|
||||
|
||||
| 시간 | 절 · 개요 | 하는 일 |
|
||||
| --- | --- | --- |
|
||||
| 11:00~11:08 | 1 · 개요 15장 | 검사와 게이트, 기준 가져오기가 넣은 것 |
|
||||
| 11:08~11:17 | 2 · 개요 16장 | 배치 게이트 · 줄 게이트 · 격리함 |
|
||||
| 11:17~11:26 | 3 · 개요 17장 | LLM 검사, 규칙을 통과한 줄만, fail-closed |
|
||||
| 11:26~11:33 | 4 · 개요 18장 | 기준을 바꾸면 |
|
||||
| 11:33~11:42 | 5 · 6 · 개요 19~21장 | 품질 기록 · 알림, LLM 호출 수 · 늘 같은가 |
|
||||
| 11:42~11:50 | 7 · 8 · 확인 질문 | 요청문, 자주 하는 실수 |
|
||||
|
||||
### 4교시 Lab 02에서 이어서 하는 것
|
||||
|
||||
| 4교시 실습 (시각) | 이 강의의 절 | 실습에서 하는 일 | 쓰는 파일 · 명령 |
|
||||
| --- | --- | --- | --- |
|
||||
| Lab 02 예제 1 (12:00~12:12) | 1 · 2 | 기준 가져오기에 먼저, 그다음 게이트 · 격리 | `test cases/lab02.json --webhook base-faq-import -v`, `my-work/faq-import.json` (새로) → `lab02` 5/6, `quality` |
|
||||
| Lab 02 예제 2 (12:12~12:22) | 3 | LLM 검사 (통과한 줄만) | 같은 파일 → `lab02` 6/6 |
|
||||
| Lab 02 예제 3 (12:22~12:28, 에이전트 없이) | 4 | 기준 0.8 · 0.05 · 0.1 | `test cases/lab02-gate.json -v`, `quality` → `QUALITY.md` 5절 |
|
||||
| Lab 02 과제 1 (12:28~12:38) | 5 | 품질 기록 · 알림 | 테스트 `cases/lab02-challenge.json` → `QUALITY.md` 7절 |
|
||||
| Lab 02 과제 2 (12:38~12:50) | 6 | `llm_calls`, 세 번 돌리기 | 테스트 `cases/lab02-challenge2.json` × 3 → `QUALITY.md` 6절 |
|
||||
|
||||
## 1. 검사와 게이트는 다른 일 (4교시 Lab 02 예제 1)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 검수와 반품 결정.** 주방장이 "이 상자는 일곱 개가 상했네"라고 보는 것(검수)과, "그러니 트럭째 돌려보내자"고 정하는 것(결정)은 다른 일입니다. 같은 검수 결과로도 식당마다 결정이 다를 수 있습니다.
|
||||
|
||||
**검사(validation)는 판정을, 게이트(gate)는 그 판정으로 할 일을 정합니다.** 검사는 Lab 01에서 만들었습니다. 게이트는 그 결과를 읽어 넣을지 · 막을지 · 격리할지를 정합니다. 둘을 나누면 검사를 고칠 때 게이트를, 게이트 기준을 바꿀 때 검사를 건드리지 않습니다. 업계에서는 데이터 파이프라인의 **품질 관문**(quality gate) · 74일차 배포 관문(release gate)과 같은 모양입니다.
|
||||
|
||||
**규칙은 한 벌.** 게이트 안에 규칙을 다시 쓰면, 규칙을 고칠 때 두 곳을 고쳐야 하고 언젠가 어긋납니다. 77일차 요약이 보고서를 **불렀듯이**, 가져오기는 검사 웹훅을 부릅니다.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
W(["배치"]) --> C["Run check<br/>POST my-faq-check"] --> G{"invalid / total<br/>≤ 기준?"}
|
||||
G -->|아니오| R(["422 · 아무것도 넣지 않음"])
|
||||
G -->|예| S["Split rows"] --> D["Store row<br/>ok → /faq/add · 아니면 → /quarantine"] --> M(["imported · quarantined · score"])
|
||||
```
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
먼저 팀이 쓰던 기준 가져오기(`base-faq-import`)에 같은 테스트를 돌리면 **0/6** (Lab 02 예제 1). 기준은 검사 없이 모든 줄을 `/faq/add`로 보냅니다.
|
||||
|
||||
| 배치 | 기준 가져오기가 넣은 것 |
|
||||
| --- | --- |
|
||||
| B-1 | 13줄 중 **12줄** — 빈 제목 · 개인 전화번호 · 단축 링크 · 이미 있는 FAQ-003과 같은 id까지 (빈 답 하나만 데이터 API가 막음) |
|
||||
| B-2 | 10줄 모두 — 메일 주소 · 다른 답까지 |
|
||||
| B-3 | 6줄 모두 — 답 "짧"까지 |
|
||||
|
||||
- 기준의 `score`는 0.9231 · 1 — "잘 들어갔다"처럼 보이는 숫자가 실제로는 나쁜 줄을 넣은 수입니다.
|
||||
|
||||
## 2. 배치 게이트 · 줄 게이트 · 격리함 (4교시 Lab 02 예제 1)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 트럭째 반품과 보류 칸.** 상자 열에 일곱이 상했으면 하나씩 골라내느니 트럭째 돌려보냅니다 (다시 받는 게 빠름). 대부분 괜찮으면 좋은 것만 냉장고에 넣고, 이상한 것은 **보류 칸**에 사유 쪽지를 붙여 둡니다. 버리지 않습니다 — 업체가 바꿔 오면 확인해야 하니까요.
|
||||
|
||||
**게이트는 두 겹입니다.**
|
||||
|
||||
| 관문 | 기준 | 넘지 못하면 |
|
||||
| --- | --- | --- |
|
||||
| 배치 게이트 | 나쁜 줄 비율 ≤ 기준 (오늘 기본 0.3, 같으면 통과) | 배치 전체 거절 — 422, 아무것도 넣지 않음 |
|
||||
| 줄 게이트 | 그 줄의 `ok` | 그 줄만 격리함으로 |
|
||||
|
||||
**격리(quarantine)는 버리지 않는 것입니다.** 넣지 않은 줄을 원래 내용(`row`)과 이유(`errors`)와 함께 보관합니다. 버리면 무엇이 왜 빠졌는지 모르고, 고친 뒤 다시 넣을 수도 없습니다. 76일차의 DLQ(dead-letter queue, 실패한 요청을 두는 곳)와 같은 생각이고, 데이터 파이프라인에서는 quarantine table · error table이라고 부릅니다.
|
||||
|
||||
**응답 코드.** 400은 "모양이 틀렸다"(읽을 수 없음), 422는 "읽었지만 받을 수 없다"(내용이 나쁨)입니다. 부른 쪽이 다음에 할 일이 다르기 때문에 나눕니다.
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
| 배치 | 내 가져오기 (Lab 02 예제 1) |
|
||||
| --- | --- |
|
||||
| B-1 (나쁜 줄 10/13) | **422** `invalid_ratio` 0.7692 > `max_invalid_ratio` 0.3, 아무것도 넣지 않음 |
|
||||
| B-2 | 9줄 넣고 FAQ-209 격리 (`pii`), `score` 0.9 |
|
||||
| B-3 | 5줄 넣고 FAQ-305 격리 (`answer_too_short`) |
|
||||
|
||||
- 넣기와 격리를 IF로 두 갈래로 나눴다가 Merge로 합치면, LLM 검사를 더한 뒤 격리 수가 틀립니다 (수업 준비 때 겪음). HTTP 노드 **하나**가 주소를 표현식으로 고르게 하면 갈래가 필요 없습니다 (AGENTS.md 5절).
|
||||
- FAQ-210(답이 다른 이야기)은 규칙을 모두 통과해 아직 들어갑니다 → `lab02` 5/6. 3절에서 막습니다.
|
||||
|
||||
## 3. LLM 검사: 뜻은 LLM이, 통과한 줄에만 (4교시 Lab 02 예제 2)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 한 숟가락 맛보기.** 무게 · 온도 · 유통기한은 기준표로 잽니다. "주문한 맛이 맞나"는 주방장이 맛봅니다. 그런데 이미 상한 것까지 맛보지는 않습니다 — 기준표에서 떨어진 것은 맛볼 필요가 없습니다.
|
||||
|
||||
**규칙으로 알 수 없는 것만 LLM에게.** "답이 제목의 질문에 답하나?"는 정해진 답이 없는 판정이라 규칙(Code)으로 쓰기 어렵습니다. LLM은 이런 뜻의 판정을 잘합니다. 다만 세 가지를 지킵니다.
|
||||
|
||||
| 원칙 | 까닭 |
|
||||
| --- | --- |
|
||||
| **규칙을 통과한 줄에만** | 규칙에 걸린 줄은 이미 격리 — LLM에 물어도 결과가 같고 돈 · 시간만 듦 (75일차) |
|
||||
| **JSON으로만 답하게** | `{"match": true/false, "reason"}` — Code가 읽음 |
|
||||
| **읽을 수 없으면 넣지 않음** (fail-closed) | LLM이 멈추거나 이상한 말을 한 날 모든 줄이 검사 없이 들어가지 않게 (73일차) |
|
||||
|
||||
업계에서는 "LLM-as-a-judge"라고 부르고, RAG 품질 평가 · 콘텐츠 검수에 씁니다. 판정의 근거(`reason`)를 함께 남겨 사람이 다시 볼 수 있게 합니다.
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
| | 규칙만 (예제 1) | + LLM (예제 2) |
|
||||
| --- | --- | --- |
|
||||
| FAQ-210 "모니터 밝기 조절" · 답은 연차 휴가 | 넣음 | 격리 `llm_mismatch` |
|
||||
| B-2 | 9줄 · `score` 0.9 | 8줄 · 0.8 |
|
||||
| B-3 | 5줄 | 5줄 (FAQ-305는 규칙에서 이미 격리, LLM에 가지 않음) |
|
||||
| B-2 시간 | 1.4초 | **9.3초** (규칙을 통과한 9줄 × LLM 한 번) |
|
||||
|
||||
- LLM이 막은 줄은 FAQ-210 **하나**뿐입니다. 드문 한 줄을 위해 줄마다 1초쯤을 씁니다. 가져오기(배치를 보낼 때 한 번)라 괜찮다고 판단했지만, 직원이 기다리는 헬프데스크 답이라면 다른 판단이 필요합니다.
|
||||
|
||||
## 4. 기준은 고르는 값 (4교시 Lab 02 예제 3)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 반품 기준을 풀면, 조이면.** "열에 셋까지 골라 받는다"를 "열에 여덟까지"로 풀면 트럭을 돌려보내는 일은 줄지만 보류 칸이 넘치고 주방장이 하루 종일 골라냅니다. "하나도 안 된다"로 조이면 보류 칸은 비지만 거의 모든 트럭이 돌아가 재료가 모자랍니다.
|
||||
|
||||
**기준 하나가 두 실수를 맞바꿉니다.** 통계에서는 1종 오류(괜찮은 것을 막음)와 2종 오류(나쁜 것을 받음)라고 부릅니다. 기준은 **맞고 틀리는 값이 아니라 고르는 값**이고, 팀이 정해 적어 둡니다. 77일차 SLO 기준 · 이상 시간대 문턱과 같습니다.
|
||||
|
||||
| 기준 | 잘못 받는 일 | 잘못 돌려보내는 일 | 누구의 일이 느나 |
|
||||
| --- | --- | --- | --- |
|
||||
| 느슨하게 | 늘어남 | 줄어듦 | 격리함을 보는 사람 |
|
||||
| 엄하게 | 줄어듦 | 늘어남 | 다시 보내는 사람, FAQ가 늦게 열림 |
|
||||
|
||||
기준을 바꿀 때마다 워크플로우를 고치지 않으려면 기준을 **입력**으로 받습니다 (`max_invalid_ratio`, 없으면 0.3).
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
같은 가져오기에 기준만 바꿔 (Lab 02 예제 3, 에이전트 없이):
|
||||
|
||||
| 배치 | 기준 | 결과 |
|
||||
| --- | --- | --- |
|
||||
| B-1 | 0.3 | 거절 (0.7692) |
|
||||
| B-1 | 0.8 | 받음 — 넣음 **2** · 격리 **11** · `score` 0.1538 |
|
||||
| B-2 | 0.05 | 거절 (0.1) — 멀쩡한 9줄도 돌아감 |
|
||||
| B-2 | 0.1 | 받음 — 딱 같으면 통과 |
|
||||
|
||||
- 실험을 하나씩 떼어 봐야 합니다: B-1을 받으면 FAQ-102 "회의실 예약"이 들어가 B-2의 FAQ-201이 `same_title`로 나빠지고, B-2를 넣은 뒤 다시 보내면 9줄이 `exists_id`입니다 (수업 준비 때 둘 다 겪음). **앞 배치가 넣은 데이터가 다음 배치의 판정을 바꿉니다.**
|
||||
- 강사는 0.3을 그대로 두었습니다: "열에 셋까지는 골라 받고, 그보다 나쁘면 돌려보내 고치게 한다."
|
||||
|
||||
## 5. 품질 기록 · 알림 (4교시 Lab 02 과제 1)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 검수 일지와 사장님 호출.** 주방장은 상자마다 일지에 "몇 개 받음 · 몇 개 반품 · 이유"를 적습니다. 일지가 쌓여야 "요즘 그 업체가 나빠졌다"를 말할 수 있습니다. 트럭째 반품한 날은 사장님께 바로 전화합니다.
|
||||
|
||||
**품질은 한 번 재고 끝나지 않습니다 — 기록이 쌓여야 관리됩니다.** 배치마다 같은 모양으로 한 줄(배치 · 데이터셋 · 줄 수 · 통과 · 격리 · 거절 · 점수 · 코드)을 남기면 3단계에서 추세 · 가장 나쁜 배치 · 가장 흔한 문제를 셉니다. 거절한 배치도 **반드시** 기록합니다 — 빼면 가장 나쁜 배치가 보고서에서 사라집니다.
|
||||
|
||||
**알림은 사람이 할 일이 있을 때만** (76일차). 거절(보낸 사람에게 알려야 함) · 낮은 점수(격리함을 봐야 함)일 때 보냅니다. 그리고 알림을 보내도 **부른 쪽이 받는 결과는 그대로**입니다 — 알림은 곁가지.
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
| 배치 | 응답 | 품질 기록 | 알림 |
|
||||
| --- | --- | --- | --- |
|
||||
| B-1 | 422 | `rejected: true` · `score` 0 | `batch_rejected` |
|
||||
| B-2 | 200 · 0.8 | `valid` 8 · `quarantined` 2 · 0.8 | `low_quality` (0.9 미만) |
|
||||
|
||||
- HTTP 노드(`Log quality` · `Alert low score`)의 출력은 데이터 API의 응답(`{"stored": 1}`)이라, 끝에 `Result again`이 가져오기 결과를 다시 꺼내 응답합니다. 그래서 `lab02` 6/6이 그대로입니다.
|
||||
|
||||
## 6. LLM 호출 수 · 늘 같은가 (4교시 Lab 02 과제 2)
|
||||
|
||||
### 일반 설명
|
||||
|
||||
> **생활 속 예 · 맛보기 횟수와 맛보는 사람.** 사장님이 묻습니다: "오늘 맛보기를 몇 번 했지? 상한 것까지 맛본 건 아니지?" 그리고 "어제 맛본 사람과 오늘 맛본 사람의 판정이 같나?"
|
||||
|
||||
**LLM 비용은 호출 수로 말합니다.** 시간은 매번 다르지만(같은 9번이 7.6~9.4초) 호출 수는 정해집니다. 호출당 비용을 알면(75일차) 배치의 비용이 바로 나옵니다.
|
||||
|
||||
**"늘 같은가"는 재 봐야 압니다.** temperature 0이어도 LLM 판정이 늘 같다는 보증은 없습니다. 같은 입력을 **같은 처음 상태**에서 여러 번 돌려 판정이 같은지 봅니다 (72일차 반복 시험). 그리고 같은 배치를 처음 상태로 되돌리지 않고 다시 보내면 **데이터가 바뀐 것**이지 판정이 흔들린 것이 아닙니다 — 둘을 구분해야 합니다.
|
||||
|
||||
### 오늘 실습에서
|
||||
|
||||
| 배치 | 줄 | `llm_calls` | 세 번 |
|
||||
| --- | --- | --- | --- |
|
||||
| B-1 (거절) | 13 | **0** | 같음 |
|
||||
| B-2 | 10 | **9** (= 10 − FAQ-209) | FAQ-210만 막음 · 9.4 · 8.1 · 7.6초 |
|
||||
| B-3 | 6 | **5** (= 6 − FAQ-305) | 넣음 5 |
|
||||
|
||||
- `--no-before --repeat 2`(처음 상태로 되돌리지 않고 연달아)는 **2/6**: 앞 실행이 넣은 FAQ 때문에 B-2 · B-3이 `exists_id`로 거절되고 LLM은 0번. 같은 배치를 두 번 보내도 FAQ가 두 벌 생기지 않는다는 확인이기도 합니다.
|
||||
|
||||
## 7. 요청문(프롬프트)으로 에이전트에게 맡기기
|
||||
|
||||
가져오기 요청문은 "검사해서 넣어 줘"가 아니라 **관문과 갈래**를 적습니다.
|
||||
|
||||
| 넣을 것 | 예 |
|
||||
| --- | --- |
|
||||
| 부를 검사 | "규칙을 다시 쓰지 말고 `my-faq-check`를 부른다 (neverError, timeout 30000)" |
|
||||
| 배치 게이트 | "`invalid / total`이 기준 이하일 때만, 기준은 본문 `max_invalid_ratio`, 없으면 0.3, 넘으면 422" |
|
||||
| 줄 게이트 · 격리 | "ok면 `/faq/add`, 아니면 `/quarantine {items: [{batch, row, errors}]}` — HTTP 노드 하나에서" |
|
||||
| LLM 검사 | "규칙을 통과한 줄만, JSON으로만, 읽을 수 없으면 match false, onError continueRegularOutput" |
|
||||
| 기록 · 알림 | "거절도 기록, 거절 · 0.9 미만이면 알림, 응답은 같은 결과" |
|
||||
| 기대 결과 | "`cases/lab02.json`, 앞의 테스트도 그대로" |
|
||||
|
||||
## 8. 자주 하는 실수
|
||||
|
||||
| 실수 | 결과 | 바로잡기 |
|
||||
| --- | --- | --- |
|
||||
| 가져오기 안에 규칙을 다시 씀 | 검사와 어긋남 | 검사 웹훅을 부름 |
|
||||
| 나쁜 줄을 버림 | 무엇이 빠졌는지 모름 · 다시 못 넣음 | 이유와 함께 격리 |
|
||||
| 넣기 · 격리를 IF로 갈랐다 합침 | LLM 뒤 격리 수가 틀림 | HTTP 노드 하나 |
|
||||
| 모든 줄을 LLM에 | 비용 · 시간 | 규칙을 통과한 줄만 |
|
||||
| LLM 판정을 읽을 수 없으면 넣음 | LLM이 멈춘 날 검사 없이 들어감 | fail-closed |
|
||||
| 기준을 IF에 숫자로 박음 | 바꿀 때마다 워크플로우 수정 | 입력(`max_invalid_ratio`)으로 |
|
||||
| 거절을 기록하지 않음 | 가장 나쁜 배치가 보고서에서 사라짐 | 두 갈래 모두 기록 |
|
||||
| 알림 노드의 출력으로 응답 | 부른 쪽이 `{"stored": 1}`을 받음 | 결과를 다시 꺼냄 |
|
||||
| `--repeat`로 "늘 같은가"를 봄 | 이미 넣은 데이터로 거절 | 처음 상태에서 따로 세 번 |
|
||||
|
||||
## 확인 질문
|
||||
|
||||
<details><summary>1. 기준 가져오기의 B-1 `score`는 0.9231, 내 가져오기는 422(거절)입니다. 점수가 높은 기준이 더 좋은 것 아닌가요?</summary>
|
||||
|
||||
기준의 점수는 "넣은 줄 / 전체 줄"인데, 넣은 12줄에 개인 전화번호 · 단축 링크 · 빈 제목이 들어 있습니다. 검사 없는 점수는 품질이 아니라 **양**입니다. 점수는 같은 규칙으로 판정한 뒤에야 품질을 말합니다.
|
||||
</details>
|
||||
|
||||
<details><summary>2. 400과 422를 나누는 까닭은?</summary>
|
||||
|
||||
400은 본문의 모양이 틀려 읽을 수조차 없다는 뜻(`items`가 목록이 아님)이고, 422는 읽었지만 내용이 기준을 넘어 받을 수 없다는 뜻입니다. 부른 쪽은 400이면 보내는 코드를, 422면 보내는 데이터를 고칩니다.
|
||||
</details>
|
||||
|
||||
<details><summary>3. LLM 검사를 모든 줄에 하면 더 안전하지 않나요?</summary>
|
||||
|
||||
규칙에 걸린 줄은 이미 격리되므로 LLM이 무엇이라 하든 결과가 같습니다. 같은 결과에 돈과 시간만 씁니다 (B-1 13줄 · B-2 10줄 대신 0 · 9번). 더 안전해지려면 오히려 "LLM 판정을 읽을 수 없으면 넣지 않는다"(fail-closed)를 지켜야 합니다.
|
||||
</details>
|
||||
|
||||
<details><summary>4. 기준을 0.8로 풀었더니 B-1을 받았습니다. 넣은 줄은 2줄뿐인데 무엇이 나빠졌나요?</summary>
|
||||
|
||||
격리함에 11줄이 쌓였습니다. 사람이 11줄을 하나씩 열어 고칠지 정해야 합니다. 거절했다면 콘텐츠 담당자가 고침 목록(Lab 01 과제 2)을 받아 한 번에 고쳐 다시 보냈을 일입니다. 기준을 푼 대가는 "격리함을 보는 사람의 일"입니다.
|
||||
</details>
|
||||
|
||||
<details><summary>5. `--repeat 2`로 돌렸더니 두 번째에 B-2가 거절됐습니다. LLM 판정이 흔들린 건가요?</summary>
|
||||
|
||||
아닙니다. 첫 실행이 FAQ-201~208을 넣었기 때문에, 같은 배치를 다시 보내면 그 8줄이 `exists_id`가 되어 나쁜 줄이 9/10, 거절입니다. 거절이니 LLM은 한 번도 부르지 않았습니다 (`llm_calls` 0). "늘 같은가"를 보려면 매번 처음 상태(테스트의 `before`)에서 돌립니다.
|
||||
</details>
|
||||
@@ -0,0 +1,236 @@
|
||||
# 3단계 · 품질 관리
|
||||
|
||||
- 교시: 5교시 강의 (14:00~14:50) · 6교시 [Lab 03](../../Last3Mon/78/LAB-03-Q-QUALITY-MANAGEMENT.md) 실습 5개 (15:00~15: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 문서](../../Last3Mon/78/LAB-03-Q-QUALITY-MANAGEMENT.md)의 그 절입니다. 파일 경로는 실습 폴더 `~/aio-01d4-stu/Last3Mon/78` 기준입니다.
|
||||
|
||||
```mermaid
|
||||
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와 같은 모양입니다.
|
||||
|
||||
```mermaid
|
||||
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만 뺌 |
|
||||
| 스키마를 리뷰 없이 바꿈 | 규칙이 몰래 바뀜 | 스키마도 저장소 · 리뷰 · 테스트 |
|
||||
| 거절을 평균에서 뺌 (말없이) | 품질이 좋아 보임 | 정의를 정하고 함께 말함 |
|
||||
| 전체 평균 · 섞은 추세만 봄 | 손볼 데이터셋이 가려짐 | 데이터셋별로, 추세는 그 안에서 |
|
||||
|
||||
## 확인 질문
|
||||
|
||||
<details><summary>1. 스키마 검사를 만들었으니 Lab 01의 FAQ 검사는 지워도 되나요?</summary>
|
||||
|
||||
아닙니다. 스키마는 모양(필수 · 길이 · 꼴 · 중복)을 보고, FAQ 검사는 FAQ만의 내용 규칙(답 안의 개인정보 · 바깥 링크)과 이미 있는 FAQ와의 관계를 봅니다. B-2를 스키마로만 보면 메일 주소 FAQ-209가 통과합니다. 모양은 스키마로 넓게, 내용은 Code로 깊게.
|
||||
</details>
|
||||
|
||||
<details><summary>2. 고친 배치를 다시 넣었는데 격리함에서 빼지 않으면 무엇이 문제인가요? 넣기는 됐잖아요.</summary>
|
||||
|
||||
격리함은 "사람이 볼 일"의 목록입니다. 해결된 FAQ-209 · 210이 남아 있으면 다음 사람이 또 고치려 하거나, 목록 전체를 믿지 않게 됩니다. 넣은 줄만 빼고, 또 틀린 줄은 남겨 다시 사람에게 보냅니다.
|
||||
</details>
|
||||
|
||||
<details><summary>3. 새 스키마를 더할 때 워크플로우를 고치지 않아도 된다면, 스키마는 누구나 바꿔도 되나요?</summary>
|
||||
|
||||
반대입니다. 워크플로우를 고치지 않고 판정이 바뀐다는 것은, 스키마 한 줄이 곧 규칙이라는 뜻입니다. `min: 4`를 `min: 40`으로 잘못 쓰면 그날부터 모든 접수 건이 막힙니다. 스키마도 코드처럼 저장소에 두고 리뷰 · 테스트를 거쳐 바꿉니다.
|
||||
</details>
|
||||
|
||||
<details><summary>4. 품질 보고서의 평균은 0.6583입니다. 거절된 B-1을 빼면 0.8778인데, 어느 쪽을 보고해야 하나요?</summary>
|
||||
|
||||
무엇을 보고 싶은지에 따라 정하고, 정의에 적어 둡니다. 오늘은 콘텐츠 담당자가 **보내오는** 배치의 품질을 보므로 거절도 넣습니다(0.6583). "받은 배치의 품질"이 궁금하면 뺀 숫자(0.8778)를 따로 말합니다. 정하지 않고 그때그때 고르면 숫자를 비교할 수 없습니다.
|
||||
</details>
|
||||
|
||||
<details><summary>5. 데이터셋별로 나누니 접수 건이 0.2222로 가장 나쁩니다. 그런데 기록이 한 배치씩뿐입니다. 이 결론을 믿어도 되나요?</summary>
|
||||
|
||||
"이번 배치는 접수 건이 가장 나쁘다"까지는 말할 수 있습니다. "접수 건 데이터가 늘 나쁘다"는 배치가 쌓여야 말할 수 있습니다 (77일차 표본 크기). 9줄 중 7줄이 줄마다 다른 이유로 나쁘다는 것은 옮기기 전에 원본을 손봐야 한다는 신호로는 충분합니다.
|
||||
</details>
|
||||
@@ -0,0 +1,207 @@
|
||||
# 4단계 · 정리: 오늘 한 일의 의미 · 효과 · 실전 응용
|
||||
|
||||
- 교시: 8교시 17:10~17:45 (35분, 바이브 코딩 발표 10분 뒤) · 자료: 이 문서 + [개요](00-DAY78-OVERVIEW.md) 30장
|
||||
- 이 시간이 끝나면: 오늘 1~3단계에서 한 일이 **무엇을 위한 것이었는지**, 숫자로 **무엇이 달라졌고 무엇을 치렀는지**, 회사에서는 같은 생각을 **어떤 이름과 도구로** 쓰는지 말할 수 있고, 최종 프로젝트에 무엇을 가져갈지 정할 수 있다.
|
||||
- 숫자: 오늘 교안의 실측(강사 노트북, 11/01 정답 워크플로우 1회)입니다. "예시"라고 적은 계산은 가정을 둔 어림입니다.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["1. 오늘 한 장"] --> B["2. 왜 데이터 품질을<br/>자동으로"] --> C["3. 효과와 값을 숫자로"] --> D["4. 회사에서 부르는 이름"]
|
||||
D --> E["5. 산업별 응용"] --> F["6. 데이터 계약서"] --> G["7. 하지 말아야 할 때"] --> H["8. 직무 · 면접"] --> I["9. 최종 프로젝트로"]
|
||||
```
|
||||
|
||||
## 0. 이 시간 (35분)
|
||||
|
||||
| 시간 | 절 | 하는 일 |
|
||||
| --- | --- | --- |
|
||||
| 17:10~17:15 | 1 · 2 | 오늘 한 장, 왜 데이터 품질을 자동으로 |
|
||||
| 17:15~17:20 | 3 | 오늘 숫자로 본 효과와 값, 한 달로 보면 (예시) |
|
||||
| 17:20~17:28 | 4 · 5 | 같은 생각의 업계 이름 · 도구, 산업별 응용 예 |
|
||||
| 17:28~17:33 | 6 · 7 | 데이터 계약서, 하지 말아야 할 때 |
|
||||
| 17:33~17:40 | 8 · 9 | 직무와 면접 질문, 최종 프로젝트 체크리스트 |
|
||||
| 17:40~17:45 | 10 · 토론 | 다음 일차와의 연결, 질문 둘 |
|
||||
|
||||
## 1. 오늘 한 장
|
||||
|
||||
| 단계 | 한 일 | 오늘 숫자 |
|
||||
| --- | --- | --- |
|
||||
| 1단계 · 품질 규칙 | 눈으로 · 기준 검사, 규칙대로 판정하는 검사, 경계, 이미 있는 데이터, 고침 목록 | 기준 **10/13 통과 · 1/5** → 규칙대로 **5/13 · 5/5**, 경계 6/6 대 **0/6**, 이미 있는 데이터까지 3/13, 고침 목록 10줄 |
|
||||
| 2단계 · 품질 게이트 | 배치 게이트 · 격리, LLM 검사, 기준을 바꾸면, 기록 · 알림, LLM 호출 수 | 기준 가져오기 **12줄 넣음 · 0/6** → B-1 거절 · B-2 9줄 → LLM이 FAQ-210을 막아 8줄 · 6/6, 기준 0.8이면 격리 **11**, LLM 호출 9 · 5 · 0 |
|
||||
| 3단계 · 품질 관리 | 스키마 검사, 고쳐서 다시, 새 스키마, 품질 보고서, 데이터셋별 | 직원 CSV 4/9, 격리 2 → 0, 접수 건 2/9 (**워크플로우 그대로**), 평균 0.6583, ticket **0.2222** |
|
||||
|
||||
## 2. 왜 데이터 품질을 자동으로
|
||||
|
||||
> **생활 속 예 · 식당의 검수.** 장사가 잘되는 식당은 손님이 "맛이 이상해요"라고 하기 전에 아침 검수에서 상한 재료를 골라냅니다. 손님이 알아챘을 때는 이미 늦습니다 — 접시는 나갔고 믿음은 깎였습니다. 그리고 검수가 주방장 한 사람의 눈에만 있으면, 그 사람이 쉬는 날 상한 재료가 들어옵니다. 그래서 기준표 · 반품 칸 · 일지를 둡니다. 3단계 7절의 "식당 주방으로 본 오늘 하루" 표도 함께 봅니다.
|
||||
|
||||
| 사람이 눈으로만 검사하면 | 규칙 · 게이트 · 기록으로 하면 |
|
||||
| --- | --- |
|
||||
| 바쁜 날 놓침 (기준 검사 10/13 통과) | 같은 배치에 늘 같은 판정 (5/13) |
|
||||
| "이 정도면 괜찮겠지" — 경계가 그날 기분 | 40자 넘으면 · 공백은 빈 값 · 호스트가 정확히 |
|
||||
| 나쁜 FAQ가 직원 화면에 (전화번호 · 단축 링크) | 거절 · 격리, 넣지 않음 |
|
||||
| 고칠 것을 말로 전달 | 고침 목록 (줄 · 코드 · 말) |
|
||||
| 새 데이터마다 사람을 새로 | 스키마 한 장 |
|
||||
| "요즘 품질 어때?"에 감으로 | 품질 기록 → 평균 · 가장 나쁜 배치 · 흔한 문제 · 데이터셋별 |
|
||||
|
||||
**오늘의 원칙 세 줄**: 규칙은 Code가, 뜻은 LLM이, 고치는 것은 사람이. 워크플로우는 나쁜 데이터를 고쳐서 넣지 않고 **막고 알리고 기록합니다.**
|
||||
|
||||
## 3. 효과와 값을 숫자로
|
||||
|
||||
### 3.1 오늘 실측 전 · 후
|
||||
|
||||
| 무엇 | 전 (팀의 기준) | 후 | 바꾼 것 |
|
||||
| --- | --- | --- | --- |
|
||||
| B-1 13줄 판정 | 10줄 통과 | 5줄 → 이미 있는 데이터까지 3줄 | 규칙 3 → 10 (+ 이미 있는 데이터) |
|
||||
| 경계 10줄 | 10줄 통과 (0/6) | 4줄 통과 (6/6) | 경계의 말 |
|
||||
| B-1이 FAQ에 | **12줄** (전화번호 · 단축 링크 · 같은 id) | **0줄** · 422 | 배치 게이트 |
|
||||
| B-2가 FAQ에 | 10줄 (메일 주소 · 다른 답) | 8줄, 2줄은 이유와 함께 격리 | 줄 게이트 + LLM 검사 |
|
||||
| 나쁜 줄의 행방 | 모름 (격리함 0) | 격리함 + 이유, 고치면 빼기 | 격리 · 되돌림 고리 |
|
||||
| 직원 · 접수 건 | 검사 못 함 (400) | 4/9 · 2/9 | 스키마 |
|
||||
| 새 데이터셋 | 워크플로우를 하나 더 | 스키마 파일 한 장 | 규칙을 데이터로 |
|
||||
| "품질 어때?" | 감 | 0.6583 · B-1 · `pii` · ticket 0.2222 | 품질 기록 · 보고서 |
|
||||
|
||||
**치른 값**:
|
||||
|
||||
- **시간**: LLM 검사로 B-2 가져오기가 1.4초 → 9.3초. 가져오기라 괜찮았지만, 사람이 기다리는 곳에서는 다른 판단이 필요합니다.
|
||||
- **사람의 일**: 격리함은 누군가 봐야 합니다. 기준을 0.8로 풀면 11줄. 기준은 그 일의 양을 정하는 값입니다.
|
||||
- **규칙을 지키는 일**: 규칙(AGENTS.md · 스키마)을 바꾸면 모든 판정이 바뀝니다. 바꿀 때는 누가 · 왜를 남기고 테스트(경계 포함)를 함께 고칩니다.
|
||||
- **오탐 · 미탐**: `01012345678`은 잡지만 `010 1234 5678`처럼 띄어 쓴 변형이나 이미지 속 번호는 못 잡습니다. 규칙은 완벽하지 않고, 그래서 기록과 사람의 검토가 함께 갑니다.
|
||||
|
||||
### 3.2 한 달로 보면 (예시)
|
||||
|
||||
가정: 콘텐츠 담당자가 하루 한 배치(10~13줄), 한 달 평일 20배치, 나쁜 FAQ 한 줄이 들어가면 직원 문의 5건이 틀린 답을 받고, 그중 1건이 담당자 확인(5분)으로 이어짐.
|
||||
|
||||
| | 검사 없이 (기준 가져오기, 오늘 비율) | 게이트 뒤 (예시) |
|
||||
| --- | --- | --- |
|
||||
| 들어가는 나쁜 줄 | B-1에서 12줄 중 약 9줄 · B-2에서 2줄 → 배치당 수 줄 | 거의 0 (규칙 · LLM에 걸리는 것) |
|
||||
| 틀린 답 · 담당자 시간 | 한 달 수십 줄 × 5건 → 담당자 확인 수십 번 | 격리함을 보는 시간 (하루 몇 분) |
|
||||
| LLM 비용 | 0 | 규칙을 통과한 줄만 — 한 배치 5~9번 |
|
||||
|
||||
- 숫자는 가정입니다. 그래도 **나쁜 데이터 한 줄의 값(틀린 답 · 사람의 시간 · 개인정보 사고)과 막는 값(시간 · LLM 호출 · 격리함)을 같은 표에서 말할 수 있다**는 것이 오늘 만든 기록의 효과입니다. 개인정보 한 줄은 횟수로 셀 수 없는 비용입니다.
|
||||
|
||||
## 4. 회사에서는 같은 생각을 이렇게 부른다
|
||||
|
||||
| 오늘 한 것 | 업계 이름 | 쓰는 도구 · 표준 (예) |
|
||||
| --- | --- | --- |
|
||||
| 품질 차원 | data quality dimensions (완전성 · 유효성 · 고유성 · 일관성 · 정확성 · 적시성) | DAMA-DMBOK, ISO 8000 |
|
||||
| 품질 규칙 · 오류 코드 | data validation rules, expectations | Great Expectations · Soda · Deequ · dbt tests |
|
||||
| 경계 테스트 | boundary value testing | 단위 테스트 · property-based testing (Hypothesis) |
|
||||
| 이미 있는 데이터와 맞추기 | referential integrity, unique constraint | 데이터베이스 제약 · dbt `relationships` · `unique` |
|
||||
| 고침 목록 · 규칙 약속 | data contract, validation report | Data Contract Specification, 스키마 레지스트리 |
|
||||
| 배치 게이트 · 품질 관문 | quality gate, circuit breaker | Airflow · Dagster 센서, CI의 데이터 테스트 |
|
||||
| 격리함 · 되돌림 | quarantine table, dead-letter queue, replay | Kafka DLQ · Delta Lake quarantine |
|
||||
| LLM 검사 | LLM-as-a-judge, content moderation | OpenAI moderation · 사내 평가기 |
|
||||
| 기준의 대가 | precision / recall, 1종 · 2종 오류 | 혼동 행렬, 임계값 조정 |
|
||||
| 품질 기록 · 보고서 | data quality score, data observability | Monte Carlo · Bigeye · Soda Cloud |
|
||||
| 스키마 | JSON Schema · OpenAPI · table schema | pydantic · zod · Avro · Protobuf |
|
||||
| 새 스키마로 넓히기 | configuration over code, schema registry | Confluent Schema Registry |
|
||||
| `tcheck` | 데이터 검사 CLI · pre-commit 검사 | `csvkit` · `great_expectations checkpoint` · pre-commit 훅 |
|
||||
|
||||
- 오늘은 n8n 워크플로우 · 작은 데이터 API · `flow.py`로 직접 만들었습니다. 회사에서는 위 도구가 대신하는 경우가 많습니다. 그래도 **무엇이 나쁜지(규칙), 어디서 막을지(관문), 얼마나 막을지(기준), 누가 고칠지(주인)**는 오늘처럼 사람이 정합니다.
|
||||
|
||||
## 5. 산업별 응용 (예)
|
||||
|
||||
아래는 오늘 한 일을 다른 업무에 옮긴 예입니다 (실제 특정 회사의 사례가 아니라 흔한 모양).
|
||||
|
||||
| 업무 | 오늘의 무엇을 | 이렇게 |
|
||||
| --- | --- | --- |
|
||||
| 고객센터 챗봇 · FAQ (오늘) | 규칙 · LLM 검사 · 고침 목록 | 콘텐츠 팀이 올리는 답에 개인정보 · 링크 · 질문과 맞나 검사, 반려 사유를 자동으로 |
|
||||
| 쇼핑몰 상품 등록 | 스키마 · 배치 게이트 | 판매자가 올린 상품 CSV를 가격 · 재고 · 카테고리 스키마로, 나쁜 줄이 많으면 통째로 반려 |
|
||||
| 인사 · 회계 데이터 이관 | 스키마 · 격리 · 되돌림 | 새 시스템으로 옮길 때 나쁜 줄을 격리하고 담당 부서가 고쳐 다시 |
|
||||
| RAG · 지식 검색 | 품질 게이트 · 중복 · 이미 있는 데이터 | 문서를 색인하기 전에 빈 문서 · 중복 · 개인정보 · 오래된 판을 막음 (80~82일차 단위 프로젝트) |
|
||||
| 데이터 파이프라인 · ETL | 품질 기록 · 데이터셋별 | 밤마다 적재한 테이블의 품질 점수, 떨어지면 알림, 테이블별 성적표 |
|
||||
| 의료 · 금융 (규제) | 데이터 계약 · 감사 | 들어온 데이터의 판정과 이유를 모두 기록, 누가 언제 고쳤는지 |
|
||||
|
||||
**토론 거리**: 내 회사(또는 가고 싶은 회사)의 데이터 하나를 골라, "스키마 다섯 칸과 막을 규칙 셋을 정한다면?"을 정해 봅니다.
|
||||
|
||||
## 6. 데이터 계약서 (최종 프로젝트용 틀)
|
||||
|
||||
오늘의 AGENTS.md 3절이 데이터 계약서였습니다. 최종 프로젝트에서도 데이터마다 이 틀로 한 장을 씁니다.
|
||||
|
||||
| 칸 | 타입 · 꼴 | 필수 | 규칙 (코드) | 위반이면 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `id` | `pattern ^FAQ-\d{3}$` | ✔ | `bad_format:id`, 중복 `duplicate_in_batch`, 이미 있음 `exists_id` | 격리 |
|
||||
| `title` | `string` ≤ 40 | ✔ | `missing:title` · `too_long:title`, 같은 제목 `same_title` | 격리 |
|
||||
| `answer` | `string` 10~300 | ✔ | 개인정보 `pii` · 바깥 링크 `external_link` · 뜻 `llm_mismatch` | 격리 |
|
||||
| 배치 | — | — | 나쁜 줄 비율 > 0.3 | 거절 + 알림 + 고침 목록 |
|
||||
| 기록 | `{batch, dataset, total, valid, quarantined, rejected, score, codes}` | — | score < 0.9 | 알림 |
|
||||
|
||||
- 계약이 없으면 품질을 말할 수 없습니다. **규칙과 그 말이 있어야 "좋아졌다"고 말할 수 있습니다.**
|
||||
|
||||
## 7. 하지 말아야 할 때 (흔한 실수)
|
||||
|
||||
| 하기 쉬운 일 | 왜 위험한가 | 대신 |
|
||||
| --- | --- | --- |
|
||||
| 규칙 없이 "나쁜 것 걸러 줘" | 판정이 사람 · 에이전트마다 다름 | 규칙 표 · 코드 |
|
||||
| 경계의 말을 안 정함 | 딱 기준선의 줄이 날마다 다르게 | 넘으면 · 공백 · 꼴 · 정확히 |
|
||||
| 나쁜 데이터를 고쳐서 넣음 | 틀린 것이 "통과"로, 원인이 숨음 | 막고 알리고, 사람이 고침 |
|
||||
| 나쁜 줄을 버림 | 무엇이 빠졌는지 모름 | 격리 + 이유 |
|
||||
| 모든 것을 LLM에게 판정 | 늘 같지 않고 비쌈 | 규칙은 Code, 뜻만 LLM, 통과한 줄에만 |
|
||||
| LLM을 모르면 통과 | LLM이 멈춘 날 검사 없이 | fail-closed |
|
||||
| 기준을 아무렇게 | 격리함 폭발 또는 모두 반려 | 대가를 재고 팀이 정해 적음 |
|
||||
| 스키마를 몰래 바꿈 | 규칙이 바뀐 줄 모름 | 저장소 · 리뷰 · 테스트 |
|
||||
| 평균 하나로 보고 | 손볼 데이터셋이 가려짐 | 데이터셋별, 추세는 그 안에서 |
|
||||
|
||||
## 8. 직무와 면접
|
||||
|
||||
오늘 한 일은 다음 직무들이 날마다 하는 일입니다: **데이터 엔지니어 · 분석 엔지니어, 데이터 품질 · 거버넌스 담당, 백엔드 · 플랫폼 엔지니어, AI · LLM 애플리케이션 엔지니어(RAG 데이터 준비), 콘텐츠 · CS 운영, 업무 자동화(n8n · RPA) 개발자.** 채용 공고의 "데이터 품질 관리", "데이터 검증 · 정합성", "ETL · 파이프라인 모니터링", "데이터 거버넌스", "스키마 설계"가 오늘 내용입니다.
|
||||
|
||||
면접에서 흔히 받는 질문과 오늘 숫자로 답하는 법:
|
||||
|
||||
<details><summary>1. "데이터 품질을 어떻게 정의하고 측정하나요?"</summary>
|
||||
|
||||
품질 차원(완전성 · 유효성 · 고유성 · 일관성 · 정확성)으로 나누고, 차원마다 규칙과 오류 코드를 정했습니다. 줄마다 코드를 붙이고 배치마다 통과 비율을 점수로 기록했습니다. 오늘 FAQ 배치 B-1은 13줄 중 3줄만 통과했고, 가장 흔한 문제는 개인정보(`pii`)였습니다. 데이터셋별로 나누니 접수 건이 0.2222로 가장 나빴습니다.
|
||||
</details>
|
||||
|
||||
<details><summary>2. "나쁜 데이터가 들어오면 어떻게 하나요? 고쳐서 넣으면 안 되나요?"</summary>
|
||||
|
||||
두 관문을 둡니다. 나쁜 줄 비율이 기준(0.3)을 넘으면 배치를 통째로 거절하고 고침 목록과 함께 돌려보내고, 넘지 않으면 좋은 줄만 넣고 나쁜 줄은 이유와 함께 격리합니다. 고쳐서 넣지 않는 까닭은, 틀린 내용이 "검사를 통과한 데이터"가 되고 원인(보내는 쪽)이 그대로 남기 때문입니다. 고쳐 돌아온 줄은 다시 검사해 넣고 격리함에서 뺍니다.
|
||||
</details>
|
||||
|
||||
<details><summary>3. "LLM을 데이터 검사에 쓴다면 무엇을 조심하나요?"</summary>
|
||||
|
||||
규칙으로 판정할 수 있는 것은 Code로 하고, 뜻(답이 질문에 맞나)만 LLM에게, 그것도 규칙을 통과한 줄에만 묻습니다. 오늘 B-2는 10줄 중 9줄만 물었고, LLM이 막은 줄은 하나였습니다. 판정을 읽을 수 없으면 넣지 않고(fail-closed), 호출 수를 기록해 비용을 말하고, 같은 처음 상태에서 여러 번 돌려 판정이 같은지 봤습니다.
|
||||
</details>
|
||||
|
||||
<details><summary>4. "검사 기준(임계값)은 어떻게 정하나요?"</summary>
|
||||
|
||||
기준을 바꿔 가며 대가를 쟀습니다. 0.3이면 B-1을 거절, 0.8로 풀면 받지만 격리함에 11줄이 쌓이고, 0.05로 조이면 B-2가 한 줄 때문에 거절됩니다. 거절(보내는 쪽의 일)과 격리(검토하는 쪽의 일)를 맞바꾸는 값이라, 팀이 일의 양을 보고 정해 적어 둡니다. 경계("같으면 통과")도 말로 정합니다.
|
||||
</details>
|
||||
|
||||
<details><summary>5. "새로운 데이터셋이 생기면 검사를 어떻게 늘리나요?"</summary>
|
||||
|
||||
규칙을 코드가 아니라 스키마로 둡니다. 검사 코드는 칸 이름을 모르고 타입마다 판정하므로, 오늘 접수 건(`ticket`) 스키마 한 장을 더하자 워크플로우를 고치지 않고 9줄을 검사했습니다. 대신 스키마 변경이 곧 규칙 변경이라 저장소에 두고 리뷰 · 테스트를 거칩니다. 데이터마다 다른 내용 규칙(개인정보 등)은 Code로 따로 둡니다.
|
||||
</details>
|
||||
|
||||
## 9. 최종 프로젝트로 가져갈 것
|
||||
|
||||
최종 프로젝트(85일차~)의 워크플로우에 아래를 넣으면 "들어오는 데이터를 믿을 수 있는 프로젝트"가 됩니다.
|
||||
|
||||
- [ ] 데이터마다 계약서 한 장 (6절 틀): 칸 · 타입 · 필수 · 규칙 코드 · 위반이면
|
||||
- [ ] 검사 웹훅 하나 (규칙은 한 곳), 줄마다 코드, 목록이 아니면 400
|
||||
- [ ] 경계 테스트 (딱 기준선 · 공백 · 꼴의 변형 · 비슷한 값)
|
||||
- [ ] 가져오기 게이트: 배치 거절(기준은 입력으로) · 줄 격리 + 이유, LLM은 통과한 줄에만 · fail-closed
|
||||
- [ ] 고침 목록을 보낸 사람에게, 고쳐 돌아오면 격리함 비우기
|
||||
- [ ] 스키마로 모양을 넓게, 데이터만의 규칙은 Code로
|
||||
- [ ] 품질 기록 (같은 모양) · 보고서 (평균 · 최저 · 흔한 문제 · 데이터셋별), 거절 · 낮은 점수 알림, `QUALITY.md`
|
||||
|
||||
## 10. 다음 일차와의 연결
|
||||
|
||||
| 일차 | 오늘의 무엇을 잇나 |
|
||||
| --- | --- |
|
||||
| 79 | 운영 데이터 기반 Ops Assistant(`tops`) — 77일차 실행 기록 · 오늘의 품질 기록 · 76일차 알림을 모아 "지금 무엇이 문제야?"에 숫자로 답하는 도우미, `tlog` · `tcheck`의 결과까지 |
|
||||
| 80~82 | 단위 프로젝트 — RAG 지식 문서를 색인하기 전에 오늘의 품질 관문, 팀 워크플로우에 9절 체크리스트 |
|
||||
|
||||
## 토론 (5분)
|
||||
|
||||
1. 오늘 "고치는 것은 사람"을 여러 번 했습니다. 공백을 지우는 것처럼 워크플로우가 "다듬어도 되는" 것과 "고치면 안 되는" 것의 경계는 어디일까요?
|
||||
2. B-1을 거절할까요, 기준을 풀어 2줄이라도 받을까요? 와이파이 FAQ처럼 그 배치에 **급한** 한 줄이 있다면 결정이 바뀌나요?
|
||||
|
||||
## 정리
|
||||
|
||||
- [ ] 데이터 품질은 차원으로 나눠 말하고, **규칙과 오류 코드**로 판정한다 (기준 10/13 vs 규칙 5/13)
|
||||
- [ ] 경계의 말을 정하고 경계에서 시험한다 (6/6 vs 0/6)
|
||||
- [ ] 검사와 게이트를 나눈다: 배치 거절 · 줄 격리 + 이유, 고치지 않고 돌려준다
|
||||
- [ ] 규칙은 Code, 뜻은 LLM(통과한 줄에만 · fail-closed), 고치는 것은 사람
|
||||
- [ ] 기준은 고르는 값 — 대가를 재고 적어 둔다
|
||||
- [ ] 규칙을 스키마로 꺼내 넓히고, 품질을 기록 · 보고서 · 데이터셋별로 관리한다
|
||||
- [ ] 최종 프로젝트에 체크리스트 7개를 가져간다
|
||||
@@ -0,0 +1,96 @@
|
||||
# 7·8교시 · 바이브 코딩 (`tcheck`)
|
||||
|
||||
- 교시: 7교시 16:00~16:50 (각자 만들기), 8교시 17:00~17:50 (발표 10분 · [4단계 정리](04-STAGE4-WRAPUP.md) 35분 · 예고 5분)
|
||||
- 과제: [VIBE-REQ-TCHECK](../../Last3Mon/78/VIBE-REQ-TCHECK.md)(요청서, 요청의 말 ①~⑫) → [VIBE-Q-TCHECK](../../Last3Mon/78/VIBE-Q-TCHECK.md)의 8단계: `Doc/TODO.md` → `Doc/SPEC.md` → `Doc/IMP-PLAN.md`(엔진 · TUI 단계) → 단계별 구현 → 확인 → `uv tool install` → 다른 폴더에서 사용 → 수업 뒤 `VIBE-A-TCHECK.md` 공개
|
||||
- 요구 14개(R1~R14). 50분 안에는 **엔진 1단계(R1 · R2 · R3 · R4 · R12 · R13) + 엔진 2단계(R5 · R6 · R7) + TUI 1단계(R11) + 설치(R14)**, 나머지(R8 내용 규칙, R9 고침 목록, R10 품질 기록)는 IMP-PLAN의 다음 단계로 집에서.
|
||||
- 72일차 `tbench`부터 77일차 `tlog`와 같은 흐름입니다: 사람의 말(요청서)을 **확인할 수 있는 요구**로 바꾸는 일을 학생이 먼저 하고, VIBE-Q는 그 다음 단계(비교 대상)로 씁니다. 에이전트에게는 처음 요청 한 번과 "확인했고 commit 했어. 다음 단계." 한 줄만 씁니다.
|
||||
- 오늘은 `tcheck`: CSV · JSON(오늘 요청 파일 모양 포함)을 데이터 API의 스키마로 검사해 **n8n `my-check`와 같은 판정**을 내고, 깨끗한 줄 · 나쁜 줄을 따로 내보내고, 배치 게이트를 종료 코드로 알리고, TUI로 탭을 나눠 보는 도구. 오늘 n8n 워크플로우로 한 일을 **보내기 전에, 내 노트북에서.**
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
R["요청서 → TODO · SPEC ·<br/>IMP-PLAN 20분"] --> A["7교시<br/>엔진 1 · 2 · TUI · 설치 30분"] --> B["발표<br/>10분"] --> C["4단계 정리<br/>35분"] --> F["79일차 예고<br/>5분"]
|
||||
```
|
||||
|
||||
> **생활 속 예 · 주머니에 넣는 검수 카드.** 오늘 주방(n8n)에 검수 기준표와 반품 칸을 만들었습니다. 납품업체가 "보내기 전에 창고에서 미리 검수하고 싶다"고 합니다. 같은 검수 카드를 **주머니에 넣어** 창고에서 쓰게 하면 됩니다. 핵심은 창고와 주방의 판정이 "같다"는 것입니다.
|
||||
|
||||
> 이 문서는 7 · 8교시 진행 문서입니다. 8교시의 정리 35분은 [04-STAGE4-WRAPUP](04-STAGE4-WRAPUP.md)으로 합니다.
|
||||
|
||||
## 1. 7교시 · 각자 만들기 (50분)
|
||||
|
||||
| 시간 | 단계 | 확인 |
|
||||
| --- | --- | --- |
|
||||
| 16:00~16:09 | 0 준비 · 1 요청서 → `Doc/TODO.md` (에이전트 없이) | 할 일 ①~⑫ · 꼭 / 나중 |
|
||||
| 16:09~16:15 | 2 `Doc/SPEC.md` → VIBE-Q 요구 표(R1~R14)와 비교 · commit | 요구마다 확인 방법 (직원 4/9 · 접수 건 2/9 · 줄마다 코드, 종료 코드) |
|
||||
| 16:15~16:20 | 3 `Doc/IMP-PLAN.md` (엔진 1~3단계 · TUI 1단계 · 설치) · commit | 단계마다 체크리스트 |
|
||||
| 16:20~16:44 | 4 구현: 엔진 1단계 → 엔진 2단계 → TUI 1단계, 막히면 5 문제 해결 팁 | 단계마다 `pytest` · 직접 실행 · commit |
|
||||
| 16:44~16:50 | 6 확인 · 7 `uv tool install --editable .` · 8 다른 폴더에서 `tcheck` | `tcheck check …/employees-new.json --url http://localhost:8800` = `my-check`의 판정 |
|
||||
|
||||
| 볼 것 | 막혔을 때 한마디 |
|
||||
| --- | --- |
|
||||
| TODO · SPEC 없이 VIBE-Q를 통째로 붙여 넣었나 | "요청서로 Doc/TODO.md부터. 직원 4/9가 SPEC에 없으면 맞았는지 모릅니다" |
|
||||
| IMP-PLAN이 한 덩어리 · 첫 요청에 14개 | "엔진 1단계만. 단계마다 확인 · 체크 · commit" |
|
||||
| 판정이 n8n과 다름 | "어느 줄 · 어느 코드가 다른지 붙여 주고, AGENTS.md 3절 스키마 표 그대로" |
|
||||
| 필드 이름이 코드에 (`if name == "email"`) | "스키마의 fields를 돌며 type마다" — 오늘 Lab 03 예제 3 |
|
||||
| `2026-02-30` · `2026-13-01`이 통과 | "실제 있는 날짜인지까지" |
|
||||
| 빈 전화번호가 `bad_format` | "선택 칸은 비었으면 형식을 보지 않음" |
|
||||
| 테스트가 진짜 API를 부름 | "가짜 서버(http.server)와 스키마 · n8n 결과 사본으로" |
|
||||
| `gate`가 늘 0 | "넘으면 거절, 거절이면 종료 코드 4, 같으면 통과" |
|
||||
| 실행해 보지 않고 다음 요청 | "에이전트가 됐다고 해도 직접 `uv run tcheck …; echo $?`" |
|
||||
|
||||
정답 예(R1~R14를 모두 넣은 `tcheck`와 정답본 `VIBE-A-TCHECK.md`)는 수업 뒤 공개됩니다.
|
||||
|
||||
## 2. 8교시 · 발표 (10분)
|
||||
|
||||
- 1~2명. **`tcheck check --json`과 `my-check`의 판정이 같다는 것을 보여 줄 수 있는 사람**, `tcheck gate`의 종료 코드 4를 보여 줄 수 있는 사람을 먼저 고릅니다.
|
||||
- 3분 발표 · 2분 질문: **내 SPEC과 VIBE-Q가 달랐던 곳** / IMP-PLAN을 어떻게 나눴나 / 처음 요청 · 고쳐 달라는 요청문 / 에이전트가 틀린 곳(판정이 달랐던 줄) / 시연.
|
||||
|
||||
## 3. 강사 정리 (8교시 4단계 정리 안에서)
|
||||
|
||||
| | n8n (오늘 Lab) | tcheck |
|
||||
| --- | --- | --- |
|
||||
| 읽기 | 웹훅 본문 (`items` · `csv`) | 파일: `.csv` · JSON 목록 · `{"items"}` · 요청 파일 (R1) |
|
||||
| 규칙 | `my-check`의 `Check rows` (스키마) | `checks.check` — 같은 타입 판정, 같은 코드 (R2 · R3 · R4) |
|
||||
| 내용 규칙 | `my-faq-check` (Lab 01) | `--content answer` (R8) |
|
||||
| 게이트 | `my-faq-import`의 `Batch ok?` (Lab 02) | `tcheck gate` · 종료 코드 4 (R7) |
|
||||
| 격리 | `/quarantine` | `--out` · `--rejects` (R6) |
|
||||
| 고침 목록 | Lab 01 과제 2 | `--fix` (R9) |
|
||||
| 품질 기록 | Lab 03 과제 2 | `--log` (R10) |
|
||||
|
||||
- 풀이 거리: 강사 본은 직원 HR-1 · 접수 건 TK-1 · FAQ B-3에서 `rows` · `codes` · `valid`가 `my-check`와 **하나도 다르지 않았습니다.** Python `re`의 `\w`는 한글도 맞아 메일 판정이 JavaScript와 다를 수 있었고(`re.ASCII`), 날짜를 꼴만 보면 2월 30일이 통과합니다. "같은 규칙을 두 곳에 쓰면 반드시 어긋난다 — 그래서 n8n 안에서는 검사를 다시 부르고, 밖에서는 테스트로 같은 판정을 확인한다."
|
||||
- 같은 FAQ B-1을 `tcheck --schema faq --content answer`로 보면 Lab 01 예제 2의 8줄과 같은 줄이 나쁩니다 — 코드 이름만 다릅니다 (`title_missing` ↔ `missing:title`).
|
||||
|
||||
## 4. 강사 바이브 코딩 (시간이 남으면 · 수업 뒤, 15분)
|
||||
|
||||
| 주제 | 요청문 요지 | 보여 줄 것 |
|
||||
| --- | --- | --- |
|
||||
| pre-commit 훅 | "저장소에 `faq/*.json`을 커밋할 때 `tcheck gate --schema faq --content answer`가 4면 커밋을 막는 pre-commit 훅" | 보내기 전 검사를 개발 흐름에 |
|
||||
| 스키마 버전 비교 | "`tcheck diff-schema old.json new.json`: 같은 파일로 두 스키마의 판정이 달라지는 줄" | 스키마 변경 = 규칙 변경, 리뷰 근거 |
|
||||
| 이미 있는 데이터 | "`--existing http://localhost:8800/faq-all`로 `exists_id` · `same_title`" | Lab 01 과제 1을 도구로 |
|
||||
|
||||
걸린 시간과 결과를 `Last3Mon/78/VIBE-A-TCHECK.md`에 적어 둡니다.
|
||||
|
||||
## 5. 보충 · 팁 (읽을거리, 4단계 정리 7절과 함께)
|
||||
|
||||
| 팁 | 설명 |
|
||||
| --- | --- |
|
||||
| 요청서 → 요구가 먼저 | 확인 방법(기대 판정 · 종료 코드 · JSON 칸)이 있는 요구가 있어야 에이전트의 "완료"를 판단할 수 있음 |
|
||||
| 기대 판정은 이미 있다 | 오늘 `cases/lab03.json` · `lab03-schema.json`의 판정을 SPEC과 테스트에 그대로 |
|
||||
| n8n의 답을 사본으로 | `call my-check`의 응답을 `tests/data/`에 두면 n8n 없이도 "같은가"를 시험 |
|
||||
| 규칙은 한 곳 | 판정 함수는 `checks.py`에만, JSON · 파일 · 게이트 · 화면은 부르기만 |
|
||||
| 필드 이름을 코드에 쓰지 않기 | 스키마가 늘어도 코드는 그대로 |
|
||||
| 정규식도 정의 | 다른 언어와 판정을 맞출 때는 `\w` · `\d`의 뜻까지 |
|
||||
| 종료 코드로 말한다 | 0 · 1 · 2 · 4 — 스크립트 · pre-commit · CI가 다음 일을 정함 |
|
||||
| 단계마다 `git commit` | 에이전트가 망가뜨려도 돌아갈 곳 |
|
||||
|
||||
## 6. 79일차 예고 (5분)
|
||||
|
||||
- 오늘: 들어오는 데이터를 규칙으로 검사하고 · 막고 · 격리하고 · 기록했습니다. 다음 수업(79일차, 11/4): **운영 데이터 기반 Workflow Ops Assistant 구현** — 77일차 실행 기록, 오늘의 품질 기록, 76일차 알림을 한데 모아, 운영자가 "지금 무엇이 문제야?"라고 물으면 숫자로 답하는 도우미를 만듭니다.
|
||||
- 바이브 코딩: 오늘 `tcheck`와 77일차 `tlog`는 지우지 마세요. 79일차 `tops`에서 씁니다.
|
||||
|
||||
## 확인 (강사)
|
||||
|
||||
- [ ] 16:00 요청서 → TODO(에이전트 없이) → SPEC → IMP-PLAN 20분을 지켰다, 16:20부터 엔진 1단계.
|
||||
- [ ] 7교시 시작 전 n8n에 `my-check`(Lab 03 예제 1 이상)가 게시돼 있어 판정 비교를 할 수 있다.
|
||||
- [ ] 수업 뒤: 요청이 있을 때 학생 저장소에 정답(LAB-A · `answers/` · VIBE-A · `tcheck/`)을 올린다.
|
||||
- [ ] 발표자 1~2명, 강사 정리 표, 팁, 예고.
|
||||
- [ ] 수업이 끝날 때 학생들의 데이터 API가 처음 상태인지 (`quality --reset`, `doctor`).
|
||||
@@ -0,0 +1,40 @@
|
||||
# 78일차 · 데이터 품질 검증 자동화와 품질 관리 Workflow (바이브 코딩)
|
||||
|
||||
- 일자: 2026-11-03 (78일차)
|
||||
- 교과목: 노코드 멀티 에이전트 워크플로우 설계 및 운영
|
||||
- 단원: AI 워크플로우 운영 및 관리 역량 강화
|
||||
- 학습 내용: 데이터 품질 검증 자동화 및 품질 관리 Workflow 적용
|
||||
- 실습 폴더: [Last3Mon/78](../../Last3Mon/78/README.md)
|
||||
- 실습 환경: 65일차 n8n 2.42.6 + OpenAI API(`gpt-4.1-mini`) + 78일차 데이터 API(격리함 · 스키마 · 품질 기록) + **CLI 코딩 에이전트**
|
||||
- **실습 준비: [00-DAY78-PREP.md](00-DAY78-PREP.md) (수업 전날까지 1~2절 완료)**
|
||||
|
||||
## 오늘의 시간표
|
||||
|
||||
| 교시 | 시간 | 내용 | 자료 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | 09:00~09:50 | 오늘의 개요 · 1단계 · 품질 규칙 | [개요](00-DAY78-OVERVIEW.md), [1단계](01-STAGE1-QUALITY-RULES.md) |
|
||||
| 2 | 10:00~10:50 | Lab 01 실습 5개 (눈으로 · 기준 검사, 검사 워크플로우, 경계, 이미 있는 데이터, 고침 목록) | [Lab 01](../../Last3Mon/78/LAB-01-Q-QUALITY-RULES.md) |
|
||||
| 3 | 11:00~11:50 | 2단계 · 품질 게이트 | [2단계](02-STAGE2-QUALITY-GATE.md) |
|
||||
| 4 | 12:00~12:50 | Lab 02 실습 5개 (배치 게이트 · 격리, LLM 검사, 기준을 바꾸면, 기록 · 알림, LLM 호출 수) | [Lab 02](../../Last3Mon/78/LAB-02-Q-QUALITY-GATE.md) |
|
||||
| - | 13:00~14:00 | 점심 | |
|
||||
| 5 | 14:00~14:50 | 3단계 · 품질 관리 | [3단계](03-STAGE3-QUALITY-MANAGEMENT.md) |
|
||||
| 6 | 15:00~15:50 | Lab 03 실습 5개 (스키마 검사, 고쳐서 다시, 새 스키마, 품질 보고서, 데이터셋별) | [Lab 03](../../Last3Mon/78/LAB-03-Q-QUALITY-MANAGEMENT.md) |
|
||||
| 7 | 16:00~16:50 | 바이브 코딩 · `tcheck` (요청서 → TODO → SPEC → IMP-PLAN → 만들기 → 설치) | [요청서](../../Last3Mon/78/VIBE-REQ-TCHECK.md), [VIBE-Q-TCHECK](../../Last3Mon/78/VIBE-Q-TCHECK.md), [진행](05-VIBE-CODING.md) |
|
||||
| 8 | 17:00~17:50 | 바이브 코딩 발표 · **4단계 정리** (의미 · 효과 · 실전 응용) · 79일차 예고 | [4단계 정리](04-STAGE4-WRAPUP.md), [진행](05-VIBE-CODING.md) |
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
P["개요"] --> S1["1단계<br/>품질 차원 · 규칙 · 코드 · 경계 · 이미 있는 데이터 · 고침 목록"] --> S2["2단계<br/>배치 게이트 · 격리 · LLM 검사 · 기준 · 기록 · 알림"] --> S3["3단계<br/>스키마 · 되돌림 · 새 스키마 · 보고서 · 데이터셋별"] --> V["7·8교시<br/>tcheck · 4단계 정리"]
|
||||
```
|
||||
|
||||
## 자료 목록
|
||||
|
||||
| 파일 | 내용 |
|
||||
| --- | --- |
|
||||
| `00-DAY78-PREP.md` | 실습 준비: n8n · 78일차 판 데이터 API 켜기, 기준 둘 게시, `flow.py quality` · `doctor` (수업 전) |
|
||||
| `00-DAY78-OVERVIEW.md` | 개요 30장 (PPT 대신 Markdown, 가로줄로 장 구분, 장마다 생활 속 예) |
|
||||
| `01-STAGE1-QUALITY-RULES.md` | 데이터 품질의 차원, 규칙은 말이 먼저, 오류 코드, 규칙은 Code가, 경계, 이미 있는 데이터 · 오류와 경고, 고침 목록 · 데이터 계약 |
|
||||
| `02-STAGE2-QUALITY-GATE.md` | 검사와 게이트, 배치 · 줄 게이트 · 격리함, LLM 검사(통과한 줄만 · fail-closed), 기준은 고르는 값, 기록 · 알림, LLM 호출 수 · 늘 같은가 |
|
||||
| `03-STAGE3-QUALITY-MANAGEMENT.md` | 스키마, 스키마로 되는 것 · 안 되는 것, 되돌림 고리, 설정으로 넓히기, 품질 보고서의 정의, 데이터셋별, 식당 주방으로 본 하루 |
|
||||
| `04-STAGE4-WRAPUP.md` | 8교시 4단계 정리 35분: 의미 · 효과 · 업계 이름 · 산업별 응용 · 데이터 계약서 · 면접 · 최종 프로젝트 체크리스트 |
|
||||
| `05-VIBE-CODING.md` | 7·8교시 바이브 코딩 진행 (`tcheck`), 발표, 강사 정리, 추가 바이브 코딩, 팁 |
|
||||
Reference in new issue
Block a user