Lattice - 1

Lattice

서비스 중

벤처캐피탈이 스타트업을 발굴하고 투자한 뒤 관리까지 하는 과정을 한 곳에서 처리하는 업무 플랫폼 - AI 에이전트를 붙여 문서 입력·기업 분류·리포트 분석을 자동화

Next.js 16React 19TypeScriptTailwind CSSSupabasePostgreSQLEdge FunctionsTanStack QueryMCPOpenAISlack APIRedisVitestPlaywrightVercel

주요 기능 개발

Lattice는 벤처캐피탈(VC)이 스타트업을 발굴하고, 심사하고, 투자한 뒤 사후관리까지 하는 전 과정을 한 곳에서 처리하는 업무 플랫폼입니다. 투자사·운영사· 스타트업·관리자 네 종류의 사용자가 같은 데이터를 서로 다른 권한으로 보기 때문에, 기능 하나를 추가할 때마다 "누가 무엇을 볼 수 있는가"를 함께 설계해야 했습니다.

2026년 3월부터 합류해 정부 지원 사업 운영, 외부 공개 API, 지원 접수 시스템, 그리고 투자 업무 전반에 AI를 붙이는 작업까지 맡았습니다.

1. TIPS 프로그램 운영 — 엑셀로 하던 일을 제품 안으로

TIPS는 VC가 정부 예산으로 스타트업을 추천하는 제도입니다. 추천권이 몇 장 남았는지, 어느 기업이 어느 단계에 있는지를 틀리면 안 되는데 담당자가 엑셀로 관리하고 있었습니다. 이 흐름 전체를 제품 안으로 옮겼습니다.

  • 기수 생성 → 참여 기업 선택 → 단계별 자료 제출 → 사후관리까지의 진행 상태를 정의하고, 추천권 소진 현황을 자동으로 집계
  • 단계마다 제출 양식과 마감을 따로 두고 승인·반려 이력을 남겨, 담당자가 판단 근거를 되짚을 수 있게 구성
  • 가장 어려운 부분은 권한 분기였습니다. 심사역·운영 담당자·조력자· 창업기업이 같은 화면에서 서로 다른 것을 봐야 해서, 화면 진입부터 개별 동작까지 역할별로 갈랐습니다
  • 운영자가 직접 데이터를 확인하도록 연도 필터와 엑셀 내보내기를 추가 — 개발자에게 조회를 요청하던 흐름을 없앰

2. Track — 외부 홈페이지가 내부 데이터를 안전하게 쓰게 하는 경계

VC가 대기업과 함께 프로그램을 운영할 때, 프로그램 홈페이지는 외부에 있고 지원자 데이터는 VC 내부에 있어야 합니다. 내부 데이터베이스를 열어줄 수는 없으니 외부에 공개하는 API를 새로 설계했습니다.

  • 회사 단위로 API 키를 발급해, 외부 사이트가 자기 회사 데이터에만 닿도록 경계를 설정
  • 이 공개 API를 본 서비스와 다른 실행 환경으로 분리 — 외부 트래픽이 몰려도 내부 서비스가 함께 느려지지 않게 하기 위함
  • 프로그램·뉴스·갤러리·약관까지 콘텐츠 전반을 어드민에서 관리하고 내보내, 외부 홈페이지에 고정된 문구가 남지 않게 설계
  • 이 API의 첫 사용자가 저였습니다. InBodyLIKE 홈페이지를 직접 붙이면서 스펙의 빈틈을 사용자 입장에서 먼저 발견했고, 신청서 수정·약관 본문 같은 기능이 여기서 나왔습니다

3. 공개 신청·자료 제출

프로그램마다 지원 양식이 다르기 때문에 양식을 코드에 적어두지 않고 데이터로 정의했습니다. 새 프로그램이 열려도 개발 없이 양식을 바꿀 수 있습니다.

  • 첨부 파일은 서버를 거치지 않고 저장소로 바로 올리고, 제출이 확정된 파일만 정식 경로로 옮겨 제출되지 않은 파일이 쌓이지 않게 처리
  • 마감 전까지는 신청서를 다시 열어 수정·재제출할 수 있도록 허용
  • 접수되면 지원자에게는 알림톡으로, 운영자에게는 메일로 각각 통보

4. Lattice AI — 투자 업무 전 단계에 AI 붙이기

사내 AI 시스템을 Lattice에 연결해 발굴부터 사후관리, 질의응답까지 AI를 넣는 프로젝트입니다. 설계의 출발점은 "AI 인프라를 새로 만들지 않는다"였습니다. Lattice는 작업을 요청하고 결과를 화면에 보여주는 역할만 맡고, 실제 추론은 기존 AI 시스템이 담당하도록 역할을 나눠 범위를 좁혔습니다.

  • 문서 자동 입력 — IR 문서를 올리면 기업 등록 양식이 저절로 채워짐
  • 콜드콜 자동 분류 — 홈페이지로 들어온 기업을 자동으로 분류하고 담당 심사역까지 배정
  • 투자 적합도 분석 — 투자사 고유 기준으로 기업을 채점하고 기존 포트폴리오와 비교
  • 리포트 분석과 요약 갱신 — 분기보고가 끝나면 이상 징후를 짚어주고, 미팅노트를 저장하면 기업 요약 카드의 수정안을 제안
  • 사내 데이터를 아는 챗봇 — 서비스 안의 챗봇과 Slack 봇으로 질문에 답하고 결재까지 처리

