Skip to content

Latest commit

 

History

History
1635 lines (1293 loc) · 55.9 KB

File metadata and controls

1635 lines (1293 loc) · 55.9 KB

Jagalchi AI Service API 명세서

Django 4.2 + Django REST Framework | Port 8000
최종 업데이트: 2026-04-07


목차

  1. 공통 사항
  2. 인증
  3. 에러 처리
  4. 문서 및 헬스체크
  5. 학습 코치 API
  6. 로드맵 API
  7. 기술 카드 API
  8. 댓글 인텔리전스 API
  9. 검색 및 추천 API
  10. Init Data 관리 API
  11. 노드 콘텐츠 생성 API
  12. 프론트엔드 통합 가이드

공통 사항

Base URL

http://localhost:8000/api/ai/

게이트웨이 경유 시 /api/ai/ 프리픽스가 붙는다. 직접 호출 시 /ai/만 사용.

요청 규칙

  • 대부분의 AI 엔드포인트는 GET + Query Parameter 방식 (request body 아님)
  • POST가 필요한 엔드포인트: init-data 생성, document-roadmap POST, node-resource-save
  • JSON key: snake_case
  • Content-Type: application/json

Rate Limiting

유형 제한
비인증 (Anonymous) 100 req/hour
인증 (Authenticated) 1,000 req/hour

초과 시 429 Too Many Requests 응답.


인증

JWT Bearer Token (HS256)

Authorization: Bearer <token>

토큰 클레임 (Payload)

{
  "sub": "user_123",
  "roadmapId": "rm_frontend",
  "permissions": ["READ", "EDIT"],
  "iat": 1712448000,
  "exp": 1712534400
}
클레임 타입 설명
sub string 사용자 ID
roadmapId string? 스코핑된 로드맵 ID (선택)
permissions string[] READ, EDIT, ADMIN 중 하나 이상
iat number 발급 시각 (Unix timestamp)
exp number 만료 시각 (Unix timestamp)

인증 비활성화

개발 환경에서는 서버 환경변수 AI_AUTH_ENABLED=false로 인증을 끌 수 있다. 이 경우 모든 요청이 허용됨.

인증 실패 응답

{
  "detail": "Invalid authorization header. Expected Bearer token."
}

HTTP Status: 401 Unauthorized 또는 403 Forbidden


에러 처리

공통 에러 형식

{
  "error": "에러 메시지"
}

HTTP 상태 코드

코드 의미 프론트 대응
200 성공 정상 처리
201 생성 성공 리소스 생성 완료
204 삭제 성공 body 없음
400 잘못된 요청 파라미터 확인 후 재요청
401 인증 필요 토큰 갱신 후 재시도
403 권한 없음 접근 권한 확인
404 리소스 없음 UI에 없음 표시
429 Rate Limit 초과 백오프 후 재시도
500 서버 에러 재시도 또는 에러 UI 표시

문서 및 헬스체크

1. OpenAPI 스키마

GET /ai/schema/

OpenAPI 3.0 JSON 스키마 반환. DRF Spectacular 자동 생성.


2. Swagger UI

GET /ai/docs/

브라우저에서 API 테스트 가능한 Swagger UI.


3. ReDoc UI

GET /ai/redoc/

읽기 전용 API 문서 뷰.


4. Health Check

서버 상태 및 외부 AI 서비스 연결 가능 여부를 확인한다.

GET /ai/health/

인증: 불필요

응답 예시:

{
  "status": "ok",
  "version": "1.0.0",
  "services": {
    "gemini": true,
    "tavily": true,
    "exa": true,
    "graph_rag": true,
    "semantic_cache": true
  },
  "timestamp": "2026-04-07T12:00:00.000000"
}
필드 타입 설명
status string "ok" 또는 "error"
version string API 버전
services Record<string, boolean> 각 서비스 가용 여부
timestamp string 체크 시각 (ISO 8601)

프론트 활용: 앱 시작 시 서비스 가용성을 체크하여, 특정 AI 기능 버튼을 비활성화할 수 있다.


5. Demo (통합 데모)

모든 AI 기능을 한 번에 호출하여 통합 결과를 반환한다. 개발 중 대시보드 UI의 샘플 데이터를 확인할 때 유용하다.

GET /ai/demo

인증: 선택

Query Parameters:

파라미터 타입 기본값 설명
roadmap_id string "rm_frontend" 로드맵 ID
tech_slug string "react" 기술 카드 슬러그
user_id string "user_1" 사용자 ID
question string (예시 포함) 질문/검색 문장
goal string - 로드맵 생성 목표
target_role string - 추천 대상 역할
compose_level "quick" | "full" "quick" 답변 상세 수준
include_rationale boolean false 태그 rationale 포함 여부

응답 예시 (축약):

{
  "meta": {
    "generated_at": "2026-04-07T00:00:00Z",
    "roadmap_id": "rm_frontend",
    "tech_slug": "react",
    "user_id": "user_1",
    "compose_level": "quick"
  },
  "record_coach": { "record_id": "rec1", "scores": { "quality_score": 68 } },
  "related_roadmaps": { "roadmap_id": "rm_frontend", "candidates": [] },
  "tech_card": { "name": "react", "summary": "..." },
  "tech_fingerprint": { "roadmap_id": "rm_frontend", "tags": [] },
  "comment_digest": { "highlights": [], "bottlenecks": [] },
  "duplicate_suggest": [],
  "resource_recommendation": { "query": "...", "items": [] },
  "learning_pattern": { "patterns": { "active_days": 5 } },
  "graph_rag_context": { "retrieval_evidence": [] },
  "roadmap_generated": { "nodes": [], "edges": [] },
  "roadmap_recommendation": { "nodes": [] },
  "learning_coach": { "answer": "..." }
}

