BigSet은 만든 회사(TinyFish)가 자기 웹 데이터 API 위에 올린 오픈소스 도구입니다. 사용자는 평범한 영어 문장으로 원하는 데이터를 묘사합니다. 예를 들어 "엔지니어를 채용 중인 YC 회사들 — 펀딩 단계, 위치, 오픈 포지션 수 포함"이라고 적으면, BigSet이 세 단계를 자동으로 밟습니다. ① 어떤 컬럼이 필요한지(이름·타입·기본키) 스스로 추론하고, ② AI 에이전트를 실제 웹에 보내 조사·검증·중복 제거를 거쳐 표를 채우고, ③ 사용자가 정한 주기(30분 / 6시간 / 매일 / 매주…)로 에이전트를 다시 돌려 데이터를 항상 최신으로 유지합니다.
결과물은 화면에서 표로 보고 CSV·엑셀(XLSX)로 내보낼 수 있습니다. 핵심 슬로건은 "Any dataset. Any source. Always fresh."(어떤 데이터든, 어떤 출처든, 항상 신선하게) 입니다. 즉 "검색 + 추출 + 표 설계 + 중복 제거 + 검증 + 정기 갱신"을 매번 손으로 꿰매던 작업을, 문장 한 줄로 자동화하는 게 목표입니다.
보통 데이터 수집은 인턴에게 "이거 좀 채워 줘"라고 시키는 일입니다. BigSet에서 사용자는 리서치 팀장(오케스트레이터 에이전트) 한 명에게 문장으로 지시합니다. 팀장은 조사할 대상(=표의 각 행)을 찾아내고, 행 하나하나를 전담 인턴(서브에이전트)에게 나눠 줍니다. 인턴은 자기 행만 책임지고 웹을 뒤져 사실을 확인한 뒤 한 줄을 채워 넣죠. 그리고 이 팀은 퇴근하지 않고, 정해진 시각마다 다시 출근해 표를 최신으로 고쳐 둡니다.
README가 직접 밝히듯 "작동은 하지만 거친 부분이 있다"는 단계입니다. 데이터셋 하나 만드는 데 2~5분이 걸리고, 기본 행 수는 설정 가능하며(--rows <n> 플래그 또는 생성 UI), 예전 기본값이 100행이었던 흔적이 코드에 남아 있습니다. 현재는 사용자가 원하는 행 수를 지정합니다. 로그인·페이월 뒤에 숨은 데이터는 수집하지 못합니다. "마법 같은 완제품"이 아니라 "가능성을 보여주는 잘 만든 프로토타입"으로 보는 게 정확합니다.
웹에서 데이터를 모으는 도구는 예전부터 많았습니다. 문제는 각자 자기 영역만 잘한다는 점입니다. 스크래핑 프레임워크는 URL을 지정해 긁고, 검색 API는 순위 결과만 주고, 리드젠 플랫폼은 미리 만들어 둔 사람·회사 리스트만 팝니다. 그래서 "여러 카테고리를 가로지르는 새로운 표"가 필요한 순간, 사용자는 검색·추출·표 설계·중복 제거·검증·크론잡(정기 실행)을 직접 코드로 꿰매야 했습니다.
| 방식 | 한계 | BigSet의 접근 |
|---|---|---|
| 스크래핑 프레임워크 | URL·CSS 선택자를 사람이 지정 | URL·선택자 없이 문장만 |
| 검색 API | 순위 링크만, 구조화 안 됨 | 검증된 구조화 표로 변환 |
| 리드젠 플랫폼 | 미리 정해진 리스트만 | 임의 주제를 즉석 생성 |
| 직접 코딩 | 매번 파이프라인 재작성 | 스키마 추론·갱신 내장 |
BigSet의 차별점은 네 가지로 압축됩니다. (1) 스키마 자동 추론 — 사용자가 컬럼을 정의하지 않습니다. (2) 자율 멀티에이전트 조사 — 오케스트레이터가 대상을 찾고 서브에이전트가 병렬로 검증합니다. (3) 출처 검증 + 중복 제거 내장 — 각 행에 근거 URL이 붙습니다. (4) 스케줄 자동 갱신 — 크론잡을 직접 관리할 필요가 없습니다.
조사 시점 GitHub 스타 수는 매우 적었습니다(공개 빌드 초기). 즉 이 프로젝트의 화제성은 "누적 인기"가 아니라 TinyFish가 공개적으로 빠르게 빌드("building in the open")하며 X(트위터)에서 밀고 있는 신규 실험작이라는 점, 그리고 "웹 전체를 데이터로 바꿔준다"는 컨셉 자체의 흡입력에서 나옵니다. 별 수와 순위는 시점에 따라 빠르게 변할 수 있습니다.
BigSet은 역할이 또렷이 나뉜 세 덩어리로 되어 있습니다. ① 사용자가 보는 프론트엔드, ② 에이전트를 실제로 돌리는 백엔드, ③ 둘이 공유하는 데이터베이스입니다. 흥미롭게도 README에는 옛 스택(Better Auth + PostgreSQL/Drizzle)의 흔적이 남아 있지만, 실제 현재 코드가 쓰는 스택은 Clerk + Convex입니다 — 프로젝트가 빠르게 진화하며 갈아탄 자국입니다.
frontend/ (Next.js · React · Convex)| 부품 | 버전 | 역할 |
|---|---|---|
| Next.js | 16.2.6 (App Router) | 웹 앱 프레임워크. 페이지·라우팅·서버 컴포넌트 |
| React | 19.2.4 | UI 렌더링 런타임 |
| Tailwind CSS | v4 | 유틸리티 클래스 기반 스타일 |
| @clerk/nextjs | ^7.3.7 | 로그인·회원 관리(인증 클라이언트) |
| convex | ^1.39.1 | 실시간 reactive DB 클라이언트(쿼리 바뀌면 화면 자동 갱신) |
| @tanstack/react-table + react-window | ^8.21 / ^1.8 | 대량 행을 가상화로 빠르게 그리는 표 뷰 |
| xlsx (SheetJS) | ^0.18.5 | 엑셀 내보내기(+ 내장 CSV) |
backend/ (Fastify · Mastra · Vercel AI SDK)| 부품 | 버전 | 역할 |
|---|---|---|
| Fastify | ^5.0.0 | 가벼운 HTTP 서버(TypeScript, ESM). 에이전트 실행 요청을 받음 |
| @mastra/core | ^1.36.0 | AI 워크플로/에이전트/툴 오케스트레이션 프레임워크 |
| ai (Vercel AI SDK) | ^6.0.0 | LLM 호출을 통일된 인터페이스로 감싸기 |
| @openrouter/ai-sdk-provider | ^2.9.0 | 여러 LLM 공급자를 한 API로 라우팅 |
| @clerk/backend | ^3.4.11 | 서버에서 JWT(로그인 토큰) 검증 |
| zod | ^4.4.3 | 데이터 형태(스키마) 런타임 검증 |
| resend / posthog-node | (옵션) | "데이터셋 준비됨" 이메일 / 서버 분석 |
createWorkflow(단계 묶음)·createStep(한 단계)·createTool(에이전트가 쓰는 도구)·에이전트를 코드로 정의합니다. BigSet의 데이터 채우기/갱신 파이프라인이 전부 Mastra로 짜여 있고, 전용 인스펙터(Mastra Studio, :4111)에서 실행을 들여다볼 수 있습니다.한 가지 모델만 쓰지 않고, 역할에 맞춰 골라 씁니다(사용자가 설정 UI에서 교체 가능). 비싼 모델은 머리 쓰는 곳에, 싼 모델은 반복 노동에 배치하는 영리한 비용 설계입니다.
| 역할 | 기본 모델 | 이유 |
|---|---|---|
| 스키마 추론 | anthropic/claude-sonnet-4.6 | 컬럼·타입·기본키 설계는 똑똑한 모델이 유리 |
| 채우기 오케스트레이터 | qwen/qwen3.7-max | 비용 효율적 — 대상을 많이 훑어야 함 |
| 조사 서브에이전트 | qwen/qwen3.7-max | 병렬로 많이 도니 저비용이 중요 |
make dev 한 줄로 6개 컨테이너가 동시에 뜹니다. 특히 Convex를 클라우드가 아니라 자기 컴퓨터(Docker)에서 직접 돌리는 자가호스팅 구성이 특징입니다.
| 서비스 | 역할 |
|---|---|
| db (postgres:16) | Convex의 저장소(백킹 스토어) |
| convex | 자가호스팅 Convex 백엔드(앱 데이터·함수) |
| convex-dashboard | Convex 관리 대시보드(:6791) |
| frontend | Next.js 앱(:3500) |
| backend | Fastify API + 갱신 스케줄러(:3501) |
| mastra | Mastra Studio 워크플로 인스펙터(:4111) |
전체 그림을 먼저 한눈에 보겠습니다. 데이터는 위(사용자 문장)에서 아래(검증된 행)로 흐르고, 마지막에 스케줄러가 그 표를 주기적으로 다시 깨웁니다.
이게 BigSet의 심장입니다. 오케스트레이터(populate.ts)는 "표에 들어갈 대상이 누구누구인지"를 찾는 데만 집중합니다. 그리고 대상 하나를 발견할 때마다 run_subagent 도구로 격리된 서브에이전트(investigate-tool.ts)에게 넘깁니다. 서브에이전트는 오직 1행만 책임지므로, 봐야 할 컨텍스트가 좁고 검증이 쉽습니다. 일을 잘게 쪼개 위임하는 이 구조는, 한 에이전트가 100가지를 동시에 들고 헤매는 것보다 훨씬 안정적입니다.
보안이 코드 구조 자체에 박혀 있습니다. 어떤 데이터셋을 만질 권한이 있는지(authorizedDatasetId)와 로그인 정보(authContext)를 도구를 만들 때 클로저로 가둬 둡니다. 그 결과 LLM은 이 값을 절대 보거나 바꿀 수 없습니다. "오케스트레이터 LLM에게 노출되지 않는다"고 코드 주석에 명시돼 있죠. LLM이 프롬프트로 속아도 권한 경계를 넘을 수 없게 만든 설계입니다.
HTTP 라우트가 검증된 Clerk JWT에서 authorizedUserId를 직접 채워 워크플로에 주입합니다. 클라이언트(브라우저)는 이 필드를 공급할 수 없습니다 — "내가 누구다"라고 거짓말할 수 없게 스키마를 분리한 것이죠. 또한 abort-registry.ts로 데이터셋별 중단 신호(AbortSignal)를 관리해, 사용자가 Stop을 눌렀을 때만 작업을 멈추고 네트워크에서 우발적으로 튀어나오는 가짜 중단 에러는 무시합니다.
매 실행마다 검색·페치·조사 횟수, 입력/출력 토큰, 스텝 수를 측정해 runStats 테이블에 1행씩 저장합니다. 어떤 데이터셋이 비싼지, 어떤 모델이 효율적인지를 숫자로 비교할 수 있죠. 사용량은 usage 테이블에서 월 단위 '행 작업(row operation)' 기준으로 회계하며, 무료 계정은 월 2,500 행 작업까지입니다(행을 지워도 환불은 없음).
README 로드맵에 적힌 "깨진 행 자동 수정(Healer agents)", "SQL 쿼리 레이어", "셀 단위 출처", "TinyFish Browser+Agent 통합"은 지향점이지 현재 기능이 아닙니다. 현재 갱신은 update 워크플로의 refresh 에이전트가 담당합니다. 코드를 읽을 때 "있어야 할 것 같은데 없다"고 당황하지 마세요 — 아직 안 만든 것입니다.
초보자가 헷갈리기 쉬운 포인트 하나를 먼저 짚겠습니다. 이 프로젝트에서 데이터베이스의 진짜 본체는 frontend/convex/ 폴더에 있습니다(Convex의 함수·스키마가 거기 살기 때문). 그리고 에이전트가 실제로 도는 두뇌는 backend/src/mastra/에 있습니다. 이 둘만 잡으면 길을 잃지 않습니다.
| 파일/폴더 | 역할 |
|---|---|
| frontend/convex/schema.ts | 모든 테이블(데이터셋·행·사용량·이력)의 형태 정의 — 여기부터 읽으면 데이터 모델이 보임 |
| backend/src/mastra/agents/ | 오케스트레이터·서브에이전트·갱신 에이전트의 '성격'(프롬프트·도구)이 정의된 곳 |
| backend/src/mastra/tools/web-tools.ts | TinyFish 검색·페이지 가져오기 도구. 외부 웹과 닿는 유일한 창구 |
| makefiles/Makefile | Convex admin key 자동 생성·검증, 서비스 기동 순서까지 한 커맨드로 처리하는 '자가치유 셋업' |
| Shell 비중 42% | 보안 스캔·셋업 스크립트·Makefile 셸 로직이 많아 셸 코드 비중이 높음 |
요즘 가장 뜨거운 주제인 "에이전트 여러 개를 협업시키기"를 실전 코드로 볼 수 있습니다. 워크플로를 clear → enumerate → build-prompt → agent 4단계로 쪼갠 구조, 그리고 오케스트레이터가 서브에이전트를 도구처럼 호출하는 패턴은, 다른 에이전트 프로젝트에도 그대로 응용됩니다.
Mastra로 "주제를 주면 → 하위 항목을 나열하고 → 항목마다 서브에이전트가 한 줄 요약을 채우는" 미니 워크플로를 만들어 보세요. createTool 안에 권한값을 클로저로 가두는 패턴까지 흉내 내면 BigSet의 80%를 체험합니다.
Convex는 "쿼리 결과가 바뀌면 화면이 자동으로 다시 그려지는" DB입니다. BigSet은 이걸 클라우드가 아닌 Docker로 직접 돌려, 데이터 주권을 지키는 셀프호스팅의 좋은 예를 보여줍니다. convex/schema.ts → datasets.ts 순으로 읽으면 "스키마 → 함수" 흐름이 잡힙니다.
Vercel AI SDK + OpenRouter로 역할마다 다른 모델을 끼우는 패턴은 실무에서 매우 중요합니다. "설계는 비싼 똑똑한 모델, 반복 노동은 싼 모델"이라는 비용 의식을 코드로 어떻게 구현하는지 배울 수 있습니다(backend/src/config/models.ts).
LLM에게 권한을 절대 노출하지 않는 클로저 스코핑, 서버 권위 인증, 중단 신호 관리, 그리고 runStats 기반 토큰·비용 측정까지 — "프로토타입"을 넘어 "운영 가능한 시스템"으로 만드는 디테일이 한 레포에 모여 있습니다. AI 앱을 실제로 배포해 본 적 없는 사람에게 특히 값진 교본입니다.
순수 소프트웨어 프로젝트라 특별한 하드웨어는 없지만, Docker 컨테이너 6개를 동시에 띄우므로 메모리 여유가 있는 개발용 PC가 필요합니다(README에 구체 RAM/CPU 수치는 없음 — 통상 수 GB 여유 권장).
| 항목 | 요구사항 |
|---|---|
| 필수 도구 | Docker, Make |
| TinyFish API 키 | 웹 검색 + 페이지 가져오기 (필수) |
| OpenRouter API 키 | LLM 호출용. $5~10 크레딧 권장 (필수) |
| Clerk 키 3종 | 로그인/회원 관리. Convex JWT 템플릿 활성화 필요 (클라우드 배포 시 필수, 로컬 개발 시 불필요 — local auth 모드 사용) |
| Resend / PostHog 키 | 이메일 알림 / 분석 (옵션) |
| 비용·시간 | 데이터셋 1건당 2~5분 + LLM 비용 몇 달러. 무료 월 2,500 행 작업 |
실행은 사실상 세 줄입니다. make dev가 의존성 설치 → Postgres/Convex 기동 → admin key 자동 생성 → Convex 스키마 배포 → 프론트/백/Mastra 기동 → 로그 출력까지 알아서 합니다.
# ── 빠른 시작 (npm 전역 설치, Docker 불필요) ────────────── npm install --global @adamexu/bigset && bigset # API 키(TinyFish / OpenRouter)만 입력하면 자동 셋업 후 실행 # ── 소스 빌드 / 개발자 경로 (Docker 필요) ───────────────── # 1) 받아서 들어가기 git clone https://github.com/tinyfish-io/bigset.git cd bigset # 2) 키 채우기 cp .env.example .env # TinyFish / OpenRouter / Clerk(클라우드 배포 시) 키 입력 # 3) 한 방에 기동 (6개 컨테이너 + 자동 셋업) make dev # 완료 후: 앱 :3500 · Convex 대시보드 :6791 · Mastra Studio :4111 # (선택) 공개 데이터셋 로드: make seed-public-datasets
make dev로 기동한 뒤 make seed-public-datasets로 9개 큐레이션 데이터셋(AI 채용 회사·GPU 가격·모델 가격 등)을 로드해 보세요. 표를 CSV/XLSX로 내보내 보고, Convex 대시보드(:6791)에서 데이터가 실제 어떻게 저장됐는지 들여다봅니다.
"한국 AI 스타트업 — 분야, 투자단계, 위치" 같은 문장을 넣고, 스키마가 어떻게 추론되는지(컬럼·타입·기본키) 확인하세요. 생성되는 2~5분 동안 Mastra Studio(:4111)에서 오케스트레이터가 어떤 검색을 하고 서브에이전트가 어떻게 행을 채우는지 실시간으로 관찰합니다.
설정 UI(dashboard/settings/models)에서 오케스트레이터/서브에이전트 모델을 다른 OpenRouter 모델로 바꿔 보세요. 같은 문장으로 두 번 생성해 runStats의 토큰·소요시간을 비교하면, "비싼 모델이 항상 옳은가?"를 직접 실험할 수 있습니다.
backend/src/mastra/tools/investigate-tool.ts를 열어, 서브에이전트가 search_web → fetch_page → insert_row를 어떤 조건으로 호출하는지 따라가 보세요. 100행 제한(MAX_DATASET_ROWS)과 권한 클로저가 어디서 적용되는지 찾는 게 핵심 과제입니다.
서브에이전트에게 새 도구(예: 특정 사이트 전용 조회, 계산기)를 만들어 붙여 보세요. createTool로 도구를 정의하고 권한값을 클로저로 가둔 뒤 에이전트에 등록하면, BigSet의 핵심 확장 메커니즘을 손으로 익히게 됩니다.
| 주차 | 주제 | 할 일 |
|---|---|---|
| 1주차 | Next.js + Fastify 풀스택 | App Router 구조, 클라이언트↔서버 분리, JWT 인증(Clerk) 흐름 익히기 |
| 2주차 | Convex 실시간 DB | 스키마·쿼리·뮤테이션 개념, reactive 갱신, Docker 자가호스팅. schema.ts 정독 |
| 3주차 | LLM 호출·게이트웨이 | Vercel AI SDK generateText, OpenRouter로 모델 교체, zod로 출력 구조 강제 |
| 4주차 | Mastra 멀티에이전트 | 워크플로·툴·에이전트 정의, 오케스트레이터-서브에이전트 패턴, 관측성(runStats) |
BigSet은 "AI 에이전트 데모"가 아니라 실제로 운영 가능한 풀스택 에이전트 앱이라, 한 주제씩 떼어 공부하기 좋습니다. 1~2주차(풀스택·실시간 DB)는 어떤 웹 개발자에게도 바로 쓸모가 있고, 3~4주차(LLM·멀티에이전트)는 요즘 가장 수요가 큰 'AI 엔지니어링' 역량으로 직결됩니다.
| 용어 | 의미 |
|---|---|
| 에이전트(Agent) | 목표만 주면 도구를 골라 스스로 여러 단계를 밟는 자율형 AI 프로그램 |
| 오케스트레이터-서브에이전트 | 상위 에이전트가 일을 잘게 쪼개 격리된 하위 에이전트에 위임하는 협업 구조 |
| 팬아웃(fan-out) | 하나의 작업을 여러 갈래로 동시에 퍼뜨려 병렬 처리하는 방식 |
| 스키마 추론 | 자연어 묘사에서 컬럼명·타입·기본키를 LLM이 자동으로 도출하는 단계 |
| 기본키(Primary Key) | 행을 고유 식별하는 컬럼. 중복 제거·갱신 시 같은 행을 다시 찾는 기준 |
| Mastra | TypeScript용 AI 워크플로/에이전트 오케스트레이션 프레임워크 |
| Convex | 쿼리가 바뀌면 화면이 자동 갱신되는 실시간 reactive DB(여기선 자가호스팅) |
| OpenRouter | 여러 LLM 공급자를 단일 API로 라우팅하는 게이트웨이(슬러그로 모델 지정) |
| Vercel AI SDK | LLM 호출을 통일된 인터페이스로 감싸 모델 비종속적으로 쓰게 하는 라이브러리 |
| Clerk | 드롭인 로그인·회원 관리 서비스. JWT를 발급해 인증에 사용 |
| 클로저 권한 스코핑 | 도구를 만들 때 권한값을 클로저에 가둬 LLM이 못 보게 하는 보안 패턴 |
| 리프레시 케이던스 | 데이터셋을 얼마나 자주 자동 재조사할지의 주기(manual~weekly) |
| 자가호스팅(Self-hosted) | SaaS 클라우드 대신 내 인프라(여기선 Docker)에서 직접 구동하는 방식 |
| AGPL-3.0 | 네트워크로 서비스해도 소스 공개 의무가 따르는 강한 카피레프트 라이선스 |