<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>廖智海</title><link href="https://hillerliao.github.io/" rel="alternate"></link><link href="https://hillerliao.github.io/feeds/all.atom.xml" rel="self"></link><id>https://hillerliao.github.io/</id><updated>2026-05-01T00:00:00+08:00</updated><subtitle>互联网产品折腾师</subtitle><entry><title>OpenClaw + Anki: 龙虾又接管了一款软件</title><link href="https://hillerliao.github.io/openclaw-anki.html" rel="alternate"></link><published>2026-05-01T00:00:00+08:00</published><updated>2026-05-01T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-05-01:/openclaw-anki.html</id><summary type="html">&lt;p&gt;让 OpenClaw 接管 Anki，把建牌组、批量制卡、搜索和复习提醒变成一句话就能完成的日常操作。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="OpenClaw + Anki 文章封面" src="../images/openclaw-anki-cover.webp"&gt;&lt;/p&gt;
&lt;p&gt;我最近在干一件事：把我所有常用的软件，都交给 OpenClaw 管。&lt;/p&gt;
&lt;p&gt;这不是什么宏大计划，就是一次使用习惯上的彻底转向。以前，我用浏览器要打开浏览器，用笔记要打开 Obsidian，用 Anki 要打开 Anki Desktop。每个软件都有自己的界面、自己的操作逻辑、自己的那一套折腾人的流程。&lt;/p&gt;
&lt;p&gt;现在，我只想打开 OpenClaw。我想让它成为我操作的统一入口。我说什么，它去各个软件里执行。&lt;/p&gt;
&lt;p&gt;Anki 是我最新收编的一个。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;为什么是 Anki&lt;/h2&gt;
&lt;p&gt;简单说，Anki 是一个间隔重复系统。你把知识点做成卡片，它会根据你记得牢不牢，自动安排下次复习时间。用久了，它会变成你的长期记忆库。&lt;/p&gt;
&lt;p&gt;但 Anki 有个一直让我不舒服的地方：它明明那么重要，但往里面喂知识的过程太原始了。&lt;/p&gt;
&lt;p&gt;复制，粘贴，新建卡片，选牌组，打标签。一张还行。十张开始烦。五十张想摔电脑。&lt;/p&gt;
&lt;p&gt;更痛苦的是，很多时候你明明知道这段内容该进 Anki——一篇文章里的关键概念、一份考试资料的易错点、Obsidian 里随手记的笔记——但一想到要手动拆卡，你就对自己说"算了，晚点再说"。&lt;/p&gt;
&lt;p&gt;然后就就是"算了，算了"。&lt;/p&gt;
&lt;p&gt;这个问题一直存在，但我以前没想通怎么解决。直到我开始用 OpenClaw。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;我要的不是插件，是入口&lt;/h2&gt;
&lt;p&gt;OpenClaw 对我来说，不是一个聊天机器人。它是一个可以长期在线、可以调用工具、可以替我执行操作的 Agent。&lt;/p&gt;
&lt;p&gt;我想要的是：&lt;strong&gt;以后只要是操作 Anki 的事，我就在 OpenClaw 里跟它说一声，它去办。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不是"它建议我怎么操作"，不是"它给我一段代码让我自己跑"。是它真的去操作。&lt;/p&gt;
&lt;p&gt;我说话，它干活。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;现在我是这么用的&lt;/h2&gt;
&lt;p&gt;先说 Anki 里最基础的操作。建牌组、批量建卡、搜索、改标签、跨牌组移动，OpenClaw 全能干。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"帮我新建一个国考错题牌组。"&lt;br&gt;
"把这 50 个单词批量导进 N5 牌组，正面日语，背面中文。"&lt;br&gt;
"查一下 biology 牌组里这周新加了什么。"&lt;br&gt;
"从日语 N3 和 N4 里找出所有带『ます形』的卡片，复制到语法复习牌组。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这些事它几秒钟干完。以前我手动做，少则几分钟，多则半小时。这叫"接管操作"。&lt;/p&gt;
&lt;p&gt;但真正让我觉得爽的，是下面这些。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;读文章&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;刷到一篇文章，里面有个观点很戳我："要相信时间的力量，相信成长的力量，不要在小事上跟孩子大动干戈，让孩子多感受爱，因为童年的爱里，藏着孩子一生的力量和光。"复制这段话，切到 OpenClaw：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"帮我做张 Anki 卡片，记到读书笔记牌组里。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不用想正反面怎么写，不用管格式。它自己判断。我继续读文章。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;陪娃&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;晚上娃唱"Elephants have wrinkles"，我觉得歌词不错，想记下来。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"你把这首歌的歌词找到，做成 Anki 卡片。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;它自己去搜，自己决定卡片结构，自己存。我陪娃继续玩。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;刷推特&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;刷到一条："Vibe Coding 加持之下，一人公司，代码实现不是最关键的。最关键的是怎么找到愿意为你的产品和服务付费的用户。"&lt;/p&gt;
&lt;p&gt;我觉得这句话说得太准了，想存下来。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"这条推特给我存一下 Anki 卡片。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;它知道该放哪个牌组（我设过规则：推特精华进『灵感池』），用什么格式。我继续刷。&lt;/p&gt;
&lt;p&gt;这些场景的共同点是：&lt;strong&gt;我不需要停下来"进入整理状态"&lt;/strong&gt;。碰到值得记的东西，顺手扔给 OpenClaw，十秒以内搞定。不打断正在做的事。&lt;/p&gt;
&lt;p&gt;以前是"我先记下来，晚点再整理进 Anki"——然后就没有然后了。现在是"OpenClaw，帮我存一下"——然后它真存了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;更多玩法：不只是"我找它"，还能"它找我"&lt;/h2&gt;
&lt;p&gt;上面说的都是"我主动找 OpenClaw"。但 OpenClaw 是 7×24 小时跑着的，它可以反过来找我。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;定时复习提醒&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"每天上午 10 点，从国考错题牌组里随机抽 5 张卡片，发给我。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OpenClaw 到点就推过来。不用打开 Anki，在聊天窗口里就能过一遍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复习进度日报&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"每天晚上 11 点，告诉我今天学了多久、复习了多少张卡、哪个牌组欠的债最多。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第二天早上我看一眼，就知道今天该补哪块。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;卡片过期预警&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"检查一下『N1 语法』牌组里，有没有超过 6 个月没复习的卡片，列出来问我是否删除或归档。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OpenClaw 自己去搜，然后把结果推给我，我一句话就处理了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主动补卡&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OpenClaw 知道我最近在读什么文章、在 Obsidian 里记了什么笔记。它可以自己判断：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"你昨天记的那段关于 MCP 协议的笔记，好像还没做成 Anki 卡片，要不要我帮你生成几张？"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我说"好"，它就做了。我说"不用"，它就不打扰。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;随机投喂&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"每周末下午 3 点，随机从我的所有牌组里抽 10 张卡片发给我，当周末小测验。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不知不觉就把边边角角的知识回顾了一遍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复习节奏提醒&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Anki 自己虽然有复习提醒，但那是"软件内的"。我经常打开 Anki 才看到有 200 张卡等着我，然后压力很大。&lt;/p&gt;
&lt;p&gt;换个方式：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"每天早上 9 点，检查今天到期的卡片数量，如果超过 50 张就提醒我'今天债有点多，早点开始复习'，如果少于 10 张就说'今天轻松，可以多往前学点新的'。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OpenClaw 自己判断，自己调整话术。像个学习搭子。&lt;/p&gt;
&lt;p&gt;核心变化是什么？以前是我追着知识跑——我得记得去打开 Anki，得记得今天该复习哪个牌组，得自己安排节奏。&lt;/p&gt;
&lt;p&gt;现在是知识来找我。OpenClaw 替我把节奏安排好了。到点推送，逾期提醒，主动补卡。&lt;/p&gt;
&lt;p&gt;我不用记"今天该复习什么"。我只管看它发给我的东西。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;技术上怎么实现的&lt;/h2&gt;
&lt;p&gt;市面上其实早就有类似方案，最主流的是给 Anki Desktop 装一个 AnkiConnect 插件，开一个本地接口。但这里有个现实问题：Anki Desktop 得一直开着。&lt;/p&gt;
&lt;p&gt;如果你的 Agent 跑在自己电脑上还凑合。但 OpenClaw 是 7×24 小时跑在服务器上的，我不可能在服务器上长期开一个带图形界面的桌面软件。关掉 Anki 就断连，电脑睡眠也断连。Agent 明明一直醒着，Anki 却只能在我打开电脑的时候被操作。&lt;/p&gt;
&lt;p&gt;所以我真正想要的是——Anki 自己也变成一个服务器上的服务。&lt;/p&gt;
&lt;p&gt;换一条路。方案比你想的简单。&lt;/p&gt;
&lt;p&gt;如果你只是想给 OpenClaw 用（它帮你建卡、整理、提醒），让 OpenClaw 和 Anki 服务跑在同一台机器上，走 localhost 就够了。不需要域名，不需要 HTTPS 证书，不需要折腾 nginx。&lt;/p&gt;
&lt;p&gt;甚至你都不用手动部署。把踩坑总结好的部署指南扔给 OpenClaw，说一句"按这份指南，在你自己的机器上把 Anki 服务部署起来"，它自己就能搞定。&lt;/p&gt;
&lt;p&gt;架构是三层：数据层（Anki 同步服务）、API 层（REST 接口）、桥接层（MCP 包装）。因为全跑在本机，省去了公网那一堆麻烦。&lt;/p&gt;
&lt;p&gt;如果你还想用自己的 Anki 客户端（电脑或手机）也连上这套服务正常复习，那服务就需要走公网。至少需要一个公网 IP 地址。Anki 的同步协议不强制 HTTPS，公网 IP 加端口就能用。&lt;/p&gt;
&lt;p&gt;两个场景，两种复杂度。看你自己需要哪一种。&lt;/p&gt;
&lt;p&gt;数据备份还是要做的。我每半小时把数据库同步到坚果云。服务器挂了不怕，卡片丢了才是真难受。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;哪些人值得试试&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;第一类，Anki 重度用户。&lt;/strong&gt; 牌组成百上千张，每天花大量时间整理卡片。OpenClaw 能把整理时间从几十分钟压缩到几秒。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二类，已经在用 OpenClaw 这类 Agent 的人。&lt;/strong&gt; 想让 Agent 真能干点活，不只是聊天。Anki 是一个很好的切入点。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三类，有"收集癖"但"整理懒"的人。&lt;/strong&gt; 看到好东西就想存，但存完就不管了。OpenClaw 能把"存"和"整理"合并成一步。&lt;/p&gt;
&lt;p&gt;如果你只是偶尔背几个单词，真没必要折腾这个。手动就够了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;不想折腾怎么办&lt;/h2&gt;
&lt;p&gt;有两种办法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一种，让 OpenClaw 自己部署。&lt;/strong&gt; 你把踩坑总结的部署指南扔给它，它自己在本机把服务跑起来。这是最省心的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二种，找我远程指导。&lt;/strong&gt; 如果你属于上面说的三类人，但不想自己踩坑，可以找我。我踩过的坑，你就不用再踩一遍了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;我正在把一切都交给 OpenClaw&lt;/h2&gt;
&lt;p&gt;不只是 Anki。浏览器、笔记软件、提醒事项、文件管理……我希望有一天，所有我常用的软件，都能在 OpenClaw 里操作。&lt;/p&gt;
&lt;p&gt;我不想再学每个软件怎么用。我只想学会怎么跟 OpenClaw 说话。&lt;/p&gt;
&lt;p&gt;Anki 是这一步里很小的一块，也是让我觉得最爽的一块。因为它解决了那个困扰我很久的问题——明明知道该复习，但懒得整理。&lt;/p&gt;
&lt;p&gt;现在不用整理了。OpenClaw 替我干。&lt;/p&gt;
&lt;p&gt;我只管学。&lt;/p&gt;
&lt;p&gt;如果你想直接拿到完整部署方案——扫码联系我，免费领取部署指南。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;原文链接：&lt;a href="https://mp.weixin.qq.com/s/-J-Dqic2Hi8V7M3fkAVg1g"&gt;OpenClaw + Anki: 龙虾又接管了一款软件&lt;/a&gt;&lt;/p&gt;</content><category term="AI"></category><category term="OpenClaw"></category><category term="Anki"></category><category term="AI智能体"></category><category term="知识管理"></category><category term="间隔重复"></category></entry><entry><title>我不再相信AI Agent说的「执行成功」了</title><link href="https://hillerliao.github.io/hermes-agent-execution-success-verification.html" rel="alternate"></link><published>2026-04-30T00:00:00+08:00</published><updated>2026-04-30T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-04-30:/hermes-agent-execution-success-verification.html</id><summary type="html">&lt;p&gt;一次延后提醒的小事，让我重新理解 AI Agent 的「执行成功」到底靠不靠谱。&lt;/p&gt;</summary><content type="html">&lt;p&gt;我最近把一些很碎的提醒，交给 Hermes Agent来处理。&lt;/p&gt;
&lt;p&gt;你可以先把它理解成一个接入微信、Telegram、飞书这些聊天工具的个人 AI 助理，不只是陪你聊天，也能调用工具，比如查资料、读文件、跑命令、管理定时任务。&lt;/p&gt;
&lt;p&gt;这里说的提醒，不是手机闹钟，也不是微信自带功能。实际效果就是，我在微信里告诉 Hermes Agent，明天几点提醒我做什么，它接到指令后调用定时任务工具登记下来，到点再把提醒发回到微信里。&lt;/p&gt;
&lt;p&gt;前一天我就是这么设了一个提醒，第二天上午9点提醒我去朝阳出入境大厅取港澳通行证。&lt;/p&gt;
&lt;p&gt;早上9点，这条提醒到了。&lt;/p&gt;
&lt;p&gt;但我当时走不开，就在微信里引用了那条提醒消息，补了一句，Delay the task and remind me at 12:30。&lt;/p&gt;
&lt;p&gt;剩下的，就是看到 Hermes Agent 在吭哧吭哧地调来调去。折腾了一阵，它告诉我：调整成功。&lt;/p&gt;
&lt;p&gt;不过这折腾的过程，我觉得有必要回顾一下。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;原任务？早没了&lt;/h2&gt;
&lt;p&gt;延后提醒，就是把原任务的提醒时间从9点改成12:30。&lt;/p&gt;
&lt;p&gt;听起来很简单。&lt;/p&gt;
&lt;p&gt;Hermes Agent一开始也是按这个方向处理的。&lt;/p&gt;
&lt;p&gt;它先确认了一下当前时间，10:26，12:30还没过。这个动作很小，但能避免把提醒设到一个已经过去的时间。&lt;/p&gt;
&lt;p&gt;然后它尝试修改原任务。&lt;/p&gt;
&lt;p&gt;原提醒消息里带着任务编号，0a1fc54812b9。既然是延后，最合理的操作就是找到这个任务，把它的执行时间改掉。&lt;/p&gt;
&lt;p&gt;结果系统返回，任务不存在。&lt;/p&gt;
&lt;p&gt;为啥？&lt;/p&gt;
&lt;p&gt;因为这个取证提醒是一次性任务。早上9点已经执行完了，执行完之后，系统就把它从调度器内存里清理掉了。&lt;/p&gt;
&lt;p&gt;也就是说，我微信里刚刚收到的那条提醒，在任务系统里已经不在了。&lt;/p&gt;
&lt;p&gt;这就是第一个小坑。&lt;/p&gt;
&lt;p&gt;对人来说，「刚刚那条提醒」还在聊天记录里。&lt;/p&gt;
&lt;p&gt;对 Hermes Agent 的调度系统来说，那个一次性任务已经结束了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;旧的没了，新建一个&lt;/h2&gt;
&lt;p&gt;既然原任务已经不存在，就不能再修改它。&lt;/p&gt;
&lt;p&gt;只能新建一个。&lt;/p&gt;
&lt;p&gt;它建了一个一次性任务，时间是当天12:30。&lt;/p&gt;
&lt;p&gt;内容还是去朝阳出入境大厅领取港澳通行证。&lt;/p&gt;
&lt;p&gt;发送位置还是当前这个微信聊天。&lt;/p&gt;
&lt;p&gt;系统返回说创建成功，并给了一个新任务编号，e3dbbb0a9bb1。&lt;/p&gt;
&lt;p&gt;如果只是普通操作，到这里就可以结束了。&lt;/p&gt;
&lt;p&gt;系统说成功，任务有编号，时间也对。&lt;/p&gt;
&lt;p&gt;看起来已经没问题。&lt;/p&gt;
&lt;p&gt;但我现在对这种「执行成功」四个字已经没那么放心了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;「成功」也不一定靠谱&lt;/h2&gt;
&lt;p&gt;这里要讲一下前一次踩坑。&lt;/p&gt;
&lt;p&gt;之前我有一个「A股每日复盘」的定时任务。它每个工作日16:30自动运行，整理当天市场情况，然后推送给我。&lt;/p&gt;
&lt;p&gt;后来我想把它的投递通道，从飞书改到Telegram。&lt;/p&gt;
&lt;p&gt;当时工具返回消息说修改成功了，任务时间还在，任务状态也正常，投递通道也确实变成了Telegram。&lt;/p&gt;
&lt;p&gt;看起来一切都对。&lt;/p&gt;
&lt;p&gt;但后来去检查持久化文件的时候，发现一个很严重的问题。&lt;/p&gt;
&lt;p&gt;这个任务的prompt被清空了。&lt;/p&gt;
&lt;p&gt;prompt可以简单理解为任务正文，也就是它到点之后到底要干什么。&lt;/p&gt;
&lt;p&gt;这就很尴尬。&lt;/p&gt;
&lt;p&gt;任务的壳还在，时间还在，状态还在，但它已经不知道自己该执行什么了。&lt;/p&gt;
&lt;p&gt;如果不去检查，下一次它可能还是会按时启动，但启动之后没有正文可执行。&lt;/p&gt;
&lt;p&gt;这种问题，光看「执行成功」是看不出来的。&lt;/p&gt;
&lt;p&gt;所以后来我让 Hermes Agent 自己想办法避免这种问题。它给出的方案是留一条持久记忆，涉及定时任务时，不能只相信 Agent 调度器返回的成功，要去~/.hermes/cron/jobs.json里确认任务是否完整落盘。&lt;/p&gt;
&lt;p&gt;你可以把jobs.json理解成定时任务真正写在硬盘上的登记本。&lt;/p&gt;
&lt;p&gt;调度器返回成功，更像是告诉你，系统刚刚接受了这个操作。&lt;/p&gt;
&lt;p&gt;但任务有没有完整、可靠地写进登记本里，尤其是正文有没有丢，还要另查。&lt;/p&gt;
&lt;p&gt;所以这次重新创建12:30提醒之后，Hermes Agent没有停在「创建成功」那里。&lt;/p&gt;
&lt;p&gt;它去读了硬盘上的jobs.json文件，想确认新任务真的存进去了。&lt;/p&gt;
&lt;p&gt;第一次查，没找到。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;查不到？原来是查错了&lt;/h2&gt;
&lt;p&gt;第一次查不到的时候，看起来有点吓人。&lt;/p&gt;
&lt;p&gt;系统刚刚说创建成功，怎么硬盘文件里没有？&lt;/p&gt;
&lt;p&gt;后来继续看文件结构，才发现是字段名不一样。&lt;/p&gt;
&lt;p&gt;定时任务工具返回的任务编号字段叫job_id。&lt;/p&gt;
&lt;p&gt;但jobs.json文件里，存的是id。&lt;/p&gt;
&lt;p&gt;这就像一张表里写「订单号」，另一张表里写「编号」，说的是同一个东西，但你按错字段查，就会以为它不存在。&lt;/p&gt;
&lt;p&gt;第一次脚本按job_id去查，所以查不到。&lt;/p&gt;
&lt;p&gt;改成按id查之后，果然找到了。&lt;/p&gt;
&lt;p&gt;新任务确实在文件里，时间是12:30，投递位置是当前微信聊天，状态是scheduled。&lt;/p&gt;
&lt;p&gt;到这里，才算确认这件事真的办完了。&lt;/p&gt;
&lt;p&gt;注意，这里的重点不是字段名有多奇怪。&lt;/p&gt;
&lt;p&gt;重点是，如果没有那条「必须查持久化文件」的规则，整个流程很可能在「创建成功」那一步就结束了。&lt;/p&gt;
&lt;p&gt;而这一步，恰恰是之前出过问题的地方。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;不是细心，是踩过坑&lt;/h2&gt;
&lt;p&gt;为什么微信引用原消息很重要？&lt;/p&gt;
&lt;p&gt;这次我不是单独发了一句「延后到12:30」，而是引用了原来的提醒消息。&lt;/p&gt;
&lt;p&gt;这个动作很重要。AI Agent 当前上下文不会把定时任务发送的消息算进去，这是很不符合用户习惯的地方。&lt;/p&gt;
&lt;p&gt;如果只说「延后到12:30」，不引用定时任务发送的消息，对于当前上下文来说，缺少三个信息，延后哪个任务，原任务编号是什么，原提醒内容是什么。&lt;/p&gt;
&lt;p&gt;AI Agent 拿到这些信息，才知道应该处理的是哪一个任务。&lt;/p&gt;
&lt;p&gt;所以和 Agent 协作时，一定要注意定时任务消息和当前上下文割裂的问题。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Agent靠谱？全靠规矩&lt;/h2&gt;
&lt;p&gt;通过不断地调教，我现在越来越觉得，Agent 的可靠性，来自三件事。&lt;/p&gt;
&lt;p&gt;上下文够不够清楚，规则有没有提前写下来，执行完有没有校验。&lt;/p&gt;
&lt;p&gt;这次的取证提醒就是一个很小的例子。&lt;/p&gt;
&lt;p&gt;如果没有引用原提醒消息，它不一定知道要延后哪个任务。&lt;/p&gt;
&lt;p&gt;如果没有持久记忆里的校验规则，它很可能会停在「创建成功」。&lt;/p&gt;
&lt;p&gt;如果没有去查jobs.json，也就发现不了任务到底有没有真正保存。&lt;/p&gt;
&lt;p&gt;所以我现在不太相信 Claude、Hermes Agent，或者其他 Agent 系统嘴里的「执行成功」。&lt;/p&gt;
&lt;p&gt;不是说它们一定在骗你。&lt;/p&gt;
&lt;p&gt;而是「执行成功」通常只代表某一个环节成功了。&lt;/p&gt;
&lt;p&gt;它不一定代表整件事已经可靠闭环。&lt;/p&gt;
&lt;p&gt;这和我们平时用软件很像。&lt;/p&gt;
&lt;p&gt;页面提示保存成功，不代表文件没有损坏。&lt;/p&gt;
&lt;p&gt;转账页面显示提交成功，不代表最终到账。&lt;/p&gt;
&lt;p&gt;任务显示创建成功，也不代表它的正文、时间、投递位置都完整保存了。&lt;/p&gt;
&lt;p&gt;关键任务，还是要看最终记录。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;想试试？多让 AI Agent 二次确认&lt;/h2&gt;
&lt;p&gt;如果你也在用 AI Agent 管定时任务，这里有一个简单的做法：&lt;strong&gt;让 Agent 马上发一条消息验证一下。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;别太相信 AI Agent 说的「执行成功」。&lt;strong&gt;验证过的「执行成功」&lt;/strong&gt;才是真的成功。&lt;/p&gt;
&lt;p&gt;扫码入群，交流 AI Agent 使用体验。&lt;/p&gt;
&lt;p&gt;&lt;img alt="扫码入群，交流 AI Agent 使用体验" src="https://hillerliao.github.io/images/openclaw-group-qrcode.jpg"&gt;&lt;/p&gt;</content><category term="AI"></category><category term="AI Agent"></category><category term="Hermes Agent"></category><category term="自动化"></category><category term="个人博客"></category></entry><entry><title>我让 OpenClaw 把《忆江南》贴在卫生间 提醒孩子背古诗</title><link href="https://hillerliao.github.io/openclaw-yijiangnan-bathroom.html" rel="alternate"></link><published>2026-04-29T00:00:00+08:00</published><updated>2026-04-29T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-04-29:/openclaw-yijiangnan-bathroom.html</id><summary type="html">&lt;p&gt;用 OpenClaw 把《忆江南》做成图片，推送到卫生间的 MindReset 电子墨水屏上，让孩子在刷牙时自然想起古诗。&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="卫生间电子墨水屏上显示《忆江南》" src="../images/openclaw-yijiangnan-bathroom.jpg"&gt;&lt;/p&gt;
&lt;p&gt;孩子这周学了白居易的《忆江南》。&lt;/p&gt;
&lt;p&gt;按照以前的经验，刚学完几天还记着，但过不了多久就会忘干净。要是专门提醒他背，又容易变成任务，反而让他更抵触。&lt;/p&gt;
&lt;p&gt;我突然想到一个地方：&lt;strong&gt;卫生间&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;每天早晚刷牙，他都会站在那里两三分钟。这个时间不长，但足够看见几个字。如果我放在卫生间那块电子墨水屏上，正好显示着“忆江南”三个字，是不是就能顺手提醒他想起这首诗？&lt;/p&gt;
&lt;p&gt;不是逼他背，也不是增加一个学习任务，只是在一个每天都会经过的地方，轻轻贴一个提醒。&lt;/p&gt;
&lt;p&gt;于是我对 &lt;strong&gt;OpenClaw（本地智能体）&lt;/strong&gt; 说了一句：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“把忆江南这三个简体汉字发成图片推送到卫生间的那一块墨水屏幕，字尽可能大一点，不能太小，只要把屏幕四边留点空白就行。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;几分钟后，卫生间的电子墨水屏上就&lt;strong&gt;贴&lt;/strong&gt;上了三个大字：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;忆江南&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;白底黑字，居中，挺大，四边留了一点空白。&lt;/p&gt;
&lt;p&gt;这件事本身不复杂，有意思的地方在于：OpenClaw 这类智能体不只是“会聊天”，而且可以把一句很日常的话，变成现实世界里的一个动作。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;这块小屏幕，为什么能被 OpenClaw 控制？&lt;/h2&gt;
&lt;p&gt;这里需要解释一下这块屏幕。&lt;/p&gt;
&lt;p&gt;我用的是 &lt;strong&gt;MindReset Dot&lt;/strong&gt; 一类的电子墨水屏。你可以先把它理解成一个“小型 Kindle 屏幕”，它不刺眼，功耗很低，内容刷新之后可以长时间停留在那里。&lt;/p&gt;
&lt;p&gt;但它和 Kindle 最大的区别是：Kindle 是拿在手里读书的，MindReset 这种屏幕更像是&lt;strong&gt;贴&lt;/strong&gt;在家里某个固定位置的“信息牌”。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;贴在冰箱上，显示今天要买什么；&lt;/li&gt;
&lt;li&gt;贴在玄关，显示出门前要带的东西；&lt;/li&gt;
&lt;li&gt;贴在书桌，显示今天最重要的一件事；&lt;/li&gt;
&lt;li&gt;贴在卫生间，显示孩子本周要背的诗。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是一个普通电子相框，其实也没什么特别。你手动换图，它就显示一张图。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MindReset 这类设备真正有魅力的地方在于：它能联网，而且有开放 API。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这意味着它不是一个孤立的屏幕，而是一个可以被外部程序控制的显示节点。&lt;/p&gt;
&lt;p&gt;对普通用户来说，这可能只是“我可以远程换屏幕内容”。&lt;/p&gt;
&lt;p&gt;但对 &lt;strong&gt;OpenClaw&lt;/strong&gt; 这类智能体来说，这就是一个入口。它可以根据你的指令，自动生成内容，再调用 API，把内容&lt;strong&gt;贴&lt;/strong&gt;到指定屏幕上。&lt;/p&gt;
&lt;p&gt;所以，这块屏幕不是一个“死”的硬件。&lt;/p&gt;
&lt;p&gt;它是家里一个可以被 OpenClaw 更新的信息角落。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;为什么提醒背诗，我反而选了卫生间？&lt;/h2&gt;
&lt;p&gt;孩子背诗，最自然的地方当然是书桌。&lt;/p&gt;
&lt;p&gt;但我这次反而选了卫生间。&lt;/p&gt;
&lt;p&gt;原因很简单：刷牙是一个非常稳定的日常动作。每天早晚都会发生，而且每次都有两三分钟的空档。&lt;/p&gt;
&lt;p&gt;这个时间不适合塞进复杂学习任务，但很适合放一个轻量提醒。&lt;/p&gt;
&lt;p&gt;比如看到“忆江南”三个字，他可能就会自然想起：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;江南好，风景旧曾谙。&lt;br&gt;
日出江花红胜火，春来江水绿如蓝。&lt;br&gt;
能不忆江南？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这不是正式背诵，也不是考试。&lt;/p&gt;
&lt;p&gt;它更像是把课堂里刚学到的东西，轻轻&lt;strong&gt;贴&lt;/strong&gt;回生活里。&lt;/p&gt;
&lt;p&gt;这也是电子墨水屏很适合的地方。&lt;/p&gt;
&lt;p&gt;手机提醒太强了。它会震动，会弹窗，会把人拉进另一个信息流。孩子看到手机，也很容易被别的东西吸引。&lt;/p&gt;
&lt;p&gt;纸条又太弱了。贴上去几天之后，就很容易变成背景，大家都看不见了。&lt;/p&gt;
&lt;p&gt;电子墨水屏刚好在中间。&lt;/p&gt;
&lt;p&gt;它不吵，不亮，不抢注意力，但它一直在那里。&lt;/p&gt;
&lt;p&gt;你路过，就能看到。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;OpenClaw 做的，不是回答，而是执行&lt;/h2&gt;
&lt;p&gt;如果只是让聊天机器人回答问题，它最多会告诉你：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“你可以用 Python 生成一张图片，然后调用电子墨水屏的 API 推送过去。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但 OpenClaw 不是停在“告诉你怎么做”。&lt;/p&gt;
&lt;p&gt;这一次，它实际完成了这些步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;找到卫生间那块屏幕对应的设备别名 &lt;code&gt;toilet&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;解析出真实设备 比如ID：&lt;code&gt;48F6EE576429&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;按屏幕尺寸（296×152 px）生成一张黑白图片。&lt;/li&gt;
&lt;li&gt;找到系统里能显示中文的字体（文泉驿正黑）。&lt;/li&gt;
&lt;li&gt;把「忆江南」三个字放到尽可能大。&lt;/li&gt;
&lt;li&gt;保留四边空白。&lt;/li&gt;
&lt;li&gt;调用 MindReset 的图片 API，把图片&lt;strong&gt;贴&lt;/strong&gt;到屏幕上。&lt;/li&gt;
&lt;li&gt;再通过飞书把原图发回来给我确认。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些步骤如果人工做，当然也可以。&lt;/p&gt;
&lt;p&gt;你可以打开设计软件，建一个 296×152 像素的画布，选中文字体，调整字号，导出 PNG，再打开设备后台或者写 curl 请求，把图片推送过去。&lt;/p&gt;
&lt;p&gt;但重点是：&lt;strong&gt;这次我没有做这些操作。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我只是用自然语言描述了我要的结果。&lt;/p&gt;
&lt;p&gt;OpenClaw 把这句话拆成了可以执行的步骤，并且真的执行了。&lt;/p&gt;
&lt;p&gt;这就是我觉得这类工具开始变得有用的地方。它不是又一个问答窗口，而是一个可以调用工具、读写文件、生成图片、访问 API、控制设备的本地智能体。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;有些提醒，不适合出现在手机里&lt;/h2&gt;
&lt;p&gt;我们平时说“提醒”，很容易想到手机通知。&lt;/p&gt;
&lt;p&gt;但手机通知适合的是即时信息，比如快递到了、会议快开始了、有人发消息了。&lt;/p&gt;
&lt;p&gt;《忆江南》这种内容不是即时通知。它不需要震动，也不需要弹窗。它只需要在某个固定地方安静地出现，让人每天多看几次。&lt;/p&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;OpenClaw + MindReset 墨水屏&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;会打断当前动作&lt;/td&gt;
&lt;td&gt;不打断，只是安静显示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;很快消失&lt;/td&gt;
&lt;td&gt;一直停留在那里&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;容易引导人继续刷手机&lt;/td&gt;
&lt;td&gt;只显示一件事&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适合即时消息&lt;/td&gt;
&lt;td&gt;适合长期提醒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;信息在 App 里&lt;/td&gt;
&lt;td&gt;信息&lt;strong&gt;贴&lt;/strong&gt;在真实空间里&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&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;所以，我不觉得这是一个“酷炫硬件玩法”。&lt;/p&gt;
&lt;p&gt;它更像是一种家庭信息摆放方式的变化。&lt;/p&gt;
&lt;p&gt;以前我们把信息放在手机里、App 里、群聊里、备忘录里。&lt;/p&gt;
&lt;p&gt;现在，我们可以让 OpenClaw 把一部分信息&lt;strong&gt;贴&lt;/strong&gt;回家里的空间里。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;从一首诗开始，家里还能&lt;strong&gt;贴&lt;/strong&gt;哪些“轻提醒”？&lt;/h2&gt;
&lt;p&gt;如果你家里也有类似的联网电子墨水屏，或者你正在考虑买一块，最值得尝试的不是复杂自动化，而是从很小的家庭提醒开始。&lt;/p&gt;
&lt;p&gt;尤其是那些“重要，但不紧急”的信息。&lt;/p&gt;
&lt;p&gt;比如孩子本周刚学的古诗。&lt;/p&gt;
&lt;p&gt;如果每天只是在书桌前背，孩子会觉得这是学习任务。但如果它出现在刷牙、吃饭、出门这些生活场景里，压力会低很多。&lt;/p&gt;
&lt;p&gt;下面这些玩法都可以从同一个思路扩展出来。&lt;/p&gt;
&lt;h3&gt;1. 本周古诗&lt;/h3&gt;
&lt;p&gt;卫生间显示诗名，饭桌旁显示一句诗，书桌旁显示完整诗文。&lt;/p&gt;
&lt;p&gt;比如卫生间只显示：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;忆江南
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;或者只显示最容易忘的一句：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;春来江水绿如蓝
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;2. 每日英语单词&lt;/h3&gt;
&lt;p&gt;每天一个单词，配一句很短的例句。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;remember
记得，想起
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;刷牙时看一眼，比专门打开背单词 App 轻很多。&lt;/p&gt;
&lt;h3&gt;3. 乘法口诀&lt;/h3&gt;
&lt;p&gt;如果孩子最近在练某一组乘法口诀，可以只显示当天的一条。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;56&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;不要一次显示太多。墨水屏最适合少量、稳定、反复出现的信息。&lt;/p&gt;
&lt;h3&gt;4. 成语提醒&lt;/h3&gt;
&lt;p&gt;每天一个成语，晚上吃饭时让孩子讲讲意思。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;画蛇添足
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这比直接塞给孩子一整页成语表更自然。&lt;/p&gt;
&lt;h3&gt;5. 出门清单&lt;/h3&gt;
&lt;p&gt;贴在玄关：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;水杯
作业
红领巾
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这个适合早上出门前看一眼。&lt;/p&gt;
&lt;h3&gt;6. 睡前问题&lt;/h3&gt;
&lt;p&gt;放在床头：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;今天最开心的事？
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;不是学习任务，而是引导孩子做一点表达和回顾。&lt;/p&gt;
&lt;h3&gt;7. 家庭共读&lt;/h3&gt;
&lt;p&gt;如果本周全家一起读一本书，可以每天显示一句摘录。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;今天读第 3 章
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;8. 低压力错题提醒&lt;/h3&gt;
&lt;p&gt;不要显示“你又错了”。
只显示一个关键词，让孩子自己回想。&lt;/p&gt;
&lt;p&gt;比如数学里容易错的是“单位换算”，屏幕上就只显示：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;单位
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;提醒越轻，越容易长期存在。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;普通人不需要懂 API，只需要知道这三层&lt;/h2&gt;
&lt;p&gt;如果你关心怎么入手，可以把这套东西拆成三层。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一层是硬件&lt;/strong&gt;：一块可以联网、有开放 API 的电子墨水屏，比如 MindReset Dot。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二层是智能体&lt;/strong&gt;：OpenClaw 或 Hermes Agent 这类工具，能理解你的自然语言指令，也能调用本地脚本和网络 API。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三层是场景&lt;/strong&gt;：孩子背诗、出门提醒、家庭共读、每日单词、错题复习。&lt;/p&gt;
&lt;p&gt;真正有价值的是三层连起来。&lt;/p&gt;
&lt;p&gt;如果只有屏幕，它只是一个可以显示东西的硬件。&lt;/p&gt;
&lt;p&gt;如果只有 OpenClaw，它还停留在电脑里或者聊天窗口里。&lt;/p&gt;
&lt;p&gt;但当 OpenClaw 能控制这块屏幕时，事情就变了。&lt;/p&gt;
&lt;p&gt;你的家里多了一个可以被自然语言更新的信息位置。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;背后其实很简单：一句话变成一张图，再&lt;strong&gt;贴&lt;/strong&gt;到屏幕上&lt;/h2&gt;
&lt;p&gt;如果你关心技术，背后其实并不神秘。&lt;/p&gt;
&lt;p&gt;这次任务大致是这样完成的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;自然语言指令
→ OpenClaw 理解目标
→ 找到卫生间屏幕设备 ID
→ 生成 296×152 黑白 PNG 图片
→ 用中文字体渲染「忆江南」
→ 转成适合设备的图片格式
→ 调用 MindReset 图片 API
→ **贴**到电子墨水屏
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;一些实际参数是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;屏幕尺寸：296 × 152 px
图片格式：黑白 PNG
生成工具：Python Pillow
中文字体：文泉驿正黑
设备别名：toilet
推送方式：MindReset 图片 API
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这些技术细节对普通用户来说不用记。&lt;/p&gt;
&lt;p&gt;关键是，OpenClaw 可以把这些步骤封装起来。下一次我不需要再关心图片尺寸、字体路径、base64 编码、API 请求格式。&lt;/p&gt;
&lt;p&gt;我只需要说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“把这周的古诗&lt;strong&gt;贴&lt;/strong&gt;到卫生间屏幕。字大一点。只显示诗名。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;或者：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“明天开始，每天早上把一个英语单词&lt;strong&gt;贴&lt;/strong&gt;到玄关屏幕上。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这才是实操价值。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;这不是把家变成补习班&lt;/h2&gt;
&lt;p&gt;我知道有人看到这里，可能会担心：这是不是又在给孩子增加学习压力？&lt;/p&gt;
&lt;p&gt;我反而觉得，好的用法应该是相反的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要把屏幕塞满学习内容。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要每天推一大堆任务。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要让孩子一刷牙就看到密密麻麻的知识点。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这块屏幕最适合的是：&lt;strong&gt;少量、温和、稳定、低压力&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;比如这次只显示三个字：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;忆江南&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它不是完整课文，也不是背诵要求。&lt;/p&gt;
&lt;p&gt;它只是一个入口。&lt;/p&gt;
&lt;p&gt;孩子看到它，可能会想起老师这周讲过的诗，可能会顺口念一句，也可能只是多看一眼。&lt;/p&gt;
&lt;p&gt;这就够了。&lt;/p&gt;
&lt;p&gt;学习不一定总是正襟危坐地发生。有时候，生活里的轻提醒，反而更容易留下痕迹。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;当信息从手机里走出来&lt;/h2&gt;
&lt;p&gt;过去几年，我们把越来越多的信息塞进手机。&lt;/p&gt;
&lt;p&gt;日程在手机里，备忘在手机里，孩子作业在群里，家庭提醒也在群里。&lt;/p&gt;
&lt;p&gt;结果是：什么都在手机里，最后什么都容易被信息流淹没。&lt;/p&gt;
&lt;p&gt;电子墨水屏提供了一个反方向的可能。&lt;/p&gt;
&lt;p&gt;它把一小部分信息从手机里拿出来，&lt;strong&gt;贴&lt;/strong&gt;回真实空间。&lt;/p&gt;
&lt;p&gt;而 OpenClaw 这类智能体，让这件事变得更灵活。&lt;/p&gt;
&lt;p&gt;你不用每次打开 App 去改内容，也不用手动上传图片。你只要用一句自然语言告诉它，你想让哪个角落显示什么。&lt;/p&gt;
&lt;p&gt;卫生间可以显示本周古诗。&lt;/p&gt;
&lt;p&gt;玄关可以显示出门清单。&lt;/p&gt;
&lt;p&gt;冰箱可以显示今天晚饭安排。&lt;/p&gt;
&lt;p&gt;书桌可以显示今天最重要的一件事。&lt;/p&gt;
&lt;p&gt;这些都不是大场面，但很真实。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;最后，它只是安静地&lt;strong&gt;贴&lt;/strong&gt;在了那里&lt;/h2&gt;
&lt;p&gt;那天晚上，孩子去刷牙。&lt;/p&gt;
&lt;p&gt;他抬头看到卫生间墨水屏上的三个字：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;忆江南&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;也许他没有立刻完整背出来。&lt;/p&gt;
&lt;p&gt;但这三个字已经把那首诗从课本里，带到了生活里。&lt;/p&gt;
&lt;p&gt;正是因为&lt;strong&gt;总忘记&lt;/strong&gt;，我们才需要把它轻轻&lt;strong&gt;贴&lt;/strong&gt;在最日常的地方。不是任务，不是考试，只是一个每天都会路过、会看见的提醒。&lt;/p&gt;
&lt;p&gt;这就是我觉得 OpenClaw 和 MindReset 这类设备组合起来很有意思的地方。&lt;/p&gt;
&lt;p&gt;它不是又多了一个 App，也不是又多了一个需要盯着看的屏幕。&lt;/p&gt;
&lt;p&gt;它让家里的某个角落，开始能听懂一句话，并且安静地帮你做一件小事。&lt;/p&gt;
&lt;p&gt;OpenClaw 真正进入家庭，也许不是从一个会走路的机器人开始，而是从一块会被它更新的电子墨水屏开始。&lt;/p&gt;
&lt;p&gt;扫码入群，一起交流 OpenClaw 玩法。&lt;/p&gt;
&lt;p&gt;&lt;img alt="OpenClaw 交流群二维码" src="../images/openclaw-group-qrcode.jpg"&gt;&lt;/p&gt;</content><category term="AI"></category><category term="OpenClaw"></category><category term="MindReset"></category><category term="电子墨水屏"></category><category term="家庭教育"></category><category term="AI智能体"></category></entry><entry><title>用 龙虾🦞 监控 OpenRouter 免费模型上新</title><link href="https://hillerliao.github.io/openrouter-free-model-monitor-lobster.html" rel="alternate"></link><published>2026-04-24T00:00:00+08:00</published><updated>2026-04-24T00:00:00+08:00</updated><author><name>龙虾</name></author><id>tag:hillerliao.github.io,2026-04-24:/openrouter-free-model-monitor-lobster.html</id><summary type="html">&lt;h2&gt;1. 痛点：不想天天刷页面薅羊毛&lt;/h2&gt;
&lt;p&gt;时不时会看到新闻说，又有哪个新模型在 OpenRouter 上提供限时免费体验。前几天打开 OpenRouter，发现某款 …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;1. 痛点：不想天天刷页面薅羊毛&lt;/h2&gt;
&lt;p&gt;时不时会看到新闻说，又有哪个新模型在 OpenRouter 上提供限时免费体验。前几天打开 OpenRouter，发现某款国产大模型可以免费用。作为一个经常薅免费模型羊毛的人，我的第一反应是——这上新多久了？我怎么才知道？&lt;/p&gt;
&lt;p&gt;OpenRouter 是一个 LLM API 聚合平台，汇集了各家大模型，其中不少提供免费额度。问题是，免费模型的上下架没有固定规律：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;你不知道什么时候会多出一个新模型&lt;/strong&gt; —— 可能是限时免费，错过了就没了&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;你不知道哪个模型悄悄下线了&lt;/strong&gt; —— 正在用的模型突然不能用了&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;你不知道哪个模型更值得用&lt;/strong&gt; —— 免费模型有几十个，质量和速度参差不齐，新上的可能更好&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我想第一时间知道，但手动刷网站太累了。OpenRouter 并未提供 RSS 订阅或邮件提醒之类的通知方式。&lt;/p&gt;
&lt;p&gt;AI时代了，不能再用手工的笨办法。与其天天刷页面，不如让我的 AI 助手帮我盯着——一旦有新免费模型上线，自动通知我。&lt;/p&gt;
&lt;h2&gt;2. 方案：让 AI 替你盯着&lt;/h2&gt;
&lt;p&gt;核心逻辑很简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;定期调用 OpenRouter API&lt;/strong&gt;，获取当前所有免费模型列表&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与本地记录对比&lt;/strong&gt;，找出新增和下架的模型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有变化就通知我&lt;/strong&gt;，没变化就静默&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本文以轻量级 AI 助手框架 &lt;strong&gt;nanobot&lt;/strong&gt;为例。它有一个 &lt;strong&gt;heartbeat 机制&lt;/strong&gt;——你可以在 &lt;code&gt;HEARTBEAT.md&lt;/code&gt; 中定义周期性任务，nanobot 会按配置的间隔（比如每小时一次）自动执行，全程无需人工干预。&lt;/p&gt;
&lt;p&gt;其他同类 AI 助手（如 OpenClaw、Hermes Agent）的实现逻辑类似。&lt;/p&gt;
&lt;h2&gt;3. 动手拆解（共四步）&lt;/h2&gt;
&lt;p&gt;下面这些步骤主要是 nanobot 自己想的。&lt;/p&gt;
&lt;p&gt;我把需求用自然语言告诉 nanobot，它自动生成 Python 脚本。&lt;/p&gt;
&lt;h3&gt;3.1 第一步：写个脚本，调 API 拿列表&lt;/h3&gt;
&lt;p&gt;OpenRouter 提供了公开的模型列表 API：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;GET https://openrouter.ai/api/v1/models
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;返回的 JSON 中，每个模型有 &lt;code&gt;id&lt;/code&gt; 和 &lt;code&gt;pricing&lt;/code&gt; 字段。免费模型的特征是 &lt;code&gt;pricing.prompt&lt;/code&gt; 和 &lt;code&gt;pricing.completion&lt;/code&gt; 都为 &lt;code&gt;"0"&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;nanobot 生成的脚本核心逻辑：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_free_models&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;m&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="s2"&gt;&amp;quot;pricing&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&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="s2"&gt;&amp;quot;prompt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;
        &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;m&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="s2"&gt;&amp;quot;pricing&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&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="s2"&gt;&amp;quot;completion&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这一步需要 OpenRouter 的 API Key，nanobot 会提示你提供。&lt;/p&gt;
