# ============================================================================= # 美搭 backend — environment template # ============================================================================= # Copy to `.env` and fill in real values. `.env` is git-ignored and MUST NEVER # be committed (架构文档 §11.2: 密钥全部走 SSM/KMS,禁止进代码与镜像). # In dev/staging/prod these variables are injected by SSM/KMS, not by a file. # Every variable below is documented; NO real values appear in this file. # ============================================================================= # --- Application ------------------------------------------------------------ APP_ENV=local # local | dev | staging | prod (架构文档 §14.2) APP_NAME=meida-backend API_PREFIX=/api/v1 # 架构文档 §9.1 基础路径;/v1/* 作为别名同样可用 DEBUG=true LOG_LEVEL=INFO # DEBUG | INFO | WARNING | ERROR LOG_JSON=true # false => human-readable console renderer # --- Database (PostgreSQL 16 + pgvector) ------------------------------------ # Async driver is required (SQLAlchemy 2.0 asyncio + asyncpg). DATABASE_URL=postgresql+asyncpg://meida:meida@localhost:55432/meida DB_POOL_SIZE=10 DB_MAX_OVERFLOW=20 DB_ECHO=false # --- Redis 7 (cache / quota counters / celery broker) ----------------------- REDIS_URL=redis://localhost:56379/0 CELERY_BROKER_URL=redis://localhost:56379/1 CELERY_RESULT_BACKEND=redis://localhost:56379/2 # --- Auth (架构文档 §9.1: JWT access 15min + 可撤销 refresh) ---------------- JWT_SECRET= # REQUIRED. >=32 random chars. Generate: openssl rand -hex 32 JWT_ALGORITHM=HS256 JWT_ACCESS_TTL_SECONDS=900 # 15 minutes JWT_ISSUER=meida DEV_AUTH_ENABLED=true # MUST be false outside local/dev: enables POST /auth/dev-token # --- LLM gateway: routing (架构文档 §8.1) ----------------------------------- LLM_PRIMARY_PROVIDER=deepseek # DeepSeek 为主 (TD-04) LLM_BACKUP_PROVIDER=zhipu # 智谱 GLM 为备(V1 未实现,仅结构占位) LLM_STRUCTURED_MAX_RETRIES=2 # 结构化输出校验失败的重试次数 LLM_CIRCUIT_FAILURE_THRESHOLD=3 # 连续失败达到该值即熔断 LLM_CIRCUIT_COOLDOWN_SECONDS=30 # 熔断冷却时长,之后半开探测 # JSON 值一律用单引号包住:scripts/smoke.sh 会 `source .env`, # 裸的双引号会被 bash 剥掉,JSON 就此损坏。 LLM_SCENE_OVERRIDES_JSON='{}' # 场景路由覆盖,JSON: {"agent_chat":{"max_tokens":900}} # --- LLM gateway: DeepSeek (OpenAI-compatible) ------------------------------ DEEPSEEK_API_KEY= # REQUIRED. sk-... Never commit. DEEPSEEK_BASE_URL=https://api.deepseek.com/v1 DEEPSEEK_MODEL=deepseek-v4-flash # 默认模型,可用: deepseek-v4-flash / deepseek-v4-pro DEEPSEEK_TIMEOUT_SECONDS=30 # --- LLM gateway: 智谱 GLM (backup, not implemented in V1) ------------------ ZHIPU_API_KEY= ZHIPU_BASE_URL=https://open.bigmodel.cn/api/paas/v4 ZHIPU_MODEL=glm-4-flash ZHIPU_TIMEOUT_SECONDS=30 # --- LLM gateway: prompt caching discipline (架构文档 §7.2 缓存前缀纪律) ---- # strict => 固定前缀含时间戳/随机ID/昵称时直接拒绝调用 # warn => 只记录告警日志;off => 关闭(不建议) LLM_CACHE_PREFIX_MODE=strict PROMPTS_DIR=prompts # --- LLM gateway: 成本归因与费率 (架构文档 §13, FR-BILL-08) ----------------- # 单位:分/百万 token(cents per 1M tokens)。上线前必须以供应商实际价目表校准。 LLM_COST_RATES_JSON='{"deepseek-v4-flash":{"input_cents_per_mtok":"14","cached_input_cents_per_mtok":"2","output_cents_per_mtok":"28"},"deepseek-v4-pro":{"input_cents_per_mtok":"200","cached_input_cents_per_mtok":"20","output_cents_per_mtok":"800"}}' LLM_DEFAULT_COST_RATE_JSON='{"input_cents_per_mtok":"100","cached_input_cents_per_mtok":"20","output_cents_per_mtok":"200"}' # --- LLM gateway: 全局日成本熔断 (架构文档 §13 三道成本闸门) ---------------- # 达到阈值后,非关键场景的 AI 调用被直接拒绝/降级,而不仅仅是告警。 LLM_DAILY_BUDGET_ENABLED=true LLM_DAILY_BUDGET_CENTS=100000 # 1000 元/天 LLM_BUDGET_TIMEZONE_OFFSET_HOURS=8 # 结算日按 UTC+8 (FR-BILL-01) # --- Observability (架构文档 §15) ------------------------------------------- OTEL_ENABLED=false OTEL_SERVICE_NAME=meida-api OTEL_EXPORTER_OTLP_ENDPOINT= # e.g. http://localhost:4318 PROMETHEUS_ENABLED=true # --- Logging redaction (NFR-SEC-03) ----------------------------------------- # Extra log field names to redact, comma separated. Built-in list already covers # phone / token / union_id / open_id / avatar_key / face image keys / diagnosis. LOG_EXTRA_REDACT_KEYS=