Skip to content
This page has been auto-translated and may contain errors.View in English

Vercel AI SDK 코스를 로컬에서 실행하기

이 페이지를 사용하여 추출한 고객 지원 에이전트를 컴퓨터에서 실행합니다. Express 서버를 OpenAI 및 코스에서 생성한 Supabase 데이터에 연결한 후, Node가 .env에서 이 값들을 로드하도록 시작 스크립트를 한 줄 수정합니다. 임베딩 및 벡터 데이터베이스 가이드는 동일한 종류의 Supabase 벡터 설정에 대해 관련 프로젝트를 실행합니다.

먼저 필요한 것

Node.js의 지원되는 LTS 버전을 설치합니다. Node 24 이상을 권장합니다. 다음도 필요합니다.

  • 청구 및 모델 접근 권한이 있는 OpenAI API 키;
  • 코스 중에 생성한 Supabase 프로젝트 및 데이터;
  • Supabase 시크릿 키 또는 레거시 service_role 키.

시크릿 및 service_role 키는 Row Level Security를 우회합니다. 이러한 키는 이 서버 측 .env에만 속하며 브라우저 코드에는 절대 포함되지 않습니다. Supabase API 키를 참조합니다.

Juno먼저 필요한 것 Node.js LTS를 설치한 후 코스의 OpenAI 키와 Supabase 프로젝트, 서버 측 키를 준비합니다. 그 Supabase 키는 전체 데이터베이스의 마스터 키 같은 것이므로 절대 브라우저 코드에 들어가면 안 됩니다.
Juno먼저 필요한 것 서버가 상승된 권한의 키로 Supabase를 읽으며, 코스 중에 생성한 행이 없으면 검색이 유용한 결과를 반환하지 않습니다. 양쪽 서비스와 그 데이터가 첫 실행 전에 존재해야 합니다. Supabase 시크릿은 Express 환경에만 유지하고 브라우저에는 절대 들어가면 안 됩니다.
Juno먼저 필요한 것 service-role 키는 Row Level Security를 우회하므로, 이것을 가진 사람은 서버의 전체 데이터베이스 권한으로 작동합니다. Express에만 유지합니다. 브라우저로 보내면 devtools를 연 모든 방문자에게 그 접근 권한을 넘기는 것입니다. 그 실수가 프로덕션에 도달한 경우를 봤는데, 정확히 한 번이었고 한 번으로도 충분했습니다.

프로젝트 열기 및 설치

package.json이 있는 추출한 폴더에서 터미널을 열고 잠금된 패키지를 설치합니다.

bash
$ cd path-to-your-downloaded-project
$ npm ci
Juno프로젝트 열기 및 설치package.json이 있는 추출한 폴더에서 npm ci를 실행합니다. 코스가 빌드된 정확한 패키지 버전을 설치하므로 구성하거나 추측할 것이 없습니다.
Juno프로젝트 열기 및 설치npm ci는 포함된 lockfile에서 설치하므로 버전이 추출한 고객 지원 프로젝트와 정확히 일치합니다. SDK와 모델 코드가 함께 테스트되었으므로 그 일치가 중요합니다. 버전이 벗어나면 의도하지 않은 디버깅 세션이 생깁니다.
Juno프로젝트 열기 및 설치 다른 작업을 하기 전에 다운로드한 lockfile에서 설치합니다. 그 후 시작 스크립트만 변경하여 관련 없는 의존성 업데이트를 환경 파일 수정으로 착각하지 않습니다. 이 둘을 분리하는 것이 제 저녁을 셀 수 없을 정도로 구해줬습니다.

Node가 .env를 로드하도록 설정

package.json을 열고 시작 스크립트를:

json
"start": "node server.js"

에서 다음으로 변경합니다.

json
"start": "node --env-file=.env server.js"

코드는 레거시 변수명 SUPABASE_SERVICE_ROLE_KEY를 사용합니다. 코드를 이름을 바꾸지 않고 현재 Supabase 시크릿 키를 그 변수에 넣을 수 있습니다.

package.json 옆에 .env를 만듭니다.

dotenv
OPENAI_API_KEY=your-openai-api-key
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-server-side-secret-key
PORT=3000

.gitignore을 만듭니다.

txt
.env
node_modules/

Git 핸드북은 이 방식을 파일 무시 및 좋은 관행에서 다룹니다.

Supabase 키를 서버에만 유지

시크릿 키에 VITE_ 접두사를 붙이거나 client.js로 옮기지 않습니다. 이것은 상승된 데이터베이스 접근 권한을 가집니다. .env을 커밋하거나 ZIP으로 공유하지 않습니다.

JunoNode가 .env를 로드하도록 설정 시작 스크립트에 --env-file=.env를 추가하고, 네 값 모두를 가진 파일을 만들고, Git에서 제외합니다. Supabase 키는 항상 서버에만 있습니다. .gitignore.env를 포함하는 것이 모든 프로젝트에서 제가 만드는 첫 파일이며, 어려운 방식으로 배운 것입니다.
JunoNode가 .env를 로드하도록 설정 Node는 자동으로 .env를 읽지 않으므로 추출한 프로젝트는 구성 없이 시작됩니다. --env-file 플래그는 내장 기능으로 이를 해결합니다. 추가 패키지가 없고 값은 Express가 읽는 서버 측에만 있습니다.
JunoNode가 .env를 로드하도록 설정 내장 플래그는 server.js가 실행되기 전에 네 개의 기존 변수명을 로드합니다. Express만 이를 읽으므로 OpenAI와 Supabase 시크릿은 브라우저로 전송된 코드에 나타나지 않습니다. 이름 바꾸기 없음, dotenv 의존성 없음, 새로운 공격 표면 없음.

