fix: system env vars silently overriding .env — load_dotenv(override=True)

Root cause: load_dotenv() default override=False meant system-level
ANTHROPIC_BASE_URL (https://api.deepseek.com/anthropic) took precedence
over .env's OPENAI_BASE_URL (https://api.minimaxi.com/anthropic). All
Anthropic API calls went to DeepSeek with a MiniMax key, causing 401.

Changes:
- backend/llm.py: load_dotenv(override=True) — .env always wins
- .env.example: add explicit ANTHROPIC_API_KEY + ANTHROPIC_BASE_URL
- CLAUDE.md: document env var priority pitfall
This commit is contained in:
2026-05-21 22:36:43 +08:00
parent aa1d8a6c52
commit 83c7da7517
3 changed files with 10 additions and 4 deletions
+8 -3
View File
@@ -2,12 +2,17 @@
LLM_BACKEND=cloud LLM_BACKEND=cloud
# 云端提供商:openai 或 anthropic # 云端提供商:openai 或 anthropic
LLM_PROVIDER=openai LLM_PROVIDER=anthropic
# 云端配置(OpenAI 兼容 # Anthropic 兼容 APIMiniMax 等,优先使用
ANTHROPIC_API_KEY=sk-xxxx
ANTHROPIC_BASE_URL=https://api.minimaxi.com/anthropic
# OpenAI 兼容 APIfallback,当 ANTHROPIC_* 未设置时使用)
OPENAI_API_KEY=sk-xxxx OPENAI_API_KEY=sk-xxxx
OPENAI_BASE_URL=https://api.openai.com/v1 OPENAI_BASE_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4o
LLM_MODEL=MiniMax-M2.7
# 本地大语言模型(Ollama # 本地大语言模型(Ollama
LOCAL_LLM_MODEL=qwen2.5-coder:7b LOCAL_LLM_MODEL=qwen2.5-coder:7b
+1
View File
@@ -223,6 +223,7 @@ validation_service/ (FastAPI, 端口 8001) — 不变
## 已知注意点 ## 已知注意点
- **环境变量优先级**: `backend/llm.py` 使用 `load_dotenv(override=True)` 确保 `.env` 值**始终覆盖**系统环境变量。曾因系统级 `ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic` 覆盖 `.env` 中的 MiniMax URL,导致 401 认证失败。新增 LLM 相关环境变量时,必须在 `.env` 中显式设置 `ANTHROPIC_*` 变量(而非仅设 `OPENAI_*` fallback),否则残留的系统环境变量会污染请求目标。
- **Anthropic SDK**: 使用原始 `anthropic` 包(非 `langchain-anthropic`),因为需要直连 MiniMax 兼容端点。API Key 优先读 `ANTHROPIC_API_KEY`fallback `OPENAI_API_KEY`。Anthropic SDK 会自动将 key 放入 `x-api-key` header。 - **Anthropic SDK**: 使用原始 `anthropic` 包(非 `langchain-anthropic`),因为需要直连 MiniMax 兼容端点。API Key 优先读 `ANTHROPIC_API_KEY`fallback `OPENAI_API_KEY`。Anthropic SDK 会自动将 key 放入 `x-api-key` header。
- **MiniMax 模型名称**: `MiniMax-M2.7`(不是 `minimax-2.7`),大小写敏感。 - **MiniMax 模型名称**: `MiniMax-M2.7`(不是 `minimax-2.7`),大小写敏感。
- **Streamlit headless**: Windows 下必须设 `STREAMLIT_SERVER_HEADLESS=true` 跳过邮箱采集提示。 - **Streamlit headless**: Windows 下必须设 `STREAMLIT_SERVER_HEADLESS=true` 跳过邮箱采集提示。
+1 -1
View File
@@ -8,7 +8,7 @@ from dotenv import load_dotenv
from backend.logger import get_logger from backend.logger import get_logger
load_dotenv() load_dotenv(override=True)
_llm_log = get_logger("llm") _llm_log = get_logger("llm")