학습 코치 API

6. Record Coach (학습 기록 피드백)

학습 기록을 루브릭으로 점수화하고, 개선 포인트와 수정 제안을 제공한다.

GET /ai/record-coach

인증: 선택 (토큰의 roadmapId로 자동 스코핑)

Query Parameters:

파라미터 타입 필수 설명
roadmap_id string O 로드맵 ID
node_id string X 특정 노드 ID
compose_level "quick" | "full" X quick: 점수/질문 중심, full: LLM 문장화 포함

응답 예시:

{
  "record_id": "rec1",
  "model_version": "rule-based",
  "prompt_version": "coach_v1",
  "created_at": "2026-04-07T12:00:00Z",
  "scores": {
    "evidence_level": 3,
    "structure_score": 75,
    "specificity_score": 45,
    "reproducibility_score": 100,
    "quality_score": 68
  },
  "strengths": [
    "링크 기반 근거가 있어 신뢰도가 높다",
    "목표/문제/해결 구조가 일정 부분 보인다",
    "재현 가능한 링크가 포함되어 있다"
  ],
  "gaps": ["구체적인 수치나 에러 메시지가 부족하다"],
  "rewrite_suggestions": {
    "portfolio_bullets": ["React 컴포넌트 최적화를 통해 렌더링 성능 30% 개선"],
    "improved_memo": "useEffect 의존성 배열 최적화로 불필요한 리렌더 제거. Before: 12회/초 -> After: 2회/초"
  },
  "code_feedback": [],
  "next_actions": [{ "effort": "2h", "task": "에러 로그/수치 기록 및 원인 분석 추가" }],
  "followup_questions": ["어떤 에러가 발생했나요? 에러 메시지를 기록해 주세요."],
  "retrieval_evidence": [
    {
      "source": "tech_card",
      "id": "card_react",
      "snippet": "useEffect 의존성 배열 누락 시 무한 렌더 발생"
    }
  ]
}
필드 타입 설명
record_id string 기록 ID
model_version string 사용된 모델 버전
prompt_version string 프롬프트 버전
created_at string 생성 시각
scores.evidence_level integer 근거 수준 (0-5)
scores.structure_score integer 구조 점수 (0-100)
scores.specificity_score integer 구체성 점수 (0-100)
scores.reproducibility_score integer 재현 가능성 점수 (0-100)
scores.quality_score integer 종합 품질 점수 (0-100)
strengths string[] 장점 목록
gaps string[] 보완 필요 사항
rewrite_suggestions object 포트폴리오 문장/메모 개선안 (compose_level=full 시)
code_feedback array 코드 품질 피드백
next_actions { effort, task }[] 다음 행동 제안
followup_questions string[] 기록 보완 질문
retrieval_evidence RetrievalEvidence[] AI가 참조한 근거

프론트 활용: 학습 기록 작성 후 피드백 카드로 표시. scores로 레이더 차트를 그리면 시각적으로 효과적. compose_level=quick으로 빠른 피드백, full로 상세 개선안 제공.


7. Learning Coach (학습 코치 Q&A)

질문 의도 분류 -> 도구 실행 -> 답변 구성의 멀티스테이지 학습 코치.

GET /ai/learning-coach

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
question string O 사용자 질문
user_id string O 사용자 ID
compose_level "quick" | "full" X quick: 캐시/로컬 중심, full: LLM 정제 포함

응답 예시:

{
  "user_id": "user_1",
  "question": "React 상태관리 어떻게 하나요?",
  "intent": "concept",
  "toolchain": ["graph_explorer"],
  "plan": ["route", "retrieve", "compose"],
  "answer": "React 상태관리는 크게 로컬 상태(useState), 전역 상태(Zustand, Redux), 서버 상태(TanStack Query)로 나뉩니다. 프로젝트 규모에 따라 선택하세요.",
  "retrieval_evidence": [
    { "source": "graph", "id": "rm_react:node_state", "snippet": "상태관리 redux zustand" }
  ],
  "behavior_summary": {
    "motivation": 0.7,
    "ability": 0.6,
    "prompt_hour": 20,
    "dropout_risk": 0.01
  },
  "model_version": "coach_v1",
  "prompt_version": "coach_v1",
  "created_at": "2026-04-07T12:00:00Z",
  "cache_hit": false
}
필드 타입 설명
intent string 의도 분류 (concept, debug, recommendation 등)
toolchain string[] 실행된 도구 (graph_explorer, doc_retriever, progress_checker)
plan string[] 실행 계획 단계
answer string 최종 답변 텍스트
retrieval_evidence RetrievalEvidence[] 참조 근거
behavior_summary object Fogg B=MAP 행동 모델 분석
behavior_summary.motivation number 동기 수준 (0-1)
behavior_summary.ability number 능력 수준 (0-1)
behavior_summary.prompt_hour number 최적 학습 시간대
behavior_summary.dropout_risk number 이탈 위험도 (0-1)
cache_hit boolean 시맨틱 캐시 히트 여부

프론트 활용: 채팅 UI에서 사용. cache_hit=true이면 응답이 빠름을 UI에 표시 가능. behavior_summary.dropout_risk가 높으면 동기 부여 알림 표시.


8. Learning Pattern (학습 패턴 분석)