&lt;p&gt;如果让我自己想，还真想不到这么优雅的解决方案。我最初的思路是直接抓页面，检查有没有新模型出现——远不如调 API 干净准确。&lt;/p&gt;
&lt;h3&gt;3.2 第二步：存个快照，当对比基准&lt;/h3&gt;
&lt;p&gt;第一次运行时，nanobot 自动把当前免费模型列表保存为 JSON 文件（如 &lt;code&gt;config/openrouter_free_models.json&lt;/code&gt;）。下次检查时，它对比这个文件里的内容，看是否有变化。&lt;/p&gt;
&lt;h3&gt;3.3 第三步：配个心跳，让任务自动重复运行&lt;/h3&gt;
&lt;p&gt;在 nanobot 的 &lt;code&gt;HEARTBEAT.md&lt;/code&gt; 中添加一行任务：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gu"&gt;## OpenRouter 免费模型监控&lt;/span&gt;
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;检查 OpenRouter 免费模型列表是否有新增（对比 config/openrouter_free_models.json），如有变化通过飞书通知用户
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;配置完成后，nanobot 每次 heartbeat 自动执行：调 API → 对比 → 通知 → 更新快照。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ OpenRouter 的 API 结构和免费策略可能随时调整。如果监控脚本失效，请检查 API 返回的数据格式是否变化。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.4 第四步：坐等通知，新模型到手&lt;/h3&gt;
&lt;p&gt;配置完成。等通知就行。&lt;/p&gt;
&lt;h2&gt;4. 效果：我收到了什么？&lt;/h2&gt;
&lt;p&gt;当 OpenRouter 上新免费模型时，我会在飞书收到类似这样的消息：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🤖 bot 🆓 OpenRouter 新增免费模型&lt;/p&gt;
&lt;p&gt;🕐 2026-04-23 18:00
新增 1 个免费模型，当前共 29 个&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tencent: Hy3 preview (free)&lt;/strong&gt;
ID: &lt;code&gt;tencent/hy3-preview:free&lt;/code&gt;
模态: text-&amp;gt;text｜上下文: 262,144
简介: Hy3 Preview is a high-efficiency Mixture-of-Experts model from Tencent designed for agentic workflows and production use...
&lt;a href="https://openrouter.ai/tencent/hy3-preview:free"&gt;查看详情&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不需要主动去查，模型上新第一时间知道。&lt;/p&gt;
&lt;h2&gt;5. 总结：全程没写一行代码&lt;/h2&gt;
&lt;p&gt;整个方案搭建过程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把需求用自然语言告诉 nanobot，它生成脚本并配好环境&lt;/li&gt;
&lt;li&gt;运行一次，保存当前免费模型列表作为基准&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;HEARTBEAT.md&lt;/code&gt; 写一句话描述任务&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;剩下的全自动。&lt;/p&gt;
&lt;p&gt;这就是 AI 助手的魅力——你不需要打开编程软件写监控脚本、配置 cron、自己对接通知渠道。把需求说清楚，剩下的它来。&lt;/p&gt;
&lt;h2&gt;6. 附录：手把手配置指南&lt;/h2&gt;
&lt;p&gt;如果你还不清楚如何让 AI 助手使用 OpenRouter 的免费模型，下面是简单的配置方法。&lt;/p&gt;
&lt;h3&gt;方法一：使用 openrouter/free 路由（推荐）&lt;/h3&gt;
&lt;p&gt;OpenRouter 提供了免费路由 &lt;code&gt;openrouter/free&lt;/code&gt;，自动选择当前可用的免费模型之一，无需手动指定模型 ID。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;配置步骤：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;注册 OpenRouter 账号：访问 &lt;a href="https://openrouter.ai"&gt;openrouter.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;创建 API Key：Settings → Keys → Create Key&lt;/li&gt;
&lt;li&gt;在 AI 助手的配置文件中添加：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;api_key&amp;quot;&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;quot;sk-or-v1-xxxxxxxx&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;base_url&amp;quot;&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;quot;https://openrouter.ai/api/v1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;model&amp;quot;&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;quot;openrouter/free&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;注意事项：&lt;/strong&gt;
- 调用时必须在请求头中携带 &lt;code&gt;HTTP-Referer&lt;/code&gt; 和 &lt;code&gt;X-Title&lt;/code&gt; 字段，否则返回 402 错误
- 免费路由会智能过滤，只选择支持你所需功能的模型
- 上下文长度支持 200,000 token&lt;/p&gt;
&lt;h3&gt;方法二：直接指定免费模型&lt;/h3&gt;
&lt;p&gt;在 &lt;a href="https://openrouter.ai/models"&gt;OpenRouter 模型列表页&lt;/a&gt; 筛选免费模型，直接指定模型 ID：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;api_key&amp;quot;&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;quot;sk-or-v1-xxxxxxxx&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;base_url&amp;quot;&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;quot;https://openrouter.ai/api/v1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;model&amp;quot;&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;quot;tencent/hy3-preview:free&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;模型 ID 带 &lt;code&gt;:free&lt;/code&gt; 后缀的是免费模型。目前 OpenRouter 上有数十款免费模型，包括 Google Gemini、Meta Llama、阿里巴巴 Qwen、腾讯混元等。&lt;/p&gt;</content><category term="AI"></category><category term="AI"></category><category term="OpenRouter"></category><category term="自动化"></category><category term="教程"></category></entry><entry><title>养虾太累？让爱马仕接手，从升级到备份全包</title><link href="https://hillerliao.github.io/hermes-agent-picoclaw-upgrade-guide.html" rel="alternate"></link><published>2026-04-23T00:00:00+08:00</published><updated>2026-04-23T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-04-23:/hermes-agent-picoclaw-upgrade-guide.html</id><summary type="html">&lt;blockquote&gt;
&lt;p&gt;OpenClaw 或 PicoClaw 这类"虾产品"安装难、配置难、维护更难。但现在，你只需要动动嘴，剩下的交给 Hermes Agent 就可以了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;一、想试那只"虾"，第一步就卡 …&lt;/h2&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;OpenClaw 或 PicoClaw 这类"虾产品"安装难、配置难、维护更难。但现在，你只需要动动嘴，剩下的交给 Hermes Agent 就可以了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;一、想试那只"虾"，第一步就卡住&lt;/h2&gt;
&lt;p&gt;OpenClaw 用着用着就碰到各种各样的问题。你听说一个叫做 PicoClaw 的类 OpenClaw 产品，它号称轻量、省钱、性能猛——"只要 10 美元硬件，内存 &amp;lt;10MB，启动 &amp;lt;1s"。&lt;/p&gt;
&lt;p&gt;这不就是 OpenClaw 绝佳的替代品吗？心动不如行动，打开 GitHub 瞧瞧。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下载哪个版本？Linux x86_64 还是 arm64？&lt;/li&gt;
&lt;li&gt;下载完怎么启动？&lt;code&gt;gateway&lt;/code&gt; 是啥？&lt;code&gt;agent&lt;/code&gt; 又是啥？&lt;/li&gt;
&lt;li&gt;配置文件里 &lt;code&gt;allow_from&lt;/code&gt; 是什么？不填能用吗？&lt;/li&gt;
&lt;li&gt;升级的时候...等等，我连当前版本是啥都不知道！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更崩溃的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;命令行黑黑的窗口，输错一个字符就报错&lt;/li&gt;
&lt;li&gt;文档全是英文，还有技术黑话（hot_reload、sandbox、spawn...）&lt;/li&gt;
&lt;li&gt;一修改配置，服务起不来了，不知道哪错了&lt;/li&gt;
&lt;li&gt;想升级，怕把配置搞丢，怕升级后连不上飞书&lt;/li&gt;
&lt;li&gt;升级失败？回滚是啥？备份了哪些文件？完全懵住&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;一句话&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"虾"是好虾，但小白根本不会煮&lt;/strong&gt; —— 不是不想学，是怕搞坏、怕背锅、怕花时间学完一次再也不用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;二、如果有个"运维助理"，你只说"我要升级"，它全包呢？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;引入 Hermes Agent：不是另一个复杂工具，而是你的&lt;strong&gt;会执行的朋友&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;⚠️ 如果还没有安装 Hermes Agent，可以运行：&lt;code&gt;curl -sSL https://hermes-agent.nousresearch.com/install.sh | bash&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;打个比方：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;你&lt;/strong&gt;：是老板，（说"我要什么结果"）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hermes Agent&lt;/strong&gt;：员工（负责研究怎么做、一步步执行、出问题修好、还会留 undo 方案）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;和传统方式对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;传统自学&lt;/th&gt;
&lt;th&gt;Hermes Agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;先看半天文档，云里雾里&lt;/td&gt;
&lt;td&gt;直接说需求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;边查边试，错一步就卡住&lt;/td&gt;
&lt;td&gt;它自己查官方最佳实践&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;做完了不知道对不对&lt;/td&gt;
&lt;td&gt;它每一步都告诉你进展&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;升级失败不知道怎么回&lt;/td&gt;
&lt;td&gt;它提前备份，给你回滚命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&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;&lt;strong&gt;你的物理动作对比&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;手动：打开浏览器、搜文档、复制命令、输密码、提心吊胆&lt;/li&gt;
&lt;li&gt;Hermes Agent：打开聊天窗口，打一句话，等结果，回一句"好的"&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、实战：一句话让 Hermes Agent 升级 PicoClaw&lt;/h2&gt;
&lt;h3&gt;Step 1️⃣：有点紧张——"能帮忙升级吗？先告诉我计划，别乱动"&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hermes Agent&lt;/strong&gt;："好的，我先调查一下当前版本和环境，然后制定升级计划给你确认。不会直接执行的。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;你心里想&lt;/strong&gt;：之前踩坑无数，还没说清楚这些龙虾们，就开始干活了，干了一半还出错，把自己也搞死了，这次一定要谨慎一点。&lt;/p&gt;
&lt;p&gt;幸好这 Hermes Agent 还挺稳，在谨慎调教之下，没有上来就干。&lt;/p&gt;
&lt;h3&gt;Step 2️⃣：Hermes Agent 调研完，给出计划表&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;目标：升级到最新稳定版 v0.2.6
步骤：
1. 备份 config.json 和 .env（白名单不会丢）
2. 停止当前服务
3. 用官方脚本 upgrade_picoclaw.sh 下载并安装
4. SHA256 校验，安全第一
5. 检查并恢复你的 feishu.allow_from 设置
6. 重启服务，验证连接
7. 如有问题，回滚命令：cp backup/* /home/ubuntu/picoclaw-bin/
请说&amp;quot;按计划执行&amp;quot;我立刻开始。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;你只需要回&lt;/strong&gt;："按最佳实践执行吧"&lt;/p&gt;
&lt;h3&gt;Step 3️⃣：你喝茶等，它全干了&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Hermes：[执行中...]
• 备份配置到 ~/.picoclaw/backup-pre-upgrade-20260421-094936
• 停止服务 OK
• 下载 v0.2.6... 24%... 78%... 100%
• SHA256 校验通过 ✅
• 安装新二进制 OK
• 恢复 feishu.allow_from = [&amp;quot;*&amp;quot;]
• 重启服务成功
• 验证：v0.2.6, PID 1853506, 内存 9.1MB, 飞书已连接
完成。升级前旧版本：0.2.5，现在是 0.2.6。
如要回滚，运行：cp /home/ubuntu/picoclaw-backup-20260421-095056/picoclaw* /home/ubuntu/picoclaw-bin/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;你的感受&lt;/strong&gt;：连 confirmation 都不用给，它自己就把事办妥了，还告诉你怎么 undo。&lt;/p&gt;
&lt;h3&gt;Step 4️⃣：你想起上次报错——"对了，我总遇到 max_tool_iterations 超限"&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hermes Agent&lt;/strong&gt;："我发现当前配置是 50，我调成 100 了。还有 summarize_message_threshold 从 20 降到 15，tools.feedback 也打开了。这样应该不会报错了。"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;你&lt;/strong&gt;："这么猛？这就调好了？"&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hermes Agent&lt;/strong&gt;："嗯，顺便的事。"&lt;/p&gt;
&lt;h2&gt;四、如果让你自己动手，要几步？&lt;/h2&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;Hermes 帮你干的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;升级&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. 打开 GitHub releases 页面 2. 找最新 stable tag 3. 下载对应系统架构的包 4. 手动算 SHA256 对比 5. 停服务、解压、覆盖、别忘了备份旧版 6. 恢复 config 里的 allow_from 7. 重启、验证、看日志 8. 记录升级前后版本，以备回滚&lt;/td&gt;
&lt;td&gt;你只说"升级" → 它全部做完，还告诉你怎么回滚&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;调优&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. 搜 max_tool_iterations 设多少合适 2. 看官方文档理解参数含义 3. 改 config.json 4. 重启测试&lt;/td&gt;
&lt;td&gt;你随口提一句"迭代报错" → 它直接改好&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;安全&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. 想想要不要备份 2. 手动 cp 文件，记备份路径 3. 升级失败时要想得起备份在哪&lt;/td&gt;
&lt;td&gt;自动备份到带时间戳的目录，最后附回滚命令&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;五、Hermes Agent 运维模式的三大安全保障&lt;/h2&gt;
&lt;h3&gt;1️⃣ 永远有后悔药&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;升级前自动备份到 &lt;code&gt;~/picoclaw-backup-20260421-095056&lt;/code&gt;
回滚命令它主动告诉你，不用你费劲找备份在哪。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2️⃣ 它只干官方推荐的事&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;不会用奇怪参数，而是找到 &lt;code&gt;upgrade_picoclaw.sh&lt;/code&gt; 官方脚本，走稳定流程。
你不需要判断哪个分支靠谱，它帮你选 stable。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3️⃣ 事后能审计&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;聊天记录就是完整操作日志。
哪天服务出问题，翻翻聊天就知道：那天升级到哪个版本、改了哪些配置、备份在哪里。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;六、小白也能用的"运维指令"清单&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;不需要记命令，只需要像聊天一样说&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;你想做的事&lt;/th&gt;
&lt;th&gt;对 Hermes Agent 说的话&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;升级 PicoClaw&lt;/td&gt;
&lt;td&gt;"帮我把 PicoClaw 升级到最新稳定版"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重启服务&lt;/td&gt;
&lt;td&gt;"重启 picoclaw gateway"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看最近日志&lt;/td&gt;
&lt;td&gt;"最近 50 行 picoclaw 的日志有 error 吗？"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;备份配置&lt;/td&gt;
&lt;td&gt;"备份一下 picoclaw 的配置文件"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;改个参数&lt;/td&gt;
&lt;td&gt;"把 max_tool_iterations 改成 100"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;回滚版本&lt;/td&gt;
&lt;td&gt;"我想回滚到升级前的版本，备份目录在 xxx"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;检查状态&lt;/td&gt;
&lt;td&gt;"PicoClaw 现在运行正常吗？飞书连上了吗？"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;诀窍&lt;/strong&gt;：
  就像跟同事说话，哪怕说不利索也没关系——
  Hermes Agent 会追问细节（"要升到哪个版本？"），你回答就行。&lt;/p&gt;
&lt;h2&gt;七、什么情况下别让 Hermes Agent 干？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;❌ 需要你输入密码的交互式操作（比如第一次 SSH 连服务器）&lt;/li&gt;
&lt;li&gt;❌ 涉及生产数据删除（rm -rf 之类的大杀器）&lt;/li&gt;
&lt;li&gt;✅ 但有&lt;strong&gt;标准流程、有官方脚本、有回滚方案&lt;/strong&gt;的任务——完美适合&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;PicoClaw 升级：用官方脚本、有备份、可回滚 → &lt;strong&gt;最适合的场景&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;八、总结：运维不再是"专家的黑盒"&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;过去&lt;/strong&gt;：
 小白：想升级，但不敢动 → 等专家、排期、背锅&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;现在&lt;/strong&gt;：
 小白：说"升级 PicoClaw" → Hermes 执行 → 小白确认 → 完成
 （专家知识被封装在 Agent 的"最佳实践"里）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心转变&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你不需要成为 🦞 运维专家，
 你只需要学会&lt;strong&gt;描述问题 + 批准执行&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;下一次，当你的"虾"需要升级时——
 别怕，你的运维搭档已经在聊天窗口等你了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;📎 附录：升级过程的"快照"&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;用户：你能帮忙升级你同一个机器上的&lt;/span&gt;&lt;span class="n"&gt;PicoClaw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;吗？你先告诉我你准备怎么做？先别执行。&lt;/span&gt;
&lt;span class="n"&gt;Hermes&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;列出详细计划&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="err"&gt;用户：按照升级服务的最佳实践开始执行吧。&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;最佳实践&lt;/span&gt;
&lt;span class="n"&gt;Hermes&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;执行&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;✅&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;升级成功！版本&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;，备份在&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;picoclaw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xxx&lt;/span&gt;

&lt;span class="err"&gt;用户：我总遇到&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;max_tool_iterations&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;报错。&lt;/span&gt;
&lt;span class="n"&gt;Hermes&lt;/span&gt;&lt;span class="err"&gt;：已调整&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;max_tool_iterations&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;summarize_threshold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="err"&gt;，启用&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tool_feedback&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;重启服务&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;✅&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;配置已优化并生效&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="blog"></category></entry><entry><title>OpenClaw 老是访问不了网页？试试 Hermes Agent</title><link href="https://hillerliao.github.io/openclaw-hermes-agent-web-scraping.html" rel="alternate"></link><published>2026-04-23T00:00:00+08:00</published><updated>2026-04-23T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-04-23:/openclaw-hermes-agent-web-scraping.html</id><summary type="html">&lt;p&gt;对比 OpenClaw 和 Hermes Agent 在抓取需要 JS 渲染的网页时的表现，解析 headless Chromium 与普通 HTTP 请求的差异。&lt;/p&gt;</summary><content type="html">&lt;p&gt;我想查韭圈儿（一个投资类网站）的恐贪指数——一个 0 到 100 的市场情绪指标，数字越高代表越贪婪——同时用了两个 AI 工具：OpenClaw 和 Hermes Agent。&lt;/p&gt;
&lt;p&gt;OpenClaw 跟我说目标页面不存在（404错误）。Hermes Agent 一开始也告诉我说404，后来我叫它继续研究，终于告诉我最新的恐贪指数为75（2026-04-21），属于贪婪状态。&lt;/p&gt;
&lt;p&gt;我自己打开浏览器验证——和 Hermes Agent 拿到的一样。同一个页面，不同智能体，得到两种结果。从抓取网页的能力来看，&lt;strong&gt;Hermes Agent 更胜一筹&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;Hermes Agent 拿到了什么&lt;/h2&gt;
&lt;p&gt;从网页 https://funddb.cn/tool/fear 中，Hermes Agent 拿到的数据是这样的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;恐贪指数：75&lt;/li&gt;
&lt;li&gt;指数属性：贪婪&lt;/li&gt;
&lt;li&gt;更新时间：2026 年 4 月 21 日&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还有六大情绪指标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;指数波动率：15.15%，近一年较低&lt;/li&gt;
&lt;li&gt;两市成交量：24096.94 亿，近一年较高&lt;/li&gt;
&lt;li&gt;股价强度：3.67%，近一年中立&lt;/li&gt;
&lt;li&gt;升贴水率：-7.02%，近一年较低&lt;/li&gt;
&lt;li&gt;避险天堂：7.18%，近一年极高&lt;/li&gt;
&lt;li&gt;杠杆水平：11.21%，近一年较高&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不只是一个总分，背后六个维度都有据可查。这不是一个简单的数字，而是一个完整的市场情绪画像。&lt;/p&gt;
&lt;p&gt;不仅仅这个网站，当今大部分网页都需要 JS 渲染才能显示内容，程序想要获得页面上的数据通常比较困难。网站甚至还会增加反爬检测，仍以上述网站为例，它一旦识别到是爬虫在请求，就会返回404状态欺骗爬虫。&lt;/p&gt;
&lt;p&gt;大部分智能体会优先发送简单的请求尝试访问目标页面，毫无意外，结果直接碰壁。Hermes Agent 一开始也是跟我说404，和 OpenClaw 得到的结果一样。但为什么我稍微引导了一下，它就比较顺利地拿到了我想要的数据呢？我让 Hermes Agent 进行自我解剖了一番，基本搞清楚了原因。&lt;/p&gt;
&lt;h2&gt;两种访问链接的方式差异&lt;/h2&gt;
&lt;p&gt;OpenClaw、Hermes Agent 等智能体向目标服务器发送 HTTP 请求后，服务器会检查 User-Agent（UA）、请求头、IP 地址等信息——这些是 HTTP 协议层面的特征，没有 JS 执行，也没有真实浏览器才有的各种响应行为。服务器稍加判断，认出是机器人，直接拒绝。&lt;/p&gt;
&lt;p&gt;Hermes Agent 在请求网页方面有多种办法。除了发送 HTTP 请求，它还会使用 agent-browser 这个命令行工具。该工具底层跑的是 headless Chromium——一个没有图形界面的 Chrome，但却是完整的真实浏览器。通过 CDP（Chrome DevTools Protocol，Chrome 原生的调试协议）驱动浏览器打开页面、执行 JS、完成渲染，再抓取内容返回。服务器收到的请求，和人用 Chrome 访问时一样，不容易区分。&lt;/p&gt;
&lt;p&gt;OpenClaw 默认没有第二类工具，就很难突破目标网站的限制，也就拿不到真实数据。&lt;/p&gt;
&lt;p&gt;当然，headless 浏览器不是没有代价。它比普通 HTTP 请求慢，资源消耗也更多。如果只是访问普通页面，HTTP 请求更轻量、更快。两种方式各有适用场景，不是一个完全替代另一个。这也很好地解释了 Hermes Agent 一开始也用 HTTP 请求的原因。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;就好比是两个人去餐厅吃饭：一个说"我是机器人，我来拿数据"，被拒之门外；另一个说"我想吃顿饭"，被热情接待。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不是餐厅对第二个更客气。而是第一个直接暴露了自己的爬虫身份。有些网站的反爬系统，专门在识别"谁在说话"。HTTP 请求和真实浏览器请求，特征差别巨大。一旦被识别为机器人，餐厅的门就直接关上了。&lt;/p&gt;
&lt;h2&gt;最后说两句&lt;/h2&gt;
&lt;p&gt;我原本主要用 OpenClaw，它支持通过第三方 Skill 扩展浏览器等想要的能力，但需要额外配置，折腾起来比较麻烦。而 Hermes Agent 针对网页浏览这种让用户很头疼的问题，内置了比较好的解决方案，一下子就让人感觉丝滑很多。&lt;/p&gt;
&lt;p&gt;所以，如果你也在用 OpenClaw，遇到过网页访问的难题，但又不想折腾第三方工具，不妨试试 Hermes Agent。如果碰到问题，欢迎扫码入群交流。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;原文链接：https://mp.weixin.qq.com/s/CBrlFrIAhTA_A0BYC0TEGg&lt;/em&gt;&lt;/p&gt;</content><category term="AI"></category><category term="OpenClaw"></category><category term="Hermes Agent"></category><category term="AI"></category><category term="网页抓取"></category><category term="智能体"></category></entry><entry><title>不仅龙虾，旧手机也能跑 Hermes Agent（安装实录）</title><link href="https://hillerliao.github.io/termux-hermes-agent-install-guide.html" rel="alternate"></link><published>2026-04-23T00:00:00+08:00</published><updated>2026-04-23T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-04-23:/termux-hermes-agent-install-guide.html</id><summary type="html">&lt;h2&gt;需求背景&lt;/h2&gt;
&lt;p&gt;近期 AI Agent 相关项目关注度较高，例如在"龙虾（OpenClaw）"之后，一些类似工具，尤其是 Hermes Agent 开始被更多人尝试。就像 OpenClaw，除了在 …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;需求背景&lt;/h2&gt;
&lt;p&gt;近期 AI Agent 相关项目关注度较高，例如在"龙虾（OpenClaw）"之后，一些类似工具，尤其是 Hermes Agent 开始被更多人尝试。就像 OpenClaw，除了在电脑或服务器上运行，这类工具基本都可以在移动设备上部署，只是可能有一些细微差异需要注意。&lt;/p&gt;
&lt;p&gt;手机具备以下特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;长时间在线&lt;/li&gt;
&lt;li&gt;自带网络环境&lt;/li&gt;
&lt;li&gt;可作为低成本运行节点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里记录一次在&lt;strong&gt;安卓手机上，通过 Termux 部署 Hermes Agent&lt;/strong&gt; 的实际过程。&lt;/p&gt;
&lt;h2&gt;前置条件&lt;/h2&gt;
&lt;p&gt;开始之前，需满足：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一部安卓手机（建议 RAM ≥ 4GB）&lt;/li&gt;
&lt;li&gt;可能需要魔法上网&lt;/li&gt;
&lt;li&gt;安装 Termux App（建议 F-Droid 版本）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;什么是 Termux&lt;/h2&gt;
&lt;p&gt;Termux 是一个在安卓系统上提供 Linux 命令行环境的应用，可以执行常见的包管理、编译和脚本操作。安装后可以通过 &lt;code&gt;pkg&lt;/code&gt; 管理软件包。&lt;/p&gt;
&lt;h2&gt;方法一：一键安装&lt;/h2&gt;
&lt;p&gt;在 Termux 中下载脚本并执行安装：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-O&lt;span class="w"&gt; &lt;/span&gt;https://raw.githubusercontent.com/hillerliao/termux-hermes-agent/main/install-termux.sh
bash&lt;span class="w"&gt; &lt;/span&gt;install-termux.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;该脚本会执行以下操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;检测运行环境&lt;/li&gt;
&lt;li&gt;安装系统依赖&lt;/li&gt;
&lt;li&gt;安装 Python 环境&lt;/li&gt;
&lt;li&gt;克隆 Hermes Agent 仓库&lt;/li&gt;
&lt;li&gt;安装 Python 依赖&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;执行过程中会出现编译输出（Rust / C 扩展）。⚠️ 视手机配置和网络情况，执行过程可能非常耗时，下文方法二也是如此。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;方法二：手动安装&lt;/h2&gt;
&lt;p&gt;如需手动执行，或一键脚本运行异常，可按以下步骤操作。&lt;/p&gt;
&lt;h3&gt;1️⃣ 安装系统依赖&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pkg&lt;span class="w"&gt; &lt;/span&gt;update
pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-y&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;build-essential&lt;span class="w"&gt; &lt;/span&gt;clang&lt;span class="w"&gt; &lt;/span&gt;cmake&lt;span class="w"&gt; &lt;/span&gt;rust&lt;span class="w"&gt; &lt;/span&gt;python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;用于安装编译和运行所需的基础环境，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git（用于克隆项目代码）&lt;/li&gt;
&lt;li&gt;Python 运行环境&lt;/li&gt;
&lt;li&gt;C / C++ 编译工具链（clang）&lt;/li&gt;
&lt;li&gt;Rust 编译环境（部分依赖需要）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2️⃣ 设置 ANDROID_API_LEVEL&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ANDROID_API_LEVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;getprop&lt;span class="w"&gt; &lt;/span&gt;ro.build.version.sdk&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;该变量用于告知编译工具当前安卓系统的 API 等级，部分依赖在编译时会用到。可写入：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;export ANDROID_API_LEVEL=$(getprop ro.build.version.sdk)&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;用于在每次启动 Termux 时自动生效。&lt;/p&gt;
&lt;h3&gt;3️⃣ 克隆仓库&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/nousresearch/hermes-agent.git&lt;span class="w"&gt; &lt;/span&gt;~/hermes-agent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;将 Hermes Agent 源代码下载到本地目录，用于后续安装。&lt;/p&gt;
&lt;h3&gt;4️⃣ 安装 Python 依赖&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/hermes-agent
pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;安装项目所需的 Python 依赖，并以"开发模式"安装当前项目，使 &lt;code&gt;hermes&lt;/code&gt; 命令可用。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：仓库自带的 &lt;code&gt;install.sh&lt;/code&gt; 面向标准 Linux 环境，Termux 中不使用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;5️⃣ 初始化配置&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;hermes&lt;span class="w"&gt; &lt;/span&gt;setup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;运行交互式配置向导，用于设置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模型 API Key&lt;/li&gt;
&lt;li&gt;基本运行参数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配置文件默认生成在：&lt;code&gt;~/.hermes/config.yaml&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ 输入大模型的 API Key 时可能看上去没反应，但实际上已经输入成功，继续回车下一步就行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;6️⃣ 验证安装&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;hermes&lt;span class="w"&gt; &lt;/span&gt;--version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;用于确认 Hermes Agent 已正确安装，并可正常调用。&lt;/p&gt;
&lt;h2&gt;常用命令&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;hermes&lt;span class="w"&gt; &lt;/span&gt;--version
hermes&lt;span class="w"&gt; &lt;/span&gt;setup
hermes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;后台运行说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;设备需保持供电&lt;/li&gt;
&lt;li&gt;关闭系统电池优化&lt;/li&gt;
&lt;li&gt;避免 Termux 被系统回收&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;功能使用&lt;/h2&gt;
&lt;p&gt;安装完成并配置后，可实现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过消息平台与 Agent 通信&lt;/li&gt;
&lt;li&gt;执行定时任务&lt;/li&gt;
&lt;li&gt;接入扩展能力&lt;/li&gt;
&lt;li&gt;执行基础自动化任务&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;已知限制&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;性能受限于手机硬件&lt;/li&gt;
&lt;li&gt;部分依赖在 ARM 架构不可用&lt;/li&gt;
&lt;li&gt;安装过程包含编译步骤，耗时较长&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;该过程本质为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 Termux 提供 Linux 环境&lt;/li&gt;
&lt;li&gt;在本地安装 Hermes Agent&lt;/li&gt;
&lt;li&gt;通过配置实现运行&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适用于在移动设备上进行基础 Agent 部署测试。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>OpenClaw多Agent配置实战（多BOT版）</title><link href="https://hillerliao.github.io/openclaw-multi-agent-tutorial.html" rel="alternate"></link><published>2026-03-25T16:45:00+08:00</published><updated>2026-03-25T16:45:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-03-25:/openclaw-multi-agent-tutorial.html</id><summary type="html">&lt;p&gt;通过多Agent架构，根据任务复杂度自动路由到不同模型，实现成本优化和专业化分工。&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;懒人方案&lt;/strong&gt;：如果不想手动折腾配置文件，可以直接进入 &lt;code&gt;~/.openclaw&lt;/code&gt; 文件夹，启用 OpenCode，把这篇文章扔给它，让 OpenCode 参照着搞定。你只需要安装OpenCode就行（让OpenClaw帮你安装）。两个工具互相帮忙！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;为什么要多Agent？&lt;/h2&gt;
&lt;p&gt;最近有一些任务，OpenClaw 处理起来不是很得力，容易出错，不太爽。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"帮我查一下这个函数怎么用" → 便宜的普通模型能够快速响应，还算不错。&lt;/li&gt;
&lt;li&gt;"帮忙破解这个接口的数据解密方法" → 一般的模型可能就搞不定了，得上更厉害的模型。而更厉害的模型，也就意味着需要更多的钱去购买。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有什么办法能够让我在不同的时候使用不同的模型，既把事办了，也把钱省了呢？&lt;/p&gt;
&lt;p&gt;经过一番研究发现，&lt;strong&gt;OpenClaw的多Agent架构完美解决了这个问题&lt;/strong&gt;：每个Agent可以绑定不同的模型，通过路由规则自动分配任务。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;最终效果&lt;/h2&gt;
&lt;p&gt;配置完成后，我的系统是这样的：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&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;main&lt;/td&gt;
&lt;td&gt;MiniMax M2.7&lt;/td&gt;
&lt;td&gt;日常对话、简单编码&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;code-reviewer&lt;/td&gt;
&lt;td&gt;GPT 5.4 Pro&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;用户通过不同的飞书机器人发起请求，OpenClaw自动路由到对应的Agent。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;原理图&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                      用户消息                                │
└─────────────────────────────────────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────┐
│                    OpenClaw Gateway                          │
│                  (根据Bindings路由)                           │
└─────────────────────────────────────────────────────────────┘
                     │                    │
                     ▼                    ▼
     ┌───────────────────────┐  ┌───────────────────────┐
     │   飞书机器人1(default)  │  │ 飞书机器人2(code-reviewer)│
     └───────────────────────┘  └───────────────────────┘
                     │                    │
                     ▼                    ▼
     ┌───────────────────────┐  ┌───────────────────────┐
     │     main Agent        │  │  code-reviewer Agent  │
     │   模型: MiniMax       │  │   模型: GPT 5.4 Pro   │
     │   成本: 低            │  │   成本: 高            │
     └───────────────────────┘  └───────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;环境准备&lt;/h2&gt;
&lt;h3&gt;1. 确认OpenClaw版本&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;--version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;确保版本 &amp;gt;= 2026.3.x&lt;/p&gt;
&lt;h3&gt;2. 获取OpenCode Zen API密钥&lt;/h3&gt;
&lt;p&gt;访问 &lt;a href="https://opencode.ai/auth"&gt;https://opencode.ai/auth&lt;/a&gt;，注册并获取API密钥。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPT 5.4系列模型通过OpenCode Zen提供。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3. 确认飞书扩展&lt;/h3&gt;
&lt;p&gt;本文使用OpenClaw内置的飞书扩展 &lt;strong&gt;&lt;code&gt;feishu&lt;/code&gt;&lt;/strong&gt;（路径：&lt;code&gt;openclaw/extensions/feishu&lt;/code&gt;），安装方便。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 查看已启用的插件&lt;/span&gt;
openclaw&lt;span class="w"&gt; &lt;/span&gt;plugins&lt;span class="w"&gt; &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;期望输出中应包含：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;feishu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;4. 准备飞书应用&lt;/h3&gt;
&lt;p&gt;需要两个飞书应用：
- &lt;strong&gt;应用1&lt;/strong&gt;：已有的飞书机器人（用于main Agent）
- &lt;strong&gt;应用2&lt;/strong&gt;：新建的代码审查机器人（用于code-reviewer Agent）&lt;/p&gt;
&lt;p&gt;在 &lt;a href="https://open.feishu.cn/"&gt;飞书开放平台&lt;/a&gt; 创建新应用，获取 &lt;code&gt;App ID&lt;/code&gt; 和 &lt;code&gt;App Secret&lt;/code&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;飞书应用需要开启以下权限：&lt;code&gt;im:message&lt;/code&gt;、&lt;code&gt;im:message:send_as_bot&lt;/code&gt; 等。最好是把能开的权限都开上。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;实战步骤&lt;/h2&gt;
&lt;h3&gt;Step 1：查看当前配置&lt;/h3&gt;
&lt;p&gt;先了解一下现有的配置结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 查看当前Agent列表&lt;/span&gt;
openclaw&lt;span class="w"&gt; &lt;/span&gt;agents&lt;span class="w"&gt; &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Agents:
- main (default)
  Model: minimax/MiniMax-M2.7
  Routing: default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;查看配置文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 配置文件位置&lt;/span&gt;
cat&lt;span class="w"&gt; &lt;/span&gt;~/.openclaw/openclaw.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;当前只有 &lt;code&gt;main&lt;/code&gt; 一个Agent，使用MiniMax模型。&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Step 2：添加OpenCode Zen模型提供商&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这一步可以通过&lt;code&gt;openclaw configure&lt;/code&gt;命令完成，模型配置步骤有OpenCode选项，更不容易出错。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;编辑 &lt;code&gt;~/.openclaw/openclaw.json&lt;/code&gt;，在 &lt;code&gt;models.providers&lt;/code&gt; 中添加GPT 5.4系列模型：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;models&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;providers&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;minimax&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;baseUrl&amp;quot;&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;quot;https://api.minimaxi.com/anthropic&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;api&amp;quot;&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;quot;anthropic-messages&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;models&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;id&amp;quot;&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;quot;MiniMax-M2.7&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&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;quot;MiniMax M2.7&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;opencode-zen&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;baseUrl&amp;quot;&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;quot;https://opencode.ai/zen/v1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;api&amp;quot;&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;quot;openai-completions&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;authHeader&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;models&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;id&amp;quot;&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;quot;gpt-5.4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&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;quot;GPT 5.4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;reasoning&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;input&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;contextWindow&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;maxTokens&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8192&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;id&amp;quot;&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;quot;gpt-5.4-pro&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&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;quot;GPT 5.4 Pro&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;reasoning&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;input&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;contextWindow&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;maxTokens&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8192&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;在 &lt;code&gt;agents.defaults.models&lt;/code&gt; 中添加模型别名：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;agents&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;defaults&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;models&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;minimax/MiniMax-M2.7&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;alias&amp;quot;&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;quot;MiniMax&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;opencode-zen/gpt-5.4-pro&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;alias&amp;quot;&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;quot;GPT 5.4 Pro (Code Review)&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3&gt;Step 3：添加OpenCode Zen API密钥&lt;/h3&gt;
&lt;p&gt;编辑 &lt;code&gt;~/.openclaw/agents/main/agent/auth-profiles.json&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;profiles&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;minimax:cn&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&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;quot;api_key&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;provider&amp;quot;&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;quot;minimax&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;key&amp;quot;&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;quot;your-minimax-api-key&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;opencode-zen:default&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;type&amp;quot;&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;quot;api_key&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;provider&amp;quot;&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;quot;opencode-zen&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;key&amp;quot;&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;quot;your-opencode-zen-api-key&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3&gt;Step 4：创建code-reviewer Agent&lt;/h3&gt;
&lt;p&gt;使用CLI命令一键创建：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;agents&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;code-reviewer&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--workspace&lt;span class="w"&gt; &lt;/span&gt;~/.openclaw/workspace-code-reviewer&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--model&lt;span class="w"&gt; &lt;/span&gt;opencode-zen/gpt-5.4-pro&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--non-interactive
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这条命令会自动创建：
- 独立的工作空间目录：&lt;code&gt;~/.openclaw/workspace-code-reviewer&lt;/code&gt;
- 独立的Agent配置目录：&lt;code&gt;~/.openclaw/agents/code-reviewer/agent&lt;/code&gt;
- 独立的会话存储：&lt;code&gt;~/.openclaw/agents/code-reviewer/sessions/&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Step 5：定义Agent人格&lt;/h3&gt;
&lt;p&gt;每个Agent都可以有独立的人格配置。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AGENTS.md&lt;/strong&gt; (&lt;code&gt;~/.openclaw/workspace-code-reviewer/AGENTS.md&lt;/code&gt;)：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;# Code Review Agent&lt;/span&gt;

你是一个专门的代码审查助手，使用GPT 5.4 Pro进行深度代码分析。

&lt;span class="gu"&gt;## 职责&lt;/span&gt;
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;代码质量审查
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;潜在Bug识别
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;性能优化建议
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;安全性检查
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;最佳实践建议

&lt;span class="gu"&gt;## 审查标准&lt;/span&gt;
&lt;span class="k"&gt;1.&lt;/span&gt; 代码可读性
&lt;span class="k"&gt;2.&lt;/span&gt; 错误处理
&lt;span class="k"&gt;3.&lt;/span&gt; 性能考虑
&lt;span class="k"&gt;4.&lt;/span&gt; 安全性
&lt;span class="k"&gt;5.&lt;/span&gt; 测试覆盖

&lt;span class="gu"&gt;## 输出格式&lt;/span&gt;
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;总体评分（A-F）
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;问题列表（文件:行号）
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;严重程度（高/中/低）
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;建议修复方案
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;SOUL.md&lt;/strong&gt; (&lt;code&gt;~/.openclaw/workspace-code-reviewer/SOUL.md&lt;/code&gt;)：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;# Code Review Agent Soul&lt;/span&gt;

你是一个经验丰富、耐心细致的代码审查专家。

&lt;span class="gu"&gt;## 性格&lt;/span&gt;
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;严谨但友好
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;注重细节
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;建设性而非批评性

&lt;span class="gu"&gt;## 语气&lt;/span&gt;
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;专业但亲切
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;清晰简洁
&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;避免技术术语滥用
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3&gt;Step 6：配置飞书机器人&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;openclaw.json&lt;/code&gt; 的 &lt;code&gt;channels&lt;/code&gt; 部分配置飞书多账户：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;channels&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;feishu&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;enabled&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;accounts&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;appId&amp;quot;&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;quot;cli_已有应用ID&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;appSecret&amp;quot;&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;quot;已有应用Secret&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;code-review&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;appId&amp;quot;&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;quot;cli_新应用ID&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;appSecret&amp;quot;&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;quot;新应用Secret&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;connectionMode&amp;quot;&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;quot;websocket&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&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;quot;feishu&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;groupPolicy&amp;quot;&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;quot;open&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：&lt;code&gt;accounts&lt;/code&gt; 是多账户配置的关键字段，每个账户对应一个飞书应用。&lt;code&gt;default&lt;/code&gt; 账户用于main Agent，&lt;code&gt;code-review&lt;/code&gt; 账户用于code-reviewer Agent。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3&gt;Step 7：配置路由绑定&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;openclaw.json&lt;/code&gt; 中添加Bindings：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;bindings&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;agentId&amp;quot;&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;quot;code-reviewer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;match&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;channel&amp;quot;&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;quot;feishu&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;accountId&amp;quot;&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;quot;code-review&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;路由规则解读&lt;/strong&gt;：
- 当消息来自 &lt;code&gt;feishu&lt;/code&gt; 渠道
- 且账户为 &lt;code&gt;code-review&lt;/code&gt;（即新创建的飞书机器人）
- 则路由到 &lt;code&gt;code-reviewer&lt;/code&gt; Agent&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Step 8：重启网关使配置生效&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;gateway&lt;span class="w"&gt; &lt;/span&gt;restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3&gt;Step 9：验证配置&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;agents&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;--bindings
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;期望输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Agents:
- main (default)
  Model: minimax/MiniMax-M2.7
  Routing: default

- code-reviewer
  Model: opencode-zen/gpt-5.4-pro
  Routing rules:
    - feishu accountId=code-review
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;检查频道状态：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;channels&lt;span class="w"&gt; &lt;/span&gt;status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;期望看到两个飞书账户都在运行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;- Feishu default: enabled, configured, running
- Feishu code-review: enabled, configured, running
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;测试效果&lt;/h2&gt;
&lt;h3&gt;测试1：日常编码（走main Agent，MiniMax模型）&lt;/h3&gt;
&lt;p&gt;通过第一个飞书机器人发送：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;帮我写一个Python函数，计算斐波那契数列
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;MiniMax快速响应，成本低。&lt;/p&gt;
&lt;h3&gt;测试2：代码审查（走code-reviewer Agent，GPT 5.4 Pro）&lt;/h3&gt;
&lt;p&gt;（简单例子示意，非大模型真实输出）&lt;/p&gt;
&lt;p&gt;通过第二个飞书机器人发送：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_user_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;SELECT * FROM users WHERE id = &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;GPT 5.4 Pro 深度分析，输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;🚨&lt;span class="w"&gt; &lt;/span&gt;严重问题：&lt;span class="nv"&gt;SQL&lt;/span&gt;注入漏洞

文件位置:&lt;span class="w"&gt; &lt;/span&gt;代码片段:&lt;span class="mi"&gt;2&lt;/span&gt;
问题:&lt;span class="w"&gt; &lt;/span&gt;用户输入直接拼接&lt;span class="nv"&gt;SQL&lt;/span&gt;查询
严重程度:&lt;span class="w"&gt; &lt;/span&gt;高
建议修复:&lt;span class="w"&gt; &lt;/span&gt;使用参数化查询

修复代码:
```&lt;span class="nv"&gt;python&lt;/span&gt;
&lt;span class="nv"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;process_user_input&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;user_input&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT * FROM users WHERE id = %s&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;db&lt;/span&gt;.&lt;span class="nv"&gt;execute&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;query&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;user_input&lt;/span&gt;,&lt;span class="ss"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;多Agent架构的核心价值：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;成本优化&lt;/strong&gt;：简单任务用便宜模型，复杂任务用强模型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;专业化&lt;/strong&gt;：每个Agent可以定制专属的人格和规则&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;好钢用在刀刃上&lt;/strong&gt;，让每个模型做最擅长的事。&lt;/p&gt;</content><category term="技术教程"></category><category term="OpenClaw"></category><category term="AI"></category><category term="多Agent"></category><category term="飞书"></category><category term="配置教程"></category></entry><entry><title>我替你踩坑了：部署 OpenClaw 后，记得先做这一步，防止服务器被跑死</title><link href="https://hillerliao.github.io/wo-ti-ni-cai-keng-liao-bu-shu-openclaw-hou-ji-de-xian-zuo-zhe-yi-bu-fang-zhi-fu-wu-qi-bei-pao-si.html" rel="alternate"></link><published>2026-02-26T12:02:14+08:00</published><updated>2026-02-26T12:02:14+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-02-26:/wo-ti-ni-cai-keng-liao-bu-shu-openclaw-hou-ji-de-xian-zuo-zhe-yi-bu-fang-zhi-fu-wu-qi-bei-pao-si.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;openclaw&lt;/li&gt;
&lt;li&gt;linux&lt;/li&gt;
&lt;li&gt;server &lt;/li&gt;
&lt;li&gt;log &lt;/li&gt;
&lt;li&gt;disk
slug: prevent-openclaw-from-filling-up-your-disk&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;如果你已经把 OpenClaw 跑起来了，这篇文章建议你花 5 分钟看完，&lt;strong&gt;可以直接帮你避开服务器跑死的坑&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;不想看过 …&lt;/h2&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;openclaw&lt;/li&gt;
&lt;li&gt;linux&lt;/li&gt;
&lt;li&gt;server &lt;/li&gt;
&lt;li&gt;log &lt;/li&gt;
&lt;li&gt;disk
slug: prevent-openclaw-from-filling-up-your-disk&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;如果你已经把 OpenClaw 跑起来了，这篇文章建议你花 5 分钟看完，&lt;strong&gt;可以直接帮你避开服务器跑死的坑&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;不想看过程？直接照做这 3 步&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1. 清理已有日志&lt;/span&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;/tmp/openclaw/*.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 2. 设置日志上限（单文件 &amp;gt;1GB 自动删）&lt;/span&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;/usr/local/bin/openclaw-log-guard.sh&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;&lt;/span&gt;
&lt;span class="s"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="s"&gt;find /tmp/openclaw -name &amp;quot;*.log&amp;quot; -size +1G -delete&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;/usr/local/bin/openclaw-log-guard.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 3. 每小时执行一次&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;0 * * * * /usr/local/bin/openclaw-log-guard.sh&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;做到这里就够了。
下面是我为什么会踩到这个坑。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;事情背景：早上 7 点，服务器告警&lt;/h2&gt;
&lt;p&gt;早上七点多，收到阿里云短信：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;磁盘使用率超过 95%&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;一、确认磁盘真的满了&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;df&lt;span class="w"&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;只看一行：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/&lt;/code&gt;（根分区）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Use% &amp;gt; 95%&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;二、到底是谁在占磁盘？&lt;/h2&gt;
&lt;h3&gt;1️⃣ 先看哪个目录最大&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;du&lt;span class="w"&gt; &lt;/span&gt;-sh&lt;span class="w"&gt; &lt;/span&gt;/*&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sort&lt;span class="w"&gt; &lt;/span&gt;-rh&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;结果发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/tmp&lt;/code&gt; 占用了 &lt;strong&gt;十几 GB&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;2️⃣ 继续往 &lt;code&gt;/tmp&lt;/code&gt; 里找&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;du&lt;span class="w"&gt; &lt;/span&gt;-sh&lt;span class="w"&gt; &lt;/span&gt;/tmp/*&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sort&lt;span class="w"&gt; &lt;/span&gt;-rh&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;当时最扎眼的一行是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;10G   /tmp/openclaw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3&gt;3️⃣ 看里面是什么&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-lh&lt;span class="w"&gt; &lt;/span&gt;/tmp/openclaw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;看到的是几个日志文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个接近 &lt;strong&gt;9GB&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;另一个 &lt;strong&gt;1GB+&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;到这里已经可以确定：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;是 OpenClaw 日志把磁盘写满了&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;三、这些日志主要在记什么？&lt;/h2&gt;
&lt;p&gt;查看日志里主要的错误信息：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;Ei&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;disconnect|reconnect|unauthorized|token|1008|ws&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;openclaw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;openclaw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2026&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;.&lt;span class="nv"&gt;log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;head&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;内容主要是三类：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gateway / WebSocket 日志&lt;/strong&gt;
   Web UI 连接、断开、重连都会写。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;浏览器或工具调用失败日志&lt;/strong&gt;
   比如浏览器控制没连上、工具参数不完整，&lt;strong&gt;失败会反复重试&lt;/strong&gt;，每次都写一条。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;插件或消息通道异常日志&lt;/strong&gt;
   插件加载了，但目标不匹配，也会持续尝试并记录失败。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;重点不在“有没有错误”，而在于：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;这些日志默认没有大小上限&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一旦进入异常循环，文件会一直涨。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;四、我当时怎么处理的（先止血）&lt;/h2&gt;
&lt;h3&gt;1️⃣ 直接删日志&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;/tmp/openclaw/*.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;2️⃣ 再看磁盘&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;df&lt;span class="w"&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这时根分区使用率降到了 &lt;strong&gt;69% 左右&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;五、真正关键的一步：防止再发生&lt;/h2&gt;
&lt;p&gt;只清一次没意义，必须加“上限”。&lt;/p&gt;
&lt;h3&gt;限制 OpenClaw 日志大小&lt;/h3&gt;
&lt;h4&gt;1️⃣ 新建清理脚本&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;/usr/local/bin/openclaw-log-guard.sh&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;&lt;/span&gt;
&lt;span class="s"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="s"&gt;find /tmp/openclaw -name &amp;quot;*.log&amp;quot; -size +1G -delete&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;/usr/local/bin/openclaw-log-guard.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;作用只有一句话：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;任何 OpenClaw 日志文件超过 1GB，就删除&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h4&gt;2️⃣ 设置定时任务（每小时一次）&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;-e
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;加一行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kr"&gt;open&lt;/span&gt;&lt;span class="n"&gt;claw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;不频繁&lt;/li&gt;
&lt;li&gt;不影响排障&lt;/li&gt;
&lt;li&gt;足够安全&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;六、现在的状态&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;磁盘不再突然 95%+&lt;/li&gt;
&lt;li&gt;日志不会无限增长&lt;/li&gt;
&lt;li&gt;OpenClaw 正常运行&lt;/li&gt;
&lt;li&gt;不需要人工盯着&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;最后一句话&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;部署 OpenClaw 后，
&lt;strong&gt;第一件要做的事是：给日志设上限。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个坑我已经踩过了，
你不需要再踩一次。&lt;/p&gt;
&lt;p&gt;如果你在部署或使用OpenClaw过程中有碰到问题，都可以进群交流，大多数坑都已经有人踩过了。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="../images/a416b9ca688bec9e83693414c4075eb3.png"&gt;&lt;/p&gt;</content><category term="Tech"></category></entry><entry><title>段永平发言太杂？我用 OpenClaw 自动筛选有价值观点（附实操）</title><link href="https://hillerliao.github.io/openclaw-duan-yong-ping-monitor.html" rel="alternate"></link><published>2026-02-25T00:00:00+08:00</published><updated>2026-02-25T00:00:00+08:00</updated><author><name>hillerdescription: 利用 OpenClaw 智能监控段永平的投资动态，通过 AI 语义理解筛选有价值信息，推送到 Telegram。</name></author><id>tag:hillerliao.github.io,2026-02-25:/openclaw-duan-yong-ping-monitor.html</id><summary type="html">&lt;p&gt;过完年，相信你已经多多少少听说过 &lt;strong&gt;OpenClaw&lt;/strong&gt; 这个词。&lt;/p&gt;
&lt;p&gt;简单一句话概括：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;它是一个&lt;strong&gt;能理解你意图、替你干活的 AI Agent&lt;/strong&gt;，有点像 &lt;em&gt;Siri + DeepSeek + 自动 …&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;过完年，相信你已经多多少少听说过 &lt;strong&gt;OpenClaw&lt;/strong&gt; 这个词。&lt;/p&gt;
&lt;p&gt;简单一句话概括：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;它是一个&lt;strong&gt;能理解你意图、替你干活的 AI Agent&lt;/strong&gt;，有点像 &lt;em&gt;Siri + DeepSeek + 自动化工具&lt;/em&gt; 的结合体。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很多人拿到 OpenClaw 后，第一反应往往是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;👉 &lt;em&gt;“这东西到底能干啥？”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这篇文章，我不讲概念，只讲一个&lt;strong&gt;我自己已经跑起来的真实案例&lt;/strong&gt;：
&lt;strong&gt;如何用 OpenClaw，智能监控段永平的投资动态，只推送“有价值的信息”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你关注的不是投资人，而是娱乐明星、行业大佬、KOL，道理完全一样。&lt;/p&gt;
&lt;h2&gt;一个痛点：信息太多，但重点太少&lt;/h2&gt;
&lt;p&gt;如果你是价值投资者，大概率关注过投资人 &lt;strong&gt;段永平&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;他的特点很鲜明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;几乎&lt;strong&gt;只在雪球发言&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;发言频率不高，但&lt;strong&gt;含金量极高&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;内容混杂：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;投资观点&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;生活闲聊&lt;/li&gt;
&lt;li&gt;回复网友&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;雪球&lt;/strong&gt;本身提供了「订阅用户动态」功能，这已经是一个不错的基础能力。&lt;/p&gt;
&lt;p&gt;但实际用下来会发现一个问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;❌ &lt;strong&gt;所有内容都会推送，混在一起&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你真正想看到的，可能只有这些：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提到 &lt;strong&gt;具体公司&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;涉及 &lt;strong&gt;买入 / 持仓 / 估值判断&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;能反映其&lt;strong&gt;投资逻辑变化&lt;/strong&gt;的发言&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么问题来了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;能不能：只在“有投资价值”的时候提醒我？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;答案是：&lt;strong&gt;可以，而且我已经跑起来了。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;实际效果预览&lt;/h2&gt;
&lt;p&gt;这是我在 &lt;strong&gt;Telegram&lt;/strong&gt; 上收到的真实推送示例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;🚨 段永平雪球更新【重点】
📝 内容：回复网友关于期权操作和阿里持仓看法
💡 看法：70元买阿里足够便宜，体现其长期价值投资理念
🔗 原文：https://xueqiu.com/1247347556/376663072
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;其中这个 &lt;strong&gt;「【重点】」&lt;/strong&gt;，并不是我手动加的，而是我给 OpenClaw 设定的&lt;strong&gt;条件告警规则&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;只要段永平的发言中：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提到具体公司（如：苹果、腾讯、阿里、茅台、Google 等）&lt;/li&gt;
&lt;li&gt;且语义上与投资相关
  👉 就自动标记为重点，并给出 AI 解读&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;整体架构（非常简单）&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;雪球 → RSSHub → OpenClaw 定时任务
     → AI 语义判断
     → 消息推送（Telegram / 微信）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;OpenClaw 部署在云服务器上，&lt;strong&gt;便宜、省心、7×24 小时运行&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果你不想买服务器，用闲置旧手机也行。
👉 之前我写过一篇完整教程：《&lt;a href="https://mp.weixin.qq.com/s/KASWkkuD2-Q5f22FDQ7bNA"&gt;不用买服务器！旧手机免费运行 OpenClaw&lt;/a&gt;》&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;实现过程：全程自然语言，没写代码&lt;/h2&gt;
&lt;p&gt;这是我最想分享的部分。&lt;/p&gt;
&lt;p&gt;整个系统，我&lt;strong&gt;没有手动写一行代码&lt;/strong&gt;，全部是跟 OpenClaw 对话完成的。&lt;/p&gt;
&lt;h3&gt;① 先说清楚目标&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;我：帮我监控投资人段永平的最新动态，
    可以通过 RSS 地址获取新内容。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;然后我把 RSS 地址丢给它：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://&amp;lt;my domain&amp;gt;/xueqiu/user/1247347556
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;这个 RSS 是我用开源项目 &lt;strong&gt;RSSHub-Python&lt;/strong&gt; 生成的。
本质上，它把段永平的雪球帖子，转换成&lt;strong&gt;机器更容易处理的数据格式&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我还特意强调了一点：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;只在“有新帖子”时才提醒&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3&gt;② RSS 不稳定？那就让 OpenClaw 自己部署&lt;/h3&gt;
&lt;p&gt;一开始我用的是别人提供的 RSS 地址，不太稳定，我就想到自己部署一套RSSHub-Python服务。于是对话变成了这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;我：这个项目能部署吗？
   https://github.com/hillerliao/rsshub-python

AI：支持 Docker / Vercel / 本地部署

我：Docker 吧

AI：网络问题……

我：那就本地部署

(若干分钟后...)

AI：部署成功，地址 http://127.0.0.1/xueqiu/user/1247347556
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;为了测试验证，可以让OpenClaw给你请求该地址实际获取到的内容。&lt;/p&gt;
&lt;p&gt;这个项目内部依赖浏览器环境抓取页面，如果环境不完整，可能会报错。如果你获取到的是这种字样的： &lt;code&gt;Playwright not supported on Vercel&lt;/code&gt;，发给OpenClaw，让它安装一下 Playwright，具体是啥不用管。&lt;/p&gt;
&lt;p&gt;整个过程，&lt;strong&gt;OpenClaw 自己解决依赖、环境、启动问题&lt;/strong&gt;，我基本只是做选择题。&lt;/p&gt;
&lt;p&gt;一个小插曲，它把我已经存在的一个网页服务给搞成404无法访问了，幸好后来让它帮忙修复了。改坏东西是OpenClaw容易犯的毛病。所以初期尝试的时候，建议在闲置电脑或独立服务器上部署。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你是云服务器，建议 4G 内存以上&lt;br&gt;
中国大陆服务器可用 &lt;a href="https://gitee.com/hillerliao/rsshub-python"&gt;Gitee 镜像&lt;/a&gt;，或让 OpenClaw 用 &lt;code&gt;r.jina.ai&lt;/code&gt; 访问 GitHub 版地址。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3&gt;③ 核心价值：不是关键词，而是“理解内容”&lt;/h3&gt;
&lt;p&gt;我只说了一句话：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;我：提到具体公司时要重点提醒
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;OpenClaw 背后做的事情，其实是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;语义理解&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文判断&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;投资 vs 生活区分&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举个最关键的例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅「70 元买阿里很便宜」 → &lt;strong&gt;重点&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;❌「今天吃了个苹果」 → &lt;strong&gt;不提醒&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一步，是传统自动化工具&lt;strong&gt;最难做到的地方&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;④ 消息推送&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;我：推送到 Telegram  
AI：已配置完成
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;就这么结束了。（现在简单是因为之前费力气调通了消息通道。😅）&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;那用别的工具不行吗？&lt;/h2&gt;
&lt;p&gt;行，但体验完全不一样。&lt;/p&gt;
&lt;p&gt;我之前用 &lt;strong&gt;N8N&lt;/strong&gt; （一个开源的低代码服务）搭过类似流程，简单对比一下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;对比项&lt;/th&gt;
&lt;th&gt;N8N&lt;/th&gt;
&lt;th&gt;OpenClaw&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&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;配置&lt;/td&gt;
&lt;td&gt;画节点 + 写 JS&lt;/td&gt;
&lt;td&gt;自然语言&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&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;AI 能力&lt;/td&gt;
&lt;td&gt;需额外集成&lt;/td&gt;
&lt;td&gt;首次填大模型API KEY即可&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;当时为了判断“是否为新帖子”，我写了不少 JS，调试非常痛苦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本质差异只有一句话：&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OpenClaw 能“看懂你在说什么”，
而传统自动化工具，只是在“对字符串”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我用的是 MiniMax 的大模型，它在中文语境下，对投资语义的区分非常准确。&lt;/p&gt;
&lt;p&gt;而且后续要优化，直接和机器人通过聊天沟通就行了，不需要登录相关工具后台去来回调试操作。&lt;/p&gt;
&lt;h2&gt;下一步我准备怎么升级？&lt;/h2&gt;
&lt;p&gt;现在系统已经稳定运行，但我还打算继续加东西：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;媒体监控&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不止雪球&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自动抓取段永平相关持仓、采访、报道&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;周期报告&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;每周 / 每月&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;自动汇总观点变化&lt;/li&gt;
&lt;li&gt;AI 生成分析摘要&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;写在最后&lt;/h2&gt;
&lt;p&gt;以前，搭一个这样的&lt;strong&gt;智能信息监控系统&lt;/strong&gt;，
意味着：服务器 + 脚本 + 定时任务 + 调试。&lt;/p&gt;
&lt;p&gt;现在，只需要动动嘴就把活儿干了。一旦用上，以前的工具好比是手动挡，OpenClaw好比是自动驾驶。&lt;/p&gt;
&lt;p&gt;这就是 &lt;strong&gt;OpenClaw + AI Agent&lt;/strong&gt; 真正让我感到“有代际差异”的地方。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;👉 &lt;strong&gt;你最想监控的是哪位投资人 / 行业大佬？&lt;/strong&gt;
欢迎在评论区留言。&lt;/p&gt;
&lt;p&gt;如果你在搭建过程中踩坑，或者想看后续升级方案，也欢迎进群交流。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="../images/a416b9ca688bec9e83693414c4075eb3.png"&gt;  &lt;/p&gt;
&lt;p&gt;如果需要购买MiniMax的大模型API，可以点击原读原文以9折优惠购买。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>Termux 环境下 frpc 和 OpenClaw 服务保活方案</title><link href="https://hillerliao.github.io/termux-frpc-openclaw-auto-restart.html" rel="alternate"></link><published>2026-02-13T00:00:00+08:00</published><updated>2026-02-13T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-02-13:/termux-frpc-openclaw-auto-restart.html</id><summary type="html">&lt;h2&gt;背景与痛点&lt;/h2&gt;
&lt;h3&gt;问题场景&lt;/h3&gt;
&lt;p&gt;在 Android 设备上运行 frpc（内网穿透客户端）和 OpenClaw 时，面临以下挑战：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;手机重启后服务不自动启动&lt;/strong&gt; - Android 系统不会 …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;h2&gt;背景与痛点&lt;/h2&gt;
&lt;h3&gt;问题场景&lt;/h3&gt;
&lt;p&gt;在 Android 设备上运行 frpc（内网穿透客户端）和 OpenClaw 时，面临以下挑战：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;手机重启后服务不自动启动&lt;/strong&gt; - Android 系统不会自动运行 Termux 中的后台服务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;进程崩溃后不会重启&lt;/strong&gt; - frpc 或 OpenClaw 可能因网络波动、内存不足等原因崩溃，需要手动介入&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无法方便地查看日志&lt;/strong&gt; - 后台运行的进程没有会话管理，调试困难&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;需求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;✅ 手机开机后 frpc + OpenClaw 自动启动&lt;/li&gt;
&lt;li&gt;✅ 进程崩溃后自动检测并重启&lt;/li&gt;
&lt;li&gt;✅ 方便查看运行日志&lt;/li&gt;
&lt;li&gt;✅ 低资源占用（不频繁检测）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;方案概述&lt;/h2&gt;
&lt;p&gt;利用 Termux 生态中的三个工具组合：&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;termux:boot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开机时自动执行脚本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;termux-wake-lock&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;防止系统休眠杀死进程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tmux&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;会话管理（保持进程运行、方便查看日志）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;cron&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;定时任务（每5分钟检测进程存活）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;依赖安装&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 安装 tmux（会话管理）&lt;/span&gt;
pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;tmux

&lt;span class="c1"&gt;# 安装 cron（定时任务）&lt;/span&gt;
pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;crontab

&lt;span class="c1"&gt;# 安装 termux:boot（开机自启）&lt;/span&gt;
pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;termux-boot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;termux:boot 安装后需要在 Android 设置中授权自启动权限&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;脚本内容&lt;/h2&gt;
&lt;h3&gt;1. OpenClaw 启动脚本 (&lt;code&gt;~/openclaw-run.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;负责清理旧进程、重新启动 OpenClaw：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-e

&lt;span class="nv"&gt;SESSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;openclaw&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;18789&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;NPM_BIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.npm-global/bin&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;TOKEN_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.openclaw_token&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 基础检查&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[ERR] tmux not found. Install: pkg install tmux&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$NPM_BIN&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[ERR] &lt;/span&gt;&lt;span class="nv"&gt;$NPM_BIN&lt;/span&gt;&lt;span class="s2"&gt; not found&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[ERR] token file not found: &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tr&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\r &amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/tmp&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 杀掉旧 session&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$SESSION&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# 新建 session 并启动&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$SESSION&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

tmux&lt;span class="w"&gt; &lt;/span&gt;send-keys&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$SESSION&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;export PATH=&lt;/span&gt;&lt;span class="nv"&gt;$NPM_BIN&lt;/span&gt;&lt;span class="s2"&gt;:\$PATH; export TMPDIR=\$HOME/tmp; export OPENCLAW_GATEWAY_TOKEN=&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;; openclaw gateway --bind lan --port &lt;/span&gt;&lt;span class="nv"&gt;$PORT&lt;/span&gt;&lt;span class="s2"&gt; --token \$OPENCLAW_GATEWAY_TOKEN --allow-unconfigured&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;C-m

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[OK] OpenClaw started in tmux session: &lt;/span&gt;&lt;span class="nv"&gt;$SESSION&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;2. 开机启动脚本 (&lt;code&gt;~/.termux/boot/services.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;手机开机时自动启动 crond、frpc 和 OpenClaw：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;

&lt;span class="c1"&gt;# 1. 清理旧会话&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# 2. 启动 crond（关键）&lt;/span&gt;
crond

&lt;span class="c1"&gt;# 3. 启动 frpc（持有 wake lock）&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new-session&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exec /data/data/com.termux/files/usr/bin/frpc -c /data/data/com.termux/files/usr/etc/frp/frpc.ini&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 4. 启动 OpenClaw&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;openclaw
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;send-keys&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;export PATH=/data/data/com.termux/files/home/.npm-global/bin:\$PATH TMPDIR=\$HOME/tmp; export OPENCLAW_GATEWAY_TOKEN=tokenac27a3d5; openclaw gateway --bind lan --port 18789 --token \$OPENCLAW_GATEWAY_TOKEN --allow-unconfigured&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;C-m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;3. frpc 启动脚本 (&lt;code&gt;~/.termux/boot/frpc-start.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;负责启动 frpc 并持有 wake lock：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
termux-wake-lock
&lt;span class="nb"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/data/data/com.termux/files/usr/bin/frpc&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;/data/data/com.termux/files/usr/etc/frp/frpc.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：使用 &lt;code&gt;exec&lt;/code&gt; 前缀确保 wake lock 正确持有&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4. 进程监控脚本 (&lt;code&gt;~/monitor.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/monitor.log
&lt;span class="nv"&gt;MAX_LOG_LINES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;

log&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;+%Y-%m-%d %H:%M:%S&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

trim_log&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;lines&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;wc&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$lines&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-gt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$MAX_LOG_LINES&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$MAX_LOG_LINES&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;.tmp&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mv&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;.tmp&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;========== Monitor started ==========&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# frpc 检测&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;pgrep&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc 进程不存在，准备重启...&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
&lt;span class="w"&gt;    &lt;/span&gt;sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;new-session&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exec /data/data/com.termux/files/usr/bin/frpc -c /data/data/com.termux/files/usr/etc/frp/frpc.ini&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc 重启命令已发送&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc 运行正常&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c1"&gt;# OpenClaw 检测&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;pgrep&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;openclaw.*gateway&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OpenClaw 进程不存在，准备重启...&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;bash&lt;span class="w"&gt; &lt;/span&gt;~/openclaw-run.sh&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pgrep&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;openclaw.*gateway&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OpenClaw 进程确认已启动&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OpenClaw 启动验证失败&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OpenClaw 运行正常&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

trim_log
log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;========== Monitor finished ==========&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;操作步骤&lt;/h2&gt;
&lt;h3&gt;第一步：安装依赖&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pkg&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;termux-api&lt;span class="w"&gt; &lt;/span&gt;crond
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;第二步：创建脚本文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot
chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot/services.sh&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot/frpc-start.sh&lt;span class="w"&gt; &lt;/span&gt;~/openclaw-run.sh&lt;span class="w"&gt; &lt;/span&gt;~/monitor.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;第三步：配置 cron&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;-e
&lt;span class="c1"&gt;# 添加以下内容（每5分钟检测一次）&lt;/span&gt;
*/5&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;/data/data/com.termux/files/home/monitor.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;常用命令&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;查看 tmux 会话&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux ls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看 frpc 日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux attach -t frpc&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看 OpenClaw 日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux attach -t openclaw&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;杀掉 tmux 会话&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux kill-session -t frpc/openclaw&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;手动执行检测&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bash ~/monitor.sh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看监控日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail -f ~/monitor.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;效果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;手机重启&lt;/strong&gt; → crond + frpc + OpenClaw &lt;strong&gt;全部自动启动&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;进程崩溃&lt;/strong&gt; → 5分钟内自动检测并重启&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;随时查看日志&lt;/strong&gt; → &lt;code&gt;tmux attach -t openclaw&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;⚠️ 关键经验教训&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;termux:boot 只在开机时执行一次&lt;/strong&gt;，杀进程后不会自动重启&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;boot 脚本不能用环境变量&lt;/strong&gt;，必须硬编码 token 和 port&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;crond 必须加入 boot 脚本&lt;/strong&gt;，否则进程监控不生效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;monitor.sh 用绝对路径&lt;/strong&gt;，cron 环境下 $PREFIX 不生效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;frpc 用 exec 启动&lt;/strong&gt;，确保 wake lock 正确持有&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wiki.termux.com/wiki/Termux:Boot"&gt;Termux Wiki - Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.termux.com/wiki/Cron"&gt;Termux Wiki - Cron&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tmuxcheatsheet.com/"&gt;Tmux 常用命令&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>用你的旧手机运行 OpenClaw，省下买服务器的钱</title><link href="https://hillerliao.github.io/install-openclaw-on-old-phone-with-termux.html" rel="alternate"></link><published>2026-02-03T00:00:00+08:00</published><updated>2026-02-03T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-02-03:/install-openclaw-on-old-phone-with-termux.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;OpenClaw&lt;/li&gt;
&lt;li&gt;Termux&lt;/li&gt;
&lt;li&gt;Android&lt;/li&gt;
&lt;li&gt;Shell 脚本&lt;/li&gt;
&lt;li&gt;AI 助手&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt="" src="../images/74590364992b496b8dbbfaf93d907f96.png"&gt;&lt;/p&gt;
&lt;h2&gt;需求背景&lt;/h2&gt;
&lt;p&gt;最近，一个叫做 OpenClaw 的软件开始火了起来。我试着在虚拟机 Ubuntu 系统上跑了一下，虽然部署过程 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;OpenClaw&lt;/li&gt;
&lt;li&gt;Termux&lt;/li&gt;
&lt;li&gt;Android&lt;/li&gt;
&lt;li&gt;Shell 脚本&lt;/li&gt;
&lt;li&gt;AI 助手&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt="" src="../images/74590364992b496b8dbbfaf93d907f96.png"&gt;&lt;/p&gt;
&lt;h2&gt;需求背景&lt;/h2&gt;
&lt;p&gt;最近，一个叫做 OpenClaw 的软件开始火了起来。我试着在虚拟机 Ubuntu 系统上跑了一下，虽然部署过程十分艰辛，但跑起来之后，发现确实很好用，能当个全天候的 AI 助手。&lt;/p&gt;
&lt;p&gt;但问题来了：要 24 小时在线，就得有台机器一直开着。有时候出门去，电脑休眠了，助手就连不上了。&lt;/p&gt;
&lt;p&gt;我看了一眼书桌上尘封已久的旧手机，突然冒出一个想法：既然网上教程都说最低 2G 2 核的机器就能运行 OpenClaw，那现在的安卓机配置那么高，&lt;strong&gt;是不是可以让 OpenClaw 跑在旧手机上？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一开始想找现成的方案，但失败了。最麻烦的就是包依赖的问题，看到那些报错，网上信息也不多，很头疼。不过带着报错信息，在多个大模型之间来回穿梭，终于比较圆满地解决了。&lt;/p&gt;
&lt;p&gt;不多说，直接上过程。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;前置条件&lt;/h2&gt;
&lt;p&gt;开始之前，请确认你准备好以下条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一部能正常使用的&lt;strong&gt;安卓旧手机&lt;/strong&gt;（配置要求不高，普通旧手机就行）&lt;/li&gt;
&lt;li&gt;手机能正常访问&lt;strong&gt;互联网&lt;/strong&gt;（下载和安装需要）&lt;/li&gt;
&lt;li&gt;⚠️ 网络环境可能需要&lt;strong&gt;魔法上网&lt;/strong&gt;，如果下载失败请注意这一点&lt;/li&gt;
&lt;li&gt;最重要的是要有&lt;strong&gt;信心和耐心&lt;/strong&gt;，跟着一步步来，没问题！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;下载和安装 Termux&lt;/h2&gt;
&lt;p&gt;首先，我们需要下载 Termux 应用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么是 Termux？&lt;/strong&gt;简单说，它是一个能在安卓手机上运行命令行工具的软件，相当于给手机装了个简易的 Linux 系统。&lt;/p&gt;
&lt;h3&gt;如何下载&lt;/h3&gt;
&lt;p&gt;由于国内应用市场无法直接下载，你需要通过以下方式之一获取：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐方式：&lt;/strong&gt;
- &lt;a href="https://f-droid.org/en/packages/com.termux/"&gt;F-Droid&lt;/a&gt; - 官方下载渠道，最安全&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其他方式（如上面的打不开）：&lt;/strong&gt;
- &lt;a href="https://github.com/termux/termux-app/releases"&gt;GitHub 官方发布页&lt;/a&gt; - 需要魔法上网
- &lt;a href="https://play.google.com/store/apps/details?id=com.termux"&gt;Google Play&lt;/a&gt;
- 第三方应用商店（如 ApkPure 等）- 注意选择正规来源&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;小贴士&lt;/strong&gt;：下载时请认准官方来源，避免下载不安全的第三方应用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;p&gt;下载好后，直接安装。安装完成后：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;打开 Termux 应用&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;你会看到一个黑色屏幕，这就是命令行终端界面&lt;/li&gt;
&lt;li&gt;长按屏幕可以粘贴内容，点击屏幕可以输入&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;🦞 运行安装脚本&lt;/h2&gt;
&lt;p&gt;接下来，复制下面的命令，粘贴到终端界面：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-sL&lt;span class="w"&gt; &lt;/span&gt;https://s.zhihai.me/openclaw&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;openclaw-install.sh
chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;openclaw-install.sh
./openclaw-install.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;或者整行复制 &lt;code&gt;curl -sL https://s.zhihai.me/openclaw &amp;gt; openclaw-install.sh &amp;amp;&amp;amp; chmod +x openclaw-install.sh &amp;amp;&amp;amp; ./openclaw-install.sh&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;注意记住你输入或随机生成的 token 。&lt;/p&gt;
&lt;h2&gt;初始化&lt;/h2&gt;
&lt;h3&gt;方法一&lt;/h3&gt;
&lt;p&gt;如果顺利安装完成，接着：&lt;/p&gt;
&lt;p&gt;1) 运行 &lt;code&gt;oclog&lt;/code&gt; 命令，查看运行状态。
2) 新开一个终端窗口（屏幕左滑，点击 New Session），运行 &lt;code&gt;openclaw setup&lt;/code&gt; 命令 。
3) 运行 &lt;code&gt;openclaw onboard&lt;/code&gt; 启动服务。这个就和常见的初始化教程说得一样了。不多说，最后一步提示 gateway 启动失败，可以不管，Termux 不支持这个，但前面 &lt;code&gt;oclog&lt;/code&gt; 能看到服务已经启动了。&lt;/p&gt;
&lt;h3&gt;方法二&lt;/h3&gt;
&lt;p&gt;如果上面这个看不懂，直接杀掉应用，重启 Termux 应用，再次进入终端界面。&lt;/p&gt;
&lt;p&gt;运行 &lt;code&gt;ocr&lt;/code&gt; 命令（OpenClaw Restart），接着运行 &lt;code&gt;oenclaw setup&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;![[7a766f2f9e5ce50840dad1267374e815.png]]
运行 ocr 命令后，过一段时间看到的效果（来自 2016年的 OnePlus 2 手机）&lt;/p&gt;
&lt;h2&gt;可能的问题与局限&lt;/h2&gt;
&lt;p&gt;OpenClaw还在快速更新，不保证脚本针对新版本还能成功运行，届时可能需要相应调整。&lt;/p&gt;
&lt;p&gt;相比标准的 OpenClaw 运行环境，使用 Termux 运行 OpenClaw 有一些局限：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;性能限制&lt;/strong&gt;：安卓设备的硬件资源可能不如 PC，影响 OpenClaw 的运行效率。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;稳定性&lt;/strong&gt;：Termux 环境可能不如正式的 Linux 发行版稳定，偶尔会出现兼容性问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;功能缺失&lt;/strong&gt;：某些高级功能可能需要额外配置或不被支持。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;![[74590364992b496b8dbbfaf93d907f96.png]]&lt;/p&gt;
&lt;p&gt;但就尝鲜和玩耍来说，这些限制是可以接受的。更何况，让旧手机变废为宝，不失为一件让人开心的事情。&lt;/p&gt;
&lt;h2&gt;更多可能的玩法&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;定时任务&lt;/strong&gt;：可以设置定时任务，让手机在特定时间自动执行某些任务。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;远程控制&lt;/strong&gt;：通过网络远程控制手机（安装 &lt;code&gt;Termux-API&lt;/code&gt; ），实现远程操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;智能家居集成&lt;/strong&gt;：将手机作为智能家居中心的一部分，实现语音控制等。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;驱动 AI 写这个脚本花了我两个晚上的时间，第一次失败了，本来想放弃。后来不死心，第二天晚上又重来一遍。大部分时间都在解决 Android 兼容性问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心思路总结为这几句话：&lt;/strong&gt;
1. 用 Termux 提供 Linux 环境
2. 修复 OpenClaw 的平台兼容性问题
3. 用 tmux 守护进程，确保服务持续运行
4. 用 termux-wake-lock 防止手机休眠&lt;/p&gt;
&lt;p&gt;安装成功之后，记住几个命令就行：
- &lt;code&gt;ocr&lt;/code&gt; - 重启 OpenClaw 服务
- &lt;code&gt;oclog&lt;/code&gt; - 查看 OpenClaw 服务状态
- &lt;code&gt;ockill&lt;/code&gt; - 停止 OpenClaw 服务&lt;/p&gt;
&lt;p&gt;如果你有旧手机，不妨让它 Great Again 。👏&lt;/p&gt;
&lt;p&gt;安装过程中如果遇到问题，或有改进建议，欢迎反馈。&lt;/p&gt;
&lt;p&gt;也可以扫码进群交流：&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="../images/a416b9ca688bec9e83693414c4075eb3.png"&gt;&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>n8n Cron Trigger 使用 UTC 时区的坑：一次完整排查与解决记录</title><link href="https://hillerliao.github.io/n8n-cron-trigger-utc-timezone-issue.html" rel="alternate"></link><published>2026-01-18T00:00:00+08:00</published><updated>2026-01-18T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2026-01-18:/n8n-cron-trigger-utc-timezone-issue.html</id><summary type="html">&lt;h2&gt;问题背景&lt;/h2&gt;
&lt;p&gt;我使用 n8n 做自动化，通过 Cron Trigger，每天&lt;strong&gt;早上 7 点&lt;/strong&gt;自动执行一个工作流：
- 抓取 &lt;strong&gt;当天天气预报&lt;/strong&gt;
- 获取 &lt;strong&gt;农历日&lt;/strong&gt;
- 组合成消息，推 …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;问题背景&lt;/h2&gt;
&lt;p&gt;我使用 n8n 做自动化，通过 Cron Trigger，每天&lt;strong&gt;早上 7 点&lt;/strong&gt;自动执行一个工作流：
- 抓取 &lt;strong&gt;当天天气预报&lt;/strong&gt;
- 获取 &lt;strong&gt;农历日&lt;/strong&gt;
- 组合成消息，推送到微信 / 企业微信&lt;/p&gt;
&lt;p&gt;N8N 容器启动时已经明确设置：
- &lt;code&gt;TZ=Asia/Shanghai&lt;/code&gt;
- &lt;code&gt;GENERIC_TIMEZONE=Asia/Shanghai&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;运行多年都没问题。但最近&lt;strong&gt;升级了n8n&lt;/strong&gt;之后，出现问题：获取到的是头一天的日期和农历。&lt;/p&gt;
&lt;h2&gt;原因排查&lt;/h2&gt;
&lt;p&gt;我第一反应是容器的时区没有指定为东八区，&lt;/p&gt;
&lt;h3&gt;Code node 中生成的日期慢了一天&lt;/h3&gt;
&lt;p&gt;工作流中有一个 Code node，用来生成当天日期，后续用这个日期去查农历：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;currentDateTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;currentDateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;month&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentDateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;currentDateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;currentDate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="si"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;month&lt;/span&gt;&lt;span class="si"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;在 &lt;strong&gt;1 月 18 日早上 7 点（中国时间）&lt;/strong&gt; 执行时，得到的却是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;20260117&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;直接导致日期、农历错位。&lt;/p&gt;
&lt;h2&gt;二、排查过程&lt;/h2&gt;
&lt;h3&gt;✅ 第一步：确认容器时区是否正确&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-it&lt;span class="w"&gt; &lt;/span&gt;n8n&lt;span class="w"&gt; &lt;/span&gt;date
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Sun Jan 18 22:48:54 CST 2026
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;结论：&lt;/p&gt;
&lt;p&gt;✔ Docker 容器时区 &lt;strong&gt;完全正确&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;❌ 第二步：怀疑 TZ / localtime 是否未生效&lt;/h3&gt;
&lt;p&gt;尝试过：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;设置 &lt;code&gt;TZ=Asia/Shanghai&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置 &lt;code&gt;GENERIC_TIMEZONE=Asia/Shanghai&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;挂载 &lt;code&gt;/etc/localtime&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cron Trigger 仍然使用 UTC&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;说明这不是 Docker / Linux 层面的问题。&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;❌ 第三步：怀疑是 n8n Code node 的 bug&lt;/h3&gt;
&lt;p&gt;测试代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;2026&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;01&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;18&lt;/span&gt;&lt;span class="n"&gt;T14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;45&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;18.537&lt;/span&gt;&lt;span class="n"&gt;Z&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;看起来像是 UTC，但这一步反而帮我确认了关键事实。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;四、真相：这是 n8n 的“设计行为”，不是 Bug&lt;/h2&gt;
&lt;h3&gt;⚠️ 核心结论&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;n8n 的 Cron Trigger 永远使用 UTC 进行调度&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是官方设计选择，原因包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;保证工作流在不同时区、不同服务器上行为一致&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;避免夏令时（DST）导致的歧义&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;方便在数据库中统一存储时间&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;同时要明确三点：&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;是否受 TZ / GENERIC_TIMEZONE 影响&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker 容器时间&lt;/td&gt;
&lt;td&gt;✅ 是&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code node &lt;code&gt;Date()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌ 默认 UTC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cron Trigger&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ 永远 UTC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;也就是说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cron ≠ 系统时间 ≠ Code node 本地时间&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是大多数人第一次踩坑的根源。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;五、正确的解决方案&lt;/h2&gt;
&lt;h3&gt;✅ 方案一：Cron 时间手动减 8 小时（最推荐）&lt;/h3&gt;
&lt;p&gt;如果你希望：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;每天 22:00（中国时间）执行&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cron 应该写成：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UTC&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;即：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;14&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;常用对照表：&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;中国时间&lt;/th&gt;
&lt;th&gt;Cron（UTC）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;08:00&lt;/td&gt;
&lt;td&gt;00:00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;09:30&lt;/td&gt;
&lt;td&gt;01:30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:00&lt;/td&gt;
&lt;td&gt;04:00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22:00&lt;/td&gt;
&lt;td&gt;14:00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这是 &lt;strong&gt;生产环境最稳妥的做法&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;✅ 方案二：Code node 中显式指定时区（处理日期）&lt;/h3&gt;
&lt;p&gt;在 Code node 中，&lt;strong&gt;永远不要&lt;/strong&gt;直接用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;正确写法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tz&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Asia/Shanghai&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;en-CA&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;timeZone&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;numeric&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;month&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2-digit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2-digit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;formatToParts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;currentDate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="si"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;month&lt;/span&gt;&lt;span class="si"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;输出：&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;20260118&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3&gt;✅ 方案三：Cron 高频触发 + 本地时间判断（进阶）&lt;/h3&gt;
&lt;p&gt;如果你不想心算 UTC：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cron：每 5 分钟 / 每 10 分钟&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Code node 判断 &lt;strong&gt;中国时间是否满足条件&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;en-US&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;timeZone&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Asia/Shanghai&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2-digit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;hour12&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;22&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;适合复杂条件调度，但不适合简单定时。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;六、强烈不建议的做法&lt;/h2&gt;
&lt;p&gt;❌ 依赖容器时区影响 Cron&lt;br&gt;
❌ 使用 &lt;code&gt;toISOString()&lt;/code&gt; 生成业务日期&lt;br&gt;
❌ 在 Code node 中假设 &lt;code&gt;Date()&lt;/code&gt; 是本地时间&lt;br&gt;
❌ 试图“修复” n8n 的 Cron 行为&lt;/p&gt;
&lt;p&gt;这些都会让问题在将来再次出现。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;七、最佳实践总结（TL;DR）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cron Trigger：永远按 UTC 思考&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;时间展示 / 业务日期：必须显式指定 Asia/Shanghai&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不要相信默认行为&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把“时区”当成显式参数，而不是隐含前提&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你的自动化流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;涉及日期边界&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;涉及每日任务&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;涉及财务 / 日志 / 报表&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么这个问题 &lt;strong&gt;迟早会踩&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;早点理解，少掉几个坑。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;八、延伸&lt;/h2&gt;
&lt;p&gt;后续可以继续深入的点包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;n8n 内部是如何存储 Cron 的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;$now&lt;/code&gt; / Expression 的时区规则&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多时区任务如何设计更安全&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你也踩过这个坑，希望这篇记录能帮你节省几个小时的排查时间。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>SQL to CSV Converter：为产品或运营人员打造的数据格式转换利器</title><link href="https://hillerliao.github.io/sql-to-csv-converterwei-chan-pin-huo-yun-ying-ren-yuan-da-zao-de-shu-ju-ge-shi-zhuan-huan-li-qi.html" rel="alternate"></link><published>2025-02-15T00:00:00+08:00</published><updated>2025-02-15T00:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2025-02-15:/sql-to-csv-converterwei-chan-pin-huo-yun-ying-ren-yuan-da-zao-de-shu-ju-ge-shi-zhuan-huan-li-qi.html</id><summary type="html">&lt;p&gt;在日常运营工作中，数据是决策的关键，但获取和处理数据的过程往往并不顺利。运营人员常常需要从数据团队获取用户 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;在日常运营工作中，数据是决策的关键，但获取和处理数据的过程往往并不顺利。运营人员常常需要从数据团队获取用户行为、市场反馈或业务指标等数据，但这些数据通常以SQL查询结果的形式提供。对于不熟悉SQL的运营人员来说，查看和分析这些数据无疑是一项挑战。幸运的是，&lt;strong&gt;SQL to CSV Converter&lt;/strong&gt; 这个工具的出现，为这一问题提供了完美的解决方案。&lt;/p&gt;
&lt;h2&gt;什么是 SQL to CSV Converter？&lt;/h2&gt;
&lt;p&gt;SQL to CSV Converter 是一个基于 Flask 框架开发的开源工具，能够将 SQL 查询结果轻松转换为 CSV 格式。它提供了一个简洁直观的 Web 界面，让运营人员无需复杂的操作即可完成数据格式的转换。项目代码完全开源，托管在 &lt;a href="https://github.com/hillerliao/sql2csv"&gt;GitHub&lt;/a&gt; 上，用户可以根据需要自行部署或使用其在线演示站点。&lt;/p&gt;
&lt;h2&gt;运营人员的痛点与解决方案&lt;/h2&gt;
&lt;h3&gt;场景：运营人员的数据需求&lt;/h3&gt;
&lt;p&gt;运营人员在工作中常常需要从数据团队获取数据。例如，他们可能需要分析用户在某个新功能上线后的使用情况，或者统计某个营销活动的转化率。然而，数据团队通常会以 SQL 查询结果的形式提供这些数据，这对于运营人员来说并不友好。SQL 文件不仅难以直接查看，还需要专业的工具或技能才能进行进一步处理。&lt;/p&gt;
&lt;p&gt;这种情况不仅浪费了运营人员的时间，还可能导致数据处理过程中的错误。而 SQL to CSV Converter 的出现，完美解决了这一痛点。运营人员只需将 SQL 查询结果上传到工具中，即可一键将其转换为 CSV 格式。CSV 文件可以直接用 Excel 打开，方便运营人员进行数据整理、分析和可视化。&lt;/p&gt;
&lt;h3&gt;在线演示站与文件限制&lt;/h3&gt;
&lt;p&gt;为了方便运营人员快速体验和使用，SQL to CSV Converter 提供了一个在线演示站点，访问 &lt;a href="https://sql2csv.vercel.app/"&gt;https://sql2csv.vercel.app/&lt;/a&gt; 即可使用。该站点支持直接上传 SQL 文件，并将其转换为 CSV 格式，无需任何复杂的配置或安装。&lt;/p&gt;
&lt;p&gt;需要注意的是，为了确保服务的稳定性和安全性，演示站点对上传文件的大小进行了限制，&lt;strong&gt;单个文件的大小不得超过 4.5MB&lt;/strong&gt;。如果运营人员需要处理更大的文件，可以考虑将数据拆分后分别上传，或者在本地环境中部署该工具。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;SQL to CSV Converter 是一个专为运营人员设计的实用工具，它通过简单的操作，将复杂的 SQL 查询结果转换为易于查看和处理的 CSV 格式。无论是日常的数据分析，还是紧急的数据提取，这个工具都能帮助运营人员快速完成任务，节省时间和精力。如果你也经常面临类似的数据处理问题，不妨试试 SQL to CSV Converter，它可能会成为你工作中不可或缺的帮手。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>免装单词App，在 iPhone 锁屏随机显示单词</title><link href="https://hillerliao.github.io/randomly-show-a-word-on-ios-lockscreen.html" rel="alternate"></link><published>2024-10-17T23:23:00+08:00</published><updated>2024-10-17T23:23:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2024-10-17:/randomly-show-a-word-on-ios-lockscreen.html</id><summary type="html">&lt;p&gt;免装单词App，在iPhone锁屏随机显示单词！这样，你每天解锁手机的时候，都能顺便瞟一眼单词，日积月累，词汇量自然水涨船高！&lt;/p&gt;</summary><content type="html">&lt;p&gt;亲爱的朋友们，你是否曾经为背单词而烦恼？是否觉得用手机时有很多零碎时间没有利用上？&lt;/p&gt;
&lt;p&gt;今天，我要给大家带来一个神奇的方法——免装单词App，在iPhone锁屏随机显示单词！这样，你每天解锁手机的时候，都能顺便瞟一眼单词，日积月累，词汇量自然水涨船高！&lt;/p&gt;
&lt;p&gt;有些背单词软件可能有提供这种功能，但通常有一些问题：单词列表不受自己控制，显示的内容无法自定义，搞不好还收费。&lt;/p&gt;
&lt;p&gt;今天我就来给大家介绍一种免费实现自定义锁屏单词小组件的办法。&lt;/p&gt;
&lt;h2&gt;需要的工具&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;iPhone；&lt;/li&gt;
&lt;li&gt;Scriptable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Scriptable是一款iOS应用程序，允许用户使用JavaScript自动化构建和自定义桌面或锁屏小部件。&lt;/p&gt;
&lt;p&gt;得益于优秀的 Scriptable（苹果应用商店的开发者工具类排名前十），我们只需要写一点简单的基于JavaScript的脚本，就能干很多事情。&lt;/p&gt;
&lt;h2&gt;脚本代码&lt;/h2&gt;
&lt;p&gt;借助ChatGPT，把需求描述一番，很快就有了如下脚本：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;指定&lt;/span&gt;&lt;span class="n"&gt;RSS源的URL&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;https://politepol.com/fd/f1NYOd8OAcsA.xml&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;使用&lt;/span&gt;&lt;span class="n"&gt;fetch来获取RSS数据&lt;/span&gt;
&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Request&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 class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rssData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loadString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;输出&lt;/span&gt;&lt;span class="n"&gt;RSS数据到日志&lt;/span&gt;
&lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rssData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;使用正则表达式解析&lt;/span&gt;&lt;span class="n"&gt;RSS中的内容&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;ChatGPT给的参考代码中变量名为title&lt;/span&gt;&lt;span class="err"&gt;，这里实际选择读取摘要。&lt;/span&gt;
&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.*&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;\&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rssData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb nb-Type"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;创建一个&lt;/span&gt;&lt;span class="n"&gt;Widget展示RSS摘要&lt;/span&gt;
&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListWidget&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb nb-Type"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;#1a1a1a&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;如果解析到的摘要为空，显示占位符&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;No RSS data available&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb nb-Type"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;systemFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;添加&lt;/span&gt;&lt;span class="n"&gt;RSS摘要到Widget&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb nb-Type"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;systemFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addSpacer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;设置&lt;/span&gt;&lt;span class="n"&gt;Widget定期刷新&lt;/span&gt;&lt;span class="err"&gt;，设为&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="err"&gt;分钟。&lt;/span&gt;
&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;refreshAfterDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Date&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="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;预览&lt;/span&gt;&lt;span class="n"&gt;Widget&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runsInWidget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Script&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;presentMedium&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Script&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;具体代码是什么意思，我们就不用管太多了，只需要注意替换数据源地址就行。上述示例的 RSS 地址 &lt;code&gt;https://politepol.com/fd/f1NYOd8OAcsA.xml&lt;/code&gt; 系通过名为 &lt;a href="https://politepol.com/"&gt;politepol&lt;/a&gt; 的网页生成RSS服务将 &lt;code&gt;https://pyrss.vercel.app/word/jlpt2&lt;/code&gt;页面的日语N2单词转换而成。如果想要英文单词，请联系我。&lt;/p&gt;
&lt;p&gt;你可以在Scriptable上先运行脚本以验证数据是否获取成功，然后再进行下一步的设置。&lt;/p&gt;
&lt;h2&gt;设置为锁屏组件&lt;/h2&gt;
&lt;p&gt;接下来，开始编辑锁屏界面。添加 Scriptable 小组件，并选取刚才添加到 Scriptable 的脚本，即告完成。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://fastly.jsdelivr.net/gh/henrylovemiller/img@main/1727536737513%E9%94%81%E5%B1%8F%E5%8D%95%E8%AF%8D.png"&gt;&lt;/p&gt;
&lt;h2&gt;更多可能&lt;/h2&gt;
&lt;p&gt;也可以把小组件钉在手机桌面上。相比锁屏界面，桌面组件效果对样式要求更高，可以通过修改脚本中的样式代码让桌面小组件变得更加漂亮。&lt;/p&gt;
&lt;p&gt;此外，不仅仅是单词，天气、热搜、格言、倒数日之类的小组件，都可以借助Scriptable实现，核心就是换个数据和显示样式，本质都一样。只要你有想法，借助ChatGPT大概率能实现，一次不行，再试一次。&lt;/p&gt;
&lt;p&gt;如果觉得这篇文章有意思，对你有启发，欢迎点个赞。&lt;/p&gt;</content><category term="blog"></category><category term="小工具"></category></entry><entry><title>让上网变得麻烦一点 效率就能提高一点</title><link href="https://hillerliao.github.io/control-wifi-to-raise-productivity.html" rel="alternate"></link><published>2024-05-12T12:31:00+08:00</published><updated>2024-05-12T12:31:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2024-05-12:/control-wifi-to-raise-productivity.html</id><summary type="html">&lt;p&gt;电脑一断网，它就是非常棒的效率工具。能断则断，最好不过。如果不能，就设法减少联网次数。&lt;/p&gt;</summary><content type="html">&lt;p&gt;近来发现自己一打开电脑，效率就比较低下。于是，就开始琢磨，问题出在哪里？有什么提高效率的办法？今天简单记录针对这个问题的思考过程可尝试的解决方案。&lt;/p&gt;
&lt;p&gt;主要结论是，上网太方便是效率杀手，减少信息输入，适当让上网变得不那么容易，可以提高效率。&lt;/p&gt;
&lt;h2&gt;用电脑时都在干些什么&lt;/h2&gt;
&lt;p&gt;大部分人为了记录金钱支出，会使用记账软件。但对时间支出，似乎没有详细记录过，只是能说出一天之内大概做了些什么。这种印象往往不准确。比如，大概知道花了不少时间看娱乐休闲网站，但到底是哪些网站、哪些页面吸引了自己，并不太清楚。&lt;/p&gt;
&lt;p&gt;所以，要找到效率低下的根源，首先要看看时间到底花到哪里去了。&lt;/p&gt;
&lt;p&gt;我采取的办法是，找一个详细记录电脑使用时间的软件。对比了几款软件之后，我相中了免费开源的“ActivityWatch”。这个软件既省钱又相对安全。毕竟相当于安装了一个监控软件，还是谨慎为上。&lt;/p&gt;
&lt;h2&gt;屏蔽部分网站&lt;/h2&gt;
&lt;p&gt;有几个网站或软件，像Twitter、抽屉热榜、雪球、微信朋友圈之类的，无需统计就能知道自己几乎天天访问。要么是社交媒体，要么是时事资讯站点，一旦有网络环境，就会时不时占领我的心智。&lt;/p&gt;
&lt;p&gt;对付它们，无需手软，简单粗暴，直接屏蔽。不访问也没什么损失，如果真有特别重要的事件，总是会传到自己耳朵的，没必要第一时间知道。&lt;/p&gt;
&lt;p&gt;可以采用两种方法来达到屏蔽的目的。第一种是修改电脑的 Hosts 文件，将指定的几个域名跳转到127.0.0.1。这种做法的好处是全局生效，并稍微带点取消难度。毕竟要重新修改一次 hosts 文件得好几步，比较费事。但凡稍微有点麻烦的事情，人往往会选择放弃，我也不例外。&lt;/p&gt;
&lt;p&gt;这种做法也有办法绕过，那就是 VPN 。一开始我发现修改 Hosts 的做法对 Edge 浏览器无效，推测是 Edge 运行在“隔离浏览”环境所致（曾经踩到垃圾网站导致电脑染上病毒，右下角一直弹垃圾广告，所以开启了 Microsoft Defender 的隔离浏览功能），后来无意中发现是 Edge 浏览器自带 VPN 功能所致。那几天刚好在 Edge 的引导下开启了 VPN，访问Twitter等网站时骗过了 Hosts 。&lt;/p&gt;
&lt;p&gt;针对这种情况，我安装了一个叫做 Redirector 的浏览器插件。它能够将指定网址自动跳转到另一个网址，达到屏蔽效果。比如我指定 Twitter.com 这个域名下的网页跳转到一个随机显示日语单词的自建网站，屏蔽的同时顺便背一背单词，一举两得。这种做法也有缺点，关闭插件比较容易。&lt;/p&gt;
&lt;p&gt;实际观察下来，根据上网时间消费记录的分析揪出几个时间消耗大户，一举屏蔽，能节约不少时间。&lt;/p&gt;
&lt;p&gt;反过来想，刷新闻刷八卦真是人的一大需求。屏蔽它们等于是在与人性对抗。所以，手痒时，这些方法都面临无效的命运。因为我会临时取消屏蔽。比如临时想看 Twitter，就默默开启 Edge 的 VPN。。。&lt;/p&gt;
&lt;p&gt;此外，有些网站的部分界面会带有诱导性的内容，让自己在看需要的网页内容时跑题。比如百度各种页面右侧的热搜榜。这种情况的话，可以针对网页的指定区域定向屏蔽，比如安装开源的广告过滤插件 uBlock Origin。&lt;/p&gt;
&lt;p&gt;当然了，屏蔽是“堵”的做法，还可以适当辅以“疏”，比如选取日报类的资讯文章来阅读，在固定的时间集中消费一定数量的内容，更加高效。也能避免打断正常使用电脑办公学习的时间。&lt;/p&gt;
&lt;h2&gt;减少消息推送&lt;/h2&gt;
&lt;p&gt;关闭Windows环境下各个软件的消息推送，或开启“请勿打扰”模式，甚至全局关闭通知功能，则是减少被动接收通知类信息的办法。大部分消息推送并没有那么重要，定期看即可。这个和 iOS 等系统的类似，不多说。&lt;/p&gt;
&lt;h2&gt;多用离线软件 减少联网需求&lt;/h2&gt;
&lt;p&gt;要想减少上网带来的时间碎片化，还有一类做法是减少联网需求。少联网也就意味着少了很多“跑题”的机会。&lt;/p&gt;
&lt;p&gt;安装带有离线功能的软件，在本机环境内解决需求，能减少联网的次数。&lt;/p&gt;
&lt;p&gt;需要上B站看视频教程？那就把视频通过客户端缓存到本地，或者直接通过一些视频下载工具下载到本地再看。&lt;/p&gt;
&lt;p&gt;查词典时需要联网？那就用带有离线功能的词典，比如有道、欧路等。&lt;/p&gt;
&lt;p&gt;需要联网使用Google翻译？可以用有道翻译，带有离线功能，基本满足需求。&lt;/p&gt;
&lt;p&gt;想要使用 ChatGPT？如果有条件，本地上跑一个大模型也是可以的。&lt;/p&gt;
&lt;p&gt;想简单联网查个资料？ 将安卓手机连上电脑，通过 AnLink 等软件在电脑上操作手机。小窗口上操作手机比较费劲，也就不容易跑题了。&lt;/p&gt;
&lt;p&gt;简而言之，电脑能不连网尽量不联网。&lt;/p&gt;
&lt;h2&gt;增加联网难度&lt;/h2&gt;
&lt;p&gt;话说回来，不联网也是不现实的，不然电脑就废了。但是，适当增加联网难度，让自己珍惜每一次联网机会，也能适当提高效率。&lt;/p&gt;
&lt;p&gt;为了灵活控制电脑的网络连接，近期在尝试使用一个叫做 InternetOff 的小软件。体验了一段时间，发现它能较好地满足我的需求。&lt;/p&gt;
&lt;p&gt;虽然手动点击电脑右下角的 WiFi 图标也能关闭或开启网络连接，但通过 InternetOff 来干这个事情有以下几点优势：   &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以选择开启网络的时长，时间一到就自动断网；  &lt;/li&gt;
&lt;li&gt;可以设置操作密码（解锁），想开启网络就得输入自己设置的操作密码，稍微增加了一点操作难度；  &lt;/li&gt;
&lt;li&gt;可以设置指定禁止联网的时间段（Schedule）。  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;该软件的联网时长选项，除了总是联网这项，最低的一档是5分钟，最高的一档是1小时，中间两档为15分钟、30分钟。针对不同的上网需求，我可以选择不同的时长。比如，有时候就想发个邮件，自己估摸着写好后3分钟就能发送成功，那么，我可以选择5分钟。它能让我知道这次联网的核心任务就是发邮件，如果跑题了，五分钟之后还没搞定，网就断了，会有一点痛感。&lt;/p&gt;
&lt;p&gt;开启联网时， InternetOff 会在电脑状态栏以比较弱的绿色进度条显示剩余联网时长，制造一种紧迫感。剩余时长在1分钟以上时，只会精确到分钟，没有和一些倒计时软件一样采取跳秒的设计。跳秒的设计太过于抢眼，喧宾夺主干扰人。&lt;/p&gt;
&lt;p&gt;其次，开启联网的操作密码也可以好好利用。我把打开电脑希望每天都要优先完成的任务名称设置为操作密码。每次想输入操作密码准备联网时，就会提醒自己是否已经完成了重要任务。事优先的理念就落实到了软件上。&lt;/p&gt;
&lt;p&gt;另外，利用 Schedule 功能，我设置了几段不联网时段：  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;早上八点到九点。起床后效率较高，可以用来写东西，避免输入信息；  &lt;/li&gt;
&lt;li&gt;中午一点到两点，吃饭，休息；  &lt;/li&gt;
&lt;li&gt;傍晚六点到七点，断网后出门跑步，或准备做饭；  &lt;/li&gt;
&lt;li&gt;晚上十一点到十二点，收心，回顾一天，准备睡觉。  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;八点到九点时段，有时候我会打开电脑记录日常生活流水账，或完善之前写了一部分还没完成的文章。
有几天在6点到7点之间断网后出去跑步了，实现了使用该软件的目标。&lt;/p&gt;
&lt;p&gt;这个软件有几个地方还可以改进，其中之一是希望开启联网时支持注明联网目的。在进度条的位置展示目标，轻微提醒自己别跑题。其次，禁止联网时段希望能支持选择半点，现在只支持选择整点，不够灵活。比如，我想晚上十点半开始断网，但按照软件现在的设计，没法实现。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;总之，电脑一断网，它就是非常棒的效率工具。能断则断，最好不过。如果不能，就设法减少联网次数。日子一久，你会发现，以前迟迟无法写完的博客，不知不觉发表了；以前无法坚持的外语听写练习，已经积累20个小时了；以前在收藏夹里吃灰的视频教程，已经看完100集了；一直想背的单词，已经背了好几遍了。&lt;/p&gt;
&lt;p&gt;有时候生活不需要太便利，不是吗？&lt;/p&gt;</content><category term="blog"></category><category term="小工具"></category></entry><entry><title>一个简单脚本，让我抛弃笔记软件flomo</title><link href="https://hillerliao.github.io/blog20231219.html" rel="alternate"></link><published>2023-12-19T21:39:57+08:00</published><updated>2023-12-19T21:39:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2023-12-19:/blog20231219.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;笔记软件
categories:&lt;/li&gt;
&lt;li&gt;工具&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;连续好几年购买了笔记软件 flomo 的会员之后，今年10月下旬我没有再续费。&lt;/p&gt;
&lt;p&gt;回想起当初使用 flomo 的原因，除了记录无压力之外，最主 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;笔记软件
categories:&lt;/li&gt;
&lt;li&gt;工具&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;连续好几年购买了笔记软件 flomo 的会员之后，今年10月下旬我没有再续费。&lt;/p&gt;
&lt;p&gt;回想起当初使用 flomo 的原因，除了记录无压力之外，最主要就是看中 flomo 的笔记回顾功能。避免笔记沉睡，想法非常好。通过简单的一条微信模板消息，就能避免笔记沉睡。&lt;/p&gt;
&lt;p&gt;但不知从何时起，每日回顾功能改版了，每天发送的微信模板消息一模一样，仅相当于定时提醒的闹钟，毫无信息量，无法勾起我点进去看的欲望，久而久之，这类消息也就被我选择性无视了，甚至有垃圾信息的味道。&lt;/p&gt;
&lt;p&gt;还有什么功能可以实现类似效果呢？&lt;/p&gt;
&lt;p&gt;之前在 VPS 上通过 Docker 部署了仿 flomo 的 memos，输入体验接近 flomo ，但没有随机回顾功能，一直没有成为我的主力笔记软件。&lt;/p&gt;
&lt;p&gt;最近狠下心来，借助 Chat GPT 用 Python 写了一个简单的脚本，连接 memos 的 SQLite 数据库，随机获取一条笔记内容，并推送到 Telegram 。为了增强体验，增加了简单的关键词过滤，比如排除掉带有“存档”字眼的笔记。 写好之后，在系统的定时任务里增加一条运行该脚本的任务。&lt;/p&gt;
&lt;p&gt;试运行发现效果挺好，我就借助别人写的数据迁移工具，把 flomo上的数据导出后导入到 memos 中。&lt;/p&gt;
&lt;p&gt;当然，自己搭建的服务，就怕不稳定，数据备份很重要。我在自己电脑的 Wsl 上、安卓手机的 Termux上分别设置定时任务，将 SQLite 数据库文件备份到本地。&lt;/p&gt;
&lt;p&gt;到此，总算可以彻底告别 flomo 了。 meomos 加上简单的脚本，恢复了我的笔记回顾习惯，也帮我省了一笔 flomo 会员费，还避免了 VPS 吃灰，少花钱反而提升了体验，可谓是一举多得。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>尝试让 Pelican 博客的部分发布步骤自动化</title><link href="https://hillerliao.github.io/automated-pelican-publishment.html" rel="alternate"></link><published>2023-06-22T20:33:00+08:00</published><updated>2023-06-22T20:33:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2023-06-22:/automated-pelican-publishment.html</id><summary type="html">&lt;p&gt;尝试让 pelican 发布博客自动化，为此折腾了一天，几点收货。&lt;/p&gt;</summary><content type="html">&lt;p&gt;个人独立博客上最新一篇文章出现烂图，严重影响站点形象，而且持续了好长一段时间没有修复。图床用的是腾讯的某个服务，后来不让我的站点引用了。我早就忘了具体通过哪个图床工具上传的。&lt;/p&gt;
&lt;h2&gt;操作繁琐 修改动力不足&lt;/h2&gt;
&lt;p&gt;为什么迟迟不修复？ &lt;/p&gt;
&lt;p&gt;我的个人博客用 Pelican 生成，静态文件托管在 Github Pages，操作过程大致为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地添加 Markdown 文件；&lt;/li&gt;
&lt;li&gt;手动运行命令生成 HTML 静态文件；&lt;/li&gt;
&lt;li&gt;运行命令将静态文件推送到 Github 仓库的 gh-page 分支。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一顿操作太麻烦，导致我对更新博客有所抵触。&lt;/p&gt;
&lt;p&gt;今天端午节，决定花点时间让上述步骤半自动化。没想到折腾了一天才搞定。&lt;/p&gt;
&lt;p&gt;为了让这一天变得更有价值一点，稍作记录，顺便执行 push 触发一下自动更新的过程。&lt;/p&gt;
&lt;h2&gt;走了一些弯路&lt;/h2&gt;
&lt;p&gt;耗时太多主要是由于走了一些弯路，碰到好几个障碍：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;将 Github 仓库拉到本地，项目内的主题文件夹内容为空。经分析，问题出在引用其他仓库作为子模块。为让子模块文件夹内容出现，花了很大力气才搞定。直到现在，对Git子模块的理解还是云里雾里。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;运行 Github Workflow 报错，说是主题文件没找到。尝试修改别人的 Github Workflow Action ，加入安装主题的命令，然后尝试在 workflow里使用。但发现需要发布到 Marketplace 才行。 思路不对，我的做法是硬编码了，fork 之后的修改不合理。明明知道不合理的做法还是花了大力气尝试。进行一项尝试前尽量多花点时间评估方案的合理性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对 Pelican 配置文件不够熟悉，折腾了大半天才知道配置项 theme 的值可以是整个路径，之前以为必须是路径的最后一节，导致使用时以为也必须通过pelican-themes 命令安装主题才能添加主题文件。 技术选型需要尽可能先对官方文档读一遍，并找一些别人的操作案例多看，然后再自己动手。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;找 &lt;a href="https://github.com/rehanhaider/pelican-to-github-pages/tree/main"&gt;Workflow 模板&lt;/a&gt;时一开始找的是 Stars 数更少的一个，里面用到的一个关键 Action &lt;a href="https://github.com/rehanhaider/pelican-to-github-pages/blob/main/entrypoint.sh"&gt;源代码&lt;/a&gt;读起来不太好理解，后来找了另外一个模板，所引用的 &lt;a href="https://github.com/marketplace/actions/github-pages-pelican-build-action"&gt;Action&lt;/a&gt; 实现思路和我自己理解的更接近，借助 Codium 进行&lt;a href="https://github.com/nelsonjchen/gh-pages-pelican-action/blob/master/entrypoint.sh"&gt;源代码&lt;/a&gt;解读，基本理解了过程。它将生成的 output 作为仓库推送到 gh-page 分支。 当然前者对我还是有价值的， 因为它指定了 submodule相关的操作。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;意外的收获&lt;/h2&gt;
&lt;p&gt;折腾过程中也算是有几点意外收获：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Git 仓库内子模块又是一个仓库的时候，该怎么做才能在 Clone 时子模块的内容也能同时克隆下来。&lt;code&gt;--recursive&lt;/code&gt; 参数能解决这个问题。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Github Workflow 的配置文件里&lt;code&gt;run&lt;/code&gt;可以直接运行指定的脚本文件。其实别人的 Action 最核心的就是一个shell脚本文件。以后如果想在 workflow 里运行自有脚本，可以尝试该功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实际感受了 &lt;a href="https://www.codium.ai/"&gt;Codium&lt;/a&gt; 这个工具在辅助阅读代码时的便利。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;基于 pelican 生成的静态博客如何更新到 github Pages？还有一个方法是借助 git hook。在执行 push 前触发运行指定脚本。&lt;a href="https://nekrasovp.github.io/pelican-github-script-automation.html"&gt;参考案例&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;通过 &lt;a href="https://gist.github.com/JosefJezek/6053301"&gt;How to use Pelican on GitHub Pages Gittip&lt;/a&gt;  发现 &lt;code&gt;theme&lt;/code&gt; 配置项可以填入整个路径。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nekrasovp.github.io/pelican-github-script-automation.html"&gt;Move blog to github and automate deploying with git hooks - Data driven&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category><category term="pelican"></category></entry><entry><title>E843，高效利用微信学英语、看新闻的小工具</title><link href="https://hillerliao.github.io/e843.html" rel="alternate"></link><published>2022-11-06T16:54:00+08:00</published><updated>2022-11-06T16:54:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2022-11-06:/e843.html</id><summary type="html">&lt;p&gt;实时推送经济学人国际简讯到微信，碎片化时间享用高质量资讯。&lt;/p&gt;</summary><content type="html">&lt;p&gt;最近半年断断续续利用业余时间自建了一个企业微信应用「E843」，用于推送经济学人 World in Brief 栏目发布的国际简讯到个人微信。 &lt;/p&gt;
&lt;p&gt;&lt;img alt="企业微信自建应用 E843" src="https://fastly.jsdelivr.net/gh/hillerliao/img@main/wecom_E843_profile.jpg"&gt;&lt;/p&gt;
&lt;p&gt;应用名字来自经济学人的创办年份 1843 年，将数字 1 换成 Economist 的首字母 E 而成。E 也可以理解为 English 的首字母 E。&lt;/p&gt;
&lt;p&gt;&lt;img alt="E843界面预览" src="https://fastly.jsdelivr.net/gh/hillerliao/img@main/E843_preview.jpg"&gt;&lt;/p&gt;
&lt;p&gt;自己体验了一段时间「E843」，觉得还不错，现在介绍给大家。&lt;/p&gt;
&lt;h2&gt;为什么选择 World in Brief ？&lt;/h2&gt;
&lt;p&gt;由于本人很喜欢 The Economist 这个媒体，但就我目前的英语水平和浮躁心态，要看那些长篇大论不太现实。照此下去，难道就没有满足我利用碎片化时间欣赏 The Economist 精彩内容的办法了？&lt;/p&gt;
&lt;p&gt;直到有一天， The Economist 官网推出 World in Brief 栏目，这让我感觉到事情有望出现转机。该栏目是一个实时播报重大国际事件的页面，具备如下特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、短小精悍，几十个字一条新闻，比只看标题的新闻内容更丰富，比整篇文章更短，很适合碎片化阅读；&lt;/li&gt;
&lt;li&gt;2、陈述事实，没有观点和明显立场。这在信息过载的喧嚣世界里，显得很有吸引力；&lt;/li&gt;
&lt;li&gt;3、每天更新，比周刊时效性更强；&lt;/li&gt;
&lt;li&gt;4、每天十来条国际大事，数量适中，阅读压力小。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举例：  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vladimir Putin, Russia’s president, said any remaining civilians in Kherson in southern Ukraine should leave, his first public acknowledgement that Ukrainian forces are drawing close to the occupied city. Meanwhile, Ukraine’s president, Volodymyr Zelensky, said that the most intense fighting was around Bakhmut, 500km away, where Russia was “forcing tens or hundreds of thousands more people to the meat grinder”.  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;简而言之，它是一个很适合利用碎片化时间来阅读的高质量新闻源。&lt;/p&gt;
&lt;h2&gt;怎么看：无需安装软件，用个人微信就能看&lt;/h2&gt;
&lt;p&gt;有了合适的新闻源，还需要合适的载体。碎片化阅读最好的工具，对中国大陆大部分人而言，恐怕非微信莫属。微信聊天界面还支持长按内容将英文翻译成中文，无需跳出应用。&lt;/p&gt;
&lt;p&gt;&lt;img alt="E843翻译示例" src="https://fastly.jsdelivr.net/gh/hillerliao/img@main/E843_translator.jpg"&gt;&lt;/p&gt;
&lt;p&gt;但要向个人微信不间断推送消息，目前能使用的手段只有企业微信的个人微信插件这一条路。至于自动发送消息，可以借助自建应用或者群聊机器人。自建应用类似微信公众号，属于点对点单聊，不会有群聊消息的干扰，就像有些理发店宣传的那样，纯干活不废话。&lt;/p&gt;
&lt;p&gt;综合考虑，最终选择企业微信自建应用「E843」 实现消息推送。&lt;/p&gt;
&lt;h2&gt;多少钱：50元一年&lt;/h2&gt;
&lt;p&gt;如果你也想要使用上述服务，可以申请加入我在企业微信创建的"企业"「智海」。由于该"企业"不是认证主体，有200人上限，加满之后将无法接纳新"员工"。&lt;/p&gt;
&lt;p&gt;为让有限的名额给到真正需要的人，「E843」 需付费使用，50元一年。可以支付5元体验一个月。&lt;/p&gt;
&lt;p&gt;扫码联系牛牛（微信：cbnn2018），备注「E843」。&lt;/p&gt;
&lt;p&gt;&lt;img alt="扫码加入 E843" src="https://fastly.jsdelivr.net/gh/hillerliao/img@main/wechat_cbnn_qrcode.jpg"&gt;&lt;/p&gt;</content><category term="blog"></category><category term="小工具"></category></entry><entry><title>每周五天英语学习法</title><link href="https://hillerliao.github.io/mei-zhou-wu-tian-ying-yu-xue-xi-fa.html" rel="alternate"></link><published>2022-10-30T13:51:57+08:00</published><updated>2022-10-30T13:51:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2022-10-30:/mei-zhou-wu-tian-ying-yu-xue-xi-fa.html</id><summary type="html">&lt;p&gt;最近在油管看到一个介绍英语学习方法的视频「 &lt;a href="https://www.bilibili.com/video/BV1QJ411J7UG/"&gt;The Best Way To Learn English (In my humble opinion.)&lt;/a&gt;&lt;br&gt;
」，播放量达到140多万次，讲得挺好，本文将其精华内容作个 …&lt;/p&gt;</summary><content type="html">&lt;p&gt;最近在油管看到一个介绍英语学习方法的视频「 &lt;a href="https://www.bilibili.com/video/BV1QJ411J7UG/"&gt;The Best Way To Learn English (In my humble opinion.)&lt;/a&gt;&lt;br&gt;
」，播放量达到140多万次，讲得挺好，本文将其精华内容作个整理。  &lt;/p&gt;
&lt;p&gt;作者是来自加拿大的英语老师Bob，也学过法语。Bob基于自己的教学经验与学习经历，总结出这份英语学习计划。  &lt;/p&gt;
&lt;p&gt;Bob 建议，学习者每周应该关注五个领域，星期一专注于阅读，星期二专注于写作，星期三专注于听力，星期四专注于口语，周五专注于词汇积累。当然，这并不是说每天将整个学习时间都花在一件事上，但每天需要有所侧重。  &lt;/p&gt;
&lt;p&gt;下面是Bob给出的具体学习计划：  &lt;/p&gt;
&lt;p&gt;你需要的东西： &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每天1小时（30分钟也可以）。  &lt;/li&gt;
&lt;li&gt;一个笔记本和一支笔，每天写下新的词汇。  &lt;/li&gt;
&lt;li&gt;一首英文歌曲。  &lt;/li&gt;
&lt;li&gt;一本英文书。  &lt;/li&gt;
&lt;li&gt;英语电视节目。  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;周一（花30-40分钟阅读）  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看书。  &lt;/li&gt;
&lt;li&gt;看新闻。  &lt;/li&gt;
&lt;li&gt;阅读 &lt;a href="http://simple.wikipedia.com"&gt;wikipedia simple版&lt;/a&gt;中的文章。    &lt;/li&gt;
&lt;li&gt;在笔记本上写下一些新单词及其定义。  &lt;/li&gt;
&lt;li&gt;花剩下的时间：  &lt;ul&gt;
&lt;li&gt;大声朗读你的书。  &lt;/li&gt;
&lt;li&gt;写出书中的一些段落。  &lt;/li&gt;
&lt;li&gt;听你书的有声读物。  &lt;/li&gt;
&lt;li&gt;使用Duolingo或其他学习应用程序。  &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;周二（花30-40分钟写作）  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在笔记本上写下你昨天、今天和明天所做的事情。  &lt;/li&gt;
&lt;li&gt;在YouTube视频上写一些评论。  &lt;/li&gt;
&lt;li&gt;写一些关于你喜欢和不喜欢你的歌曲、你的书和电视节目的句子。  &lt;/li&gt;
&lt;li&gt;写下你前一天在书中读到的内容的摘要。  &lt;/li&gt;
&lt;li&gt;在你的字典里放一些新单词。  &lt;/li&gt;
&lt;li&gt;花剩下的时间：  &lt;ul&gt;
&lt;li&gt;读你写的东西。  &lt;/li&gt;
&lt;li&gt;将你的东西粘贴到谷歌翻译中，利用其发音功能播放出来。  &lt;/li&gt;
&lt;li&gt;大声朗读你写的东西。  &lt;/li&gt;
&lt;li&gt;使用Duolingo或其他学习应用程序。  &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;周三（花30-40分钟听）：  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看电视节目。  &lt;/li&gt;
&lt;li&gt;听歌。  &lt;/li&gt;
&lt;li&gt;听你所选图书的有声版本。  &lt;/li&gt;
&lt;li&gt;观看一些YouTube视频。  &lt;/li&gt;
&lt;li&gt;在你的字典里输入新单词。  &lt;/li&gt;
&lt;li&gt;花剩下的时间：  &lt;ul&gt;
&lt;li&gt;阅读电视节目的内容。  &lt;/li&gt;
&lt;li&gt;写下所听歌曲给你的感觉。  &lt;/li&gt;
&lt;li&gt;影子跟读或跟读电视节目中的人物。  &lt;/li&gt;
&lt;li&gt;跟着你的歌唱。  &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;周四（花30-40分钟说）：  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;聘请导师，可借助这些平台：  &lt;ul&gt;
&lt;li&gt;Preply：http://tracking.preply.com/SH2X    &lt;/li&gt;
&lt;li&gt;Cambly：http://cambly.com    &lt;/li&gt;
&lt;li&gt;iTalki：http://italki.com  &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;大声说话。  &lt;/li&gt;
&lt;li&gt;叙述你的生活。  &lt;/li&gt;
&lt;li&gt;录制自己的叙述并播放。  &lt;/li&gt;
&lt;li&gt;把单词放在你的字典里。  &lt;/li&gt;
&lt;li&gt;花剩下的时间：  &lt;ul&gt;
&lt;li&gt;大声朗读。  &lt;/li&gt;
&lt;li&gt;大声唱歌。  &lt;/li&gt;
&lt;li&gt;影子跟读或模仿电视节目中的演员。  &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;周五（花整整一个小时在词汇上）：  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看字典中的所有单词。  &lt;/li&gt;
&lt;li&gt;把它们写出来。  &lt;/li&gt;
&lt;li&gt;大声说出来。  &lt;/li&gt;
&lt;li&gt;在句子中使用它们。  &lt;/li&gt;
&lt;li&gt;制作一个&lt;a href="http://quizlet.com"&gt;Quizlet&lt;/a&gt;卡片集合。  &lt;/li&gt;
&lt;li&gt;制作抽认卡。  &lt;/li&gt;
&lt;li&gt;努力学习，直到你把它们都记住了。  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;周末：  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查找新歌。  &lt;/li&gt;
&lt;li&gt;找一本新书。  &lt;/li&gt;
&lt;li&gt;查找新的电视节目。  &lt;/li&gt;
&lt;li&gt;休息一下。  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;⌛ 请记住：视频观看三遍，节奏为：今天两次打开英文字幕，明天一次关闭英文字幕，以强化你学到的英语。  &lt;/p&gt;
&lt;p&gt;以上就是 Bob 分享的英语学习计划。其实没有什么特别之处，重要的是能坚持实施。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>阿里云函数版 RSS 过滤器上线</title><link href="https://hillerliao.github.io/rssfilter-on-aliyun-cf.html" rel="alternate"></link><published>2022-09-18T10:57:57+08:00</published><updated>2022-09-18T10:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2022-09-18:/rssfilter-on-aliyun-cf.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;产品体验
categories:&lt;/li&gt;
&lt;li&gt;产品体验&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;为方便薅阿里云函数计算的羊毛，将 &lt;a href="https://github.com/hillerliao/RSSHub-python"&gt;RSSHub-Python&lt;/a&gt; 项目里的 &lt;a href="https://pyrsshub.vercel.app/feeds"&gt;RSS 过滤器&lt;/a&gt;功能独立出来，做成阿里云函数计算的版 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;产品体验
categories:&lt;/li&gt;
&lt;li&gt;产品体验&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;为方便薅阿里云函数计算的羊毛，将 &lt;a href="https://github.com/hillerliao/RSSHub-python"&gt;RSSHub-Python&lt;/a&gt; 项目里的 &lt;a href="https://pyrsshub.vercel.app/feeds"&gt;RSS 过滤器&lt;/a&gt;功能独立出来，做成阿里云函数计算的版本。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;code&gt;https://github.com/hillerliao/RssFilter&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;部署方法记录如下：&lt;/p&gt;
&lt;h2&gt;一、创建服务&lt;/h2&gt;
&lt;p&gt;1、进入&lt;a href="https://fcnext.console.aliyun.com/overview"&gt;阿里云函数计算&lt;/a&gt;后台，点击创建服务。&lt;/p&gt;
&lt;p&gt;&lt;img alt="阿里云函数计算概览" src="https://github.com/easychen/wecomchan/raw/main/python-aliyunfc/pic/image-20220205142747826.png"&gt;&lt;/p&gt;
&lt;p&gt;2、填入服务名称，比如 &lt;code&gt;RssFilter&lt;/code&gt;，点击确定。&lt;/p&gt;
&lt;p&gt;&lt;img alt="阿里云函数计算-创建服务" src="https://raw.githubusercontent.com/hillerliao/img/main/20220918133712.png"&gt;&lt;/p&gt;
&lt;h2&gt;二、配置函数&lt;/h2&gt;
&lt;p&gt;3、配置函数。&lt;/p&gt;
&lt;p&gt;3.1 进入刚创建的服务，点击&lt;code&gt;创建函数&lt;/code&gt;；&lt;br&gt;
3.2 选择&lt;code&gt;使用自定义运行时创建&lt;/code&gt;，填写函数名称，如&lt;code&gt;main&lt;/code&gt;；&lt;br&gt;
3.3 代码上传方式选择&lt;code&gt;通过 ZIP 包上传代码&lt;/code&gt;，将本项目仓库中的&lt;a href="https://github.com/hillerliao/RssFilter/blob/main/func-code-4-RSSFilter.zip"&gt;过滤器zip代码包&lt;/a&gt;&lt;code&gt;func-code-4-RSSFilter.zip&lt;/code&gt;下载后上传；&lt;br&gt;
3.4 启动命令填入&lt;code&gt;python app.py&lt;/code&gt;；  &lt;/p&gt;
&lt;p&gt;点击 &lt;code&gt;创建&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img alt="阿里云函数计算-配置函数" src="https://raw.githubusercontent.com/hillerliao/img/main/20220918134114.png"&gt;&lt;/p&gt;
&lt;h2&gt;三、获取地址&lt;/h2&gt;
&lt;p&gt;4、获得测试地址，带上路径和参数，如 &lt;code&gt;/filter?feed=&amp;lt;rss 地址&amp;gt;&amp;amp;include_title=&amp;lt;过滤词&amp;gt;&lt;/code&gt; 支持的参数同 RSSHub-Python 的 &lt;a href="https://pyrsshub.vercel.app/feeds"&gt;RSS Filter参数&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="阿里云函数计算-获取函数公网地址" src="https://raw.githubusercontent.com/hillerliao/img/main/20220918134337.png"&gt;&lt;/p&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;http://&amp;lt;testing sub domain for fc&amp;gt;.cn-beijing.functioncompute.com/filter?feed=https://sspai.com/feed&amp;amp;include_title=派评&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;5、测试验证通过后，点击 &lt;code&gt;部署代码&lt;/code&gt;，部署完成。&lt;/p&gt;
&lt;p&gt;&lt;img alt="阿里云函数计算-在线编辑器" src="https://raw.githubusercontent.com/hillerliao/img/main/20220918134819.png"&gt;&lt;/p&gt;
&lt;h2&gt;四、制作 RSS 过滤器的初衷&lt;/h2&gt;
&lt;p&gt;回顾我作 RSS 过滤器的初心：提高信息获取效率。&lt;/p&gt;
&lt;p&gt;比如，有些 RSS，我只关心带有特定关键词的内容；另一些 RSS，我不想看到含有特定关键词的广告内容。有了 RSS 过滤器，这些需求都能得到满足。&lt;/p&gt;
&lt;p&gt;好了，如果你觉得本项目对你有用，不妨请我喝杯咖啡。&lt;/p&gt;
&lt;p&gt;&lt;img alt="个人微信收款码-智海" src="https://raw.githubusercontent.com/hillerliao/img/main/IMG_0096%20copy.jpg"&gt;&lt;/p&gt;
&lt;p&gt;如果有改进建议，欢迎交流。微信： &lt;code&gt;hillerliao&lt;/code&gt;。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>如何训练你的大脑用英语思考</title><link href="https://hillerliao.github.io/how-to-practice-thinking-in-english.html" rel="alternate"></link><published>2022-08-16T08:36:53+08:00</published><updated>2022-08-16T08:36:53+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2022-08-16:/how-to-practice-thinking-in-english.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;学外语
categories:&lt;/li&gt;
&lt;li&gt;学外语&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;如果有条件，你从小跟着父母从中国去了美国，可以每天使用英语几小时，英语可能已成为你“内心语言”的 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;学外语
categories:&lt;/li&gt;
&lt;li&gt;学外语&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;如果有条件，你从小跟着父母从中国去了美国，可以每天使用英语几小时，英语可能已成为你“内心语言”的一部分。换句话说，你开始用英语思考。你的大脑不再试图将汉语翻译成英语。
但是，大多数中国人在日常生活中可能没有很多机会练习英语，甚至可能只是在自学。当你开口说话时，你说的可能比你想要的慢。这是因为你的大脑仍然在从你的第一语言进行翻译，这听起来也很不自然。毕竟，英语和其他语言一样，有自己的句子结构。
有什么办法让你更接近流利的水平？这里推荐一个方法：用英语思考。
这并不难，但确实需要有意识的努力和实践，下面是一些有帮助的“心理练习”。&lt;/p&gt;
&lt;h2&gt;用一个词思考&lt;/h2&gt;
&lt;p&gt;大多数专家指出，最好从小事做起。因此，用单个词来思考不失为好的开始。环顾四周，你看到了什么？在你的脑海中，试着说出你周围的每个物体的名字。
说出他们周围看到的东西的名字，无论他们身在何处。当它成为一种习惯后，东西会突然出现在你的脑海里——电脑、电话、椅子、桌子。不管它是什么。
建议先从名词开始，然后再添加动词。
你也可以在家里醒来和睡觉前这样做。
如果你是学生给房间或公寓里的所有东西都贴上标签，这样，这些英语单词就可以在你的的脑海中留下印象。&lt;/p&gt;
&lt;h2&gt;描述生词&lt;/h2&gt;
&lt;p&gt;另一个练习是在你的头脑中描述你不知道该用什么词的物体。
举个例子，如果你在看你的房子，看到你的车库，但你想不起“车库”的英文名字，你可以说，“我把车放在里面的地方。” 或者你可以说，“它在我家旁边。我把东西放在那里。'”
你也可以使用较短的短语，如“它类似于…”或“它与…相反”。
这样做可以帮助任何语言的学习者。&lt;/p&gt;
&lt;h2&gt;用句子思考&lt;/h2&gt;
&lt;p&gt;下一个练习是用简单的句子思考。
例如，如果你坐在公园里，你可以告诉自己这样的事情：“今天天气真好”和“人们正在和朋友一起运动。”
一旦这变得容易，你就可以继续学习更难的句子。
你可以用这个练习来思考你想用英语对人们说什么：你在脑海中说出这些句子，或者尝试将这些单词组合在一起，不用过多考虑这些句子是否绝对正确。&lt;/p&gt;
&lt;h2&gt;描述你的一天&lt;/h2&gt;
&lt;p&gt;专家建议的另一项练习是描述你的日常活动。有几种方法可以做到这一点。
早上醒来时，你可以在脑子里制定计划。这需要其他动词时态，所以技能水平要高一点。
例如，你可能会告诉自己，“当我离开家的时候，我要喝杯冰咖啡。然后，我要坐火车去上课。我今天和阿峰一起学习。他说他在图书馆预订了一个下午2点的自习室。”&lt;/p&gt;
&lt;h2&gt;对话思考&lt;/h2&gt;
&lt;p&gt;现在，让我们转到对话思考：想象自己在和别人说话。你在问问题，并思考答案。
这个方法能很好地练习你在真实对话中可能说的话。
假设一个想象中的人问你这样的问题，“你觉得昨晚的颁奖典礼怎么样？”你会怎么回答？想象这个对话，并在脑海中练习。
你可以大声说出来，也可以保持沉默。&lt;/p&gt;
&lt;h2&gt;记笔记&lt;/h2&gt;
&lt;p&gt;对于所有这些练习，当然会有你不知道的单词和短语。所以，在某个时候你需要使用字典。
如果你的技能水平足够高，你可以考虑使用英译英词典。
建议每天只写下5到10个新词和短语。
记笔记可以帮助你记住你需要那个词或短语来表达的情况。当你再次处于这种情况时，这使你很容易回忆起来。&lt;/p&gt;
&lt;h2&gt;每天练习&lt;/h2&gt;
&lt;p&gt;那么，你应该花多少时间在这些练习上？每天做一点。
当你每天都这样做时，一遍又一遍，一点一点地做，这就是&lt;strong&gt;关键&lt;/strong&gt;。
当你把事情变成一种习惯时，它会突然出现在你的脑海中，而在你意识到之前，实际上，你是在用英语思考。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>Vercel 环境无法正常请求带中文字符URL的问题排查</title><link href="https://hillerliao.github.io/fix-chinese-characters-included-url-bug-in-vercel.html" rel="alternate"></link><published>2022-08-11T21:12:57+08:00</published><updated>2022-08-11T21:12:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2022-08-11:/fix-chinese-characters-included-url-bug-in-vercel.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;运维
categories:&lt;/li&gt;
&lt;li&gt;运维&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;问题描述&lt;/h2&gt;
&lt;p&gt;利用 &lt;a href="https://github.com/hillerliao/RSSHub-python"&gt;RSSHub-python&lt;/a&gt; 项目抓取&lt;a href="https://www.aisixiang.com/"&gt;爱思想&lt;/a&gt;网站搜索结果列表生成 RSS 时，在 &lt;a href="https://vercel.com/"&gt;Vercel&lt;/a&gt; 环境下，关键词为英文时一切正常，关键词 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;运维
categories:&lt;/li&gt;
&lt;li&gt;运维&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;问题描述&lt;/h2&gt;
&lt;p&gt;利用 &lt;a href="https://github.com/hillerliao/RSSHub-python"&gt;RSSHub-python&lt;/a&gt; 项目抓取&lt;a href="https://www.aisixiang.com/"&gt;爱思想&lt;/a&gt;网站搜索结果列表生成 RSS 时，在 &lt;a href="https://vercel.com/"&gt;Vercel&lt;/a&gt; 环境下，关键词为英文时一切正常，关键词为中文时无法获取到结果。&lt;/p&gt;
&lt;h2&gt;问题分析&lt;/h2&gt;
&lt;p&gt;根据第一版程序，请求&lt;code&gt;https://pyrsshub.vercel.app/aisixiang/search/author/%E9%83%91%E6%B0%B8%E5%B9%B4&lt;/code&gt;得到的HTML 源码&lt;code&gt;&amp;lt;title&amp;gt;&amp;lt;![CDATA[%E9%83%91%E6%B0%B8%E5%B9%B4 - author搜索 - 爱思想]]&amp;gt;&amp;lt;/title&amp;gt;&lt;/code&gt;可以看出，RSS 地址中的中文字符在 HTML 源码没有正常显示，还是 urlencode之后的状态。
第一版本&lt;a href="https://github.com/hillerliao/RSSHub-python/commit/cfcb04afa116941292a1bddab03cfbad4fde59da"&gt;程序&lt;/a&gt;通过以下代码直接将URL 中的中文字符转换为为GBK编码的字符。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;
&lt;span class="n"&gt;keywords_gbk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gbk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;然后将上述转换后的字符拼成目标网站的 URL 供爬虫发送请求之用。
程序在本地、docker 上运行，都没有问题，但在 vercel.app 环境中不灵。
具体原因没搞懂，也不方便调试。结论就是： vercel.app 的环境不支持 urlencode 过的字符串直接urlencode为 gbk 字符串，需要先解码再编码。&lt;/p&gt;
&lt;h2&gt;查找方案&lt;/h2&gt;
&lt;p&gt;先解码再编码的解决方案：
&lt;code&gt;rss 地址中的中文字符 → urldecode 为 utf-8字符 → urlencode 为 gbk 字符&lt;/code&gt;
增加中间这一步，兼容 vercel.app 环境。
&lt;strong&gt;编码&lt;/strong&gt;：一般来说，URL只能使用英文字母、阿拉伯数字和某些标点符号，不能使用其他文字和符号。如果URL中有汉字，就必须编码（&lt;code&gt;urlencode&lt;/code&gt;）后使用。这一步由浏览器完成。
&lt;strong&gt;解码&lt;/strong&gt;：当urlencode之后的字符串传递到后端之后，Flask 响应函数需要进行解码（&lt;code&gt;urldecode&lt;/code&gt;），可以用 Python 库&lt;code&gt;urllib.parse&lt;/code&gt; 的&lt;code&gt;unquote&lt;/code&gt;函数进行解码。
&lt;strong&gt;编码&lt;/strong&gt;：接着，将解码后的字符，按照目标网站指定的字符集进行编码（&lt;code&gt;urlencode&lt;/code&gt;），可以用&lt;code&gt;quote&lt;/code&gt;方法实现。
具体到爱思想搜索结果列表页，为什么确定用的是gbk 字符来编码？&lt;code&gt;https://www.aisixiang.com/data/search.php?keyWords=%D1%D6%D1%A7%CD%A8&amp;amp;searchfield=author&lt;/code&gt; 属于其他页面搜索框的 Get 方法触发的请求，URL包含汉字，这时的URL编码方法由网页的编码决定，也就是由HTML源码中字符集的设定决定。 查看 HTML 源码 &lt;code&gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=gbk" /&amp;gt;&lt;/code&gt;得知，所发请求必须是GBK 编码的 URL。
&lt;a href="https://github.com/hillerliao/RSSHub-python/commit/53e055637a85191cf88987740eeedb7bdb8204af"&gt;最终程序&lt;/a&gt;修改为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unquote&lt;/span&gt;
&lt;span class="n"&gt;keywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 或者用 gbk 字符集解码&lt;/span&gt;
&lt;span class="n"&gt;keywords_gbk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gbk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;以字符&lt;code&gt;郑永年&lt;/code&gt;为例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unquote&lt;/span&gt;

