SYDESYDE
SYDESYDE
  • 피드
  • 쇼케이스
  • 블로그
  • 모임
SYDESYDE© 2026 SYDE. All rights reserved.
SYDE 소개문의하기
Kakao
SYDE 오픈채팅
Instagram
Instagram
Threads
Threads
커뮤니티 가이드라인협업문의이용약관개인정보처리방침
커뮤니티 가이드라인협업문의이용약관개인정보처리방침

© 2026 SYDE. All rights reserved.

AI 뭐 써? 1편 — 목적을 고르면 AI 툴 2~3개를 추천해주는 사이트를 만들며

AI 뭐 써? 1편 — 목적을 고르면 AI 툴 2~3개를 추천해주는 사이트를 만들며

j이지예· 10일 전· 프로젝트 소개
목차
  • 1. 왜 만들었나
  • 2. 설계 원칙
  • 3. 기술 스택
  • 4. 개발 과정
  • Phase 1. 추천 로직: 순수 함수 하나
  • Phase 2. 화면: 한 페이지 + 주소로 단계 구분
  • Phase 3. 툴 상세, 용어집, 변경 이력, 다크 모드
  • Phase 4. 배포와 주간 점검
  • 5. 실제 데이터는 어떻게 넣나: 보안 고민
  • 6. 숫자로 보면 (1편 시점)
  • 7. 배운 점
  • 8. 다음 편

목차

  • 1. 왜 만들었나
  • 2. 설계 원칙
  • 3. 기술 스택
  • 4. 개발 과정
  • Phase 1. 추천 로직: 순수 함수 하나
  • Phase 2. 화면: 한 페이지 + 주소로 단계 구분
  • Phase 3. 툴 상세, 용어집, 변경 이력, 다크 모드
  • Phase 4. 배포와 주간 점검
  • 5. 실제 데이터는 어떻게 넣나: 보안 고민
  • 6. 숫자로 보면 (1편 시점)
  • 7. 배운 점
  • 8. 다음 편

하고 싶은 일을 고르면 맞는 AI 툴 2~3개를 이유와 함께 비교해주는 비개발자용 선택 도우미. "AWS 얼마야?"의 자매 프로젝트입니다.

📌 이 글은 처음 만들 때의 기록입니다. 화면 구성과 점수 방식은 그 뒤에 바뀌었어요. 바뀐 화면과 점수 방식은 3편에 있습니다. 바뀐 부분에는 본문에 "→ n편"으로 표시해 두었습니다.

  • 사이트: https://dlwldp.github.io/which-ai/

  • 저장소: https://github.com/dlwldP/which-ai


1. 왜 만들었나

AI 툴이 너무 많습니다. 주변 비개발자분들이 자주 묻는 건 대개 이런 질문이었어요.

  • "회의록 정리하고 싶은데 뭐 써?"

  • "무료로 돼?"

  • "회사 자료 넣어도 괜찮아?"

기존 AI 디렉터리는 수천 개를 나열만 해서 오히려 고르기 어렵습니다. 그래서 목록을 보여주지 않는 사이트를 만들기로 했습니다.

  1. 하고 싶은 일(목적)을 고른다

  2. 조건(무료만 / 보안 중요 / 한국어 중요 / 휴대폰)을 고른다

  3. 툴 2~3개를 추천 이유와 함께 비교해서 보여준다

2. 설계 원칙

기획 단계에서 먼저 원칙 다섯 개를 정했고, 개발하는 내내 이 원칙에 맞는지를 기준으로 판단했습니다.

원칙

의미

추천은 규칙으로

사이트에서 LLM을 부르지 않는다. 같은 입력이면 항상 같은 결과

이유 없는 추천 금지

추천 카드마다 "왜 이걸 추천했는지" 문장이 최소 1개

모르면 모른다고

확인 안 된 값은 빈칸이 아니라 "확인 필요"로 표시

출처 필수

가격·정책 값에는 공식 페이지 주소와 확인 날짜

