조달핏 — 수주 영업의 나라장터 공고 탐색을 대신하는 서비스. 회사명 하나로 등록업종·공급물품·수주이력을 임베딩 매칭해 자격 필터 통과 공고 TOP 5 추천
翻譯準備中
正在載入完整 README。 以下為已儲存的摘錄。
회사명을 입력하면 등록업종·공급물품·수주 이력을 함께 분석해, 검토할 만한 나라장터(G2B) 입찰공고 TOP 5를 추천한다. 문제. 입찰 알리미는 키워드 알림이라 "우리가 들어갈 수 있는 공고"와 "검토할 가치가 있는 공고"를 구분하지 못한다. 접근. 회사를 벡터로 만들어 공고와 비교한다. 다만 임베딩은 후보 정렬용이고, 자격(면허·지역·마감) 하드 필터가 먼저다. 100점 매칭이어도 자격이 안 되면 못 들어가기 때문이다. 실데이터로 확인한 것. 초기 설계는 "과거 수주 이력"을 메인 시그널(α=0.7)로 잡았다. 실데이터에 돌려 보니 수주 이력이 매칭되는 회사가 1.1%에 그쳐 추천이 성립하지 않았다. "이 회사가 뭐 하는 회사인가"(등록업종·공급물품)를 메인으로 옮기고, 가중치를 회사 데이터 양에 따라 동적으로 정하는 쪽으로 피벗했다 (2026-05-25). 규모. 공고 10,990건 임베딩, 계약 32,580건, 회사 34,517개. 나라장터 OpenAPI 8종을 매일 GitHub Actions cron으로 누적한다. 상태. WIP MVP. 사내 수주 영업 도입 추진 중. 한국 공공조달(나라장터, G2B) 입찰공고 추천 사이트.檢視完整 README ↗
회사명을 입력하면 등록업종·공급물품·수주 이력을 함께 분석해, 검토할 만한 나라장터(G2B) 입찰공고 20건을 추천한다 (비로그인은 상위 5건 공개).
문제. 입찰 알리미는 키워드 알림이라 "우리가 들어갈 수 있는 공고"와 "검토할 가치가 있는 공고"를 구분하지 못한다.
접근. 회사를 벡터로 만들어 공고와 비교한다. 다만 임베딩은 후보 정렬용이고, 자격(면허·지역·마감) 하드 필터가 먼저다. 100점 매칭이어도 자격이 안 되면 못 들어가기 때문이다.
실데이터로 확인한 것. 초기 설계는 "과거 수주 이력"을 메인 시그널(α=0.7)로 잡았다. 실데이터에 돌려 보니 수주 이력이 매칭되는 회사가 1.1%에 그쳐 추천이 성립하지 않았다. "이 회사가 뭐 하는 회사인가"(등록업종·공급물품)를 메인으로 옮기고, 가중치를 회사 데이터 양에 따라 동적으로 정하는 쪽으로 피벗했다 (2026-05-25).
규모 (2026-11-05). 공고 누적 41.8만 건(지금 입찰 가능 약 9,500건), 계약 67.6만 건, 회사 19.6만 개(벡터 91,585). 나라장터 OpenAPI 8종을 GitHub Actions(매일 05:00 + 매시)로 누적한다.
상태. jodalfit.co.kr 운영 중. 이메일·구글·네이버 로그인, 검토함, 저장 회사 주간 메일, 어드민. 임베딩은 KURE-v1 운영 중이고 Gemini embedding-001 로 전환하기 위한 백필이 진행 중이다(아래 6장).
한국 공공조달(나라장터, G2B) 입찰공고 추천 사이트.
컨셉:
회사명/벡터 미확보 시에는 자유 키워드 모드로 폴백 — 콜드스타트에도 즉시 추천.
경쟁사 대비 차별화:
| 일반 입찰 알리미 | jodalfit |
|---|---|
| 키워드 알림 | 등록업종/공급물품 + 수주 이력 통합 임베딩 매칭 |
| 점수 없음 | 매칭 점수 + 게이지 + 적합도 라벨 |
| 이유 없음 | LLM이 "왜 추천했는지" 자연어 설명 ⭐ |
| 단일 공고 페이지만 | 발주계획 → 사전규격 → 공고 → 낙찰 → 계약 라이프사이클 페이지 ⭐ |
| 자격 미확인 공고 다수 | 자격(면허/지역/마감) 하드 필터 |
초기 설계는 수주 메인(α=0.7)이었으나, 실데이터 검증 결과 수주 매칭 커버리지가 1.1%에 그쳐 추천 자체가 불가능했습니다. "이 회사가 뭐 하는 회사인가"가 메인 시그널이고, 과거에 뭘 따냈는가는 보조라는 사용자 직관 + 코덱스 재검토를 반영해 γ(업종)을 메인으로 옮기고 가중치를 동적으로 산출합니다.
회사 벡터 = 3가지 시그널의 동적 가중합
회사 벡터 = α · 수주벡터 + β · 관심벡터 + γ · 업종벡터 (α+β+γ = 1, 회사 데이터별 동적)
| 회사 상태 | 업종 γ | 수주 α | 관심 β | 메모 |
|---|---|---|---|---|
| 수주 0건 (콜드스타트) | 1.00 | 0.00 | 0.00 | 등록업종만으로 추천 |
| 수주 1~5건 (균형) | 0.65 | 0.30 | 0.05 | 업종 메인, 수주 보조 |
| 수주 6건+ (수주 풍부) | 0.50 | 0.45 | 0.05 | 업종/수주 비등 |
시그널 소스
| 시그널 | 소스 |
|---|---|
| 업종(γ) | company_industries 등록업종 + company_supply_products 공급물품 + corp_bsns_div_nm + mnfctr_div_nm 텍스트 (회사당 1회 임베딩) |
| 수주(α) | contracts → 따낸 공고들의 bid_notices.embedding 평균 |
| 관심(β) | 사전규격 의견 (v0.2.1 — 회사명 매핑 후 활성화) |
가용한 시그널만 정규화해서 가중합 → 콜드스타트도 즉시 추천 가능. 회사 식별/벡터가 없으면 키워드 모드(자유 텍스트 → 직접 임베딩)로 폴백.
추천 파이프라인:
회사명 입력
↓
[1] 회사 식별 (pg_trgm fuzzy + 사업자번호 매칭)
↓
[2] 하드 필터 ← 못 들어가는 공고 제거 (자격/지역/마감/예산)
↓
[3] pgvector 코사인 검색 ← 통과 공고 중 TOP 100
↓
[4] 휴리스틱 rerank ← 마감 임박 패널티, 지역 매칭 보너스 등
↓
[5] LLM 설명 생성 ← Claude Haiku 4.5, ThreadPoolExecutor(5) 병렬 호출 (~3초)
↓
20건 + 매칭 이유 반환
핵심 통찰:
조달 단계마다 별도 OpenAPI가 있고, jodalfit은 모든 단계를 누적합니다.
[발주계획] → [사전규격(+의견)] → [입찰공고] → [낙찰/개찰] → [계약]
선행지표 SW식별, 관심신호 추천 대상 참여신호 수주신호
| 단계 | API 서비스 | 핵심 가치 |
|---|---|---|
| 발주계획 | OrderPlanSttusService | "1개월 전" 알림 가능 |
| 사전규격 | HrcspSsstndrdInfoService | swBizObjYn SW 사업 자동 필터 |
| 사전규격 의견 | 동일 (getPublicPrcureThngOpinionInfo*) | 회사 관심 신호 (콜드스타트 해결) |
| 입찰공고 | PubDataOpnStdService/getDataSetOpnStdBidPblancInfo | 추천 대상 공고 풀 |
| 입찰공고 자격 | BidPublicInfoService (면허제한/참가지역) | 자격 하드 필터 |
| 낙찰/개찰 | ScsbidInfoService | 참가 업체 정보 = 회사 3번째 시그널 |
| 계약 | PubDataOpnStdService/getDataSetOpnStdCntrctInfo | 사업자번호 → 수주 이력 |
| 회사 마스터 | UsrInfoService02 | 등록업종, 공급물품, 부정당 제재 |
| 업종 lookup | IndstrytyBaseLawrgltInfoService | 자격요건 매핑 |
flowchart LR
U[회사명 입력] --> FE[Next.js 16<br/>SEO 회사·공고 페이지]
FE -->|POST /recommendations| BE[FastAPI]
BE --> DB[(Supabase Postgres<br/>pgvector HNSW · pg_trgm)]
BE -->|추천 이유| LLM[Claude Haiku 4.5]
subgraph J[GitHub Actions · 매일 KST 5시 + 매시]
I[ingest 잡들<br/>나라장터 OpenAPI 8종] --> E[embed 잡들<br/>KURE-v1 · Gemini 백필] --> CV[compute_company_vectors]
end
CV --> DB
추천 요청 경로: 회사 식별(pg_trgm) → 자격 하드 필터 → pgvector 코사인 TOP 100 → 가중치 score + 협업 시그널 + MMR 다양성 → LLM 설명(병렬).
以上為 README 的開頭部分。其餘內容請閱讀原文。 檢視完整 README ↗