id: 058740da637b4861a7df0fe50f603340
parent_id: 
item_type: 1
item_id: 5235596520544ceba15bae0e0c2059a6
item_updated_time: 1764345638620
title_diff: "[{\"diffs\":[[1,\"Cloudflare Worker AI 实战：用 AI + Worker 定时任务实现一\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":45}]"
body_diff: "[{\"diffs\":[[1,\"<html>\\\r\\\n<head>\\\r\\\n  <title>Cloudflare Worker AI 实战：用 AI + Worker 定时任务实现一个免费的智能发帖机器人</title>\\\r\\\n  <basefont face=\\\"微软雅黑\\\" size=\\\"2\\\" />\\\r\\\n  <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html;charset=utf-8\\\" />\\\r\\\n  <meta name=\\\"exporter-version\\\" content=\\\"YXBJ Windows/608924 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;\\\"/>\\\r\\\n  <meta name=\\\"content-class\\\" content=\\\"yinxiang.peso.superNote\\\"/>\\\r\\\n  <meta name=\\\"application-data:yinxiang.noteLayout\\\" content=\\\"{\\\"lineSpace\\\":\\\"recommend\\\",\\\"paragraphSpace\\\":\\\"recommend\\\"}\\\"/>\\\r\\\n  <style>\\\r\\\n\\tbody, td {\\\r\\\n\\t  font-family: 微软雅黑;\\\r\\\n\\t  font-size: 12pt;\\\r\\\n\\t}\\\r\\\n  </style>\\\r\\\n</head>\\\r\\\n<body>\\\r\\\n<a name=\\\"45030\\\"></a>\\\r\\\n<h1>Cloudflare Worker AI 实战：用 AI + Worker 定时任务实现一个免费的智能发帖机器人</h1>\\\r\\\n\\\r\\\n<div><span><div><br/></div><p><br/></p><div style=\\\"--en-blockquote:true;box-sizing: border-box; padding-left: 19px; padding-top: 6px; padding-bottom: 6px; border-left: 3px solid #b4c0cc; background-position: initial initial; background-repeat: initial initial; margin-top: 6px\\\"><div>原文链接: <a href=\\\"https://mp.weixin.qq.com/s?__biz=MzU3NzA5MDUwOA==&amp;mid=2247484953&amp;idx=1&amp;sn=cf5e1aca95beab6184e353e494ca61f6&amp;chksm=fcd9375495965ff1a24aaedeecd937da295dd351625d7b8947ffa8be435be8a7725705b2737f&amp;mpshare=1&amp;scene=1&amp;srcid=0726ZvcekXb3Gq78ZkSoXj8W&amp;sharer_shareinfo=bf3b6525fbc8a26c72fa551e46c4e9ee&amp;sharer_shareinfo_first=bf3b6525fbc8a26c72fa551e46c4e9ee#rd\\\" rev=\\\"en_rl_none\\\">https://mp.weixin.qq.com/s?__biz=MzU3NzA5MDUwOA==&amp;mid=224748...</a></div></div><p><br/></p><div><br/></div><h1 style=\\\"other-props:eyJibG9ja0lkIjoiaVNFclN1REdWTHQifQ==;\\\"> Cloudflare Worker AI 实战：用 AI + Worker 定时任务实现一个免费的智能发帖机器人</h1><div>原创 某鸟  某鸟碎碎 </div><div>在这个大模型的时代，Cloudflare也放出自己的AI平台：Cloudflare Worker AI，同样提供了大量的免费额度，足够小型项目使用了！</div><div>我之前写了个树洞小网站（<a href=\\\"https://mp.weixin.qq.com/s?__biz=MzU3NzA5MDUwOA==&amp;mid=2247484916&amp;idx=1&amp;sn=dd595d3e76889b0085a269981c578e67&amp;scene=21#wechat_redirect\\\" rev=\\\"en_rl_none\\\" target=\\\"_blank\\\">抛弃传统服务器：基于 Cloudflare Worker 和 D1 构建全栈 React 应用</a>），但是现在还没有人用，所以空荡荡的。于是我就想能不能让AI生成一些文章，每天自动提交几篇，假装有人在用……</div><div>那么一起来看看下怎么用免费的 Worker AI + 定时任务实现这个小功能吧！</div><div style=\\\"text-align:center;\\\"><span style=\\\"font-size: 24px;\\\"><span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\">创建一个  Worker 项目</span></span></span></div><div>使用 Wrangler 来创建worker。</div><div style=\\\"--en-codeblock:true;--en-blockId:HtRQT-21Al6;--en-meta:{&quot;title&quot;:&quot;&quot;,&quot;lang&quot;:&quot;Plain Text&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;showLine&quot;:true,&quot;lineWrap&quot;:true};box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;\\\">npm create cloudflare@latest -- hello-ai</div><div>图片中红色框框住的是我创建 worker项目时候的选项：</div><img src=\\\":/6424f1fd5f634955a3a6af90f7fe3829\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\" width=\\\"622\\\"/><ul><li><div><span style=\\\"font-size: 16px;\\\"><span style=\\\"font-family: ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;\\\"><span style=\\\"color: rgb(56,56,56);\\\"><span style=\\\"font-weight: 400;\\\"><i>What would you like to start with?</i></span></span></span></span></div><div> <code style=\\\"-en-code: true\\\"><span style=\\\"font-family: var(--__sl-font-mono);\\\">Hello World example：这是最简单的模板。</span></code></div></li><li><div> <i>Which template would you like to use?</i></div><div><i>  </i>Scheduler work<code style=\\\"-en-code: true\\\"><span style=\\\"font-family: var(--__sl-font-mono);\\\">：这次我们不需要页面，只是一段可以调用大模型的代码，后续会提到为什么选 Scheduler。</span></code></div></li><li><div><i>Which language do you want to use?</i></div><div> <code style=\\\"-en-code: true\\\"><span style=\\\"font-family: var(--__sl-font-mono);\\\">TypeScript</span></code></div></li><li><div><i>Do you want to use git for version control?</i></div><div> 根据自己的后续需求随便选一个，建议选 yes，这样在本地编辑器里面做的时候可以看到修改的记录.</div></li><li><div><i>Do you want to deploy your application?</i></div><div> <code style=\\\"-en-code: true\\\"><span style=\\\"font-family: var(--__sl-font-mono);\\\">No</span></code> 因为我们还需要修改代码，本地测试通过后再部署。</div></li></ul><div><br/></div><div style=\\\"text-align:center;\\\"><span style=\\\"font-size: 24px;\\\"><span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\">绑定 Worker AI 到 worker 上</span></span></span></div><div>用文本编辑器打开刚创建项目的 wrangler.jsonc, 添加 AI 的绑定上去，和之前绑定 D1 数据库一样：</div><img src=\\\":/6cee2bb4332149d09c95b547465f31a7\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div style=\\\"text-align:center;\\\"><span style=\\\"font-size: 24px;\\\"><span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\">指定模型和添加调用接口</span></span></span></div><div>我们需要在woker的代码中指定要调用的模型，Cloudflare中支持50多种开源的大模型（基本涵盖现有的各种模型），当然基本上都是蒸馏版本的。这里我们来试一下 deepseek-r1-distill-qwen-32b ： 一个基于Qwen2.5 蒸馏的 Deepseek。</div><div>打开 ./src/index.ts，修改代码，主要是fetch中使用 envAI.run 来指定模型和prompt。</div><img src=\\\":/76f21bb1b78048ef9859b729e5c9a529\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div style=\\\"text-align:center;\\\"><span style=\\\"font-size: 24px;\\\"><span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\">本地测试 Worker AI 调用</span></span></span></div><div>我们在worker代码中定义了一个接口，访问后可以直接调用模型返。让我们在本地调试一下是否可以跑起来：</div><div style=\\\"--en-codeblock:true;--en-blockId:pjbgTCW-uTY;--en-meta:{&quot;title&quot;:&quot;&quot;,&quot;lang&quot;:&quot;Plain Text&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;showLine&quot;:true,&quot;lineWrap&quot;:true};box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;\\\">npx wrangler dev</div><img src=\\\":/93e3c9c443a84206865a9ade91dc8161\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div>可以直接访问 local server测试调用逻辑：</div><img src=\\\":/74d142ad9b274782b4ac20b7f21f813b\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div style=\\\"text-align:center;\\\"><span style=\\\"font-size: 24px;\\\"><span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\">定时触发 Worker</span></span></span></div><div>让 Worker 可以定时触发，关键是下面两个地方：</div><ul><li><div>在 wrangler.jsonc 文件中增加 trigger 的配置，使用 crons的格式，可以配置多个时间。关于Cron，可以参考这篇文章：<a href=\\\"https://mp.weixin.qq.com/s?__biz=MzU3NzA5MDUwOA==&amp;mid=2247483729&amp;idx=1&amp;sn=c9d0167ee75926e05acb24be6d52ba44&amp;scene=21#wechat_redirect\\\" rev=\\\"en_rl_none\\\" target=\\\"_blank\\\">Cron表达式入门</a>。</div></li></ul><img src=\\\":/59c58723ecc44f6dbf61e324e318834a\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><ul><li><div>在 Worker 的 index.ts 中添加一个 scheduled 的的方法。</div></li></ul><img src=\\\":/d24de46165e64044b6a197b31413febb\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div style=\\\"text-align:center;\\\"><span style=\\\"font-size: 24px;\\\"><span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\">让 worker 可以发布文章到树洞网站</span></span></span></div><div>可以让 scheduled 方法直接操作数据库添加文章，这样可以减少 worker的调用次数，节省一点免费额度……</div><ul><li><div>修改配置文件 wrangler.jsonc 添加数据库绑定：</div></li></ul><img src=\\\":/d04d3e9a2ad7417390cd963c646bcdb6\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><ul><li><div>修改代码调用大模型，然后将回复插入数据库中：</div></li></ul><img src=\\\":/8c27eee4bb4c481c9a5f07493283a1e1\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div style=\\\"text-align:center;\\\"><span style=\\\"font-size: 24px;\\\"><span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\">本地测试与部署</span></span></span></div><div>可以通过 npx wrangler dev 在本地启动 Worker，Wrangler 检测到有trigger的配置，会自动配置一个测试端口 /cdn-cgi/handler/scheduled，可以直接在浏览器访问：</div><img src=\\\":/0682bc3b0fa340bc85e6d3b037545171\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div>报错了？是因为我没有在本地初始化数据库。不过看起来方法是成功执行了， 直接部署到Cloudflare上看看效果吧！</div><ul><li><div>先登录一下：登录经常会遇到真人校验刷新不出来的情况，可以重启一下浏览器，还是有就是先主动打开 Cloudflare 的网页登陆成功后，再来执行这个登录命令会速度快一点：</div></li></ul><div style=\\\"--en-codeblock:true;--en-blockId:bR7GQ6j7TIF;--en-meta:{&quot;title&quot;:&quot;&quot;,&quot;lang&quot;:&quot;Plain Text&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;showLine&quot;:true,&quot;lineWrap&quot;:true};box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;\\\">npx wrangler login</div><ul><li><div>然后部署：</div></li></ul><div style=\\\"--en-codeblock:true;--en-blockId:j9CQTaHaEmS;--en-meta:{&quot;title&quot;:&quot;&quot;,&quot;lang&quot;:&quot;Plain Text&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;showLine&quot;:true,&quot;lineWrap&quot;:true};box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial; margin-top: 6px;\\\">npx wrangler deploy</div><div>因为这次只是部署一个存储的定时worker， 不需要真实的访问接口，所以就不绑定域名了。</div><div>访问 <span style=\\\"color: rgb(255, 165, 0);\\\"><span style=\\\"font-weight: bold;\\\"><u>htts:/treehole.luoyuan.cloud</u></span></span> 看一下部署后的运行效果：原来空空如也的树洞，现在堆满了大模型模拟人类的强说愁……</div><img src=\\\":/fc8153c744de4969bdd441e828ea6483\\\" type=\\\"image/png\\\" data-filename=\\\"640.png\\\" style=\\\"--en-marks:%7B%22align%22%3A%22center%22%7D;--en-uploadstate:uploaded;\\\"/><div><br/></div><div><br/></div></span>\\\n</div></body></html>\\u0000\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":11104}]"
metadata_diff: {"new":{"id":"5235596520544ceba15bae0e0c2059a6","parent_id":"f67288c3a0be4374b5d532b5dcc3aabc","latitude":"0.00000000","longitude":"0.00000000","altitude":"0.0000","author":"","source_url":"","is_todo":0,"todo_due":0,"todo_completed":0,"source":"joplin-desktop","source_application":"net.cozic.joplin-desktop","application_data":"","order":1764348817421,"markup_language":2,"is_shared":0,"share_id":"","conflict_original_id":"","master_key_id":"","user_data":"","deleted_time":0},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2025-11-28T21:03:20.982Z
created_time: 2025-11-28T21:03:20.982Z
type_: 13