학습 이벤트 로그 기반으로 활동 패턴을 분석하고 개선 제안을 제공한다.

GET /ai/learning-pattern

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
user_id string O 사용자 ID
days integer X 분석 기간 (일, 기본 30)

응답 예시:

{
  "user_id": "user_1",
  "period": "last_30d",
  "patterns": {
    "active_days": 12,
    "avg_session_gap_days": 2.3,
    "completion_velocity": 0.4
  },
  "recommendations": [
    "현재 학습 패턴이 안정적입니다. 난이도를 조금 올려보세요",
    "주 3-4회 학습을 유지하면 완주율이 크게 높아집니다"
  ],
  "model_version": "pattern_v1",
  "generated_at": "2026-04-07T12:00:00Z"
}
필드 타입 설명
period string 분석 기간 (last_7d, last_30d 등)
patterns.active_days integer 활동 일수
patterns.avg_session_gap_days number 평균 세션 간격 (일)
patterns.completion_velocity number 완료 속도 (0-1)
recommendations string[] 개선 제안
model_version string 모델 버전
generated_at string 생성 시각

프론트 활용: 프로필/대시보드에서 학습 통계 카드로 표시. active_dayscompletion_velocity로 진행률 차트 렌더링.


로드맵 API

9. Related Roadmaps (관련 로드맵 추천)

행동/콘텐츠/그래프 유사도를 종합하여 연관 로드맵 후보를 반환한다.

GET /ai/related-roadmaps

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
roadmap_id string O 기준 로드맵 ID

응답 예시:

{
  "roadmap_id": "rm_frontend",
  "generated_at": "2026-04-07T12:00:00Z",
  "candidates": [
    {
      "related_roadmap_id": "rm_react",
      "score": 0.92,
      "reasons": [
        { "type": "co_complete", "value": 0.31 },
        { "type": "tag_overlap", "value": 4 }
      ]
    },
    {
      "related_roadmap_id": "rm_backend",
      "score": 0.53,
      "reasons": [{ "type": "tag_overlap", "value": 2 }]
    }
  ],
  "model_version": "ranker_v1",
  "evidence_snapshot": {
    "tracks": ["behavior", "content", "structure"],
    "candidate_count": 2
  }
}
필드 타입 설명
candidates[].related_roadmap_id string 추천 로드맵 ID
candidates[].score number 유사도 점수 (0-1)
candidates[].reasons { type, value }[] 추천 근거 (co_complete, tag_overlap 등)
evidence_snapshot object 랭킹 피처 스냅샷

프론트 활용: 로드맵 상세 페이지 하단에 "관련 로드맵" 섹션으로 표시. score 기준으로 정렬하여 카드 리스트 렌더링.


10. Roadmap Generated (AI 로드맵 생성)

목표와 선호 태그를 기반으로 로드맵을 자동 생성한다.

GET /ai/roadmap-generated

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
goal string O 목표 (예: "백엔드 개발자")
preferred_tags string X 선호 태그 (콤마 구분, 예: "python,django,docker")
max_nodes integer X 최대 노드 수
compose_level "quick" | "full" X quick: 규칙 기반, full: LLM 문장화 포함

응답 예시:

{
  "roadmap_id": "generated",
  "title": "백엔드 개발자 로드맵",
  "description": "Python과 Django를 중심으로 백엔드 개발 역량을 키우는 로드맵입니다.",
  "nodes": [
    { "node_id": "node_python", "title": "Python 기초", "tags": ["python", "basics"] },
    { "node_id": "node_django", "title": "Django 프레임워크", "tags": ["django", "web"] },
    { "node_id": "node_db", "title": "Database 설계", "tags": ["database", "sql"] },
    { "node_id": "node_api", "title": "REST API 설계", "tags": ["api", "rest"] },
    { "node_id": "node_deploy", "title": "Docker 배포", "tags": ["docker", "deploy"] }
  ],
  "edges": [
    { "source": "node_python", "target": "node_django" },
    { "source": "node_django", "target": "node_api" },
    { "source": "node_python", "target": "node_db" },
    { "source": "node_api", "target": "node_deploy" }
  ],
  "tags": ["python", "django", "backend"],
  "model_version": "generator_v1",
  "prompt_version": "gen_v1",
  "created_at": "2026-04-07T12:00:00Z",
  "retrieval_evidence": [
    { "source": "graph", "id": "rm_backend:node_python", "snippet": "Python 기초 문법과 자료구조" }
  ]
}
필드 타입 설명
roadmap_id string 항상 "generated" (아직 저장 전)
title string 생성된 로드맵 제목
description string 로드맵 설명
nodes { node_id, title, tags }[] 노드 목록
edges { source, target }[] 엣지 목록 (선후행 관계)
tags string[] 로드맵 태그
retrieval_evidence RetrievalEvidence[] 생성 시 참조한 근거

프론트 활용: "AI 로드맵 생성" 기능에서 nodesedges를 그래프로 렌더링. 사용자가 확인 후 로드맵 서비스에 저장하는 플로우로 구성.


11. Roadmap Recommendation (로드맵 추천)

목표 역할 기반으로 그래프 온톨로지에서 학습 순서를 추천한다.

GET /ai/roadmap-recommendation

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
target_role string O 목표 역할 (예: "frontend_dev")
user_id string X 사용자 ID

응답 예시:

