185 lines
9.9 KiB
Markdown
185 lines
9.9 KiB
Markdown
# 配置说明
|
||
|
||
本文档描述 `llm-intelligence` 在本地、CI 与生产环境中的关键配置项,以及各脚本的运行语义。
|
||
|
||
## 配置原则
|
||
|
||
- 生产环境优先使用容器平台、systemd 或 CI/CD 注入环境变量,不要依赖仓库内 `.env`
|
||
- `.env.example` 只作为示例,不应存放真实密钥
|
||
- 避免在 `.env.local` 与 `.env` 中重复定义同一变量
|
||
- 由于不同脚本的加载方式不同,重复定义时优先级并不完全一致
|
||
- Shell 脚本通常按 `.env.local` 然后 `.env` 顺序 `source`,后者可能覆盖前者
|
||
- `generate_daily_report.go` 会优先保留已存在环境变量,并优先保留较早注入的值
|
||
|
||
生产环境建议:所有关键变量统一在部署系统中注入,仓库内 `.env*` 仅用于开发。
|
||
|
||
## 关键环境变量
|
||
|
||
| 变量名 | 必填 | 使用方 | 默认值 | 说明 |
|
||
|--------|------|--------|--------|------|
|
||
| `DATABASE_URL` | 是 | API Server、迁移、采集、日报、备份恢复、验收脚本 | 无 | PostgreSQL 连接串,缺失时多数核心脚本会直接失败 |
|
||
| `OPENROUTER_API_KEY` | 条件必填 | `fetch_openrouter.go`、`run_real_pipeline.sh`、`run_daily.sh`、`run_intraday_price_watch.sh` | 无 | 真实采集所需;只查看历史数据或仅跑前端时可不配 |
|
||
| `PORT` | 否 | `cmd/server/main.go` | `8080` | API Server 监听端口 |
|
||
| `API_AUTH_TOKEN` | 条件必填 | `cmd/server/main.go`、API smoke / 外部调用 | 空 | 对外访问 `/api/*` 时推荐使用的 Bearer token;外部请求未携带合法 token 或 Basic Auth 时返回 `401` |
|
||
| `API_BASIC_AUTH_USER` | 条件必填 | `cmd/server/main.go` | 空 | 对外访问 `/api/*` 的 Basic Auth 用户名;与 `API_BASIC_AUTH_PASS` 配套使用 |
|
||
| `API_BASIC_AUTH_PASS` | 条件必填 | `cmd/server/main.go` | 空 | 对外访问 `/api/*` 的 Basic Auth 密码 |
|
||
| `API_RATE_LIMIT_PER_WINDOW` | 否 | `cmd/server/main.go` | `60` | `/api/*` 按来源 IP 的窗口限流阈值;设为 `0` 表示关闭内建限流 |
|
||
| `API_RATE_LIMIT_WINDOW_SEC` | 否 | `cmd/server/main.go` | `60` | `/api/*` 限流窗口长度(秒) |
|
||
| `FEISHU_WEBHOOK` | 否 | `run_daily.sh`、`feishu_alert.sh` | 空 | 正式日报失败时发送飞书告警 |
|
||
| `REPORT_OUTPUT_DIR` | 否 | `generate_daily_report.go` | `reports/daily` | 日报主产物输出目录 |
|
||
| `REPORT_DATE` | 否 | `generate_daily_report.go`、`rebuild_historical_report.sh`、`run_intraday_price_watch.sh`、`run_intraday_discovery_watch.sh` | 当天日期 | 指定日报或日内链路日期,格式 `YYYY-MM-DD` |
|
||
| `REPORT_RUN_KIND` | 否 | `generate_daily_report.go` | `manual` | 运行语义,如 `scheduled` / `manual` / `historical_rebuild` |
|
||
| `REPORT_TRIGGER_SOURCE` | 否 | `generate_daily_report.go`、`materialize_daily_signals.go` | `cli` | 触发来源,如 `cron` / `pipeline` / `intraday` / `intraday_discovery` / `rebuild_script` |
|
||
| `REPORT_IS_OFFICIAL_DAILY` | 否 | `generate_daily_report.go` | `false` | 是否属于正式日报产出 |
|
||
| `REPORT_RUNTIME_AUDIT` | 否 | `generate_daily_report.go` | 空 | 来源级运行审计摘要,通常由流水线脚本注入 |
|
||
| `INTRADAY_DISCOVERY_SEARCH_PROVIDER` | 条件必填 | `discover_intraday_news_candidates.go`、`run_intraday_discovery_watch.sh` | 空 | 候选发现搜索 provider 类型;计划支持 `fixture` / `command_json` / `http_json` |
|
||
| `INTRADAY_DISCOVERY_SEARCH_COMMAND` | 条件必填 | `discover_intraday_news_candidates.go` | 空 | 当 `INTRADAY_DISCOVERY_SEARCH_PROVIDER=command_json` 时执行的搜索命令,stdout 必须输出 JSON 数组 |
|
||
| `INTRADAY_DISCOVERY_SEARCH_URL` | 条件必填 | `discover_intraday_news_candidates.go` | 空 | 当 `INTRADAY_DISCOVERY_SEARCH_PROVIDER=http_json` 时调用的搜索接口 URL |
|
||
| `INTRADAY_DISCOVERY_SEARCH_FIXTURE` | 否 | `discover_intraday_news_candidates.go` | 空 | 搜索 provider 样例文件,用于 dry-run / 本地测试 |
|
||
| `INTRADAY_DISCOVERY_LLM_PROVIDER` | 条件必填 | `discover_intraday_news_candidates.go`、`run_intraday_discovery_watch.sh` | 空 | 候选归纳 LLM provider 类型;计划支持 `fixture` / `command_json` / `http_json` |
|
||
| `INTRADAY_DISCOVERY_LLM_COMMAND` | 条件必填 | `discover_intraday_news_candidates.go` | 空 | 当 `INTRADAY_DISCOVERY_LLM_PROVIDER=command_json` 时执行的 LLM 命令,stdout 必须输出 JSON 数组 |
|
||
| `INTRADAY_DISCOVERY_LLM_URL` | 条件必填 | `discover_intraday_news_candidates.go` | 空 | 当 `INTRADAY_DISCOVERY_LLM_PROVIDER=http_json` 时调用的 LLM 接口 URL |
|
||
| `INTRADAY_DISCOVERY_LLM_FIXTURE` | 否 | `discover_intraday_news_candidates.go` | 空 | LLM provider 样例文件,用于 dry-run / 本地测试 |
|
||
| `INTRADAY_DISCOVERY_TIMEOUT_SEC` | 否 | `discover_intraday_news_candidates.go`、`verify_intraday_news_candidates.go` | `20` | discovery provider 与验证抓取的默认超时秒数 |
|
||
| `PHASE6_PORT` | 否 | `verify_phase6.sh` | 自动挑选 `18080-18120` | Phase 6 验收时临时启动 API Server 的端口 |
|
||
| `LIGHTHOUSE_PORT` | 否 | `verify_lighthouse.sh` | `4173` | Lighthouse 预览端口 |
|
||
| `LIGHTHOUSE_SCORE_THRESHOLD` | 否 | `verify_lighthouse.sh` | `80` | 前端性能分数门槛 |
|
||
| `LIGHTHOUSE_FCP_THRESHOLD_MS` | 否 | `verify_lighthouse.sh` | `2000` | 首次内容绘制门槛 |
|
||
| `VERIFY_DB_NAME` | 否 | `verify_common.sh` | `llm_intelligence` | SQL 型验收脚本默认连接的数据库名 |
|
||
|
||
|
||
|
||
## 推荐的生产注入方式
|
||
|
||
### API Server
|
||
|
||
```bash
|
||
export DATABASE_URL="postgres://app_user:***@db:5432/llm_intelligence?sslmode=disable"
|
||
export PORT="8080"
|
||
export API_AUTH_TOKEN="replace-with-long-random-token"
|
||
# 或者:export API_BASIC_AUTH_USER="review" && export API_BASIC_AUTH_PASS="replace-with-password"
|
||
./server
|
||
```
|
||
|
||
|
||
### 正式日报调度
|
||
|
||
```bash
|
||
export DATABASE_URL="postgres://app_user:***@db:5432/llm_intelligence?sslmode=disable"
|
||
export OPENROUTER_API_KEY="***"
|
||
export FEISHU_WEBHOOK="https://open.feishu.cn/..."
|
||
bash scripts/run_daily.sh
|
||
```
|
||
|
||
### 手工真实复跑
|
||
|
||
```bash
|
||
export DATABASE_URL="postgres://app_user:***@db:5432/llm_intelligence?sslmode=disable"
|
||
export OPENROUTER_API_KEY="***"
|
||
bash scripts/run_real_pipeline.sh
|
||
```
|
||
|
||
### 日内价格追踪
|
||
|
||
```bash
|
||
export DATABASE_URL="postgres://app_user:***@db:5432/llm_intelligence?sslmode=disable"
|
||
export OPENROUTER_API_KEY="***"
|
||
bash scripts/run_intraday_price_watch.sh
|
||
```
|
||
|
||
说明:
|
||
- 该入口只刷新价格 importer 与 `daily_signal_snapshot`
|
||
- 不生成正式 HTML / Markdown 日报
|
||
- 推荐先按每 4 小时一次调度,再根据外部源稳定性决定是否收紧到每 2 小时
|
||
|
||
### 日内候选发现与验证
|
||
|
||
```bash
|
||
export DATABASE_URL="postgres://app_user:***@db:5432/llm_intelligence?sslmode=disable"
|
||
export INTRADAY_DISCOVERY_SEARCH_PROVIDER="command_json"
|
||
export INTRADAY_DISCOVERY_SEARCH_COMMAND="/usr/local/bin/intraday-search --date $REPORT_DATE"
|
||
export INTRADAY_DISCOVERY_LLM_PROVIDER="command_json"
|
||
export INTRADAY_DISCOVERY_LLM_COMMAND="/usr/local/bin/intraday-llm --date $REPORT_DATE"
|
||
bash scripts/run_intraday_discovery_watch.sh
|
||
```
|
||
|
||
说明:
|
||
- 该入口只刷新候选池、验证轨迹与 `daily_signal_snapshot` 中的已验证事实
|
||
- 它不会直接写 `daily_report`,不会覆盖 `/api/v1/reports/latest` 对应的正式日报
|
||
- 搜索 / LLM provider 缺失时应明确报前置条件错误,不能伪装成“今日无新闻”
|
||
- `leak_or_rumor` 默认留在候选层,不进入正式日报事实
|
||
|
||
## 日报运行语义
|
||
|
||
项目用以下字段区分正式日报、手工复跑和历史补跑:
|
||
|
||
| 字段 | 说明 | 典型值 |
|
||
|------|------|--------|
|
||
| `run_kind` | 运行类型 | `scheduled` / `manual` / `historical_rebuild` |
|
||
| `trigger_source` | 触发来源 | `cron` / `pipeline` / `rebuild_script` / `cli` |
|
||
| `is_official_daily` | 是否视为最新正式日报 | `true` / `false` |
|
||
| `summary_md` | 运行摘要与审计 | 包含 `REPORT_RUNTIME_AUDIT` 拼接结果 |
|
||
|
||
`/api/v1/reports/latest` 只返回:
|
||
|
||
- `status='generated'`
|
||
- `output_path` 非空
|
||
- `is_official_daily=true`
|
||
|
||
这意味着:
|
||
|
||
- 手工复跑不会覆盖“最新正式日报”
|
||
- 历史补跑不会冒充当天正式结果
|
||
- 如果正式日报写库成功但落盘产物丢失,元数据查询可成功,文件拉取接口会返回 `404`
|
||
|
||
## 产物路径约定
|
||
|
||
| 类型 | 路径 |
|
||
|------|------|
|
||
| 当天 Markdown | `reports/daily/daily_report_YYYY-MM-DD.md` |
|
||
| 当天 HTML | `reports/daily/html/daily_report_YYYY-MM-DD.html` |
|
||
| 归档 Markdown | `reports/daily/YYYY/MM/daily_report_YYYY-MM-DD.md` |
|
||
| 归档 HTML | `reports/daily/YYYY/MM/daily_report_YYYY-MM-DD.html` |
|
||
| 每日日志 | `/tmp/llm_hub_daily_YYYY-MM-DD.log` |
|
||
| 备份目录 | `/tmp/llm_hub_backups` |
|
||
|
||
## 最小可运行配置
|
||
|
||
### 仅启动 API Server
|
||
|
||
```bash
|
||
DATABASE_URL="host=/var/run/postgresql dbname=llm_intelligence user=long sslmode=disable" \
|
||
PORT="8080" \
|
||
go run ./cmd/server
|
||
```
|
||
|
||
说明:
|
||
- `/health` 仅允许本机或私网来源访问
|
||
- `/api/*` 对外访问默认要求 Bearer token 或 Basic Auth
|
||
- 本机与私网来源可直接访问,便于同机前端、验收脚本和内网反代联调
|
||
|
||
### 仅生成指定日期日报
|
||
|
||
```bash
|
||
DATABASE_URL="host=/var/run/postgresql dbname=llm_intelligence user=long sslmode=disable" \
|
||
REPORT_DATE="2026-05-13" \
|
||
go run -tags llm_script ./scripts/generate_daily_report.go
|
||
```
|
||
|
||
### 真实采集并写库
|
||
|
||
```bash
|
||
DATABASE_URL="host=/var/run/postgresql dbname=llm_intelligence user=long sslmode=disable" \
|
||
OPENROUTER_API_KEY="***" \
|
||
go run ./scripts/fetch_openrouter.go -strict-real -db "$DATABASE_URL" -api-key "$OPENROUTER_API_KEY"
|
||
```
|
||
|
||
## 配置错误的典型症状
|
||
|
||
| 症状 | 可能原因 | 排查方向 |
|
||
|------|----------|----------|
|
||
| `/health` 返回 `503 database not configured` | `DATABASE_URL` 未注入到 API Server | 检查进程环境变量 |
|
||
| `run_real_pipeline.sh` 直接退出 | `OPENROUTER_API_KEY` 或 `DATABASE_URL` 缺失 | 检查 `.env` 或部署配置 |
|
||
| `/api/v1/reports/latest` 返回 `404` | 没有正式日报或 `is_official_daily=false` | 查 `daily_report` 表 |
|
||
| 最新日报元数据存在,但 `/html` 返回 `404` | `output_path` 对应文件丢失 | 检查 `reports/daily` 与归档目录 |
|