담소 팀의 앱 살아있는 회고록 AI 서버입니다. 가족이 보낸 질문에 부모님이 영상으로 답하면, 이 서버가 STT, 요약, 명대사, 감정 태그, 민감정보 검토, 후속 질문, 네컷 메타데이터, 질문/자막 오버레이 영상을 생성합니다.
이 저장소는 AI 기능만 다룹니다. /backend, /frontend는 열람하거나 수정하지 않습니다.
| ID | 기능 | Endpoint |
|---|---|---|
| AI-001 | 인터뷰 질문 추천 | POST /api/v1/ai/questions/recommend |
| AI-002 | 답변 영상 STT | 운영: POST /api/v1/ai/jobs with mediaUrl, 개발 테스트: POST /api/v1/ai/stt/transcribe-file |
| AI-003~009 | 요약, 명대사, 감정 태그, 후속 질문, 안전검토, 상태, 네컷 메타데이터 | AI-002 pipeline 또는 개별 endpoint |
| AI-010 | 실패 fallback | POST /api/v1/ai/fallback/result |
| AI-011 | 질문/자막 영상 오버레이 | POST /api/v1/ai/overlay/subtitle-file |
| JOB | 비동기 AI 작업 | POST /api/v1/ai/jobs, GET /api/v1/ai/jobs/{job_id}?includeResult=false |
운영 기본값:
- API framework: FastAPI
- Queue: Redis
- STT primary: local
faster-whisper-large-v3-turbo - STT fallback: OpenRouter
microsoft/mai-transcribe-1.5 - Overlay segmentation:
videosdk-live/Namo-Turn-Detector-v1-Multilingual - Public test endpoint: Tailscale Funnel
ai/
├── api/ FastAPI endpoint layer
├── source/ 실제 AI 기능 구현
├── skills/ 기능별 CLI, 실험, 프롬프트, 공모전 기록
├── documents/ 기능명세서, Notion 복붙용 API/DB 문서
├── server/ Docker, Redis, API, worker, Funnel 실행 스크립트
└── data/ 로컬 mock 데이터 위치, 실제 파일은 git 제외
자세한 기능 계약은 documents/notion/API_FUNCTIONAL_SPEC_CURRENT.md와 documents/notion/DB_SCHEMA_CURRENT.md를 먼저 보면 됩니다.
Host 기준:
cd /home/medisc/eiden/DAMSO-APP/ai/server
bash 0_redis_run.sh
bash 2_env_build.sh
bash 3_env_run.shAPI 서버 실행:
docker exec -it damso-ai bash -lc 'cd /workspace && bash server/4_api_run.sh'Health check:
curl http://127.0.0.1:8000/api/v1/ai/health컨테이너 내부의 /workspace는 이 저장소의 ai/ 폴더입니다.
.env는 git에 올리지 않습니다. 최소 운영 키는 다음과 같습니다.
OPENROUTER_API_KEY=...
gateway_auth_token=...
# 또는
DAMSO_AI_API_KEY=...
HF_TOKEN=...비-health API는 DAMSO_AI_API_KEY 또는 gateway_auth_token이 있으면 인증을 요구합니다.
Authorization: Bearer <token>
X-Damso-AI-Key: <token>
현재 검증된 Funnel endpoint:
https://eiden-main-gpu.tailf7cde3.ts.net/api/v1/ai
Funnel 시작:
cd /home/medisc/eiden/DAMSO-APP/ai/server
bash 7_funnel_start.shFunnel 상태:
bash 9_funnel_status.sh주의: Tailscale 100.x.x.x 주소는 tailnet 내부 전용이고, Funnel URL은 공개 HTTPS URL입니다. 그래서 앱서버 연동에는 반드시 API key 헤더를 사용합니다.
공통 입력 컨텍스트:
{
"send_user": "최대현",
"send_role": "둘째 아들",
"question": "자녀에게 들었던 말이나 행동 중 기억에 남는 가장 고마웠던 순간은 언제였나요?",
"receive_user": "최기섭",
"receive_role": "아버지"
}AI-002 운영 비동기 STT:
앱서버는 원본 비디오를 GCS에 먼저 올리고, AI 서버에는 GCS signed download URL만 전달합니다. 가공 영상이 필요하면 GCS signed PUT URL을 editedVideoUploadUrl로 함께 보냅니다. POST /jobs 응답은 즉시 202 Accepted이며, 앱서버는 timingPollUrl로 소요시간을 polling하고 최종 결과는 callbackUrl로 받습니다.
curl -X POST "$DAMSO_AI_BASE_URL/jobs" \
-H "Content-Type: application/json" \
-H "X-Damso-AI-Key: $DAMSO_AI_API_KEY" \
-d '{
"jobId": "ai_job_001",
"answerId": "ans_001",
"questionId": "q_001",
"send_user": "최대현",
"send_role": "둘째 아들",
"question": "자녀에게 들었던 말이나 행동 중 기억에 남는 가장 고마웠던 순간은 언제였나요?",
"receive_user": "최기섭",
"receive_role": "아버지",
"mediaUrl": "https://storage.googleapis.com/damso-videos/answers/ans_001.mp4?X-Goog-Algorithm=...",
"editedVideoUploadUrl": "https://storage.googleapis.com/damso-videos/answers/ans_001_edited.mp4?X-Goog-Algorithm=...",
"mediaDurationSeconds": 39.9,
"includeDownstream": true,
"providerMode": "auto",
"callbackUrl": "https://app.example.com/internal/ai/jobs/ai_job_001/callback",
"callbackToken": "server-issued-callback-token"
}'Polling:
curl -H "X-Damso-AI-Key: $DAMSO_AI_API_KEY" \
"$DAMSO_AI_BASE_URL/jobs/ai_job_001?includeResult=false"includeResult=false polling 응답은 elapsedSeconds, processingElapsedSeconds, estimatedTotalSeconds, estimatedRemainingSeconds, progress, status만 확인하는 용도입니다. 완료 결과 JSON은 callback payload의 result에 들어갑니다. callback 장애 시에는 includeResult=true 또는 query 생략으로 polling fallback을 사용할 수 있습니다.
AI-002 개발 테스트용 업로드 STT:
curl -X POST "$DAMSO_AI_BASE_URL/stt/transcribe-file" \
-H "X-Damso-AI-Key: $DAMSO_AI_API_KEY" \
-F "file=@data/mock_data_v2.mp4;type=video/mp4" \
-F "answerId=ans_001" \
-F "questionId=q_001" \
-F "send_user=최대현" \
-F "send_role=둘째 아들" \
-F "question=자녀에게 들었던 말이나 행동 중 기억에 남는 가장 고마웠던 순간은 언제였나요?" \
-F "receive_user=최기섭" \
-F "receive_role=아버지" \
-F "providerMode=local" \
-F "includeDownstream=true"AI-011 질문/자막 영상 오버레이:
curl -X POST "$DAMSO_AI_BASE_URL/overlay/subtitle-file" \
-H "X-Damso-AI-Key: $DAMSO_AI_API_KEY" \
-F "file=@data/mock_data_v2.mp4;type=video/mp4" \
-F "answerId=ans_001" \
-F "questionId=q_001" \
-F "send_user=최대현" \
-F "send_role=둘째 아들" \
-F "question=자녀에게 들었던 말이나 행동 중 기억에 남는 가장 고마웠던 순간은 언제였나요?" \
-F "receive_user=최기섭" \
-F "receive_role=아버지" \
-F "outputPath=/workspace/tmp/answer_overlay.mp4" \
-F "runSttIfMissing=true" \
-F "segmentationMode=namo-turn" \
-F "uploadToStorage=true" \
-F "storageProvider=gcs" \
-F "storagePrefix=damso-ai/overlays"GCP Storage bucket과 public/CDN base URL은 나중에 .env에 DAMSO_GCS_BUCKET, DAMSO_GCS_PUBLIC_BASE_URL, GOOGLE_APPLICATION_CREDENTIALS로 채우면 됩니다. 설정이 없으면 영상은 생성되고 storage.uploaded=false로 반환됩니다.
컨테이너 안에서 개별 기능을 확인할 수 있습니다.
docker exec -it damso-ai bash
cd /workspace
python skills/question/run_recommendation.py --mock
python skills/stt/run_transcribe.py --input skills/stt/mock_input.json
python skills/summary/run_summary.py
python skills/overlay/run_overlay.py --input skills/overlay/mock_input.json공모전 제출용 프롬프트/개발 과정 기록은 skills/vibe-coding/에 있습니다.
2026-07-06 기준 Funnel URL로 실제 mediaUrl Job과 multipart upload 검증을 완료했습니다.
| Test | Result |
|---|---|
GET /health |
200 OK |
| 비-health API without key | 401 |
AI-002 POST /jobs with mediaUrl |
202 Accepted |
| AI-002 Redis job mode | completed, jobMode=redis_queue |
| AI-002 timing polling | includeResult=false, result omitted, elapsed/estimated seconds returned |
| AI-002 callback | delivered, 204, AI-003~AI-009 included |
| AI-002 polling fallback | includeResult=true, result returned |
| AI-002 upload STT | 200 OK, faster-whisper GPU, fallback false |
| AI-002 downstream | AI-003~AI-009 포함 |
| AI-011 overlay upload | 200 OK |
| AI-011 output | /workspace/tmp/FINAL-FUNNEL-AI011-overlay.mp4 |
| Overlay video probe | 720x1280, 39.873s |
테스트 산출물은 tmp/에 있으며 git에 포함하지 않습니다.
Push 대상:
api/,source/,skills/,documents/,server/- 작은 예시 JSON
- 실행/배포 스크립트
- BMJUA overlay font
Push 금지:
.env, API key, tokendata/원본 영상/음성tmp/테스트 결과source/models/모델 파일source/stt/faster-whisper/외부 clone- pycache/log/output 파일
이 README는 GitHub의 README 권장 항목인 프로젝트 목적, 유용성, 시작 방법, 도움 문서 위치를 우선 배치했습니다. FastAPI 컨테이너 실행은 공식 FastAPI Docker 문서의 requirements.txt 기반 설치와 단일 서버 프로세스 구조를 따릅니다. Dockerfile은 Docker 공식 best practices의 RUN apt-get update && apt-get install 결합 및 --no-install-recommends 스타일을 따릅니다. Funnel 운영 안내는 Tailscale 공식 Funnel 요구사항과 공개 HTTPS URL 특성을 기준으로 작성했습니다.
- GitHub README guide: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes
- FastAPI Docker deployment: https://fastapi.tiangolo.com/deployment/docker/
- Docker build best practices: https://docs.docker.com/build/building/best-practices/
- Tailscale Funnel: https://tailscale.com/docs/features/tailscale-funnel