从 CCTV 主页抓取《新闻联播》,下载 → 转 MP3/WAV → 静音切分 → ASR 识别 → LLM 校对 → 切分为单条新闻 → 入库 MySQL。 主要内容: - 全链路:getVideo5 抓取下载、audioRead 转写、deepseek 校对与切分、newsProcess 入库 - 可移植化:配置分层,.env 只放密钥、config.yml 放模型/接入点/路由/参数 - 可换供应商:endpoints(kind/base_url/api_key_env/extra_body)+ routes 按环节选路 - 数据保真:数值事实守卫,校对改动数字/年份/届次则整片回退 ASR 原文; 识别不完整不发布该日精编,避免半天内容被当成完整一天 - 定时任务:systemd 每天 21:00,失败 21:30 / 22:00 重试; 只缺切分时只重跑切分(省掉全部 ASR),用 state/.asr_complete_* 标记判定阶段 - 隧道自愈:13306 不通时自动执行 autossh.sh(所有入口共用,systemd 托管时只等待) - 中间产物每日清理;97 项离线自检(配置/清理/事实守卫/解析/隧道)
137 lines
6.6 KiB
YAML
137 lines
6.6 KiB
YAML
# ============================================================================
|
||
# xwlb 非敏感配置
|
||
# ============================================================================
|
||
# 敏感配置(密钥、数据库口令)保留在 .env:
|
||
# MYSQL_PASSWORD / DASHSCOPE_API_KEY / DEEPSEEK_API_KEY
|
||
#
|
||
# 修改本文件后无需改代码;可用 XWLB_CONFIG_FILE 指定其他配置文件。
|
||
# 优先级:进程环境变量 > config.yml > 代码内置默认值
|
||
# (即为临时试验,可用 `DASHSCOPE_LLM_MODEL=qwen-max python audioRead.py ...` 覆盖)
|
||
# ============================================================================
|
||
|
||
# ---- 数据库(口令在 .env 的 MYSQL_PASSWORD)----
|
||
mysql:
|
||
# 隧道自愈:端口不通时自动执行下面的脚本(逻辑见 tunnel.py,所有入口都生效)
|
||
tunnel:
|
||
enabled: 1
|
||
script: autossh.sh # 相对项目根
|
||
systemd_unit: xwlb-tunnel.service # 该单元 active 时只等待它自动重连,不抢端口
|
||
wait_seconds: 30 # 执行后最多等多久
|
||
connect_timeout: 2 # 单次 TCP 探测超时
|
||
host: localhost
|
||
port: 13306 # 经 autossh.sh 隧道时的本地端口(隧道: 13306 -> 远端 3306)
|
||
user: myquant
|
||
database: myquant
|
||
|
||
# ---- 目录(相对项目根,也可写绝对路径)----
|
||
paths:
|
||
video_dir: xwlb_video # mp4 / mp3 中间产物
|
||
audio_dir: audio_processing # wav 分片
|
||
|
||
# ---- 各环节实际使用的模型(集中在此管理)----
|
||
models:
|
||
asr_model: paraformer-realtime-v2 # 语音识别
|
||
correct_model: qwen3.8-flash # ASR 文本校对
|
||
split_model: deepseek-flash # 新闻切分 + 标题(API 实测:deepseek-flash / deepseek-v4-pro)
|
||
|
||
# ============================================================================
|
||
# 接入点(base url):换供应商 / 换区域 / 走公司网关或代理,只改这一段
|
||
# ============================================================================
|
||
# 每个接入点声明三件事:
|
||
# kind 协议类型:dashscope=用 dashscope SDK;openai=OpenAI 兼容的 /chat/completions
|
||
# *base_url* 服务地址
|
||
# api_key_env 该供应商的密钥放在 .env 里的**变量名**(密钥本身不进本文件)
|
||
endpoints:
|
||
dashscope:
|
||
kind: dashscope
|
||
# 文本生成(校对)走 HTTP
|
||
http_base_url: https://dashscope.aliyuncs.com/api/v1
|
||
# 实时语音识别走 WebSocket
|
||
websocket_base_url: wss://dashscope.aliyuncs.com/api-ws/v1/inference
|
||
api_key_env: DASHSCOPE_API_KEY
|
||
# 国际站示例:把上面两行换成
|
||
# http_base_url: https://dashscope-intl.aliyuncs.com/api/v1
|
||
# websocket_base_url: wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference
|
||
deepseek:
|
||
kind: openai
|
||
base_url: https://api.deepseek.com/v1
|
||
chat_completions_path: /chat/completions
|
||
api_key_env: DEEPSEEK_API_KEY
|
||
# 注意:**切分环节不要关思维链**。同一天(2026-09-23)实测对比:
|
||
# 思考开启 27 条 / 正文覆盖率 99.67% / 19k token
|
||
# 思考关闭 20 条 / 正文覆盖率 95.34% / 4.7k token
|
||
# 关掉省 4 倍 token 但会丢 4.7% 正文、少切 7 条新闻,得不偿失。
|
||
# 若确实要关(DeepSeek 用 thinking 字段,写 enable_thinking 会被静默忽略),在此加:
|
||
# extra_body:
|
||
# thinking: {type: disabled}
|
||
qwen:
|
||
kind: openai
|
||
base_url: https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
|
||
chat_completions_path: /chat/completions
|
||
api_key_env: QWEN_TOKEN_PLAN
|
||
# 校对关思维链:通义/百炼兼容模式用 enable_thinking(实测 4045 → 312 token,约 13 倍,
|
||
# 输出仅差一个"的"字、数值无漂移)。校对是机械任务,想不出什么,纯属浪费。
|
||
extra_body:
|
||
enable_thinking: false
|
||
|
||
# 每个环节走哪个接入点(值是 endpoints 下的名字)
|
||
routes:
|
||
asr: dashscope # 语音识别:仅支持 kind=dashscope(paraformer 实时识别协议)
|
||
correct: qwen # 文本校对
|
||
split: deepseek # 新闻切分
|
||
|
||
# ---- 换供应商示例:把「校对」换成 OpenAI 兼容的第三方,只需三步 ----
|
||
# 1) 上面的 routes.correct 改成 moonshot
|
||
# 2) 在 endpoints 下加一段:
|
||
# moonshot:
|
||
# kind: openai
|
||
# base_url: https://api.moonshot.cn/v1
|
||
# chat_completions_path: /chat/completions
|
||
# api_key_env: MOONSHOT_API_KEY
|
||
# 3) models.correct_model 改成对方的模型名(如 kimi-k2-0905-preview)
|
||
# 并在 .env 里加 MOONSHOT_API_KEY=...
|
||
# 说明:换供应商不影响数值事实守卫(对任何供应商的校对结果都会校验)。
|
||
#
|
||
# 若某供应商的 OpenAI 兼容地址不带版本号(如 https://my-gateway/llm),
|
||
# 直接写进 base_url 即可,代码只做 base_url + chat_completions_path 拼接。
|
||
|
||
# ---- 语音识别 ----
|
||
asr:
|
||
sample_rate: 16000
|
||
language_hints: [zh, en]
|
||
|
||
# ---- 音频切分(静音检测 + 合并)----
|
||
audio_split:
|
||
min_silence_ms: 700 # 超过该静音长度即切分
|
||
silence_thresh_db: -40 # 静音阈值(dBFS)
|
||
keep_silence_ms: 400 # 切分处保留的静音
|
||
max_chunk_ms: 180000 # 单片最长 3 分钟
|
||
|
||
# ---- LLM 文本校对 ----
|
||
llm_correct:
|
||
enabled: 1 # 1=开启校对(默认);0=关闭,直接以 ASR 原文作为 news_improve
|
||
max_retries: 2 # 失败重试次数(失败后回退原文,不丢分片)
|
||
timeout: 120 # 单次调用超时(秒)
|
||
max_tokens: 8000
|
||
temperature: 0.1
|
||
top_p: 0.5
|
||
# 思维链开关在接入点(endpoints.*.extra_body)上配置,因为参数名因供应商而异;
|
||
# 如需只针对本环节覆盖,可在此加 extra_body: { ... }
|
||
# 开启时仍受「数值事实守卫」保护:若校对改动了数字/年份/届次/规划期等,
|
||
# 该分片一律回退 ASR 原文(详见 docs/BUGS.md B2 补充说明)
|
||
|
||
# ---- DeepSeek 新闻切分 ----
|
||
llm_split:
|
||
max_tokens: 60000 # 首次尝试;推理模型 reasoning 可能占 2 万+,上限要给足(按实际产出计费)
|
||
retry_max_tokens: 80000 # 解析失败后强化提示词重试时的上限
|
||
temperature: 0.5
|
||
timeout: 180 # 单次 HTTP 超时(秒);输出 2 万 token 级别需要更久
|
||
max_retries: 3 # 网络/5xx 重试次数(429、5xx 退避重试)
|
||
|
||
# ---- 任务完成后清理中间产物 ----
|
||
cleanup:
|
||
after_daily_run: 1 # 1=当天全程任务结束后自动清理;0=不清理
|
||
only_on_success: 1 # 1=仅当当天全部成功才清理(失败时保留文件便于重跑)
|
||
remove_video: 1 # 删除 paths.video_dir 下所有 mp3 / mp4
|
||
remove_audio: 1 # 删除 paths.audio_dir 下所有 wav
|