&lt;span class="n"&gt;str_urlencoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%E&lt;/span&gt;&lt;span class="s1"&gt;9&lt;/span&gt;&lt;span class="si"&gt;%83%&lt;/span&gt;&lt;span class="s1"&gt;91&lt;/span&gt;&lt;span class="si"&gt;%E&lt;/span&gt;&lt;span class="s1"&gt;6%B0%B8&lt;/span&gt;&lt;span class="si"&gt;%E&lt;/span&gt;&lt;span class="s1"&gt;5%B9%B4&amp;#39;&lt;/span&gt; 
&lt;span class="n"&gt;str_utf8_decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_urlencoded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;str_gbk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_utf8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gbk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;str_gbk2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_urlencoded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gbk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;按 utf8 解码结果：&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;str_utf8_decoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;按 gbk 编码结果：&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;str_gbk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;urlencoded字符直接按gbk编码结果：&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;str_gbk2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;运行结果：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;按&lt;/span&gt; &lt;span class="n"&gt;utf8&lt;/span&gt; &lt;span class="n"&gt;解码结果&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt; &lt;span class="n"&gt;郑永年&lt;/span&gt;
&lt;span class="n"&gt;按&lt;/span&gt; &lt;span class="n"&gt;gbk&lt;/span&gt; &lt;span class="n"&gt;编码结果&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;D6&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;A3&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;D3&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;C0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;C4&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;EA&lt;/span&gt;  &lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="n"&gt;此为需要的结果&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;
&lt;span class="n"&gt;urlencoded&lt;/span&gt; &lt;span class="n"&gt;字符直接按gbk编码结果&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;25E9&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2583&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2591&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;25E6&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="n"&gt;B0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="n"&gt;B8&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;25E5&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="n"&gt;B9&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="n"&gt;B4&lt;/span&gt; &lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="n"&gt;vercel&lt;/span&gt; &lt;span class="n"&gt;环境出错的结果&lt;/span&gt;&lt;span class="err"&gt;）&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;后续工作&lt;/h2&gt;
&lt;p&gt;需要再次研究Vercel环境下怎么调试的问题，提高问题排查效率。&lt;/p&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ruanyifeng.com/blog/2010/02/url_encoding.html"&gt;关于URL编码 - 阮一峰的网络日志&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.csdn.net/a359680405/article/details/44857359"&gt;Python菜鸟晋级11----urlencode与unquote_翻滚吧挨踢男的博客-CSDN博客&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>Termux 环境下 frpc 和 OpenClaw 服务保活方案</title><link href="https://hillerliao.github.io/termux-frpc-openclaw-service-survival.html" rel="alternate"></link><published>2022-05-10T16:00:00+08:00</published><updated>2022-05-10T16:00:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2022-05-10:/termux-frpc-openclaw-service-survival.html</id><summary type="html">&lt;h2&gt;背景与痛点&lt;/h2&gt;
&lt;h3&gt;问题场景&lt;/h3&gt;
&lt;p&gt;在 Android 设备上运行 frpc（内网穿透客户端）和 OpenClaw 时，面临以下挑战：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;手机重启后服务不自动启动&lt;/strong&gt;&lt;br&gt;
   Android 系统不会 …&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;h2&gt;背景与痛点&lt;/h2&gt;
