# AI 업무 브리핑 캐스터

Python 3.12 이상, Cursor가 필요합니다. app.py가 있는 briefing-lab 폴더를 여세요.

DB 없이 JSON을 읽으며 브리핑은 저장하지 않습니다. 기본 demo는 외부 호출이 없습니다.

### 터미널 실행


```powershell
py -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe app.py
```

`py`가 없으면 `python --version`을 확인한 뒤 첫 명령의 py를 python으로 바꿉니다. 가상환경 활성화는 필요 없습니다. `http://127.0.0.1:5000`에서 목록과 demo 표시를 확인하고 버튼을 누릅니다. 종료는 Ctrl+C입니다. 포트가 사용 중이면 이전 실습 서버를 먼저 종료하세요.

### 터미널에서도 브리핑 듣기

새 터미널에서 아래 명령을 실행하면 텍스트 브리핑이 출력됩니다. 음성 합성은 하지 않습니다. demo에서는 외부 호출이 없고, live에서는 한 번의 실제 호출이 발생합니다.

```powershell
.\.venv\Scripts\python.exe sample_briefing.py
```

이 도구는 서버 설정을 사용하는 로컬 실행 도구여서 웹의 LAB_ACCESS_CODE를 묻지 않습니다. URL과 키는 출력하지 않고 브리핑과 API 보고 사용량만 출력합니다.

## 06 · 주소와 키를 받으면 live로

실행 중인 서버를 종료하고 예제 환경 파일을 복사합니다. 기존 파일이 있으면 덮어쓰지 말고 Cursor에서 수정하세요.

```powershell
if (-not (Test-Path -LiteralPath .env_privatellm)) {
    Copy-Item -LiteralPath .env_privatellm.example -Destination .env_privatellm
}
```

```dotenv
LLM_MODE=demo
PRIVATE_LLM_URL=
PRIVATE_LLM_MODEL=claude-sonnet-4-5-20250929
ANTHROPIC_VERSION=2023-06-01
SUBSCRIPTION_KEY=
LAB_ACCESS_CODE=
LLM_MAX_OUTPUT_TOKENS=256
```

1. PRIVATE_LLM_URL에 공유받은 **전체 HTTPS ENDPOINT**를 넣습니다. 임의로 경로를 덧붙이지 않습니다.
2. SUBSCRIPTION_KEY를 입력하고 LAB_ACCESS_CODE에는 API 키와 다른 추측하기 어려운 영문·숫자 코드를 정합니다.
3. LLM_MODE를 live로 바꾸고 서버를 다시 실행합니다. 터미널 샘플 또는 웹 버튼으로 한 번 호출합니다.
4. 브리핑과 업무 목록, 입력·출력 사용량을 비교합니다. 사용량이 없는 응답도 가능하며 실제 게이트웨이 형식을 확인해야 합니다.

실제 파일 `.env_privatellm`은 `.env.*` 패턴에 포함되지 않습니다. 제공한 .gitignore에는 별도 제외 규칙이 있습니다. GitHub에 올리기 전에 파일 목록을 확인하세요. 환경 파일은 기존 프로세스 환경변수를 덮어쓰지 않으므로, 예전에 터미널에서 설정한 값이 있으면 새 터미널에서 확인합니다.

## 07 · 실패와 제한을 안전하게 체험하기

demo 화면의 예제 선택에서 다음을 확인합니다. **실제 API에 반복 요청을 보내 한도를 소진하지 않습니다.**

| 예제 | 확인할 결과 |
|---|---|
| 정상 브리핑 | 3건 중 1건 완료, 담당자별 남은 업무, 실제 호출 없음 |
| 429 요청·토큰 제한 | 제한 안내, 5초 대기, 자동 호출 없음 |
| 시간 초과 | 실패 안내, 수동 재시도 가능 |
| 출력 잘림 | 짧아진 결과와 잘림 안내, demo 토큰 수치 없음 |

