ai-startup-skills
AI 제품을 만드는 스타트업을 위한 7단계 에이전트 스킬: 검증 → 비즈플랜 → 정책 → 로드쇼 → 고객 확보 → 가격 책정 → 등록
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기논문을 기반으로 챗봇을 만들어 실증을 합니다.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
한국소비자원 상담 상황을 대상으로 Vanilla LLM · Native RAG · Agentic RAG 세 가지 파이프라인을 같은 질문에 동시에 돌려 비교하는 서비스입니다. 논문 「실무 환경에서의 Agentic RAG 파이프라인 구축 및 다중 계층 평가 체계에 관한 연구」의 구조를 재현하고, 그것을 실제로 쓸 수 있는 웹 제품으로 만들었습니다. 왜 세 개를 동시에 돌리나요? "에이전트 구조가 정말 더 나은가"는 말로 설명하기 어렵습니다. 같은 질문에 대해 세 답변과 토큰·지연·비용·검색 근거·검증 판정을 나란히 보여 주면, 차이가 눈에 보입니다. • 지식베이스: 소비자분쟁해결기준(공정위 고시) + 전자상거래법 → 청크 1,654개, 개념 그래프 노드 2,663개 • 모델: GPT-5.6 Luna(기본) · GPT-5.6 Terra · GPT-4o 중 선택 • API 키: 사용자가 자기 키를 넣습니다(BYOK). 서버는 키를 저장하지 않습니다README 전문 보기 ↗
한국소비자원 상담 상황을 대상으로 Vanilla LLM · Native RAG · Agentic RAG 세 가지 파이프라인을 같은 질문에 동시에 돌려 비교하는 서비스입니다. 논문 「실무 환경에서의 Agentic RAG 파이프라인 구축 및 다중 계층 평가 체계에 관한 연구」의 구조를 재현하고, 그것을 실제로 쓸 수 있는 웹 제품으로 만들었습니다.
왜 세 개를 동시에 돌리나요? "에이전트 구조가 정말 더 나은가"는 말로 설명하기 어렵습니다. 같은 질문에 대해 세 답변과 토큰·지연·비용·검색 근거·검증 판정을 나란히 보여 주면, 차이가 눈에 보입니다.
flowchart LR
U["사용자 브라우저<br/>BYOK: 자기 OpenAI 키 입력"]
subgraph Front["Vercel"]
W["Next.js 16<br/>챗봇 · 대시보드 · 관리자"]
end
subgraph Back["Google Cloud Run"]
A["FastAPI + LangGraph<br/>SSE 스트리밍"]
KB[("ChromaDB 벡터 색인<br/>+ NetworkX 개념 그래프<br/>이미지에 동봉")]
end
DB[("Neon PostgreSQL<br/>요청 · 실행 · 단계 · 검색근거")]
O["OpenAI API"]
U -->|"질문 + X-OpenAI-Key"| W
W -->|"POST /api/chat (SSE)"| A
A --> KB
A -->|"사용자 키로 호출"| O
A -->|"로그 적재"| DB
A -.->|"run_step / run_done 이벤트"| W
설계 의도
| 선택 | 이유 |
|---|---|
| 벡터 색인을 컨테이너 이미지에 동봉 | 재검색이 잦은 순환 구조라 네트워크 지연이 누적되면 안 됩니다. 로컬 파일 읽기가 가장 빠릅니다 |
| SSE(EventSource 아님) | 파이프라인이 끝나는 순서대로 화면에 꽂아 주려면 스트리밍이 필요한데, API 키를 헤더로 보내야 해서 fetch 스트림을 씁니다 |
| BYOK | 공개 서비스에서 운영자가 토큰 비용을 전부 떠안지 않기 위해서입니다. 키는 브라우저에만 남습니다 |
| 로그에 검색 근거 원문 스냅샷 저장 | 지식베이스를 다시 만들어도 "그때 무엇을 보고 답했는지"가 남아야 합니다 |
flowchart TB
Q["같은 질문"]
subgraph V["① Vanilla LLM — 성능 하한선"]
direction LR
V1["모델 지식만으로 생성"]
end
subgraph N["② Native RAG — 표준 RAG 대조군"]
direction LR
N1["벡터 검색 상위 20"] --> N2["정제 없이 전량 주입"] --> N3["생성"]
end
subgraph AG["③ Agentic RAG — 제안 구조"]
direction LR
A1["세션 메모리"] --> A2["의도 라우팅"] --> A3["하이브리드 검색"] --> A4["생성"] --> A5["Critic 검증"]
A5 -.->|"미달 시 재시도"| A3
end
Q --> V
Q --> N
Q --> AG
| Vanilla | Native RAG | Agentic RAG | |
|---|---|---|---|
| 역할 | 검색이 없을 때의 하한선 | 검색만 붙였을 때의 기준 | 검증·라우팅까지 붙인 제안 구조 |
| 검색 | 없음 | 벡터 단독, 정제 없음 | 벡터 + 그래프 + RRF + 리랭킹 |
| 자기 검증 | 없음 | 없음 | Critic 3기준 · 최대 3회 |
| 도메인 밖 질문 | 그냥 답해 버림 | 엉뚱한 법령을 검색 | 라우터가 즉시 거절 |
| 실측 평균 토큰 | 1,107 | 2,395 | 9,270 |
실측은 28문항(정책 22 + 도메인 밖 6), GPT-5.6 Luna 기준입니다. Native RAG를 일부러 정제 없이 두는 이유는 대조군이기 때문입니다. 검색만 붙이면 오히려 나빠지는 현상("맥락 혼동")을 드러내려는 구성입니다.
flowchart TD
S([질문 도착]) --> M["① 세션 메모리<br/>DisputeTarget 추출·갱신"]
M --> R{"② 의도 라우터"}
R -->|"out_of_domain"| X["고정 문구로 거절"] --> E1([종료])
R -->|"system_action<br/>(도구 켤 때만)"| T["ReAct 도구 루프<br/>주문 조회 · 환불 접수"] --> G
R -->|"policy_inquiry"| RT["③ 하이브리드 검색"]
RT --> G["④ 답변 생성<br/>XML 태그로 맥락 격리"]
G --> C{"⑤ Critic<br/>근거성 · 관련성 · 완결성"}
C -->|"통과"| E2([답변])
C -->|"1회차 미달"| RT
C -->|"2회차 미달"| G
C -->|"3회 초과"| U["검증 미통과 상태로<br/>마지막 답변 출력"] --> E3([종료])
| 노드 | 기술 | 왜 이 기술인가 |
|---|---|---|
| ① 세션 메모리 | LangGraph MemorySaver + Pydantic DisputeTarget | 대화 전문을 쌓으면 컨텍스트가 부풀고 환각이 늘어납니다. 품목·분쟁유형·주문번호만 남겨 다음 턴으로 넘깁니다. "그럼 환불은요?"처럼 품목이 빠진 후속 질문이 엉뚱한 표를 찾는 것을 막습니다 |
| ② 의도 라우터 | Structured Output + 퓨샷 | 모든 질문을 무거운 추론 루프에 태우면 지연과 도구 오남용이 생깁니다. 진입점에서 분기시켜 무관한 질의는 검색 전에 차단합니다 |
| ③ 하이브리드 검색 | ChromaDB + NetworkX + RRF + LLM 리랭커 | 아래 §4 |
| ④ 생성 | XML 태그 맥락 격리 | <retrieved_documents>로 감싸 모델 내부 지식과 검색 문서가 섞이는 것을 막습니다 |
| ⑤ Critic | Self-RAG를 Structured Output으로 | 법률 도메인에서 가장 치명적인 오류는 근거 없는 답변입니다. 판정 전에 feedback을 먼저 쓰게 해(CoT) 다음 회차에 교정 방향을 남깁니다 |
Critic이 3회를 넘기면 복구 장치 없이 마지막 답변을 그대로 내보냅니다. 검증 미통과 표시가 붙습니다. 안전성과 답변 성공률 사이의 트레이드오프를 감추지 않고 그대로 보여 주기 위한 선택입니다.
flowchart LR
Q["질문 + 기억된 품목/분쟁유형"] --> EX["질의 확장<br/>노트북 → 퍼스널컴퓨터·전자제품"]
EX --> V["1. 벡터 검색<br/>text-embedding-3-large (3072차원)"]
EX --> GR["2. 그래프 탐색<br/>개념 노드 2-hop"]
EX --> IT["2-1. 품목 한정 재검색<br/>메타데이터 필터"]
V --> RRF["3. RRF 병합<br/>k=60"]
GR --> RRF
IT --> RRF
RRF --> RR["4. LLM 리랭킹<br/>'문제 해결 기여도'·'정보 밀도'"]
RR --> OUT["상위 5개만 생성에 주입"]
| 단계 | 왜 |
|---|---|
| 3072차원 임베딩 | '청약철회 / 계약해제 / 취소'는 표면은 비슷하고 법적 효력은 전혀 다릅니다. 저차원 모델은 이 차이를 뭉갭니다 |
| 그래프 탐색 | 벡터만으로는 청약철회 → 전자상거래법 제17조 → 7일 이내 같은 간접 참조 관계가 잡히지 않습니다 |
| RRF 병합 | 점수 체계가 다른 두 검색 결과를 순위만으로 합칩니다. 정규화가 필요 없습니다 |
| LLM 리랭킹 | 단어가 겹친다고 유용한 문서는 아닙니다. 기준을 '문제 해결 기여도'로 바꿉니다 |
| 질의 확장 · 품목 한정 재검색 | 고시는 '퍼스널컴퓨터'라 적고 사용자는 '노트북'이라 씁니다. 또 별표Ⅱ는 품목이 달라도 문구가 거의 같아(해결기준 중앙값 17자) 품목 구분이 묻힙니다 |
원문이 표로 된 고시라 일반적인 청킹으로는 의미가 무너집니다.
flowchart LR
P["원문<br/>고시 · 법률 · 별표 PDF"] --> T["표 구조 파싱<br/>pdfplumber 좌표 기반"]
T --> V{"자동 검증 V1~V6<br/>행·열·숫자·마커"}
V -->|"실패한 표만"| F["LLM 보정"]
V -->|"통과"| CH
F --> CH["청킹<br/>표의 한 행 = 한 청크"]
CH --> EM["임베딩 (증분)"]
CH --> G["개념 그래프 추출<br/>+ Louvain 군집"]
EM --> ART[("빌드 산출물<br/>chroma / graph.json")]
G --> ART
별표Ⅱ > 전자제품·사무용기기 > 품질보증기간 이내 하자 > 무상수리처럼 경로를 만들어 붙입니다. 500자 단위로 자르면 이 경로가 사라져 검색 결과가 개정 이력 덩어리가 됩니다flowchart LR
subgraph P["정책 질의 22건"]
direction TB
P1["Native 2,263 토큰 / 4.1초"]
P2["Agentic 11,664 토큰 / 32.9초"]
end
subgraph O["도메인 밖 6건"]
direction TB
O1["Native 2,880 토큰<br/>법령을 검색해 답함"]
O2["Agentic 494 토큰<br/>6건 모두 차단"]
end
| 영역 | 선택 | 이유 |
|---|---|---|
| 그래프 오케스트레이션 | LangGraph | 검색→생성→비평→재검색의 순환이 필요합니다. 체인으로는 되돌아갈 수 없습니다 |
| 구조화 출력 | Pydantic + json_schema strict | 라우팅 결과가 문자열이면 분기가 흔들립니다. 스키마로 강제해 확률적 생성을 분기 스위치로 바꿉니다 |
| 벡터 DB | ChromaDB (로컬 영속) | 한 요청에서 재검색이 최대 3회 일어납니다. 클라우드 DB의 왕복 지연이 누적되면 응답 예산을 넘깁니다 |
| 그래프 | NetworkX + Louvain | 조항 간 참조 관계를 담고, 군집으로 관련 조항을 묶습니다 |
| 백엔드 | FastAPI + SSE | 세 파이프라인을 동시에 돌리고 끝나는 대로 흘려보냅니다 |
| 프런트 | Next.js 16 + Tailwind 4 + shadcn/ui | |
| DB | PostgreSQL (Neon) | 로그를 무기한 보관하고 대시보드 집계에 씁니다 |
| 배포 | Vercel + Cloud Run + Neon | 무료 한도 안에서 상시 운영 가능한 조합입니다. Cloud Run은 쉬면 0으로 줄어듭니다 |
# 백엔드
cd apps/api
uv sync
uv run uvicorn app.main:app --port 8100
# 프런트
pnpm --dir apps/web install
pnpm --dir apps/web dev --port 3100
지식베이스를 새로 만들려면 (운영자 키 OPENAI_API_KEY 필요):
cd apps/api && uv run kb build
주요 환경변수
| 이름 | 기본값 | 설명 |
|---|---|---|
DATABASE_URL | 로컬 Postgres | Neon은 postgresql+asyncpg://...?ssl=require 형태로 |
ALLOWED_ORIGINS | http://localhost:3100 | 프런트 도메인 |
NATIVE_MODE | paper | Native RAG 주입 방식 (paper 전량 / compressed 리랭킹 5개) |
CRITIC_EXHAUSTED | paper | Critic 소진 시 처리 (paper 그대로 출력 / native_fallback 대체) |
TOOLS_ENABLED | false | 도구 호출·가상 주문 DB |
SESSION_MAX / SESSION_TTL_MIN | 500 / 120 | 세션 메모리 상한 |
Postgres 외에 Prometheus·Grafana도 docker-compose로 띄운다. API는 컨테이너 밖(호스트)에서 돌므로 Prometheus가 host.docker.internal:8100으로 스크레이프한다 (observability/prometheus/prometheus.yml).
cp .env.example .env # GRAFANA_ADMIN_PASSWORD 채우기
docker compose up -d
uv run --directory apps/api uvicorn app.main:app --port 8100
.env의 GRAFANA_ADMIN_PASSWORD) — CDQ API 개요 대시보드가 자동으로 올라와 있다계획 전체는 docs/10_observability_load_test_plan.md 참고.
load/k6/에 파이프라인별 시나리오(vanilla / native / agentic)가 있다. BYOK 테스트 키 2개를 load/k6/.env에 두고
(.env.example 참고) 아래처럼 실행한다. 모델은 GPT-5.6 Luna로 고정, 키는 VU마다 번갈아 쓴다.
bash load/k6/run.sh native # 1 VU x 10회 베이스라인
K6_PROM_RW=1 bash load/k6/run.sh native ramp # 결과를 Prometheus로 보내 Grafana "k6 부하테스트"에서 실시간으로 본다
배포 환경 모드(scaleout, limit), Cloud Run 서버 지표 조회(load/gcp_metrics.py), OpenAI 한도 점검(load/openai_limits.py)은
docs/11_deployment_test_env_plan.md 참고.
apps/api/
app/pipelines/ vanilla · native · agentic 그래프, 세션 메모리
app/kb/ 하이브리드 검색기, 지식베이스 적재
app/tools/ Lightweight ReAct 도구 + 가상 주문 DB (기본 꺼짐)
app/api/ /api/chat(SSE) · 대시보드 · 관리자 로그
kb_build/ 표 파싱 → 검증 → 청킹 → 임베딩 → 그래프
cli/ kb 빌드, 표준답변 대조표, 도구 편향 실험
apps/web/src/ 챗봇 · 대시보드 · 관리자 화면
기획·설계 문서(문제 정의, 데이터 분석, UX/IA, 시스템 설계, 배포 런북, 논문 대조)는 상담 데이터와 논문 원문을 포함하고 있어 저장소에 넣지 않았습니다.