Skip to content

서버 구성 ​

이 문서는 서버의 시작과 구성 가이드로, 세 가지 질문에 답합니다:

  1. 어떻게 시작하는가(로컬 / 클라우드 / 데스크톱 세 형태)
  2. 공인 네트워크가 필요한가(결론: 본체는 불필요. REST 인터페이스가 필요할 때만)
  3. 클라우드 연결을 어떻게 구성하는가(Rust 게이트웨이에 연결해 이후 원격 관리 가능)

사전 준비 ​

항목요구 사항
Node.js≥ 18.17(20+ 권장)
모델 API KeyOpenAI 호환 엔드포인트(DeepSeek / OpenAI / Ollama / 사용자 지정)
(선택) 클라우드 계정자체 Rust 게이트웨이 + Hub, 또는 관리형 서비스
(선택) QQ 오픈 플랫폼 봇q.qq.com에서 등록
bash
# 코드 받고 의존성 설치
pnpm install

# 대화형 구성(권장): LLM은 필수, QQ/메일은 선택이며 건너뛸 수 있음
bash scripts/configure-server.sh

# 또는 수동: 템플릿을 복사해 작성
# cp .env.example .env

환경 변수 개요 ​

프로젝트 루트의 .env에 작성(또는 시작 전 export):

변수설명기본
DATA_DIR데이터/테넌트 루트./.zqagent_data
PORTREST 대기 포트8787
HOST대기 주소(공인 배포 시 0.0.0.0)127.0.0.1
WORKSPACEAgent 작업 디렉터리현재 디렉터리
APPROVAL_TIMEOUT_SECONDS승인/질문 보류 타임아웃900
MAX_ITERATIONS턴당 최대 반복800
OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL / OPENAI_REASONING_EFFORT모델 구성(OPENAI_MODEL 미설정 시 모델 미지정이며 콘솔에서 선택 필요)—
TENANT_ID / TENANT_API_KEY / MODEL첫 시작 시 자동 생성되는 데모 테넌트demo / 첫 시작 시 무작위 생성 / 모델 기본값
SECRET_KEY알림 자격 증명 등을 암호화하는 마스터 키자동 생성
FLEET_TOKEN / FLEET_SECRET / FLEET_GATEWAY_URL클라우드 연결(보통 등록 코드 연결로 fleet.json에 자동 기록)—
QQ_BOT_APP_ID / QQ_BOT_APP_SECRET / QQ_BOT_SANDBOXQQ 봇(설정하면 활성화)—
CONTEXT_WINDOW / COMPACTION_THRESHOLD_PCT / COMPACTION_CAP_TOKENS긴 대화 압축 매개변수자동

SECRET_KEY는 한 번 설정하면 장기 고정을 권장합니다. 테넌트 서명 키와 알림 채널 자격 증명 암호화에 쓰이므로 변경하면 기존 테넌트의 키와 자격 증명이 무효가 됩니다.

세 가지 배포 형태 ​

로컬 / 내부망 실행(가장 권장, 공인 네트워크 불필요) ​

bash
# 최소 실행(시작과 대화가 되는지 먼저 확인)
pnpm run server
# 로그:
#   zqagent server 监听 http://127.0.0.1:8787
#   已创建演示租户: id=demo apiKey=zk_xxxx(随机生成) model=...

# 완전한 원격 제어(.env 구성 후):
#   FLEET_GATEWAY_URL=wss://gw.example.com/ws
#   QQ_BOT_APP_ID=...  QQ_BOT_APP_SECRET=...
#   OPENAI_API_KEY=sk-... OPENAI_MODEL=...
pnpm run server

시작 후 서비스 사용 가능 여부 확인:

bash
# 데모 테넌트 apiKey는 첫 시작 시 무작위 생성되어 시작 로그에 출력됨. 꺼내서 TOKEN에 저장
TOKEN=<시작 로그의 apiKey>   # zk_1f0c... 형식
curl -s http://localhost:8787/healthz     # => {"status":"ok"}
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8787/api/v1/sessions

클라우드 배포(REST 공인 접근이 필요할 때) ​

클라우드 서버를 빌려 HOST=0.0.0.0으로 포트를 노출합니다.

bash
# pm2로 상주시키는 것을 권장
npm install -g pm2
HOST=0.0.0.0 pm2 start "pnpm run server" --name zqagent-server

