Daily News Collector
项目链接
定位
这是一个基于 Agently v4 重写的新闻采集与日报生成项目。按当前 v4.0.8.3 源码核对后,它已经不只是“Search + Browse + TriggerFlow”的组合示例,而是一个完整使用了父流程、栏目子流程、capture / write_back、runtime_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、栏目级 chunkstools/Search / Browse 适配层prompts/结构化输出契约
4. 实际使用到的 v4.0.8.3 能力
4.1 TriggerFlow 父子流程组合 + 并发编排
workflow/daily_news.py 中父流程是:
prepare_requestgenerate_outlinefor_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_newspick_column_newssummarize_column_newswrite_column
这说明项目直接使用了:
TriggerFlow.for_each(concurrency=...)TriggerFlow.to_sub_flow(...)capture显式把父流程当前value、runtime_data.request和logger / search_tool / browse_tool传给子流程write_back={"value": "result"}把子流程最终结果回收到父流程当前循环项输出.end_for_each()把所有栏目结果收敛给render_report
4.2 runtime_resources 注入
news_collector/collector.py 中通过:
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 默认封装:
SearchBrowse
其中 Browse 的构造参数直接使用:
enable_playwrightresponse_modemax_content_lengthmin_content_lengthplaywright_headless
4.4 结构化输出契约
workflow/report_chunks.py 和 workflow/column_chunks.py 中,outline 生成、新闻筛选、摘要生成、栏目写作都通过 YAML prompt 和结构化结果约束保持步骤接口稳定。
4.5 ${ENV.xxx} + auto_load_env=True
news_collector/collector.py 中使用:
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-insub_flow的独立封装和复用capture / write_back的显式边界runtime_resources的跨父子流程注入- Mermaid 对循环内部节点和子流程结构的可视化展开
所以它现在不只是一个“工具调用案例”,而是一个更接近真实工程的 TriggerFlow 组合案例。
6. 当前类型接口风格
项目里的 chunk 和辅助函数现在已经统一使用:
from agently import TriggerFlowRuntimeData这意味着:
- 当前项目已经不再依赖旧的
TriggerFlowEventData兼容别名 - chunk 接口风格已经和当前文档推荐的
TriggerFlowRuntimeData保持一致 - 子流程里像
request这类父流程数据,也是通过capture后在runtime_data上显式读取,而不是依赖隐式共享上下文