{
  "roadmap_id": "roadmap:frontend_dev",
  "target_role": "frontend_dev",
  "nodes": [
    { "node_id": "node_html", "status": "COMPLETED" },
    { "node_id": "node_css", "status": "AVAILABLE" },
    { "node_id": "node_js", "status": "AVAILABLE" },
    { "node_id": "node_react", "status": "LOCKED" }
  ],
  "edges": [
    { "source": "node_html", "target": "node_css" },
    { "source": "node_css", "target": "node_js" },
    { "source": "node_js", "target": "node_react" }
  ],
  "gnn_predictions": {
    "node_html": ["node_css"],
    "node_css": ["node_js"],
    "node_js": ["node_react"]
  },
  "model_version": "gnn_v1",
  "created_at": "2026-04-07T12:00:00Z"
}
필드 타입 설명
target_role string 요청된 목표 역할
nodes[].status string COMPLETED, AVAILABLE, LOCKED, IN_PROGRESS, NEEDS_REVIEW
gnn_predictions Record<string, string[]> GNN 기반 다음 학습 후보 예측

프론트 활용: 온보딩 또는 "추천 학습 경로" 페이지에서 사용. status로 노드 색상 분기, gnn_predictions로 "다음 추천" 하이라이트.


12. Document Roadmap (문서 기반 로드맵 추천)

이력서/학습 계획서 등 문서를 분석하여 맞춤 학습 로드맵을 추천한다.

GET /ai/document-roadmap
POST /ai/document-roadmap

인증: 선택

GET (짧은 문서)

Query Parameters:

파라미터 타입 필수 설명
document string O 분석할 문서 내용
goal string X 목표 직군/분야 (예: "Backend Developer")

POST (긴 문서 권장)

Request Body:

{
  "document": "저는 Python과 Django를 1년간 공부했습니다. 백엔드 개발자로 취업하고 싶습니다.",
  "goal": "Backend Developer"
}

응답 예시 (GET/POST 동일):

{
  "document_summary": "Python/Django 1년 학습 경험 보유. 백엔드 개발자 취업 목표.",
  "extracted_keywords": ["python", "django", "백엔드"],
  "recommended_roadmaps": [
    { "related_roadmap_id": "rm_backend:node_api", "score": 0.95, "reasons": [] },
    { "related_roadmap_id": "rm_backend:node_db", "score": 0.85, "reasons": [] },
    { "related_roadmap_id": "rm_devops:node_docker", "score": 0.75, "reasons": [] }
  ],
  "suggested_topics": ["rest api", "database", "docker", "ci/cd", "testing"],
  "model_version": "doc_v1",
  "created_at": "2026-04-07T12:00:00Z"
}
필드 타입 설명
document_summary string AI 문서 요약
extracted_keywords string[] 추출된 핵심 키워드
recommended_roadmaps RelatedRoadmapCandidate[] 추천 로드맵 목록 (ID + 점수)
suggested_topics string[] 후속 학습 추천 주제

프론트 활용: 문서(이력서) 업로드 -> 분석 결과로 맞춤 로드맵 추천. suggested_topics로 태그 선택 UI 연계.


기술 카드 API

13. Tech Cards (기술 카드)

기술의 요약/사용 시점/대안/주의사항/학습 경로를 카드 형태로 제공한다.

GET /ai/tech-cards

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
tech_slug string O 기술 슬러그 (예: "react", "django", "docker")

응답 예시:

{
  "id": "card_react",
  "name": "react",
  "tech_slug": "react",
  "category": "tech",
  "version": "2026-04",
  "summary": "Facebook이 개발한 UI 라이브러리. 컴포넌트 기반 아키텍처로 복잡한 UI를 선언적으로 구성.",
  "summary_vector": [0.12, 0.34, 0.56],
  "why_it_matters": [
    "업계 표준에 가까운 사용 사례를 확보할 수 있다",
    "방대한 생태계와 커뮤니티 지원"
  ],
  "when_to_use": [
    "UI/서비스의 구조를 빠르게 확장해야 할 때",
    "SPA 또는 SSR이 필요한 웹 애플리케이션"
  ],
  "alternatives": [
    { "slug": "vue", "why": "학습 난이도가 낮고 템플릿 기반" },
    { "slug": "svelte", "why": "번들 크기가 작고 빌드 타임 컴파일" }
  ],
  "pitfalls": [
    "의존성 배열을 누락해 무한 렌더가 발생하는 케이스가 많다",
    "과도한 상태 리프팅은 성능 저하를 유발한다"
  ],
  "learning_path": [
    { "stage": "basic", "items": ["JSX 문법", "컴포넌트 props/state"] },
    { "stage": "intermediate", "items": ["Hooks (useEffect, useMemo)", "Context API"] },
    { "stage": "advanced", "items": ["Server Components", "Concurrent Features"] }
  ],
  "metadata": {
    "language": "JavaScript/TypeScript",
    "license": "MIT",
    "latest_version": "19.1.0",
    "last_updated": "2026-03"
  },
  "relationships": {
    "based_on": ["javascript"],
    "alternatives": ["vue", "svelte", "angular"]
  },
  "reliability_metrics": {
    "community_score": 95,
    "doc_freshness": 90,
    "source_count": 12
  },
  "latest_changes": {
    "changed": true,
    "change_ratio": 0.15,
    "summary": "React 19 Server Actions 추가"
  },
  "reel_evidence": [{ "query": "license", "snippet": "MIT License" }],
  "sources": [
    { "title": "React 공식 문서", "url": "https://react.dev", "fetched_at": "2026-04-01T00:00:00Z" }
  ],
  "generated_by": {
    "model_version": "card_v1",
    "prompt_version": "card_v1"
  }
}
필드 타입 설명
id string 카드 고유 ID
name string 기술명
tech_slug string 슬러그
summary string 기술 요약
why_it_matters string[] 왜 중요한지
when_to_use string[] 언제 사용하는지
alternatives { slug, why }[] 대안 기술
pitfalls string[] 주의사항
learning_path { stage, items }[] 단계별 학습 경로
metadata object 언어/라이선스/최신 버전
relationships object 기반 기술/대안 관계
reliability_metrics object 커뮤니티 점수/문서 최신성/소스 수
latest_changes object 최근 변경 여부/비율/요약
sources { title, url, fetched_at }[] 출처