# 보안 권장: 필요한 사람에게만 개방. REST를 혼자만 쓴다면 공인에 직접 노출하지 말고
# 내부망 관통을 쓰거나 클라우드 서버 방화벽으로 출발지 IP를 제한하세요.

데스크톱 앱(macOS / Windows) ​

데스크톱 앱은 로컬에서 서버를 자동으로 띄우므로 수동 시작이 필요 없습니다. 데스크톱 앱을 참고하세요.

REST 공인 접근이 필요할 때의 세 가지 방안 ​

방안방법적합
A. 내부망 관통(개인 권장)Cloudflare Tunnel(무료) 또는 frp/ngrok으로 로컬 포트를 공인 HTTPS에 매핑집/내부망 머신. 서버를 빌리고 싶지 않음
B. 클라우드 서버VPS에 직접 배포하고 HOST=0.0.0.0기존 서버가 있거나 장기 안정성이 필요
C. REST 미사용게이트웨이 전 구간(자격 증명은 제어 플레인이 발급)을 쓰고 REST는 내 PC에서만포트를 전혀 노출하고 싶지 않음

클라우드 연결(Rust 게이트웨이) ​

연결 후 어떤 기기에서든 이 노드를 원격 관리할 수 있습니다. 노드는 게이트웨이로 아웃바운드 연결(wss://, 보통 443)만 하면 되며, 공인 인바운드도 포트 개방도 필요 없고 MQTT broker도 필요 없습니다.

방법 1: 등록 코드로 연결(권장) ​

사용자 센터(Hub)에서 일회용 등록 코드를 만들고 노드 머신에서 실행합니다:

bash
zqagent link --hub https://hub.example.com --code <등록 코드>
  • 이 기기에서 서비스가 실행 중 → 핫 연결(재시작 불필요)
  • 아니면 자격 증명을 {DATA_DIR}/fleet.json에 쓰고 다음 zqagent serve에서 자동 연결

방법 2: 수동 구성 ​

bash
# .env
FLEET_TOKEN=<고엔트로피 랜덤>          # 네임스페이스 식별자
FLEET_SECRET=<고엔트로피 랜덤>         # 서명 키(게이트웨이 측과 일치해야 함)
FLEET_GATEWAY_URL=wss://gw.example.com/ws
SECRET_KEY=<64자리 hex>           # 명시적 설정을 강력 권장

시작 후 확인:

bash
curl -s -H "Authorization: Bearer $ADMIN_API_KEY" \
  http://localhost:8787/api/v1/fleet/pairing
# => {"data":{"gatewayUrl":"wss://gw.example.com/ws","fleetToken":"...","fleetSecret":"...","nodeId":"..."}}

시작 로그에 「云端接入: wss://…(节点 nodeId)」가 나오면 성공입니다.

클라우드에 연결하지 않기 ​

FLEET_*를 전혀 설정하지 않으면 순수 로컬 노드입니다. 로컬 기능은 모두 그대로이며 클라우드에서 보이지 않을 뿐입니다. 언제든 zqagent link로 연결할 수 있습니다.

게이트웨이 측 배포(키, TLS, 다중 복제본)는 리포지토리의 docs/rust-gateway-plan.md와 deploy/k8s/gateway/를 참고하세요. 프로토콜 세부 사항은 docs/wire-protocol.md.

자주 발생하는 문제 ​

현상확인
노드가 게이트웨이에 연결되지 않음주소가 wss://.../ws인지, 인증서가 CA 발급(자체 서명 아님)인지, 방화벽에서 443 허용 여부
로그에 「未能接入网关」FLEET_GATEWAY_URL 접근성과 FLEET_SECRET이 게이트웨이와 일치하는지 확인
서버가 외부를 대기하지 않음HOST 기본은 127.0.0.1. 공인 접근에는 HOST=0.0.0.0과 포트 개방 필요
QQ 게이트웨이 연결 실패AppID/Secret 확인, intents 권한 신청 여부, 샌드박스는 QQ_BOT_SANDBOX=1
메일이 발송되지 않음QQ 메일은 인증 코드(로그인 비밀번호 아님). secure와 포트 일치(465→true, 587→false)
SECRET_KEY 변경 후 자격 증명 무효SECRET_KEY는 고정 권장. 변경하면 기존 테넌트 자격 증명이 모두 무효가 됨