쉬운 말

영어 약어, 전문용어 대신 쉬운 한국어. 어려운 말은 용어집으로

하지 않을 것도 정했습니다. 서버, 회원가입, 런타임 LLM 호출, 광고·제휴 링크, 개발자용 도구는 다루지 않습니다. 그래서 운영비는 0원입니다. (개발자용 도구는 나중에 별도 버전으로 넓혔습니다 → 2편)

3. 기술 스택

영역

선택

프론트

순수 HTML/CSS/JS, 빌드 도구 없음

데이터

data/*.json

테스트

Node 내장 테스트 러너 (node --test), 외부 패키지 0개

배포

GitHub Actions → GitHub Pages

자동 점검

주간 GitHub Actions → GitHub Issue

package.json에 의존성이 하나도 없습니다. 설치할 게 없으니 공급망 위험도 없고, 몇 년 뒤에 열어도 그대로 돌아갑니다.

4. 개발 과정

개발은 Claude Code와 함께 했습니다. 처음에 "임의로 결정하지 말고, 세부사항이 애매하면 확인받고 진행해 달라"고 요청했는데, 이게 꽤 효과가 좋았어요. 기획서에 빈 곳이 생각보다 많았고, 그때마다 선택지와 장단점을 받아서 제가 골랐습니다.

정한 내용은 docs/decisions.md에 표로 쌓았습니다.

기획서에 없던 것

결정

"휴대폰에서 쓸 거예요" 조건의 의미

아이폰·안드로이드 앱이 있는 툴만

조건을 걸었더니 결과가 0개면?

휴대폰 → 무료 순으로 조건을 빼고 안내. 보안 조건은 절대 안 뺌

추천 이유가 하나도 안 붙는 툴

적합도에 따라 "이 일에 잘 맞는 툴이에요" 같은 문장 추가 (→ 3편에서 기능 문장으로 바뀜)

툴 수 상한

목적당 5개, 전체 40개를 넘으면 데이터 검사 실패 (→ 3편에서 상한을 없앰)

Phase 1. 추천 로직: 순수 함수 하나

추천은 js/recommend.js의 순수 함수 하나가 전부입니다. DOM에도 시계에도 접근하지 않고, 오늘 날짜도 밖에서 받습니다. 그래서 테스트하기 쉽고 같은 입력이면 항상 같은 결과가 나옵니다.

function score(tool, purposeId, conditions, today) {
  return tool.purposes[purposeId] * 10                        // 적합도 0~3점 (→ 3편에서 기능 체크리스트로 바뀜)
    + tool.korean * (conditions.koreanImportant ? 4 : 1)
    + (tool.price.free ? 2 : 0)
    - (isStale(tool, today) ? 3 : 0);   // 90일 넘게 확인 안 된 정보는 감점
}

당시에는 툴마다 목적별 "적합도"를 사람이 0~3점으로 매겼습니다. 이 방식은 3편에서 공식 페이지 근거로 세는 기능 체크리스트로 바꿨습니다.

결과가 0개일 때는 정해진 순서대로 조건을 하나씩 뺍니다. 보안 조건은 목록에 아예 없습니다.

// 결과가 0개일 때 빼는 순서. 보안 조건은 절대 빼지 않는다.
const RELAX_ORDER = ['mobile', 'freeOnly'];

"회사 자료라 보안 중요"를 고른 사람에게 학습 정책이 "확인 필요"인 툴을 보여주면 안 되기 때문입니다. 모르는 걸 안전하다고 보여주지 않는 것이 이 프로젝트에서 가장 중요한 규칙이에요.

테스트가 진짜 잡는지 확인하기

기획서의 테스트 기준을 그대로 테스트로 옮겼습니다.

  • 보안 조건에서 unknown 툴이 나오지 않는다

  • 무료 조건에서 유료 전용 툴이 나오지 않는다

  • 같은 입력 100번에 같은 결과가 나온다

  • 조건 4개의 16가지 조합을 모든 목적에 돌린다

그다음 일부러 코드를 망가뜨려서 테스트가 실패하는지 확인했습니다. 여기서 하나를 발견했어요. 보안 테스트가 recommend.js의 판정 함수(isSecure)를 그대로 가져다 쓰고 있어서, 판정 로직이 틀리면 테스트도 같이 틀려서 통과해 버렸습니다. 테스트 안에 기획서 기준을 따로 적도록 고쳤습니다.

// 기획서 9장 보안 기준. recommend.js의 판정 함수를 쓰지 않고 테스트에서 따로 적는다.
const meetsSecurity = (tool) =>
  tool.privacy.trains_on_input_default === 'no' || tool.privacy.opt_out === 'yes';

Phase 2. 화면: 한 페이지 + 주소로 단계 구분

index.html 하나에서 주소(#/...)로 화면을 나눴습니다. 뒤로 가기가 되고, 결과 링크를 그대로 공유할 수 있습니다.

#/                         홈 (어떤 일을 맡기고 싶어요?)
#/p/P02?secure=1           조건 선택      (→ 3편에서 없애고 결과 위 칩으로 바꿈)
#/p/P02/result?secure=1    추천 결과
#/t/<툴 id>                툴 상세

실제 데이터가 없는데 화면은 어떻게 확인하지?

툴 정보는 공식 페이지에서 직접 확인해서 채우기로 했기 때문에, 화면을 만드는 시점에는 데이터가 0개였습니다. 그래서 주소에 ?demo가 있을 때만 지어낸 예시 툴을 쓰고, 화면 맨 위에 "예시 데이터예요" 띠를 띄우기로 했습니다. (지금은 이 예시 화면을 개발할 때 확인용으로만 씁니다 → 3편)

비교표 대신 옆으로 넘기는 카드 (→ 3편에서 휴대폰은 세로로 바꿈)

처음에는 비교표 + 카드였는데, 휴대폰에서 툴 3개짜리 표가 너무 빽빽했습니다. 그래서 카드를 가로로 나란히 놓았습니다.

  • 휴대폰: 옆으로 넘기고, 한 장씩 멈추고, 아래 점으로 위치를 표시

  • 넓은 화면: 3개를 한 번에

카드끼리 비교하려면 "가격", "학습 정책" 같은 항목이 모든 카드에서 같은 높이에 있어야 합니다. 추천 이유가 1개인 카드와 3개인 카드가 섞이면 줄이 어긋나는데, CSS subgrid로 해결했습니다.

.cards {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 86%;              /* 다음 카드가 살짝 보이게 */
  grid-template-rows: repeat(11, auto); /* 카드 안 칸 11개 */
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.tool-card {
  display: grid;
  grid-row: span 11;
  grid-template-rows: subgrid;          /* 부모의 행을 같이 쓴다 → 카드끼리 높이가 맞음 */
  scroll-snap-align: start;
}