프론트 활용: 노드 클릭 시 기술 카드 모달/패널로 표시. learning_path로 "학습 순서" 스텝퍼 구현. alternatives로 "대안 기술 보기" 링크.


14. Tech Fingerprint (기술 핑거프린트 자동 태깅)

로드맵 텍스트에서 핵심 기술을 추출하여 core/optional/alternative/deprecated로 분류한다.

GET /ai/tech-fingerprint

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
roadmap_id string O 로드맵 ID
include_rationale boolean X true 시 분류 근거 포함

응답 예시:

{
  "roadmap_id": "rm_frontend",
  "tags": [
    {
      "tech_slug": "react",
      "type": "core",
      "confidence": 0.95,
      "rationale": "로드맵의 핵심 주제로, 5개 이상의 노드에서 직접 언급"
    },
    {
      "tech_slug": "zustand",
      "type": "alternative",
      "confidence": 0.72,
      "rationale": "상태관리 대안으로 1개 노드에서 언급"
    },
    {
      "tech_slug": "jquery",
      "type": "deprecated",
      "confidence": 0.88,
      "rationale": "현대 프레임워크 대비 사용이 권장되지 않음"
    }
  ],
  "generated_at": "2026-04-07T12:00:00Z",
  "model_version": "tagger_v1"
}
필드 타입 설명
tags[].tech_slug string 기술 슬러그
tags[].type string core, optional, alternative, deprecated
tags[].confidence number 신뢰도 (0-1)
tags[].rationale string? 분류 근거 (include_rationale=true 시)

프론트 활용: 로드맵 편집 페이지에서 자동 태그 제안. type 기준으로 태그 색상 분기 (core=파랑, deprecated=빨강 등).


댓글 인텔리전스 API

15. Comment Digest (댓글 요약)

최근 댓글에서 주요 이슈와 병목 노드를 요약한다.

GET /ai/comment-digest

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
roadmap_id string O 로드맵 ID
period_days integer X 분석 기간 (일, 기본 14)

응답 예시:

{
  "roadmap_id": "rm_frontend",
  "period": "last_14d",
  "highlights": [
    "useEffect에서 의존성 배열을 비우면 렌더가 반복돼요",
    "JS async/await 에러 처리를 어떻게 정리하나요?",
    "CSS Grid와 Flexbox 차이가 헷갈립니다"
  ],
  "bottlenecks": [
    {
      "node_id": "node_js",
      "score": 1.0,
      "top_topics": ["질문 빈도 증가", "에러 처리 반복 질문"]
    },
    {
      "node_id": "node_css",
      "score": 0.65,
      "top_topics": ["레이아웃 혼란"]
    }
  ],
  "generated_by": {
    "model_version": "digest_v1",
    "prompt_version": null
  }
}
필드 타입 설명
highlights string[] 주요 이슈 문장
bottlenecks object[] 병목 노드 (질문 수/부정 반응/미해결 비율 기반)
bottlenecks[].node_id string 병목 노드 ID
bottlenecks[].score number 병목 점수 (0-1, 높을수록 심각)
bottlenecks[].top_topics string[] 주요 토픽

프론트 활용: 로드맵 관리자 대시보드에서 병목 노드 하이라이트. score가 높은 노드에 경고 아이콘 표시. highlights를 "이번 주 주요 질문" 섹션으로 표시.


16. Comment Duplicates (중복 질문 탐지)

질문 작성 시 유사한 기존 질문을 추천한다. LLM 없이 벡터 유사도 기반으로 빠르게 동작.

GET /ai/comment-duplicates

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
roadmap_id string O 로드맵 ID
question string O 작성 중인 질문
top_k integer X 추천 개수 (기본 5)

응답 예시:

[
  {
    "comment_id": "c2",
    "snippet": "JS async/await 에러 처리를 어떻게 정리하나요?"
  },
  {
    "comment_id": "c1",
    "snippet": "useEffect에서 의존성 배열을 비우면 렌더가 반복돼요"
  }
]
필드 타입 설명
comment_id string 기존 댓글 ID
snippet string 유사 질문 내용

프론트 활용: 댓글 작성 폼에서 입력 중 debounce(300ms)로 호출. "이미 비슷한 질문이 있어요" 팝오버로 중복 질문 방지.


검색 및 추천 API

17. Resource Recommendation (학습 자원 추천)

로컬 지식베이스(BM25/Vector)와 웹 검색 결과를 결합한 하이브리드 추천.

GET /ai/resource-recommendation

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
query string O 검색 질의 (예: "React hooks 상태 관리")
top_k integer X 추천 개수 (기본 3)
recency_days integer X 최신 자료 기준 기간 (기본 30, 0이면 제한 없음)

응답 예시:

