---
title: "기능설명서 — AI 브리프 (코칭 브리프)"
category: "guide"
parent: "달록 개발 현황"
document_type: "spec"
source_status: "generated"
knowledge_group: "02_specs"
priority: "Medium"
purpose: "최근 7일 운동·체성분 데이터로 CF Worker 프록시를 통해 AI를 직접 호출해 6섹션 코칭 글+시각화 카드를 생성·저장·표시하는 '✦ AI 브리프' 완전 자동 기능설명서. 모든 인증 사용자 사용 가능."
read_when: ["기능파악","AI브리프·코칭"]
updated: "2026-06-04"
source_of_truth: "https://dallog-tools.hansbridge.co.kr/"
---

# 달록 기능설명서 — "AI 브리프"

| 항목 | 내용 |
|---|---|
| 기능명 | AI 브리프 (코칭 브리프) |
| 작성일 | 2026.06.04 |
| 상태 | 운영 중 (인증 사용자 전체 사용 가능) |
| 분류 | 기능설명서 |
| 관련 코드 | `src/pages/CoachNotes.tsx`, `src/lib/claude.ts`, `src/lib/briefApi.ts`, `src/pages/Settings.tsx`, `workers/brief-proxy/index.js` |

---

## 1. 한 줄 정의

> 최근 운동·체성분 기록을 모아 **앱 안에서 직접 AI를 호출해 코칭 브리프(글 + 시각화 카드)를 생성·저장·표시**하는 기능.

"AI에게 보내기"가 데이터를 복사해 사용자가 외부 AI에 붙여넣는 **반자동** 기능이라면, "AI 브리프"는 버튼 한 번으로 AI가 코칭 코멘트를 써서 앱 화면에 바로 띄워 주는 **완전 자동** 기능이다.

> 비개발 해설 — 코치노트 페이지에서 "✦ AI 브리프" 버튼을 누르면, 최근 7일치 내 기록을 AI가 읽고 "체중 해석 / 체성분 흐름 / 러닝 / 근력 / 다음 운동 추천 / 식단 추천" 6개 항목의 코칭 글을 써 준다. 동시에 내일 추천 운동·권장 섭취량 같은 정보를 카드 형태로 보기 좋게 정리해 준다.

---

## 2. 접근 권한

| 대상 | 권한 |
|---|---|
| AI 브리프 **생성**(코치노트 페이지) | 인증된 **모든 사용자** 사용 가능 (이메일 제한 없음) |
| AI 브리프 **지침 설정**(설정 페이지) | 모든 사용자 접근 가능 |

> 참고 — "AI에게 보내기"(클립보드 복사)는 `ccy8215@gmail.com` 전용이지만, "AI 브리프" 생성 자체에는 이메일 제한이 걸려 있지 않다. 다만 현재 시스템 프롬프트에는 특정 개인(체중·목표 등) 맥락이 하드코딩되어 있어, 실질적으로는 본인 기준에 맞춰진 상태다.

---

## 3. 버튼·UI 위치

| UI | 파일 | 위치 |
|---|---|---|
| "✦ AI 브리프" 생성 버튼 | `src/pages/CoachNotes.tsx` | 코치노트 페이지 좌측 사이드바 상단(데스크탑) |
| "✦ AI 브리프 지침" 설정 | `src/pages/Settings.tsx` | 설정 > 개인 메모 탭 |
| 시각화 카드 | `CoachNotes.tsx` `VisualBriefCards` | 생성 결과 표시 영역 |

---

## 4. 동작 흐름

```
"✦ AI 브리프" 클릭
  └→ handleGenerateBrief()
       ① buildBriefContext()    ── 최근 7일 데이터 수집(체성분·러닝·근력) + 이전 브리프 2건 참고
       ② buildSystemPrompt()    ── 코칭 지침 + 사용자 AI 지침 4종 + 6섹션 구조 명시
       ③ CF Worker 프록시 호출   ── POST { provider:'auto', max_tokens:2500, stream:true, system, messages }
       ④ SSE 스트리밍 누적        ── delta 조각을 실시간 수신, 진행상태 표시
       ⑤ 응답 분리 저장
            - prose 본문 → coach_notes (category='brief')
            - JSON 시각화 → app_settings (brief_visual_cache / brief_visual_date)
       ⑥ loadAll()              ── 화면 갱신, 카드 렌더링
```

> 비개발 해설 — AI가 글을 쓰는 동안 한 글자씩 흘러나오듯 화면에 표시(스트리밍)된다. 완성된 글은 "코치노트"로 저장되고, 카드용 정보는 따로 떼어내 저장해 두었다가 다음에 다시 들어와도 보이도록 캐시한다.

---

## 5. AI 호출 아키텍처 (프록시 구조)

브라우저가 AI API를 직접 부르지 않고, **클라우드플레어 Worker 프록시**를 거친다. API 키를 프런트엔드에 노출하지 않기 위함이다.

```
브라우저 (dallog.kr / pages.dev)
   └→ CF Worker 프록시  https://dallog-brief-proxy.ccy4848.workers.dev
        ├─ 1차: OpenAI   gpt-5.4-mini-2026-03-17
        └─ 폴백: Anthropic  claude-sonnet-4-20250514
```

**프록시(`workers/brief-proxy/index.js`)가 담당하는 것**

