- POST /api/v1/ingest:鉴权(X-Ingest-Token) + 限速(每 token 2 篇/秒,
Redis 滑动桶,INGEST_RATE_PER_SEC 可调) + 三层去重(L1 external_id /
L2 content_hash / L3 DB UNIQUE 兜底,均带 reason)
- 写入字段:is_short_news=True、translation/format/image_ai_status='n/a'、
classify_status=(有 tags?'ok':'pending')、commentary_{angel,meituan}_status='pending'、
body_zh_text=body_text(走统一路径,前端/prompt 不用改)
- services/fetchers/api_push.py:compute_content_hash + synthesize_url +
normalize_published_at + build_initial_status 纯函数
- schemas/ingest.py:IngestPayload(title 1-200/body 1-5000/tags 去重去空) +
IngestResponse(article_id/content_hash/status/reason/matched_external_id)
- admin.py:POST/GET/DELETE /admin/sources/{id}/ingest-tokens — owner 生成
(raw_token 仅一次性返回)、列出、撤销
- schemas/article.py:ArticleListItem 加 is_short_news/source_ref;
ArticleDetail 加 is_short_news/source_ref/external_id
- main.py:挂 ingest router;config.py + .env.example:ingest_rate_per_sec 默认 2
短新闻由 commit 1 enrichment_loop 自动接管 classify + 双 provider commentary,
跳过 format/image。
102 lines
3.3 KiB
Plaintext
102 lines
3.3 KiB
Plaintext
# ===== 通用 =====
|
||
TZ=Asia/Hong_Kong
|
||
LOG_LEVEL=INFO
|
||
|
||
# ===== 数据库 =====
|
||
POSTGRES_USER=news
|
||
POSTGRES_PASSWORD=change_me_strong_password
|
||
POSTGRES_DB=news
|
||
POSTGRES_HOST=postgres
|
||
POSTGRES_PORT=5432
|
||
|
||
# ===== Redis =====
|
||
REDIS_HOST=redis
|
||
REDIS_PORT=6379
|
||
REDIS_PASSWORD=change_me_redis_password
|
||
REDIS_DB=0
|
||
|
||
# ===== JWT =====
|
||
# openssl rand -hex 64 生成
|
||
JWT_SECRET=change_me_to_a_64byte_random_hex
|
||
JWT_ALGORITHM=HS256
|
||
ACCESS_TOKEN_TTL_MIN=60
|
||
REFRESH_TOKEN_TTL_DAY=14
|
||
|
||
# ===== 腾讯云 TMT 翻译 =====
|
||
# https://console.cloud.tencent.com/cam/capi 申请
|
||
TENCENTCLOUD_SECRET_ID=your_tencent_secret_id
|
||
TENCENTCLOUD_SECRET_KEY=your_tencent_secret_key
|
||
TENCENTCLOUD_REGION=ap-hongkong
|
||
TENCENT_TMT_ENDPOINT=tmt.tencentcloudapi.com
|
||
# 字符配额(月度,5000000 = 500 万)
|
||
TENCENT_TMT_QUOTA_MONTH=5000000
|
||
# 缓冲比例(0.05 = 95% 触发后切本地)
|
||
TENCENT_TMT_QUOTA_BUFFER=0.05
|
||
# 单次请求最大字符
|
||
TENCENT_TMT_MAX_CHARS_PER_REQ=4500
|
||
|
||
# ===== 星火 Spark(优先翻译;Lite 免费)=====
|
||
# 留空 = 不启用星火(直接走腾讯 TMT)
|
||
# 控制台 https://console.xfyun.cn/ → 应用 → Spark Lite → "HTTP 服务接口认证信息" → APIPassword
|
||
SPARK_API_PASSWORD=your_spark_api_password
|
||
SPARK_BASE_URL=https://spark-api-open.xf-yun.com/v1
|
||
# 模型:lite(默认,免费) / generalv3 / generalv3.5 / 4.0Ultra
|
||
SPARK_MODEL=lite
|
||
# 单次调用间隔(秒),避免被限速
|
||
SPARK_INTERVAL_SEC=1.0
|
||
|
||
# ===== 智谱 GLM(第二序位翻译;glm-4-flash 免费)=====
|
||
# 留空 = 不启用智谱(spark 不可用时直接走 tencent)
|
||
# 控制台 https://open.bigmodel.cn/ → API Keys → 新建
|
||
ZHIPU_API_KEY=your_zhipu_api_key
|
||
ZHIPU_BASE_URL=https://open.bigmodel.cn/api/paas/v4
|
||
# 模型:glm-4-flash(默认,免费) / glm-4-air / glm-4-airx / glm-4 / glm-4-plus / glm-4.5 / glm-4.6
|
||
ZHIPU_MODEL=glm-4-flash
|
||
ZHIPU_INTERVAL_SEC=1.0
|
||
|
||
# ===== 本地翻译(降级) =====
|
||
# 不启用就留空:不会用本地模<E59CB0>?LOCAL_TRANSLATE_ENABLED=false
|
||
LOCAL_TRANSLATE_MODEL=nllb-200-distilled-600M
|
||
LOCAL_TRANSLATE_DEVICE=cpu
|
||
|
||
# ===== 腾讯 MaaS 翻译(备用通道,OpenAI 兼容协议)=====
|
||
# 申请:https://console.cloud.tencent.com/maas 或 hivoice 控制台
|
||
# 留空 api_key = 不启用(只在 TMT 配额耗尽/TMT 失败时启用)
|
||
# 端点固定为 https://maas-api.hivoice.cn/v1(腾讯 MaaS 翻译服务)
|
||
# 模型:u2(翻译专用,支持多语种)
|
||
TENCENT_MAAS_API_KEY=
|
||
TENCENT_MAAS_BASE_URL=https://maas-api.hivoice.cn/v1
|
||
TENCENT_MAAS_MODEL=u2
|
||
# 单次调用间隔(秒),避免被 MaaS 限流
|
||
TENCENT_MAAS_INTERVAL_SEC=1.0
|
||
|
||
# ===== 抓取 =====
|
||
# 全局 QPS 上限
|
||
FETCH_GLOBAL_QPS=4
|
||
# 单源超时(秒)
|
||
FETCH_TIMEOUT=20
|
||
# 单源失败连续次数后暂停
|
||
FETCH_FAIL_PAUSE_THRESHOLD=3
|
||
# 单源 fetch 最大重试次数
|
||
FETCH_MAX_RETRIES=2
|
||
|
||
# ===== API Push 短新闻 ingest 限速 =====
|
||
# 每个 ingest token 每秒最多推几篇(滑动窗口)。2 = 一秒最多 2 篇
|
||
INGEST_RATE_PER_SEC=2
|
||
|
||
# ===== Caddy / 域名 =====
|
||
# 留空走 IP 自签证书;有域名走自动 HTTPS
|
||
DOMAIN=
|
||
# 邮箱(Let's Encrypt 用)
|
||
ACME_EMAIL=you@example.com
|
||
|
||
# ===== Agnes LLM(翻译后智能增强)=====
|
||
# 留空 = 不启用 LLM 增强(只走翻译)
|
||
# Agnes 控制台申请:https://platform.agnes-ai.com/
|
||
AGNES_API_KEY=your_agnes_api_key
|
||
AGNES_BASE_URL=https://apihub.agnes-ai.com/v1
|
||
AGNES_CHAT_MODEL=agnes-2.0-flash
|
||
AGNES_IMAGE_MODEL=agnes-image-2.1-flash
|
||
# LLM 调用间隔(秒,避免被限流;chat + image 各 1 个串行)
|
||
LLM_INTERVAL_SEC=2.0
|