Files
life-echo/api/docs/configuration.md

112 lines
4.5 KiB
Markdown
Raw Permalink Normal View History

# 配置 SSOTTOML + .env
Life Echo API 配置分为两层,避免 env 膨胀,同时保留密钥安全边界。
## 两层 SSOT
| 层 | 来源 | 改什么 | 如何生效 |
|----|------|--------|----------|
| **Secrets / bootstrap** | [`.env.example`](../.env.example) → `.env.development` / staging / production | `DATABASE_URL``SECRET_KEY`、API 密钥、支付/Liblib 私钥 | 改 env重启进程 |
| **非密钥配置** | [`config/default.toml`](../config/default.toml) + `config/{APP_ENV}.toml` | 功能开关、token 过期、SMS 模板 ID、Chat/Memoir 调参、OTel 等 | 改 TOML**发版**(随镜像/代码部署) |
`APP_ENV` 必须在 `.env` 中设置,用于选择 overlay`development` / `staging` / `production`
加载逻辑:[`app/core/app_config_loader.py`](../app/core/app_config_loader.py) 深合并 `default.toml``{APP_ENV}.toml`,经 Pydantic 校验后暴露为 [`app_config`](../app/core/app_config.py)。
## 文件说明
```
api/config/
default.toml # 全量默认值(所有 section
development.toml # 本地差异OTel、mock 登录、dev COS 等)
staging.toml # 预发差异CORS、SMS/COS 业务 ID 等)
production.toml # 生产差异
```
TOML 顶层 section 与代码模块对应:
| Section | 用途 |
|---------|------|
| `[deploy]` | 原 Settings 非密钥项开关、SMS 模板、CORS、OTel endpoint 等) |
| `[chat]` | 访谈 / 对话 |
| `[memoir]` | 回忆录流水线 |
| `[memory]` | Memory 富化 / compaction |
| `[story]` | Story / 章节 |
| `[eval]` | 内网评测 / judge |
| `[llm]` `[asr]` `[tts]` `[celery]` `[alembic]` `[agent_log]` `[otel]` `[misc]` | 运行时默认 |
业务代码仍可通过原有 import 读取(薄 re-export
- `from app.features.conversation.constants import chat`
- `from app.core.runtime_constants import llm_defaults`
- `settings.enable_tts` 等 deploy 字段通过 [`SettingsFacade`](../app/core/config.py) 代理到 TOML
## 常见操作
**改访谈温度**
```toml
# config/default.toml 或 config/staging.toml
[chat]
interview_temperature = 0.7
```
**改生产 CORS**
```toml
# config/production.toml
[deploy]
api_cors_origins = "https://your-domain.com"
```
**改 DeepSeek API Key** — 仍在 `.env`
```env
DEEPSEEK_API_KEY=sk-...
```
## 旧 env 键对照(节选)
| 旧 env 键 | 新位置 |
|-----------|--------|
| `CHAT_INTERVIEW_PERSONA` | `[chat] interview_persona` |
| `CHAT_INTERVIEW_TEMPERATURE` | `[chat] interview_temperature` |
| `MEMOIR_ORAL_NORMALIZE_MODE` | `[memoir] oral_normalize_mode` |
| `MEMORY_COMPACTION_ENABLED` | `[memory] compaction_enabled` |
| `EVAL_JUDGE_MODEL` | `[eval] judge_model` |
| `DEEPSEEK_BASE_URL` | `[llm] deepseek_base_url` |
| `ENABLE_TTS` | `[deploy] enable_tts` |
| `TENCENT_SMS_SDK_APP_ID` | `[deploy] tencent_sms_sdk_app_id` |
| `OTEL_ENABLED` | `[deploy] otel_enabled` |
| `SECRET_KEY` | 仍在 `.env` |
## 测试
- 设置 `CONFIG_DIR` 指向 fixture 目录可隔离加载:见 [`tests/test_app_config_loader.py`](../tests/test_app_config_loader.py)
- `tests/test_settings_allowlist.py` 防止 Settings 字段反弹
## Docker
`config/``COPY . .` 打入镜像compose 仍 `env_file: .env` 注入密钥。确保容器内 `APP_ENV` 与目标 overlay 文件名一致。
### Redis / Celery 分离
| 用途 | 默认 DB | 环境变量 |
|------|---------|----------|
| 会话、对话历史、task tracker 等业务 key | DB/0 | `REDIS_URL` |
| Celery broker + result backend | DB/1 | `CELERY_REDIS_URL`compose 显式注入;未设时由 `REDIS_URL` 自动 +1 |
**升级注意:** 启用 DB 分离后,旧版在 DB/0 上未消费的 Celery 消息会被丢弃(一次性 cutover无需迁移脚本
`REDIS_URL` 使用 DB/15必须显式设置 `CELERY_REDIS_URL`Redis 仅支持 logical DB 015无法 auto +1
## Shell 脚本与 TOML
| 脚本 | 仍读 `.env` | 已改读 TOML |
|------|-------------|-------------|
| `development.sh` | `APP_ENV`、密钥、`OTEL_ENABLED`legacy 覆盖) | `deploy.otel_enabled` → 是否起 Grafana 栈;`eval.internal_enable_docs` → 是否打印 `/docs` 链接 |
| `deploy.sh` | 密钥、`DATABASE_URL` 等 | SMS 模板等不再检查 env`config/production.toml` |
| `verify_observability_metrics.sh` | — | 提示文案指向 `deploy.otel_enabled` |
**勿再依赖** `.env` 中的 `OTEL_ENABLED``MOCK_SMS_LOGIN_ENABLED``INTERNAL_EVAL_ENABLE_DOCS` 等(应用运行时已从 TOML 读取);测试里 `os.environ["OTEL_ENABLED"]` 亦已无效,见 `tests/conftest.py`