1476 字
7 分钟
- 次浏览
给日报工具加插件时,把改法写进 AGENTS
读前导览

daily-open-source-brief 后续要加来源、评分、摘要、渲染和投递,把这些约定写清楚,避免每次扩展都重新猜。

正文
1476 字
阅读
7 分钟
结构
7 节
来源线索
GitLaughs/daily-open-source-brief
daily-open-source-brief:AGENTS daily-open-source-brief:plugin-contract daily-open-source-brief:agent-instructions

插件化项目最容易出现一种反复横跳:架构图里写着插件,实际改功能时又把逻辑塞回主入口。

daily-open-source-brief 也是这样。它一开始已经把日报系统拆成采集、摘要、渲染、发送几个阶段,但只要没有一份明确的开发约定,后面新增 RSS、网页来源、评分策略、LLM provider 或发送渠道时,开发者还是很容易为了省事,直接改 run_daily

所以插件系统需要代码接口,也需要一份写给 agent 和维护者看的入口规则。

这就是 AGENTS.md 的价值。

AGENTS 不是装饰文档#

很多项目里的 AGENTS.md 只是告诉模型“怎么跑测试”。这当然有用,但还不够。

对一个长期被 agent 修改的项目来说,它更应该说明一件事:以后遇到某类需求,应该往哪里改,不该往哪里塞。

日报工具的约定很直接:

  • 新采集来源走 collector 插件。
  • 新评分策略走插件或 enricher 阶段。
  • 新摘要方式走 summarizer 插件。
  • 新 HTML 或文本输出走 renderer
  • 新邮件、飞书或其他投递方式走 sender
  • LLM/provider 选择走 provider
  • 管理命令优先扩展统一 CLI。

这几条主要是为了防止主流程继续变胖,不是追求形式整齐。

插件系统除了目录结构,还得约束后续修改路线。没有这层约束,目录拆得再漂亮,下一次赶时间时还是会回到“先塞进入口文件再说”。

主入口应该越来越薄#

批处理脚本最常见的演化路径,是从一个清爽入口变成一个万能入口。

今天加一个 --skip-rss,明天加一个 --use-llm,后天加一个邮件重试,再过几天又加一个特殊网页来源。每一项看起来都很小,但最后入口文件会同时负责配置、采集、异常处理、摘要、渲染、投递和兼容旧参数。

这不一定是某个人写得不好。缺少约定时,项目很自然就会长成这样。

所以 AGENTS.md 里把职责写死:runner 负责执行管线,旧入口只保留兼容,新的管理命令放到 CLI,新增能力优先映射到插件配置或 CLI override。

主入口越薄,项目越容易继续改。

插件阶段要说清楚#

只说“插件化”太空。

更有用的是明确当前有哪些阶段:

provider -> collector -> summarizer -> renderer -> sender

这条链能帮开发者快速判断一个需求应该放在哪里。

比如“支持一个新的公开网页源”,它不该改摘要器,也不该改投递器,而是新增 collector,把外部内容转成统一 item。

比如“换一个 LLM provider”,它不该散落在每个摘要函数里,而是 provider 插件负责配置和选择。

比如“增加飞书投递”,它属于 sender,不该污染 HTML 归档逻辑。

阶段说清楚以后,后面的代码审查也更简单:这个改动有没有跨过自己的阶段范围。

插件结果要能被记录#

插件系统如果只解决“怎么调用”,还不够。

日报这种工具每天跑,最重要的是知道昨天哪一段正常,哪一段失败。于是插件约定里要求新插件返回统一的 PluginResult,运行状态写进 plugin_runsplugin_health

这比普通日志更稳。

日志适合临时排查,结构化结果适合长期维护。一个 collector 今天抓到 12 条、明天抓到 0 条、后天超时,这些状态应该能被 CLI 或健康页读出来,而不是靠人翻终端输出。

可观察性也应该写进开发约定。新功能如果不能报告自己的状态,就还没接入系统。

失败不能随便阻断#

AGENTS.md 里还有一条很实际:单个来源失败,应尽量记录到 result 或 source health,不应无故阻断其它插件。

这条对日报系统很关键。

GitHub、RSS、学校公告、技术博客、邮件、飞书,本来就不是同一类依赖。一个 RSS 源坏了,不该让当天 GitHub 摘要也消失;邮件投递失败,也不该抹掉已经生成的 HTML 归档。

所以插件约定里也要写清楚故障怎么旁路。

写清楚这条以后,后续 agent 新增插件时就会默认考虑失败旁路,而不是把异常一路抛到最外层。

本地插件也要有注册口#

plugins/local/*.py 这种设计很合适。

内置插件面向公开流程,本地插件承接个人偏好。它们用同一个 register(registry) 入口接入系统,但本地插件不需要挤进主仓库的内置列表。

这个设计对个人工具很有用。公开仓库保留通用能力,本地环境可以有自己的采集源、过滤规则和投递习惯。只要注册接口稳定,二者不需要互相污染。

博客写作也类似:公开文章保留工程判断,本地记忆保留私人现场。

约定要写到 agent 看得到的地方#

插件系统不是把代码拆进几个目录就结束了。

能让它长期工作的,是一组可以被 agent 反复读取的工程约定:新能力放到哪个阶段,主入口保持多薄,状态怎么记录,失败怎么隔离,本地扩展怎么注册,测试补在哪里。

AGENTS.md 在这里起到的是约束后续修改的作用,不应只当成一份说明。

对这种每天运行的小工具来说,轨道比灵感重要。功能可以慢慢加,但新增功能不能每次都把主流程重新搅浑。

给日报工具加插件时,把改法写进 AGENTS
https://blog.sunmmyapi.xyz/posts/daily-brief-agents-plugin-contract/
作者
Sun
发布于
2026-05-29
许可协议
CC BY-NC-SA 4.0

继续读

相关内容