Skip to content

Daily News Collector

项目链接

定位

这是一个基于 Agently v4 重写的新闻采集与日报生成项目。按当前 v4.0.8.3 源码核对后,它已经不只是“Search + Browse + TriggerFlow”的组合示例,而是一个完整使用了父流程、栏目子流程、capture / write_backruntime_resources 和结构化输出的参考项目。

1. 项目分层架构

如何阅读这张图

  • news_collector/ 是应用装配层,真正的流程逻辑集中在 workflow/
  • workflow/ 现在明确拆成父 flow、栏目 sub flow、报告级 chunks 和栏目级 chunks,而不是把栏目生成链路继续塞进一个大 chunk。

2. 运行链路

架构思路

这个项目现在的关键点已经不是“在循环里调用一个生成栏目函数”,而是:

  • 父 flow 负责 prepare_request -> generate_outline -> for_each(column) -> render_report
  • column_sub_flow 负责单个栏目的 search -> pick -> summarize -> write_column
  • 父子流程之间通过 capture / write_back 显式传递输入、状态和资源
  • render_report 接收的是 end_for_each() 收敛后的栏目结果列表

这也是它现在更适合作为 v4.0.8.3 示例的原因:

  • for_each 内部节点能在 Mermaid 中展开
  • 嵌套 sub_flow 能以内联子流程结构的方式呈现
  • 父流程循环后的节点不会再错误落进循环组里

3. 结构分层

项目分成四层:

  • news_collector/ app / integration 层,负责配置、CLI、Agently 设置装配
  • workflow/ TriggerFlow 定义与 chunk 实现,包含父 flow、栏目 sub flow、报告级 chunks、栏目级 chunks
  • tools/ Search / Browse 适配层
  • prompts/ 结构化输出契约

4. 实际使用到的 v4.0.8.3 能力

4.1 TriggerFlow 父子流程组合 + 并发编排

workflow/daily_news.py 中父流程是:

  • prepare_request
  • generate_outline
  • for_each(concurrency=settings.workflow.column_concurrency)
  • to_sub_flow(column_sub_flow, capture=..., write_back=...)
  • end_for_each()
  • render_report

其中 column_sub_flow 本身又是一条独立流程:

  • search_column_news
  • pick_column_news
  • summarize_column_news
  • write_column

这说明项目直接使用了:

  • TriggerFlow.for_each(concurrency=...)
  • TriggerFlow.to_sub_flow(...)
  • capture 显式把父流程当前 valueruntime_data.requestlogger / search_tool / browse_tool 传给子流程
  • write_back={"value": "result"} 把子流程最终结果回收到父流程当前循环项输出
  • .end_for_each() 把所有栏目结果收敛给 render_report

4.2 runtime_resources 注入

news_collector/collector.py 中通过:

python
self.flow.update_runtime_resources(
    logger=self.logger,
    search_tool=search_tool,
    browse_tool=browse_tool,
)

把依赖注入 execution runtime,而不是闭包塞进 chunk。之后父 flow 再通过 capture["resources"] 把这些资源显式传给 column_sub_flow

4.3 内置 Search / Browse

tools/builtin.py 默认封装:

  • Search
  • Browse

其中 Browse 的构造参数直接使用:

  • enable_playwright
  • response_mode
  • max_content_length
  • min_content_length
  • playwright_headless

4.4 结构化输出契约

workflow/report_chunks.pyworkflow/column_chunks.py 中,outline 生成、新闻筛选、摘要生成、栏目写作都通过 YAML prompt 和结构化结果约束保持步骤接口稳定。

4.5 ${ENV.xxx} + auto_load_env=True

news_collector/collector.py 中使用:

python
Agently.set_settings(
    self.settings.model.provider,
    model_settings,
    auto_load_env=True,
)

SETTINGS.yaml 中使用 ${ENV.xxx} 占位符。

5. 为什么它现在是更完整的 TriggerFlow 参考案例

v4.0.8.3 这版代码里,Daily News Collector 已经同时覆盖了:

  • 父 flow 的日报级编排
  • for_each 的 fan-out / fan-in
  • sub_flow 的独立封装和复用
  • capture / write_back 的显式边界
  • runtime_resources 的跨父子流程注入
  • Mermaid 对循环内部节点和子流程结构的可视化展开

所以它现在不只是一个“工具调用案例”,而是一个更接近真实工程的 TriggerFlow 组合案例。

6. 当前类型接口风格

项目里的 chunk 和辅助函数现在已经统一使用:

python
from agently import TriggerFlowRuntimeData

这意味着:

  • 当前项目已经不再依赖旧的 TriggerFlowEventData 兼容别名
  • chunk 接口风格已经和当前文档推荐的 TriggerFlowRuntimeData 保持一致
  • 子流程里像 request 这类父流程数据,也是通过 capture 后在 runtime_data 上显式读取,而不是依赖隐式共享上下文