Configuración del servidor
Este documento es la guía de arranque y configuración del servidor y responde a tres preguntas:
- Cómo arrancarlo (tres formas: local / nube / escritorio)
- Si hace falta red pública (conclusión: el cuerpo no la necesita; solo si se quiere la interfaz REST)
- Cómo configurar la conexión a la nube (conectar a la pasarela Rust para gestionarlo en remoto)
Preparación previa
| Elemento | Requisito |
|---|---|
| Node.js | ≥ 18.17 (se recomienda 20+) |
| API Key del modelo | Endpoint compatible con OpenAI (DeepSeek / OpenAI / Ollama / personalizado) |
| (Opcional) Cuenta en la nube | Pasarela Rust + Hub propios, o servicio gestionado |
| (Opcional) Bot de la plataforma abierta de QQ | Registro en q.qq.com |
# Obtener el código e instalar dependencias
pnpm install
# Configuración interactiva (recomendada): LLM obligatorio, QQ/correo opcionales y omitibles
bash scripts/configure-server.sh
# O manual: copia la plantilla y rellénala
# cp .env.example .envResumen de variables de entorno
Se escriben en .env en la raíz del proyecto (o con export antes de arrancar):
| Variable | Descripción | Por defecto |
|---|---|---|
DATA_DIR | Raíz de datos/inquilinos | ./.zqagent_data |
PORT | Puerto de escucha REST | 8787 |
HOST | Dirección de escucha (0.0.0.0 para despliegue público) | 127.0.0.1 |
WORKSPACE | Directorio de trabajo del Agent | Directorio actual |
APPROVAL_TIMEOUT_SECONDS | Tiempo de espera de aprobaciones/preguntas | 900 |
MAX_ITERATIONS | Máximo de iteraciones por turno | 800 |
OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL / OPENAI_REASONING_EFFORT | Configuración del modelo (sin OPENAI_MODEL no se fija modelo y hay que elegirlo en la consola) | — |
TENANT_ID / TENANT_API_KEY / MODEL | Inquilino de demostración creado en el primer arranque | demo / aleatorio en el primer arranque / modelo por defecto |
SECRET_KEY | Clave maestra para cifrar credenciales de notificación, etc. | Se genera automáticamente |
FLEET_TOKEN / FLEET_SECRET / FLEET_GATEWAY_URL | Conexión a la nube (normalmente la escribe el código de registro en fleet.json) | — |
QQ_BOT_APP_ID / QQ_BOT_APP_SECRET / QQ_BOT_SANDBOX | Bot de QQ (se activa al configurarlo) | — |
CONTEXT_WINDOW / COMPACTION_THRESHOLD_PCT / COMPACTION_CAP_TOKENS | Parámetros de compactación de conversaciones largas | Automático |
Se recomienda fijar
SECRET_KEYa largo plazo una vez definida: cifra las claves de firma de los inquilinos y las credenciales de los canales de notificación, y cambiarla invalida las claves y credenciales de los inquilinos antiguos.
Tres formas de despliegue
Local / red interna (la más recomendada, sin red pública)
# Mínimo para arrancar (primero confirma que arranca y conversa)
pnpm run server
# Registro:
# zqagent server 监听 http://127.0.0.1:8787
# 已创建演示租户: id=demo apiKey=zk_xxxx(随机生成) model=...
# Control remoto completo (tras configurar .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 serverComprobar que el servicio responde tras arrancar:
# La apiKey del inquilino demo se genera aleatoriamente en el primer arranque y se imprime en el registro; cópiala en TOKEN
TOKEN=<apiKey del registro de arranque> # con forma zk_1f0c...
curl -s http://localhost:8787/healthz # => {"status":"ok"}
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8787/api/v1/sessionsDespliegue en la nube (cuando se necesita acceso público a REST)
Alquila un servidor en la nube y expón el puerto con HOST=0.0.0.0.
# Se recomienda dejarlo residente con pm2
npm install -g pm2
HOST=0.0.0.0 pm2 start "pnpm run server" --name zqagent-server
# Recomendación de seguridad: abre solo a quien lo necesite. Si REST es solo para ti, no lo expongas directamente a internet;
# usa penetración de red interna o limita las IP de origen con el cortafuegos del servidor.App de escritorio (macOS / Windows)
La app de escritorio levanta el servidor en local automáticamente; no hay que arrancarlo a mano. Consulta App de escritorio.
Tres opciones si necesitas acceso público a REST
| Opción | Cómo | Para qué |
|---|---|---|
| A. Penetración de red interna (recomendada para particulares) | Cloudflare Tunnel (gratis) o frp/ngrok para mapear el puerto local a HTTPS público | Máquina en casa/red interna, sin alquilar servidor |
| B. Servidor en la nube | Desplegar en un VPS con HOST=0.0.0.0 | Ya tienes servidor o necesitas estabilidad a largo plazo |
| C. Sin REST | Usar toda la vía de la pasarela (el plano de control emite las credenciales) y REST solo en tu equipo | No quieres exponer ningún puerto |
Conexión a la nube (pasarela Rust)
Tras conectar, puedes gestionar este nodo en remoto desde cualquier dispositivo. El nodo solo necesita conexión saliente a la pasarela (wss://, normalmente 443); no requiere entrada pública ni abrir puertos, ni ningún broker MQTT.
Opción 1: conexión con código de registro (recomendada)
Crea un código de registro de un solo uso en el centro de usuario (Hub) y ejecútalo en la máquina del nodo:
zqagent link --hub https://hub.example.com --code <código>- Si ya hay un servicio en ejecución → conexión en caliente (sin reiniciar)
- Si no, las credenciales se escriben en
{DATA_DIR}/fleet.jsony el siguientezqagent serveconecta solo.
Opción 2: configuración manual
# .env
FLEET_TOKEN=<aleatorio de alta entropía> # identificador del espacio de nombres
FLEET_SECRET=<aleatorio de alta entropía> # clave de firma (debe coincidir con la pasarela)
FLEET_GATEWAY_URL=wss://gw.example.com/ws
SECRET_KEY=<hex de 64 caracteres> # se recomienda encarecidamente definirloComprobar tras arrancar:
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":"..."}}Si el registro de arranque muestra «云端接入: wss://…(节点 nodeId)», la conexión es correcta.
Sin conexión a la nube
Sin configurar ningún FLEET_*, el nodo es puramente local: todas las funciones locales siguen igual, solo que la nube no lo ve. Puedes ejecutar zqagent link en cualquier momento.
El despliegue del lado de la pasarela (claves, TLS, réplicas) está en
docs/rust-gateway-plan.mdydeploy/k8s/gateway/del repositorio. Los detalles del protocolo, endocs/wire-protocol.md.
Solución de problemas
| Síntoma | Comprobación |
|---|---|
| El nodo no conecta con la pasarela | Verifica que la dirección sea wss://.../ws, que el certificado lo emita una CA (no autofirmado) y que el cortafuegos permita 443 |
| El registro dice «未能接入网关» | Comprueba el acceso a FLEET_GATEWAY_URL y que FLEET_SECRET coincida con la pasarela |
| El servidor no escucha en el exterior | HOST es 127.0.0.1 por defecto; para acceso público usa HOST=0.0.0.0 y abre el puerto |
| Falla la conexión con la pasarela de QQ | Revisa AppID/Secret, si solicitaste los permisos de intents y usa QQ_BOT_SANDBOX=1 en sandbox |
| No se envían correos | En QQ usa el código de autorización (no la contraseña); secure debe casar con el puerto (465→true, 587→false) |
Las credenciales dejan de valer tras cambiar SECRET_KEY | Se recomienda fijar SECRET_KEY; cambiarla invalida todas las credenciales de inquilinos antiguos |