여기서 중요한 판단이 하나 있었습니다. 처음에는 AI에게 필요한 데이터를 전부 요청에 담아 보냈는데, 구성원이 늘어나자 요청이 허용 크기를 넘겨 접수 자체가 거부됐습니다. 그래서 데이터를 밀어 넣는 대신 AI가 필요할 때 직접 가져가도록 조회 창구를 따로 만들었습니다. 요청에는 "무엇을 처리하라"만 남아 크기 문제가 사라졌고, 권한 판정을 그 창구 한 곳에 모을 수 있었습니다. 화면에서 되는 검색이 챗봇에서는 안 되는 괴리를 없애기 위해 조회 조건도 화면과 동일하게 맞췄습니다.

AI 작업은 실패해도 조용히 실패하기 때문에, 개발자가 로그를 보지 않으면 아무도 모른다는 점이 문제였습니다. 그래서 비개발자도 직접 파이프라인을 확인할 수 있는 테스트 페이지를 만들고 접근 권한을 제한해 두었습니다.


트러블 슈팅 경험

1. 두 서비스가 서로를 부르다 요청이 통째로 막힌 문제

AI 분석을 접수하는 지점에서 요청이 막혔습니다. 받는 쪽 서비스의 기록에는 요청이 도착한 흔적조차 없었고, 보내는 쪽에는 문서에 없는 오류 코드만 남았습니다.

원인

두 서비스가 같은 호스팅(Vercel)에 올라가 있는 것이 원인이었습니다. 이 호스팅은 "요청이 요청을 부른" 횟수를 기록해 두다가 일정 깊이를 넘으면 무한 반복으로 간주하고 차단합니다. 그런데 이 시스템은 AI 쪽이 결과를 돌려주고 그 결과를 받아 다음 작업을 다시 접수하는 구조라, 주고받을수록 사슬이 깊어졌습니다. 서비스 코드에 닿기도 전에 잘리기 때문에 원인을 알려주는 정보도 없었습니다.

해결

사슬을 끊으려면 이 호스팅 바깥에서 요청을 새로 시작해야 한다는 결론에 도달했습니다. 나가는 요청만 다른 환경을 한 번 거치도록 만들자 사슬이 처음부터 다시 세어졌습니다. 중계를 만들면서 세 가지를 지켰습니다.

  • 응답을 변형 없이 그대로 통과시켜, 중계 때문에 호출한 쪽의 재시도 판단이 달라지지 않게 함
  • 아무나 호출하지 못하도록 내부 비밀값을 안전한 방식으로 대조
  • 요청 본문에 키가 들어 있어 오류 기록에도 민감하지 않은 정보만 남기고, 개인정보를 열 수 있는 키는 아예 이 중계에 주지 않음

중계가 실패하면 직접 호출로 되돌아가도록 두어, 인프라 한 조각이 빠져도 기능이 죽지 않게 했습니다.

2. 몇 분씩 걸리는 AI 작업이 중간에 끊기던 문제

AI 작업 상태가 "진행 중"에서 영원히 내려오지 않는 현상이 반복됐습니다. 사용자 화면에는 로딩만 계속 돌았습니다.

원인

처음에는 AI에 요청을 보내고 결과가 올 때까지 기다리는 방식이었는데, 작업 하나가 2~5분씩 걸렸습니다. 서버 함수에는 최대 실행 시간이 있어서 그 한도에 걸려 연결이 끊기면, AI는 계속 일하는 중인데 결과를 받을 쪽이 이미 사라져 있는 상태가 됩니다.

해결

기다리는 방식을 버리고 맡겨두고 끝나면 연락받는 방식으로 바꿨습니다. 요청과 함께 "끝나면 여기로 알려달라"는 주소를 넘기면 AI 쪽은 접수만 확인하고 바로 응답하고, 완료 시점에 그 주소로 결과를 보냅니다. 접수만 하고 종료하니 실행 시간 한도와 무관해집니다.

대신 새로 생기는 문제가 중복 접수입니다. 재시도하면 같은 작업이 두 번 돌 수 있습니다. 그래서 작업마다 고유한 표시를 붙여 한 번만 접수되도록 하고, 결과 역시 같은 자리를 덮어쓰는 방식이라 여러 번 도착해도 같은 결과가 되게 했습니다. 재시도할 오류와 즉시 실패시킬 오류도 구분해, 사용자에게 이유를 보여줄 수 있게 정리했습니다.

3. AI가 쓴 문장에 내부 번호와 비밀 키가 섞여 나온 문제

QA에서 두 종류의 누출이 잡혔습니다. 사람이 읽는 문장 한가운데 36자리 기계용 번호가 그대로 들어가 있었고, 화면 일부에는 서버가 쓰는 접근 키의 원문이 노출되고 있었습니다.

원인

둘 다 "AI에게 그렇게 쓰지 말라고 지시하면 된다"는 가정이 틀렸다는 점이 공통 원인이었습니다. 프롬프트에 아무리 적어도 AI 문장을 그대로 싣는 자리가 여러 곳이면 어딘가에서 다시 샙니다. 지시는 근본 처방이지만 유일한 방어선이 될 수 없었습니다.

해결

지시 아래에 코드로 한 겹 더 걸러내는 그물을 깔았습니다. 기계용 번호는 사람이 읽는 서술 문장에만 지웠습니다. 데이터 항목까지 똑같이 지우면 기업을 구분하는 실제 값이 사라져 비교표가 깨지기 때문에, 적용 범위를 좁히는 것이 핵심이었습니다. 키 가리기는 전달 형태를 하나라도 놓치면 전부 통과한다는 점을 전제로 패턴을 겹쳐 두었습니다.

이 처리를 기록뿐 아니라 사용자에게 보이는 모든 지점에서 공용으로 쓰도록 만들어, 새로운 노출 자리가 생겨도 같은 방어가 따라가게 했습니다.