68일차 교안·실습(복합 업무 시나리오 · Multi-Agent 라우터) 추가, 결석 수강생용 최소 준비 문서 포함

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mcchaeandClaude Opus 5.5 committed 2026-10-19 22:05:32 +09:00
1 parent a57360d4d9
commit 587ca5c2b3
42 files changed
+5481

No files matched your search

+208
View File
@@ -0,0 +1,208 @@
# 68일차 개요 · 복합 업무 시나리오와 Multi-Agent 워크플로우
> 운영·확장 관점의 AI 워크플로우 설계 고도화 · 2026-10-20
> 13장 · 각 장은 가로줄(`---`)로 나뉩니다. 1교시에는 1~5장을 보고, 나머지 장은 각 단계를 설명할 때 함께 띄웁니다.
| 장 | 범위 |
| --- | --- |
| 1~5 | 표지 · 목표 · 시간표 · 새 단원 · 오늘의 그림 |
| 6~7 | 1단계 · 복합 업무 시나리오 분석 |
| 8~9 | 2단계 · Multi-Agent 워크플로우 설계 |
| 10~11 | 3단계 · 장애 격리와 확장 |
| 12~13 | 7교시 바이브 코딩 · 정리와 예고 |
---
## 1 / 13 · 표지
```mermaid
flowchart LR
R["복합<br/>요청"] --> S["나누기"]
S --> I["IT<br/>Agent"] & M["회의록<br/>Agent"]
I & M --> O["통합<br/>응답"]
classDef g fill:#8A9BA0,stroke:#8A9BA0,color:#fff
classDef o fill:#F2A541,stroke:#F2A541,color:#fff
classDef t fill:#0F7C80,stroke:#0F7C80,color:#fff
classDef d fill:#0F3D3E,stroke:#0F3D3E,color:#fff
class R g
class S o
class I,M t
class O d
```
**68일차**
# 복합 업무 시나리오와 Multi-Agent 워크플로우
업무 분석 · 업무 나누기 · Agent에게 분배 · 결과 통합 · 장애 격리
<sub>운영·확장 관점의 AI 워크플로우 설계 고도화 · 2026-10-20</sub>
---
## 2 / 13 · 오늘 할 수 있게 될 세 가지
| | 오늘 할 수 있게 될 것 |
| :-: | --- |
| **①** | 요청 하나에 섞인 업무를 **분석표**로 나누고, 그대로 나누는 워크플로우를 요청문으로 만든다 |
| **②** | 이미 만든 Agent의 **계약**을 정리하고, 그 Agent들을 부르는 **라우터**를 만든다. Supervisor와 비교한다 |
| **③** | Agent 하나가 꺼지거나 입력이 빠져도 **나머지 답은 나오게** 만들고, 측정값으로 확장 계획을 쓴다 |
---
## 3 / 13 · 오늘의 시간표
| ① 1~2교시 | ② 3~4교시 | ③ 5~6교시 | ④ 7~8교시 |
| --- | --- | --- | --- |
| **1단계** | **2단계** | **3단계** | **바이브 코딩** |
| 복합 업무 시나리오 분석 | Multi-Agent 설계 | 검증 · 장애 격리 · 확장 | `tflow` |
| Lab 01 분석표 · 나누기 | Lab 02 라우터 · Supervisor | Lab 03 빠진 입력 · 꺼진 Agent | 만들기 · 발표 · 정리 |
> 09:00 시작 · 50분 수업 10분 휴식 · 4교시 뒤 13:00~14:00 점심
---
## 4 / 13 · 새 단원: 하나의 Agent에서 여러 Agent로
```mermaid
flowchart LR
D66["66 · 회의록<br/>→ 할 일"] --> D67["67 · IT 문의<br/>Agent"] --> D68["68 · 둘을 묶는<br/>라우터"] --> D69["69 · 역할 분리<br/>협업"] --> D70["70 · 템플릿<br/>재사용"]
classDef t fill:#0F7C80,stroke:#0F7C80,color:#fff
classDef g fill:#8A9BA0,stroke:#8A9BA0,color:#fff
class D68 t
class D66,D67,D69,D70 g
```
- 66·67일차에 만든 것이 오늘은 **부품**(`agents/`)이 됩니다. 오늘 만드는 것은 그 부품을 묶는 쪽입니다.
- 방식은 67일차와 같습니다: 요청문은 내가, JSON은 에이전트가, push·test는 내가.
---
## 5 / 13 · 오늘의 그림
```mermaid
flowchart LR
W(["요청<br/>message · user · notes"]) --> S{{"Split tasks"}} --> SW{"Route by type"}
SW -->|it| IT{{"IT 문의 Agent"}}
SW -->|meeting| MT{{"회의록 Agent"}}
SW -->|other| O["담당자 연결"]
SW -->|needs input| N["입력 필요"]
IT & MT & O & N --> M["Collect · Build reply"] --> R(["count · results · reply"])
```
> 이 그림을 Lab 01(나누기) → Lab 02(분배·통합) → Lab 03(입력 필요·장애 격리) 순서로 완성합니다.
---
## 6 / 13 · 1단계 · 업무 분석 다섯 칸
> "T-1002 처리 상태 알려주고, 첨부한 회의록에서 할 일도 정리해줘. 그리고 프린터 출력이 안 돼요."
| 업무 | 유형 | 필요한 입력 | 요청에 있나 | 관계 |
| --- | --- | --- | --- | --- |
| T-1002 처리 상태 | it | 접수 번호, 요청한 사람 | 문장 + `user` | 독립 |
| 회의록 할 일 정리 | meeting | 회의록 원문 | `notes` | 독립 |
| 프린터 출력 안 됨 | it | 증상 | 문장 | 독립 |
> 필요한 입력은 **문장 밖**에도 있습니다. 나누기는 LLM이, 빠진 입력 확인은 규칙이.
---
## 7 / 13 · 1단계 · LLM이 할 일, 규칙이 할 일
| 일 | 누가 | 이유 |
| --- | --- | --- |
| 문장을 업무로 나누기, 유형 고르기 | LLM | 말의 뜻을 알아야 함 |
| 유형 → 담당 Agent | 규칙 (표) | 늘 같은 답이어야 함 |
| 필요한 입력이 있나 | 규칙 (빈 칸 확인) | 짐작하면 안 됨 |
수업 준비 때 정답 워크플로우: 나누기 `lab01` 7/7, 규칙을 더한 과제 `lab01-challenge` 0/4 → 4/4.
---
## 8 / 13 · 2단계 · Agent를 묶는 네 가지 모양
```mermaid
flowchart LR
subgraph 라우터
a1["나누기"] --> a2["A"] & a3["B"]
end
subgraph 파이프라인
b1["A"] --> b2["B"] --> b3["C"]
end
subgraph Supervisor
c1{{"LLM"}} -.-> c2["A"] & c3["B"]
end
```
| 모양 | 언제 | 오늘 |
| --- | --- | --- |
| 라우터 | 업무가 서로 **독립** | Lab 02 예제 2 |
| 파이프라인 | 앞 결과가 뒤에 필요 | 69일차 |
| Fork-Join | 같은 입력을 여럿이 동시에 보고 합침 | 69일차 |
| Supervisor | 요청이 열려 있고 LLM이 고르게 | Lab 02 과제 |
---
## 9 / 13 · 2단계 · 라우터 vs Supervisor (수업 준비 측정)
| | 라우터 | Supervisor |
| --- | --- | --- |
| 누가 Agent를 고르나 | 유형 표 (코드) | LLM (Tool 설명·지시문) |
| 복합 요청 (업무 3개) | 4.5~6.6초 | 9.6~10.8초 |
| 결과 | 업무별 `results[]` (계약) | 답 글자 하나 |
| 라우터 테스트(`lab02`)를 그대로 | 6/6 | 1/6 |
| 흔들린 곳 | — | 지시문 낱말 하나로 4/5 ↔ 5/5 |
> 정해진 업무는 라우터, 열린 요청은 Supervisor. **계약이 있으면 둘을 같은 테스트로 비교**할 수 있습니다.
---
## 10 / 13 · 3단계 · 하나가 꺼지면 전체가 멈춘다
| 회의록 Agent 꺼짐 · 복합 요청 | 결과 |
| --- | --- |
| 고치기 전 (Lab 02 예제 라우터) | **HTTP 500** · T-1002 답까지 사라짐 (`lab03-down` 1/3) |
| `neverError` + 빈 결과는 담당자 연결 | 200 · IT 둘은 자동 답변, 회의록만 담당자 연결 (3/3) |
> 회의록 없이 온 회의 요청도 같은 문제(Agent가 400 → 전체 500). **부르기 전에 막거나, 받은 오류를 결과로 바꾸거나.**
---
## 11 / 13 · 3단계 · 측정으로 확장 계획
| 수업 준비 측정 (1회) | 시간 |
| --- | --- |
| 기타만 (LLM 나누기 한 번) | 0.9~1.0초 |
| IT 하나 | 2.3~2.6초 |
| 회의록 하나 | 3.5초 |
| 복합 요청 (업무 3개) | 4.5~6.6초 |
- 요청 하나가 Agent 실행 여러 개를 만든다 → 21명 동시면 n8n 실행 수는 몇 배?
- 시간 대부분은 LLM API 대기 → 더 큰 서버(수직)보다 작업자 여럿(수평)·속도 제한 관리가 먼저.
---
## 12 / 13 · 7교시 · 바이브 코딩 `tflow`
```text
$ tflow agents/it-agent.json
▼ IT question webhook [webhook POST /it-agent]
▼ Has question? [if]
├ true ▼ Has user? [if] ...
```
- 에이전트가 만든 n8n JSON을 **트리 · mermaid · 한국어 설명**으로 확인하는 TUI
- 오늘 만든 `my-work/assistant.json`을 열어 내 설계(`DESIGN.md`)와 같은지 봅니다.
---
## 13 / 13 · 정리와 69일차 예고
| 오늘 | 한 줄 |
| --- | --- |
| 1단계 | 업무 분석이 먼저, 나누기는 LLM, 담당·빠진 입력은 규칙 |
| 2단계 | Agent는 계약으로 묶는다. 라우터와 Supervisor는 같은 테스트로 비교 |
| 3단계 | 하나가 꺼져도 나머지는 답한다. 확장은 측정값으로 |
- 69일차: **역할 기반 Agent 분리** (작성자 → 검토자 → 정리자) · 바이브 코딩 `tcrew`
+108
View File
@@ -0,0 +1,108 @@
# 68일차 실습 준비 · 수업 전에 미리 해 두면 좋은 것
- 수업일: 2026-10-20 (68일차) · 복합 업무 시나리오 분석과 Multi-Agent 기반 워크플로우 설계
- 준비 시간: 약 15분 (67일차 준비를 했다면 1·3절만)
- 먼저 WSL에서 `cd ~/aio-01d4-stu && git pull`로 오늘 자료를 받습니다 (수강생 저장소: https://gl.isitsoft.kr/publicproj/aio-01d4-stu).
- **수업 전날까지** 1~3절을 끝내 주세요.
- 65~67일차를 하지 못해 n8n · Credential · 데이터 API가 없다면 [PREPARE-68-FROM-65.md](../../Last3Mon/68/PREPARE-68-FROM-65.md)를 따라 하면 최소 명령으로 `ready`까지 갑니다.
```mermaid
flowchart LR
A["1. n8n · 데이터 API 켜기"] --> B["2. 두 Agent 게시"] --> C["3. doctor<br/>ready"] --> D["4. 미리 읽기"]
```
---
## 1. n8n과 데이터 API 켜기 (전날 필수, 3분)
67일차와 같습니다. n8n은 65일차 설치(`~/day65-n8n`)를 `Last3Mon/65/n8n`에서 켜고, 데이터 API는 67일차 폴더의 것을 그대로 씁니다.
```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/67/data-api
docker compose up -d
curl -s localhost:8800/health # {"status": "ok"}
```
- **66일차부터 LLM은 OpenAI API 키(`Last3Mon/.env`, Credential `OpenAI (.env)`)만 씁니다.** Ollama는 쓰지 않으므로 위처럼 꺼서 메모리를 아낍니다. 다음 날부터는 같은 명령을 그대로 써도 됩니다.
- `network day65-n8n_default not found` → n8n이 켜져 있지 않음. 위 n8n 부분부터 다시.
- `.../day65-n8n/compose.yml: no such file or directory` → 홈이 아닌 곳에 설치함. `Last3Mon/65/n8n/.env`에 `N8N_HOME=<설치 폴더>` ([67일차 준비](../67/00-DAY67-PREP.md) 1절).
## 2. 오늘 부를 Agent 두 개 게시 (전날 필수, 2분)
오늘 라우터가 부르는 Agent입니다. 만들지 않고 **게시만** 합니다.
| Agent | 파일 | 웹훅 |
| --- | --- | --- |
| IT 문의 (67일차 Lab 03 완성본) | `agents/it-agent.json` | `/webhook/it-agent` |
| 회의록 (66일차 회의록 → 할 일) | `agents/meeting-agent.json` | `/webhook/meeting-agent` |
```bash
cd ~/aio-01d4-stu/Last3Mon/68
uv run tools/flow.py push agents/it-agent.json agents/meeting-agent.json # 수업 준비 때 약 19초
uv run tools/flow.py call it-agent requests/agent-it.json # route 자동 답변, T-1002 처리 중
uv run tools/flow.py call meeting-agent requests/agent-meeting.json # count 4
```
같은 경로를 쓰던 예전 워크플로우가 있으면 `push`가 게시를 해제하고 `! unpublished ...`로 알려 줍니다 (정상).
## 3. 준비 확인 (전날 필수, 2분)
```bash
cd ~/aio-01d4-stu/Last3Mon/68
uv run tools/flow.py doctor
```
```text
✔ n8n install folder /home/<사용자>/day65-n8n
✔ n8n container day65-n8n-n8n-1
✔ n8n http://localhost:5678
✔ data API http://localhost:8800
✔ n8n → http://data-api:8800
✔ credential 'OpenAI (.env)' (openAiCourse0001)
✔ node catalog (for check)
✔ agent webhook /it-agent
✔ agent webhook /meeting-agent
✔ CLI coding agent: codex, claude
ready
```
| ✘ 항목 | 할 일 |
| --- | --- |
| n8n container · data API | 1절 |
| credential | `cd ~/aio-01d4-stu/Last3Mon/65/n8n && bash register-credentials.sh` |
| agent webhook | 2절 `push` |
| CLI coding agent | [67일차 준비](../67/00-DAY67-PREP.md) 2절 (설치·로그인) |
---
## 4. 미리 읽어 오면 좋은 내용 (선택, 약 5분)
### 4.1 요청 하나에 업무가 여럿
> "T-1002 처리 상태 알려주고, 첨부한 회의록에서 할 일도 정리해줘. 그리고 프린터 출력이 안 돼요."
이 문장에 업무가 몇 개인지, 각각 누가(어느 Agent가) 맡으면 좋을지 생각해 옵니다.
### 4.2 용어
| 용어 | 한 줄 설명 |
| --- | --- |
| Multi-Agent | 일을 나눠 맡은 Agent 여럿이 함께 하나의 업무를 처리 |
| 라우터 | 요청을 보고 담당 Agent에게 **보내 주는** 정해진 흐름 |
| Supervisor | LLM 하나가 필요한 Agent를 **골라 부르는** 방식 |
| 계약 | Agent의 입력·결과 모양 약속. 계약을 지키면 Agent 속은 바꿔도 됨 |
## 5. 당일 준비물
- 충전된 노트북과 충전기, WSL의 Docker, Windows Terminal(WSL) 창 **두 개**, 웹 브라우저
- 67일차 `my-work/it-agent.json` (지우지 마세요, 7교시 `tflow` 연습에 씀)
## 확인
- [ ] `curl -s localhost:8800/health` → `{"status": "ok"}`
- [ ] `call it-agent`, `call meeting-agent` 응답을 받았다
- [ ] `uv run tools/flow.py doctor` → 마지막 줄 `ready`
+106
View File
@@ -0,0 +1,106 @@
# 1단계 · 복합 업무 시나리오 분석
- 교시: 1~2교시 (09:00~10:50)
- 실습: [Lab 01](../../Last3Mon/68/LAB-01-Q-SCENARIO-AND-SPLIT.md)
- 이 단계가 끝나면: 요청 하나에 섞인 업무를 **분석표**로 나눌 수 있다. 업무 나누기에서 **LLM이 할 일과 규칙이 할 일**을 구분해 요청문에 적을 수 있다.
```mermaid
flowchart LR
A["1. 요청 하나,<br/>업무 여럿"] --> B["2. 분석 다섯 칸"] --> C["3. 업무 관계"] --> D["4. 나누기는 LLM,<br/>판단은 규칙"] --> E["5. 분석표를<br/>요청문으로"]
```
## 1. 요청 하나에 업무가 여럿
67일차 IT 문의 Agent는 질문 하나에 답 하나를 했습니다. 실제 직원 요청은 이렇게 옵니다.
> "T-1002 처리 상태 알려주고, 첨부한 회의록에서 할 일도 정리해줘. 그리고 프린터 출력이 안 돼요."
이 요청을 67일차 IT 문의 Agent에 그대로 보내면 회의록 정리는 할 수 없습니다 (그 Agent에는 회의록 Tool이 없음). Agent 하나에 Tool을 계속 붙이는 대신, **업무를 나눠 맡은 Agent 여럿**이 일하게 하는 것이 오늘의 주제입니다.
| Agent 하나에 다 붙이기 | 업무별 Agent로 나누기 |
| --- | --- |
| 지시문이 계속 길어지고 서로 부딪힘 | Agent마다 짧은 지시문, 자기 Tool만 |
| 하나를 고치면 전부 다시 테스트 | 고친 Agent만 테스트 (계약이 그대로면) |
| 하나가 느리면 전부 느림 | 느린 Agent만 따로 늘리거나 끌 수 있음 (3단계) |
## 2. 업무 분석 다섯 칸
요청을 받으면 에이전트에게 맡기기 전에 **사람이 먼저** 표를 채웁니다. 이 표가 곧 요청문과 테스트의 재료입니다.
| 칸 | 묻는 것 | 위 요청에서 |
| --- | --- | --- |
| 업무 | 한 번에 처리할 수 있는 단위는? | ① T-1002 상태 ② 회의록 할 일 ③ 프린터 |
| 유형 | 지금 있는 Agent 중 누구 일인가? | it · meeting · it |
| 필요한 입력 | 처리하려면 무엇이 있어야 하나? | ① 번호 + **요청한 사람** ② **회의록 원문** ③ 증상 |
| 요청에 있나 | 문장 안? 본문의 다른 칸? 없음? | ① `user` ② `notes` ③ 문장 |
| 관계 | 다른 업무의 결과가 필요한가? | 셋 다 독립 |
- **업무 수는 접속사 수가 아닙니다.** "비밀번호를 잊어버렸어요. 그리고 메일함 용량이 꽉 찼대요"는 같은 IT Agent지만 업무 둘입니다.
- **필요한 입력은 문장 밖에도 있습니다.** 회의록 원문은 문장에 없고 요청 본문의 `notes` 칸에 붙어 옵니다. 없으면 회의록 Agent를 불러도 소용이 없습니다.
- **맡을 Agent가 없는 업무**(회식 장소 추천)는 `other`로 두고 사람에게 넘깁니다. 억지로 다른 Agent에게 보내지 않습니다.
## 3. 업무 관계: 독립인가, 순서가 있나
```mermaid
flowchart LR
subgraph 독립["독립 (오늘)"]
a["T-1002 상태"]
b["회의록 할 일"]
c["프린터"]
end
subgraph 순서["순서 있음 (69일차)"]
d["보고서 초안"] --> e["검토"] --> f["정리"]
end
```
| 관계 | 처리 | 모양 |
| --- | --- | --- |
| 독립 | 따로 처리해 마지막에 모음 | 라우터 (2단계) |
| 순서 | 앞 결과를 뒤에 넘김 | 파이프라인 (69일차) |
오늘 Lab의 요청은 모두 독립입니다. 내 업무 시나리오(64일차 Lab 03)에서 순서가 있는 업무가 있는지도 표에 적어 둡니다.
## 4. 나누기는 LLM, 판단은 규칙
업무 나누기 워크플로우에서 할 일을 둘로 나눕니다.
| 일 | 누가 | 왜 |
| --- | --- | --- |
| 문장을 업무로 나누고 유형 고르기 | LLM (AI Agent, Tool 없음) | 문장의 뜻을 알아야 함 |
| LLM 답을 JSON으로 읽고, 이상한 값 고치기 | Code | LLM은 앞뒤에 다른 글자를 붙이거나 없는 유형을 쓰기도 함 |
| 유형 → 담당 Agent | Code (표) | 늘 같은 답 |
| 필요한 입력이 있나 | Code (본문 빈 칸 확인) | 짐작하면 안 됨. 테스트로 확인할 수 있어야 함 |
수업 준비 때 정답 워크플로우의 결과 (1회, gpt-4.1-mini):
| 워크플로우 | `cases/lab01.json` | `cases/lab01-challenge.json` |
| --- | --- | --- |
| 나누기만 (예제 2) | 7/7 (0.9~3.2초) | 0/4 (담당·빠진 입력 칸 없음) |
| 규칙을 Code에 더함 (과제) | 7/7 | 4/4 |
> 67일차의 "LLM이 정하면 안 되는 값"(요청한 사람)과 같은 생각입니다. **매번 같아야 하는 것은 규칙으로.**
## 5. 분석표를 요청문으로
67일차 요청문 다섯 가지(① 파일 ② 입력 ③ 처리 ④ 결과 모양 ⑤ 기대 결과)는 그대로입니다. 오늘은 ③ 처리에 **분석표의 기준**이 들어갑니다. Lab과 다른 업무(총무 요청)로 예를 듭니다.
```text
my-work/office.json 에 n8n 워크플로우를 만들어 줘.
① 파일: my-work/office.json
② 입력: POST 웹훅 my-office, 본문 message(요청 문장), room(회의실 이름, 없을 수 있음)
③ 처리: AI Agent(Tool 없음)가 문장을 업무로 나눈다. 유형은 reserve(회의실 예약), parcel(택배 문의), other.
업무 하나 = 한 번에 처리할 수 있는 요청 하나. 날짜·시간은 쓴 그대로 남긴다.
Code에서 결과를 읽고, reserve 인데 본문 room 이 비었으면 missing ["room"].
④ 결과: {"count": 2, "tasks": [{"type": "reserve", "text": "...", "missing": []}]}
⑤ 기대 결과: cases/office.json (케이스 4개)
```
- 유형마다 **정의**(무엇이 여기에 드는지)를 적었습니다. 정의가 없으면 "회의실이 추워요"가 reserve인지 other인지를 LLM이 그때그때 정하게 됩니다.
- 규칙 부분은 "Code에서"라고 **어디서 할지**까지 적었습니다.
- Lab 01에서는 이 모양을 보고 **IT 문의 · 회의록** 요청문을 직접 씁니다.
## 정리
- [ ] 업무 분석 다섯 칸: 업무 · 유형 · 필요한 입력 · 요청에 있나 · 관계
- [ ] 필요한 입력은 문장 밖(본문의 다른 칸)에도 있다
- [ ] 나누기와 유형은 LLM, 담당과 빠진 입력은 규칙
+133
View File
@@ -0,0 +1,133 @@
# 2단계 · Multi-Agent 워크플로우 설계
- 교시: 3~4교시 (11:00~12:50)
- 실습: [Lab 02](../../Last3Mon/68/LAB-02-Q-ROUTER-AGENTS.md)
- 이 단계가 끝나면: Agent의 **계약**을 정리하고, 업무를 유형별로 담당 Agent에게 보내 결과를 모으는 **라우터**를 요청문으로 만들 수 있다. 라우터와 **Supervisor**의 차이를 측정값으로 설명할 수 있다.
```mermaid
flowchart LR
A["1. 계약이 있는<br/>Agent"] --> B["2. 네 가지 모양"] --> C["3. Agent를 부르는 법"] --> D["4. 라우터 구현"] --> E["5. Supervisor와<br/>비교"]
```
## 1. 계약이 있는 Agent
Agent를 여럿 묶으려면 각 Agent가 **무엇을 받고 무엇을 돌려주는지**가 정해져 있어야 합니다. 이것이 계약입니다.
| Agent | 웹훅 | 입력 | 결과 | 실패할 때 |
| --- | --- | --- | --- | --- |
| IT 문의 (67일차) | `/webhook/it-agent` | `question`, `user` 필수 | `route`, `answer`, `tools_used`, `sources` | 입력 없음 400 · 근거 없음·남의 접수 건 `route: 담당자 연결` |
| 회의록 (66일차) | `/webhook/meeting-agent` | `title`, `notes`(필수) | `route`, `count`, `summary`, `actions[]` | `notes` 없음 400 |
- 라우터는 Agent의 **속**(지시문, Tool)을 모릅니다. 계약만 압니다. 그래서 IT 문의 Agent의 지시문을 고쳐도 계약이 그대로면 라우터는 그대로입니다.
- 계약에서 가장 빠뜨리기 쉬운 칸이 **실패할 때**입니다. 3단계에서 이 칸 때문에 전체가 멈추는 것을 봅니다.
- 계약 표는 에이전트에게 **Agent 파일을 읽혀** 만들게 할 수 있습니다 (Lab 02 예제 1). 그 표를 `call` 결과와 대조하는 것은 사람의 일입니다.
수업 준비 때 직접 부른 결과: IT 문의 4.8초 (`Get_ticket`, "처리 중"), 회의록 2.3초 (할 일 4개), `notes` 없이 400 `{"error": "notes are required"}`.
## 2. Agent를 묶는 네 가지 모양
```mermaid
flowchart TB
subgraph R["라우터"]
r0["나누기"] --> r1["A"] & r2["B"] --> r3["모으기"]
end
subgraph P["파이프라인"]
p1["A"] --> p2["B"] --> p3["C"]
end
subgraph F["Fork-Join"]
f0["같은 입력"] --> f1["A"] & f2["B"] --> f3["합치기"]
end
subgraph S["Supervisor"]
s0{{"LLM"}} -.->|Tool| s1["A"]
s0 -.->|Tool| s2["B"]
end
```
| 모양 | 누가 다음을 정하나 | 어울리는 업무 | 이 과정에서 |
| --- | --- | --- | --- |
| 라우터 | 정해진 규칙 (Switch) | 업무가 독립이고 종류가 정해짐 | 오늘 Lab 02 |
| 파이프라인 | 정해진 순서 | 앞 결과가 뒤에 필요 (초안 → 검토) | 69일차 |
| Fork-Join | 정해진 흐름 | 같은 입력을 여러 관점으로 보고 합침 | 69일차 |
| Supervisor | LLM | 요청이 열려 있고 무엇이 필요한지 미리 모름 | 오늘 Lab 02 과제 |
## 3. n8n에서 다른 Agent를 부르는 법
| 방법 | 어떻게 | 오늘 |
| --- | --- | --- |
| HTTP Request로 웹훅 부르기 | 게시된 Agent의 웹훅에 POST | **라우터** (계약을 HTTP로 확인하기 쉬움) |
| HTTP Request **Tool**로 붙이기 | Agent가 Tool로 골라 부름 | **Supervisor** |
| Execute Workflow | 같은 n8n 안의 워크플로우를 직접 실행 | 70일차 (모듈화) |
n8n 안에서 같은 n8n의 웹훅을 부를 때 주소는 `http://localhost:5678/webhook/<path>`입니다 (같은 컨테이너 안). 데이터 API(`http://data-api:8800`)와 다릅니다. [AGENTS.md](../../Last3Mon/68/AGENTS.md) 2절에 적어 두었습니다.
넘기는 값의 **출처**를 정합니다 (67일차 2단계와 같은 질문).
| 값 | 출처 | 이유 |
| --- | --- | --- |
| IT 질문 문장 | 나누기 결과 `text` | LLM이 나눈 조각 |
| 요청한 사람 `user` | 웹훅 본문 그대로 | LLM이 바꾸면 남의 접수 건이 보일 수 있음 |
| 회의록 원문 `notes` | 웹훅 본문 그대로 | LLM이 다시 쓰면 내용이 줄거나 바뀔 수 있음 |
## 4. 라우터 구현
```mermaid
flowchart LR
W(["Assistant webhook"]) --> H{"Has message?"} --> S{{"Split tasks"}} --> P["Parse tasks"] --> O["One item per task"] --> SW{"Route by type"}
SW -->|it| CI["Call IT agent"] --> RI["IT result"]
SW -->|meeting| CM["Call meeting agent"] --> RM["Meeting result"]
SW -->|other| RO["Other result"]
RI & RM & RO --> M["Collect results<br/>(Merge)"] --> A["All results<br/>(Aggregate)"] --> B["Build reply"] --> R(["Send result"])
```
| 노드 | 하는 일 | 놓치기 쉬운 것 |
| --- | --- | --- |
| One item per task (Code) | 업무 하나당 항목 하나, `index` 붙이기 | 다음 노드는 **항목마다** 실행됨 |
| Route by type (Switch) | 유형별 출력 | 출력 순서 = 연결의 칸 순서 |
| Call … agent (HTTP Request) | Agent 웹훅에 POST | 본문 값의 출처 (3절) |
| … result (Set) | Agent마다 다른 결과를 **같은 모양**으로 | 회의록은 `summary`·`actions` → `answer` |
| Collect results (Merge) · All results (Aggregate) | 갈래를 모아 `results` 배열 하나로 | 데이터가 안 온 갈래가 있어도 동작 |
| Build reply (Code) | `index` 순으로 정렬해 `reply` | 업무 순서 = 요청 순서 |
수업 준비 때 정답 라우터 (`reference/lab02-example2-router.json`, 1회):
| 케이스 | 결과 · 시간 |
| --- | --- |
| `cases/lab02.json` 전체 | 6/6 |
| 복합 요청 (업무 3개) | 6.6초 |
| IT 하나 · 회의록 하나 | 2.6초 · 3.5초 |
| 기타만 (Agent를 부르지 않음) | 0.9초 |
n8n **Executions**를 열면 `my-assistant` 실행 하나에 `it-agent`, `meeting-agent` 실행이 **따로** 생깁니다. Agent마다 실행 기록이 남으니 어느 Agent에서 문제가 났는지 찾기 쉽습니다.
## 5. Supervisor와 비교
같은 요청을 LLM 하나(Supervisor)가 두 Agent를 Tool로 골라 부르게 만들 수 있습니다.
```mermaid
flowchart LR
W(["Assistant webhook"]) --> SV{{"Supervisor agent"}} --> B["Build reply<br/>agents_used"] --> R(["Send result"])
M["OpenAI chat model"] -.-> SV
T1["Ask IT agent"] -.-> SV
T2["Ask meeting agent"] -.-> SV
```
수업 준비 때 정답 두 개를 같은 요청으로 비교했습니다 (gpt-4.1-mini, 측정값).
| | 라우터 | Supervisor |
| --- | --- | --- |
| 누가 Agent를 고르나 | 유형 표 (코드) | LLM (Tool 설명·지시문) |
| 복합 요청 시간 | 4.5~6.6초 | 9.6~10.8초 |
| 결과 | 업무별 `results[]` | 답 글자 하나 + `agents_used` |
| 라우터 테스트 `lab02.json`을 그대로 | 6/6 | 1/6 (빈 요청만, 계약이 다름) |
| 자기 테스트 `lab02-challenge.json` | — | 처음 4/5 → 지시문 고친 뒤 5/5 |
| Agent 하나 더 | Switch 갈래 + 결과 Set | Tool 하나 + 지시문 한 줄 |
- Supervisor가 처음 실패한 이유: 기타 요청에 "**담당 직원**이 도와드릴 예정입니다"라고 답해 테스트의 `담당자`가 없었습니다. 지시문에 정확한 문장을 주자 통과했습니다. **Supervisor는 지시문이 곧 분배 규칙**입니다.
- 결론은 "어느 쪽이 낫다"가 아니라 **계약이 있으면 같은 테스트로 비교할 수 있다**는 것입니다. 업무 종류가 정해져 있고 결과를 다른 시스템이 다시 쓰면 라우터, 요청이 열려 있고 사람에게 바로 답하면 Supervisor.
## 정리
- [ ] Agent는 계약(입력 · 결과 · 실패할 때)으로 묶는다
- [ ] 라우터: 나누기 → 항목마다 → Switch → HTTP → 같은 모양 → Merge·Aggregate → 답
- [ ] LLM이 정하면 안 되는 값(`user`, `notes`)은 웹훅 본문에서 그대로
- [ ] 라우터와 Supervisor는 시간·안정성·결과 모양이 다르고, 계약이 있어야 비교할 수 있다
+115
View File
@@ -0,0 +1,115 @@
# 3단계 · 검증과 장애 격리, 확장 고려
- 교시: 5~6교시 (14:00~15:50)
- 실습: [Lab 03](../../Last3Mon/68/LAB-03-Q-VERIFY-AND-ISOLATE.md)
- 이 단계가 끝나면: Multi-Agent 워크플로우에서 **한 곳의 문제가 전체 답을 망치지 않게** 만들 수 있다. 측정값으로 확장 계획(수직·수평)을 설명할 수 있다.
```mermaid
flowchart LR
A["1. Multi-Agent는<br/>어디서 깨지나"] --> B["2. 빠진 입력"] --> C["3. 꺼진 Agent"] --> D["4. 어려운 테스트"] --> E["5. 측정과 확장"]
```
## 1. Multi-Agent는 어디서 깨지나
Agent가 하나일 때보다 깨지는 곳이 늘어납니다.
| 깨지는 곳 | 예 | 테스트 |
| --- | --- | --- |
| 나누기 | 업무 수가 틀림, 유형이 틀림 | `lab01` |
| 넘기는 값 | 필요한 입력이 없음 (`notes`, `user`) | `lab03` · 과제 |
| 부른 Agent | 꺼짐(404), 오류(400·500), 느림 | `lab03-down` |
| 모으기 | 결과 모양이 다름, 순서가 섞임 | `lab02` |
| Agent 규칙 | 라우터를 거치면서 67일차 규칙(남의 접수 건)이 깨짐 | 과제 |
## 2. 빠진 입력: 부르기 전에 막는다
Lab 02 예제 라우터에 회의록 없이 회의 요청을 보내면:
```mermaid
sequenceDiagram
participant 직원
participant 라우터 as my-assistant
participant 회의록 as meeting-agent
직원->>라우터: "회의록 할 일 정리 부탁해요" (notes 없음)
라우터->>회의록: POST {notes: ""}
회의록-->>라우터: 400 notes are required
Note over 라우터: Call meeting agent에서 멈춤
라우터-->>직원: 500 (아무 결과 없음)
```
수업 준비 때 `cases/lab03.json` 4/5, 이 케이스만 HTTP 500.
| 막는 방법 | 어떻게 | 직원이 받는 답 |
| --- | --- | --- |
| 부르기 전에 (권장) | Lab 01 과제의 `missing`이 있으면 Agent를 부르지 않고 `route: 입력 필요` | "회의록 정리를 하려면 회의록 내용(notes)을 함께 보내 주세요." |
| 받은 뒤에 | 400을 결과로 바꿈 (3절) | "담당자에게 전달" (다시 보내면 되는 걸 모름) |
> 직원이 **고쳐서 다시 보낼 수 있는 실패**는 무엇이 빠졌는지 알려 주고, 고칠 수 없는 실패(Agent 장애)는 사람에게 넘깁니다.
## 3. 꺼진 Agent: 하나가 꺼져도 나머지는 답한다
`uv run tools/flow.py off agents/meeting-agent.json`으로 회의록 Agent를 끄고 복합 요청을 보냅니다.
| | 응답 | T-1002 답 | 회의록 업무 | `lab03-down` |
| --- | --- | --- | --- | --- |
| 고치기 전 | **HTTP 500** | 사라짐 | — | 1/3 |
| `neverError` + 빈 결과는 담당자 연결 | 200 | "처리 중" | `담당자 연결` · "담당 Agent가 응답하지 않아 …" | 3/3 |
(수업 준비 때 측정, 1회)
장애 격리 세 가지:
| 장치 | n8n에서 | 하는 일 |
| --- | --- | --- |
| 오류를 결과로 | HTTP Request `options.response.response.neverError: true` | 404·500에도 멈추지 않고 응답을 다음 노드로 |
| 기다리는 한도 | `options.timeout` (예: 60000 ms) | 느린 Agent 때문에 직원이 끝없이 기다리지 않게 |
| 대체 답 | 결과 Set에서 `{{ $json.route \|\| '담당자 연결' }}` | 빈 결과를 정해진 답으로 |
- 67일차 IT 문의 Agent의 "검증 실패 → 담당자 연결"과 같은 생각을 **Agent 사이**에 한 번 더 둡니다.
- Agent를 나눠 둔 덕분에 회의록 Agent만 꺼도 IT 답은 나옵니다. Agent 하나에 다 붙였다면 함께 멈췄습니다.
## 4. 어려운 테스트: 내가 찾는 구멍
67일차 Lab 03처럼, 고친 것만 확인하는 테스트로는 부족합니다. 수업 준비 때 쓴 어려운 케이스 7개를 예제 2 정답(빠진 입력 + 장애 격리)에 돌린 결과 5/7이었습니다.
| 실패한 케이스 | 원인 | 고침 |
| --- | --- | --- |
| user 없이 IT 질문 | `missing: ["user"]`를 보지 않고 IT Agent를 부름 → 400 → 장애로 처리해 `담당자 연결` | IT 갈래도 `missing`을 보고 `입력 필요` |
| 공백만 보냄 | `" "`도 "비어 있지 않음" → LLM까지 감 | 앞뒤 공백을 지우고 확인 |
통과한 케이스도 남겨 둡니다: 남의 접수 건이 섞인 요청(라우터를 거쳐도 "정우성"이 나오지 않음), 업무 4개, 소문자 `t1002`, 영어 질문. 고친 뒤 7/7, `lab02` 6/6, `lab03` 5/5, `lab03-down` 3/3.
> 수업 준비 때 "남의 접수 건" 케이스의 기대를 처음에 `본인이 접수한`(답 문장)으로 써서 실패했습니다. IT 문의 Agent의 계약은 이때 `route: 담당자 연결`입니다. **테스트가 틀렸는지 워크플로우가 틀렸는지는 계약 표로 판단**합니다.
## 5. 측정과 확장
수업 준비 때 정답 워크플로우의 시간 (1회씩, 여러 테스트에서 모음):
| 요청 | 시간 |
| --- | --- |
| 기타만 (LLM 나누기 한 번, Agent 없음) | 0.9~1.0초 |
| IT 하나 | 2.3~2.6초 |
| 회의록 하나 | 3.5초 |
| 복합 요청 (업무 3개) | 4.5~6.6초 |
| 업무 4개 | 4.6~4.8초 |
이 숫자에서 읽을 것:
- 시간 대부분은 **LLM API를 기다리는 시간**입니다 (나누기 한 번 약 1초, Agent마다 LLM 한두 번).
- 요청 하나가 n8n 실행 여러 개를 만듭니다: 복합 요청 = 라우터 1 + Agent 3. 21명이 동시에 보내면 n8n 실행은 약 84개.
| 확장 | 무엇 | 이 측정값에서 |
| --- | --- | --- |
| 수직 | 더 큰 서버 (CPU · 메모리) | 기다리는 시간이 대부분이라 효과가 작음 |
| 수평 | n8n 큐 모드: 메인 1 + 작업자(worker) 여러 개, Redis 큐 | 동시에 처리하는 실행 수를 늘림 |
| Agent별 분리 | 자주 쓰는 Agent만 작업자를 더 주거나 따로 운영 | 업무별 Agent로 나눴기 때문에 가능 |
| 바깥 한도 | OpenAI 분당 요청·토큰 한도 | 실행을 늘리면 여기서 막힘 → 75일차 비용·사용량 |
- 큐 모드는 오늘 실습하지 않습니다. 확장 계획은 `DESIGN.md` 6절에 **내 측정값**으로 씁니다.
## 정리
- [ ] 고칠 수 있는 실패(빠진 입력)는 부르기 전에 막고, 무엇이 빠졌는지 알려 준다
- [ ] 부른 Agent의 실패는 `neverError` · timeout · 대체 답으로 그 업무에서 멈춘다
- [ ] 테스트 기대가 맞는지는 Agent 계약으로 판단한다
- [ ] 확장은 측정값으로: 기다리는 시간이 대부분이면 수평 확장과 바깥 한도가 먼저
+84
View File
@@ -0,0 +1,84 @@
# 7·8교시 · 바이브 코딩 (`tflow`)
- 교시: 7교시 16:00~16:50 (각자 만들기), 8교시 17:00~17:50 (발표 · 정리 · 강사 바이브 코딩 · 팁 · 예고)
- 과제: [VIBE-Q-TFLOW](../../Last3Mon/68/VIBE-Q-TFLOW.md)
- 오늘은 `tflow`: n8n 워크플로우 JSON을 **트리 · mermaid · 노드별 한국어 설명**으로 보여 주는 TUI입니다. 에이전트가 만든 n8n 파일을 확인하는 도구라 오늘 오전 실습과 바로 이어집니다.
```mermaid
flowchart LR
A["7교시<br/>각자 만들기 50분"] --> B["발표<br/>10분"] --> C["강사 정리<br/>10분"] --> D["강사 바이브 코딩<br/>15분"] --> E["보충 · 팁<br/>10분"] --> F["69일차 예고<br/>5분"]
```
## 1. 7교시 · 각자 만들기 (50분)
| 시간 | 단계 | 확인 |
| --- | --- | --- |
| 16:00~16:03 | 0. 준비 (`~/vibe/tflow`, `git init`, 에이전트 실행) | |
| 16:03~16:15 | 1. 글자로 트리 · mermaid (R1 · R4) | `uv run tflow agents/it-agent.json`, `--mermaid` |
| 16:15~16:30 | 2. TUI · 상세 · 경고 (R2 · R3 · R5) | `IT help agent`의 모델·Tool, 망가진 파일 |
| 16:30~16:43 | 3. 한국어 설명 · 캐시 (R3) | 두 번째 선택은 바로 |
| 16:43~16:50 | 4. 정리 · 내 `assistant.json` 열어 보기 · 발표 메모 | |
강사는 교실을 돌며 아래를 봅니다.
| 볼 것 | 막혔을 때 한마디 |
| --- | --- |
| 한 번에 TUI까지 만들어 달라고 했나 | "1단계는 글자 출력만. 트리가 맞는지부터" |
| 트리가 끝없이 길어지거나 같은 노드 반복 | "다시 모이는 노드(`Send result`)는 두 번째부터 한 줄로" |
| mermaid가 안 그려짐 | "노드 이름에 `?`·괄호가 있어요. id는 번호로" |
| If 갈래가 반대 | "`main` 바깥 목록 0번이 true" |
| 설명에 Credential이 들어감 | "credentials는 빼고 보내라고 하세요" |
| 실행해 보지 않고 다음 요청 | "에이전트가 됐다고 해도 직접 `uv run tflow`" |
확인 기준 (입력 파일에서 센 값): `agents/it-agent.json` 노드 14 · main 11 · 모델 1 · Tool 2, `reference/lab03-example2-isolated.json` 노드 18 · main 19 · Switch 출력 4개. 수업 준비 때 tflow를 미리 만들어 보지는 않았습니다. 강사 바이브 코딩(4절)에서 걸린 시간을 재어 정답본(`VIBE-A-TFLOW.md`)에 남깁니다.
## 2. 8교시 · 발표 (10분)
- 1~2명. 7교시에 돌면서 **다시 모이는 노드나 mermaid 깨짐을 스스로 푼 사람**을 먼저 고릅니다.
- 3분 발표 · 2분 질문: 잘 먹힌 요청문 / 안 먹힌 요청문 / 에이전트가 틀린 곳과 알아챈 방법 / 내 `assistant.json` 시연.
## 3. 강사 정리 (10분)
오늘 n8n 실습과 tflow를 이 표로 묶습니다.
| | n8n 사내 업무 도우미 | tflow |
| --- | --- | --- |
| 나누기 | 요청 → 업무 (LLM) | 파일 → 노드·연결 목록 (코드) |
| 계약 | Agent 입력·결과 | `model.py`의 Node·Link (트리·mermaid·TUI가 함께 씀) |
| 규칙이 할 일 | 담당 Agent, 빠진 입력 | 갈래 이름, 다시 모이는 노드, 경고 |
| LLM이 할 일 | 업무 나누기 | 노드 설명 (캐시) |
| 실패해도 계속 | 꺼진 Agent → 담당자 연결 | 키 없음·LLM 실패 → 트리는 그대로 |
| 확인 | `cases/*.json` | 노드·연결 수 테스트, 망가진 파일 |
## 4. 강사 바이브 코딩 (15분)
학생 화면 앞에서 강사가 직접 이어서 만듭니다. 하나를 고릅니다.
| 주제 | 요청문 요지 | 보여 줄 것 |
| --- | --- | --- |
| `tflow diff a.json b.json` | "두 워크플로우의 노드 추가·삭제, 바뀐 parameters를 표로" | 74일차 `tver`의 예고. 에이전트가 고친 곳을 한눈에 |
| `flow.py check` 가져오기 | "Last3Mon/68/tools/flow.py 의 check 규칙을 읽고 tflow 경고에 더해" | 이미 있는 코드를 **읽혀서** 재사용 |
| 실행 기록 붙이기 | "runs/*.json 보고서를 읽어 실패한 케이스가 지나간 노드를 표시" | 테스트와 구조를 한 화면에 (77일차 `tlog` 예고) |
걸린 시간과 결과를 `Last3Mon/68/VIBE-A-TFLOW.md`에 적어 둡니다.
## 5. 보충 · 팁 (10분)
| 팁 | 설명 |
| --- | --- |
| 데이터 모양부터 | "파일 → Node·Link"를 먼저 만들고 테스트하면 화면은 나중에 얼마든지 바꿈 |
| 테스트 자료는 진짜 파일로 | 오늘 쓴 `agents/*.json`을 `tests/data`에 복사. 숫자(노드 14)로 확인 |
| 망가진 입력도 테스트 | 경고 기능은 망가진 파일이 있어야 확인됨 |
| 비싼 일은 캐시 | LLM 설명은 내용(해시)으로 캐시, 바뀌면 다시 |
| 비밀은 보내지도 않기 | Credential, 키는 LLM 입력에서 빼기 |
| 단계마다 `git commit` | 에이전트가 망가뜨려도 돌아갈 곳 |
## 6. 69일차 예고 (5분)
- 오늘: 독립 업무를 Agent에게 **나눠** 맡김 (라우터). 내일: 한 업무를 역할별 Agent가 **이어서** 처리 (작성자 → 검토자 → 정리자, 역할 기반 분리와 협업).
- 바이브 코딩: `tcrew` (한 질문을 역할별 LLM이 차례로 처리하는 TUI). 오늘 `tflow`는 지우지 마세요. 내일 만든 워크플로우를 여는 데 씁니다.
## 확인 (강사)
- [ ] 7교시 시작 전 `OPENAI_API_KEY` 꺼내는 명령을 화면에 띄웠다 (키 값은 띄우지 않음).
- [ ] 발표자 1~2명, 강사 정리 표, 강사 바이브 코딩 1개(시간 기록), 팁, 예고.
+39
View File
@@ -0,0 +1,39 @@
# 68일차 · 복합 업무 시나리오 분석과 Multi-Agent 기반 워크플로우 설계 (바이브 코딩)
- 일자: 2026-10-20 (68일차)
- 교과목: 노코드 멀티 에이전트 워크플로우 설계 및 운영
- 단원: 운영·확장 관점의 AI 워크플로우 설계 고도화
- 학습 내용: 복합 업무 시나리오 분석, Multi-Agent 기반 Workflow 설계
- 실습 폴더: [Last3Mon/68](../../Last3Mon/68/README.md)
- 실습 환경: 65일차 n8n 2.42.6 + OpenAI API(`gpt-4.1-mini`) + 67일차 데이터 API + **CLI 코딩 에이전트**(Codex · Claude Code · Antigravity 중 하나)
- **실습 준비: [00-DAY68-PREP.md](00-DAY68-PREP.md) (수업 전날까지 1~3절 완료)**
## 오늘의 시간표
| 교시 | 시간 | 내용 | 자료 |
| --- | --- | --- | --- |
| 1 | 09:00~09:50 | 오늘의 개요 · 1단계 · 복합 업무 시나리오 분석 | [개요](00-DAY68-OVERVIEW.md), [1단계](01-STAGE1-COMPOSITE-SCENARIO.md) |
| 2 | 10:00~10:50 | 1단계 · Lab 01 (분석표, 업무 나누기, 과제: 담당·빠진 입력) | [Lab 01](../../Last3Mon/68/LAB-01-Q-SCENARIO-AND-SPLIT.md) |
| 3 | 11:00~11:50 | 2단계 · Multi-Agent 워크플로우 설계, Lab 02 예제 1·2 | [2단계](02-STAGE2-MULTI-AGENT-DESIGN.md), [Lab 02](../../Last3Mon/68/LAB-02-Q-ROUTER-AGENTS.md) |
| 4 | 12:00~12:50 | 2단계 · Lab 02 과제 35분 (Supervisor로도 만들어 비교) · 풀이 | [Lab 02](../../Last3Mon/68/LAB-02-Q-ROUTER-AGENTS.md) |
| - | 13:00~14:00 | 점심 | |
| 5 | 14:00~14:50 | 3단계 · 검증과 장애 격리, Lab 03 예제 1·2 | [3단계](03-STAGE3-VERIFY-AND-SCALE.md), [Lab 03](../../Last3Mon/68/LAB-03-Q-VERIFY-AND-ISOLATE.md) |
| 6 | 15:00~15:50 | 3단계 · Lab 03 과제 40분 (어려운 테스트 · 확장 계획) · 풀이 | [Lab 03](../../Last3Mon/68/LAB-03-Q-VERIFY-AND-ISOLATE.md) |
| 7 | 16:00~16:50 | 바이브 코딩 · `tflow` 만들기 (각자) | [VIBE-Q-TFLOW](../../Last3Mon/68/VIBE-Q-TFLOW.md), [진행](04-VIBE-CODING.md) |
| 8 | 17:00~17:50 | 바이브 코딩 발표 · 정리 · 강사 바이브 코딩 · 팁 · 69일차 예고 | [진행](04-VIBE-CODING.md) |
```mermaid
flowchart LR
P["개요"] --> S1["1단계<br/>복합 시나리오 분석<br/>업무 나누기"] --> S2["2단계<br/>라우터 · Supervisor"] --> S3["3단계<br/>장애 격리 · 확장"] --> V["7·8교시<br/>바이브 코딩 tflow"]
```
## 자료 목록
| 파일 | 내용 |
| --- | --- |
| `00-DAY68-PREP.md` | 실습 준비: n8n · 데이터 API 켜기, 두 Agent 게시, `flow.py doctor` (수업 전) |
| `00-DAY68-OVERVIEW.md` | 개요 13장 (PPT 대신 Markdown, 가로줄로 장 구분) |
| `01-STAGE1-COMPOSITE-SCENARIO.md` | 복합 요청, 업무 분석 다섯 칸, 업무 관계, LLM이 할 일과 규칙이 할 일 |
| `02-STAGE2-MULTI-AGENT-DESIGN.md` | Agent 계약, 라우터 · 파이프라인 · Fork-Join · Supervisor, 라우터 구현, Supervisor와 비교 |
| `03-STAGE3-VERIFY-AND-SCALE.md` | Multi-Agent 테스트, 빠진 입력, 장애 격리(`neverError`, 대체 답), 측정, 수직·수평 확장 |
| `04-VIBE-CODING.md` | 7·8교시 바이브 코딩 진행 (tflow), 발표, 강사 정리, 추가 바이브 코딩, 팁 |