&lt;h3&gt;问题场景&lt;/h3&gt;
&lt;p&gt;在 Android 设备上运行 frpc（内网穿透客户端）和 OpenClaw 时，面临以下挑战：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;手机重启后服务不自动启动&lt;/strong&gt;&lt;br&gt;
   Android 系统不会自动运行 Termux 中的后台服务&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;进程崩溃后不会重启&lt;/strong&gt;&lt;br&gt;
   frpc 或 OpenClaw 可能因网络波动、内存不足等原因崩溃，需要手动介入&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;无法方便地查看日志&lt;/strong&gt;&lt;br&gt;
   后台运行的进程没有会话管理，调试困难&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;需求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;✅ 手机开机后 frpc + OpenClaw 自动启动&lt;/li&gt;
&lt;li&gt;✅ 进程崩溃后自动检测并重启&lt;/li&gt;
&lt;li&gt;✅ 方便查看运行日志&lt;/li&gt;
&lt;li&gt;✅ 低资源占用（不频繁检测）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;方案概述&lt;/h2&gt;
&lt;p&gt;利用 Termux 生态中的三个工具组合：&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;termux:boot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开机时自动执行脚本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;termux-wake-lock&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;防止系统休眠杀死进程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tmux&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;会话管理（保持进程运行、方便查看日志）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;cron&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;定时任务（每5分钟检测进程存活）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;架构图&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                        Android 系统                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                  Termux 环境                         │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌──────────────┐ │   │
│  │  │ termux:boot │→ │ frpc-start │→ │ frpc        │ │   │
│  │  │ (开机执行)   │→ │ (wake lock) │  │ openclaw    │ │   │
│  │  └─────────────┘  └─────────────┘  └──────────────┘ │   │
│  │                                                  │     │   │
│  │  ┌─────────────┐  ┌────────────────────────────┐  │     │   │
│  │  │    cron     │→ │ monitor.sh (每5分钟执行)   │  │     │   │
│  │  │ (定时检测)   │  │ 检测进程是否存在 → 重启    │  │     │   │
│  │  └─────────────┘  └────────────────────────────┘  │     │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;依赖安装&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 安装 tmux（会话管理）&lt;/span&gt;
pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;tmux

