사용자의 정보를 무조건 AI에 전달하는 것이 아니라, 질문에 필요한 맥락만 추천하고 사용자가 직접 승인한 정보만 활용하는 사용자 통제형 AI 서비스입니다.
일반적인 생성형 AI는 사용자의 상황과 제약을 충분히 알지 못해 매번 같은 설명을 반복하게 하거나, 반대로 너무 많은 개인정보를 한꺼번에 사용하게 만들 수 있습니다.
Context Bridge는 다음 문제를 해결하는 것을 목표로 합니다.
- 사용자가 자신의 정보를 매번 반복해서 설명해야 하는 문제
- 질문과 관련 없는 개인정보까지 AI에 전달될 수 있는 문제
- 고령층과 AI 초보자가 복잡한 설정을 이해하기 어려운 문제
- AI가 저장한 정보가 언제, 어떻게 사용되는지 알기 어려운 문제
질문이 입력되면 전체 사용자 정보를 그대로 보내지 않고 다음 흐름으로 처리합니다.
사용자 질문
→ 질문 의도 및 결정 영역 분석
→ 관련 맥락 후보 추천
→ 민감도·최신성·충돌 검사
→ 사용자 승인 또는 거절
→ 승인된 맥락만 AI에 전달
→ 개인화 답변 생성
→ 새 정보 저장 여부를 다시 사용자에게 확인
- 사용자가 승인한 정보만 최종 생성 모델에 전달합니다.
- 거절한 카드의 값, 제목, ID, 존재 여부를 프롬프트와 로그에 포함하지 않습니다.
- 민감정보는 기본 선택 해제 상태로 제공하고 사용자가 직접 승인하도록 합니다.
- 기밀정보는 모델에 전달되지 않도록 차단합니다.
- 모든 제약을 무조건 적용하지 않고 현재 질문과 관련된 제약만 검사합니다.
- 오래된 정보, 현재 질문과 프로필의 충돌, 카드 간 모순을 검사합니다.
- 생성된 답변을 다시 검증해 개인정보 노출과 필수 제약 위반을 확인합니다.
- 답변에서 발견된 새 정보는 자동 저장하지 않고 사용자 승인 후에만 저장합니다.
사용자의 질문을 분석해 답변에 필요한 정보만 후보 카드로 추천합니다.
사용자는 추천된 카드 중 사용할 정보만 직접 선택할 수 있습니다.
답변 중 새롭게 확인된 정보는 자동 저장하지 않고 저장 또는 무시를 선택하게 합니다.
사용자는 목적에 따라 여러 프로필을 만들고 선택할 수 있습니다.
예시:
- 대학생 프로필
- 시니어 프로필
- 취업 준비 프로필
- 여행 프로필
사용자 정보는 이해하기 쉬운 네 가지 기준으로 관리합니다.
- 기본정보
- 취향과 원하는 방향
- 목표와 목적
- 꼭 지켜야 할 주의사항과 제약
- 큰 글씨와 명확한 버튼
- 음성 입력
- 답변 읽어주기
- 특수문자를 자연스럽게 제외한 음성 읽기
- 고령층과 AI 초보자를 고려한 간단한 승인 흐름
기존의 복잡한 설정 화면보다 채팅을 중심으로 설계했습니다.
프로필 선택
→ 질문 입력
→ 필요한 맥락 확인
→ 사용할 정보 승인
→ 답변 확인
→ 새 정보 저장 여부 선택
주요 UX 원칙은 다음과 같습니다.
- 처음 사용하는 사람도 설명 없이 사용할 수 있어야 합니다.
- 한 화면에서 너무 많은 선택지를 보여주지 않습니다.
- 전문 용어보다 사용자가 이해할 수 있는 표현을 사용합니다.
- 승인, 거절, 저장, 무시 상태가 명확하게 보여야 합니다.
- 기능이 UI에 가려지지 않도록 핵심 흐름을 우선합니다.
담당: 전이현
주요 역할:
- 서비스 아이디어 및 문제 정의
- 핵심 사용자와 사용 시나리오 설계
- 기능 우선순위와 프로젝트 방향 결정
- 발표 및 서비스 전달 구조 기획
- 팀원 간 요구사항 정리와 역할 조율
담당: 종현
주요 역할:
- 채팅 중심 UI
- 프로필 선택 및 수정 화면
- 맥락 추천 카드와 승인 UI
- 접근성 설정
- 질문 히스토리와 음성 기능
- API 연동
담당: 강도원
주요 역할:
- 질문 의도 분석
- 관련 맥락 후보 생성
- 의미 기반 맥락 선별
- 민감정보 및 기밀정보 필터링
- 승인된 맥락만 전달하는 생성 흐름
- 답변 후 검증
- 승인 기반 기억 저장
- Supabase 데이터 및 권한 관리
- API 계약, 테스트, 배포 환경 구성
프론트엔드와 백엔드가 동시에 개발할 수 있도록 API 계약을 먼저 정의했습니다.
주요 공유 파일:
contracts/
docs/FRONTEND_HANDOFF.md
src/types.ts
mock-server.mjs
.env.example
프론트엔드는 Mock API로 먼저 개발하고, 이후 실제 백엔드 API 주소로 교체할 수 있도록 구성합니다.
- React
- TypeScript
- Vite
- 접근성 중심 UI
- Web Speech API 기반 음성 기능
- Node.js
- TypeScript
- 질문 분석 및 맥락 선택 파이프라인
- 생성 모델 연동
- 답변 안전성 검증
- Supabase
- Row Level Security
- Vercel
- GitHub
- 환경변수 기반 설정
전체 사용자 카드
→ 질문 관련 후보 검색
→ 의미 관련성 평가
→ 정책 및 안전성 검사
→ 사용자 승인
→ 승인 카드만 별도 객체로 구성
→ 생성 모델 호출
→ 출력 검증
생성 모델에는 전체 프로필이 아니라 승인된 최소 정보만 전달합니다.
POST /api/proposals
질문에 필요한 맥락 후보 생성
POST /api/approvals
사용자가 승인한 맥락 확정
POST /api/generate
승인된 맥락만 사용해 답변 생성
POST /api/memory-suggestions
답변에서 새롭게 발견된 저장 후보 제안
POST /api/memories
사용자가 승인한 정보만 저장
실제 API 이름과 요청 형식은 contracts 및 프론트 전달 문서를 기준으로 관리합니다.
초기 버전에서는 태그와 고정된 의도 분류에 크게 의존해 새로 추가한 사용자 카드가 추천되지 않는 문제가 있었습니다.
이를 다음과 같이 개선했습니다.
- 하드코딩된 태그 의존도 축소
- 사용자 정의 카드 지원
- 질문과 카드의 의미 기반 관련성 평가
- 최근 정보와 오래된 정보 구분
- 카드 간 충돌 검사
- 질문과 프로필 정보의 모순 검사
- 관련 없는
hard_limit자동 제외 - 승인 전후 데이터 흐름 분리
- 답변 후 개인정보 및 제약 위반 재검증
- 자동 저장 제거 및 승인 기반 저장 적용
- 복잡한 대시보드형 UI에서 채팅 중심 UI로 변경
- 고령층도 사용할 수 있도록 승인 단계를 단순화
현재 프로젝트는 다음 핵심 흐름을 우선 검증합니다.
계정 생성
→ 프로필 선택
→ 질문 입력
→ 맥락 추천
→ 승인 및 거절
→ 승인 맥락 기반 답변
→ 답변 검증
→ 기억 저장 승인
필수 테스트 항목:
- 거절한 맥락이 모델 입력에 포함되지 않는지
- 승인한 맥락만 답변에 반영되는지
- 다른 사용자의 프로필에 접근할 수 없는지
- 기밀정보가 차단되는지
- 관련 없는 제약이 적용되지 않는지
- 오래된 정보와 충돌 정보가 표시되는지
- 저장하지 않은 새 정보가 DB에 남지 않는지
- 음성 입력과 답변 읽기가 정상 작동하는지
Context Bridge의 목표는 단순한 개인화 챗봇이 아닙니다.
사용자가 자신의 정보를 통제하면서도 AI의 도움을 더 쉽게 받을 수 있도록 만드는 것이 핵심입니다.
필요한 정보만, 사용자가 확인한 뒤, 안전하게 AI와 연결합니다.
프로젝트는 기능을 한꺼번에 구현하기보다 아래 순서대로 진행합니다.
먼저 기획, 프론트엔드, 백엔드가 공통으로 사용할 용어와 데이터 구조를 확정합니다.
확정해야 할 핵심 항목:
- 프로필 구조
- 사용자 정보 카드 구조
- 맥락 추천 결과 구조
- 승인 및 거절 데이터 구조
- 답변 생성 요청과 응답 구조
- 기억 저장 제안 구조
- 오류 응답 형식
API 계약은 다음 위치에서 관리합니다.
contracts/
docs/FRONTEND_HANDOFF.md
src/types.ts
프론트엔드와 백엔드는 같은 타입 이름과 필드명을 사용해야 합니다.
백엔드가 완성되기 전에는 Mock 서버를 사용해 프론트엔드 흐름을 먼저 구현합니다.
우선 구현할 화면:
- 로그인 또는 사용자 선택
- 프로필 선택
- 채팅 질문 입력
- 추천 맥락 카드 확인
- 승인 및 거절
- 개인화 답변 표시
- 새 정보 저장 또는 무시
- 프로필 및 접근성 설정
백엔드는 아래 순서로 구현합니다.
인증 확인
→ 사용자 프로필 조회
→ 질문 분석
→ 관련 카드 검색
→ 의미 관련성 평가
→ 정책 및 민감도 검사
→ 후보 반환
→ 사용자 승인 수신
→ 승인된 카드만 생성 모델에 전달
→ 답변 검증
→ 저장 후보 제안
Mock 데이터로 핵심 흐름을 확인한 뒤 실제 Supabase를 연결합니다.
연결 대상:
- 사용자 계정
- 프로필
- 사용자 정보 카드
- 질문 기록
- 승인 기록
- 기억 저장 제안
- 저장된 기억
프론트엔드의 Mock API 주소를 실제 백엔드 주소로 변경합니다.
통합 시 반드시 확인할 항목:
- 요청 및 응답 필드명 일치
- 사용자 인증 토큰 전달
- 승인된 카드 ID만 전송
- 오류 메시지 처리
- 로딩 및 재시도 처리
- 승인하지 않은 정보가 생성 요청에 포함되지 않는지 확인
최종 사용자가 실제로 사용하는 순서대로 테스트합니다.
회원가입 또는 로그인
→ 프로필 생성
→ 정보 카드 등록
→ 질문 입력
→ 추천 카드 확인
→ 일부 승인 및 일부 거절
→ 답변 생성
→ 답변 검증
→ 새 정보 저장 또는 무시
→ 히스토리 확인
- 프론트엔드 배포
- 백엔드 API 배포
- Supabase 운영 환경 연결
- 환경변수 등록
- 실제 계정으로 데모 리허설
- 실패 시 복구 시나리오 준비
┌──────────────────────────────┐
│ 사용자 UI │
│ React · TypeScript · Vite │
│ 채팅 · 프로필 · 승인 · 음성 │
└──────────────┬───────────────┘
│ HTTPS / JSON
▼
┌──────────────────────────────┐
│ Backend API │
│ 인증 · 권한 · 요청 검증 │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Context Selection Engine │
│ 질문 분석 │
│ 관련 카드 검색 │
│ 의미 관련성 평가 │
│ 민감도·최신성·충돌 검사 │
└──────────────┬───────────────┘
│ 후보 카드
▼
┌──────────────────────────────┐
│ User Approval Gate │
│ 승인 · 거절 · 선택 해제 │
└──────────────┬───────────────┘
│ 승인된 최소 맥락
▼
┌──────────────────────────────┐
│ Response Generator │
│ 승인 맥락 기반 답변 생성 │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Output Validator │
│ 개인정보 노출 검사 │
│ 제약 위반 검사 │
│ 승인 맥락 반영 검사 │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Supabase │
│ Auth · PostgreSQL · RLS │
│ Profile · Card · History │
└──────────────────────────────┘
- 데이터 조회와 모델 전달을 분리합니다.
- 전체 사용자 정보를 생성 모델에 직접 전달하지 않습니다.
- 승인 전 후보 데이터와 승인 후 생성 데이터를 별도로 관리합니다.
- 승인 ID를 기준으로 서버가 실제 카드 값을 다시 조회합니다.
- 클라이언트가 임의로 카드 값을 수정해 생성 요청에 넣지 못하게 합니다.
- 거절한 정보는 생성 프롬프트와 로그에서 제외합니다.
- 데이터 접근 권한은 Supabase RLS와 백엔드 인증에서 모두 검사합니다.
실제 저장소 구조에 맞춰 일부 이름은 달라질 수 있습니다.
context-bridge/
├─ api/ # API 엔드포인트 또는 서버리스 함수
├─ backend/ # 백엔드 서비스
│ ├─ controllers/ # 요청 및 응답 처리
│ ├─ services/ # 핵심 비즈니스 로직
│ ├─ domain/ # 맥락 선택 및 정책 규칙
│ ├─ repositories/ # DB 접근 계층
│ ├─ validators/ # 입력 및 출력 검증
│ └─ tests/ # 백엔드 테스트
├─ contracts/ # 프론트·백엔드 공통 API 계약
├─ docs/
│ └─ FRONTEND_HANDOFF.md # 프론트 전달 문서
├─ supabase/
│ ├─ migrations/ # DB 마이그레이션
│ └─ policies/ # RLS 정책 문서
├─ src/
│ ├─ components/ # React UI 컴포넌트
│ ├─ services/ # 프론트 API 및 저장소 모듈
│ ├─ data/ # Mock 또는 기본 데이터
│ ├─ hooks/ # 공통 React Hooks
│ ├─ types.ts # 공통 타입
│ ├─ App.tsx
│ └─ index.css
├─ mock-server.mjs # 프론트 독립 개발용 Mock API
├─ .env.example # 환경변수 예시
├─ package.json
└─ README.md
Node.js 20 이상
npm 10 이상
Git 최신 안정 버전
VS Code
현재 Node.js 버전 확인:
node -v
npm -v
git --versiongit clone https://github.com/ABC26-SUMMER/context_bridge.git
cd context_bridge
npm installnpm run devVite 기본 주소 예시:
http://localhost:5173
프로젝트 설정에 따라 3000번 포트를 사용할 수도 있습니다.
npm run build프로젝트 스크립트에 따라 다음 명령을 사용합니다.
npm run lint또는:
npx tsc --noEmitnpm test등록된 테스트 스크립트가 다르면 package.json의 scripts 항목을 기준으로 실행합니다.
저장소 루트의 .env.example을 복사해 .env.local 또는 프로젝트가 사용하는 환경 파일을 만듭니다.
Windows CMD:
copy .env.example .env.localPowerShell:
Copy-Item .env.example .env.localVITE_SUPABASE_URL=https://YOUR_PROJECT.supabase.co
VITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_OR_PUBLISHABLE_KEY
VITE_API_BASE_URL=http://localhost:4000프로젝트가 VITE_SUPABASE_PUBLISHABLE_KEY를 사용한다면 실제 코드의 변수명에 맞춰 통일합니다.
VITE_SUPABASE_PUBLISHABLE_KEY=YOUR_SUPABASE_PUBLISHABLE_KEYSUPABASE_URL=https://YOUR_PROJECT.supabase.co
SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY=YOUR_SERVER_ONLY_SERVICE_ROLE_KEY
GEMINI_API_KEY=YOUR_MODEL_API_KEY
PORT=4000- 실제 키를 GitHub에 커밋하지 않습니다.
.env,.env.local은.gitignore에 포함합니다.SUPABASE_SERVICE_ROLE_KEY는 브라우저 코드에 절대 넣지 않습니다.- 프론트에서 사용하는 키와 서버 전용 키를 구분합니다.
- Vite 환경변수는
VITE_접두사가 있어야 브라우저에서 읽을 수 있습니다. - 배포 환경에서는 Vercel 또는 서버 플랫폼의 환경변수 설정 화면에 등록합니다.
- Supabase Auth
- PostgreSQL Database
- Row Level Security
- 필요 시 Realtime 또는 Storage
profiles
context_cards
questions
context_proposals
context_approvals
answer_history
memory_suggestions
memories
auth.users
└─ profiles
├─ context_cards
├─ questions
│ ├─ context_proposals
│ ├─ context_approvals
│ └─ answer_history
└─ memories
모든 사용자 데이터 테이블은 기본적으로 RLS를 활성화합니다.
사용자는 다음 조건을 만족하는 행만 읽고 수정할 수 있어야 합니다.
auth.uid() = user_id프로필 소유권을 경유해야 한다면 프로필 테이블과 연결해 권한을 검사합니다.
서비스 역할 키를 사용하는 서버 기능도 요청 사용자의 소유권을 별도로 확인해야 합니다.
Mock 서버가 포함되어 있다면:
node mock-server.mjs예시 주소:
http://localhost:4000
프론트 환경변수:
VITE_API_BASE_URL=http://localhost:4000배포 후에는 다음처럼 변경합니다.
VITE_API_BASE_URL=https://YOUR_BACKEND_DOMAIN가능하면 같은 도메인의 /api 경로를 사용하는 구조를 권장합니다.
VITE_API_BASE_URL=/api- 모든 요청은 JSON을 기본으로 사용합니다.
- 인증이 필요한 요청에는 사용자 세션 토큰을 전달합니다.
- 서버는 클라이언트가 전달한
user_id를 그대로 신뢰하지 않습니다. - 사용자 ID는 인증 토큰에서 확인합니다.
- 오류 응답은 공통 형식으로 통일합니다.
예시:
{
"error": {
"code": "UNAUTHORIZED",
"message": "로그인이 필요합니다."
}
}권장 브랜치 구조:
main
develop
feature/planning
feature/chat-ui
feature/profile-settings
feature/context-approval
feature/backend-rule-engine
feature/supabase
fix/문제이름
git checkout develop
git pull origin develop
git checkout -b feature/작업이름작업 완료 후:
git add .
git commit -m "feat: 기능 설명"
git push -u origin feature/작업이름그다음 GitHub에서 Pull Request를 생성해 develop에 병합합니다.
배포 가능한 상태가 되면 develop을 main에 병합합니다.
feat: 맥락 승인 UI 추가
feat: 질문 관련 카드 추천 로직 구현
fix: 거절 카드가 생성 요청에 포함되는 문제 수정
test: 승인 기반 답변 E2E 테스트 추가
docs: 프론트엔드 API 전달 문서 갱신
chore: Supabase 환경변수 구성
공용 main 브랜치에서는 다음 명령을 가급적 사용하지 않습니다.
git push --force필요한 경우에도 팀원과 확인한 뒤 다음을 우선 사용합니다.
git push --force-with-lease해커톤과 짧은 개발 기간에서는 다음 순서로 완성합니다.
- 로그인 및 사용자 구분
- 프로필 선택과 수정
- 사용자 정보 카드 등록
- 질문 입력
- 관련 맥락 추천
- 사용자 승인 및 거절
- 승인 맥락 기반 답변 생성
- 답변 후 저장 승인
- 기본적인 음성 입력과 읽기
- 데이터 권한 분리
- 추천 질문의 일별 자동 변경
- JSON 백업 및 복원
- 보호자 연락처
- 고급 히스토리 검색
- 위치 기반 기능
- 여러 생성 모델 자동 전환
- 복잡한 관리자 대시보드
핵심 흐름이 안정적으로 작동하기 전에는 후순위 기능을 추가하지 않습니다.
- 질문 의도 분석
- 관련성 점수 계산
- 민감정보 분류
- 제약 필터링
- 승인 카드 추출
- 출력 검증
- 인증 없는 요청은
401 - 다른 사용자 데이터 접근은
403또는404 - 존재하지 않는 프로필은
404 - 잘못된 요청 구조는
400 - 승인되지 않은 카드가 포함되면 차단
- 기밀정보 전달 시 차단
최소 다음 시나리오를 통과해야 합니다.
- 대학생 사용자가 자신의 프로필로 질문합니다.
- 서버가 관련 카드만 추천합니다.
- 사용자가 일부 카드만 승인합니다.
- 생성 모델에는 승인 카드만 전달됩니다.
- 답변이 승인된 정보와 필수 제약을 반영합니다.
- 거절 카드 정보는 답변과 로그에 나타나지 않습니다.
- 답변 후 새 정보가 저장 후보로 표시됩니다.
- 사용자가 저장을 눌렀을 때만 DB에 저장됩니다.
Vercel 프로젝트에 GitHub 저장소를 연결합니다.
주요 설정:
Framework: Vite
Build Command: npm run build
Output Directory: dist
Vercel 환경변수에 다음 값을 등록합니다.
VITE_SUPABASE_URL
VITE_SUPABASE_ANON_KEY
VITE_API_BASE_URL
백엔드가 Vercel Functions 구조라면 api/ 경로를 사용합니다.
별도 Node 서버라면 Render, Railway, Fly.io 또는 다른 서버 플랫폼을 사용할 수 있습니다.
서버 환경변수:
SUPABASE_URL
SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
GEMINI_API_KEY
- 로그인 성공 여부
- Supabase 연결 여부
- API CORS 설정
- 인증 토큰 전달
- 맥락 추천 응답
- 승인 후 답변 생성
- 모바일 화면
- 음성 기능의 브라우저 지원
- 새로고침 후 세션 유지
- 오류 발생 시 사용자 안내
- 사용자가 시니어 프로필을 선택합니다.
- “오늘 병원에 갈 때 무엇을 준비해야 해?”라고 질문합니다.
- 시스템이 이동 방식, 복용 중인 약, 보호자 연락 필요 여부 등을 추천합니다.
- 민감한 건강 관련 정보는 기본 선택 해제 상태로 보여줍니다.
- 사용자가 필요한 정보만 승인합니다.
- 승인된 정보만 반영한 준비 목록을 제공합니다.
- 새로운 일정 정보는 저장할지 다시 확인합니다.
- 대학생 프로필을 선택합니다.
- “이번 학기 조기졸업 가능성을 확인하고 싶어”라고 질문합니다.
- 시스템이 현재 학점, 필수 전공, 졸업 조건과 관련된 카드만 추천합니다.
- 사용자가 사용할 정보를 승인합니다.
- 승인 정보에 근거한 확인 항목과 다음 행동을 제공합니다.
프로젝트는 화면이 많다고 완성된 것이 아닙니다.
다음 조건을 만족하면 핵심 버전이 완성된 것으로 판단합니다.
- 신규 사용자가 설명 없이 핵심 흐름을 사용할 수 있음
- 질문에 관련된 카드가 안정적으로 추천됨
- 사용자가 승인한 정보만 모델에 전달됨
- 거절한 정보가 프롬프트와 로그에 남지 않음
- 다른 사용자 데이터에 접근할 수 없음
- 민감정보가 기본 해제되거나 정책에 따라 차단됨
- 답변 후 정보가 자동 저장되지 않음
- 핵심 E2E 테스트가 통과함
- 로컬과 배포 환경에서 동일한 흐름이 작동함
- 발표 중 사용할 데모 시나리오가 반복해서 성공함