<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>工作流 on Kalend's Blog</title><link>https://blog.kalend.top/tags/%E5%B7%A5%E4%BD%9C%E6%B5%81/</link><description>Recent content in 工作流 on Kalend's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Thu, 17 Sep 2026 08:36:00 +0800</lastBuildDate><atom:link href="https://blog.kalend.top/tags/%E5%B7%A5%E4%BD%9C%E6%B5%81/index.xml" rel="self" type="application/rss+xml"/><item><title>AI Agent定时任务：从被动响应到主动行动</title><link>https://blog.kalend.top/2026/09/17/2026-09-17-ai-agent-scheduled-tasks.html/</link><pubDate>Thu, 17 Sep 2026 08:36:00 +0800</pubDate><guid>https://blog.kalend.top/2026/09/17/2026-09-17-ai-agent-scheduled-tasks.html/</guid><description>&lt;p&gt;先说结论：定时任务让AI Agent从&amp;quot;你问我答&amp;quot;变成&amp;quot;主动找活干&amp;quot;。&lt;/p&gt;
&lt;p&gt;很多人对AI的理解还停留在聊天框里——你打字，它回复。但真正用过一段时间之后你会发现，最有价值的场景不是你问它答，而是它自己知道什么时候该干什么。&lt;/p&gt;
&lt;p&gt;这就是定时任务的意义：让AI从被动工具变成主动助手。&lt;/p&gt;
&lt;h2 id="从被动到主动"&gt;从被动到主动
&lt;/h2&gt;&lt;p&gt;传统AI的交互模式很简单：你问一句，它答一句。关掉对话框，它就不存在了。&lt;/p&gt;
&lt;p&gt;定时任务改变了这个模式。你不需要盯着屏幕等它，它会在该出现的时候自己出现。早上8点给你一份当天的新闻摘要，周五下午自动生成本周工作周报，监控到异常立刻发告警——这些事情不需要你触发，它自己会做。&lt;/p&gt;
&lt;p&gt;这个转变看起来很小，但实际用起来差别巨大。我之前每天早上要花20分钟手动整理信息源，现在Agent会在7:30把整理好的摘要推过来，我起床直接看就行。省的不是那20分钟，是那个&amp;quot;记得去做&amp;quot;的额外开销。&lt;/p&gt;
&lt;h2 id="定时任务的三种形态"&gt;定时任务的三种形态
&lt;/h2&gt;&lt;p&gt;很多人一提定时任务就想到cron，但实际上AI Agent的定时任务至少有三种形态，各有各的用途。&lt;/p&gt;
&lt;h3 id="周期性执行cron式"&gt;周期性执行（cron式）
&lt;/h3&gt;&lt;p&gt;最经典的形态。每天早上8点、每周五下午、每月1号——固定时间，固定执行。&lt;/p&gt;
&lt;p&gt;适合场景：信息汇总、报告生成、定时提醒。这类任务的特点是&amp;quot;到了时间就该做&amp;quot;，不需要额外判断。&lt;/p&gt;
&lt;p&gt;配置通常就是一个cron表达式加一段prompt：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0 8 * * *&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 每天早上8点&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;抓取以下RSS源的最新文章，按重要性排序，生成中文摘要&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;简单直接，但也有明显局限——不管有没有新内容，到点就跑，可能浪费token。&lt;/p&gt;
&lt;h3 id="事件驱动trigger式"&gt;事件驱动（trigger式）
&lt;/h3&gt;&lt;p&gt;不是按时间触发，而是按条件触发。GitHub有新star了、某个API返回异常了、RSS源更新了——条件满足才执行。&lt;/p&gt;
&lt;p&gt;这类任务比cron聪明得多，因为它只在&amp;quot;有事发生&amp;quot;的时候才动。配置上通常是webhook或者轮询加条件判断：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;webhook&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;github.repo.stars &amp;gt; last_check + 10&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;分析新增star的用户画像，总结是什么内容吸引了他们&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;实际用下来，事件驱动的任务比cron式省很多token，因为大部分时间它都在安静等待，不会无意义地消耗资源。&lt;/p&gt;
&lt;h3 id="持续运行daemon式"&gt;持续运行（daemon式）
&lt;/h3&gt;&lt;p&gt;前两种都是&amp;quot;触发→执行→结束&amp;quot;，daemon式是常驻后台的。它不等触发条件，而是持续观察环境，自己判断什么时候该行动。&lt;/p&gt;
&lt;p&gt;最典型的例子是代码review机器人：它一直在监听PR事件，但不是每个PR都review——它会根据变更大小、文件类型、作者等因素决定是否介入，介入时用什么策略。&lt;/p&gt;
&lt;p&gt;daemon式的好处是上下文连续。它记得之前review过哪些PR、提过什么建议、团队的代码风格偏好是什么。但代价也明显：token消耗高，需要做好成本控制。&lt;/p&gt;
&lt;h2 id="真实应用场景"&gt;真实应用场景
&lt;/h2&gt;&lt;p&gt;说了三种形态，来看看具体能干什么。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信息监控&lt;/strong&gt;是我用得最多的场景。定时抓取GitHub Trending、竞品动态、特定关键词的新闻。以前我每天手动刷Hacker News和几个技术博客，现在Agent每天早上把筛选过的内容推过来，而且它会记住我关注什么，越用越准。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;内容生产&lt;/strong&gt;也很实用。自动写周报、生成日报、整理笔记。不是让它完全替代你写，而是它先把框架和素材准备好，你只需要改改措辞、加点自己的判断。我每周的周报从写40分钟变成了改10分钟。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;系统运维&lt;/strong&gt;是另一个高频场景。服务器巡检、日志分析、异常告警。特别是那种&amp;quot;99%的时间没事，但出事了要第一时间知道&amp;quot;的场景，daemon式任务比人盯屏幕靠谱得多。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;个人助理&lt;/strong&gt;方面，定时提醒、日程管理、自动回复都很常见。我有一个任务是每天晚上9点检查明天的日历，如果有重要会议就提前提醒我准备材料。&lt;/p&gt;
&lt;h2 id="主流工具对比"&gt;主流工具对比
&lt;/h2&gt;&lt;p&gt;做定时任务的工具有不少，我实际用过的几个拿出来对比一下。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;触发方式&lt;/th&gt;
					&lt;th&gt;执行能力&lt;/th&gt;
					&lt;th&gt;上下文&lt;/th&gt;
					&lt;th&gt;适合场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Claude Code Scheduled Tasks&lt;/td&gt;
					&lt;td&gt;cron式&lt;/td&gt;
					&lt;td&gt;代码执行+文件操作&lt;/td&gt;
					&lt;td&gt;单次会话&lt;/td&gt;
					&lt;td&gt;开发相关定时任务&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Cloudflare Workers + AI&lt;/td&gt;
					&lt;td&gt;cron+事件&lt;/td&gt;
					&lt;td&gt;HTTP请求+AI推理&lt;/td&gt;
					&lt;td&gt;无状态&lt;/td&gt;
					&lt;td&gt;轻量监控、API聚合&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GitHub Actions + AI&lt;/td&gt;
					&lt;td&gt;事件+cron&lt;/td&gt;
					&lt;td&gt;完整CI环境&lt;/td&gt;
					&lt;td&gt;单次运行&lt;/td&gt;
					&lt;td&gt;代码相关自动化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Temporal.io Workflows&lt;/td&gt;
					&lt;td&gt;任意&lt;/td&gt;
					&lt;td&gt;分布式执行&lt;/td&gt;
					&lt;td&gt;持久化&lt;/td&gt;
					&lt;td&gt;复杂长流程&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;选哪个取决于你的需求。如果只是每天抓个RSS写个摘要，Cloudflare Workers够用了，便宜且免运维。如果要和代码仓库深度联动，GitHub Actions是自然选择。如果需要复杂的多步骤流程和失败重试，Temporal是工业级方案。&lt;/p&gt;
