pgvector를 활용하여 이커머스 판매자를 위한 자체 개선 AI 답변 시스템 구축기
요약
본 글은 pgvector를 활용하여 이커머스 판매자를 위한 자체 개선 AI 답변 시스템 구축 과정을 설명합니다. 단순히 LLM을 호출하는 것을 넘어, 셀러가 승인한 답변 데이터를 벡터 DB에 저장하고 이를 퓨샷 예시로 프롬프트에 포함시켜 모델의 성능과 브랜드 일관성을 높이는 것이 핵심입니다.
핵심 포인트
- pgvector를 활용하여 별도 벡터 DB 없이 Postgres에서 유사 질문/답변을 검색합니다.
- 승인된 답변 데이터를 퓨샷 예시로 사용해 LLM이 셀러 고유 패턴을 학습하게 합니다.
- 제품 컨텍스트, 브랜드 목소리, 규칙 등 다중 레이어 프롬프트 조립으로 답변의 품질을 높였습니다.
터키의 마켓플레이스 셀러들은 끊임없이 고객 질문을 받습니다. “이 테이블 방수되나요?”, “작은 발코니에 들어갈까요?”, “왜 리뷰가 이렇게 안 좋은가요?” 등입니다. 답하지 못한 모든 질문은 놓친 판매 기회이며, 하루 종일 사려 깊은 답변을 작성하는 것은 규모를 확장하기 어렵습니다.
저는 Trendyol 셀러들을 위한 수익 분석 도구인 Netaliz를 구축하면서, 이러한 질문에 대한 답변 초안을 작성하는 AI 모듈을 추가했습니다. 흥미로운 부분은 단순히 LLM(Large Language Model)을 호출하는 것이 아니라, 셀러가 답변을 승인할 때마다 시스템이 더 똑똑해지게 만드는 것입니다.
작동 방식은 다음과 같습니다.
‘그냥 프롬프트에 넣기’의 문제점
저의 첫 번째 버전은 간단했습니다. 제품 정보와 질문을 LLM에 보내 답변을 받는 것이었습니다. 작동은 했지만, 다음 문제가 있었습니다:
- 답변이 일반적이라 셀러 브랜드의 느낌이 나지 않았습니다.
- 모델이 셀러 고유의 규칙(“배송은 항상 1~3 영업일이 걸린다고 말해야 한다”)을 알지 못했습니다.
- 학습되는 것이 없었기 때문에 같은 스타일적 실수를 반복했습니다.
셀러들은 거의 모든 초안을 수정하고 있었습니다. 이것은 자동화가 아니라 추가적인 작업이었습니다.
아키텍처
최종 시스템은 프롬프트에 조립되는 네 개의 레이어로 구성됩니다:
- 제품 컨텍스트 (Product context): 마켓플레이스 API에서 가져온 소재, 치수, 보증 기간 등.
- 브랜드 목소리 (Brand voice): 셀러가 어조(친근함, 기업적, 판매 중심)를 선택하고 금지 단어를 정의합니다.
- 템플릿 규칙 (Template rules): “배송 질문의 경우 1~3 영업일이라고 말하라”와 같은 하드한 지침입니다.
- 퓨샷 예시 (Few-shot examples): 벡터 검색을 통해 유사한 질문에 대해 이전에 승인된 답변들입니다.
이 네 번째 레이어가 시스템을 자체 개선(self-improving)하게 만드는 핵심입니다.
pgvector를 사용한 승인된 답변 저장
셀러가 초안을 승인하거나 (또는 수정하여 전송할 때마다), 우리는 질문, 최종 답변, 그리고 해당 질문의 임베딩을 저장합니다:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE approved_answers (
...
Postgres에 별도의 벡터 데이터베이스를 사용하지 않고 여기에 유지하기로 한 것은 의도적인 선택이었습니다. 이미 데이터가 그곳에 존재하며, 간단한 WHERE 절로 스토어별 범위 지정이 가능하고, 운영해야 할 서비스가 하나 줄어들기 때문입니다.
유사 예시 검색 (Retrieving similar examples)
새로운 질문이 들어오면, 이를 임베딩(embed)하여 동일 스토어의 가장 근접한 승인된 답변들을 가져옵니다:
SELECT question, answer
FROM approved_answers
WHERE store_id = $1
...
이러한 예시들은 프롬프트에 퓨샷 데모(few-shot demonstrations)로 포함됩니다. 만약 판매자가 항상 사이즈 관련 질문에 특정 방식으로 답변한다면, 모델은 그 패턴을 감지하고 파인튜닝(fine-tuning) 없이도 이를 따르게 됩니다.
답변 구조화 (Structuring the answer)
또한 모델에게 고정된 3단계 구조를 제공했는데, 이 덕분에 답변이 눈에 띄게 설득력이 높아졌습니다:
- 우려 사항 인정: 고객이 경청받았다고 느끼게 합니다.
- 구체적인 논거 제시: 제품에 대한 특정 사실(재질, 보증, 치수)을 언급합니다.
- 신뢰로 마무리: 추가 도움을 제공하며 끝맺습니다.
프롬프트 조립의 간소화된 버전은 다음과 같습니다:
function buildPrompt(ctx: ReplyContext): string {
return [
`You are a customer support writer for a marketplace seller.`,
...
인간의 통제 유지 (Keeping humans in control)
기본적으로 아무것도 자동으로 전송되지 않습니다. AI가 초안을 작성하고, 판매자가 검토한 후 '전송' 버튼을 누릅니다. 자동 전송은 선택 사항이며, 설령 그렇게 하더라도 브랜드 보이스(brand voice), 금지어 목록, 템플릿 규칙 등이 여전히 적용됩니다.
이것이 두 가지 이유로 중요했습니다: 판매자들이 시스템을 더 신뢰하게 되었고, 모든 인간의 승인 과정이 새로운 학습 예시가 되기 때문입니다. 검토 단계 자체가 학습 루프(learning loop)인 것입니다.
제가 배운 점 (What I learned)
- 개별 고객 스타일에는 검색(Retrieval)이 파인튜닝보다 우수합니다. 각 스토어는 훈련 파이프라인 없이도 즉시 자체적인 '기억'을 갖게 됩니다.
- Postgres + pgvector만으로 충분합니다. 이 규모에서는 불필요한 인프라를 추가하지 마십시오.
- 인간 개입형 루프(Human-in-the-loop)는 제약이 아니라 기능입니다. 신뢰를 구축하고 최고의 데이터를 생성해 줍니다.
제품 측면이 궁금하시다면, Netaliz는 샘플 데이터가 있는 데모 스토어를 운영하고 있으며 가입할 필요가 없습니다: netaliz.com/demo.
LLM 앱에서 사용자별 스타일(per-user style)을 어떻게 처리하는지 다른 분들의 의견이 궁금합니다. 검색 증강 생성(retrieval), 미세 조정(fine-tuning) 중 어떤 방식을 사용하고 계신가요, 아니면 다른 방식인가요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기