{
  "query": "React hooks 상태 관리",
  "generated_at": "2026-04-07T12:00:00Z",
  "items": [
    {
      "title": "React 공식 문서 - useState",
      "url": "https://react.dev/reference/react/useState",
      "source": "web",
      "score": 0.95
    },
    {
      "title": "Zustand로 간단한 상태 관리",
      "url": "https://zustand-demo.pmnd.rs/",
      "source": "web",
      "score": 0.87
    },
    {
      "title": "커뮤니티 추천: React 상태 관리 비교",
      "url": "https://example.com/react-state",
      "source": "resource",
      "score": 0.82
    }
  ],
  "model_version": "retriever_v1",
  "retrieval_evidence": [
    {
      "source": "resource",
      "id": "res_react_hooks",
      "snippet": "useState와 useReducer의 차이점..."
    }
  ]
}
필드 타입 설명
items[].title string 자료 제목
items[].url string 자료 URL
items[].source string 출처 (web, resource, internal)
items[].score number 관련성 점수 (0-1)
retrieval_evidence RetrievalEvidence[] 추천 근거

프론트 활용: 노드 상세 패널의 "추천 자료" 섹션. recency_days를 줄여 최신 자료 우선 표시. score로 추천 순위 표시.


18. Web Search (웹 검색)

Tavily(웹 검색) + Exa(시맨틱 검색)을 조합한 실시간 웹 검색.

GET /ai/web-search

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
query string O 검색 쿼리 (예: "Python 비동기 프로그래밍")
top_k integer X 최대 결과 수 (기본 5, 최대 20)
engine "tavily" | "exa" | "all" X 사용할 검색 엔진 (기본 "all")
recency_days integer X 최신 자료 기준 기간 (기본 30, 0이면 제한 없음)

응답 예시:

{
  "query": "Django tutorial 2026",
  "results": [
    {
      "title": "Django Girls Tutorial",
      "url": "https://tutorial.djangogirls.org/en/",
      "content": "Django를 사용하여 블로그 웹사이트를 만드는 단계별 가이드...",
      "score": 0.9998,
      "source": "tavily",
      "fetched_at": "2026-04-07T12:00:00Z"
    },
    {
      "title": "Getting started with Django",
      "url": "https://www.djangoproject.com/start/",
      "content": "Django 공식 시작 가이드. 설치부터 첫 앱 만들기까지...",
      "score": 0.9995,
      "source": "exa",
      "fetched_at": "2026-04-07T12:00:00Z"
    }
  ],
  "engines_used": ["tavily", "exa"],
  "total_results": 2,
  "generated_at": "2026-04-07T12:00:00Z"
}
필드 타입 설명
results[].title string 검색 결과 제목
results[].url string 검색 결과 URL
results[].content string 내용 요약
results[].score number 관련성 점수 (0-1)
results[].source string 출처 엔진 (tavily 또는 exa)
results[].fetched_at string 검색 수행 시각
engines_used string[] 실제 사용된 엔진 목록
total_results integer 총 결과 수

프론트 활용: 검색 결과 페이지 또는 "자료 찾기" 모달에서 사용. 최신성이 중요하면 recency_days=7, 다양성이 중요하면 engine=all 사용.


19. Graph RAG (그래프 RAG 컨텍스트 검색)

그래프 기반 RAG 검색 결과를 반환한다. 근거 스니펫과 그래프 스냅샷을 함께 제공.

GET /ai/graph-rag

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
query string O 검색 질의
top_k integer X 근거 개수

응답 예시:

{
  "retrieval_evidence": [
    {
      "source": "graph",
      "id": "rm_frontend:node_html",
      "snippet": "HTML 구조와 시맨틱 태그"
    },
    {
      "source": "graph",
      "id": "rm_react:node_state",
      "snippet": "상태관리 redux zustand"
    }
  ],
  "graph_snapshot": {
    "nodes": [
      { "node_id": "rm_frontend:node_html", "text": "HTML 구조", "tags": ["html"] },
      { "node_id": "rm_react:node_state", "text": "상태관리", "tags": ["redux", "zustand"] }
    ],
    "edges": [
      {
        "source": "rm_frontend:node_html",
        "target": "rm_frontend:node_css",
        "type": "prerequisite"
      }
    ]
  }
}
필드 타입 설명
retrieval_evidence RetrievalEvidence[] 근거 스니펫 목록
graph_snapshot.nodes { node_id, text, tags }[] 관련 그래프 노드
graph_snapshot.edges { source, target, type? }[] 관련 그래프 엣지

프론트 활용: 다른 AI 응답의 retrieval_evidence를 "근거 보기"로 확장할 때 사용. 그래프 시각화로 관련 노드 간 관계를 보여줄 수 있다.


Init Data 관리 API

로드맵 생성을 위한 초기 데이터(파일/텍스트)를 관리하는 CRUD API.

20. Init Data 목록 조회

GET /ai/init-data

인증: 선택 (토큰의 roadmapId로 자동 스코핑)

Query Parameters:

파라미터 타입 필수 설명
roadmap_id string O 로드맵 ID (미지정 시 토큰의 roadmapId 사용)

응답 예시:

[
  {
    "init_data_id": "init_a1b2c3d4",
    "roadmap_id": "rm_frontend",
    "content": "React는 Facebook에서 개발한 UI 라이브러리로...",
    "data_type": "text",
    "filename": null,
    "created_at": "2026-04-07T10:00:00Z",
    "updated_at": "2026-04-07T10:00:00Z"
  },
  {
    "init_data_id": "init_e5f6g7h8",
    "roadmap_id": "rm_frontend",
    "content": "# Frontend Roadmap\n## HTML/CSS\n...",
    "data_type": "file",
    "filename": "frontend-roadmap.md",
    "created_at": "2026-04-06T09:00:00Z",
    "updated_at": "2026-04-06T09:00:00Z"
  }
]

