Files
llm-intelligence/docs/CONFIGURATION.md
phamnazage-jpg 475401bcbe
Some checks failed
CI / go-test (push) Has been cancelled
CI / scripts-regression (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / docker-build (push) Has been cancelled
feat(intraday): add discovery and verification watch pipeline
2026-05-27 18:54:32 +08:00

185 lines
9.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 配置说明
本文档描述 `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` 与归档目录 |