&lt;h2 id="实操搭一个定时信息聚合"&gt;实操：搭一个定时信息聚合
&lt;/h2&gt;&lt;p&gt;以Claude Code为例，搭一个每天早上自动抓取技术新闻的定时任务。&lt;/p&gt;
&lt;p&gt;第一步，创建项目目录和任务定义：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/projects/news-agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/projects/news-agent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第二步，写一个抓取脚本。核心逻辑就是：读取RSS源→过滤→用LLM生成摘要→输出到文件。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# fetch_news.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;feedparser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SOURCES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;https://hnrss.org/newest?points=100&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;https://feeds.arstechnica.com/arstechnica/index&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_and_filter&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;yesterday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;articles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;SOURCES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;feed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feedparser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;published_parsed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;summary&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;summary&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 最多20篇&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;news&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fetch_and_filter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;news&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第三步，在Claude Code里配置定时执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;claude schedule add &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name &lt;span class="s2"&gt;&amp;#34;daily-tech-news&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --cron &lt;span class="s2"&gt;&amp;#34;0 7 * * *&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --prompt &lt;span class="s2"&gt;&amp;#34;运行 ~/projects/news-agent/fetch_news.py，读取输出，用中文生成摘要，保存到 ~/news/&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date +%Y-%m-%d&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;.md&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样一个最基础的定时信息聚合就搭好了。每天早上7点自动跑，你起床后直接看 &lt;code&gt;~/news/&lt;/code&gt; 目录下当天的文件就行。&lt;/p&gt;
&lt;h2 id="踩坑经验"&gt;踩坑经验
&lt;/h2&gt;&lt;p&gt;用了大半年定时任务，踩过不少坑，挑几个值得说的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;token消耗比你想象的高。&lt;/strong&gt; cron式任务每天跑一次，每次消耗2000-5000 token，一个月下来就是6-15万token。如果用的是Claude Opus这个级别的模型，一个月光定时任务就要几十美元。解决办法：简单任务用便宜模型（Haiku、GPT-4o-mini），复杂任务才上高端模型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;模型幻觉在定时任务里更危险。&lt;/strong&gt; 聊天场景下模型说了错话你可以当场纠正，但定时任务是无人值守的。我遇到过Agent把新闻标题里的&amp;quot;Apple&amp;quot;理解成水果，生成了一段莫名其妙的摘要。解决方案：对输出做结构化校验，加一个validation步骤。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;错误会累积。&lt;/strong&gt; 如果某个RSS源挂了或者格式变了，cron任务不会自动停止，它会每天尝试、每天失败、每天消耗token。我有一次一个任务连续失败了两周才发现。所以一定要加监控——任务连续失败N次就发告警。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;时区是个坑。&lt;/strong&gt; cron表达式默认用UTC，如果你在UTC+8，&lt;code&gt;0 8 * * *&lt;/code&gt; 实际是北京时间下午4点。这个坑我踩了整整一周才反应过来。记得确认你的任务调度器用的是什么时区。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文丢失。&lt;/strong&gt; daemon式任务理论上能保持上下文，但实际运行中上下文窗口是有限的。当对话历史太长时，早期的信息会被截断。重要的中间结论要定期持久化到文件里，不能全靠对话记忆。&lt;/p&gt;
&lt;h2 id="定时任务对ai-agent的意义"&gt;定时任务对AI Agent的意义
&lt;/h2&gt;&lt;p&gt;说到底，定时任务不只是一个技术功能，它改变了你和AI之间的关系。&lt;/p&gt;
&lt;p&gt;过去我们用AI的方式是&amp;quot;有问题才打开&amp;quot;——写代码遇到bug了问一下，写文案没灵感了问一下。AI是一个被动的工具，放在那里等你来用。&lt;/p&gt;
&lt;p&gt;定时任务让AI从被动工具变成了主动助手。&lt;/p&gt;
&lt;p&gt;当然，现在还远没到AI完全自主行动的程度。定时任务的prompt还是你写的，触发条件还是你定的，输出你还是要看的。但方向很明确：AI在变得越来越主动，人在变得越来越像&amp;quot;管理者&amp;quot;而不是&amp;quot;操作者&amp;quot;。&lt;/p&gt;
&lt;p&gt;学会给AI安排定时任务，就是学会当一个好管理者的第一步。&lt;/p&gt;</description></item></channel></rss>