제공된 모델 유지

다운로드한 constants.js는 답변 생성 및 분류에 gpt-4o를, 임베딩에 text-embedding-3-small을 사용합니다. 로컬 설정은 어느 모델도 변경할 필요가 없습니다. OpenAI가 프로젝트의 한 모델을 거부하지 않는 한 변경 없이 유지합니다. 나중에 모델을 교체하는 경우, 전체 에이전트 흐름을 테스트하고 새 쿼리 임베딩이 저장된 Supabase 벡터와 호환되는지 확인합니다. 임베딩 교체는 조용히 실패할 수 있습니다. 같은 차원 수이지만 다른 벡터 공간의 모델은 오류 없이 형편없는 일치를 반환하므로, 임베딩 모델을 변경한 후 저장된 벡터를 다시 생성합니다.

Juno제공된 모델 유지 로컬 설정에서는 제공된 모델명 둘 다 변경 없이 유지합니다. 이것이 이 페이지에서 뭔가가 실패하는 이유는 아닙니다. OpenAI 프로젝트가 한 모델을 거부하면 코드를 편집하기 전에 현재 모델 목록을 확인하고 그 후 전체 에이전트를 다시 테스트합니다.
Juno제공된 모델 유지 답변, 분류, 임베딩 역할은 서로 다른 호환성 요구를 가지므로 모델 교체는 절대 한 줄짜리 변경이 아닙니다. 교체 모델은 이 SDK와 작동하며 이미 Supabase에 저장된 벡터와 호환되어야 합니다.
Juno제공된 모델 유지 같은 차원 수이지만 다른 벡터 공간의 임베딩 모델은 검색을 조용히 깹니다. 쿼리는 형편없는 일치를 반환하고 오류가 없습니다. 그래서 임베딩 교체는 constants.js만 편집하는 것이 아니라 저장된 벡터를 다시 생성합니다. 무음 성능 저하는 알림이 없으므로 가장 존경하는 실패 모드입니다.

에이전트 실행

bash
$ npm start

http://localhost:3000을 열거나 .env에 설정한 포트를 사용합니다. Ctrl+C로 서버를 중지합니다.

페이지가 로드되면 로컬 서버가 실행 중임을 보여줍니다. 코스 데이터로 다룬 질문을 합니다. 유용한 답변은 Supabase 검색과 OpenAI 생성이 작동함을 보여줍니다. 답변이 실패하면 서버 터미널이 체인의 첫 실패 호출(임베딩, 검색 또는 생성)을 인쇄합니다. RAG 장은 에이전트가 처음부터 검색된 코스 데이터에 답변을 기반으로 하는 이유를 설명합니다.

Juno에이전트 실행npm start를 실행하고 브라우저에서 로컬 주소를 엽니다. 페이지 로드는 서버가 실행 중임을 증명합니다. 완전한 답변도 OpenAI와 코스의 Supabase 데이터를 필요로 하므로 그것들을 두 가지의 별개 승리로 취급합니다.
Juno에이전트 실행 서버 시작과 답변 생성을 별개의 확인으로 취급합니다. 실행 중인 서버가 답변 실패는 서비스 문제이지 코드 문제가 아닙니다. Ctrl+C로 중지하고 기본 주소가 바쁜 경우 .env에서 PORT를 설정합니다.
Juno에이전트 실행 답변이 실패하면 서버 터미널이 체인의 첫 실패 호출(임베딩, 검색 또는 생성)을 인쇄합니다. 그 오류를 읽고 어떤 구성도 건드리기 전에 실패를 속성 지정합니다. 세 가지 외부 호출이 이미 진행 중인 상황에서 구성을 추측하는 것이 제 저녁을 사라지게 만듭니다. 경험에서 비롯된 것입니다.

문제 해결

Missing OPENAI_API_KEY: 시작 스크립트가 --env-file=.env를 포함하고, .envpackage.json 옆에 있고, 변수명이 정확히 일치하는지 확인합니다.

Supabase 인증 또는 relation 오류: URL과 서버 측 키가 같은 프로젝트에 속하는지 확인한 후 코스의 스키마 및 데이터 단계를 완료합니다. 서버 작동을 위해 게시 가능한 키로 대체하지 않습니다.

포트 3000이 이미 사용 중입니다: .env에서 PORT를 변경하고, 서버를 다시 시작하고, 새 포트를 엽니다.

페이지는 로드되지만 답변이 실패합니다: 서버 터미널에서 첫 제공자 또는 데이터베이스 오류를 확인합니다. 로컬 시작만으로는 외부 서비스 중 하나도 검증하지 않습니다.

Juno문제 해결 누락된 키는 시작 스크립트나 .env를 가리키고, Supabase 오류는 프로젝트나 데이터를 가리키고, 로드된 페이지가 답변에 실패하면 외부 서비스를 가리킵니다. 증상을 먼저 레이어에 일치시키면 수정이 보통 자신의 이름을 표시합니다.
Juno문제 해결 마지막 서버 터미널 오류가 아니라 첫 번째를 읽습니다. 나중의 실패는 보통 그것의 진부입니다. 그 첫 오류는 환경 로딩, 데이터베이스 권한 부여, 포트 바인딩, OpenAI 접근을 네 가지 별개의 수정으로 분리합니다.
Juno문제 해결 서버 오류를 순서대로 따릅니다. Node가 .env를 로드했나요, Supabase가 코스 데이터를 반환했나요, OpenAI가 답변을 생성했나요. 그리고 오류를 조용히 하기 위해 브라우저 안전 Supabase 키로 바꾸지 않습니다. 그렇게 하면 누락된 테이블 또는 정책 문제를 숨기지 해결하지 않습니다.