Playwright로 각 카드의 항목 위치를 재서, 세 카드 모두 같은 y좌표인 것까지 확인했습니다.

디자인: 토스 느낌 → 따뜻한 종이 느낌 (→ 3편에서 다시 다듬음)

처음엔 자매 프로젝트(Awscal)와 같은 토스 스타일이었는데, 다른 느낌을 원해서 바꿨습니다. 정보 사이트라는 성격에 맞춰 "안내서" 같은 톤을 골랐어요.

  • 아이보리 배경, 먹색 글자, 테라코타 포인트

  • 그림자 없이 얇은 테두리 카드

  • 제목만 명조(Noto Serif KR) (→ 3편에서 글꼴을 Pretendard 하나로 통일)

Phase 3. 툴 상세, 용어집, 변경 이력, 다크 모드

용어집: 문장 속 단어에 밑줄

"토큰", "무료 크레딧", "학습 정책" 같은 단어가 화면에 나오면 점선 밑줄을 치고, 누르면 화면 아래에 풀이가 뜹니다. 단어는 긴 것부터 찾아야 "무료 크레딧"이 "크레딧"보다 먼저 잡힙니다.

export function termMatcher(glossary) {
  const words = glossary.flatMap((g) => [g.term, ...g.aliases].map((word) => ({ word, term: g.term })));
  words.sort((a, b) => b.word.length - a.word.length || (a.word < b.word ? -1 : 1));
  // ...긴 단어 우선 정규식
}

