尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗일반 ChatGPT는 "요즘 비트코인 흐름 어때?"라고 물어도 내가 가진 데이터를 모릅니다. 이 서비스는 내가 저장한 비트코인 일별 종가 200일치를 분석해 요약을 만들고, 그 요약을 AI의 시스템 프롬프트에 넣어서 내 데이터 기준으로 대답하게 합니다. 데이터는 화면에서 직접 추가·수정·삭제할 수 있고, 바뀐 데이터는 곧바로 요약과 AI 답변에 반영됩니다.
데이터 출처: 이전 미션(M1-1)에서 바이낸스 API로 수집한 BTC/USDT 일봉 중 최근 200일 (2026-04-04 ~ 2026-10-20)
| 구분 | URL |
|---|---|
| 프론트엔드 (Vercel) | https://codyssey-native-m1-2-frontend.vercel.app |
| 백엔드 API (Render) | https://btc-data-assistant-api.onrender.com |
| Swagger UI | https://btc-data-assistant-api.onrender.com/docs |
⏳ 백엔드는 Render 무료 플랜이라 15분 동안 요청이 없으면 잠듭니다. 첫 접속은 1분 가까이 걸릴 수 있고 (실측 약 56초), 그동안 화면 상단에 "서버 깨우는 중" 안내가 뜨고 자동으로 다시 연결을 시도합니다.
| 영역 | 사용 기술 |
|---|---|
| 백엔드 | Python 3.12, FastAPI, Uvicorn, Pydantic v2 |
| DB | Firebase Firestore (firebase-admin) |
| AI | OpenAI Chat Completions API (gpt-5.4-mini) + Function Calling |
| 프론트엔드 | HTML / CSS / JavaScript (프레임워크 없음), 그래프는 SVG 직접 그리기 |
| 배포 | Render (백엔드), Vercel (프론트엔드) |
(date, value, memo) 추가/수정/삭제, 목록 즉시 갱신, 저장 결과 메시지├── backend/
│ ├── main.py # FastAPI 앱: CORS, 라우터 연결, 공통 예외 처리
│ ├── app/
│ │ ├── config.py # 환경 변수 읽기 (키는 전부 여기로만 들어옴)
│ │ ├── db.py # 저장소 계층: Firestore / 메모리(로컬 테스트용)
│ │ ├── schemas.py # Pydantic 요청·응답 검증 규칙
│ │ ├── routers/ # URL ↔ 함수 연결만 담당 (HTTP 층)
│ │ │ ├── data.py # /api/data ...
│ │ │ ├── conversations.py # /api/conversations ...
│ │ │ └── chat.py # /api/chat
│ │ └── services/ # 실제 로직 (라우터와 분리)
│ │ ├── summary.py # 시계열 분석 → 요약·통계
│ │ ├── data_service.py # 데이터 CRUD
│ │ ├── conversation_service.py
│ │ └── chat_service.py # 컨텍스트 주입 + GPT 호출 + 도구 실행 + 자동 저장
│ ├── data/btc_daily.csv # 초기 데이터 200일
│ ├── scripts/seed_firestore.py# CSV → Firestore 업로드 (1회)
│ ├── requirements.txt
│ └── .env.example
├── frontend/
│ ├── index.html / style.css / app.js
│ ├── build.sh # Vercel 빌드 시 API_BASE_URL → config.js 생성
│ └── vercel.json
├── render.yaml # Render 배포 설정
└── docs/screenshots/ # 제출 스크린샷
/api/data/summary와 /api/chat이 함께 쓰므로 계산이 한곳에만 있다.STORAGE=memory로
같은 코드를 돌려 볼 수 있고, 나중에 DB를 바꿔도 서비스 코드는 그대로다.| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/data | 새 데이터 추가 (같은 날짜가 있으면 409) |
| GET | /api/data?start=&end= | 데이터 목록 (날짜 오름차순, 기간 필터 선택) |
| PUT | /api/data/{id} | 데이터 수정 (보낸 필드만 변경) |
| DELETE | /api/data/{id} | 데이터 삭제 |
| GET | /api/data/summary | 데이터 요약 (프롬프트 주입용) |
| GET | /api/data/statistics | [보너스] 7일 이동평균·월별 평균·최대 상승/하락일·상승/하락 일수 |
| POST | /api/conversations | 대화 저장 |
| GET | /api/conversations | 대화 목록 — messages는 포함하지 않음 (message_count, preview만) |
| GET | /api/conversations/{id} | 특정 대화 불러오기 — 전체 messages 포함 (요구사항 (A) 방식) |
| DELETE | /api/conversations/{id} | 대화 삭제 |
| POST | /api/chat | AI 채팅 (요약 주입 → GPT → 대화 자동 저장) |
data/{자동ID}
date: "2026-10-20" value: 83028.15 memo: "" created_at updated_at
conversations/{자동ID}
title: "최근 일주일 추세 어때?"
messages: [ {role: "user"|"assistant", content, created_at}, ... ]
created_at updated_at
| 필드 | 규칙 | 틀리면 |
|---|---|---|
date | 실제 존재하는 날짜 (YYYY-MM-DD) | 422 |
value | 0보다 크고 1천만 이하, NaN·무한대 불가 | 422 |
memo | 200자 이하, 앞뒤 공백 제거 | 422 |
| 수정 요청 | date/value/memo 중 최소 1개 | 422 |
| 같은 날짜 중복 | 하루에 값 1개만 | 409 |
message (채팅) | 1~1000자, 공백만은 불가 | 422 |
라우터 함수까지 오기 전에 FastAPI가 자동으로 막아 주므로, 잘못된 값이 DB에 들어갈 수 없습니다.
예상하지 못한 에러는 공통 핸들러가 받아 내부 정보 없이 500 "서버 내부 오류"로만 응답합니다.
Firestore data (200일)
│ build_summary()
▼
요약: 기간 / 개수 / 최신값 / 평균 / 최고·최저(날짜) / 기간 변화율 / 최근 추세 / 30일 변동성
│ summary_to_prompt()
▼
시스템 프롬프트 "[사용자 데이터 요약] ..." 에 삽입
│
▼
GPT 호출 ── 요약만으로 부족하면 도구 호출 ──► get_data_range / get_statistics ...
│ (서버가 실행해 결과를 다시 GPT에게)
▼
최종 답변 → conversations에 질문·답변 자동 저장 → 화면 표시
증가, -2% 미만이면 감소, 그 사이면 유지| 도구 | 돌려주는 것 (예시 질문) |
|---|---|
get_statistics(start_date?, end_date?, last_days?) | 지정한 기간(비우면 전체)의 변화율·평균·최고/최저·최대 상승/하락일(종가 포함)·상승/하락 일수·변동성·월별 평균 — "9월 중 가장 크게 오른 날은?", "요즘 어때?" |
get_data_range(start_date, end_date | last_days) | 그 기간의 일별 값·메모·전일 대비 변동률 (최대 120일) — "10월 15일 값은?", "9월 한 달 흐름 요약해줘" |
list_conversations() | 저장된 이전 대화 목록 — "전에 내가 뭐 물어봤지?" |
기간은 start_date~end_date로 주거나, last_days(마지막 데이터 날짜까지 최근 N일)로 줍니다.
last_days는 AI가 날짜 계산을 직접 하다 틀리지 않도록 서버가 날짜로 바꿔 줍니다.
질문마다 도구를 정해 주는 대신, 시스템 프롬프트에는 "질문이 가리키는 기간을 대화 흐름에서 먼저 정하고
그 범위로 도구를 부른다"는 원칙만 두었습니다. 기간 표현이 없으면 전체 기간,
"요즘·최근"처럼 길이 없이 최근을 말하면 최근 30일로 봅니다.
그래서 "요즘 어때?" → "그 중 가장 많이 오른 날은?" 같은 이어 묻기도 앞 질문의 기간으로 계산합니다.
도구 설명(description)과 이 원칙을 보고 GPT가 스스로 고르며,
화면에서는 답변 아래 🔧 get_statistics 처럼 실제로 호출된 도구가 표시됩니다.
비용 보호를 위해 도구 호출은 최대 3번, 답변은 최대 600토큰으로 제한했습니다.
cd backend
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env # 값 채우기 (아래 환경 변수 표 참고)
.venv/bin/python -m scripts.seed_firestore # 처음 1번만: CSV 200일 → Firestore
.venv/bin/uvicorn main:app --reload # http://127.0.0.1:8000/docs
키 없이 화면만 먼저 보고 싶다면
STORAGE=memory .venv/bin/uvicorn main:app --reload(CSV 데이터가 메모리에 자동으로 채워지고, 서버를 끄면 사라짐. 채팅은 OpenAI 키가 있어야 동작)
cd frontend
echo 'window.APP_CONFIG = { API_BASE_URL: "http://127.0.0.1:8000" };' > config.js
python3 -m http.server 5500 # http://127.0.0.1:5500
backend/.env)| 이름 | 필수 | 설명 |
|---|---|---|
OPENAI_API_KEY | ✅ | OpenAI API 키 |
FIREBASE_SERVICE_ACCOUNT_JSON | ✅ (배포) | 서비스 계정 키 JSON 내용 전체를 한 줄 문자열로 |
FIREBASE_SERVICE_ACCOUNT_PATH | (로컬 대안) | 서비스 계정 키 파일 경로 — 위 JSON 대신 사용 가능 |
ALLOWED_ORIGINS | ✅ | CORS 허용 프론트 주소, 쉼표 구분 (예: https://xxx.vercel.app) |
OPENAI_BASE_URL | OpenAI 호환 프록시 주소 (예: https://copa.codyssey.kr/v1), 비우면 OpenAI 공식 주소 | |
OPENAI_MODEL | 기본 gpt-5.4-mini | |
OPENAI_MAX_TOKENS | 답변 최대 토큰, 기본 600 | |
STORAGE | firestore(기본) 또는 memory |
| 이름 | 필수 | 설명 |
|---|---|---|
API_BASE_URL | ✅ | 백엔드 주소 (예: https://xxx.onrender.com). 빌드 때 build.sh가 config.js로 만들어 줌 |
.env와 키 파일은 .gitignore로 제외하고, 키는 백엔드에만 두며 프론트(브라우저)에는 절대 넣지 않습니다.백엔드 (Render) — GitHub에 푸시 → Render New > Blueprint로 이 저장소 선택(render.yaml 자동 인식)
→ OPENAI_API_KEY, FIREBASE_SERVICE_ACCOUNT_JSON, ALLOWED_ORIGINS 입력 → 배포 후 /docs 확인
프론트엔드 (Vercel) — Add New > Project → 같은 저장소 선택 → Root Directory frontend
→ 환경 변수 API_BASE_URL 입력 → Deploy → 나온 주소를 Render의 ALLOWED_ORIGINS에 추가
| 화면 | 이미지 |
|---|---|
| 데이터 요약이 보이는 채팅 (질문+답변) — 상단 요약 카드, "요즘" 질문을 최근 30일로 계산, 호출한 도구 표시 | |
| 데이터 관리 (CRUD 동작) — 2026-10-20 메모 수정 후 저장 결과와 갱신된 목록 | |
| 대화 기록 불러오기 — 왼쪽 목록에서 이전 대화를 선택해 메시지를 다시 표시 | |
| Swagger UI |