21. Init Data 생성

POST /ai/init-data

인증: 선택

Request Body:

{
  "roadmap_id": "rm_frontend",
  "content": "React 컴포넌트 설계 가이드...",
  "data_type": "text",
  "filename": null
}
필드 타입 필수 설명
roadmap_id string X 로드맵 ID (미지정 시 토큰 roadmapId)
content string O 데이터 내용
data_type "file" | "text" X 데이터 타입 (기본 "text")
filename string? X 파일명 (file 타입일 때)

응답: 201 Created

{
  "init_data_id": "init_x9y0z1w2",
  "roadmap_id": "rm_frontend",
  "content": "React 컴포넌트 설계 가이드...",
  "data_type": "text",
  "filename": null,
  "created_at": "2026-04-07T12:00:00Z",
  "updated_at": "2026-04-07T12:00:00Z"
}

22. Init Data 상세 조회

GET /ai/init-data/{init_data_id}

인증: 선택

Path Parameters:

파라미터 타입 설명
init_data_id string Init Data ID (예: init_a1b2c3d4)

응답: InitData 객체 (목록 조회와 동일 형태)

404 응답:

{ "error": "Not found" }

23. Init Data 수정

PUT /ai/init-data/{init_data_id}

인증: 선택

Request Body:

{
  "content": "수정된 내용..."
}
필드 타입 필수 설명
content string O 수정할 내용

응답: 200 OK, 수정된 InitData 객체


24. Init Data 삭제

DELETE /ai/init-data/{init_data_id}

인증: 선택

응답: 204 No Content (body 없음)


Init Data 모델

필드 타입 설명
init_data_id string 고유 ID (자동 생성, init_ 접두사)
roadmap_id string 관련 로드맵 ID
content string 데이터 내용
data_type "file" | "text" 데이터 타입
filename string? 파일명 (file 타입일 때)
created_at string 생성 시각 (ISO 8601)
updated_at string 수정 시각 (ISO 8601)

노드 콘텐츠 생성 API

25. Node Generation (Init 데이터 기반 노드 생성)

Init 데이터를 분석하여 로드맵 노드를 자동 생성한다.

GET /ai/node-generation

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
init_data_id string O Init Data ID

응답 예시 (RoadmapGenerated 형태):

{
  "roadmap_id": "generated",
  "title": "Init 데이터 기반 생성 로드맵",
  "description": "업로드된 데이터를 분석하여 생성된 노드 구조입니다.",
  "nodes": [
    { "node_id": "node_1", "title": "HTML 기초", "tags": ["html"] },
    { "node_id": "node_2", "title": "CSS 레이아웃", "tags": ["css", "layout"] },
    { "node_id": "node_3", "title": "JavaScript 기본", "tags": ["javascript"] }
  ],
  "edges": [
    { "source": "node_1", "target": "node_2" },
    { "source": "node_2", "target": "node_3" }
  ],
  "tags": ["frontend", "web"],
  "model_version": "gen_v1",
  "prompt_version": "gen_v1",
  "created_at": "2026-04-07T12:00:00Z",
  "retrieval_evidence": []
}

에러 응답 (404):

{ "error": "Init data not found: init_invalid_id" }

프론트 활용: Init 데이터 업로드 후 "노드 생성" 버튼 클릭 시 호출. 결과를 그래프 에디터에 프리로드.


26. Node Description (AI 노드 설명 생성)

노드 제목으로부터 AI가 설명을 생성한다.

GET /ai/node-description

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
node_title string O 노드 제목 (예: "React Hooks")
context string X 추가 컨텍스트 (로드맵 제목 등)

응답 예시:

{
  "node_title": "React Hooks",
  "description": "React 16.8에서 도입된 함수형 컴포넌트에서 상태와 라이프사이클을 관리하는 기능입니다. useState, useEffect, useContext 등의 내장 훅을 제공하며, 커스텀 훅을 통해 로직 재사용이 가능합니다.",
  "generated_at": "2026-04-07T12:00:00Z"
}
필드 타입 설명
node_title string 요청한 노드 제목
description string AI 생성 설명
generated_at string 생성 시각

프론트 활용: 노드 편집 시 "AI 설명 생성" 버튼으로 사용. 생성된 텍스트를 설명 필드에 자동 입력.


27. Node Resource Recommendation (노드별 자원 추천)

특정 노드 주제에 대한 학습 자료를 추천한다.

GET /ai/node-resource-recommendation

인증: 선택

Query Parameters:

파라미터 타입 필수 설명
node_id string O 노드 ID
roadmap_id string X 로드맵 ID (미지정 시 토큰 roadmapId)

응답 예시 (ResourceRecommendation 형태):

{
  "query": "React Hooks 학습 자료",
  "generated_at": "2026-04-07T12:00:00Z",
  "items": [
    {
      "title": "React 공식 문서 - Hooks",
      "url": "https://react.dev/reference/react/hooks",
      "source": "web",
      "score": 0.96
    },
    {
      "title": "useHooks - Custom Hook 레시피 모음",
      "url": "https://usehooks.com",
      "source": "web",
      "score": 0.88
    }
  ],
  "model_version": "retriever_v1",
  "retrieval_evidence": []
}

프론트 활용: 노드 상세 패널에서 "추천 자료" 탭으로 표시. 추천 결과에서 "저장" 버튼을 누르면 node-resource-save를 호출.


