briefing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Briefing Pipeline

简报流水线

Multi-domain daily briefing system: collect → generate → review → email → keyword evolution.
多域名日报简报系统:收集→生成→审核→邮件发送→关键词演化。

Tool

工具

python3 scripts/briefing_run.py <command> [options]
python3 scripts/briefing_run.py <command> [options]

Commands

命令

bash
undefined
bash
undefined

Run full pipeline for a domain

为指定域名运行完整流水线

python3 scripts/briefing_run.py run --domain ai-drama [--date 2026-03-03]
python3 scripts/briefing_run.py run --domain ai-drama [--date 2026-03-03]

Run keyword evolution only

仅运行关键词演化

python3 scripts/briefing_run.py evolve --domain ai-drama [--date 2026-03-03]
python3 scripts/briefing_run.py evolve --domain ai-drama [--date 2026-03-03]

Check last run status

检查上次运行状态

python3 scripts/briefing_run.py status --domain ai-drama
python3 scripts/briefing_run.py status --domain ai-drama

List all configured domains

列出所有已配置的域名

python3 scripts/briefing_run.py domains
python3 scripts/briefing_run.py domains

Run collection step only

仅运行收集步骤

python3 scripts/briefing_run.py run --domain ai-drama --step collect

All commands accept `--config config.yaml` (defaults to hub config).
python3 scripts/briefing_run.py run --domain ai-drama --step collect

所有命令均支持`--config config.yaml`参数(默认使用hub配置)。

File Structure

文件结构

~/briefing/
  config/
    email.json          # Global fallback email config (only user's own email)
  engine/
    collector.py        # Domain-aware RSS/API collector
    notify.py           # Domain-aware email sender
    prompt_init.py      # Prompt initialization and evolution
  templates/
    generate_base.md    # Base template for generation prompts
    review_base.md      # Base template for review prompts
  domains/<name>/
    domain.yaml         # Core config: models, distribution, keyword_evolution, schedule
    sources.yaml        # Keywords (by supply-chain layer) + source definitions (RSS, API)
    config/
      email.json        # Domain-specific email config (overrides global)
    prompts/
      generate.md       # Gemini generation prompt
      review.md         # Claude review prompt
    data/
      today_context.json      # Latest collector output
      keyword_feedback.json   # Per-keyword hit stats (30-day rolling)
      keywords_dynamic.yaml   # Auto-evolved keywords (candidate/active/deprecated)
      keywords_meta.json      # Evolution history + idempotency
      run_status.json         # Latest pipeline run status
      output/                 # Final briefing markdown files
~/briefing/
  config/
    email.json          # 全局备用邮件配置(仅包含用户自身邮箱)
  engine/
    collector.py        # 支持域名识别的RSS/API收集器
    notify.py           # 支持域名识别的邮件发送器
    prompt_init.py      # 提示词初始化与演化
  templates/
    generate_base.md    # 生成提示词的基础模板
    review_base.md      # 审核提示词的基础模板
  domains/<name>/
    domain.yaml         # 核心配置:模型、分发设置、关键词演化、调度计划
    sources.yaml        # 关键词(按供应链层级划分)+ 数据源定义(RSS、API)
    config/
      email.json        # 域名专属邮件配置(覆盖全局配置)
    prompts/
      generate.md       # Gemini生成提示词
      review.md         # Claude审核提示词
    data/
      today_context.json      # 最新收集器输出
      keyword_feedback.json   # 关键词命中统计(30天滚动数据)
      keywords_dynamic.yaml   # 自动演化的关键词(候选/活跃/废弃)
      keywords_meta.json      # 演化历史 + 幂等性记录
      run_status.json         # 最新流水线运行状态
      output/                 # 最终简报Markdown文件

Email Config

邮件配置

