# PolyGateway 工程配置模板(复制为 .env 使用;.env 不提交)。 # 键名清单 = M1 设计文档 §8 定稿;缺关键配置直接报错,不做默认值兜底。 # ══ 多源配置: {SCOPE}__{PROVIDER}__{N}__{FIELD} ══ # PROVIDER 必须是注册表键(qwen/deepseek/openai,或 register_provider 注册后经 registry 传入)。 # 必填: BASE_URL / API_KEY / MODEL / TIMEOUT_S(或用平铺 LLM_TIMEOUT 作缺省)。 LLM__QWEN__1__BASE_URL= LLM__QWEN__1__API_KEY= LLM__QWEN__1__MODEL= LLM__QWEN__1__TIMEOUT_S=120 # 可选(0 = 该闸不启用): # LLM__QWEN__1__MAX_CONCURRENCY=8 # LLM__QWEN__1__RPM=60 # LLM__QWEN__1__TPM=100000 # LLM__QWEN__1__EST_TOKENS=2000 # 可选调优覆盖: TPM 入场预扣量;未填则库按 tpm//60 派生 # LLM__QWEN__1__TTFT_TIMEOUT_S=30 # 须与 INTER_TOKEN 成对;0 < inter < ttft < timeout # LLM__QWEN__1__INTER_TOKEN_TIMEOUT_S=15 # LLM__QWEN__1__ENABLE_THINKING=true # 三态: 缺省=不注入 / true=注入开启 / false=注入关闭 # LLM__QWEN__1__MISSING_DONE=retry # SSE 缺 [DONE]: retry(默认) | salvage # LLM__QWEN__1__TRUST_ENV=true # false = 绕过本地代理(LAN 直连) # ══ scope 级全局闸(跨源合计;0/缺省 = 不启用)══ # LLM__GLOBAL__MAX_CONCURRENCY=8 # LLM__GLOBAL__RPM=120 # LLM__GLOBAL__TPM=200000 # ══ 韧性参数(平铺键 = 单 scope 简写,沿用三项目习惯;scope 键优先)══ LLM_MAX_RETRIES=3 # 总尝试次数(含首次);或 LLM__RETRY__MAX_ATTEMPTS LLM_RETRY_BASE_DELAY=2.0 # 或 LLM__RETRY__BACKOFF_BASE_S LLM_RETRY_MAX_DELAY=30.0 # 或 LLM__RETRY__BACKOFF_MAX_S LLM_CIRCUIT_BREAKER_THRESHOLD=5 # 连续失败通道;有效阈值取 max(此值, 源级并发×2);或 LLM__BREAKER__FAIL_THRESHOLD LLM_CIRCUIT_BREAKER_COOLDOWN=60 # 或 LLM__BREAKER__COOLDOWN_S # LLM_TIMEOUT=120 # 源缺 TIMEOUT_S 时的缺省 # LLM_TTFT_TIMEOUT=30 # 平铺看门狗缺省(成对生效) # LLM_INTER_TOKEN_TIMEOUT=15 # LLM__BREAKER__PROBE_TTL_S=240 # 缺省派生: max(2×最大源超时, cooldown, 最大源超时+5);显式值须 ≥ 最大源超时+5 # LLM__BACKPRESSURE__STALL_WINDOW_S=300 # stall 双条件判死窗口;须 ≥ 最大源 TTFT # LLM__BACKPRESSURE__POLL_INTERVAL_S=0.05 # LLM__SELECTOR=health_aware # health_aware(默认,M2.5) | round_robin | least_inflight # ── M2.5 失败率熔断通道(可选,缺省即生产推荐值)── # LLM__BREAKER__MIN_CALLS=10 # 率通道最小样本(防低流量误判) # LLM__BREAKER__FAIL_RATE=0.6 # 窗口失败率阈值(429 不计入) # LLM__BREAKER__WINDOW_S=60 # 失败率窗口(双 30s 桶) # LLM__BREAKER__MAX_COOLDOWN_S=300 # 开路指数退避封顶(缺省 max(300, cooldown)) # ── AIMD 自适应并发(M2.5,库常量非 env 键): 每源初始 8,429 ×0.5,成功 +1/limit, # ── ceiling = max(64, 源级 MAX_CONCURRENCY);禁用需构造函数注入自定义 pacer ── # LLM__QUOTA_FULL=wait # wait(默认) | fail_fast # ══ 装配选择(PGW_*)══ PGW_LIMITER_BACKEND=memory # memory | redis(redis 需 REDIS_URL;多进程 worker 必须 redis) PGW_BREAKER_BACKEND=memory # memory | redis PGW_CACHE_BACKEND=none # redis | memory | none(必填,显式优于隐式) PGW_TELEMETRY_BACKEND=none # sqlite | postgres | none(必填) # PGW_TELEMETRY_SQLITE_PATH=logs/telemetry.db # sqlite 时必填 # PGW_TELEMETRY_PG_DSN=postgresql://user:pass@host:5432/polygateway # postgres 时必填;严禁指向在用业务库(实验室约定: 专用库 polygateway) # PGW_PRICING_PATH=config/prices.json # 可选: {"": {"input_per_1m": x, "output_per_1m": y}};缺省 cost 恒 None # PGW_CACHE_NAMESPACE=<项目名或租户前缀> # 缓存启用时必填(防跨项目毒化) # PGW_CACHE_TTL_S=604800 # 缓存启用时必填,须 > 0 # PGW_STRUCTURED_MAX_RETRIES=2 # 缺省 2(M2.5);0 = 解析失败不重问(CHS 策略) # PGW_LEASE_TTL_S=1500 # permit 租约;须 ≥ 最大源 timeout # ══ Redis(缓存 + 分布式限流/熔断)══ # 实验室纪律: 共享实例的 db0 有在用键,PolyGateway 一律用专用 db3(soak 会 FLUSHDB!) # REDIS_URL=redis://:password@host:6379/3 # ══ Embedding scope(M2;EmbeddingClient.from_env 装配)══ # EMBED__QWEN__1__BASE_URL= # EMBED__QWEN__1__API_KEY= # EMBED__QWEN__1__MODEL=text-embedding-v3 # EMBED__QWEN__1__TIMEOUT_S=60 # EMBED__RETRY__MAX_ATTEMPTS=3 # EMBED__RETRY__BACKOFF_BASE_S=1.0 # EMBED__RETRY__BACKOFF_MAX_S=10.0 # EMBED__BREAKER__FAIL_THRESHOLD=5 # EMBED__BREAKER__COOLDOWN_S=60 # EMBED__BATCH_SIZE=64 # 必填: 每批条数(分批是行为关键,不设默认) # EMBED__NORMALIZE=false # 可选: true = 库内 L2 归一化(VT 语义) # EMBED__EXPECTED_DIM=768 # 可选: 维度校验,不符抛 ResultInvalid # ══ SOAK scope(压测 harness 专用;tools/soak/run_soak.py --scope SOAK)══ # 网关保护(设计 §8.1 签字值,run_soak 强制: 必配且 ≤ 100/600,否则拒跑) # SOAK__GLOBAL__MAX_CONCURRENCY=100 # SOAK__GLOBAL__RPM=600 # 健康源 + 故障源混编(findings §3): 坏 key 源 / 黑洞源 / 紧看门狗源 / 紧闸源 # SOAK__MINIMAX__1__BASE_URL= # 健康源(真实网关) # SOAK__MINIMAX__1__API_KEY= # SOAK__MINIMAX__1__MODEL= # SOAK__MINIMAX__1__TIMEOUT_S=180 # SOAK__MINIMAX__2__BASE_URL= # 坏凭据源: 真实网关 + 错误 API_KEY → 401 # SOAK__MINIMAX__2__API_KEY=sk-wrong-key-on-purpose # SOAK__MINIMAX__3__BASE_URL=http://10.255.255.1/v1 # 黑洞源: 防火墙 DROP → 连接超时 # SOAK__MINIMAX__4__RPM=5 # 紧闸源: 真实源 + rpm=5 / 并发 1 # SOAK__MINIMAX__4__MAX_CONCURRENCY=1 # ══ OCR scope(M3;MonkeyOCR 自建 LAN 服务,无鉴权故 API_KEY 填占位 "none")══ # CHS 单源写法: # OCR__MONKEY__1__BASE_URL=http://10.77.0.20:7866 # OCR__MONKEY__1__API_KEY=none # 占位惯例: 服务无鉴权,SourceConfig 非空校验用 # OCR__MONKEY__1__MODEL=monkey-ocr # OCR__MONKEY__1__TIMEOUT_S=300 # /parse 两段协议较慢,给足 # OCR__MONKEY__1__MAX_CONCURRENCY=4 # OCR__MONKEY__1__RPM=120 # VT 双实例写法(原 MONKEY_OCR_URLS 逗号列表拆多源;LAN 直连绕代理配 TRUST_ENV=false): # OCR__MONKEY__2__BASE_URL=http://10.77.0.20:7867 # OCR__MONKEY__2__API_KEY=none # OCR__MONKEY__2__MODEL=monkey-ocr # OCR__MONKEY__2__TIMEOUT_S=300 # OCR__MONKEY__2__TRUST_ENV=false # OCR__RETRY__MAX_ATTEMPTS=3 # per-scope 韧性键与 LLM scope 同一套 # ══ SOAK_OCR scope(P7 OCR 压测;tools/soak/run_soak.py --scenario P7 --scope SOAK_OCR)══ # 双真实实例 + 黑洞(连接超时)+ 坏端口(连接拒绝)故障池; # SOAK_OCR_FAULT_SOURCES 供记分板"坏源吸流占比"不变量归因 # SOAK_OCR__GLOBAL__MAX_CONCURRENCY=16 # SOAK_OCR__GLOBAL__RPM=300 # SOAK_OCR_FAULT_SOURCES=monkey_3,monkey_4