| 기능 | 설명 |
|---|---|
| Origin 검증 | 허용 도메인(예: dallog.pages.dev, localhost)만 호출 허용 |
| Rate limit | 시간당 360건(분당 약 6건) 제한 |
| 요청 크기 제한 | Content-Length 최대 50KB |
| Provider 자동 선택 | `provider:'auto'` 또는 모델명 접두사로 OpenAI/Anthropic 판별 |
| Fallback | 1차(OpenAI) 실패 시 2차(Anthropic)로 자동 전환 |
| 응답 정규화 | OpenAI 응답을 Anthropic Messages 형식으로 변환해 클라이언트 호환 유지 |
| 스트리밍 | 클라이언트 `stream:true` 시 SSE로 조각 전송 |

> 비개발 해설 — "프록시"는 중간 다리 서버다. 비밀 API 키를 브라우저에 노출하면 누구나 도용할 수 있으므로, 키는 이 다리 서버에만 보관하고 브라우저는 다리 서버에게만 요청한다. 다리 서버가 우리 사이트에서 온 요청인지 확인하고, 너무 잦은 호출을 막고, 한 AI가 실패하면 다른 AI로 자동으로 바꿔 준다.

**API 키·환경변수**(Worker secret으로 보관, 코드에 평문 없음)

- `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`
- `DEFAULT_BRIEF_PROVIDER`(openai), `FALLBACK_BRIEF_PROVIDER`(anthropic)
- `DEFAULT_BRIEF_MODEL`(gpt-5.4-mini-2026-03-17), `FALLBACK_BRIEF_MODEL`(claude-sonnet-4-20250514)
- `RATE_LIMIT_HOURLY`(360), `REQUIRE_AUTH`(false)

---

## 6. 프롬프트 구성

### 6-1. 시스템 프롬프트 (`buildSystemPrompt`)

- **코칭 맥락** — 코치 역할, 사용자 목표 체중·체성분·러닝 폼 기준 등
- **사용자 추가 지침 4종** — 아래 설정값을 주입(있을 때만)
  - 러닝 철학/훈련 방향(philosophy)
  - 현재 부상/신체 이슈(injuries)
  - 식이 패턴/특이사항(diet)
  - 기타 개인 지침(etc)
- **논조·화법** — 평가·판정이 아닌 해석·조율 중심, 자연스러운 한국어 종결(콜론 금지), JSON 키 등 코드 요소 노출 금지
- **6섹션 고정 구조** — ①체중 해석 ②체성분 흐름 ③러닝 구성 ④근력 구성 ⑤다음 운동 추천 ⑥식단 추천
- **시각화 JSON 스키마** — 본문 뒤에 ```json 블록으로 tomorrow_workout / nutrition / menu / weekly_assessment / coach_message 첨부 지시

### 6-2. 사용자 프롬프트 (`buildBriefContext`)

- 참조 범위: 각 데이터셋 최신 기록일 기준 **최근 7일(inclusive)**
- 최근 체성분(체중·골격근·체지방·체지방률 + 7일 증감)
- 최근 러닝(누적 마일리지·런타입 분포·상세)
- 최근 근력(세션별 종목·무게·반복)
- 이전 코칭 브리프 최대 2건(참고용, 원문 복붙 금지 지침 포함)

---

## 7. 결과 저장·표시

| 산출물 | 저장 위치 | 표시 |
|---|---|---|
| 코칭 글(prose 본문) | `coach_notes` (category='brief') | 코치노트 목록 |
| 시각화 데이터(JSON) | `app_settings` (brief_visual_cache / brief_visual_date) | `VisualBriefCards` 카드 |

- `extractProseBody()` — 응답에서 JSON 블록을 제거해 순수 글 본문만 코치노트에 저장
- `parseVisualBrief()` — JSON 블록을 파싱해 카드 데이터로 분리 저장
- 시각화 카드 — 내일 추천 운동, 권장 섭취량(매크로 막대 차트), 추천 메뉴(아침·점심·저녁), 주간 컨디션 평가, 코치 한마디

---

## 8. AI 브리프 지침 설정 (사용자 맞춤)

설정 > 개인 메모 탭의 "✦ AI 브리프 지침" 카드에서 4개 필드(철학·부상·식이·기타)를 입력하면 `app_settings`의 `ai_brief_instructions`(JSON)에 저장되고, 다음 브리프 생성 시 시스템 프롬프트에 자동 주입된다.

> 비개발 해설 — "나는 슬로우 조깅 위주다", "오른쪽 무릎이 아프다" 같은 개인 사정을 한 번 적어 두면, 이후 AI 브리프가 매번 그 맥락을 반영해 코칭해 준다.

---

## 9. "AI에게 보내기" 와의 차이 요약

| 구분 | AI 브리프 | AI에게 보내기 |
|---|---|---|
| 동작 | 앱 내에서 AI 직접 호출 | 데이터를 클립보드 복사 |
| AI 호출 주체 | 앱(자동) | 사용자(수동 붙여넣기) |
| 데이터 범위 | 최근 7일 | 전체 기간 |
| 결과 | 코치노트 + 카드 자동 저장 | 외부 AI에서 사용자가 직접 처리 |
| 권한 | 모든 인증 사용자 | `ccy8215@gmail.com` 전용 |
| 모델 | gpt-5.4-mini(폴백 claude-sonnet-4) | (사용자가 붙여넣는 AI에 따름) |

"AI에게 보내기" 상세는 [기능설명서 — AI에게 보내기](#/doc/spec-doc-91) 참조.

---

## 10. 정리

"AI 브리프"는 **최근 7일 운동·체성분 데이터를 모아 CF Worker 프록시를 통해 AI(OpenAI 기본·Anthropic 폴백)를 직접 호출하고, 6섹션 코칭 글과 시각화 카드를 생성해 코치노트·설정에 저장·표시**하는 완전 자동 코칭 기능이다. 사용자별 AI 지침으로 맞춤화가 가능하며, API 키는 프록시 Worker에만 보관해 보안을 유지한다.