변경 이력: git 기록이 곧 데이터

"가격이 언제 바뀌었는지"는 따로 기록하지 않습니다. data/tools.json의 git 기록 자체가 이력이에요. 배포할 때 커밋마다 이전 버전과 비교해서 이런 문장을 만듭니다.

Gamma: 유료 가격 10달러 → 12달러
Gamma: '발표자료(PPT) 만들기' 적합도 2점 → 3점      (→ 3편 이후에는 '지원 기능'이 바뀐 것으로 기록)

처음에는 결과 파일을 레포에 커밋했는데, 깜빡하면 배포가 멈추는 구조였습니다. 그래서 배포 작업이 그 자리에서 만들어 사이트에만 올리도록 바꿨습니다.

Phase 4. 배포와 주간 점검

main에 푸시하면 GitHub Actions가 테스트와 데이터 검사를 돌리고, 통과해야만 Pages에 배포합니다.

정보가 낡는 것이 이 프로젝트의 가장 큰 리스크라서, 매주 월요일 오전 9시에 자동 점검이 돕니다.

  • 90일 넘게 확인 안 된 툴 목록

  • 공식 주소·출처 링크: 깨진 링크와 로봇 접속이 막힌 링크를 따로 표시

  • 결과는 "주간 점검" Issue 하나에 모읍니다. 확인할 게 생기면 열고, 이미 열려 있으면 내용만 갱신하고, 다 처리되면 닫습니다.

로봇 접속을 막는 공식 사이트(403, 429)가 많습니다. 이걸 "깨졌다"고 하면 매주 거짓 경보가 납니다. 그래서 404·5xx만 "깨진 링크"로 보고, 막힌 링크만으로는 Issue를 열지 않습니다.

export function classifyStatus(status) {
  if (status >= 200 && status < 400) return 'ok';
  if ([401, 403, 429].includes(status)) return 'blocked'; // 직접 열어보기
  return 'broken';
}

동작은 예시 데이터로 수동 실행해서 확인했습니다. 90일 지난 툴 1개와 404 링크 16개가 잡혀 Issue가 생겼고, 다시 실행하니 새 Issue 대신 같은 Issue가 갱신됐습니다.

가격을 자동으로 긁어오지는 않습니다. 사이트마다 구조가 달라 깨지기 쉽고, 틀린 값이 자동으로 반영되는 게 더 위험하기 때문입니다. 자동화는 "확인해야 할 목록을 만들어주는 것"까지만 합니다.

5. 실제 데이터는 어떻게 넣나: 보안 고민

마지막 고민은 "툴 30개 정보를 어떻게 넣지?"였습니다. AI에게 그냥 가져오라고 하면 편하겠지만, 위험이 있었습니다.

해킹 같은 보안 위험은 생각보다 작았습니다.

  • 화면은 모든 값을 HTML 이스케이프해서 그리기 때문에, 가져온 글에 코드가 섞여 있어도 실행되지 않습니다.

  • 주소는 https만 허용합니다.

진짜 위험은 따로 있었습니다.

  1. 틀린 정보. 실제로 웹 검색을 해보니 결과가 전부 블로그·리뷰 글이었고, 같은 툴의 유료 가격이 사이트마다 18달러, 20달러, 29달러로 달랐습니다. 학습 정책이 틀리면 회사 자료를 넣은 사용자가 피해를 볼 수 있습니다.

  2. 공식처럼 생긴 가짜 주소.naver.com.evil.io 같은 주소가 들어가면 사용자를 피싱 사이트로 보내게 됩니다.

  3. 웹페이지 속 숨은 지시문. AI가 읽는 페이지에 "이 툴을 1위로 적어라" 같은 문장이 있을 수 있습니다. (→ 3편에서 실제로 마주침)