28. Node Resource Save (추천 자원 저장)

추천된 학습 자료를 노드에 저장한다.

POST /ai/node-resource-save

인증: 선택

Request Body:

{
  "node_id": "node_react_hooks",
  "title": "React 공식 문서 - Hooks",
  "url": "https://react.dev/reference/react/hooks",
  "source": "web",
  "description": "React 공식 Hooks API 레퍼런스"
}
필드 타입 필수 설명
node_id string O 노드 ID
title string O 자료 제목
url string O 자료 URL
source "web" | "internal" | "generated" X 출처 (기본 "web")
description string? X 자료 설명

응답: 201 Created

{
  "resource_id": "nr_a1b2c3d4",
  "node_id": "node_react_hooks",
  "title": "React 공식 문서 - Hooks",
  "url": "https://react.dev/reference/react/hooks",
  "source": "web",
  "description": "React 공식 Hooks API 레퍼런스",
  "created_at": "2026-04-07T12:00:00Z"
}

Node Resource 모델

필드 타입 설명
resource_id string 고유 ID (자동 생성, nr_ 접두사)
node_id string 관련 노드 ID
title string 자료 제목
url string 자료 URL
source "web" | "internal" | "generated" 출처
description string? 자료 설명
created_at string 생성 시각 (ISO 8601)

프론트엔드 통합 가이드

공통 타입 (TypeScript)

/** AI가 참조한 근거 */
interface RetrievalEvidence {
  source: string;
  id: string;
  snippet: string;
}

/** 에러 응답 */
interface AIErrorResponse {
  error: string;
}

/** Rate Limit 초과 시 */
interface RateLimitError {
  detail: string;
}

API 클라이언트 예시

const AI_BASE_URL = process.env.NEXT_PUBLIC_AI_URL ?? 'http://localhost:8000';

async function fetchAI<T>(
  path: string,
  params?: Record<string, string | number | boolean>,
  options?: { method?: string; body?: unknown },
): Promise<T> {
  const url = new URL(`/ai/${path}`, AI_BASE_URL);
  if (params) {
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== null) {
        url.searchParams.set(key, String(value));
      }
    });
  }

  const token = getAccessToken(); // 프로젝트의 토큰 관리 방식에 맞게

  const res = await fetch(url.toString(), {
    method: options?.method ?? 'GET',
    headers: {
      'Content-Type': 'application/json',
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
    ...(options?.body ? { body: JSON.stringify(options.body) } : {}),
  });

  if (res.status === 429) {
    throw new Error('Rate limit exceeded. 잠시 후 다시 시도하세요.');
  }

  if (!res.ok) {
    const err = await res.json().catch(() => ({ error: 'Unknown error' }));
    throw new Error(err.error ?? `HTTP ${res.status}`);
  }

  if (res.status === 204) return undefined as T;
  return res.json();
}

TanStack Query 연동 예시

// 학습 코치 Q&A
function useLearningCoach(question: string, userId: string) {
  return useQuery({
    queryKey: ['ai', 'learning-coach', question, userId],
    queryFn: () =>
      fetchAI<LearningCoachResponse>('learning-coach', {
        question,
        user_id: userId,
      }),
    enabled: !!question && !!userId,
    staleTime: 5 * 60 * 1000, // 캐시 히트가 있으므로 5분
  });
}

// 기술 카드
function useTechCard(techSlug: string) {
  return useQuery({
    queryKey: ['ai', 'tech-cards', techSlug],
    queryFn: () => fetchAI<TechCardResponse>('tech-cards', { tech_slug: techSlug }),
    enabled: !!techSlug,
    staleTime: 30 * 60 * 1000, // 카드는 잘 안 바뀌므로 30분
  });
}

// Init Data CRUD
function useCreateInitData() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateInitDataRequest) =>
      fetchAI<InitDataResponse>('init-data', undefined, {
        method: 'POST',
        body: data,
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['ai', 'init-data'] });
    },
  });
}

로딩 상태 처리

AI 엔드포인트는 처리 시간이 길 수 있다 (특히 compose_level=full). 프론트에서 적절한 로딩 UI를 반드시 구현할 것.

엔드포인트 예상 응답 시간 권장 로딩 UI
health < 1초 불필요
comment-duplicates < 1초 인라인 스피너
tech-fingerprint 1-3초 스켈레톤
record-coach (quick) 1-3초 스켈레톤
learning-coach (quick) 2-5초 채팅 타이핑 인디케이터
roadmap-generated 3-10초 프로그레스 바 + 메시지
tech-cards 3-10초 카드 스켈레톤
web-search 2-5초 검색 중 스피너
learning-coach (full) 5-15초 단계별 프로그레스

429 Rate Limit 대응

async function fetchWithRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (err) {
      if (err instanceof Error && err.message.includes('Rate limit') && i < maxRetries - 1) {
        await new Promise((r) => setTimeout(r, 2000 * (i + 1))); // 지수 백오프
        continue;
      }
      throw err;
    }
  }
  throw new Error('Max retries exceeded');
}

공통 응답 필드 참고

많은 AI 응답에 포함되는 공통 필드:

필드 설명 프론트 활용
retrieval_evidence AI가 참조한 근거 소스 "출처 보기" 토글로 투명성 제공
model_version 사용된 AI 모델 버전 디버깅/로깅용
prompt_version 프롬프트 버전 디버깅/로깅용
generated_at / created_at 결과 생성 시각 "N분 전 생성" 표시
cache_hit 캐시 재사용 여부 빠른 응답 표시