Email recipients are in
email.json
. Lookup order: domain-specific (
domains/<name>/config/email.json
) → global fallback (
~/briefing/config/email.json
).
json
{
  "sender": "user@example.com",
  "app_password": "smtp_app_password",
  "recipients": ["a@example.com", "b@example.com"],
  "cc": ["c@example.com"],
  "smtp_host": "smtp.qq.com",
  "smtp_port": 465
}
To change recipients for a specific domain, edit its
domains/<name>/config/email.json
. The global file only applies to domains without their own config.
邮件收件人配置在
email.json
中。查找顺序:域名专属配置(
domains/<name>/config/email.json
)→ 全局备用配置(
~/briefing/config/email.json
)。
json
{
  "sender": "user@example.com",
  "app_password": "smtp_app_password",
  "recipients": ["a@example.com", "b@example.com"],
  "cc": ["c@example.com"],
  "smtp_host": "smtp.qq.com",
  "smtp_port": 465
}
如需修改特定域名的收件人,编辑其
domains/<name>/config/email.json
文件。全局配置仅适用于未配置专属邮件设置的域名。

Adding a New Domain

添加新域名

  1. Create
    ~/briefing/domains/<new-name>/
  2. Add
    domain.yaml
    (copy from existing domain, customize)
  3. Add
    sources.yaml
    with keywords and sources
  4. Add
    prompts/generate.md
    and
    prompts/review.md
  5. Register a cron job: use hub-ops skill to add
    briefing:<new-name>
    handler
  1. 创建
    ~/briefing/domains/<new-name>/
    目录
  2. 添加
    domain.yaml
    文件(复制现有域名的配置文件并自定义)
  3. 添加包含关键词和数据源的
    sources.yaml
    文件
  4. 添加
    prompts/generate.md
    prompts/review.md
    提示词文件
  5. 注册定时任务:使用hub-ops技能添加
    briefing:<new-name>
    处理器

Key Config in domain.yaml

domain.yaml中的关键配置

yaml
models:
  generate: { model: "3-Flash", thinking: medium, fallback_model: sonnet }
  review: { enabled: true, model: sonnet }
distribution:
  email: { enabled: true, subject_template: "{name} | {date}" }
  feishu: { enabled: true, chat_id: "oc_xxx" }
keyword_evolution:
  enabled: true
  max_auto_additions_per_cycle: 5
schedule: "0 8 * * *"
yaml
models:
  generate: { model: "3-Flash", thinking: medium, fallback_model: sonnet }
  review: { enabled: true, model: sonnet }
distribution:
  email: { enabled: true, subject_template: "{name} | {date}" }
  feishu: { enabled: true, chat_id: "oc_xxx" }
keyword_evolution:
  enabled: true
  max_auto_additions_per_cycle: 5
schedule: "0 8 * * *"

What Doesn't Need Restart

无需重启的变更

ChangeNeeds restart?
Pipeline logic (
scripts/briefing_run.py
)
No — runs as subprocess
Keyword evolution logicNo — same file
domain.yaml
/
sources.yaml
/ prompts
No — read fresh each run
keywords_dynamic.yaml
No — read fresh by collector
This SKILL.mdNo
briefing_plugin.py
(shim)
Yes — but it never changes
config.yaml
(credentials)
Yes — tell user to send
#restart
in Feishu
变更内容是否需要重启?
流水线逻辑(
scripts/briefing_run.py
—— 以子进程方式运行
关键词演化逻辑 —— 同属一个文件
domain.yaml
/
sources.yaml
/ 提示词
—— 每次运行时重新读取
keywords_dynamic.yaml
—— 收集器会重新读取最新内容
本SKILL.md文件
briefing_plugin.py
(垫片文件)
是 —— 但该文件从不修改
config.yaml
(凭证信息)
是 —— 告知用户在飞书中发送
#restart
指令

Registered Handlers

已注册的处理器

Handlers are auto-discovered from
~/briefing/domains/
. Example:
HandlerDomainCronDescription
briefing
(default domain)
0 8 * * *
Daily briefing for the default domain
briefing:<name>
<name>
user-definedPer-domain briefing
briefing
handler (no suffix) = default domain (set via
briefing.default_domain
in config.yaml). New domains register as
briefing:<name>
.
Handler jobs don't need a prompt — they spawn
briefing_run.py
as subprocess.
处理器会自动从
~/briefing/domains/
目录中发现。示例:
处理器域名定时计划描述
briefing
(默认域名)
0 8 * * *
默认域名的每日简报
briefing:<name>
<name>
用户自定义专属域名的简报
briefing
处理器(无后缀)对应默认域名(通过
config.yaml
中的
briefing.default_domain
设置)。新域名会注册为
briefing:<name>
格式。
处理器任务无需提示词——它们会以子进程方式启动
briefing_run.py