&lt;span class="c1"&gt;# 安装 cron（定时任务）&lt;/span&gt;
pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;crontab

&lt;span class="c1"&gt;# 安装 termux:boot（开机自启）&lt;/span&gt;
pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;termux-boot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;termux:boot 安装后需要在 Android 设置中授权自启动权限&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;⚠️ 关键经验教训&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;termux:boot 只在开机时执行一次&lt;/strong&gt;，杀进程后不会自动重启&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;boot 脚本不能用环境变量&lt;/strong&gt;，必须硬编码 token 和 port&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;crond 必须加入 boot 脚本&lt;/strong&gt;，否则进程监控不生效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;monitor.sh 用绝对路径&lt;/strong&gt;，cron 环境下 $PREFIX 不生效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;frpc 用 exec 启动&lt;/strong&gt;，确保 wake lock 正确持有，防止休眠被杀死&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;monitor.sh 添加日志&lt;/strong&gt;，便于追踪重启历史和调试&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/monitor.log
log&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;脚本内容&lt;/h2&gt;
&lt;h3&gt;1. OpenClaw 启动脚本 (&lt;code&gt;~/openclaw-run.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;负责清理旧进程、重新启动 OpenClaw：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;# OpenClaw 启动脚本&lt;/span&gt;

&lt;span class="c1"&gt;# 杀掉旧进程&lt;/span&gt;
pkill&lt;span class="w"&gt; &lt;/span&gt;-9&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;openclaw&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null

&lt;span class="c1"&gt;# 等待资源释放&lt;/span&gt;
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# 创建新 tmux 会话&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;openclaw

&lt;span class="c1"&gt;# 等待会话就绪&lt;/span&gt;
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# 发送启动命令到 tmux 会话&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;send-keys&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;export PATH=&lt;/span&gt;&lt;span class="nv"&gt;$NPM_BIN&lt;/span&gt;&lt;span class="s2"&gt;:\$PATH TMPDIR=\$HOME/tmp; export OPENCLAW_GATEWAY_TOKEN=&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;; openclaw gateway --bind lan --port &lt;/span&gt;&lt;span class="nv"&gt;$PORT&lt;/span&gt;&lt;span class="s2"&gt; --token \$OPENCLAW_GATEWAY_TOKEN --allow-unconfigured&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;C-m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;2. 开机启动脚本 (&lt;code&gt;~/.termux/boot/services.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;手机开机时自动启动 crond、frpc 和 OpenClaw：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;# termux:boot services - 开机会话启动&lt;/span&gt;

&lt;span class="c1"&gt;# 启动 crond（关键）&lt;/span&gt;
crond

&lt;span class="c1"&gt;# 启动 frpc（使用独立脚本，包含 wake lock）&lt;/span&gt;
bash&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot/frpc-start.sh&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;

&lt;span class="c1"&gt;# 清理旧 OpenClaw 进程后启动&lt;/span&gt;
pkill&lt;span class="w"&gt; &lt;/span&gt;-9&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;openclaw&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;openclaw
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="c1"&gt;# 注意：这里必须用硬编码的参数，不能用环境变量&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;send-keys&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;export PATH=/data/data/com.termux/files/home/.npm-global/bin:\$PATH TMPDIR=\$HOME/tmp; export OPENCLAW_GATEWAY_TOKEN=tokenac27a3d5; openclaw gateway --bind lan --port 18789 --token \$OPENCLAW_GATEWAY_TOKEN --allow-unconfigured&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;C-m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;3. frpc 启动脚本 (&lt;code&gt;~/.termux/boot/frpc-start.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;负责启动 frpc 并持有 wake lock，防止系统休眠导致进程被杀死：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
termux-wake-lock
/data/data/com.termux/files/usr/bin/frpc&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;/data/data/com.termux/files/usr/etc/frp/frpc.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;4. 进程监控脚本 (&lt;code&gt;~/monitor.sh&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;每5分钟检测一次，崩溃则重启：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;# 进程监控脚本 - 每5分钟检测并重启崩溃的服务&lt;/span&gt;

&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/monitor.log
&lt;span class="nv"&gt;MAX_LOG_LINES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# 日志最大行数&lt;/span&gt;

log&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;+%Y-%m-%d %H:%M:%S&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

trim_log&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# 保留最后 MAX_LOG_LINES 行&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;lines&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;wc&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$lines&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-gt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$MAX_LOG_LINES&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$MAX_LOG_LINES&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;.tmp&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mv&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;.tmp&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;========== Monitor started ==========&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# frpc 检测&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;pgrep&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc 进程不存在，准备重启...&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
&lt;span class="w"&gt;    &lt;/span&gt;sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# 用 exec 确保 wake lock 正确持有&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;new-session&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exec /data/data/com.termux/files/usr/bin/frpc -c /data/data/com.termux/files/usr/etc/frp/frpc.ini&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc 重启命令已发送&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc 运行正常&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c1"&gt;# OpenClaw 检测&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;pgrep&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;openclaw.*gateway&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OpenClaw 进程不存在，准备重启...&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
&lt;span class="w"&gt;    &lt;/span&gt;sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# 等待端口释放&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;bash&lt;span class="w"&gt; &lt;/span&gt;~/openclaw-run.sh
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OpenClaw 重启命令已发送&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OpenClaw 运行正常&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c1"&gt;# 清理日志&lt;/span&gt;
trim_log

log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;========== Monitor finished ==========&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;操作步骤&lt;/h2&gt;
&lt;h3&gt;第一步：安装依赖&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pkg&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pkg&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;termux-api
crond
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;第二步：创建脚本文件&lt;/h3&gt;
&lt;h4&gt;创建目录&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;创建 &lt;code&gt;~/openclaw-run.sh&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;（将下方内容写入文件，&lt;strong&gt;注意：参数必须硬编码&lt;/strong&gt;）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;# OpenClaw 启动脚本 - 硬编码参数&lt;/span&gt;

&lt;span class="c1"&gt;# 杀掉旧进程&lt;/span&gt;
pkill&lt;span class="w"&gt; &lt;/span&gt;-9&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;openclaw&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null

&lt;span class="c1"&gt;# 等待资源释放（增加等待时间）&lt;/span&gt;
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;

&lt;span class="c1"&gt;# 创建新 tmux 会话&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;openclaw

&lt;span class="c1"&gt;# 等待会话就绪&lt;/span&gt;
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# 发送启动命令（硬编码所有参数）&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;send-keys&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;export PATH=/data/data/com.termux/files/home/.npm-global/bin:\$PATH TMPDIR=\$HOME/tmp; export OPENCLAW_GATEWAY_TOKEN=tokenac27a3d5; openclaw gateway --bind lan --port 18789 --token \$OPENCLAW_GATEWAY_TOKEN --allow-unconfigured&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;C-m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;创建 &lt;code&gt;~/.termux/boot/services.sh&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;（将下方内容写入文件，&lt;strong&gt;注意：参数必须硬编码&lt;/strong&gt;）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;# termux:boot services - 开机会话启动&lt;/span&gt;

&lt;span class="c1"&gt;# 1. 清理旧会话&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# 2. 启动 crond（关键）&lt;/span&gt;
crond

&lt;span class="c1"&gt;# 3. 启动 frpc（持有 wake lock）&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new-session&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exec /data/data/com.termux/files/usr/bin/frpc -c /data/data/com.termux/files/usr/etc/frp/frpc.ini&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 4. 启动 OpenClaw&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;openclaw
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;send-keys&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;export PATH=/data/data/com.termux/files/home/.npm-global/bin:\$PATH TMPDIR=\$HOME/tmp; export OPENCLAW_GATEWAY_TOKEN=tokenac27a3d5; openclaw gateway --bind lan --port 18789 --token \$OPENCLAW_GATEWAY_TOKEN --allow-unconfigured&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;C-m

log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Services started at &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;~/boot.log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;创建 &lt;code&gt;~/.termux/boot/frpc-start.sh&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;（将下方内容写入文件，包含 wake lock 防止休眠）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
termux-wake-lock
/data/data/com.termux/files/usr/bin/frpc&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;/data/data/com.termux/files/usr/etc/frp/frpc.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;创建 &lt;code&gt;~/monitor.sh&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;（将下方内容写入文件，&lt;strong&gt;注意：用 tmux 管理 frpc&lt;/strong&gt;）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/data/data/com.termux/files/usr/bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;# frpc 检测&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;pgrep&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;new-session&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;frpc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;frpc -c /data/data/com.termux/files/usr/etc/frp/frpc.ini&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c1"&gt;# OpenClaw 检测&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;pgrep&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;openclaw.*gateway&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null
&lt;span class="w"&gt;    &lt;/span&gt;bash&lt;span class="w"&gt; &lt;/span&gt;~/openclaw-run.sh
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;第三步：设置权限&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot/services.sh&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot/frpc-start.sh&lt;span class="w"&gt; &lt;/span&gt;~/openclaw-run.sh&lt;span class="w"&gt; &lt;/span&gt;~/monitor.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;第四步：配置 cron&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 编辑 crontab&lt;/span&gt;
crontab&lt;span class="w"&gt; &lt;/span&gt;-e

&lt;span class="c1"&gt;# 添加以下内容（每5分钟检测一次）&lt;/span&gt;
*/5&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;*&lt;span class="w"&gt; &lt;/span&gt;/data/data/com.termux/files/home/monitor.sh

&lt;span class="c1"&gt;# 保存退出后，启动 cron 服务（这一步也可以放到 boot 脚本里自动执行）&lt;/span&gt;
crond
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;第五步：测试&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 手动启动 boot 脚本测试&lt;/span&gt;
bash&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot/services.sh

&lt;span class="c1"&gt;# 查看 tmux 会话&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;ls

&lt;span class="c1"&gt;# 查看进程是否运行&lt;/span&gt;
ps&lt;span class="w"&gt; &lt;/span&gt;aux&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-E&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;crond|frpc|openclaw&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;grep

&lt;span class="c1"&gt;# 查看 crond 是否运行（验证 boot 脚本是否成功执行）&lt;/span&gt;
ps&lt;span class="w"&gt; &lt;/span&gt;aux&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;crond&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;grep

&lt;span class="c1"&gt;# 手动测试检测脚本&lt;/span&gt;
bash&lt;span class="w"&gt; &lt;/span&gt;~/monitor.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;第六步：验证开机自启动&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 重启手机，验证以下进程是否自动启动：&lt;/span&gt;
&lt;span class="c1"&gt;# 1. crond - 进程监控依赖它&lt;/span&gt;
&lt;span class="c1"&gt;# 2. frpc - 内网穿透&lt;/span&gt;
&lt;span class="c1"&gt;# 3. OpenClaw - 主服务&lt;/span&gt;

ps&lt;span class="w"&gt; &lt;/span&gt;aux&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-E&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;crond|frpc|openclaw&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;grep
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;常用命令&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;查看 tmux 会话&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux ls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看 frpc 日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux attach -t frpc&lt;/code&gt;（Ctrl+B 然后 D 退出）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看 OpenClaw 日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux attach -t openclaw&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;强制退出日志视图&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+B 然后 D&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;杀掉 tmux 会话&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux kill-session -t frpc/openclaw&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;手动执行检测&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bash /data/data/com.termux/files/home/monitor.sh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看监控日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail -f ~/monitor.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看启动日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail -f ~/boot.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查看 cron 日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;logcat -s crond&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;常见问题&lt;/h2&gt;
&lt;h3&gt;Q1: 检测频率会影响电池吗？&lt;/h3&gt;
&lt;p&gt;不会。&lt;code&gt;pgrep&lt;/code&gt; 进程检查是非常轻量的系统调用，比手机待机功耗低几个数量级。每5分钟一次完全可接受。&lt;/p&gt;
&lt;h3&gt;Q2: 为什么用 tmux 而不是 nohup？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;tmux 可以方便地查看实时日志&lt;/li&gt;
&lt;li&gt;tmux 保持会话不中断&lt;/li&gt;
&lt;li&gt;可以随时手动连接查看状态&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Q3: termux:boot 没生效？&lt;/h3&gt;
&lt;p&gt;检查：
1. Android 设置中允许 Termux 自启动
2. 脚本权限正确（&lt;code&gt;chmod +x&lt;/code&gt;）
3. &lt;strong&gt;boot 脚本里用了硬编码的路径和参数？&lt;/strong&gt;
4. 重启手机测试，不只是重启 Termux app&lt;/p&gt;
&lt;h3&gt;Q4: 手机重启后 frpc/OpenClaw 没启动？&lt;/h3&gt;
&lt;p&gt;可能原因：
1. &lt;strong&gt;crond 没在 boot 脚本里启动&lt;/strong&gt; → monitor.sh 不会运行
2. &lt;strong&gt;boot 脚本用了环境变量&lt;/strong&gt; → 开机时 $TOKEN、$PORT 为空
3. &lt;strong&gt;boot 脚本语法错误&lt;/strong&gt; → 检查日志：&lt;code&gt;logcat -s termux:boot&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Q5: 进程崩溃后没自动重启？&lt;/h3&gt;
&lt;p&gt;可能原因：
1. &lt;strong&gt;crond 没运行&lt;/strong&gt; → &lt;code&gt;ps aux | grep crond&lt;/code&gt;
2. &lt;strong&gt;monitor.sh 路径错误&lt;/strong&gt; → crontab 里用绝对路径 &lt;code&gt;/data/data/com.termux/files/home/monitor.sh&lt;/code&gt;
3. &lt;strong&gt;monitor.sh 里用了 $PREFIX&lt;/strong&gt; → 改成绝对路径&lt;/p&gt;
&lt;h3&gt;Q6: 如何调整检测频率？&lt;/h3&gt;
&lt;p&gt;编辑 crontab：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;crontab&lt;span class="w"&gt; &lt;/span&gt;-e
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;每1分钟：&lt;code&gt;* * * * * /data/data/com.termux/files/home/monitor.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;每5分钟：&lt;code&gt;*/5 * * * * /data/data/com.termux/files/home/monitor.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;每10分钟：&lt;code&gt;*/10 * * * * /data/data/com.termux/files/home/monitor.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Q7: boot 脚本执行了但进程没起来？&lt;/h3&gt;
&lt;p&gt;调试方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 手动执行 boot 脚本看报错&lt;/span&gt;
bash&lt;span class="w"&gt; &lt;/span&gt;-x&lt;span class="w"&gt; &lt;/span&gt;~/.termux/boot/services.sh

&lt;span class="c1"&gt;# 查看 termux:boot 日志&lt;/span&gt;
logcat&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;termux:boot

&lt;span class="c1"&gt;# 检查环境变量是否存在&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$PORT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$PREFIX&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Q8: 如何查看日志？&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 查看监控日志（进程重启记录）&lt;/span&gt;
tail&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;~/monitor.log

&lt;span class="c1"&gt;# 查看启动日志&lt;/span&gt;
tail&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;~/boot.log

&lt;span class="c1"&gt;# 查看 tmux 会话日志&lt;/span&gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;openclaw
tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;frpc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;效果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;手机重启&lt;/strong&gt; → crond + frpc + OpenClaw &lt;strong&gt;全部自动启动&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;进程崩溃&lt;/strong&gt; → 5分钟内自动检测并重启&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;随时查看日志&lt;/strong&gt; → &lt;code&gt;tmux attach -t openclaw&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;完整启动链路（手机开机后）&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;手机开机
    ↓
termux:boot 自动触发
    ↓
services.sh 执行：
  1. crond（关键！进程监控依赖它）
  2. frpc-start.sh（持有 wake lock）
  3. OpenClaw（主服务）
    ↓
frpc 持有 termux-wake-lock，防止系统休眠
    ↓
crond 每5分钟运行 monitor.sh
    ↓
检测到进程挂了 → 自动重启
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wiki.termux.com/wiki/Termux:Boot"&gt;Termux Wiki - Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.termux.com/wiki/Cron"&gt;Termux Wiki - Cron&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tmuxcheatsheet.com/"&gt;Tmux 常用命令&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>如何发布 pelican 到 github pages</title><link href="https://hillerliao.github.io/publish-pelican-to-ghp.html" rel="alternate"></link><published>2021-12-26T17:32:00+08:00</published><updated>2021-12-26T17:32:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2021-12-26:/publish-pelican-to-ghp.html</id><summary type="html">&lt;p&gt;Short version for index and feeds&lt;/p&gt;</summary><content type="html">&lt;p&gt;去年决定将静态博客的生成工具从 hexo 改成基于 Python 的 pelican，初次搬运之后就没在动过，以至于已经忘了该如何更新。&lt;/p&gt;
&lt;p&gt;为避免再次遗忘，现决定将发布过程写下来。  &lt;/p&gt;
&lt;h2&gt;第一次配置环境&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# 进入项目根目录  
pipenv shell  
pip install pelican markdown

# change theme Enter prject home directory, run 
git clone https://github.com/getpelican/pelican-themes.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# generate html pages&lt;/span&gt;
&lt;span class="n"&gt;pelican&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;

&lt;span class="c1"&gt;# preview &lt;/span&gt;
&lt;span class="n"&gt;pelican&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="mi"&gt;8082&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;

&lt;span class="c1"&gt;# publish to github pages&lt;/span&gt;
&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;ghp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;import&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2.1.0&lt;/span&gt;
&lt;span class="n"&gt;ghp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;output&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;gh&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pages&lt;/span&gt;
&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="n"&gt;gh&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="blog"></category><category term="pelican"></category></entry><entry><title>部署Flask项目到手机上 并供外网访问</title><link href="https://hillerliao.github.io/deploy-flask-project-on-android.html" rel="alternate"></link><published>2021-11-29T21:03:57+08:00</published><updated>2021-11-29T21:03:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2021-11-29:/deploy-flask-project-on-android.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;教程
categories:&lt;/li&gt;
&lt;li&gt;教程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;为什么写这篇文章？本需求的实现将之前折腾的几个服务综合起来，链条比较长，记录之，备忘。&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;需求缘起&lt;/h2&gt;
&lt;p&gt;有一个 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;教程
categories:&lt;/li&gt;
&lt;li&gt;教程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;为什么写这篇文章？本需求的实现将之前折腾的几个服务综合起来，链条比较长，记录之，备忘。&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;需求缘起&lt;/h2&gt;
&lt;p&gt;有一个抓取微信公众号文章生成 RSS 地址的 Flask 项目RSSHub-python，本地运行没什么问题，一旦部署到服务器上，秒秒钟被数据源网站搜狗给封杀了。&lt;/p&gt;
&lt;p&gt;从两种环境的不同结果来看，本地运行没有问题可能是因为本地出口 IP 没有被封杀。顺着这个思路，如果把服务部署在本地，并保证持续不断地运行，即可避免被封杀的悲剧。&lt;/p&gt;
&lt;p&gt;但本地化部署需要解决被外网访问的问题。电脑不适合一直开着，购买树莓派之类的硬件设备需要花钱，而且过往经历告诉我，树莓派大部分时候只是用来吃灰。综合考虑，我决定用闲置的安卓机OnePlus 2作为服务器运行服务，还能省省电。而要让外网能访问，可以借助内网穿透来实现。&lt;/p&gt;
&lt;p&gt;简单说，需要准备一台OS版本至少在6.0以上的Android手机。本文以 Android 版本为 10的Redmi 10X 为例进行介绍。&lt;/p&gt;
&lt;h2&gt;部署方案&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image.png" src="https://cdn.nlark.com/yuque/0/2021/png/147312/1637474979948-88ed5582-7cad-4b70-ad69-fd8e83e9eea3.png#height=440&amp;amp;id=uf821016d&amp;amp;originHeight=880&amp;amp;originWidth=1539&amp;amp;originalType=binary&amp;amp;ratio=1&amp;amp;rotation=0&amp;amp;showTitle=false&amp;amp;size=96230&amp;amp;status=done&amp;amp;style=shadow&amp;amp;title=&amp;amp;width=769.5"&gt;
我实际的部署方案如上图所示，用到了几个第三方服务，除了阿里云服务器，其他都是免费就能搞定。
关键点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;借助名字叫做 Aid Learning 的安卓 App 作为服务器环境，在服务器内部署 Flask 项目，并用 Supervisor 保证服务运行的稳定性；&lt;/li&gt;
&lt;li&gt;然后借助花生壳内网版作内网穿透，让服务支持外网访问；&lt;/li&gt;
&lt;li&gt;由于公司网络禁用了花生壳的服务，需要借助SS服务作为正向代理，通过 SS 客户端将访问花生壳的服务转换为访问阿里云服务器。如果本地网络不禁用花生壳内网穿透服务，这一步可以省略，一分钱都不用花。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;配置「服务器」Aid Learning&lt;/h2&gt;
&lt;p&gt;要 Android 变成服务器，我们需要借助一个叫做「Aid Learning」的 App（最新版已更名为 AidLux ，查找网络资料时两个关键词都可以试试），可以从&lt;a href="http://www.aidlearning.net/"&gt;官网&lt;/a&gt;下载。撰写本文时一开始想用&lt;a href="https://www.aidlux.com/apk/AidLux_1.0a.apk"&gt;1.0a&lt;/a&gt;，结果遇到各种坑，换回0.86b2f4版本（可以通过酷安下载历史版本）。&lt;/p&gt;
&lt;p&gt;安装成功后参考教程进行一些&lt;a href="https://dontkillmyapp.com/xiaomi"&gt;设置&lt;/a&gt;，包括开启自动启动、常驻后台等，以确保App能持续在后台运行。&lt;/p&gt;
&lt;p&gt;或者安装 &lt;a href="https://termux.com/"&gt;Termux&lt;/a&gt; App 也可以达到同样目的。Termux 的优点是环境干净，占用存储空间小，自己想装什么就自行安装；缺点是需要自行配置各种环境依赖，配置过程往往会碰到各种各样的依赖问题，掉进坑里的感觉会把人逼疯。可以把App理解为一台 Linux 服务器，两个 APP 好比是Ubuntu 和Arch Linux之别。
&lt;img alt="20211121_222306.png" src="https://cdn.nlark.com/yuque/0/2021/png/147312/1637505262582-a9c92bec-008a-47d0-9e18-c06c0f3ae0b2.png#height=439&amp;amp;id=fi2tX&amp;amp;originHeight=994&amp;amp;originWidth=462&amp;amp;originalType=binary&amp;amp;ratio=1&amp;amp;rotation=0&amp;amp;showTitle=false&amp;amp;size=1836966&amp;amp;status=done&amp;amp;style=stroke&amp;amp;title=&amp;amp;width=204"&gt; 
上图：手机号登录，省得以后打开APP时老提示登录。当然这个步骤不是强制的，可以选择跳过。&lt;/p&gt;
&lt;p&gt;首次运行APP 时，由于初始化任务的执行，会请求网络下载一些东西，速度比较慢，可能耗时数分钟。如果需要节省流量，记得在 WIFI 环境下操作。
&lt;img alt="image.png" src="https://cdn.nlark.com/yuque/0/2021/png/147312/1637505980097-2aa0a7c7-a21f-44d4-a55a-57dd84dd146b.png#height=440&amp;amp;id=ue7b0ca5b&amp;amp;originHeight=880&amp;amp;originWidth=396&amp;amp;originalType=binary&amp;amp;ratio=1&amp;amp;rotation=0&amp;amp;showTitle=false&amp;amp;size=150917&amp;amp;status=done&amp;amp;style=none&amp;amp;title=&amp;amp;width=198"&gt;
默认登录的是 root 用户，未设置密码，可以设置一个 root 用户的密码：打开 APP 内的终端，切换到全屏模式，输入命令 &lt;code&gt;passwd root&lt;/code&gt;，按界面提示输入两次密码，设置成功。
&lt;img alt="image.png" src="https://cdn.nlark.com/yuque/0/2021/png/147312/1637506748306-153cc560-5584-4e71-a92f-4c6e276995e7.png#height=440&amp;amp;id=u401acc46&amp;amp;originHeight=880&amp;amp;originWidth=396&amp;amp;originalType=binary&amp;amp;ratio=1&amp;amp;rotation=0&amp;amp;showTitle=false&amp;amp;size=78958&amp;amp;status=done&amp;amp;style=none&amp;amp;title=&amp;amp;width=198"&gt;
为方便输入命令行命令，可以通过电脑远程访问服务器(Aidlux)：打开服务器上的终端，输入命令 &lt;code&gt;ifconfig&lt;/code&gt; ，确认服务器的 ip 地址，如我的手机为 172.16.99.125。&lt;/p&gt;
&lt;p&gt;保证手机与电脑在同一个WIFI 网络，通过电脑终端远程登录该服务器，注意端口为 &lt;strong&gt;9022&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="mf"&gt;@192.168.1.9&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9022&lt;/span&gt;
&lt;span class="cp"&gt;# 密码为demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;更新软件包列表，并安装一些常用工具，如 git 等。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt&lt;span class="w"&gt; &lt;/span&gt;update
apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;部署项目&lt;/h2&gt;
&lt;h3&gt;生成 ssh 密钥&lt;/h3&gt;
&lt;p&gt;获取项目代码拉取权限&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 生成密钥 ssh-keygen&lt;/span&gt;
ssh-keygen
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/root/.ssh
&lt;span class="c1"&gt;# 复制 id_rsa.pub 文件中的字符。&lt;/span&gt;
&lt;span class="c1"&gt;# 将公钥添加到 github.进入 https://github.com/settings/keys，&lt;/span&gt;
&lt;span class="c1"&gt;# 创建新的 SSH key，填入刚才复制的公钥字符。 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;拉取项目代码&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 回到服务器，拉取项目代码&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/opt
git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;git@github.com:hillerliao/RSSHub-python.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;本地测试运行&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 进入项目文件夹&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/opt/RSSHub-python

&lt;span class="c1"&gt;# 修改pip镜像源&lt;/span&gt;
mkdir&lt;span class="w"&gt; &lt;/span&gt;~/.config/pip
touch&lt;span class="w"&gt; &lt;/span&gt;~/.config/pip/pip.config

&lt;span class="c1"&gt;# 修改 pip.config 内容为&lt;/span&gt;
&lt;span class="sb"&gt;```&lt;/span&gt;pip.config内容
&lt;span class="o"&gt;[&lt;/span&gt;global&lt;span class="o"&gt;]&lt;/span&gt;
index-url&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;https://mirrors.aliyun.com/pypi/simple
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;安装 pipenv。也可以用 apt install pipenv 安装，但版本比较旧&lt;/h1&gt;
&lt;p&gt;pip install pipenv &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# 安装
whereis pipenv 
# 得到 /usr/local/bin/pipenv
# 创建软连接
ln -s /usr/local/bin/pipenv /usr/bin/pipenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;创建Python 虚拟环境。&lt;/h1&gt;
&lt;h1&gt;我用Android 11的红米手机尝试会报错，用Android 6 的 OnePlus 2手机不报错&lt;/h1&gt;
&lt;h1&gt;提示「OSError: Cannot find path to android app folder」&lt;/h1&gt;
&lt;p&gt;cd /opt/RSSHub-python
pipenv install&lt;/p&gt;
&lt;h1&gt;记下虚拟环境位置，后续 uwsgi 配置文件里会用到&lt;/h1&gt;
&lt;h1&gt;/root/User/demo/.local/share/virtualenvs/RSSHub-python-e4f4sLQi&lt;/h1&gt;
&lt;h1&gt;验证本地运行是否正常&lt;/h1&gt;
&lt;p&gt;flask run &lt;/p&gt;
&lt;h1&gt;如果确实依赖包，就手动安装，如 dotenv&lt;/h1&gt;
&lt;p&gt;pip install python-dotenv&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;## 配置 uwsgi 服务
### 安装 uwsgi
```bash
# 需要在root用户下运行
pip install uwsgi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;uwsgi 配置文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# uwsgi --ini {current_file_path_and_name}&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;uwsgi&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;http&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:5000
&lt;span class="nv"&gt;processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;
&lt;span class="nv"&gt;threads&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;plugins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3
&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# 启动主进程，来管理其他进程，其它的uwsgi进程都是这个master进程的子进程，如果kill这个master进程，相当于重启所有的uwsgi进程。&lt;/span&gt;

&lt;span class="nv"&gt;chdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/opt/RSSHub-python
&lt;span class="c1"&gt;# 在app加载前切换到当前目录， 指定运行目录 &lt;/span&gt;

wsgi-file&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;wsgi.py
&lt;span class="c1"&gt;#virtualenv = /root/.local/share/virtualenvs/RSSHub-python-e4f4sLQi&lt;/span&gt;
&lt;span class="nv"&gt;virtualenv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/usr/bin/python
&lt;span class="c1"&gt;# pythonpath = /opt/RSSHub-python&lt;/span&gt;
&lt;span class="c1"&gt;#上面的pythonpath需要换成刚才你自己创建的应用的目录&lt;/span&gt;
&lt;span class="c1"&gt;# module = rsshub&lt;/span&gt;
&lt;span class="nv"&gt;callable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;app
memory-report&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;#py-autoreload = 1 ##监控python模块mtime来触发重载 (只在开发时使用)&lt;/span&gt;

&lt;span class="c1"&gt;#daemonize = /var/log/uwsgi/rsshub-python.log&lt;/span&gt;
&lt;span class="c1"&gt;# 使进程在后台运行，并将日志打到指定的日志文件或者udp服务器&lt;/span&gt;

touch-reload&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/opt/RSSHub-python
&lt;span class="c1"&gt;# 表示要监听的文件路径，当要监听的文件路径下的文件发生变化的时候自动重新加载服务。&lt;/span&gt;

lazy-apps&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# 在每个worker而不是master中加载应用&lt;/span&gt;

&lt;span class="nv"&gt;vacuum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# 当服务退出的时候自动删除unix socket文件和pid文件。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;配置Nginx&lt;/h2&gt;
&lt;h3&gt;安装Nginx&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt install nginx

#查看Nginx状态
service nginx status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Nginx配置文件&lt;/h3&gt;
&lt;p&gt;创建配置文件  &lt;code&gt;touch /etc/nginx/conf.d/rsshub.conf&lt;/code&gt;，通过 nano 命令编辑该文件。具体配置如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;server&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;listen&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;server_name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;域名&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;location&lt;span class="w"&gt; &lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;include&lt;span class="w"&gt; &lt;/span&gt;uwsgi_params&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="c1"&gt;#uwsgi_pass 127.0.0.1:5000;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;proxy_pass&lt;span class="w"&gt; &lt;/span&gt;http://127.0.0.1:5000&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;uwsgi_read_timeout&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;120&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;保存好配置文件，并进行测试  &lt;code&gt;service nginx -t&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;重新加载Nginx服务 &lt;code&gt;service nginx reload&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;开启Supervisor服务&lt;/h2&gt;
&lt;h3&gt;安装supervisor&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# 安装supervisor
apt install supervisor
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Supervisor 配置文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 文件位置：/etc/supervisor/conf.d/rsshub.conf&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;program:rsshub_python&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/lxf/.local/bin/uwsgi&lt;span class="w"&gt; &lt;/span&gt;--ini&lt;span class="w"&gt; &lt;/span&gt;/opt/RSSHub-python/uwsgi.ini
&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lxf
&lt;span class="nv"&gt;autorestart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="nv"&gt;autostart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="nv"&gt;startretries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="nv"&gt;redirect_stderr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="nv"&gt;startsecs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="c1"&gt;#↓注意需要创建这个日志文件&lt;/span&gt;
&lt;span class="nv"&gt;stdout_logfile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/log/uwsgi/supervisor.log&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="nv"&gt;stopasgroup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="nv"&gt;killasgroup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="nv"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;999&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;启动Supersivor&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# 启动supervisor
service supervisor start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;配置内网穿透&lt;/h2&gt;
&lt;h3&gt;配置映射关系&lt;/h3&gt;
&lt;p&gt;在花生壳内网穿透服务后台&lt;a href="https://console.hsk.oray.com/parts"&gt;配置中心&lt;/a&gt;开启 HTTP 映射服务；
接着在内网穿透菜单填写配置信息，其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内网主机：为上文服务器内通过&lt;code&gt;ifconfig&lt;/code&gt; 命令获取到的ip；&lt;/li&gt;
&lt;li&gt;内网端口：为9080（aid learning默认的http端口）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="image.png" src="https://cdn.nlark.com/yuque/0/2021/png/147312/1638106924932-113da602-2430-419a-b4a5-3f84029e10de.png#height=275&amp;amp;id=uf78ea94b&amp;amp;originHeight=867&amp;amp;originWidth=1578&amp;amp;originalType=binary&amp;amp;ratio=1&amp;amp;rotation=0&amp;amp;showTitle=false&amp;amp;size=105038&amp;amp;status=done&amp;amp;style=shadow&amp;amp;title=&amp;amp;width=500"&gt;&lt;/p&gt;
&lt;h3&gt;安装花生壳内网版 App&lt;/h3&gt;
&lt;p&gt;apk文件可以通过&lt;a href="https://www.wandoujia.com/apps/7956016"&gt;豌豆荚&lt;/a&gt;下载，官网比较凌乱，没找到下载入口；
安装后登录花生壳账号，诊断一下，预期是正常连接；
访问花生壳内网穿透服务后台的外网域名，即可访问到Nginx默认页面：
&lt;img alt="image.png" src="https://cdn.nlark.com/yuque/0/2021/png/147312/1638149455953-acb7d41a-9f11-446a-9c6c-2fcffa63f3e8.png#clientId=u7beefe37-88dc-4&amp;amp;from=paste&amp;amp;height=144&amp;amp;id=u7770bb69&amp;amp;originHeight=287&amp;amp;originWidth=591&amp;amp;originalType=binary&amp;amp;ratio=1&amp;amp;rotation=0&amp;amp;showTitle=false&amp;amp;size=31776&amp;amp;status=done&amp;amp;style=shadow&amp;amp;taskId=ub24d638c-e9d2-430a-ab0c-ca3c8e6231c&amp;amp;title=&amp;amp;width=295.5"&gt;&lt;/p&gt;
&lt;h2&gt;代理访问(非必须)&lt;/h2&gt;
&lt;p&gt;有的公司网络监控会将花生壳、todesk等内网穿透性质的服务在域名层面进行封禁，所以可能需要正向代理来突破限制。&lt;/p&gt;
&lt;p&gt;这里我们借助小火箭，在阿里云服务器上部署ss-server端。为简化部署，通过docker方式进行。考虑到安全问题，本文不详述部署过程。&lt;/p&gt;
&lt;h2&gt;日常运维&lt;/h2&gt;
&lt;h3&gt;重启服务&lt;/h3&gt;
&lt;p&gt;手机没电了，重新充电，怎么重启服务？
依次启动几个APP，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开启代理软件 SS&lt;/li&gt;
&lt;li&gt;开启内网穿透App“ 花生壳内网版”&lt;/li&gt;
&lt;li&gt;重启‘服务器’&lt;/li&gt;
&lt;li&gt;启动nginx &lt;code&gt;service nginx start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;启动supervisor服务。此时会自动启动 uwsgi 服务。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总体还算比较稳定，出现过一次花生壳内网版APP崩溃的情况。&lt;/p&gt;
&lt;p&gt;首发在&lt;a href="https://www.yuque.com/hillerliao/zhihai.me/mtx53r"&gt;语雀&lt;/a&gt;&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>如何实现微信接收龙岩学院讲座提醒</title><link href="https://hillerliao.github.io/qugakt.html" rel="alternate"></link><published>2020-11-05T19:57:57+08:00</published><updated>2020-11-05T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2020-11-05:/qugakt.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;编程
categories:&lt;/li&gt;
&lt;li&gt;编程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;产品概述&lt;/h1&gt;
&lt;p&gt;微信扫描二维码码关注公众号「新消息服务」。方便用户跟踪龙岩学院官网发布的讲座动态，无人值守 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;编程
categories:&lt;/li&gt;
&lt;li&gt;编程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;产品概述&lt;/h1&gt;
&lt;p&gt;微信扫描二维码码关注公众号「新消息服务」。方便用户跟踪龙岩学院官网发布的讲座动态，无人值守，有新讲座时自动推送到微信。&lt;/p&gt;
&lt;h1&gt;实现步骤简述&lt;/h1&gt;
&lt;p&gt;步骤说起来很简单，就两步：抓取数据、推送消息。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、抓取龙岩学完首页的讲座信息；&lt;/li&gt;
&lt;li&gt;2、设置自动监控任务，检查是否有抓取到新内容，如果有，则将新内容推送到微信。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果要自己写代码、买服务器，成本太高，本文介绍一种 no code 的方案，具体用到三个工具： Feed43、IFTTT、WxPusher。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;抓取信息采用 &lt;a href="https://feed43.com"&gt;Feed43&lt;/a&gt;，免费烧制静态网页 RSS 的工具，烧制 RSS 相当于将非标准化格式的数据转换成标准化的通用格式，方便在后续步骤中使用。；&lt;/li&gt;
&lt;li&gt;自动监控任务采用  &lt;a href="https://ifttt.com"&gt;IFTTT&lt;/a&gt;，免费的自动化工具，自动监控 RSS 数据源是否有新内容；&lt;/li&gt;
&lt;li&gt;消息提醒采用 &lt;a href="https://wxpusher.zjiecode.com"&gt;WxPusher&lt;/a&gt;，免费的微信推送服务。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Feed43 → IFTTT → WxPusher&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;下面介绍主要步骤。&lt;/p&gt;
&lt;h1&gt;生成 RSS 地址&lt;/h1&gt;
&lt;p&gt;要利用免费烧制静态网页 RSS 的工具 Feed43 ，关键点在于找到所需数据在页面 HTML 源代码中的位置，需要一点 HTML 和 CSS 的知识。操作过程可参考 &lt;a href="https://zhuanlan.zhihu.com/p/26511654"&gt;RSS 入门篇：FEED43&amp;amp;FeedEx-为静态网页定制 RSS 源 - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最终配置的抽取规则如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt="image.png" src="https://cdn.nlark.com/yuque/0/2020/png/147312/1604579741891-1fd39115-3df0-4fe8-bf61-6a016ac6a5b3.png#align=left&amp;amp;display=inline&amp;amp;height=22&amp;amp;margin=%5Bobject%20Object%5D&amp;amp;name=image.png&amp;amp;originHeight=43&amp;amp;originWidth=811&amp;amp;size=4922&amp;amp;status=done&amp;amp;style=none&amp;amp;width=405.5#align=left&amp;amp;display=inline&amp;amp;height=43&amp;amp;margin=%5Bobject%20Object%5D&amp;amp;originHeight=43&amp;amp;originWidth=811&amp;amp;status=done&amp;amp;style=none&amp;amp;width=811"&gt;&lt;/p&gt;
&lt;h1&gt;设置监控任务&lt;/h1&gt;
&lt;p&gt;利用免费服务 &lt;a href="https://ifttt.com"&gt;IFTTT&lt;/a&gt;，一个自动化工具，IFTTT = if this then that ，即，如果符合某个条件则做某件事情。如果没有使用过，则可以参考一些 IFTTT 教程，如 &lt;a href="https://sspai.com/post/25270"&gt;触发你的智能生活：IFTTT 入门&lt;/a&gt;。
触发器(this) 我们选择  RSS，动作 (then) 我们选择 Webhook，具体步骤略过，最终配置如下图。&lt;/p&gt;
&lt;p&gt;&lt;img alt="image.png" src="https://cdn.nlark.com/yuque/0/2020/png/147312/1604540219734-4dc16462-b9fe-495f-a021-56acd2111157.png#align=left&amp;amp;display=inline&amp;amp;height=504&amp;amp;margin=%5Bobject%20Object%5D&amp;amp;name=image.png&amp;amp;originHeight=1007&amp;amp;originWidth=492&amp;amp;size=68906&amp;amp;status=done&amp;amp;style=shadow&amp;amp;width=246#align=left&amp;amp;display=inline&amp;amp;height=1007&amp;amp;margin=%5Bobject%20Object%5D&amp;amp;originHeight=1007&amp;amp;originWidth=492&amp;amp;status=done&amp;amp;style=none&amp;amp;width=492"&gt;&lt;/p&gt;
&lt;h1&gt;获得微信提醒&lt;/h1&gt;
&lt;p&gt;要通过正常途径持续推送消息到微信，只有一条路，那就是服务号模板消息。开通服务号需要有企业资质，而注册一家企业的成本非常高。不用急，幸好已经有人注册了服务号并开发出一条消息通道供其他人免费使用，其产品的名字叫做「WxPusher」。官方是这么介绍的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WxPusher (微信推送服务)是一个使用微信公众号作为通道的，实时信息推送平台，你可以通过调用 API 的方式，把信息推送到微信上，无需安装额外的软件，即可做到信息实时通知。 你可以使用 WxPusher 来做服务器报警通知、抢课通知、抢票通知，信息更新提示等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我们在其上创建一个应用「消息来了」，然后创建一个主题「龙院讲座」，获得订阅二维码。将二维码分享给朋友，对方只需要扫一扫，即可实现订阅。
&lt;img alt="龙岩学院讲座提醒-二维码.jpg" src="https://cdn.nlark.com/yuque/0/2020/jpeg/147312/1604542059523-bbb8bdcc-f45f-4d8b-9c78-847fe87afb52.jpeg#align=left&amp;amp;display=inline&amp;amp;height=395&amp;amp;margin=%5Bobject%20Object%5D&amp;amp;name=%E9%BE%99%E5%B2%A9%E5%AD%A6%E9%99%A2%E8%AE%B2%E5%BA%A7%E6%8F%90%E9%86%92-%E4%BA%8C%E7%BB%B4%E7%A0%81.jpg&amp;amp;originHeight=1304&amp;amp;originWidth=990&amp;amp;size=69543&amp;amp;status=done&amp;amp;style=stroke&amp;amp;width=300#align=left&amp;amp;display=inline&amp;amp;height=1304&amp;amp;margin=%5Bobject%20Object%5D&amp;amp;originHeight=1304&amp;amp;originWidth=990&amp;amp;status=done&amp;amp;style=none&amp;amp;width=990"&gt;&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>天猫精灵智能音箱新闻收听体验报告</title><link href="https://hillerliao.github.io/hxz52w.html" rel="alternate"></link><published>2020-10-22T19:57:57+08:00</published><updated>2020-10-22T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2020-10-22:/hxz52w.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;产品体验
categories:&lt;/li&gt;
&lt;li&gt;产品体验&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;我主要用天猫精灵听新闻，基于这个需求，希望作出以下改进：&lt;/p&gt;
&lt;h3&gt;一、优化体验&lt;/h3&gt;
&lt;p&gt;目前天猫精灵的资讯由乐 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;产品体验
categories:&lt;/li&gt;
&lt;li&gt;产品体验&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;我主要用天猫精灵听新闻，基于这个需求，希望作出以下改进：&lt;/p&gt;
&lt;h3&gt;一、优化体验&lt;/h3&gt;
&lt;p&gt;目前天猫精灵的资讯由乐天头条提供，这是什么机构？&lt;/p&gt;
&lt;p&gt;1、记住用户偏好，实现智能推荐
记住用户偏好，举例：如果用户每天都请求 日本新闻、福建新闻、新西兰新闻，那么可以多推荐这类新闻给该用户，而不仅仅是推荐用户所在地的本地新闻。&lt;/p&gt;
&lt;p&gt;2、资讯排重
出现资讯重复播放的问题，能否做到完整播放过的资讯，别再播放了。&lt;/p&gt;
&lt;p&gt;3、更精准地记住播放位置
相同节目，无法记住上一次播放的位置，比如连载评书三国演义，上一次听到第二章的第 15 分 35 秒，再次播放时只会从第二章的开头播放，无法从 15 分 35 秒处继续播放。&lt;/p&gt;
&lt;h3&gt;二、提供更多资源&lt;/h3&gt;
&lt;p&gt;特色爆款节目无法找到，如 新闻联播每日音频回放。
缺少英语新闻。&lt;/p&gt;
&lt;p&gt;可能的丰富音频资源的办法：&lt;/p&gt;
&lt;p&gt;1、直接播放第三方音频
希望能做到在天猫精灵 APP 内通过 webview 打开第三方网页，网页播放音频时，能选择将天猫精灵音箱作为外放。比如百度网盘里的音频，能将智能音箱作为外放。&lt;/p&gt;
&lt;p&gt;2、搭建内容开放平台，PGC
一些不错的公众号文章，会提供音频版，但散落在微信公众平台，并不能为天猫精灵所用。天猫精灵能否与自媒体合作，给他们方便的工具，将内容提交到开放平台。如 财经早餐、人民日报、十点读书等，在喜马拉雅更新不勤快，但公众号更新很勤快，导致天猫精灵无法使用。&lt;/p&gt;
&lt;p&gt;3、让用户分享音频，UGC
许多内容都是文字的，能否通过用户生产音频？比如用户可以念新闻，选择是否分享给其他用户。&lt;/p&gt;
&lt;p&gt;当然我知道这个体验反馈估计不会引起天猫精灵的注意，因为资讯是第三方的乐天头条提供的。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>基于古诗词名言名篇应用需求分析</title><link href="https://hillerliao.github.io/ji-yu-gu-shi-ci-ming-yan-ming-pian-ying-yong-xu-qiu-fen-xi.html" rel="alternate"></link><published>2019-02-25T19:57:57+08:00</published><updated>2019-02-25T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2019-02-25:/ji-yu-gu-shi-ci-ming-yan-ming-pian-ying-yong-xu-qiu-fen-xi.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;产品设计
categories:&lt;/li&gt;
&lt;li&gt;产品设计&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;「到此一游」小程序，让装逼来得更文艺些！问题来了，吹牛怎么变成现实？  &lt;/p&gt;
&lt;h2&gt;场景举例&lt;/h2&gt;
&lt;p&gt;昨天又和我娘子吹了 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;产品设计
categories:&lt;/li&gt;
&lt;li&gt;产品设计&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;「到此一游」小程序，让装逼来得更文艺些！问题来了，吹牛怎么变成现实？  &lt;/p&gt;
&lt;h2&gt;场景举例&lt;/h2&gt;
&lt;p&gt;昨天又和我娘子吹了一遍「到此一游」应用的构想，比如：  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;游庐山，拾级而上，为美景所吸引，想引用点知名诗句诗并配图发到朋友圈装逼，可记性不好死活想不起来？没关系，打开「到此一游」小程序，摇一摇，摇出毛主席写的与庐山有关的诗句，发到朋友圈，引来点赞无数。  &lt;/p&gt;
&lt;p&gt;引用别人的没意思？没关系，花费 1 块钱，切换到 AI 写诗模式，程序自动基于位置，关联景点、美食、天气、用户昵称、已有的古诗词名言名篇等自动写诗。  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个场景还让我想起了小学五年级一位老师兜售作文描写词典的往事。想看看名家怎么描写雪景？打开描写词典瞅瞅！现在应该通过互联网、大数据、APP、人工智能技术让让这种需求得到更好的满足！  &lt;/p&gt;
&lt;p&gt;简而言之，「到此一游」小程序让古诗词、名人名言名篇在现实生活中得到应用，满足装逼犯的表现欲。手机版「描写词典」满足学生党掉书袋、写满分作文的需求。  &lt;/p&gt;
&lt;h2&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;关于XX的诗句&lt;/td&gt;
&lt;td&gt;100万+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;描写XX的诗句&lt;/td&gt;
&lt;td&gt;3200万+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;关于XX的名言&lt;/td&gt;
&lt;td&gt;1500万+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;出自哪里&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;下一句是什么&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.baidu.com/s?wd=%E4%B8%8A%E4%B8%80%E5%8F%A5%E6%98%AF%E4%BB%80%E4%B9%88&amp;amp;ie=UTF-8"&gt;上一句是什么&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;商业前景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2C，按服务收费，增值服务收费；  &lt;/li&gt;
&lt;li&gt;2B，也可以输出技术能力给教育机构。  &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;问题&lt;/h2&gt;
&lt;h3&gt;刚需吗？高频吗？&lt;/h3&gt;
&lt;p&gt;学生提升古文考试成绩是刚需！安传东已经拿到投资了。  &lt;/p&gt;
&lt;h3&gt;技术难度&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;诗词库、古文库、名言、名篇库；  &lt;/li&gt;
&lt;li&gt;对诗词古文名篇打标签；  &lt;/li&gt;
&lt;li&gt;匹配算法；  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI写诗&lt;/strong&gt;；  &lt;/li&gt;
&lt;li&gt;小程序开发。  &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;竞品分析&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;&lt;a href="https://www.jinrishici.com/"&gt;今日诗词&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;今日诗词是一个诗词实时智能推荐的网站。根据不同地点、时间、节日、季节、天气、景观、城市进行智能推荐。今日诗词提供今日诗词API，可以通过图片和 JSON 格式调用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.xcz.im/"&gt;西窗烛&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;千万级下载量？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://duilian.msra.cn/app/couplet.aspx"&gt;电脑对联&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;由微软亚洲研究院自然语言计算组研发的计算机自动对联系统。  技术看着不错！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;偶得&lt;/td&gt;
&lt;td&gt;IBM中国研究院基于回馈神经网络的深度学习模型，开发的诗歌自动写作应用系统。它巧妙地将语音学特征引入到诗词的算法当中，当输入“神策数据”四个字后，自动输出一首七言藏头诗：“神仙不得隐无踪，策杖长空水墨中，数点红莲开碧玉，据临万象搫金龙。”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;席读&lt;/td&gt;
&lt;td&gt;创业名人安传东切入的市场&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.a-site.cn/article/805835.html"&gt;古诗文助手&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;还没怎么研究&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://poem.msxiaobing.com/"&gt;少女诗人小冰&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;微软小冰，看图创作现代诗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://jiuge.thunlp.cn/"&gt;九歌&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;清华大学，基于深度学习的中国古典诗歌自动生成系统。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;总体看，目前基于古诗词名篇的应用不太好玩，好玩才能让学生好学。机会是有的。  &lt;/p&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://baijiahao.baidu.com/s?id=1608115520173864534&amp;amp;wfr=spider&amp;amp;for=pc"&gt;用AI写歌的清华博士生宿涵：科技让音乐更美好&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhuanlan.zhihu.com/p/38465195"&gt;AI智能文案一秒生成20000条创意，文案要失业了？&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://102.alibaba.com/detail/?id=180"&gt;“天猫精灵”如何为你写诗？人机共创的秘密在这儿&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.leiphone.com/news/201809/nkL0pOmRWT9yQhkr.html"&gt;清华大学矣晓沅：「九歌」——基于深度学习的中国古典诗歌自动生成系统&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.weibo.com/6347645237/GANze1NDr"&gt;九歌联合腾讯相册管家、中国国家地理，推出思乡写诗功能&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;反馈&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;属于 nice to have，不属于 must have 。  &lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>我理解的「离钱近」</title><link href="https://hillerliao.github.io/cvplkz.html" rel="alternate"></link><published>2019-02-22T19:57:57+08:00</published><updated>2019-02-22T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2019-02-22:/cvplkz.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;商业思考
categories:&lt;/li&gt;
&lt;li&gt;商业思考&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;我对于「离钱近」的理解，其中一类场景的关键词是「账户」，比如银行等借贷平台、公募基金等资产管理公 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;商业思考
categories:&lt;/li&gt;
&lt;li&gt;商业思考&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;我对于「离钱近」的理解，其中一类场景的关键词是「账户」，比如银行等借贷平台、公募基金等资产管理公司。用户在这些公司创立账户，并把钱放进去，公司能动用这些钱，从中赚取价差、收取管理费或收益提成，非常爽。只要用户不走，就能持续收到钱。这类场景往往是牌照保护。&lt;/p&gt;
&lt;p&gt;另一类场景的关键词是「交易」，比如淘宝上每天在进行各种交易，一手交钱一手交货。又比如外卖，每天发生上千万量级的交易，覆盖人群大，还高频，这也算是离钱近。&lt;/p&gt;
&lt;p&gt;相对来说，媒体行业大家觉得离钱远，是因为媒体免费向用户提供内容，靠卖广告或软文收钱，不直接向用户收钱。知识付费稍微不同一点，直接像用户卖内容，一手交钱一手交货，离钱近。&lt;/p&gt;
&lt;p&gt;以上这些都是建立在用户有需求的基础上，而产品服务提供者比同行更好地提供了用户需要的东西，就收到钱了。或者东西差不多，但效率更高，也行。&lt;/p&gt;
&lt;p&gt;再看我们都了解的金融信息服务行业，它为金融行业从业者或投资者提供信息服务。如果是万得卖终端，一手交钱一手交货，属于交易场景，离钱近。至于后来者怎么切入，是另外一个问题。&lt;/p&gt;
&lt;p&gt;金融信息服务业相比于借贷、资产管理、投行等我们通常理解的金融行业，它没有账户，没有资金沉淀，离钱又远一些了。&lt;/p&gt;
&lt;p&gt;再看区块链行业，离交易近的环节，典型如一级市场投资、二级市场的交易所，是个好模式，尤其是交易所，等于是券商+交易所二合一。但目前看，给后来者似乎没什么机会了。&lt;/p&gt;
&lt;p&gt;基于区块链的项目，愿景宏大，但吹牛居多，虚无缥缈。有些概念甚至违背经济学原理。&lt;/p&gt;
&lt;p&gt;我最近几天在思考分布式商业有什么逻辑缺陷，我觉得它可能违背了分工提高效率的经济学原理。比如出行，打车的用户最关心的是怎么以合适的价格高效地找到出行服务提供者，除此之外，应该把精力花在他擅长的主业上，没必要去为出行服务平台拉用户，因为这样的机会成本很大。拉用户的事情，雇佣管理团队专职做就行了，专业的人才能做得更好。另外，有了基于通证的激励机制，就能解决管理层的道德风险问题吗？不见得，管理层该揩油的还是会揩油。&lt;/p&gt;
&lt;p&gt;此外，如果是早期项目，呈现的是一级市场的投资场景，分布式商业的模式过早地让普通个人投资者参与其中并不适合，风险太高，否则传统金融领域就没必要设定私募门槛了。机构投资者可以同时投资多个项目，如果某个项目黄了，对机构整体的收益风险并不大，但对个人投资者而言，由于资金实力有限，无法通过同时投资多个项目而分散风险，在一个项目上踩雷，血本无归，在投资上恐怕难以再翻身了。&lt;/p&gt;
&lt;p&gt;区块链是个好技术，在许多地方有它的价值，金融等行业也在尝试使用。但就像 AI ，没有场景、没有数据，一切都白搭，顶多为掌握了场景的甲方打工。庞大如百度，自动驾驶技术也得和车企合作。&lt;/p&gt;
&lt;p&gt;所以，不一定要有「账户」才离钱近，有交易场景，用户愿意买单，就是离钱近。当然，如果交易基数大、频次高、客单价高，就更好了。&lt;/p&gt;
&lt;p&gt;再具体到你的技术团队本身的优势，目前做的事情完全体现不出价值，机会成本太高了。好好挖掘实际需求、能利用自身优势做的事情，可能是更好的选择。可以暂时不全身心做主战场的事情，但可以花一部分精力去做主战场的事情，就好比
Tushare 团队，兼职做、免费用，虽然暂时看不出什么大的前景，但慢慢积累用户，做出口碑，未来他们也许就可以拿到投资，全身心投入。现在已经开始搞积分了，token 的感觉，哈哈。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>旧电脑安装 Ubuntu 折腾记</title><link href="https://hillerliao.github.io/rcgvbw.html" rel="alternate"></link><published>2019-02-13T19:57:57+08:00</published><updated>2019-02-13T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2019-02-13:/rcgvbw.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;电脑数码
categories:&lt;/li&gt;
&lt;li&gt;电脑数码&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;家里只有一台 2012 年的 Mac 电脑，但常被被娘子占用，我自己如果没有带公司电脑回家，经常无电脑可用 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;电脑数码
categories:&lt;/li&gt;
&lt;li&gt;电脑数码&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;家里只有一台 2012 年的 Mac 电脑，但常被被娘子占用，我自己如果没有带公司电脑回家，经常无电脑可用。书桌底下柜子里还躺着一台十多年前的惠普电脑，就想利用起来，不过安装的是 Windows XP 系统，作为编程开发环境不方便。遂打算改装系统，换成 Ubuntu，好专心用来码代码，避免出现 Windows 上各种奇怪的 Bug。&lt;/p&gt;
&lt;p&gt;说起用 Windows 环境写代码这事儿来。就拿几个月前的一次经历来说吧。当时在 Windows 环境下修改了一个 Python 脚本，本地测试一切正常，但更新到 Ubuntu 服务器之后脚本无法正常运行，费好大劲才定位到问题所在，原来是 file format 从 unix 变成 dos 了。&lt;/p&gt;
&lt;p&gt;回归正题，那就开始折腾吧。没想到折腾了三个晚上才搞定，中途最大的麻烦就是无线网卡驱动的安装问题。 我的老古董接网线也无法上网，只能通过离线安装，无形中增加了难度。找半天幸好找到了离线安装的办法。&lt;/p&gt;
&lt;p&gt;主要过程如下：
安装 Ubuntu 14，64 位，可以安装无线网卡驱动，但运行太慢，操作很卡。有人建议那么老的电脑别安装 64 位系统；
改成 Ubuntu 14，32 位，无法安装无线网卡驱动；
改成 Ubuntu 16，32 位，无法安装无线网卡驱动；
改成 LUbuntu 18, 32 位，无法正常启动，黑屏，也不报啥错误信息。而且安装过程也不够傻瓜，得自己配置分区，对我来说折腾过多次依然害怕；
改成 Puppy Linux，竟然无需自己折腾无线网卡驱动，能联网！问题是无法正常显示中文，而且界面也奇丑无比；
改成 Ubuntu 12，32 位，成功安装无线网卡驱动。&lt;/p&gt;
&lt;p&gt;按照提示 update 系统，结果所有界面都出现这样的问题，找不到窗口的菜单栏，无法关闭，终端也无法敲入命令，废了。&lt;/p&gt;
&lt;p&gt;重新安装 Ubuntu 12，32 位，回退到更新前的状态，重新安装驱动，重复做相同的事情，时间就这样浪费了。&lt;/p&gt;
&lt;p&gt;总算可以松一口气，老古董能正常使用了。希望以后别再乱升级，能正常运行就不错了，保证偶尔能应急用一下。&lt;/p&gt;
&lt;p&gt;折腾中途曾经想放弃，但不能让电脑正常使用让我很不甘心，最终还是坚持下来了。&lt;/p&gt;
&lt;p&gt;题外话，每天都要使用的东西，高频，应该买好用的，避免折腾，因为时间才是最贵的，应该把时间用来做更有价值的事情，而不是用在重复造轮子上。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mirrors.163.com/ubuntu-releases/12.04.5/"&gt;Ubuntu 12 系统 iso 文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jingyan.baidu.com/article/ce4366494448fd3773afd306.html"&gt;利用 Rufus 制作 U 盘启动盘&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.csdn.net/ifmvo/article/details/54023628"&gt;Ubuntu 离线安装网卡驱动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cnbeta.com/articles/tech/417919.htm"&gt;7 款适用老旧设备并对初学者非常友好的轻量级 Linux 发行版&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>财报牛牛「个股群」入群指南</title><link href="https://hillerliao.github.io/guide-for-joining-cbnn-group.html" rel="alternate"></link><published>2019-01-05T19:06:00+08:00</published><updated>2019-01-05T19:06:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2019-01-05:/guide-for-joining-cbnn-group.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;项目
categories:&lt;/li&gt;
&lt;li&gt;项目&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;作为投资者，需要阅读大量信息，并与其他投资者一起交流，以增进对投资标的的认识。但如何高效获取信息、找 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;项目
categories:&lt;/li&gt;
&lt;li&gt;项目&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;作为投资者，需要阅读大量信息，并与其他投资者一起交流，以增进对投资标的的认识。但如何高效获取信息、找到值得交流的投资者，一直是个难题。&lt;/p&gt;
&lt;p&gt;为此，财报牛牛作了一些探索，具体的解决方案，我们称之为微信「个股群」。下图的拼多多群讨论片段就是一个典型案例：&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://raw.githubusercontent.com/HenryLoveMiller/img/main/cbnn-wechat-group.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;该群和其他微信群最大的不同在于，它为你定制了一个智能机器人「小黄牛」。小黄牛由「财报牛牛」研发，到处采集个股重要信息，并第一时间发送到群里。这些信息包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;公司新闻&lt;/strong&gt;：最新公告、财报预告 、财报结果等；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;经营动态&lt;/strong&gt;：招聘动向、APP/小程序更新日志和排名变化等；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;高管跟踪&lt;/strong&gt;：高管行为、言论、社会评价等；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;热门讨论&lt;/strong&gt;：来自雪球、知乎等社区的精选话题；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;其他内容&lt;/strong&gt;：分析、研报等其他相关信息。  &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除了「小黄牛」，群里还有和你一样共同关注个股的投资者，当你对股票动态发表观点时，说不定就能引发他们的干货发言。&lt;/p&gt;
&lt;p&gt;财报牛牛目前已创建包括陌陌、拼多多和分众传媒在内的3个个股群，更多个股群还在陆续创建中。&lt;/p&gt;
&lt;p&gt;心动了吗？那就点击「好看」后联系牛牛提交申请吧！申请时请注明你想加入的群。为保证交流质量，牛牛会对申请进行审核，届时需要你配合回答一些问题。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://raw.githubusercontent.com/HenryLoveMiller/img/main/cbnn-wechat-account-qrcode.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;长按或保存二维码，联系牛牛(微信号：cbnn2018)&lt;/p&gt;
&lt;p&gt;如果你想要其他个股群，也欢迎反馈，并提供你觉得不错的个股信息源。&lt;/p&gt;
&lt;p&gt;「个股群」服务目前免费。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>如何将网站的内容发送到微信群</title><link href="https://hillerliao.github.io/wbmnod.html" rel="alternate"></link><published>2018-10-15T19:57:57+08:00</published><updated>2018-10-15T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2018-10-15:/wbmnod.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;编程
categories:&lt;/li&gt;
&lt;li&gt;编程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;过程简述&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;雪球等 --&amp;gt; rsshub_rss / Huginn_rss --&amp;gt; inoreader_rss聚合 --&amp;gt; web_wechat_api --&amp;gt; 微信&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;过程分述&lt;/h3&gt;
&lt;p&gt;目前的推送过程是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过开源的 Rsshub / Huginn 作为数据抓取工具，生成 rss 格式 …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;编程
categories:&lt;/li&gt;
&lt;li&gt;编程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;过程简述&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;雪球等 --&amp;gt; rsshub_rss / Huginn_rss --&amp;gt; inoreader_rss聚合 --&amp;gt; web_wechat_api --&amp;gt; 微信&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;过程分述&lt;/h3&gt;
&lt;p&gt;目前的推送过程是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过开源的 Rsshub / Huginn 作为数据抓取工具，生成 rss 格式数据；&lt;/li&gt;
&lt;li&gt;inoreader 订阅多个 rsshub 生成的 rss 数据，形成 rss 组；&lt;/li&gt;
&lt;li&gt;rss 组自身有又可以额外生成一个新 rss，这个新 rss 包括了多个子 rss ；&lt;/li&gt;
&lt;li&gt;VPS 上创建定时任务检查 rss 更新，then 通过 webhook 发一条消息到微信群。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后一步的 webhook 是关键，涉及到打通外部网络与微信群的通路，靠的是一个开源的项目 &lt;a href="https://github.com/joeeeeey/web_wechat_api"&gt;web_wechat_api&lt;/a&gt;，它将微信个人号发送消息等接口封装成 web api ，方便外部系统调用。目前我稍微改造了一下，通过 Docker 部署在 VPS 上，省去部署程序的痛苦。&lt;/p&gt;
&lt;p&gt;其次，这一步可能会漏消息，没搞明白什么原因。目前的解决方案是，如果发送结果为失败，则继续尝试重新发送。&lt;/p&gt;
&lt;p&gt;再者，基于个人微信号搭建的微信机器人，不太稳定，为此，我每隔一个小时给指定的小群发送一个托福单词，如果发送间断，说明通道服务挂了，需要登录 VPS 及时重启。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>财报牛牛能为你做什么</title><link href="https://hillerliao.github.io/what-is-cai-bao-niu-niu.html" rel="alternate"></link><published>2018-08-13T23:53:00+08:00</published><updated>2018-08-13T23:53:00+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2018-08-13:/what-is-cai-bao-niu-niu.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;项目
categories:&lt;/li&gt;
&lt;li&gt;项目&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;财报牛牛能为你做什么？&lt;/h1&gt;
&lt;p&gt;牛牛  光子财经  &lt;em&gt;2018-08-13 23:53&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;“某某股票什么时候发财报？”牛牛在逛一些投资交流平台时，总能 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;项目
categories:&lt;/li&gt;
&lt;li&gt;项目&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;财报牛牛能为你做什么？&lt;/h1&gt;
&lt;p&gt;牛牛  光子财经  &lt;em&gt;2018-08-13 23:53&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;“某某股票什么时候发财报？”牛牛在逛一些投资交流平台时，总能看到这类问题。  &lt;/p&gt;
&lt;p&gt;这确实是投资者的基本需求之一。众所周知，财报是上市公司定期披露的业绩报告，是研究公司基本面的第一手材料。任何对投资决策负责的投资者，都不会忽视它的价值。&lt;/p&gt;
&lt;p&gt;但是财报提醒需求被很好地满足了吗？虽然目前市场上不乏此类服务提供者，但投资者还是感觉相当“不爽”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;投资交流平台功能太多，财报提醒入口很难找；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;千辛万苦找到了入口，却发现历史数据杂乱又零散；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没有财报结果提醒，如果不主动查询，发了财报根本就不知道；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;就算有提醒，也是夹杂在各类消息中，一不小心就看漏了。  &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实，投资者的需求很简单，但目前市场上的实现方案却过于复杂。为了让投资者更“爽”，牛牛为投资者准备了新的解决方案：&lt;strong&gt;只需要关注微信公众号「财报牛牛」，在财报日历中添加股票，剩下的工作就交给牛牛了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://raw.githubusercontent.com/HenryLoveMiller/img/main/cbnn-mystocks.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;在财报日历中添加股票，即可查看股票最新财报的发布日期、预期EPS和实际EPS。  &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://raw.githubusercontent.com/HenryLoveMiller/img/main/cbnn-receive-notification-in-wechat.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;关注微信公众号「财报牛牛」，即可自动接收财报预告。  &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://raw.githubusercontent.com/HenryLoveMiller/img/main/cnbb-result-notification.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;自选股财报结果发布后，第一时间通知你。&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://raw.githubusercontent.com/HenryLoveMiller/img/main/cnbb-result-detail.jpeg"&gt;  &lt;/p&gt;
&lt;p&gt;你还可以在「财报牛牛」的个股详情页里，获得财报公告和电话会议链接，省去从纷繁复杂的信息海洋中搜寻这些材料的烦恼。  &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://raw.githubusercontent.com/HenryLoveMiller/img/main/cnbb-search.jpeg"&gt;  &lt;/p&gt;
&lt;p&gt;此外，如果你想查阅某个股票最新的财报信息，只需在「财报牛牛」公众号内输入股票代码或股票名称，即可获得你想要的结果。  &lt;/p&gt;
&lt;p&gt;好了，今天牛牛就为你介绍到这里啦。如果你还有其他“不爽”，记得给牛牛留言。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>利用类Slack软件背单词</title><link href="https://hillerliao.github.io/xs32su.html" rel="alternate"></link><published>2017-11-14T19:57:57+08:00</published><updated>2017-11-14T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2017-11-14:/xs32su.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;编程
categories:&lt;/li&gt;
&lt;li&gt;编程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;出发点&lt;/h3&gt;
&lt;p&gt;我认为英语单词需要天天背诵，重复重复再重复，是不是在眼前露个脸，加深记忆。&lt;/p&gt;
&lt;h3&gt;怎么做到？&lt;/h3&gt;
&lt;p&gt;但是，问题来 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;编程
categories:&lt;/li&gt;
&lt;li&gt;编程&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;出发点&lt;/h3&gt;
&lt;p&gt;我认为英语单词需要天天背诵，重复重复再重复，是不是在眼前露个脸，加深记忆。&lt;/p&gt;
&lt;h3&gt;怎么做到？&lt;/h3&gt;
&lt;p&gt;但是，问题来了，每天工作太忙，又有智能手机占用太多时间，哪有功夫去背单词？&lt;/p&gt;
&lt;p&gt;我的答案是：利用零碎时间。&lt;/p&gt;
&lt;p&gt;怎么利用？利用工具，通过定时发条消息到手机上的方式来实现。&lt;/p&gt;
&lt;h3&gt;最终效果预览&lt;/h3&gt;
&lt;p&gt;提醒自己喝水，消息附带一个单词。&lt;/p&gt;
&lt;h3&gt;方案架构&lt;/h3&gt;
&lt;p&gt;通过云服务器定时往类 Slack 软件 BearyChat 发送一条消息。具体如下：&lt;/p&gt;
&lt;h4&gt;触发器&lt;/h4&gt;
&lt;p&gt;在服务器上设一个定时任务&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;服务器。 购买便宜的 VPS 作为服务器，每个月 2.5 美元，选择 Ubuntu 系统，方便设置定时任务。&lt;/li&gt;
&lt;li&gt;域名。在万网上购买 &lt;code&gt;zhihai.me&lt;/code&gt; ，便宜，一年十几块钱。没有对比 godaddy 一年多少钱。&lt;/li&gt;
&lt;li&gt;WEB 服务。部署基于 Django 的 Mezzanine ，省得自己折腾。为了学这个花了不少时间，顺便部署了一个 &lt;a href="http://zhihai.me"&gt;博客&lt;/a&gt; 。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;接收器&lt;/h4&gt;
&lt;p&gt;该 BearyChat 出场了。在客户端，以 BearyChat 作为消息接收工具。BearyChat 提供了 Ingoing 这个好用的工具。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>今日参考盈亏该如何计算</title><link href="https://hillerliao.github.io/dzpxkg.html" rel="alternate"></link><published>2017-11-03T19:57:57+08:00</published><updated>2017-11-03T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2017-11-03:/dzpxkg.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;证券
categories:&lt;/li&gt;
&lt;li&gt;证券&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;所需工具&lt;/h2&gt;
&lt;p&gt;今日参考盈亏该如何计算&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;算法一：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;今日参考盈亏额 ＝&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;（现价-昨日收盘价格）* (当前持股量-今日买入数量) //存 …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;证券
categories:&lt;/li&gt;
&lt;li&gt;证券&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;所需工具&lt;/h2&gt;
&lt;p&gt;今日参考盈亏该如何计算&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;算法一：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;今日参考盈亏额 ＝&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;（现价-昨日收盘价格）* (当前持股量-今日买入数量) //存量部分&lt;/li&gt;
&lt;li&gt;买入数量 * 现价 - 买入发生金额 //增量部分：买入&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;卖出金额 - 昨收价 * 卖出数量 // 卖出&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;算法二：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>开通工银亚洲账户的经历</title><link href="https://hillerliao.github.io/aoktqb.html" rel="alternate"></link><published>2017-09-01T19:57:57+08:00</published><updated>2017-09-01T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2017-09-01:/aoktqb.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;琐事
categories:&lt;/li&gt;
&lt;li&gt;琐事&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;富途证券通过支付宝上银汇款入金被拒。顺便想到出金问题。富途证券建议用境外银行卡，从境外卡汇款到境 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;琐事
categories:&lt;/li&gt;
&lt;li&gt;琐事&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;富途证券通过支付宝上银汇款入金被拒。顺便想到出金问题。富途证券建议用境外银行卡，从境外卡汇款到境内同名卡。因为境外机构账户往境内账号汇款容易失败，而个人同名卡之间汇款成功率高。&lt;/p&gt;
&lt;p&gt;该开通什么银行的账户？看到帖子《&lt;a href="https://xueqiu.com/4043855103/75461122"&gt;吐血整理！内地办理香港银行卡最强攻略！&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;联系招行信用卡客服索要最近三个月的纸质账单，收件地址为我的住所地址。这个用来证明居住地址的。不过后来才知道有办法不需要这个材料。&lt;/p&gt;
&lt;p&gt;打开工银亚洲网站，线上填写开户申请资料，打印申请表，确认可以线下见证的营业厅。&lt;/p&gt;
&lt;p&gt;拿着用公司打印机彩色打印的工银亚洲开户申请表，找附近支持工银亚洲线下见证的工行北京惠新支行。还没到银行开门我就已经在门口等候了。到了营业厅问询台，工作人员却告知办理工银亚洲线下见证的预约排队已经排到 2018 年 11 月！如果需要，我可以先做个预约，什么时候轮到我，就等电话通知吧？我说等明年 11 月，我都可能已经移民火星了。&lt;/p&gt;
&lt;p&gt;十分气愤，我反复质疑怎么可能要那么久，大声疾呼“不科学！让我预约是没有问题的，但要等一年多不科学。把排队名单给我看，不然我怎么相信你真的需要这么久？！”没有预约觉得理亏，我退一步：当天如果有人预约了没来，把这个空缺让给我，让我办理，不能让我那么辛苦专门请假白来一趟。必须告诉我今天是否有预约者无法前来办理。&lt;/p&gt;
&lt;p&gt;工作人员还算客气，给我去里面的办公室查了，过了一阵子，回来跟我说当天真的没有，都会来办理，第二天有人不来，我可以早点到，找工作人员要一个号，给我办理。我收行，病赔礼道歉，我态度不好，过于着急云云，并告诉她我开户的真实目的是投资境外股市。她很认真地指导我把能先填写签字的表格先填好，签名，除了日期留着办理当天再填写。相比线上工银亚洲公开的填写指引，她告诉我几个重要的修改：居住地址可以选择和身份证地址一样，如此一来就无需住址证明了；开户用途不要勾选发工资之类的，少填写为好，只需勾选两个，具体哪两个我已经忘记了。这两个地方真是潜规则呀，不去现场还不容易知道，害得我事先傻傻地找招行信用卡客服要最近三个月的纸质账单。&lt;/p&gt;
&lt;p&gt;离开银行回公司上班的路上，我顺便打电话咨询工商银行北辰支行，接电话的人告诉我，不支持护照办理，必须是签注有效期在三个月内的港澳台通行证才可以办理。预约队伍也排到了 2018 年的 7 月份。&lt;/p&gt;
&lt;p&gt;第二天一大早，带着已经准备好的材料再次前往工商银行惠新支行。40 分钟左右就办好了，给我一个保密信函和一个电子密码器。工作人员说我这次线下见证真是快。我说多亏了头一天她的同事亲自指导，少走了弯路。无需上传住址证明，确实让办理流程加快了不少。&lt;/p&gt;
&lt;p&gt;2017-08-30：工银亚洲来电话和我确认个人信息、收件地址等。提醒我注意汇入资金激活账户。&lt;/p&gt;
&lt;p&gt;2017 年 9 月 1 日，短信通知：&lt;em&gt;【工银亚洲】您的账户及银行服务已开通，请存入同名存款激活相关账户及银行服务。账户激活前一概拒纳收取任何非同名存款。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;对了，此时我该如何存款呢？账号在哪里？一会儿找客服确认。&lt;/p&gt;
&lt;p&gt;先分享到这里，若有错别字我再改。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>产品设计之列表设计要点</title><link href="https://hillerliao.github.io/urffxs.html" rel="alternate"></link><published>2017-08-30T19:57:57+08:00</published><updated>2017-08-30T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2017-08-30:/urffxs.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;产品设计
categories:&lt;/li&gt;
&lt;li&gt;产品设计&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;以交易记录列表为例，需要考虑一下几个地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问授权。
  是否需要登录才能访问。&lt;/li&gt;
&lt;li&gt;初始状态。
  为空时界 …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;产品设计
categories:&lt;/li&gt;
&lt;li&gt;产品设计&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;以交易记录列表为例，需要考虑一下几个地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问授权。
  是否需要登录才能访问。&lt;/li&gt;
&lt;li&gt;初始状态。
  为空时界面显示文案“该时段暂无记录”。&lt;/li&gt;
&lt;li&gt;翻页。
  每页显示 30 条记录。&lt;/li&gt;
&lt;li&gt;排序。&lt;/li&gt;
&lt;li&gt;按成交时间倒序；&lt;/li&gt;
&lt;li&gt;切换排序，是否可以按其他字段排序，正序与倒序。&lt;/li&gt;
&lt;li&gt;刷新。&lt;/li&gt;
&lt;li&gt;打开时刷新一次；&lt;/li&gt;
&lt;li&gt;3s 自动刷新一次；&lt;/li&gt;
&lt;li&gt;下拉刷新。&lt;/li&gt;
&lt;li&gt;缓存。
  客户端是否提供缓存，以提升体验，避免等待请求时页面为空。&lt;/li&gt;
&lt;li&gt;时间范围。
  默认显示当月的记录，可选择其他月份。&lt;/li&gt;
&lt;li&gt;显示字段。
  每条记录显示：股票名称、股票代码、市场、交易方向、成交价格、成交数量、成交时间。&lt;/li&gt;
&lt;li&gt;操作按钮。
  点击各行是否提供操作菜单。&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>如何通过IB模拟账号体验程序化交易</title><link href="https://hillerliao.github.io/gc9osg.html" rel="alternate"></link><published>2017-08-24T19:57:57+08:00</published><updated>2017-08-24T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2017-08-24:/gc9osg.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;证券
categories:&lt;/li&gt;
&lt;li&gt;证券&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;所需工具&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IB 账号信息&lt;/li&gt;
&lt;li&gt;通过老虎证券获取 IB 账号和密码&lt;/li&gt;
&lt;li&gt;登录 IB 后台，申请 &lt;a href="https://www.interactivebrokers.com/en/software/allocationfunds/topics/papertrader.htm"&gt;IB 模拟交易账号&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;抓包&lt;/li&gt;
&lt;li&gt;安卓本地抓包 …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;证券
categories:&lt;/li&gt;
&lt;li&gt;证券&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;所需工具&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IB 账号信息&lt;/li&gt;
&lt;li&gt;通过老虎证券获取 IB 账号和密码&lt;/li&gt;
&lt;li&gt;登录 IB 后台，申请 &lt;a href="https://www.interactivebrokers.com/en/software/allocationfunds/topics/papertrader.htm"&gt;IB 模拟交易账号&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;抓包&lt;/li&gt;
&lt;li&gt;安卓本地抓包工具 &lt;a href="https://github.com/JZ-Darkal/AndroidHttpCapture"&gt;HttpCapture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;包文件解析工具 &lt;a href="http://www.telerik.com/download/fiddler"&gt;Fiddler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IB API for Python&lt;/li&gt;
&lt;li&gt;&lt;a href="https://interactivebrokers.github.io/tws-api/classIBApi_1_1Contract.html#gsc.tab=0"&gt;IB 官方 API 文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/blampe/IbPy"&gt;IbPy 第三方 Python API&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://valiant-falstaff.github.io/IbPy-Getting-Started/"&gt;入门教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.quantstart.com/articles/Using-Python-IBPy-and-the-Interactive-Brokers-API-to-Automate-Trades"&gt;下单 DEMO&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;其他信息&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.interactivebrokers.com/en/index.php?f=16040"&gt;TWS 下载地址&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/getlantern/forum/issues/833"&gt;科学上网&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="blog"></category></entry><entry><title>ibpy-tutorial</title><link href="https://hillerliao.github.io/rmgp29.html" rel="alternate"></link><published>2017-08-23T19:57:57+08:00</published><updated>2017-08-23T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2017-08-23:/rmgp29.html</id><content type="html">&lt;ul&gt;
&lt;li&gt;证券
categories:&lt;/li&gt;
&lt;li&gt;证券&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href="https://valiant-falstaff.github.io/IbPy-Getting-Started/"&gt;IbPy Tutorial&lt;/a&gt;，流畅的行文，让我夜不能寐！希望能把它翻译成中文。&lt;/p&gt;</content><category term="blog"></category></entry><entry><title>我是如何复习迎考 Series 65 的</title><link href="https://hillerliao.github.io/hr3mpx.html" rel="alternate"></link><published>2014-11-26T19:57:57+08:00</published><updated>2014-11-26T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2014-11-26:/hr3mpx.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;琐事
categories:&lt;/li&gt;
&lt;li&gt;琐事&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;题记：这是 2014 年最后一天回顾当时的考试经历，可作为复习建议给后来者。原文首发于&lt;a href="https://xueqiu.com/1880228584/34685622"&gt;雪球&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;我是如何复习迎考 …&lt;/h2&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;琐事
categories:&lt;/li&gt;
&lt;li&gt;琐事&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;题记：这是 2014 年最后一天回顾当时的考试经历，可作为复习建议给后来者。原文首发于&lt;a href="https://xueqiu.com/1880228584/34685622"&gt;雪球&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;我是如何复习迎考 Series 65 的&lt;/h2&gt;
&lt;p&gt;2014 年底的 12 月 26 日，再战，终于通过 series 65 考试，得分 76%，比及格线高出 4 分，130 道题里做对了 99 道题，十分幸运。&lt;/p&gt;
&lt;h3&gt;初战失利&lt;/h3&gt;
&lt;p&gt;9 月份第一次考试前，也复习了一次，但完全不得要领。&lt;/p&gt;
&lt;p&gt;先把 wiley 的教材通读了一遍。看的时候就发现知识点之间的层级关系标注得非常乱，还不如 investopedia 里的编排来得清晰。但后者也有缺点，太简洁，解释不够详细。&lt;/p&gt;
&lt;p&gt;不像中国的考试，series65 在网上的资料非常少，基本没找到什么题目，也不知道题型是什么样的，国内考试经典的题海战术也无从发挥。好不容易从 quizlet 里找到一份开普兰的模拟题，做了一遍，大部分都做错。&lt;/p&gt;
&lt;p&gt;考前一个星期，突然醒悟过来，应该按照官方提供的考试大纲来复习，没提到的知识点不再纠结。比如教材花了一整章介绍期权知识，大纲里只要求理解期权的定义，并不要求灵活运用。此前看教材花了好多时间在该章节，对考试来说等于无用功。&lt;/p&gt;
&lt;p&gt;事已至此，只好硬着头皮上场，就像买彩票从来不中一样，整整差 10 道题。出考场，竟然下雨了。&lt;/p&gt;
&lt;p&gt;简单总结初战失败之因：&lt;/p&gt;
&lt;p&gt;思想上不够重视，以为不会比国内的类似考试更难。殊不知，美国的法律、监管结构、证券市场结构和国内有很大差别，仅凭土鳖的常识只能做对很小的一部分题目；&lt;/p&gt;
&lt;p&gt;语言障碍。有的句子，竟然单词意思都搞错，这个没什么好说的，英语要是好一点，至少看题目与选项也会快一些；&lt;/p&gt;
&lt;p&gt;教材没选好，wiley 没有严格按照大纲来编排教材，有的知识点有遗漏，有的讲得不够深入。&lt;/p&gt;
&lt;p&gt;没有按照大纲来复习。如对冲基金、遗产税等并没有深入理解透彻。&lt;/p&gt;
&lt;p&gt;做的题目不够多。&lt;/p&gt;
&lt;h3&gt;再战告捷&lt;/h3&gt;
&lt;p&gt;第二次考试，时间依然也比较紧迫。从 11 月底开始准备，在复习方法上作了调整：&lt;/p&gt;
&lt;p&gt;严格根据官方大纲复习，把每个知识点都了解清楚，根据 investopedia、wiley 教材、错题、中文资料、bing 搜出来的英文资料、法案原文，结合自己的理解，整理到 evernote 上，几乎是重新编排了一遍教材。如信托、遗产税、AMT、员工期权计划等知识点，专门找了一些中文资料来帮助理解。&lt;/p&gt;
&lt;p&gt;找到复习伙伴，复习路上不孤单。上述重编教材的工作，是我和考友一起通过 evernote 协作完成的。另外，我们还互相分享错题、难题，探讨不理解的地方。发现这样的方法很有效，讲解的过程也是再次理解的过程，如果对方不会的知识点，我能比较完整顺畅地说清楚，说明我已经理解了。&lt;/p&gt;
&lt;p&gt;做题，把能找到的题目，都做了一遍。主要有 quizlet 里开普兰的模拟题、investopedia 里的模拟题、wiley 里的题库，算下来估计有 800 百道题。&lt;/p&gt;
&lt;p&gt;通读法律法规。iaa、usa、model rule 打印出来翻一遍，增加感性认识。法律法规很枯燥，有的句子，从句一大堆，理解起来很费劲，需要耐心。&lt;/p&gt;
&lt;p&gt;把需要死记硬背的可能考点，单独记录，考前强化记忆。&lt;/p&gt;
&lt;h3&gt;用到的资料与工具&lt;/h3&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;官方大纲&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.nasaa.org/wp-content/uploads/2011/08/Series-65-Exam-Specification.pdf"&gt;Official Guidance&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;严格按照大纲来复习，多 Google，不要有遗漏，提到的知识点，基本上都会考到。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;法律法规&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.sec.gov/about/laws/iaa40.pdf"&gt;Iaa&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.nasaa.org/wp-content/uploads/2011/08/UniformSecuritesAct1956withcomments.pdf"&gt;Usa&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.nasaa.org/wp-content/uploads/2011/07/IA-Model-Rule-Definition-Under-2002-Act.pdf"&gt;Model Rule&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;教材&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.investopedia.com/exam-guide/series-65/"&gt;Investopedia&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;在线电子版，有些法律法规涉及到金额的可能会有些旧。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.securitiesexam.com/products/series65.html"&gt;securitiesexam.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://as.wiley.com/WileyCDA/WileyTitle/productCd-1119379741.html"&gt;Wiely&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;教材编排得凌乱。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;练习题&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.investopedia.com/quizzer/series65/"&gt;Investopedia&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://quizlet.com/subject/series-65/"&gt;Quizlet&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;有 App，可随时随地刷题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Wiely 习题&lt;/td&gt;
&lt;td&gt;有光盘，不过现在电脑都不带光驱了，没用到&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="blog"></category></entry><entry><title>玩转四方sybian s60v3体验报告</title><link href="https://hillerliao.github.io/aqhic9.html" rel="alternate"></link><published>2010-06-27T19:57:57+08:00</published><updated>2010-06-27T19:57:57+08:00</updated><author><name>hillerliao</name></author><id>tag:hillerliao.github.io,2010-06-27:/aqhic9.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;产品体验
categories:&lt;/li&gt;
&lt;li&gt;产品体验&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;安装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1 首次接入点设置&lt;/p&gt;
&lt;p&gt;首次安装后提示选择接入点，选好后进入登录/注册界面，由于我已经在 iphone 上 …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;产品体验
categories:&lt;/li&gt;
&lt;li&gt;产品体验&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;安装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1 首次接入点设置&lt;/p&gt;
&lt;p&gt;首次安装后提示选择接入点，选好后进入登录/注册界面，由于我已经在 iphone 上注册过，遂填写用户名与密码，点击登录。此时出现一个问题，界面提示“接入点错误，请重新选择”，可是，这个提示界面软键没有相应的菜单功能，也就不知道该去哪里操作接入点切换了就这个登录过程，重复了好几次，最终只好把软件卸载（如果我嫌麻烦不回头，就流失了一个用户，并且很可能我会告诉别人这个软件很垃圾），重新安装。&lt;/p&gt;
&lt;p&gt;可能的解决办法：&lt;/p&gt;
&lt;p&gt;办法 1：利用硬件功能。出错提示界面可以让用户通过左右软键激活菜单，从而可以选择接入点切换。&lt;/p&gt;
&lt;p&gt;办法 2:改变流程。就像注册流程的设计一样，等用户填写好了表单，点击提交（注册或登录按键）之后再提示用户选择接入点，这样，哪怕接入点一直出错，用户根据这个流程照样可以通过排除的办法，选择另一个接入点，直到正确为止。&lt;/p&gt;
&lt;p&gt;（后来陆续重装过几次，情况有变化：点击左软键，可出现接入点列表,供用户切换。第一次的体验还是挺重要的，可能会影响用户流失率）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;功能：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;2、&lt;strong&gt;注册、登录、注销&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;注册无需填写多少个文本域，尤其不需要验证码，也不需立即邮件激活，注册流程比较顺畅；&lt;/p&gt;
&lt;p&gt;注册界面输入域的输入类型控制，对搜狗拼音等智能拼音输入法不友好。（图）&lt;/p&gt;
&lt;p&gt;邮箱与密码输入框，不支持“En 智能英文”，自造的词（比如邮箱）没法用上，导致又要重复繁琐的邮箱输入，而手机上输入时最麻烦的事情之一。&lt;/p&gt;
&lt;p&gt;鉴于手机的特殊性，可以考虑让用户用手机号码登录。好处是：自己的手机号码容易记住，其次手机号码输入方便，不必像输入邮箱一样，在字母、数字、符号之间来回切换。当然，需要注意保护用户隐私，对外显示有另外的 id 替代手机号。&lt;/p&gt;
&lt;p&gt;注册时提示用户输入手机号，并注有“可选”字眼。作为软件提供商，获取用户手机号的目的是什么呢？能否明确告诉用户？毕竟手机号码是很重的隐私，而且常常容易被泄露，导致垃圾短信不断。如果想鼓励用户填写手机号，在信息设计上是否可以显示一些鼓励用户填写的文字，比如填写之后能获得什么好处？在减少用户隐私泄露之顾虑的同时，又能更多地收集到手机号码。&lt;/p&gt;
&lt;p&gt;然现在玩转四方没有让用户选择是否自动登录，直接自动登录，比较理想的是，考虑安全性，让用户选择是否自动登录。在有自动登录的情况下，可以考虑增加“记忆功能”，能够记住用户的输入历史，从而在用户输入帐号时，能够自动补全，减少输入的操作。&lt;/p&gt;
&lt;p&gt;”注销“在玩转四方是”切换用户“的表述，在菜单中的位置可以考虑紧邻“退出"，注销和退出时一组并列功能，符合用户的习惯。&lt;/p&gt;
&lt;p&gt;3、&lt;strong&gt;定位&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;定位比较准，但地图只是一个截屏，暂时不能实现缩放、移动等操作；&lt;/p&gt;
&lt;p&gt;附近地点、猜你喜欢；&lt;/p&gt;
&lt;p&gt;地图不可移动；当位置不准确时，无法手动调整。&lt;/p&gt;
&lt;p&gt;4、&lt;strong&gt;sns 常用功能有待提升&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;无法对好友动态与 tips 作点评；&lt;/p&gt;
&lt;p&gt;无法添加好友的好友为好友；&lt;/p&gt;
&lt;p&gt;无法点击”@XXX“查看朋友所 checkin 的地点；&lt;/p&gt;
&lt;p&gt;5、界面：&lt;/p&gt;
&lt;p&gt;挺照顾该系统的常用手机屏幕大小，设计上体现出节约空间的考虑，比如将标签切换放置于类似于窗口栏的位置。当然也可以考虑采取九宫格的设计。&lt;/p&gt;
&lt;p&gt;字体大小不能自定义，默认的文字显得有点小。&lt;/p&gt;
&lt;p&gt;6、交互：出错提示与解决办法；标签切换的一致性；退出无提示&lt;/p&gt;
&lt;p&gt;7、用户激励&lt;/p&gt;
&lt;p&gt;用户如何愿意发表观点、分享有价值的信息。可作一些提示与引导，类似“行吟诗人”的思路。&lt;/p&gt;
&lt;p&gt;8、反馈：没有反馈意见的入口 ，可通过让触发邮件程序，收集用户意见；mobile web 提交表单等其他方式。&lt;/p&gt;
&lt;p&gt;改进：鼓励用户发表体会的办法，激励机制；好友动态推送；活动推广信息&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;融合有关 LBS 的介绍&lt;/p&gt;
&lt;p&gt;等待界面&lt;/p&gt;
&lt;p&gt;*注册流程对比。可以考虑自动获取用户手机号，生成一个数字 id，eg 贝多；&lt;/p&gt;</content><category term="blog"></category></entry></feed>