새김 웍스
새김AI 검색 엔진을 다루는 개발자 콘솔이자 저장소 공통 디자인 규격.
새김 웍스는?
새김AI 검색 엔진을 다루는 개발자 콘솔이다. 자료를 지식베이스로 묶고, 검색 값을 밀어 시험하고, 그 조합을 「앱」으로 굳혀 MCP 주소로 내보낸다. works.saegim.studio에 올라가 있고, 허용목록에 든 계정만 로그인한다. 지금 쓰는 사람은 한 명이다.
같은 프로젝트에 이 저장소의 공통 디자인 규격(src/ui)이 산다. 토큰과 컴포넌트를 여기서 만들고, 콘솔 화면이 그 규격의 첫 시험대다.
역할은 이렇게 갈린다. 파싱·청킹·임베딩·검색은 새김AI 백엔드가 갖고, 웍스는 원본과 권한과 화면을 갖는다. 이 글은 화면 쪽 이야기이고, 엔진 쪽 판단은 새김AI에 있다.
그룹웨어로 시작했다
처음 이름은 대내 그룹웨어였다. 방이 넷이었다. 공지, 자원, 관제, 조직. 로그인은 구글 계정과 허용목록으로 열었고, 자원 방에 파일을 올리면 자동으로 태그와 설명이 붙고 본문이 색인됐다. 첫 주에는 브라우저 안에서 색인과 검색을 돌리다가 바로 걷어내고 새김AI의 RAG API에 맡겼다. 이 판단이 나중에 방향 전환의 씨앗이 된다.
한 달이 지나고 정리한 사실은 단순했다. 사용자가 한 명인 그룹웨어는 열 이유가 없다. 공지도 조직도 실제로 안 썼고, 관제 방은 끝까지 비어 있었다.
반대로 새김AI는 이미 도는 RAG 엔진인데 그걸 다룰 화면이 없었다. 원한 것은 그룹웨어가 아니라 내 파이프라인을 밖에서 써 보는 감각이었다. 그래서 2026-09-02에 웍스를 개발자 콘솔로 다시 정의했다.
첫 관문은 화면이 아니라 열쇠였다
막힌 지점은 인증이었다. 엔진을 부르는 길이 사람이 브라우저에서 로그인해야 생기는 토큰 하나뿐이라, MCP 서버도 야간 배치도 다른 앱도 문 앞에서 막혔다. 그래서 순서를 이렇게 잡았다.
판정 문장도 같이 적었다. P3까지 가서 MCP로 한 번이라도 실제로 찾아 썼는가. 안 썼으면 이 방향도 틀린 것이다. 2026-09-04에 편집기에서 MCP로 문서 하나를 찾아 썼다. 저장소 grep이 두 번 「없습니다」라고 답한 문서였다.
같은 문서에 안 만들 것도 적었다. 에이전트 스튜디오, 멀티테넌트, SSO, 에어갭 배포. 사용자가 한 명인 콘솔에서는 흉내다.
시험만 있고 결과물이 없었다
시험대가 생기자 다음 문제가 보였다. 손잡이를 밀어 좋은 조합을 찾아도 창을 닫으면 사라졌다. 그리고 MCP는 색인 전체를 여는 만능 열쇠 하나라, 「원두 자료만 보는 바리스타」 같은 도구를 따로 만들 수 없었다.
밖에서는 Dify가 이걸 푼다. 지식을 넣고, 붙이기 전에 검색을 시험하고, 그대로 MCP 도구로 발행한다. 놓친 것은 기능이 아니라 단위였다. 단위가 화면이 아니라 앱이다.
그래서 개념을 둘 만들었다. 자료를 목적별로 묶는 지식베이스, 그리고 지식 범위와 지침과 파라미터를 묶은 앱이다. 앱마다 MCP 주소가 따로 나간다.
claude mcp add --transport http barista \
https://api.saegim.studio/api/v1/rag/mcp/barista \
--header "X-Saegim-Key: sgk_..."
순서는 여섯 단계로 나눴고, 앞의 셋이 시험대였다. 밀어 봐야 무엇을 저장할지 정해지기 때문이다. 여섯 단계 전부 2026-09-07 하루에 구현했다. 다만 그날 검증은 타입 검사와 빌드와 순수 함수까지였고, 화면은 아무도 안 봤다. 사흘 뒤 실제로 눌러 보니 앱 발행이 한 번도 성공한 적이 없었다. 지침을 비우면 서버가 422로 거절하고 있었다. 이 이야기는 새김AI 쪽에 있다.
값을 그 창에서 다시 고치게 하면, 시험한 적 없는 값으로 앱이 발행된다. 그러면 시험대와 앱을 잇는 선이 끊긴다. 밀어 본 값이 그대로 앱의 초기값이 되고, 창은 이름만 붙인다.
만드는 화면과 쓰는 화면을 갈랐다
09-07에 네비를 셋으로 줄였다. 자료, 검색, MCP. 그런데 「검색」 한 판에 두 사람의 화면이 겹쳐 있었다. 왼쪽은 값을 미는 만드는 사람의 시험대, 오른쪽은 답을 받는 쓰는 사람의 채팅이다.
가르는 선을 한 문장으로 잡았다. 「답이 나왔나 안 나왔나」. 「왜 답이 없나」는 쓰는 사람도 묻지만, 「왜 저 문서를 안 봤나」는 만드는 사람만 묻는다. 그래서 09-10에 넷이 됐다.
두 화면은 대화 부품 하나를 같이 쓴다. 갈래는 role: 'publish' | 'use' 낱말 하나로만 가른다. 탭을 보일지, 떨어진 후보를 보일지 같은 boolean을 여섯 개 열면 화면이 둘이 아니라 조합 수만큼 생기고, 아무도 의도하지 않은 조합이 언젠가 한 번 렌더된다.
대화 이력은 두 화면이 따로 갖는다. 앞 턴이 다음 요청에 실려 가는 구조라, 발행에서 값을 바꿔 가며 태운 턴이 검색 첫 질문에 딸려 가면 쓰는 사람이 모르는 맥락이 답을 바꾼다.
색인은 수십 초, 화면은 한 마디
자료 하나를 색인하는 데 수십 초가 걸리는데 화면에는 「진행 중」 한 마디뿐이었다. 멈춘 것과 도는 것이 구별되지 않았다.
처음 나온 질문은 Redis를 중계로 둬야 하느냐였다. 아니었다. 색인 요청은 이미 열려 있는 긴 연결이고, 그 연결이 걸음을 다 안다. 옆에 두 번째 통로를 뚫을 이유가 없어서 같은 연결로 걸음을 흘렸다(SSE). 서버 쪽 배관은 답변 스트리밍 때 깔아 둔 것을 그대로 썼다.
화면에서 정한 것이 셋이다.
- 걸음은 상태 열이 아니라 이름 칸 둘째 줄에 둔다. 상태 열에 「설명 만드는 중」을 넣으면 폭을 넘치고, 상태 거르개 칩이 같은 낱말을 써서 둘 중 하나만 바꾸면 칩과 열이 다른 말을 한다.
- 서버 걸음 일곱을 화면 말 넷으로 묶는다. 묶는 기준은 「실패하면 다음에 할 일이 같은가」다.
- 진행률 막대를 안 만든다. 걸음 시간이 극단으로 불균등해서, 설명 만들기 한 걸음이 20~40초를 먹는다. 「3/7, 43%」가 30초 넘게 안 움직이는 막대는 멈춘 것처럼 보이는 화면을 고치려다 진짜 멈춘 막대를 세우는 일이다.
답변 스트림에는 중지가 있는데 색인에는 일부러 안 걸었다. 재색인은 옛 조각을 지우고 새 조각을 넣는 순서라, 중간에 끊으면 그 자료가 색인에서 통째로 사라진다. 돈이 나가는 단계는 맨 앞이라 멈춰서 아낄 것도 없다.
잃은 것도 하나 있다. 화면을 떠나면 걸음 표시가 사라진다. 색인은 끝까지 돈다.
평가 화면은 한 번 버렸다
다섯째 자리는 평가다. 지금 첫 평가는 AI가 법령의 위임 사슬을 끝까지 따라가는지 재는 BMT다. 처음 판(09-16)은 케이스를 나란히 놓는 비교 실험대로 그렸다가 통째로 버렸다. 문서만 보고 그렸고 채점 엔진(새김 Eval의 eval_core) 코드를 안 열어 본 탓이다. 평가 항목은 케이스가 아니라 평가의 종류였고, 화면에는 실제로 없는 채점 항목까지 들어가 있었다. 코드를 읽고 다시 쓰니 4분의 1 남짓으로 줄었다.
다시 쓰면서 정한 것들이다.
- 고르개 일곱이 한 줄에 같은 크기로 서 있어서 무엇부터 정할지 안 보였다. 평가 종류를 카드로 고르고 들어가 설정하는 두 걸음으로 나눴다.
- 카드에 지난 실행의 통과 수를 올리려다 뺐다. 고르는 자리에 수치가 서면 관제판이 되고, 정작 고를 것이 수치에 묻힌다.
- 값을 바꾸면 결과가 실제로 달라지는 고르개만 켜고, 아직 결과를 못 바꾸는 것은 자리만 두고 잠갔다.
- 「층 도달」이 늘 0으로 보여 오류처럼 읽혔다. 다섯 층을 모두 닿아야 통과하는 판정이라 이름을 「전층 도달」로 고쳤다.
- 값이 없는 칸은 하이픈, 0은 숫자 0으로 적는다. 없는 것과 0을 같은 모양으로 두지 않는다.
10-02에 이 화면이 부르는 곳을 운영 백엔드에서 이 맥에서만 도는 로컬 평가 엔진(saegim-bench)으로 갈아 끼웠다. 엔진이 로그인된 Claude Code 구독으로 모델을 부르기 때문에 127.0.0.1에만 뜨고, 남이 접속해 그 구독으로 돌리면 안 된다. 그래서 평가는 로컬 dev 서버에서만 돈다. 배포본에서 평가를 열면 「아직 쓸 수 없습니다」가 뜬다.
옮겨 오면서 원래 앞단의 어두운 테마 색 44개와 글자 크기 9종은 하나도 가져오지 않았다. 웍스 글자 단계는 넷이라 거기로 접었고, 새 색 여섯은 웍스 의미 토큰으로 바꿔 끼웠다.
정답지 화면
같은 날 정답지를 만들고 검토하는 화면을 평가 안에 들였다. 네비 여섯째가 아니라 평가 설정 안 한 단계 깊이다. 정답지 하나가 곧 평가 데이터셋 하나라서, 데이터셋 고르개 옆이 관리하는 자리다. 정답지가 없을 때 뜨던 막힘 문구도 「정답지 만들기」 단추로 바꿨다.
AI가 뽑은 초안은 사람이 확인하기 전 상태다. 경고처럼 노랑을 쓰고 싶어지는데, 막 만든 정답지는 문항 전부가 초안이라 화면이 노랑으로 찬다. 그러면 진짜 경고가 묻힌다. 중립 색에 아이콘으로 표시했다. 같은 이유로 「AI니까 보라」도 쓰지 않았다.
저장은 누르는 즉시 보내되 문항마다 줄을 세워 차례로 보낸다. 화면을 떠나도 보낸 것은 끝까지 간다. 질문과 층은 한 번에 하나만 고칠 수 있고, 고치는 동안 확인 완료와 이동을 막는다.
공통 디자인 규격
src/ui는 웍스의 부품 창고이자 이 저장소의 공통 규격이다. 2026-07-30에 독립 프로젝트로 만들었다가 같은 날 밤 웍스 안으로 들였다. 컴포넌트 폴더가 116개다(2026-10-06 기준).
규칙 하나는 실패에서 나왔다. 규격 컴포넌트를 만들면 같은 날 표본 페이지에 세운다. 08-01에 만든 컴포넌트 열한 개가 표본에 없었고, 결함을 화면에 조립한 뒤에야 발견하고 있었다. 표본에 세우자 15분 만에 다섯 개가 드러났다. 화면을 만들다 새로 생긴 부품도 화면 전용으로 두지 않고 규격으로 올린다. 정답지 화면 때 판정 표지, 빵부스러기, 표의 고르기 잠금, 복사 단추가 그렇게 올라갔다.
색 실험은 대부분 되돌렸다. 앱 셸 전체에 오로라를 깔고 크롬을 유리판으로 만든 한 벌, 로그인 오른쪽 판의 오로라, 참고 화면 없이 감으로 잡은 네비 장식 셋. 지금 오로라는 본문 칸 하나에만 있고 나머지는 블루 하나로 간다. 왼쪽 사진이 이미 비주얼을 맡은 로그인 화면에 오른쪽까지 색을 쓰면 주인공이 둘이 되고, 눌러야 할 버튼이 그 사이에 묻힌다.
기술 스택
- 화면: React 19 · TypeScript 5.9 · Vite 7 · 순수 CSS 커스텀 프로퍼티 · recharts
- 인증·저장: Firebase Auth(구글 로그인 + 허용목록) · Firestore
- 엔진: 새김AI RAG API(검색·색인·앱·MCP) · 로컬 평가 엔진 saegim-bench
- 배포: Vercel(
works.saegim.studio) · 비공개 미러 저장소
로그인은 아이패드 사파리에서 세 번 걸렸다. 팝업이 막혔고, 추적 방지 때문에 인증 페이지를 works.saegim.studio 아래로 옮겨야 했고, IndexedDB가 닫혀 로그인 유지를 localStorage 우선으로 바꿨다.
지금 상태와 남은 것
검증이 덜 된 것이 많다. 정직하게 적는다.
- 앱 발행 여섯 단계는 화면 검증 없이 올라갔고, 09-29에도 「앱 화면 미검증부터 점검」이 할 일로 남아 있다.
- 평가 화면은 디자인 검수를 거치지 않았다. 넓은 화면 정렬은 미리보기로만 봤다.
- 정답지 화면은 사용자 검증 전이다. 파일을 끌어다 놓는 동작은 실기로 안 해 봤다.
- 규격은 Chromium에서만 봤다. Firefox·Safari, 스크린 리더 실청취, 실기기 터치, 한글 IME는 미검증이다.
- 평가는 로컬에서만 돈다.
남의 앱을 담아 쓰는 마켓플레이스는 안 만들었다. 두 번째 사람이 실제로 로그인하는 날 꺼낸다. 지금 만들면 껍데기이고, 남의 앱을 담아도 그 사람의 지식베이스는 안 따라온다.
회고
웍스는 두 번 시작했다. 처음은 그룹웨어라는 모양에서 시작했고, 한 달 만에 쓸 이유가 없다는 걸 알았다. 두 번째는 「내 엔진을 다른 앱이 키로 부른다」는 한 번의 동작에서 시작했고, 판정 문장을 먼저 적었다. 두 번째가 굴러간 이유는 그 문장 하나다.
화면 쪽에서 반복된 것은 같은 실수의 다른 얼굴이었다. 문서만 보고 그린 평가 첫 판, 화면을 안 보고 「끝났다」고 적은 앱 발행, 감으로 잡았다가 되돌린 장식들. 그래서 이 프로젝트의 규칙 끝에는 이 줄이 있다. 화면은 사용자가 본다. 무엇을 어디서 고쳤는지만 보고하고, 좋아졌는지는 말하지 않는다.