AI를 실제 제품에 붙일 때, 기본값을 의심해야 하는 세 가지 순간

AI를 실제 제품에 붙일 때, 기본값을 의심해야 하는 세 가지 순간

CSS 셀렉터 파싱·n8n 워크플로우 자동화·LangChain 캐시 교체—세 현장 사례가 함께 가리키는 것은 'AI 기본값'이 편의를 위해 설계되었지 당신의 제품을 위해 설계된 게 아니라는 사실이다

AI 워크플로우 LLM 연동 n8n 자동화 LangChain 캐시 CSS 셀렉터 시맨틱 캐시 프로덕션 설계
광고

AI를 제품에 붙이는 과정은 생각보다 훨씬 빠르다. API 키 발급, 몇 줄의 코드, 그리고 작동하는 프로토타입. 문제는 그 이후다. 실제 트래픽이 들어오고, 엣지 케이스가 터지고, 비용 청구서가 날아올 때—그때야 비로소 우리가 '기본값'을 그냥 믿었다는 걸 깨닫는다. 최근 dev.to에 올라온 세 편의 실전 사례는 서로 다른 맥락에서 출발하지만, 하나의 질문으로 수렴한다. AI 도구가 제공하는 기본 동작 방식이, 내 제품의 실제 요구와 정말 맞는가?


첫 번째 순간: 파서가 부서질 때마다 고치고 있다면

스타트업 채용 페이지를 스크래핑하던 한 개발자의 이야기는 낯설지 않다. 정성껏 작성한 CSS 셀렉터는 사이트가 리디자인될 때마다 부러졌고, 그 디버깅에 매번 몇 시간씩 사라졌다. XPath, 정규식, 스마트 스크래핑 라이브러리—모두 시도했지만 근본 문제는 해결되지 않았다. 구조가 바뀌면 파서도 부서진다.

전환점은 발상의 전환에서 왔다. HTML 구조를 이해하는 파서 대신, 의미를 이해하는 LLM에게 "여기 HTML 있는데, 채용 공고를 JSON으로 추출해줘"라고 부탁하는 방식이다. GPT-4o-mini에 정제된 HTML을 넘기면 사이트 구조가 바뀌어도 '채용 공고'라는 개념 자체를 이해하고 결과를 뽑아낸다. 비용도 놀라울 정도로 저렴하다—페이지당 3000토큰 기준으로 수 센트 수준이며, 이는 셀렉터 디버깅에 쏟는 개발자 시간 비용과 비교하면 압도적으로 합리적이다.

물론 LLM이 만능은 아니다. 필드를 할루시네이션하거나 마크다운 코드 펜스를 응답에 섞어 넣는 경우도 있다. 토큰 한계 때문에 HTML을 먼저 정제하고 잘라야 하고, 수만 페이지를 동일한 구조로 처리하는 대량 스크래핑 상황에선 고전적인 파서가 여전히 빠르고 저렴하다. 핵심 시사점은 이것이다—LLM을 쓸 때는 '구조를 어떻게 파싱할까'가 아니라 '무엇을 추출하고 싶은가'로 사고를 전환해야 그 도구가 진짜 힘을 발휘한다.


두 번째 순간: n8n 기본 노드가 내 요구와 맞지 않을 때

플랫폼 종속과 구독료를 피하려 n8n과 Gemini로 셀프호스팅 뉴스레터 엔진을 구축한 사례는, AI 워크플로우 설계의 트레이드오프를 생생하게 보여준다. 개발자가 첫 번째로 맞닥뜨린 벽은 CORS였다. n8n 웹훅은 기본적으로 크로스오리진 요청을 허용하지 않는다. 빠르게 테스트하려고 Access-Control-Allow-Origin: *로 열어두면 당장은 작동하지만, 프로덕션에선 어떤 외부 사이트도 내 DB에 쓰기 요청을 보낼 수 있는 구멍이 생긴다.

두 번째 함정은 더 교묘하다. Supabase에서 기존 구독자가 재구독할 때 upsert를 사용했는데, DB의 기본값(default gen_random_uuid())이 업데이트 시에는 재실행되지 않는다. 결과적으로 만료된 구 토큰이 재사용되는 보안 취약점이 발생했다. 해결책은 n8n 표현식으로 매번 새 UUID를 명시적으로 생성해 payload에 담는 것—DB 기본값을 신뢰하지 말고 직접 제어해야 한다는 교훈이다.