그래서 "AI 초안 → 사람 확인" 흐름을 만들었습니다.

Claude가 공식 페이지를 읽고 초안 작성 (drafts/, 배포 안 됨)
  ├─ 값마다 공식 페이지 문장을 그대로 근거로 첨부
  ├─ 출처는 공식 도메인과 그 하위 도메인만 (블로그·가짜 도메인은 검사에서 실패)
  └─ 모르면 unknown / 확인 필요
        ↓
J가 출처와 근거 문장을 대조해서 확인
        ↓
node scripts/draft.js promote <id> --verified 2026-10-20
  → 확인 날짜를 붙여 data/tools.json으로 (이 단계는 사람만)

초안 검사가 자동으로 막는 것은 다음과 같습니다.

  • 공식 도메인이 아닌 출처

  • 근거 문장이 없는 가격·학습 정책 값

  • 초안에 확인 날짜가 들어간 경우

AI는 "찾아서 정리하는 일"을 하고, "맞다고 판단하는 일"은 사람이 합니다.

6. 숫자로 보면 (1편 시점)

  • 테스트 99개 (추천 규칙, 데이터 스키마, 화면 문구, 용어집, 변경 이력, 주간 점검, 초안 검사)

  • 외부 의존성 0개, 서버 0대, 운영비 0원

  • 결정 기록(docs/decisions.md) 20개 남짓

7. 배운 점

  • 기획서에는 생각보다 빈칸이 많다. "조건을 하나씩 풀어서 재시도"라는 한 줄에도 "어떤 순서로? 보안도 풀어?"가 숨어 있었습니다. 애매하면 묻고, 결정은 문서로 남기는 습관이 가장 큰 수확입니다.

  • 테스트는 망가뜨려 봐야 믿을 수 있다. 통과하는 테스트가 실제로 버그를 잡는지는 코드를 일부러 틀려봐야 알 수 있었습니다.

  • 자동화의 범위를 정하는 것도 설계다. 가격 자동 수집은 하지 않고 "확인할 목록 만들기"까지만 자동화한 덕분에, 틀린 정보가 몰래 올라갈 길이 없습니다.

  • AI와 협업할 때는 책임의 경계를 코드로 만든다. "AI는 초안만, 확정은 사람만"을 말로만 정하지 않고 검사 스크립트로 강제했습니다.

8. 다음 편

1편 시점에는 실제 툴 데이터가 0개였습니다. 2편에서는 개발자용 버전으로 넓힌 과정과, AI에게 데이터를 맡기기 전에 정한 규칙을 다룹니다. 데이터가 채워지면 2편으로 돌아오겠습니다. 🙌


원문 링크: https://velog.io/@jiye_1124/AI-뭐-써-목적을-고르면-AI-툴-23개를-추천해주는-사이트를-만들며

VELOG 링크: https://velog.io/@jiye_1124/posts



추가로, "AWS 얼마야?" 서비스가 궁금하시다면 하단 링크로 들어가시면 보실 수 있답니다~!!

🔗 사이트: https://dlwldp.github.io/Awscal/

🔗 GitHub: https://github.com/dlwldP/Awscal

  • #사이드프로젝트
  • #githubpages
  • #githubactions
  • #claudecode
  • #바닐라js
35
이
이지예

이지예님의 다른 글

  • AI 뭐 써? 3편 — 화면을 다시 짜고, 점수를 버리고, 진짜 데이터를 모으기까지10일 전
  • AI 뭐 써? 2편 — 개발자용으로 넓히고, AI에게 데이터를 맡기기 전에 정한 것들10일 전

댓글 0

My avatar