live에서 잘못된 접근 코드는 사내 API를 호출하기 전에 거부합니다. 잘못된 사내 키·접근 권한은 별도 오류로 안내하고, 사내 주소·외부 원본 오류는 보여주지 않습니다. 429의 원인이 구체적으로 제공되지 않으면 RPM인지 TPM인지 단정하지 않습니다. 유효한 Retry-After의 초 또는 날짜는 대기 안내에 반영합니다.

요청 중에는 버튼을 비활성화하고 끝나면 최소 5초를 기다립니다. 이는 **클릭 실수 방지**이며 여러 사용자·탭의 호출량을 제한하는 서버 정책이 아닙니다. 공유 코드도 비용 상한 장치가 아닙니다. 실제 사용량과 조직의 제한을 확인하세요.

외부 호출은 연결 대기 5초·응답 읽기 대기 30초로 설정합니다. 이는 모든 네트워크 상황에서 총 실행 시간을 정확히 30초로 자르는 제한은 아닙니다. 화면은 45초 뒤 대기를 끝낼 수 있지만 이미 시작된 서버 호출까지 취소됐다는 뜻은 아닙니다. 즉시 반복 클릭하지 않습니다.

새로고침하면 결과가 사라지는지 확인합니다. JSON 상태를 수정하고 로컬 서버를 재실행하면 demo 브리핑도 바뀝니다. 배포 앱은 파일 수정 후 재배포해야 바뀝니다. 자동 저장이나 브리핑 기록은 없습니다.

## 08 · Vercel에서 실행하기

[23주차 배포 절차](https://ax-team-logbook.vercel.app/week-23/deployment-guide#deploy)를 복습합니다. briefing-lab만 별도 GitHub 저장소로 올리고 가져오면 기존 23주차 실습도 보존할 수 있습니다.

| 설정 | 값 |
|---|---|
| Root Directory | app.py가 있는 폴더 |
| Framework Preset | Flask 자동 감지 확인 |
| Build / Output | 기본값, 별도 override 없음 |
| Python | .python-version의 3.12 |
| 초기 LLM_MODE | demo |
| 함수 실행 설정 | 제공된 vercel.json의 app.py maxDuration=60 |

requirements.txt, llm_client.py, templates, sample-jobs.json이 함께 커밋됐는지 확인합니다. Vercel에서는 Python 앱을 실행하며 JSON은 배포 묶음에서 읽습니다. 이 앱은 실행 중 파일을 쓰지 않습니다.

**먼저 demo로 배포**해 휴대폰에서도 목록과 브리핑·오류 체험이 되는지 확인합니다. 사내 API의 Vercel 외부 접근이 허용되고 호출 정책이 확인된 경우에만 Settings → Environment Variables에 서버 변수들을 등록하고 live로 재배포합니다. 로컬 환경 파일을 업로드하지 않습니다. Preview에서 실제 호출을 원하지 않으면 live 설정을 Production에만 적용하세요.

사내망·VPN 전용 API면 **Vercel demo + 로컬 live**로 진행합니다. 제한을 우회하지 않습니다. 실습 종료 후 LLM_MODE를 demo로 바꿔 새 배포하거나 프로젝트를 삭제하세요. 새 배포가 생겨도 이전 배포 URL이 남을 수 있으므로 이전 live 배포도 삭제·보호하고 필요 시 실습용 키를 폐기합니다. 키의 폐기는 다른 사용자가 공유하는 키인지 운영 담당자와 확인합니다.

### 완료 체크

- demo 표시와 실제 AI 응답을 구별했다.
- 업무명·담당자·상태를 원본과 비교했다.
- RPM·TPM과 한 요청의 출력 한도를 구별할 수 있다.
- 사용 토큰 미제공을 0으로 해석하지 않는다.
- 429·시간 초과·출력 잘림을 모의 응답으로 확인했다.
- Vercel에서 demo가 실행되고, live 가능 여부는 네트워크·정책에 따라 구별했다.