세 번째는 AI 노드 선택의 문제다. n8n에는 Gemini 연동을 위한 네이티브 노드가 있지만, 이 노드는 LangChain 추상화 위에 올라가 있어 대화형 모델에 최적화되어 있다. 뉴스레터 큐레이션처럼 엄격한 JSON 스키마를 단 한 번의 결정론적 응답으로 받아야 하는 상황에선 오히려 방해가 된다. 이 개발자는 네이티브 노드를 버리고 Gemini REST API를 직접 HTTP Request 노드로 호출하는 방식을 택했다. 시스템 인스트럭션, 온도, 응답 포맷을 완전히 통제할 수 있었고, 응답도 불필요한 래핑 없이 깔끔한 JSON으로 왔다. 편의를 위해 추상화된 노드가, 내가 원하는 제어 수준을 포기하게 만들고 있진 않은지 확인해야 할 순간이다.


세 번째 순간: 캐시가 있는데도 비용이 줄지 않을 때

LangChain의 내장 캐시는 분명히 작동한다. 동일한 프롬프트 문자열이 반복될 때 즉시 응답을 돌려주고 토큰 비용을 아껴준다. 그런데 실제 반복 워크플로우에서 '완전히 동일한 문자열'은 생각보다 훨씬 드물다. "1월 6일 주차 Acme Corp 보안 리포트 생성"과 "1월 13일 주차 Acme Corp 보안 리포트 생성"은 사람 눈에는 같은 작업이지만, 키-값 캐시 눈에는 전혀 다른 키다. 매주 같은 구조의 리포트를 만들면서도 매번 풀 LLM 호출이 발생하는 이유가 여기에 있다.

이 문제를 직면한 개발자는 LangChain 내장 캐시를 시맨틱 캐시 라이브러리(Mnemon-ai)로 교체했다. 의미적으로 유사한 프롬프트를 같은 캐시 엔트리로 매핑하는 방식으로, 반복 워크플로우에서 80% 히트율을 달성했을 때 하루 1000회 실행 기준 월 500달러 이상의 절감 효과가 나온다. 중요한 건 단순한 비용 절감이 아니다. 기본 캐시가 '작동하고 있다'는 사실이 오히려 '충분하다'는 착각을 만들어냈다는 점이다. 계측하지 않으면 기본값의 한계가 보이지 않는다.


세 사례가 함께 가리키는 것

이 세 이야기의 공통점은 놀랍도록 단순하다. CSS 파서, n8n 기본 노드, LangChain 내장 캐시—셋 다 분명히 '작동'했다. 문제는 제품의 실제 요구사항과 맞닥뜨리기 전까지는 그 한계가 보이지 않는다는 것이다. AI 도구의 기본값은 일반적인 사용 사례를 위해 설계되었지, 당신의 구체적인 제품 맥락을 위해 설계된 게 아니다.

빠른 프로토타이핑의 시대에 기본값은 강력한 출발점이다. 하지만 프로덕션으로 가는 길목에서는 반드시 한 번씩 물어봐야 한다. 이 추상화가 내 제어를 가리고 있진 않은가? 이 기본 동작이 내 보안 모델과 충돌하진 않는가? 이 캐시 전략이 내 워크플로우 패턴에 실제로 맞는가? AI를 제품에 붙이는 일은 API를 호출하는 게 아니라, 기본값 뒤에 숨겨진 가정을 하나씩 검증하는 과정이다.

전망은 역설적으로 낙관적이다. 기본값의 한계가 명확해질수록, 그 위에 더 정밀한 설계 선택지가 쌓인다. 시맨틱 캐시, 직접 REST 호출, LLM 기반 파서—이 선택들은 모두 '기본값을 의심한 결과'다. AI 도구가 더 정교해질수록 기본값도 더 스마트해지겠지만, 그 기본값이 내 제품의 특수성을 이해하는 날은 오지 않는다. 설계 판단은 여전히 개발자의 몫이다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요