자기개발/프로젝트

[Next.js] 개인 프로젝트 - AI 원두 설명기 제작 (2)(문제 발생)

devbrew 2025. 8. 22. 22:22

이전 글에서 OpenAI 가 원두 제품명만 하드 코딩해도 제법 정보를 설명해주는 것을 확인했습니다 !

 

이전 글:

https://devbrew.tistory.com/120

 

[Next.js] 미니 프로젝트 - AI 원두 설명기 제작 (1)

저는 카페를 참 좋아하고, 필터 커피를 좋아하고, 원두 설명지 보는 것을 좋아하는데요.원두가 이름과 설명이 복잡하다보니 주변에서 필터 커피 자체를 어렵게 느끼는 분들이 많았고,메뉴판에

devbrew.tistory.com

 

이제 이 답변에서 어떤 정보를 표시할지, 또 어떻게 요약해서 보여줄지를 고민해봤습니다.

 

1. 어떤 정보를 표시할지 고민하기

우선, 카페에서 일반적으로 받게되는 원두 설명지를 다시 한 번 살펴봤습니다.

 

항목 별로 국가, 지역, 농장(농부), 고도, 품종, 가공 방식, 컵노트가 가장 많이 보이는 것 같았습니다.

이것을 토대로 기존 설명지의 틀을 그대로 구현하는 방향으로 규칙을 추가해보기로 했습니다.

 

2. 규칙 추가해보기

import OpenAI from "openai";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const RULE = [
  "너는 커피 원두 제품명 분석기야.",
  "입력으로 주어진 '원두 제품명'에 포함된 정보만 사용하고, 임의 추정 및 창작은 금지",
  "아래 ‘출력 형식(마크다운)’을 정확히 지켜줘.",
  "",
  "[출력 형식(마크다운)]",
  "- 지역: 국가 > 지역 > 세부지역 순으로 가능한 범위만 기입, 없으면 없는 부분만 미표기",
  "- 농장: 농장/생산자",
  "- 고도: '####m' 또는 '####–####m' 범위(en-dash, m 단위)",
  "- 품종: 원두의 품종",
  "- 가공 방식: 내추럴/워시드/허니/아나에어로빅/카보닉 매서레이션 등 한국어 표기로 통일",
  "- 컵노트: 원두의 향미",
].join("\n");

export async function POST(req: Request) {
  if (!process.env.OPENAI_API_KEY) {
    return Response.json({ error: "OPENAI_API_KEY가 존재하지 않습니다." }, { status: 500 });
  }

  // 하드 코딩 (기본)
  const model = "gpt-4o-mini";

  // 프롬프트 입력 받기
  const { prompt } = await req.json();
  const user = String(prompt ?? "").trim();
  if (!user) {
    return Response.json({ error: "prompt가 비어 있습니다." }, { status: 400 });
  }

  // 규칙 + 사용자 입력
  const input = `${RULE}\n\n---\n사용자 입력:\n${user}`;

  const response = await client.responses.create({ model, input });

  // 결과 텍스트 반환
  return Response.json({ text: response.output_text });
}

 

사용자 입력을 추가했고, 입력한 원두 제품명만 사용하도록 했습니다.

원두 설명지처럼 보이도록 출력 형식도 지정해주었습니다.

 

그리고 OpenAI 모델이 알아서 필요한 부분만 분리해 섹션을 채워주고,

나머지 부분은 학습되있는 정보로 채워주기를 기대했습니다. 

 

결과 (문제 발생..)

 

그런데 문제가 발생했습니다.

생성하기를 반복해도 일부 항목이 정보 없음으로 표시가 되는 것이었습니다.

채워주기를 기대했던 부분이 "임의 추정 및 창작 금지" 규칙과 부딪히는 것 같았습니다.

 

3. 규칙 수정 및 옵션 추가

// 규칙 수정
const RULE = [
  "사용자가 원두 이름을 입력하면 너는 그 원두를 조사해서 요약 정보를 제공해야 되",
  "아래 ‘출력 형식(마크다운)’을 정확히 지켜줘.",
  "",
  "[출력 형식(마크다운)]",
  "- 지역: 국가 > 지역 > 세부지역 순으로 가능한 범위만 기입, 없으면 없는 부분만 미표기",
  "- 농장: 농장/생산자",
  "- 고도: '####m' 또는 '####–####m' 범위(en-dash, m 단위)",
  "- 품종: 원두의 품종",
  "- 가공 방식: 내추럴/워시드/허니/아나에어로빅/카보닉 매서레이션 등 한국어 표기로 통일",
  "- 컵노트: 원두의 컵노트",
].join("\n");

// 옵션 추가
const OPTIONS = {
  temperature: 0.1,
};

// 최종 응답 생성 값
const response = await client.responses.create({ model, input, ...OPTIONS, });

 

그래서 규칙 중 "임의 추정 및 창작 금지" 텍스트를 제거하고,

무작위성에 관련된 옵션인 temperature 값을 별도로 추가해봤습니다.

temperature 값을 낮게 설정하면 텍스트를 제거했어도 표현이 안정되지 않을까가 이유였습니다.

 

결과

 

문제가 해결되고 이제 정보를 잘 표시해줍니다 !

temperature를 낮춘 덕분인지 반복 실행해도 거의 일관된 내용만 보여주는 것 같고,

출력 형식도 문제없이 원하는 방향으로 답변이 등장을 했습니다. 

 

그런데..

 

살펴보니 또 다른 문제가 있었습니다.

생략된 부분도 있고, 답변의 내용이 실제와 다른 부분이 보이는 것이었습니다.

물론 AI가 제공하는 정보가 정확하지 않을 수 있음을 많은 곳에서 별도 안내하기는 하지만

 

어떻게 수정하면 정확도가 오를지, 생략된 정보를 표현해줄지 다시 고민에 빠졌습니다.