<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>风琳</title>
        <link>https://www.lvy.life/</link>
        <description>一个NotionNext搭建的博客</description>
        <lastBuildDate>Mon, 22 Jun 2026 00:20:56 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2026, 吕行者</copyright>
        <item>
            <title><![CDATA[微博自动发布故障复盘：一次 browser 插件缺失引发的静默漏发]]></title>
            <link>https://www.lvy.life/article/2026/03/31/3341f2f0-5182-81ac-97fe-d22bee7658ea</link>
            <guid>https://www.lvy.life/article/2026/03/31/3341f2f0-5182-81ac-97fe-d22bee7658ea</guid>
            <pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[复盘一次真实的 AI 内容自动发布故障：表面现象是微博没有按时发出，真正根因却不是 cron、不是内容、也不是平台风控，而是 browser 插件未被加载，导致 publisher-weibo 在运行时失去真实发布能力并静默停在 pending。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3341f2f0518281ac97fed22bee7658ea"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-blue_background_co notion-block-3341f2f05182815cb363c6bd0a96ca49"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="🛠️">🛠️</span></div><div class="notion-callout-text">这是一篇关于内容自动发布链路的真实复盘：表面现象是“今天为什么没有发微博”，真正根因却不是 cron、不是内容、也不是微博风控，而是 browser 能力在运行环境里静默失效。</div></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f0518281518edeca628be3a695" data-id="3341f2f0518281518edeca628be3a695"><span><div id="3341f2f0518281518edeca628be3a695" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f0518281518edeca628be3a695" title="先说结论"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">先说结论</span></span></h3><div class="notion-text notion-block-3341f2f0518281fe80d7e30d1bb27d02">这次故障的直接现象是：publisher-weibo 的定时任务按时触发了，当天也确实存在可发内容，但微博没有自动发出去，内容状态一直停在 pending。</div><blockquote class="notion-quote notion-block-3341f2f0518281dfa395d4514cc4876d"><div>真正的根因是：publisher-weibo 依赖的 browser 能力在运行时不可用，导致真实发布步骤无法执行；同时流程又没有把这类能力缺失可靠地回写成 failed，于是任务看起来像“跑过了”，实际上只是静默停住。</div></blockquote><hr class="notion-hr notion-block-3341f2f05182810ea8ceff94a50d2703"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f051828146bba2cc166be04a75" data-id="3341f2f051828146bba2cc166be04a75"><span><div id="3341f2f051828146bba2cc166be04a75" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f051828146bba2cc166be04a75" title="一、故障背景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一、故障背景</span></span></h3><div class="notion-text notion-block-3341f2f051828107b08ae009f1fb4ef8">当天的内容流水线里，有两条已经进入微博分发阶段的内容：</div><ul class="notion-list notion-list-disc notion-block-3341f2f051828135adcfdd5822376c39"><li><code class="notion-inline-code">topic_20260331_skill_supply_chain_security</code></li></ul><ul class="notion-list notion-list-disc notion-block-3341f2f051828184b1afc4f13f206d9b"><li><code class="notion-inline-code">topic_20260331_verification_vs_confirmation</code></li></ul><div class="notion-text notion-block-3341f2f0518281c2b616f21efdffa9c1">两条内容都已经满足微博分发条件：candidate 状态为 drafted，distribution_targets 包含 weibo，对应 core draft 已存在。也就是说，从内容准备角度看，发布动作本来应该继续往下执行。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f0518281c59b21fb6b10e23856" data-id="3341f2f0518281c59b21fb6b10e23856"><span><div id="3341f2f0518281c59b21fb6b10e23856" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f0518281c59b21fb6b10e23856" title="二、第一层排查：不是 cron 没触发"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二、第一层排查：不是 cron 没触发</span></span></h3><div class="notion-text notion-block-3341f2f051828141b9acf7b30dbe362a">先查的是最容易怀疑的部分：定时任务有没有启动，publisher-weibo 有没有真正收到任务。结论很清楚：9:20 的 publisher-weibo daily publish 确实被 cron 正常触发，对应 agent session 也已经创建。</div><div class="notion-text notion-block-3341f2f05182811c95f8ff353931dc83">它还正常读取了 AGENTS.md、TASK_TEMPLATE.md、MEMORY.md、schema 文件、两条候选内容以及对应 core draft。</div><blockquote class="notion-quote notion-block-3341f2f051828154bcd4f190490144f3"><div>问题不是任务没跑，而是任务跑到中途停住了。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f05182815ab68be594e96992ef" data-id="3341f2f05182815ab68be594e96992ef"><span><div id="3341f2f05182815ab68be594e96992ef" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f05182815ab68be594e96992ef" title="三、第二层排查：不是没有内容可发"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三、第二层排查：不是没有内容可发</span></span></h3><div class="notion-text notion-block-3341f2f0518281199959da53fc18b50a">接着看候选文件本身。当时两条内容的 weibo 状态都还是 pending，但内容本身明显是完整的，尤其 skill_supply_chain_security 甚至已经有 MoltBook 成功记录。</div><div class="notion-text notion-block-3341f2f05182814ebd02e7ab0a3d603b">这说明问题不是“今天没有候选内容”，而是“有内容，但 publisher-weibo 没把真实发布动作走完”。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f05182818a9708fbbd6e530d0a" data-id="3341f2f05182818a9708fbbd6e530d0a"><span><div id="3341f2f05182818a9708fbbd6e530d0a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f05182818a9708fbbd6e530d0a" title="四、真正的根因：browser tool 当时根本不可用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">四、真正的根因：browser tool 当时根本不可用</span></span></h3><div class="notion-text notion-block-3341f2f0518281ee90fdfafa16ffb847">继续查 publisher-weibo 的会话日志和 OpenClaw 运行日志后，故障点终于显形。最关键的一条日志是：agents.publisher-weibo.tools.allow allowlist contains unknown entries (browser)。</div><div class="notion-text notion-block-3341f2f05182816695bff5bae1f388c4">这句话翻译成人话就是：对于当天 9:20 运行的 publisher-weibo 来说，browser 并不是一个可用工具。</div><div class="notion-text notion-block-3341f2f0518281ea9dfbfb97de59bf88">而任务模板又要求微博真实发布必须优先使用 browser tool，不能改走 shell，也必须先检查登录态。于是链路进入了一个典型死角：它知道必须走 browser，但 browser 在当时的环境里不可用，它又不能按规则绕路，最后流程只能停住。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f0518281b0bd63e50871f8ad2e" data-id="3341f2f0518281b0bd63e50871f8ad2e"><span><div id="3341f2f0518281b0bd63e50871f8ad2e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f0518281b0bd63e50871f8ad2e" title="五、为什么 browser 会不可用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">五、为什么 browser 会不可用</span></span></h3><div class="notion-text notion-block-3341f2f0518281f6b2dae8c740ccd11c">继续往下查，发现并不是 OpenClaw 删除了 browser 功能，而是 browser 插件没有真正加载进 Gateway。最开始看到的是：@openclaw/browser-plugin 状态是 disabled，openclaw help 里也没有 browser 子命令。</div><div class="notion-text notion-block-3341f2f051828175b5eeebeb9616627b">进一步查配置后发现，虽然 browser 相关 entry 已经被打开，但 plugins.allow 里缺少 browser。也就是说，browser 配置表面存在，但它没有进入最终允许加载的插件集合。</div><blockquote class="notion-quote notion-block-3341f2f0518281f39142d93b424b28c0"><div>真正根因不是 browser 没配置，而是 browser 没被允许加载。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f051828194a6efde03999a3010" data-id="3341f2f051828194a6efde03999a3010"><span><div id="3341f2f051828194a6efde03999a3010" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f051828194a6efde03999a3010" title="六、修复动作：不是只开开关，而是把插件真正放进白名单"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">六、修复动作：不是只开开关，而是把插件真正放进白名单</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-3341f2f051828177a8bddade327ff977" style="list-style-type:decimal"><li>确认 browser 相关配置开启：browser.enabled = true，plugins.entries.browser.enabled = true。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3341f2f0518281e7bda7d2e3b643cba8" style="list-style-type:decimal"><li>把 browser 明确加入 plugins.allow。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3341f2f05182813ca42cf9dda9f42f77" style="list-style-type:decimal"><li>重启 Gateway，让 browser 插件用新配置重新注册。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3341f2f05182817da1abc03afa089a74" style="list-style-type:decimal"><li>验证恢复结果：browser 插件重新变成 loaded，openclaw browser 命令恢复可见，browser control service 开始正常监听。</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f0518281f4bec9d070fb452705" data-id="3341f2f0518281f4bec9d070fb452705"><span><div id="3341f2f0518281f4bec9d070fb452705" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f0518281f4bec9d070fb452705" title="七、补发微博：验证修复是否有效"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">七、补发微博：验证修复是否有效</span></span></h3><div class="notion-text notion-block-3341f2f051828129b624db86f942a62f">环境修好之后，没有停在“理论上应该可以了”。而是做了两步验证：先人工补发当天漏掉的微博，再手动重跑 publisher-weibo 的 cron，验证它能否先查重、再补记录、再继续自动发布。</div><div class="notion-text notion-block-3341f2f0518281fa93bde0184315ebfc">最终结果是：一条内容被识别为已发过并补齐记录，另一条内容成功自动发布。两条内容都把 weibo 状态更新为 success。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f0518281789bebd716ebfd01d0" data-id="3341f2f0518281789bebd716ebfd01d0"><span><div id="3341f2f0518281789bebd716ebfd01d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f0518281789bebd716ebfd01d0" title="八、这次故障真正暴露的问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">八、这次故障真正暴露的问题</span></span></h3><ul class="notion-list notion-list-disc notion-block-3341f2f0518281a1ab62f9f86591e0ca"><li>运行环境能力缺失：browser 插件没加载，publisher-weibo 因此失去真实发布能力。</li></ul><ul class="notion-list notion-list-disc notion-block-3341f2f0518281f592cdf85249ad6d2c"><li>失败没有被可靠回写：当 browser tool 不可用时，流程没有明确写回 failed 和 last_error，而是静默留在 pending。</li></ul><div class="notion-callout notion-yellow_background_co notion-block-3341f2f0518281e483a4ed8a91a49d4e"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="⚠️">⚠️</span></div><div class="notion-callout-text">自动化系统最危险的故障，往往不是直接报错，而是任务表面上跑过了，状态却没有告诉你它其实已经失效。</div></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3341f2f0518281569ef0e4b3e8bb4336" data-id="3341f2f0518281569ef0e4b3e8bb4336"><span><div id="3341f2f0518281569ef0e4b3e8bb4336" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3341f2f0518281569ef0e4b3e8bb4336" title="九、后续建议"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">九、后续建议</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-3341f2f0518281a29a99dbde5b7772d7" style="list-style-type:decimal"><li>对关键依赖做前置自检。像 browser 这种能力，任务启动前就应该检查是否可用。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3341f2f05182810ba903e00706c60a80" style="list-style-type:decimal"><li>遇到能力缺失时必须写回 last_error。至少让外部一眼能看出不是“今天没内容”，而是“当前环境缺少发布能力”。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3341f2f05182818c833cf498796d5b38" style="list-style-type:decimal"><li>保留查重和补记逻辑。真正成熟的自动发布系统，不只是能发，而是能查重、能补记、能容错、能恢复。</li></ol><hr class="notion-hr notion-block-3341f2f0518281f2a4e8d98a8bacff21"/><div class="notion-callout notion-teal_background_co notion-block-3341f2f0518281a9a915ec13f72a74b2"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="✅">✅</span></div><div class="notion-callout-text">一句话总结：这次不是微博没内容可发，而是 publisher-weibo 在 browser 插件失效时静默停在了 pending；修复 browser 插件加载后，链路已经恢复正常，并通过手动重跑任务完成了自动发布验证。</div></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenClaw 安装指南：从零开始搭建你的本地 AI 助手]]></title>
            <link>https://www.lvy.life/article/2026/03/10/openclaw-install-guide</link>
            <guid>https://www.lvy.life/article/2026/03/10/openclaw-install-guide</guid>
            <pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[一篇面向新手的 OpenClaw 安装入门指南，包含安装前准备、初始化、登录授权、常见配置与排错建议。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-31f1f2f0518281af91caddde407a7524"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-31f1f2f05182816db172c735b8317008">如果你想在自己的电脑上装一个能长期协作、能接消息、还能直接帮你处理本地工作区事务的 AI 助手，OpenClaw 是一个很顺手的选择。它不是那种“装完就结束”的工具，而更像一个可以慢慢养起来的个人助手系统。</div><div class="notion-text notion-block-31f1f2f0518281ecbb30e39389385c65">这篇文章不讲太多抽象概念，重点是三件事：怎么装、怎么跑、怎么尽快开始用。你可以把它理解成一篇面向新手的 OpenClaw 上手实战文。</div><blockquote class="notion-quote notion-block-31f1f2f0518281789a60e9a6c4f97162"><div>先安装，再跑通，再慢慢打磨配置。对大多数人来说，这比一开始就追求完美更有效。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f0518281d4b074d83b875f312d" data-id="31f1f2f0518281d4b074d83b875f312d"><span><div id="31f1f2f0518281d4b074d83b875f312d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f0518281d4b074d83b875f312d" title="一、OpenClaw 适合什么人"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一、OpenClaw 适合什么人</span></span></h3><div class="notion-text notion-block-31f1f2f051828155b829ee38421ec67c">如果你只是偶尔和模型聊几句，网页聊天工具可能已经够用了。但如果你希望助手能持续记住工作区、接入消息平台、读写本地文件、执行自动化任务，那 OpenClaw 会更合适。</div><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281719e6de4194e18d4c3"><li>想把 AI 当成长期协作助手，而不是一次性聊天工具的人</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f051828177b57bd7648bf52e3e"><li>希望把消息、文件、技能、定时任务串起来的人</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f05182819e8dccc53b665055ca"><li>愿意在自己的电脑上维护一个可控、本地优先的助手环境的人</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f0518281ef8ba8f9d514889d7c" data-id="31f1f2f0518281ef8ba8f9d514889d7c"><span><div id="31f1f2f0518281ef8ba8f9d514889d7c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f0518281ef8ba8f9d514889d7c" title="二、安装前要准备什么"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二、安装前要准备什么</span></span></h3><div class="notion-text notion-block-31f1f2f0518281bda6adc2e988964cc6">正式安装前，先准备好几个基础条件。这样后面会顺很多。</div><ul class="notion-list notion-list-disc notion-block-31f1f2f051828171af41d92df61fb661"><li>一台可正常联网的电脑，macOS 和 Linux 都比较合适</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f05182810db9dbd49331ff74b2"><li>Node.js 22 或更高版本</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281fba777e57a4cb26682"><li>一个可用的模型登录方式；如果支持网页授权，可以不手填 API Key</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281adb9e5da1982a152a9"><li>预留一个工作区目录，用来放配置、技能、记忆和项目文件</li></ul><div class="notion-text notion-block-31f1f2f0518281609548d79a2a65af68">如果你以后还想接 Telegram、企业微信、Notion 这类外部服务，也可以先不急着一次性全接好，先把 OpenClaw 主体跑起来再说。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f051828161b0f3ce9e81bb3de5" data-id="31f1f2f051828161b0f3ce9e81bb3de5"><span><div id="31f1f2f051828161b0f3ce9e81bb3de5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f051828161b0f3ce9e81bb3de5" title="三、安装 OpenClaw"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三、安装 OpenClaw</span></span></h3><div class="notion-text notion-block-31f1f2f0518281d7a8f4e337665490f7">OpenClaw 常见的安装方式是通过 npm 或 pnpm。先确认 Node.js 已安装，再执行下面的命令：</div><div class="notion-text notion-block-31f1f2f0518281368b0bff63bd8578ce">安装完成后，建议先检查一下命令是否生效：</div><div class="notion-text notion-block-31f1f2f05182812dae78d951cab76ba9">如果这里提示命令找不到，通常是全局安装路径还没有加入 PATH。这类问题先别急着怀疑 OpenClaw 本身，十有八九是 Node 的全局命令路径没配好。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f05182810e9010ca2ac942b0fc" data-id="31f1f2f05182810e9010ca2ac942b0fc"><span><div id="31f1f2f05182810e9010ca2ac942b0fc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f05182810e9010ca2ac942b0fc" title="四、第一次初始化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">四、第一次初始化</span></span></h3><div class="notion-text notion-block-31f1f2f0518281cca7acc93df04edad0">第一次使用时，最省事的方式就是直接跑初始化引导：</div><div class="notion-text notion-block-31f1f2f0518281b2a029f729725285a9">引导过程中，通常会让你确认这些内容：</div><ul class="notion-list notion-list-disc notion-block-31f1f2f05182816d856ae2ce4d0c3c49"><li>工作区目录放在哪里</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f051828134ae26ee051ab19e9e"><li>默认使用哪个模型</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f05182817ba2def94b2666107e"><li>是否通过网页登录授权</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281a4b0a3ddd04690a4be"><li>是否启用一些基础功能</li></ul><div class="notion-text notion-block-31f1f2f051828139bad3edc9dc23b1b4">如果你不想自己维护 API Key，而是更希望像网页登录那样完成授权，那么按提示走 OAuth 就行。这种方式一般更省心，也更适合个人使用。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f05182813d89f7eb1ef6a4fc77" data-id="31f1f2f05182813d89f7eb1ef6a4fc77"><span><div id="31f1f2f05182813d89f7eb1ef6a4fc77" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f05182813d89f7eb1ef6a4fc77" title="五、安装完成后先做什么"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">五、安装完成后先做什么</span></span></h3><div class="notion-text notion-block-31f1f2f05182816e9517c2f28a39f410">很多人装完就停在“命令能跑”这一步，其实真正重要的是：确认它能正常工作。建议你装好以后，立刻做这几步检查。</div><div class="notion-text notion-block-31f1f2f0518281dab205dc9e162b12be">如果你启用了网关，也顺手看一下：</div><div class="notion-text notion-block-31f1f2f0518281e6b51ccfa1885ec48b">这几条命令能帮你快速判断：当前有没有正常运行、有没有更新、网关是不是活着。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f0518281dc97f3fb4388da5c41" data-id="31f1f2f0518281dc97f3fb4388da5c41"><span><div id="31f1f2f0518281dc97f3fb4388da5c41" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f0518281dc97f3fb4388da5c41" title="六、怎么开始真正用起来"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">六、怎么开始真正用起来</span></span></h3><div class="notion-text notion-block-31f1f2f0518281558934f17509e7458c">OpenClaw 最有价值的地方，不是“能安装”，而是“能进入你的日常流程”。比较推荐的入门方式是从最小可用开始。</div><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281feb869fd92beb5fcc8"><li>先让它处理简单任务，比如查天气、整理文件、生成文档</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281d5a4d0f3adecd69329"><li>把你常用的工作内容放进 workspace</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281bda2d0e1911fecc8a2"><li>需要时再接入 Notion、Telegram、企业微信等外部入口</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f051828155a62dd6b5c0d3fcaf"><li>把重复性任务逐步改造成定时任务或固定工作流</li></ul><div class="notion-text notion-block-31f1f2f05182813faba1d1b93a6b1640">不要一上来就想把所有能力一次性配满。真正好用的助手，往往都是边用边长出来的。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f0518281a09a16c84a3ab8d01a" data-id="31f1f2f0518281a09a16c84a3ab8d01a"><span><div id="31f1f2f0518281a09a16c84a3ab8d01a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f0518281a09a16c84a3ab8d01a" title="七、常见问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">七、常见问题</span></span></h3><div class="notion-text notion-block-31f1f2f0518281cfa84bcb85fa8a887d">1）命令找不到怎么办？</div><div class="notion-text notion-block-31f1f2f0518281c095e3dd4770fd6e65">优先检查 Node.js 是否正确安装、npm/pnpm 全局路径是否进入 PATH。</div><div class="notion-text notion-block-31f1f2f051828178bc3fef42a812bf26">2）模型为什么不可用？</div><div class="notion-text notion-block-31f1f2f0518281ea8d15d34e570a2fa9">先看登录状态，再看默认模型配置，最后看网络连通性。</div><div class="notion-text notion-block-31f1f2f05182813f8ba3fff8b22ee652">3）消息平台为什么不工作？</div><div class="notion-text notion-block-31f1f2f051828154b19fd35ce581d70b">一般优先检查 token、allowlist、配对状态，以及对应插件是否启用。</div><div class="notion-text notion-block-31f1f2f0518281c19c01dd159b218063">4）安全审计出现 warning 要不要紧？</div><div class="notion-text notion-block-31f1f2f05182815e9323d942119b831d">多数 warning 不是马上会出事故的高危项，但最好尽早收紧，比如插件 allowlist、插件版本固定、防火墙状态、外网暴露方式。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f0518281a0a01ec1d619fef137" data-id="31f1f2f0518281a0a01ec1d619fef137"><span><div id="31f1f2f0518281a0a01ec1d619fef137" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f0518281a0a01ec1d619fef137" title="八、装好之后的建议"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">八、装好之后的建议</span></span></h3><ul class="notion-list notion-list-disc notion-block-31f1f2f051828193add6dc33c16110b0"><li>先跑一次安全审计：openclaw security audit --deep</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f05182813e80ade69f7a8d8f46"><li>再确认更新状态：openclaw update status</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f05182819a9027c921912b0d5b"><li>如果是个人电脑，建议打开系统防火墙并保留磁盘加密</li></ul><ul class="notion-list notion-list-disc notion-block-31f1f2f0518281f48ad6e999a19e615e"><li>接第三方服务时，尽量用最小权限原则</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-31f1f2f051828106a91cfdf0eca7f2c4" data-id="31f1f2f051828106a91cfdf0eca7f2c4"><span><div id="31f1f2f051828106a91cfdf0eca7f2c4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#31f1f2f051828106a91cfdf0eca7f2c4" title="结语"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">结语</span></span></h3><div class="notion-text notion-block-31f1f2f051828142b556f31fdccc3bd1">OpenClaw 适合那种“不是只想聊几句，而是真想把助手养起来”的使用方式。安装本身不难，真正拉开体验差距的，是你是否愿意把它接入自己的工作区、笔记系统和日常流程。</div><div class="notion-text notion-block-31f1f2f0518281acb68df26f062c3f37">如果你刚开始接触，最好的节奏不是追求一步到位，而是先让它稳定跑起来，再一点点把你自己的习惯和需求塞进去。等你用顺手之后，它就不只是一个模型入口，而会更像一个真正的个人助手。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[我是怎么把内容系统从一个全能 Agent 拆成多 Agent ]]></title>
            <link>https://www.lvy.life/article/2026/03/24/32d1f2f0-5182-8036-af09-d0338ef78663</link>
            <guid>https://www.lvy.life/article/2026/03/24/32d1f2f0-5182-8036-af09-d0338ef78663</guid>
            <pubDate>Tue, 24 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[这篇文章系统总结了我把内容系统从“一个全能 Agent”逐步拆分成多 Agent 流水线的过程。最初我试图让同一个 Agent 同时承担采集、筛选、写作、发布和复盘，但很快发现这样会让判断标准混在一起，系统也会迅速退化成搬运工。后来我把流程拆成 collector、reviewer、writer-core 和多个 publisher，让每个 Agent 只做一件事：collector 负责忠实采集，reviewer 负责主题归并与新增价值判断，writer-core 负责生成平台无关的核心稿，publisher 则分别面向微博、Notion 和 Moltbook 做多端适配和发布。文章重点分析了拆分过程中遇到的几个核心问题，包括采集与筛选不能混做、reviewer 应该“筛主题”而不是“筛素材”、多发布端必须基于一份 core draft 二次适配、以及多平台状态设计为什么比角色命名更重要。最终沉淀出的原则是：多 Agent 的价值不在于角色越多越高级，而在于每一层职责清晰、状态可控、错误可恢复，这样内容系统才不会沦为机械搬运，而会更像一个真正做过、想过、踩过坑之后持续输出判断的系统。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-32d1f2f051828036af09d0338ef78663"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280e5aaf1fb6ff2c5f7ae" data-id="32d1f2f0518280e5aaf1fb6ff2c5f7ae"><span><div id="32d1f2f0518280e5aaf1fb6ff2c5f7ae" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280e5aaf1fb6ff2c5f7ae" title="一、背景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一、背景</span></span></h3><div class="notion-text notion-block-32d1f2f0518280a79a8ada73eebf5997">这段时间我一直在做一件事：</div><div class="notion-text notion-block-32d1f2f051828042966de981f175271f"><b>搭一套能持续产出内容、但又不至于退化成搬运工的多 Agent 内容系统。</b></div><div class="notion-text notion-block-32d1f2f0518280c7ab45ced7bdf4790b">我最初的目标并不是做一个“看起来很复杂”的系统，而是想解决一个很实际的问题：</div><blockquote class="notion-quote notion-block-32d1f2f05182808a90e1e5b62fa6ae06"><div>怎么让内容系统既能自动跑起来，又能保留真实经验、判断和复盘感，而不是变成“看到一条发一条”的流水线。</div></blockquote><div class="notion-text notion-block-32d1f2f0518280609f6aec0febf9a292">一开始，我直觉上会觉得：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828096ab40c5b24f196076"><li>既然有 OpenClaw</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280e4ae49f9761a632b3e"><li>有浏览器能力</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182804c9cfac1129f6d0c6c"><li>有 cron</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c7a413e8f7d86d9d27"><li>有多 agent</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182804b9d14e39bc8f1a51f"><li>干脆做一个“全能 Agent”就好了</li></ul><div class="notion-text notion-block-32d1f2f05182809dbf26c49f1aa81c43">它负责：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182803698c5ffdd873ca271"><li>采集</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b7a380d57e4e6ad3e2"><li>判断价值</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280698abaeeb792c88255"><li>合并主题</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b587e0eeef890a28d1"><li>生成文案</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280888a56f1bb4fdba738"><li>发布到微博</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280f4a654e4f9a6354af0"><li>发布到 Notion</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280fcacc0f55da129e33e"><li>再发到 Moltbook</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182802a9f55f7f3f2673424"><li>最后更新状态、记住经验</li></ul><div class="notion-text notion-block-32d1f2f05182803fbc47db91b6e9d4f8">听起来很完整。</div><div class="notion-text notion-block-32d1f2f0518280efa912fc8220e50f78">但真正做起来以后，我很快发现：</div><div class="notion-text notion-block-32d1f2f0518280249cfaf0850fe9f0f1"><b>多 Agent 系统最容易犯的第一个错误，不是能力不足，而是让一个 Agent 做太多事。</b></div><div class="notion-text notion-block-32d1f2f051828082b060e63b6bcbe319">后来我一步步把它拆开，最后形成了现在这条流水线：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280f7a787e0d5273dc865"><li><code class="notion-inline-code">collector-moltbook</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182803e8261c4cf7fa68170"><li><code class="notion-inline-code">collector-ops-log</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182808d8870c9552a8b57c9"><li><code class="notion-inline-code">reviewer</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182803aabf3c6606d523448"><li><code class="notion-inline-code">writer-core</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280039b44c636758f6f01"><li><code class="notion-inline-code">publisher-weibo</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828008a9c6fdd479e4df97"><li><code class="notion-inline-code">publisher-notion</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b6a1b8efdeff542a81"><li><code class="notion-inline-code">publisher-moltbook</code></li></ul><div class="notion-text notion-block-32d1f2f0518280ae89f0f323a68203ec">这篇文章想系统整理一下：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182803fa17fe0d25432d77f"><li>为什么要这么拆</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182804abcbdd66b9ebbae85"><li>每一层的职责是什么</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280629214ecd0b350d5f6"><li>过程中踩了哪些坑</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182805482ffc1a3d4727d5e"><li>最后沉淀出了哪些设计原则</li></ul><hr class="notion-hr notion-block-32d1f2f0518280c7a004eb69a95c46b6"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280aa8e7eecf14814588b" data-id="32d1f2f0518280aa8e7eecf14814588b"><span><div id="32d1f2f0518280aa8e7eecf14814588b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280aa8e7eecf14814588b" title="二、为什么一开始会想做多 Agent"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二、为什么一开始会想做多 Agent</span></span></h3><div class="notion-text notion-block-32d1f2f0518280f49f62d858d50f9a90">我做多 Agent，不是为了“证明 multi-agent 很高级”，而是因为内容系统天然存在多个层级。</div><div class="notion-text notion-block-32d1f2f05182804a89cbd36da53bfe20">我真正想实现的不是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c1ad0cc37beb0f13ba"><li>看到一条新闻，转一条</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182807f95bac0be391d9338"><li>看到一个帖子，总结一条</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828075b6afc1b1bca91313"><li>看到一个热点，再换个说法发一次</li></ul><div class="notion-text notion-block-32d1f2f0518280d5b1ebdbd642645a30">我真正想实现的是：</div><ol start="1" class="notion-list notion-list-numbered notion-block-32d1f2f0518280caa4e9ebe1ee0124cb" style="list-style-type:decimal"><li>先收集多个来源的信息</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-32d1f2f0518280f5831aeb19ba16152b" style="list-style-type:decimal"><li>再把同一主题的内容归并起来</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-32d1f2f0518280c8937be159f224b3cd" style="list-style-type:decimal"><li>理解这些内容之间的共识与分歧</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-32d1f2f05182807f840ae2921b3b2f56" style="list-style-type:decimal"><li>基于这些信息形成自己的判断</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-32d1f2f0518280d98fa4e3b9eb52de20" style="list-style-type:decimal"><li>最后输出有新增价值的表达</li></ol><div class="notion-text notion-block-32d1f2f05182802cb166c625302bfc0d">一旦目标变成这样，系统就天然会分层：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280358695c49323655912"><li>收集</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828073902ac32f5af7fa75"><li>筛选</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182803f95b0e42ed7539d0b"><li>归并</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828095bce1de053615ff7b"><li>写作</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828047b252f0f0748d3625"><li>发布</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c096baf756e61186d2"><li>复盘</li></ul><div class="notion-text notion-block-32d1f2f051828061a6e7cc93c501006f">而这时，“一个 Agent 全包”很快就会开始失控。</div><hr class="notion-hr notion-block-32d1f2f05182806b8309f4ab6d1242a9"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f05182807990c9c0656931ef41" data-id="32d1f2f05182807990c9c0656931ef41"><span><div id="32d1f2f05182807990c9c0656931ef41" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182807990c9c0656931ef41" title="三、为什么一个全能 Agent 很快会失控"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三、为什么一个全能 Agent 很快会失控</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280078da4d8d105409891" data-id="32d1f2f0518280078da4d8d105409891"><span><div id="32d1f2f0518280078da4d8d105409891" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280078da4d8d105409891" title="1. 判断标准会混在一起"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 判断标准会混在一起</span></span></h4><div class="notion-text notion-block-32d1f2f0518280468bafd4a7a66c0b51">最早我让一个 Agent 同时负责：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a0805ac6896bbc1afb"><li>收素材</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b58ae8c86bacf40f15"><li>判断值不值得留</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182802f89b2c197e1b50f39"><li>决定今天写什么</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d4a836ea5e692c9895"><li>写文案</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182807e9031f9b5fe48e7b1"><li>发布</li></ul><div class="notion-text notion-block-32d1f2f051828018ad4ec09fa12be4b5">后来发现最直接的问题是：</div><div class="notion-text notion-block-32d1f2f0518280a2bdbee478f12c6146"><b>“值得采集”和“值得发布”根本不是同一件事。</b></div><div class="notion-text notion-block-32d1f2f0518280b09e73e394c537c126">一条内容可能：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182803fb4d1d7f3b68f0243"><li>值得采集，因为它提供了一个话题线索</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280daa6fde93052154a1e"><li>不值得直接发，因为还没有新增价值</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280f3976cc2d238d772ec"><li>值得进 Notion 沉淀，但不适合发微博</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280ddab26f54c2a677714"><li>适合发 Moltbook，但不适合做公开短帖</li></ul><div class="notion-text notion-block-32d1f2f05182804a9f1dd15e8f8f87ae">如果同一个 Agent 同时处理这些判断，它就会不断提前替下游做决定。</div><div class="notion-text notion-block-32d1f2f05182805aa894d5bf8a4dab93">最后系统会出现两种极端：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280dcb09bf9290d5e7e2a"><li>要么太保守，前面就把很多潜在线索过滤掉</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280eb8136eee1d439cbe2"><li>要么太宽松，后面一路放行，最后变成搬运工</li></ul><hr class="notion-hr notion-block-32d1f2f05182807d8ff7de0110eadfa7"/><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280ad9dd5e5eca5d3ad0d" data-id="32d1f2f0518280ad9dd5e5eca5d3ad0d"><span><div id="32d1f2f0518280ad9dd5e5eca5d3ad0d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280ad9dd5e5eca5d3ad0d" title="2. 同一个任务里混了太多目标"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 同一个任务里混了太多目标</span></span></h4><div class="notion-text notion-block-32d1f2f05182803e8c18eb8e9e2ec440">collector 的职责本来应该是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280fda20ee716b6d48a18"><li>忠实获取信息</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280e3920ed0d26508887e"><li>标准化信息</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d0a8b8e2f8abffa14d"><li>尽量少做价值判断</li></ul><div class="notion-text notion-block-32d1f2f0518280f0b5adedb2fb747923">但如果 collector 同时还承担“这条值不值得写”，它就会开始带着下游目标去看素材。</div><div class="notion-text notion-block-32d1f2f0518280cd9b97fba60f5a4712">结果就是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182808cb12cdd76b295683e"><li>采集阶段开始脑补价值</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280dc8d29cf677530491d"><li>采集阶段开始提前裁剪</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828019a0eafeb60eaa99db"><li>系统在最前面就开始失真</li></ul><div class="notion-text notion-block-32d1f2f0518280f28694e38fc7f23c93">后来我越来越确定一件事：</div><blockquote class="notion-quote notion-block-32d1f2f051828096b4badeed9592a3b6"><div><b>多 Agent 的关键，不是多几个角色，而是每个角色只做一件事。</b></div></blockquote><hr class="notion-hr notion-block-32d1f2f0518280c3b740d625262cbd04"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f05182802296f0e1dfaaa397f7" data-id="32d1f2f05182802296f0e1dfaaa397f7"><span><div id="32d1f2f05182802296f0e1dfaaa397f7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182802296f0e1dfaaa397f7" title="四、第一层拆分：collector 和 reviewer 必须分开"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">四、第一层拆分：collector 和 reviewer 必须分开</span></span></h3><div class="notion-text notion-block-32d1f2f051828025b52cd24674148aa0">这是我最早踩到、也最早确认必须坚持的原则。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f051828032848eedde2d79fae4" data-id="32d1f2f051828032848eedde2d79fae4"><span><div id="32d1f2f051828032848eedde2d79fae4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f051828032848eedde2d79fae4" title="为什么采集和筛选必须分开"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么采集和筛选必须分开</span></span></h3><div class="notion-text notion-block-32d1f2f0518280ab86b7c44edc76302f">如果让 collector 既采集又筛选，它会天然倾向于只留下“自己觉得有价值”的内容。</div><div class="notion-text notion-block-32d1f2f05182806b8a59c0d9072f1f78">但 LLM 对“有价值”的判断其实并不稳定：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b1baf5ce2186b89f7e"><li>同一条内容，不同时间判断可能不同</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280688098eaa353fb31ff"><li>同一条内容，换一句提示词结果可能不同</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280aea390fc03c3e01040"><li>同一条内容，今天觉得平，明天觉得能写</li></ul><div class="notion-text notion-block-32d1f2f0518280978d3cfe58b7bcb303">而采集阶段最怕的就是这种不稳定。</div><div class="notion-text notion-block-32d1f2f0518280369057cfb862f99f7a">所以后来我把这一层明确拆开。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280e8aa5ec30cc7bbcdf4" data-id="32d1f2f0518280e8aa5ec30cc7bbcdf4"><span><div id="32d1f2f0518280e8aa5ec30cc7bbcdf4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280e8aa5ec30cc7bbcdf4" title="collector-moltbook"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><code class="notion-inline-code">collector-moltbook</code></span></span></h4><div class="notion-text notion-block-32d1f2f051828024b77dea6423ebc384">只负责：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280419c9bebb888f991db"><li>从 Moltbook 收内容</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182805588ccf1dce96cf6cf"><li>标准化成统一 JSON</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280739224de2ed352c6d2"><li>写入 <code class="notion-inline-code">inbox/</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b486f4c42be02a625c"><li>设置：</li><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b486f4c42be02a625c"><li><code class="notion-inline-code">status = raw</code></li><li><code class="notion-inline-code">owner = reviewer</code></li></ul></ul><div class="notion-text notion-block-32d1f2f0518280259049f24fbffad252">它不负责判断“值不值得发”。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280d89888ef9e31dc7f44" data-id="32d1f2f0518280d89888ef9e31dc7f44"><span><div id="32d1f2f0518280d89888ef9e31dc7f44" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280d89888ef9e31dc7f44" title="reviewer"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><code class="notion-inline-code">reviewer</code></span></span></h4><div class="notion-text notion-block-32d1f2f0518280a39587c1c579ec62e2">再负责：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182805d8e63df418c4bc158"><li>去重</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828052bce2d59ff52558b8"><li>判断价值</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828085aac5d94ed2192158"><li>主题归并</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828064aafff12bcf3f86e4"><li>决定哪些内容继续往下流转</li></ul><div class="notion-text notion-block-32d1f2f0518280929de8e29b585563cb">这个拆分做完以后，系统立刻稳了很多。</div><hr class="notion-hr notion-block-32d1f2f05182809d9557ce043d8e562b"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280e8b3efca2ebbdcb09c" data-id="32d1f2f0518280e8b3efca2ebbdcb09c"><span><div id="32d1f2f0518280e8b3efca2ebbdcb09c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280e8b3efca2ebbdcb09c" title="五、第二层升级：reviewer 不应该筛素材，而应该筛主题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">五、第二层升级：reviewer 不应该筛素材，而应该筛主题</span></span></h3><div class="notion-text notion-block-32d1f2f05182808d8ec7d24a59d50fa6">这是我整个系统里最关键的一次升级。</div><div class="notion-text notion-block-32d1f2f05182809f82adf2b7209b1673">一开始 reviewer 只是普通筛选器：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182800daffacf85fff66b05"><li>看一条 raw</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182809e9419c9525e979dda"><li>打个分</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280bca161c1d2f6935cd7"><li>决定通过 / 拒绝</li></ul><div class="notion-text notion-block-32d1f2f0518280488e67f9095c1c57fe">但后来我发现，这样还是不够。</div><div class="notion-text notion-block-32d1f2f05182803b8085e918852ff079">因为如果 reviewer 还是逐条判断，那 writer 拿到的仍然是“单条素材”。</div><div class="notion-text notion-block-32d1f2f05182801fb4c2cfef3e9133ee">而单条素材天然会把系统往这条路上带：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280e69fa4f7d01f2ed5a6"><li>收一条</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182806c9052c27b3e2d3c85"><li>改一条</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280ebbaddfda696de733c"><li>发一条</li></ul><div class="notion-text notion-block-32d1f2f0518280ceba53e894da38501c">这本质上还是很容易退化成搬运流。</div><div class="notion-text notion-block-32d1f2f0518280a69913ed6bf200d813">后来我把 reviewer 的职责改成了：</div><blockquote class="notion-quote notion-block-32d1f2f05182806bbb8debc827489728"><div><b>不判断这条能不能发，而是判断今天最值得写的主题是什么。</b></div></blockquote><div class="notion-text notion-block-32d1f2f0518280ffaaf0c5eb495af001">它的工作变成：</div><ol start="1" class="notion-list notion-list-numbered notion-block-32d1f2f051828034a962dbf08589cf6e" style="list-style-type:decimal"><li>读取多条 raw 素材</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-32d1f2f051828099b9a0e70350439eb2" style="list-style-type:decimal"><li>按主题聚类</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-32d1f2f05182800f98cfe9a206f30d3c" style="list-style-type:decimal"><li>提炼：</li><ol class="notion-list notion-list-numbered notion-block-32d1f2f05182800f98cfe9a206f30d3c" style="list-style-type:lower-alpha"><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280699bdfdcb3ede88526"><li>大家都在说什么</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280ca89fcfc9753424949"><li>哪些信息是重复的</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182808ea4c7c6a1135b4598"><li>哪些观点互相冲突</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a3b50dcee943762f43"><li>哪些角度还没说透</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182802398e0e405967837a1"><li>最值得补充的新增价值是什么</li></ul></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-32d1f2f0518280299ef9dc22227b3efa" style="list-style-type:decimal"><li>产出 candidate</li></ol><div class="notion-text notion-block-32d1f2f0518280d490dbc4f4c7dcdd25">这时候 <code class="notion-inline-code">candidate</code> 的含义也变了。</div><div class="notion-text notion-block-32d1f2f05182803d853fdb6523b0bbb9">它不再是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828032b98dc9e7f41372a1"><li>一条待写素材</li></ul><div class="notion-text notion-block-32d1f2f0518280dfbfa6d32f7d7c461f">而变成：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280148696f73d0bb5e5fe"><li>一个已经经过归并、提炼和判断的候选主题</li></ul><div class="notion-text notion-block-32d1f2f0518280ed9cd5c6d0f73b5058">这一步之后，我才真正觉得系统开始脱离“搬运流水线”。</div><hr class="notion-hr notion-block-32d1f2f05182806c9e90ff5d10498cf5"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f05182803491dcf9ca16e05c50" data-id="32d1f2f05182803491dcf9ca16e05c50"><span><div id="32d1f2f05182803491dcf9ca16e05c50" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182803491dcf9ca16e05c50" title="六、第三层拆分：writer 不应该直接写平台稿，而应该先写 core draft"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">六、第三层拆分：writer 不应该直接写平台稿，而应该先写 core draft</span></span></h3><div class="notion-text notion-block-32d1f2f0518280f9bbced27862a9344b">最开始我有一个 <code class="notion-inline-code">writer-publisher-weibo</code>，它做的是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828051ae6bec1593ad8faa"><li>读取 candidate</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182809e948cde39a8fbfe62"><li>改写成微博</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182806ea466e3a09789bcc2"><li>直接发出去</li></ul><div class="notion-text notion-block-32d1f2f0518280ab85f0fcf755b84248">这个设计在只有微博的时候还勉强说得过去。</div><div class="notion-text notion-block-32d1f2f051828000bc73e64870b609f2">但一旦平台变成：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182802eba8ec57244eee031"><li>微博</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280508e33ca3c80e48bf8"><li>Notion</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182808181ffc16d59e1c8c1"><li>Moltbook</li></ul><div class="notion-text notion-block-32d1f2f0518280d7b6e0d729b81bc235">问题就立刻暴露出来了。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f051828040ac69ccc0578f8b43" data-id="32d1f2f051828040ac69ccc0578f8b43"><span><div id="32d1f2f051828040ac69ccc0578f8b43" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f051828040ac69ccc0578f8b43" title="原因很简单"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原因很简单</span></span></h4><div class="notion-text notion-block-32d1f2f0518280febc98c57229797655">微博、Notion、Moltbook 根本不是同一种表达环境。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280f78c26fcbe0f4fb570" data-id="32d1f2f0518280f78c26fcbe0f4fb570"><span><div id="32d1f2f0518280f78c26fcbe0f4fb570" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280f78c26fcbe0f4fb570" title="微博需要："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">微博需要：</span></span></h4><ul class="notion-list notion-list-disc notion-block-32d1f2f05182801ea1b4df7ab4b84180"><li>更短</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280988f50c727ab25c053"><li>更直接</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c2872df80ffa485d4b"><li>更快给出判断</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280818f4efdddee7844b0"><li>适合即时传播</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280bc9330deb79de7a4c8" data-id="32d1f2f0518280bc9330deb79de7a4c8"><span><div id="32d1f2f0518280bc9330deb79de7a4c8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280bc9330deb79de7a4c8" title="Notion 需要："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Notion 需要：</span></span></h4><ul class="notion-list notion-list-disc notion-block-32d1f2f051828008a291cec6e6d86153"><li>更完整</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828047a2f4f346a8cdba32"><li>更结构化</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280f9b231e605aba7fc9c"><li>适合沉淀</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182802ab7e5dd42bb8af10d"><li>方便以后复用</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f05182806985ebf774c2fb1c19" data-id="32d1f2f05182806985ebf774c2fb1c19"><span><div id="32d1f2f05182806985ebf774c2fb1c19" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182806985ebf774c2fb1c19" title="Moltbook 需要："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Moltbook 需要：</span></span></h4><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d38e69cf1683817358"><li>更像真实的 field notes</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280aa9561cf629eb64647"><li>有过程感</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d7b778d2cd20129e15"><li>有 agent 社区里的经验交流感</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182801c950dc8863f492045"><li>不是微博短帖，也不是知识库文档</li></ul><div class="notion-text notion-block-32d1f2f0518280438050d3c054926c44">如果 writer 直接写微博稿，那再想拿去发 Notion 或 Moltbook，效果一定会变差。</div><div class="notion-text notion-block-32d1f2f0518280acbc71cd2e68e5dc2a">于是后来我把写作层拆成：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280ce9a2ed60db596405c" data-id="32d1f2f0518280ce9a2ed60db596405c"><span><div id="32d1f2f0518280ce9a2ed60db596405c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280ce9a2ed60db596405c" title="writer-core"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><code class="notion-inline-code">writer-core</code></span></span></h4><div class="notion-text notion-block-32d1f2f051828074a2ece697cff3469a">只做一件事：</div><blockquote class="notion-quote notion-block-32d1f2f05182802ea8e1d374747002c0"><div>把 candidate 写成一份平台无关的核心稿（core draft）</div></blockquote><div class="notion-text notion-block-32d1f2f0518280f1b866d5e779b46aec">这份 core draft 不是终稿，而是一份母稿。</div><div class="notion-text notion-block-32d1f2f05182806597fbf03a900cd177">它应该具备：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280458ba2e41427c68195"><li>明确主题</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280e98b22f94395b26bcc"><li>核心判断</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b893c8d8132f579cfd"><li>支撑判断的关键信息</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182800e9e23f0f2bfd74b0e"><li>可延展方向</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182808785cacb49e41c6634"><li>足够的信息密度</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828002bc4bd93dbafc3880"><li>但不带过强的平台口吻</li></ul><div class="notion-text notion-block-32d1f2f0518280c3aecada29278734c1">这一步让我真正接受了一件事：</div><blockquote class="notion-quote notion-block-32d1f2f0518280dca131c88bbf65040e"><div><b>“一份理解，多端发布” 的关键，不是多个平台共用同一份终稿，而是多个平台共用同一份母稿。</b></div></blockquote><hr class="notion-hr notion-block-32d1f2f051828089ad2ddd8a1c1b7290"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f051828021a092c13f5f16fd04" data-id="32d1f2f051828021a092c13f5f16fd04"><span><div id="32d1f2f051828021a092c13f5f16fd04" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f051828021a092c13f5f16fd04" title="七、第四层拆分：publisher 必须按平台拆开"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">七、第四层拆分：publisher 必须按平台拆开</span></span></h3><div class="notion-text notion-block-32d1f2f0518280c0b88ce1b9825ef64d">有了 core draft 之后，发布层就必须拆开。</div><div class="notion-text notion-block-32d1f2f051828081b9bbe7fd9b6dd41c">后来我把它分成：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a49f55e0853aba0e5e"><li><code class="notion-inline-code">publisher-weibo</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828057a15ee18b11c3e8f1"><li><code class="notion-inline-code">publisher-notion</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828018821ac48b5bd2a97e"><li><code class="notion-inline-code">publisher-moltbook</code></li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f05182802eaaaeca3e0d612158" data-id="32d1f2f05182802eaaaeca3e0d612158"><span><div id="32d1f2f05182802eaaaeca3e0d612158" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182802eaaaeca3e0d612158" title="publisher-weibo"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><code class="notion-inline-code">publisher-weibo</code></span></span></h4><div class="notion-text notion-block-32d1f2f0518280998df6f3f0cfed3307">负责：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280bc813de0f1e234855b"><li>读取 core draft</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828059a6f0e32945965994"><li>适配成微博版本</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182802fbcf2e98887e3aa6e"><li>执行发布</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828047965ccca4145bbac5"><li>写 publish-record</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c698f5f743339a59d9"><li>更新 <code class="notion-inline-code">publish_state.weibo</code></li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280c1981bd76578043a00" data-id="32d1f2f0518280c1981bd76578043a00"><span><div id="32d1f2f0518280c1981bd76578043a00" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280c1981bd76578043a00" title="publisher-notion"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><code class="notion-inline-code">publisher-notion</code></span></span></h4><div class="notion-text notion-block-32d1f2f051828045a861e75ce2e6ec24">负责：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828026b2a0e4a7ac68a0b6"><li>读取 core draft</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280dbb1ccd4cf9bd46791"><li>整理成适合沉淀的结构</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280198a6df80233cfc9ea"><li>调 Notion API 发布</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182807fae59ddb2c0959da4"><li>写 publish-record</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c3b36dcd713a163bf2"><li>更新 <code class="notion-inline-code">publish_state.notion</code></li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f05182804d89dee3e0c72975a4" data-id="32d1f2f05182804d89dee3e0c72975a4"><span><div id="32d1f2f05182804d89dee3e0c72975a4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182804d89dee3e0c72975a4" title="publisher-moltbook"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><code class="notion-inline-code">publisher-moltbook</code></span></span></h4><div class="notion-text notion-block-32d1f2f0518280f0ac48fc0e14b5cb9f">负责：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280749e25e35abb34a5d4"><li>读取 core draft</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182803e920df038eb79f740"><li>改写成更适合 Moltbook 的表达</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828046a433f755591ff245"><li>调 Moltbook API 发布</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182805582b8d9464a4c1570"><li>写 publish-record</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a58e5cff14174954ff"><li>更新 <code class="notion-inline-code">publish_state.moltbook</code></li></ul><div class="notion-text notion-block-32d1f2f05182809588e3c17c36232c19">这样之后，一个主题就变成：</div><div class="notion-text notion-block-32d1f2f05182801a8b0bf96ee08dd4bc"><b>reviewer → writer-core → 多个 publisher 各自适配</b></div><div class="notion-text notion-block-32d1f2f0518280c887ccf6e9c0c45959">这才是真正意义上的多平台分发。</div><hr class="notion-hr notion-block-32d1f2f051828016ac2df3b2d0223355"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f05182804a8b1aceeae64d75f0" data-id="32d1f2f05182804a8b1aceeae64d75f0"><span><div id="32d1f2f05182804a8b1aceeae64d75f0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182804a8b1aceeae64d75f0" title="八、过程中踩过的关键坑"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">八、过程中踩过的关键坑</span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f05182806dab09cc0a670ea1a0" data-id="32d1f2f05182806dab09cc0a670ea1a0"><span><div id="32d1f2f05182806dab09cc0a670ea1a0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182806dab09cc0a670ea1a0" title="1. schema 不能一开始拍脑袋定完"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. schema 不能一开始拍脑袋定完</span></span></h3><div class="notion-text notion-block-32d1f2f0518280988497e3ee96586bea">一开始我写了很多 example：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828099a603f55206a7c854"><li><code class="notion-inline-code">content-item.example.json</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182807f95fbe78a78809301"><li><code class="notion-inline-code">draft-item.example.json</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b2a785c88efb03e48f"><li><code class="notion-inline-code">publish-record.example.json</code></li></ul><div class="notion-text notion-block-32d1f2f0518280e194d2d1caf0b38161">但后来很快发现，schema 不能只靠想象设计。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280db9344f0c1cc8c0341" data-id="32d1f2f0518280db9344f0c1cc8c0341"><span><div id="32d1f2f0518280db9344f0c1cc8c0341" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280db9344f0c1cc8c0341" title="最明显的问题有两个"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">最明显的问题有两个</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280eb8816db712c866653" data-id="32d1f2f0518280eb8816db712c866653"><span><div id="32d1f2f0518280eb8816db712c866653" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280eb8816db712c866653" title="问题一：单条素材和候选主题混在一起"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">问题一：单条素材和候选主题混在一起</span></span></h4><div class="notion-text notion-block-32d1f2f05182807b9455ff0deca0c295">最开始 <code class="notion-inline-code">content-item</code> 更像单条素材。</div><div class="notion-text notion-block-32d1f2f051828025b9f4e55d9b4b54bf">后来 reviewer 产出的其实已经不是“单条素材”，而是“候选主题”。</div><div class="notion-text notion-block-32d1f2f0518280fd82c9c221c10102be">我没有立刻新建 <code class="notion-inline-code">topic-item</code>，而是先做兼容，在 <code class="notion-inline-code">extra</code> 中加入：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280bcaeddfedcac68d1fd"><li><code class="notion-inline-code">merged_source_ids</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182800ca491d7eb93444b8c"><li><code class="notion-inline-code">consensus</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828027af16c40ca4202a82"><li><code class="notion-inline-code">differences</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182805c82ced555b8dd4411"><li><code class="notion-inline-code">unsaid_angle</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c28f42cda6c840e39c"><li><code class="notion-inline-code">new_value</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c48c78fde637b6cf5a"><li><code class="notion-inline-code">recommended_angle</code></li></ul><div class="notion-text notion-block-32d1f2f05182802fa82df009eb2bb799">这是一个很典型的经验：</div><blockquote class="notion-quote notion-block-32d1f2f0518280e684bed81b2ed34097"><div>先让 schema 兼容真实流转，再考虑彻底重构。</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280ceb195f9b15a6a125b" data-id="32d1f2f0518280ceb195f9b15a6a125b"><span><div id="32d1f2f0518280ceb195f9b15a6a125b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280ceb195f9b15a6a125b" title="问题二：状态不能只有一个总状态"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">问题二：状态不能只有一个总状态</span></span></h4><div class="notion-text notion-block-32d1f2f051828017a90bd6db2e33da17">一开始只有：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280838cd5dd0ad67add34"><li><code class="notion-inline-code">candidate</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b9bd57ce230ac0c914"><li><code class="notion-inline-code">drafted</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280ea9569cf62a9e4f9ac"><li><code class="notion-inline-code">published</code></li></ul><div class="notion-text notion-block-32d1f2f0518280dea02ae70420b73f71">但一旦同一主题要同时发：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828053a39acfaad974c64f"><li>微博</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b58cf5c29ee2099ce5"><li>Notion</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280f79d53cd05fbd66af2"><li>Moltbook</li></ul><div class="notion-text notion-block-32d1f2f05182809b86fae2b36d5eec4a">问题就出来了。</div><div class="notion-text notion-block-32d1f2f0518280f385e8ebeb71b2317e">比如微博先发了，如果立刻把总状态改成 <code class="notion-inline-code">published</code>，那 Notion 和 Moltbook 后面就接不到。</div><div class="notion-text notion-block-32d1f2f0518280edbbe2c68d2b96837d">后来我把状态拆成两层：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f05182805c9f7cf9ae06dcc753" data-id="32d1f2f05182805c9f7cf9ae06dcc753"><span><div id="32d1f2f05182805c9f7cf9ae06dcc753" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182805c9f7cf9ae06dcc753" title="总状态"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">总状态</span></span></h4><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280849f33c46f85184983"><li><code class="notion-inline-code">candidate</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828099a6ade5eb472b3cfb"><li><code class="notion-inline-code">drafted</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280bcb246e06285fac1a6"><li><code class="notion-inline-code">published</code></li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280849e76cc72dc5c6abf" data-id="32d1f2f0518280849e76cc72dc5c6abf"><span><div id="32d1f2f0518280849e76cc72dc5c6abf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280849e76cc72dc5c6abf" title="平台状态"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">平台状态</span></span></h4><div class="notion-text notion-block-32d1f2f051828036927df072a25dad28">放进：</div><div class="notion-text notion-block-32d1f2f05182800fa41fc48623b17f5b">然后规则变成：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828051a2b2fe9907619afc"><li>单个平台成功，只更新自己的状态</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280bb8494c390effa165f"><li>只有所有目标平台都 success，才把总状态改成 <code class="notion-inline-code">published</code></li></ul><div class="notion-text notion-block-32d1f2f0518280ef970ff57ab5729c8d">这一步对多 publisher 系统至关重要。</div><hr class="notion-hr notion-block-32d1f2f0518280f0aaf7d6fd64fc5869"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280daaccee3c49319a219" data-id="32d1f2f0518280daaccee3c49319a219"><span><div id="32d1f2f0518280daaccee3c49319a219" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280daaccee3c49319a219" title="2. Notion 发布成功，不只是“能写进去”"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. Notion 发布成功，不只是“能写进去”</span></span></h3><div class="notion-text notion-block-32d1f2f051828096aa25e82a69aef65d">一开始我以为：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182805aa808c24a552fec94"><li>API 通了</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c9b766ce6dd661bd52"><li>页面建出来了</li></ul><div class="notion-text notion-block-32d1f2f0518280579f27ff121dac5070">就算发布成功。</div><div class="notion-text notion-block-32d1f2f0518280998961f42b4ab1b2f0">后来才发现，对于真实业务来说，这远远不够。</div><div class="notion-text notion-block-32d1f2f05182800782d2e48659cbcc1e">比如对我的 Notion 内容库来说，发布成功不仅意味着“页面存在”，还意味着：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828078ac9ec69bb82690ba"><li>标题必须是中文</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828016889ce7d1683e62ff"><li><code class="notion-inline-code">status</code> 必须是 <code class="notion-inline-code">Published</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280f7a656dd9a0d326a0a"><li>字段映射必须符合数据库要求</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d4bee6c667ca2ba773"><li>目标位置必须明确</li></ul><div class="notion-text notion-block-32d1f2f05182809984f3fa124881f48d">所以后来 <code class="notion-inline-code">publisher-notion</code> 的成功条件变成了字段级的，而不是动作级的。</div><div class="notion-text notion-block-32d1f2f0518280a3b43cf7239ba830aa">我最终得到的结论是：</div><blockquote class="notion-quote notion-block-32d1f2f0518280b1b315d8bf5bb6abb3"><div>自动化系统里最容易被忽略的，不是“能不能执行”，而是“执行结果是否符合业务语义”。</div></blockquote><hr class="notion-hr notion-block-32d1f2f05182803aab43fa0f4a1ce536"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280039de4f1ffee1ce178" data-id="32d1f2f0518280039de4f1ffee1ce178"><span><div id="32d1f2f0518280039de4f1ffee1ce178" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280039de4f1ffee1ce178" title="3. 微博发布链路里，不能假设 agent 一定有 browser tool"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 微博发布链路里，不能假设 agent 一定有 browser tool</span></span></h3><div class="notion-text notion-block-32d1f2f05182809d97f0efa59df9467a">这也是一个非常实际的坑。</div><div class="notion-text notion-block-32d1f2f051828003b555d42cafbcfeed">一开始我把 <code class="notion-inline-code">publisher-weibo</code> 写得很理想化：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182805e9037d99393f7a30b"><li>必须优先使用 browser tool</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280278cd3ceaa1a8c9ef3"><li>禁止通过 shell 调 <code class="notion-inline-code">openclaw browser</code> CLI</li></ul><div class="notion-text notion-block-32d1f2f0518280fba905cebc17caa4b2">结果真跑的时候才发现：</div><div class="notion-text notion-block-32d1f2f0518280e7a6def50b2e9728f2">当前 agent 实际拿到的工具只有：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828047929ef5e80172abe8"><li><code class="notion-inline-code">exec</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182800d8de2cf0820089971"><li><code class="notion-inline-code">read</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280bd8189c8539bf91227"><li><code class="notion-inline-code">write</code></li></ul><div class="notion-text notion-block-32d1f2f0518280a7b48de7f4b50d3c66">没有独立 browser tool。</div><div class="notion-text notion-block-32d1f2f051828067ba22c7b61a61bad5">这就导致规则要求必须 browser tool，但运行时根本没这个工具，最后陷入死锁。</div><div class="notion-text notion-block-32d1f2f0518280ccaa91f0de045c4336">后来我才真正接受：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828008b320d4d338bbd8b4"><li>底层浏览器能力可能是同一套</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280e99a29eae90a93f26e"><li>但对 agent 来说，“原生 tool” 和 “通过 exec 间接调用 CLI” 是不同层次</li></ul><div class="notion-text notion-block-32d1f2f0518280ba8e72f60b12fe4c52">于是后来我把规则改成：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c7aeecd0ec21bb9ba7"><li>优先使用 browser tool</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828029b004de1cab275cc4"><li>如果当前环境没有独立 browser tool，但有 <code class="notion-inline-code">exec</code>，允许回退到 <code class="notion-inline-code">openclaw browser</code> CLI</li></ul><div class="notion-text notion-block-32d1f2f0518280a28b95e4f31d6ef584">这个坑让我重新理解了一件事：</div><blockquote class="notion-quote notion-block-32d1f2f051828016afa8d11c0277c290"><div>设计时不能只按理想架构写规则，还要考虑当前运行环境到底能提供什么能力。</div></blockquote><hr class="notion-hr notion-block-32d1f2f05182809184a9f2ac56ad117c"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f05182801eb4aae3e762721593" data-id="32d1f2f05182801eb4aae3e762721593"><span><div id="32d1f2f05182801eb4aae3e762721593" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182801eb4aae3e762721593" title="4. Moltbook 没发出去，不一定是 publisher 的锅"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. Moltbook 没发出去，不一定是 publisher 的锅</span></span></h3><div class="notion-text notion-block-32d1f2f0518280468a3dcce225c683ae">这几天 Moltbook 没发出去，我一开始也以为是 <code class="notion-inline-code">publisher-moltbook</code> 有问题。</div><div class="notion-text notion-block-32d1f2f0518280edb2c2fc7ae3f89b9a">后来逐层检查才发现，问题其实更早出在上游。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f05182801dbdb6fa7a8b669b23" data-id="32d1f2f05182801dbdb6fa7a8b669b23"><span><div id="32d1f2f05182801dbdb6fa7a8b669b23" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182801dbdb6fa7a8b669b23" title="第一层问题：reviewer 没稳定写 distribution_targets"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第一层问题：reviewer 没稳定写 <code class="notion-inline-code">distribution_targets</code></span></span></h4><div class="notion-text notion-block-32d1f2f0518280a88982f3c254fda2fb">有些旧主题带了 <code class="notion-inline-code">moltbook</code>，但很多新主题没有。</div><div class="notion-text notion-block-32d1f2f0518280a6a409dd9c0c80eefd">这说明 reviewer 在“应该发到哪些平台”这件事上，判断规则不够稳定。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280ceabffc1f6a174b01e" data-id="32d1f2f0518280ceabffc1f6a174b01e"><span><div id="32d1f2f0518280ceabffc1f6a174b01e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280ceabffc1f6a174b01e" title="第二层问题：writer-core 没初始化 publish_state.moltbook"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第二层问题：writer-core 没初始化 <code class="notion-inline-code">publish_state.moltbook</code></span></span></h4><div class="notion-text notion-block-32d1f2f05182800bbf2dcd984fa34ea9">它只初始化了：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280cdb32feac659f28041"><li><code class="notion-inline-code">weibo</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182800cb834e84970a1b04c"><li><code class="notion-inline-code">notion</code></li></ul><div class="notion-text notion-block-32d1f2f0518280cbadd3f0646ed15138">忘了：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a1bb89df4cc792cadc"><li><code class="notion-inline-code">moltbook</code></li></ul><div class="notion-text notion-block-32d1f2f05182808880d3e2b757bd7861">这意味着即使 reviewer 把 <code class="notion-inline-code">moltbook</code> 放进了 <code class="notion-inline-code">distribution_targets</code>，后面的状态依然不完整。</div><div class="notion-text notion-block-32d1f2f0518280c38895e73bb1f60f8f">这个坑让我更确定一件事：</div><blockquote class="notion-quote notion-block-32d1f2f051828035876ff4287deff99a"><div>多 agent 系统里，很多下游问题，真正的根源都在上游字段不统一、职责边界没写死。</div></blockquote><hr class="notion-hr notion-block-32d1f2f0518280cd9e9dd72e200651e0"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280d9afc1f62b0c8a1f7c" data-id="32d1f2f0518280d9afc1f62b0c8a1f7c"><span><div id="32d1f2f0518280d9afc1f62b0c8a1f7c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280d9afc1f62b0c8a1f7c" title="九、最后沉淀出的设计原则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">九、最后沉淀出的设计原则</span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280f1abe8dbc2e1cb8fb5" data-id="32d1f2f0518280f1abe8dbc2e1cb8fb5"><span><div id="32d1f2f0518280f1abe8dbc2e1cb8fb5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280f1abe8dbc2e1cb8fb5" title="原则一：每个 Agent 只做一件事"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原则一：每个 Agent 只做一件事</span></span></h3><div class="notion-text notion-block-32d1f2f05182809ab830d8b90b8a2a4f">collector 就采集。</div><div class="notion-text notion-block-32d1f2f05182809aa9eff83bcb1a5f3c">reviewer 就归并和判断。</div><div class="notion-text notion-block-32d1f2f05182800b94d1f158d15141cc">writer-core 就写母稿。</div><div class="notion-text notion-block-32d1f2f051828052b258c68dc987374e">publisher 就只负责适配和发布。</div><div class="notion-text notion-block-32d1f2f05182801ca76fd5969ba28a1a">一旦一个 agent 同时承担多个目标，它就会开始替下游做决定。</div><hr class="notion-hr notion-block-32d1f2f0518280319a3dc338c39960f0"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280658a8cca9766481e79" data-id="32d1f2f0518280658a8cca9766481e79"><span><div id="32d1f2f0518280658a8cca9766481e79" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280658a8cca9766481e79" title="原则二：收集、筛选、写作、发布必须分层"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原则二：收集、筛选、写作、发布必须分层</span></span></h3><div class="notion-text notion-block-32d1f2f0518280da8137e2e33544dd16">这四层不能混。</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280968b85dee587f87ab9"><li>收集负责忠实获取信息</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182804694b0cfeaba337758"><li>筛选负责形成主题判断</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b188f6f30d87a360d3"><li>写作负责形成表达骨架</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d9b3eac6c4e438abca"><li>发布负责适配平台和执行动作</li></ul><div class="notion-text notion-block-32d1f2f05182809688e9fb1fd20cc8c2">混在一起，系统必乱。</div><hr class="notion-hr notion-block-32d1f2f0518280bcacc9efade6e9f59d"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f05182809c9275e61457273ea2" data-id="32d1f2f05182809c9275e61457273ea2"><span><div id="32d1f2f05182809c9275e61457273ea2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182809c9275e61457273ea2" title="原则三：不要逐条转发信息，要先形成主题理解"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原则三：不要逐条转发信息，要先形成主题理解</span></span></h3><div class="notion-text notion-block-32d1f2f0518280c28191f9572c19eb47">如果系统最后只是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280cf83d1ceb77c9c3d07"><li>收一条</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d79dc0c4abf750fc26"><li>改一条</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280ba9daff9fdbb812683"><li>发一条</li></ul><div class="notion-text notion-block-32d1f2f05182805db28cfca180d1fac8">那它迟早会退化成搬运工。</div><div class="notion-text notion-block-32d1f2f0518280b78e8ad9d4dd0b8b1c">真正有价值的是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d099faf140a42e5b2a"><li>多条信息</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182800ebee1fc7201db8d30"><li>一个主题</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280ba8067fcddbbe55d21"><li>一次判断</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828034913ccee079deb16a"><li>一份表达</li></ul><hr class="notion-hr notion-block-32d1f2f05182808c90bcc3537dc087bc"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f051828012a2ebd0ddc20c9fa4" data-id="32d1f2f051828012a2ebd0ddc20c9fa4"><span><div id="32d1f2f051828012a2ebd0ddc20c9fa4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f051828012a2ebd0ddc20c9fa4" title="原则四：多发布端不是多抄几份，而是一份母稿多端适配"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原则四：多发布端不是多抄几份，而是一份母稿多端适配</span></span></h3><div class="notion-text notion-block-32d1f2f051828024bfd0c06bb9680f46">不要让微博稿兼容 Notion。</div><div class="notion-text notion-block-32d1f2f0518280c9bc7adf8cdfd4c828">不要让 Notion 页兼容 Moltbook。</div><div class="notion-text notion-block-32d1f2f0518280709f39cb4155ec5653">不要让 writer 直接面向所有平台写终稿。</div><div class="notion-text notion-block-32d1f2f0518280f384cbce5da52817ec">正确方式是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828037b69cdc9ddff036f0"><li>一份 core draft</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182801ea9a1f4f8bb03f3ff"><li>多个平台各自适配</li></ul><hr class="notion-hr notion-block-32d1f2f051828066a039ec398dd083b9"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f051828027a224f2c45523b841" data-id="32d1f2f051828027a224f2c45523b841"><span><div id="32d1f2f051828027a224f2c45523b841" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f051828027a224f2c45523b841" title="原则五：状态设计比角色设计更重要"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原则五：状态设计比角色设计更重要</span></span></h3><div class="notion-text notion-block-32d1f2f0518280e49f34ce05c93fa190">角色好起名字，状态难设计。</div><div class="notion-text notion-block-32d1f2f05182807da51bc8707bf1bf1d">真正难的是：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280149bd8ce9eae268e42"><li>owner 怎么流转</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280f4891fcf232f6a2c82"><li>status 怎么变化</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182808a80c8d608f76d6f66"><li>多 publisher 怎么互不阻塞</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280149bd9f53781464c3d"><li>失败后怎么恢复</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b2912ef841d76580de"><li>成功后怎么收口</li></ul><div class="notion-text notion-block-32d1f2f05182802eb93be962de9361ff">如果状态没想清楚，多 agent 只会越拆越乱。</div><hr class="notion-hr notion-block-32d1f2f0518280c89d17f9a5f56b0aff"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f0518280298977e4af10ddb898" data-id="32d1f2f0518280298977e4af10ddb898"><span><div id="32d1f2f0518280298977e4af10ddb898" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280298977e4af10ddb898" title="原则六：长期偏好放记忆层，流程规则写死在 AGENTS.md"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原则六：长期偏好放记忆层，流程规则写死在 AGENTS.md</span></span></h3><div class="notion-text notion-block-32d1f2f0518280fea7a8d01060699326">像这些内容：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c39d97e9a08e4b3128"><li>当前关注主题</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d79666d937fc915bf4"><li>账号定位</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280188e8cc6ccffa90067"><li>风格偏好</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182804397eefda3d1556be3"><li>质量阈值</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828031b99fd376a55ada3b"><li>最近不想重复的话题</li></ul><div class="notion-text notion-block-32d1f2f0518280e88cabd3227bb49758">更适合放进：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280998f21dd2b872842f5"><li><code class="notion-inline-code">MEMORY.md</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280aaaf24feee039e1fcc"><li><code class="notion-inline-code">USER.md</code></li></ul><div class="notion-text notion-block-32d1f2f05182806f9283df9e1067fa1b">而不是反复改 <code class="notion-inline-code">AGENTS.md</code>。</div><div class="notion-text notion-block-32d1f2f051828046ab02f15b5b3d421b"><code class="notion-inline-code">AGENTS.md</code> 更适合写死：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f051828092b197cfc1f989e879"><li>职责</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280b08f30cf1580ebf830"><li>输入输出</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280748aaeeceb4d430705"><li>状态流转</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280e5921bedf77cb5776f"><li>成功条件</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828083864eef874541123d"><li>失败处理</li></ul><hr class="notion-hr notion-block-32d1f2f0518280578f1fc87bb1ea4052"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f051828056a009ee0e92375181" data-id="32d1f2f051828056a009ee0e92375181"><span><div id="32d1f2f051828056a009ee0e92375181" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f051828056a009ee0e92375181" title="十、如果让我重来一次，我会怎么设计"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">十、如果让我重来一次，我会怎么设计</span></span></h3><div class="notion-text notion-block-32d1f2f05182804b863ad98f473fd885">如果重新做一遍，我会比一开始更克制。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280a3b7bdd4e389820a15" data-id="32d1f2f0518280a3b7bdd4e389820a15"><span><div id="32d1f2f0518280a3b7bdd4e389820a15" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280a3b7bdd4e389820a15" title="第一阶段"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第一阶段</span></span></h4><div class="notion-text notion-block-32d1f2f051828011b807ce011ed7e6bc">先只做：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182802baf17fbe2b135bce0"><li><code class="notion-inline-code">collector</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182806b888ce08b789479ec"><li><code class="notion-inline-code">reviewer</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a1aad0f1b68b32017a"><li><code class="notion-inline-code">writer-core</code></li></ul><div class="notion-text notion-block-32d1f2f051828086bf51e67f94608cde">先验证：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280798fa6d827634971de"><li>能收</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828061a039c62d1ee01bd6"><li>能归并</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182804cb3b2dadf51bd48d1"><li>能写出像样的母稿</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f05182804a88d3eef315093594" data-id="32d1f2f05182804a88d3eef315093594"><span><div id="32d1f2f05182804a88d3eef315093594" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182804a88d3eef315093594" title="第二阶段"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第二阶段</span></span></h4><div class="notion-text notion-block-32d1f2f0518280669d96f9b6118b92be">加：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f05182800ba873ec00575d7b48"><li><code class="notion-inline-code">publisher-weibo</code></li></ul><div class="notion-text notion-block-32d1f2f0518280399e01f1ad80ba816d">先跑通一个真实发布端。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f05182804f8b0cd38afa6537bf" data-id="32d1f2f05182804f8b0cd38afa6537bf"><span><div id="32d1f2f05182804f8b0cd38afa6537bf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f05182804f8b0cd38afa6537bf" title="第三阶段"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第三阶段</span></span></h4><div class="notion-text notion-block-32d1f2f051828068afa5c4df1bef1bfc">再加：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280639893e10499e09d39"><li><code class="notion-inline-code">publisher-notion</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280d2ba02f38d99e10725"><li><code class="notion-inline-code">publisher-moltbook</code></li></ul><div class="notion-text notion-block-32d1f2f05182809ab464cf3a6067cde4">然后再解决：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280c5997cc09a4c7c0136"><li>多平台状态拆分</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a8b131da4702b75ceb"><li>并行发布</li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f051828066b500d9846fa75c81"><li>整体收口</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-32d1f2f0518280b69411cfa9399fc401" data-id="32d1f2f0518280b69411cfa9399fc401"><span><div id="32d1f2f0518280b69411cfa9399fc401" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f0518280b69411cfa9399fc401" title="第四阶段"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第四阶段</span></span></h4><div class="notion-text notion-block-32d1f2f0518280e1b126e2adc6d6330f">最后再加：</div><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280389419dcc755eee2be"><li><code class="notion-inline-code">collector-ops-log</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f0518280a6ae8dc296207794f6"><li><code class="notion-inline-code">collector-history</code></li></ul><ul class="notion-list notion-list-disc notion-block-32d1f2f05182808a9971c0603beffb97"><li>复盘与记忆更新</li></ul><div class="notion-text notion-block-32d1f2f0518280af811be2343d55c773">因为如果一开始就把所有角色都堆上去，系统不是不能跑，而是你很难知道到底哪一层出了问题。</div><hr class="notion-hr notion-block-32d1f2f05182807997dbfa29c00694a5"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-32d1f2f051828059b6fbef0e7f990e63" data-id="32d1f2f051828059b6fbef0e7f990e63"><span><div id="32d1f2f051828059b6fbef0e7f990e63" class="notion-header-anchor"></div><a class="notion-hash-link" href="#32d1f2f051828059b6fbef0e7f990e63" title="十一、最终感受"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">十一、最终感受</span></span></h3><div class="notion-text notion-block-32d1f2f05182808c95ace4262de9e2ce">这段时间折腾下来，我最大的感受不是“multi-agent 很强”，而是：</div><blockquote class="notion-quote notion-block-32d1f2f051828032b3e5e80a76dbb0ed"><div><b>多 Agent 的价值，不在于角色变多，而在于系统能不能更诚实地面对每一层问题。</b></div></blockquote><div class="notion-text notion-block-32d1f2f0518280ae9b20f13dae86c0f5">collector 诚实地收集。</div><div class="notion-text notion-block-32d1f2f051828019a2efd9e04899fb50">reviewer 诚实地判断。</div><div class="notion-text notion-block-32d1f2f0518280428d66f8bd2b1043af">writer-core 诚实地写出骨架。</div><div class="notion-text notion-block-32d1f2f0518280679d5fc1f4f9233e46">publisher 诚实地适配和发布。</div><div class="notion-text notion-block-32d1f2f0518280b69099f07b70e68c4f">状态层诚实地记录谁完成了、谁还没完成。</div><div class="notion-text notion-block-32d1f2f0518280ffbc3afaa6a9148f17">当每一层都不再替下一层做决定，系统才真正开始稳定。</div><div class="notion-text notion-block-32d1f2f051828048ba63d0575884fd2b">而稳定之后，内容系统才有可能慢慢长成我更想要的样子：</div><div class="notion-text notion-block-32d1f2f05182801b972cd6f5fb92e87a"><b>不是一个自动生成器，而是一个真的做过、想过、踩过坑之后，慢慢把经验讲清楚的系统。</b></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[为什么 OpenClaw 在 Ubuntu 上可以 Tab 补全，macOS 上却不行？]]></title>
            <link>https://www.lvy.life/article/2026/04/15/3431f2f0-5182-8003-bdb3-f32930436fcf</link>
            <guid>https://www.lvy.life/article/2026/04/15/3431f2f0-5182-8003-bdb3-f32930436fcf</guid>
            <pubDate>Wed, 15 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[在 Ubuntu 上，OpenClaw 的 Tab 自动补全可以正常工作，但在 macOS 上却没有反应。排查后发现，问题并不在 OpenClaw 本身，而在 shell 环境：macOS 默认使用 zsh，而 zsh 的补全系统如果没有执行 compinit，即使已经加载了 OpenClaw 的补全脚本，Tab 补全也不会真正生效。新版 OpenClaw 也调整了 completion 命令的用法，需要通过 --shell zsh 这样的参数形式来生成或安装补全脚本。最终只要在 ~/.zshrc 中补上 autoload -Uz compinit 和 compinit，再保留 OpenClaw 的补全脚本加载语句，问题就解决了。本质上，这不是 OpenClaw 在 macOS 上不支持补全，而是 zsh 没有初始化自己的补全框架。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3431f2f051828003bdb3f32930436fcf"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-3431f2f0518280cb879bfa4abddfcf35"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text"><div class="notion-text notion-block-3431f2f0518280689d6ce0260b5d8796">最近在折腾 OpenClaw 的命令行时，我遇到一个小坑：</div><div class="notion-text notion-block-3431f2f0518280419f14d05d3481e0f5">同样是 <code class="notion-inline-code">openclaw</code> 命令，</div><ul class="notion-list notion-list-disc notion-block-3431f2f0518280e2bc57d50400528e11"><li>在 <b>Ubuntu</b> 上按 <code class="notion-inline-code">Tab</code> 可以自动补全</li></ul><ul class="notion-list notion-list-disc notion-block-3431f2f0518280aea60af0ee37ebe220"><li>在 <b>macOS</b> 上却完全没反应</li></ul><div class="notion-text notion-block-3431f2f05182807481d2dff461ccdc57">一开始我以为是 OpenClaw 在 macOS 上没装完整，或者 Homebrew 安装方式有区别。后来排查下来，问题其实很简单：</div><div class="notion-text notion-block-3431f2f05182802c8efef86bf46a778a"><b>不是 OpenClaw 不支持，而是 zsh 的补全系统没有初始化。</b></div><div class="notion-text notion-block-3431f2f0518280f78758dfbe33c4c3cb">这篇记录一下排查过程和最终解决方法。</div></div></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3431f2f051828018941be30c9d2d0d81" data-id="3431f2f051828018941be30c9d2d0d81"><span><div id="3431f2f051828018941be30c9d2d0d81" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f051828018941be30c9d2d0d81" title="现象"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">现象</span></span></h3><div class="notion-text notion-block-3431f2f051828055aa5ccf9f005dcf03">在 macOS 上执行：</div><div class="notion-text notion-block-3431f2f05182801e88f4dc4afcf3a54a">输出是：</div><div class="notion-text notion-block-3431f2f0518280a88605dc7f3d0e5857">说明两件事：</div><ol start="1" class="notion-list notion-list-numbered notion-block-3431f2f05182807ba149e4be79fe4ab7" style="list-style-type:decimal"><li>当前 shell 是 <b>zsh</b></li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3431f2f0518280ed9c3ef36d62420696" style="list-style-type:decimal"><li><code class="notion-inline-code">openclaw</code> 命令本身已经正常安装</li></ol><div class="notion-text notion-block-3431f2f051828032b7a5c531b2d0d396">再看 OpenClaw 的 completion 帮助：</div><div class="notion-text notion-block-3431f2f05182803abae6ee22989332ba">可以看到它本身是支持补全脚本生成/安装的。</div><hr class="notion-hr notion-block-3431f2f051828008adaaf78c438b8a17"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3431f2f0518280eaa370dff4b1c59d6e" data-id="3431f2f0518280eaa370dff4b1c59d6e"><span><div id="3431f2f0518280eaa370dff4b1c59d6e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f0518280eaa370dff4b1c59d6e" title="第一个误区：新版命令不是 openclaw completion zsh"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">第一个误区：新版命令不是 <code class="notion-inline-code">openclaw completion zsh</code></span></span></h3><div class="notion-text notion-block-3431f2f0518280a288b8f6b14e36d73e">我一开始习惯性执行：</div><div class="notion-text notion-block-3431f2f0518280a5a834e89a5c282e0e">结果报错：</div><div class="notion-text notion-block-3431f2f0518280828815ca42e5eccd81">原因是新版 OpenClaw 改了参数格式，正确写法是：</div><div class="notion-text notion-block-3431f2f0518280868e7bc6c12b37115d">如果想直接安装补全脚本，可以用：</div><div class="notion-text notion-block-3431f2f05182807a9e15d2bb01457008">执行后，OpenClaw 会把补全相关内容写到 <code class="notion-inline-code">~/.zshrc</code>，类似这样：</div><div class="notion-text notion-block-3431f2f051828068aa9dcf2b9d8a0a41">看起来像是已经安装成功了。</div><div class="notion-text notion-block-3431f2f051828039ba32ca24438e08e4">但问题来了：</div><div class="notion-text notion-block-3431f2f0518280749c45e879fca3c173"><b>即使已经 source 了补全脚本，Tab 还是不生效。</b></div><hr class="notion-hr notion-block-3431f2f0518280e1a875e0c888d5d915"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3431f2f0518280f4a155f2fbf79d341f" data-id="3431f2f0518280f4a155f2fbf79d341f"><span><div id="3431f2f0518280f4a155f2fbf79d341f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f0518280f4a155f2fbf79d341f" title="真正原因：zsh 没有初始化补全系统"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">真正原因：zsh 没有初始化补全系统</span></span></h3><div class="notion-text notion-block-3431f2f051828093a0b9ff9cf0c99fe9">最后发现，<code class="notion-inline-code">~/.zshrc</code> 里只有这一段还不够：</div><div class="notion-text notion-block-3431f2f05182804aa568def1f543670c">还必须先初始化 zsh 的补全框架，也就是这两句：</div><div class="notion-text notion-block-3431f2f0518280d5bb72d3be28e1a799">最终可用的配置是：</div><div class="notion-text notion-block-3431f2f0518280f29c3ac66a541248f1">执行：</div><div class="notion-text notion-block-3431f2f051828048ba4bd41f89e8dbe5">之后，<code class="notion-inline-code">openclaw</code> 的 Tab 补全就恢复正常了。</div><hr class="notion-hr notion-block-3431f2f0518280cda93dd5255669f04a"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3431f2f05182807faa46c736783217ec" data-id="3431f2f05182807faa46c736783217ec"><span><div id="3431f2f05182807faa46c736783217ec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f05182807faa46c736783217ec" title="为什么 Ubuntu 上通常没问题？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么 Ubuntu 上通常没问题？</span></span></h3><div class="notion-text notion-block-3431f2f0518280a38e75f30fb1e99eb0">这个现象其实很常见，本质不是 Ubuntu 比 macOS “更兼容”，而是默认 shell 环境不同。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3431f2f05182802d940cdc1481099ba0" data-id="3431f2f05182802d940cdc1481099ba0"><span><div id="3431f2f05182802d940cdc1481099ba0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f05182802d940cdc1481099ba0" title="Ubuntu 常见情况"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Ubuntu 常见情况</span></span></h4><div class="notion-text notion-block-3431f2f05182807f9269f0661e513f12">Ubuntu 很多环境默认就已经把补全系统配置好了，尤其是 bash 环境里，<code class="notion-inline-code">bash-completion</code> 往往已经启用。</div><div class="notion-text notion-block-3431f2f0518280c0b38be288f0d34e08">所以即使你只是安装了 OpenClaw 的补全脚本，也可能“天然就能用”。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3431f2f051828012a318fd344e78cf89" data-id="3431f2f051828012a318fd344e78cf89"><span><div id="3431f2f051828012a318fd344e78cf89" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f051828012a318fd344e78cf89" title="macOS 常见情况"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">macOS 常见情况</span></span></h4><div class="notion-text notion-block-3431f2f0518280aaa0c5f0c30a30b125">macOS 默认 shell 通常是 <b>zsh</b>。</div><div class="notion-text notion-block-3431f2f051828070bfe5cf292055beef">而 zsh 的补全不是自动无脑生效的，它依赖：</div><div class="notion-text notion-block-3431f2f051828081a790c863b674349e">如果这两句没跑，很多补全脚本就算被 <code class="notion-inline-code">source</code> 进来了，也不会真正工作。</div><div class="notion-text notion-block-3431f2f0518280b4b571cbe7d64ac12f">所以表面看是：</div><ul class="notion-list notion-list-disc notion-block-3431f2f0518280cf9c6cdb4a48858df3"><li>Ubuntu：Tab 补全正常</li></ul><ul class="notion-list notion-list-disc notion-block-3431f2f05182800591d6c814dfd3fbbb"><li>macOS：Tab 补全失效</li></ul><div class="notion-text notion-block-3431f2f05182803ea9a6e39a8142ac0d">实际上根因是：</div><ul class="notion-list notion-list-disc notion-block-3431f2f0518280908fb3f9fff3e8d93f"><li>Ubuntu 的 shell completion 环境往往已经准备好了</li></ul><ul class="notion-list notion-list-disc notion-block-3431f2f0518280f4bd68daf3bc276536"><li>macOS 的 zsh 没有初始化补全系统</li></ul><hr class="notion-hr notion-block-3431f2f0518280dd848cfa648dc7a489"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3431f2f0518280e493dadbc1f63d82c2" data-id="3431f2f0518280e493dadbc1f63d82c2"><span><div id="3431f2f0518280e493dadbc1f63d82c2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f0518280e493dadbc1f63d82c2" title="最终解决方法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">最终解决方法</span></span></h3><div class="notion-text notion-block-3431f2f0518280178c56d3dcac26c6ae"><b>OpenClaw 的补全脚本已经装上了，但 macOS 下 zsh 没有执行 </b><code class="notion-inline-code"><b>compinit</b></code><b>，导致补全系统根本没启动。</b></div><div class="notion-text notion-block-3431f2f051828041b3d4de708e6c8147">只要在 <code class="notion-inline-code">~/.zshrc</code> 里加上：</div><div class="notion-text notion-block-3431f2f051828070993deff37df2def7">问题就解决了。</div><hr class="notion-hr notion-block-3431f2f0518280dca346e21596a63484"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3431f2f05182800db128edc3fe4b2135" data-id="3431f2f05182800db128edc3fe4b2135"><span><div id="3431f2f05182800db128edc3fe4b2135" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f05182800db128edc3fe4b2135" title="可直接复制的最终配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">可直接复制的最终配置</span></span></h3><hr class="notion-hr notion-block-3431f2f0518280e2b5d9c68d0ab0e4dc"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3431f2f051828033bad2eaa2480a6dc9" data-id="3431f2f051828033bad2eaa2480a6dc9"><span><div id="3431f2f051828033bad2eaa2480a6dc9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3431f2f051828033bad2eaa2480a6dc9" title="一句话版结论"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一句话版结论</span></span></h3><div class="notion-text notion-block-3431f2f0518280cf8decca9721f36406"><b>不是 OpenClaw 在 macOS 上不支持补全，而是 zsh 没初始化补全系统；加上 </b><code class="notion-inline-code"><b>autoload -Uz compinit</b></code><b> 和 </b><code class="notion-inline-code"><b>compinit</b></code><b> 就行。</b></div><div class="notion-blank notion-block-3431f2f0518280b292acef15d2f0eda3"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[用 Python 把「流水线 Agent」从即兴发挥，收敛成可复用的工具]]></title>
            <link>https://www.lvy.life/article/2026/04/16/3441f2f0-5182-8047-8b53-e344b542703a</link>
            <guid>https://www.lvy.life/article/2026/04/16/3441f2f0-5182-8047-8b53-e344b542703a</guid>
            <pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[我们把内容流水线里重复、机械的操作（读草稿、调平台 API、更新发布状态、多平台一致性判断等）从「全靠 Agent 在对话里完成」收敛成 Python CLI 脚本：Agent 负责理解与成稿，脚本负责规则与副作用。这样减少了无效检索与拼 JSON 的 Token 消耗，也避免了单平台成功就误标「已发布」、以及临时脚本硬编码密钥等问题。Notion / 微博 / Moltbook 等发布路径统一走「正文进文件 → 一条命令发布 → 自动更新状态」；Moltbook 复用现有 API 封装并注意发帖间隔；Cron 与文档与脚本行为对齐。核心收获：确定性进代码，创造性留给模型。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3441f2f0518280478b53e344b542703a"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-3441f2f0518280818c6afc20fe5fd4b5"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text"><div class="notion-text notion-block-3441f2f05182807eb75cc4925cec608f">我们在内容流水线里拆了很多专用 Agent：采集、审核、成稿、多平台发布。早期做法是：让模型在对话里读 JSON、改状态、调PI——能跑，但费 Token、易出错、难审计。
这次改动的核心思路很简单：把重复、机械、有固定规则的操作，下沉到 Python 脚本里；Agent 只负责理解与决策，脚本负责一致性与副作用。</div></div></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3441f2f0518280609af6f7ef7f3c19cb" data-id="3441f2f0518280609af6f7ef7f3c19cb"><span><div id="3441f2f0518280609af6f7ef7f3c19cb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280609af6f7ef7f3c19cb" title="我们解决了什么问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>我们解决了什么问题</b></span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3441f2f0518280139ebdda44d0407abe" data-id="3441f2f0518280139ebdda44d0407abe"><span><div id="3441f2f0518280139ebdda44d0407abe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280139ebdda44d0407abe" title="1. 状态与「过早标记已发布」"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>1. 状态与「过早标记已发布」</b></span></span></h4><div class="notion-text notion-block-3441f2f051828080aeaddb2d73229137">多平台发布时，很容易出现：某一端成功了，就把整条素材标成「已发布」，而实际上其他端还没发完。</div><div class="notion-text notion-block-3441f2f05182807f9031f56d65a169cd">做法是引入<b>统一的状态更新脚本</b>：按「分发目标」逐平台记录成功/失败，<b>只有所有目标都成功</b>，才把整条内容推到终态。这样逻辑集中在一处，Agent 不必每次复述规则。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3441f2f05182809c9938da7dd4968bd9" data-id="3441f2f05182809c9938da7dd4968bd9"><span><div id="3441f2f05182809c9938da7dd4968bd9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f05182809c9938da7dd4968bd9" title="2. 发布逻辑从「批处理脚本」变成「CLI 工具」"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2. 发布逻辑从「批处理脚本」变成「CLI 工具」</b></span></span></h4><div class="notion-text notion-block-3441f2f0518280c5affcc91c0db6f657">以 Notion 为例，曾经出现过「脚本自己扫目录、自己拼内容」的批处理形态——和「先由 Agent 写好再发布」的职责混在一起，也容易长出<b>一次性脚本、硬编码密钥或正文</b>的坏味道。</div><div class="notion-text notion-block-3441f2f05182805dac78c77020977094">现在的形态更接近微博那套：<b>Agent 把正文写成文件（例如 Markdown），再调用一个带参数的发布命令</b>。脚本负责：读文件、调平台、失败时写清原因、成功后更新流水线状态。<b>不把业务正文写死在仓库里的 Python 里。</b></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3441f2f0518280b38a47e43edf4fc407" data-id="3441f2f0518280b38a47e43edf4fc407"><span><div id="3441f2f0518280b38a47e43edf4fc407" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280b38a47e43edf4fc407" title="3. 密钥与配置：少搜、少猜、少浪费 Token"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3. 密钥与配置：少搜、少猜、少浪费 Token</b></span></span></h4><div class="notion-text notion-block-3441f2f05182809aa21dcc0c935756d3">之前 Agent 会为了找「Notion Key 在哪」反复检索，纯烧 Token。</div><div class="notion-text notion-block-3441f2f0518280da9183d503d6fab78f">现在约定：<b>脚本从固定、文档化的位置读密钥</b>（与官方 Skill 一致），Agent 文档里写清楚「不要自己去翻一堆配置文件」。省下来的不只是调用次数，更是对话里的无效探索。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3441f2f05182803695f2e1af5cf337d6" data-id="3441f2f05182803695f2e1af5cf337d6"><span><div id="3441f2f05182803695f2e1af5cf337d6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f05182803695f2e1af5cf337d6" title="4. 封面等「可自动化」的增强"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>4. 封面等「可自动化」的增强</b></span></span></h4><div class="notion-text notion-block-3441f2f0518280cca8bbe2edad7e4f0e">Notion 需要封面时，如果每次都让 Agent 去搜图、找 API，成本很高。</div><div class="notion-text notion-block-3441f2f05182806d90eec77d1c90f833">把「按标题/标签选一张风格合适的图」放进发布脚本里，失败时降级为无封面继续发，<b>不阻断主流程</b>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3441f2f0518280918045e253b29860d0" data-id="3441f2f0518280918045e253b29860d0"><span><div id="3441f2f0518280918045e253b29860d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280918045e253b29860d0" title="5. 网络不稳时的务实处理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>5. 网络不稳时的务实处理</b></span></span></h4><div class="notion-text notion-block-3441f2f051828064885bf67f1b4d9e34">外部 API（例如图片服务）有时会超时。做法是：<b>适当拉长超时、在 curl/子进程层给足余量</b>，并允许「拿不到图就跳过」，避免一次封面请求拖死整次发布。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3441f2f0518280ddbbdbdc33722ed059" data-id="3441f2f0518280ddbbdbdc33722ed059"><span><div id="3441f2f0518280ddbbdbdc33722ed059" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280ddbbdbdc33722ed059" title="6. 新平台：Moltbook"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>6. 新平台：Moltbook</b></span></span></h4><div class="notion-text notion-block-3441f2f0518280829bcfc00c3ce5d702">Moltbook 侧我们<b>不重复实现 HTTP 客户端</b>：项目里已有完整的 <code class="notion-inline-code">moltbook.py</code>（封装官方 API）。发布脚本只做「读正文 → 调已有客户端发帖 → 更新流水线状态」。</div><div class="notion-text notion-block-3441f2f0518280679389f17b0a68dfc4">另外，官方对发帖频率有限制，我们在文档和 Cron 提示里写明：<b>多篇连续发布时要留出间隔</b>（例如在两次发帖之间等待数分钟），避免触发限流。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3441f2f0518280e9a4b6d60e656c3057" data-id="3441f2f0518280e9a4b6d60e656c3057"><span><div id="3441f2f0518280e9a4b6d60e656c3057" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280e9a4b6d60e656c3057" title="7. Cron 提示词也要跟着架构变"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>7. Cron 提示词也要跟着架构变</b></span></span></h4><div class="notion-text notion-block-3441f2f0518280449d0ff9df9f0d22cf">定时任务里如果还写着「手动调状态更新」「从过时路径读 Key」，Agent 会照做，反而破坏统一方案。</div><div class="notion-text notion-block-3441f2f0518280db8e00d0079f4c29f9">我们把 Cron 文案改成：<b>读哪些规范文件、筛哪些 draft、如何用发布脚本、何时收尾清理</b>——与当前脚本行为一致，减少歧义。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3441f2f0518280d48698ede7879625dc" data-id="3441f2f0518280d48698ede7879625dc"><span><div id="3441f2f0518280d48698ede7879625dc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280d48698ede7879625dc" title="设计原则（可复用到别的流水线）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>设计原则（可复用到别的流水线）</b></span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-3441f2f05182805bbf6df5204698b1c0" style="list-style-type:decimal"><li><b>脚本管副作用，模型管语义</b>：创建记录、改状态、调 API，尽量不进对话长文本。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3441f2f05182808cac33fc1ca6debf82" style="list-style-type:decimal"><li><b>CLI 优于批处理</b>：输入是文件 + 元数据路径 + 业务 ID，输出是退出码 + 简短日志。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3441f2f05182806cbdaef97d5a124a63" style="list-style-type:decimal"><li><b>单一事实来源</b>：状态怎么迁、何时算「全平台完成」，只在一处实现。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3441f2f0518280859797c6c9f469a411" style="list-style-type:decimal"><li><b>安全默认</b>：禁止在仓库里塞密钥和整篇正文；一次性脚本该删就删。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-3441f2f0518280b79150d6966d0785d5" style="list-style-type:decimal"><li><b>可观测</b>：失败要写清原因（含退出码、错误摘要），方便人和后续自动化处理。</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3441f2f0518280b4b2aee4a23659d6fe" data-id="3441f2f0518280b4b2aee4a23659d6fe"><span><div id="3441f2f0518280b4b2aee4a23659d6fe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3441f2f0518280b4b2aee4a23659d6fe" title="小结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>小结</b></span></span></h3><div class="notion-text notion-block-3441f2f05182807098dff02c91a18cfc">这次不是「多写了几个脚本」这么简单，而是把<b>流水线里的确定性</b>从模型侧挪到代码侧：<b>Token 花在审稿和表达上，而不是花在重复查文档、拼 JSON、猜路径上。</b></div><div class="notion-text notion-block-3441f2f0518280558595c6f1d7a5c93e">如果你也在搭多 Agent 内容系统，可以问自己一句：<b>这件事有没有固定规则？有的话，就该进脚本。</b></div><div class="notion-blank notion-block-3441f2f0518280e28132e81f874f58f5"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tailscale 连接变慢排查与自建 DERP 实践记录]]></title>
            <link>https://www.lvy.life/article/2026/04/30/3521f2f0-5182-8091-9ea0-ee9f13919838</link>
            <guid>https://www.lvy.life/article/2026/04/30/3521f2f0-5182-8091-9ea0-ee9f13919838</guid>
            <pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[本文记录了一次 Tailscale 远程连接变慢的完整排查过程：从 tailscale status 中发现连接家中 Mac mini 时走了海外 DERP 中继，到通过 tailscale netcheck 分析 UDP、IPv6、NAT 映射和最近 DERP 节点，最终确认问题不是设备故障，而是公司网络与家庭网络之间无法建立直连。为降低中继延迟，使用一台国内云服务器自建 DERP，并在 Tailscale ACL 中配置 derpMap。配置完成后，连接路径从 DERP(sfo/lax) 切换到 DERP(cn-self)，延迟从几百毫秒甚至 2 秒左右降至 30～40ms，VNC 远程桌面体验明显改善。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-3521f2f0518280919ea0ee9f13919838"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-3521f2f0518280369657fa5e09fc57c8"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text"><div class="notion-text notion-block-3521f2f0518280c7aedcd7728391ec27">最近发现从公司电脑连接家里的 Mac mini 时，Tailscale 延迟突然变高，VNC 变得非常卡。最开始以为是 Mac mini 的网络出了问题，但排查后发现，真正原因是 <b>公司电脑和 Mac mini 无法建立直连，退回到了 Tailscale 海外 DERP 中继</b>。</div><div class="notion-text notion-block-3521f2f0518280a09c6af6eb5b126fc0">最终通过在自己的国内服务器上搭建 DERP，中继延迟从几百毫秒降到了 30～40ms，VNC 体验明显恢复。</div></div></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3521f2f0518280c79156c1cfe75f0f26" data-id="3521f2f0518280c79156c1cfe75f0f26"><span><div id="3521f2f0518280c79156c1cfe75f0f26" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280c79156c1cfe75f0f26" title="一、问题现象"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一、问题现象</span></span></h3><div class="notion-text notion-block-3521f2f0518280ddb227d86a57e606e4">在公司 Windows 电脑上 ping 家里的 Mac mini：</div><div class="notion-text notion-block-3521f2f051828068a556ce0ff52ba829">能 ping 通，但是延迟很高：</div><div class="notion-text notion-block-3521f2f0518280c08f10d58f96eef73d">再看 Tailscale 状态：</div><div class="notion-text notion-block-3521f2f0518280b4b462e135098e3bf9">发现 Mac mini 这一行是：</div><div class="notion-text notion-block-3521f2f05182804c843fd8f0d5e7e38a">这说明：</div><div class="notion-text notion-block-3521f2f05182806c813fdea9f82ab9f2">所以延迟高是正常的，因为流量绕到了海外。</div><hr class="notion-hr notion-block-3521f2f0518280a6910fd771ac611146"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3521f2f0518280efa5b9e159fd1c542f" data-id="3521f2f0518280efa5b9e159fd1c542f"><span><div id="3521f2f0518280efa5b9e159fd1c542f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280efa5b9e159fd1c542f" title="二、先确认是哪条链路出问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二、先确认是哪条链路出问题</span></span></h3><div class="notion-text notion-block-3521f2f05182801780d6d87d9150ca58">在 Mac mini 上查看 Tailscale 状态：</div><div class="notion-text notion-block-3521f2f051828065a71ede42aeb97574">macOS 图形版 Tailscale 可能没有直接把 <code class="notion-inline-code">tailscale</code> 命令加到 PATH，所以要用完整路径：</div><div class="notion-text notion-block-3521f2f05182801b82b9cd0f88d06634">测试 Mac mini 到服务器：</div><div class="notion-text notion-block-3521f2f051828017af8ccd90354ea547">一开始可能是：</div><div class="notion-text notion-block-3521f2f0518280a5bf87c95f987f5464">随后切到了 IPv6 直连：</div><div class="notion-text notion-block-3521f2f051828031a410f985d31e0e07">说明：</div><hr class="notion-hr notion-block-3521f2f05182803d9214e6ec1461333f"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3521f2f0518280879e16c47137eb239b" data-id="3521f2f0518280879e16c47137eb239b"><span><div id="3521f2f0518280879e16c47137eb239b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280879e16c47137eb239b" title="三、查看 netcheck"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三、查看 netcheck</span></span></h3><div class="notion-text notion-block-3521f2f0518280c6b6c2c4d048d5c2c6">公司 Windows 执行：</div><div class="notion-text notion-block-3521f2f0518280589896d9141860cef7">Mac mini 执行：</div><div class="notion-text notion-block-3521f2f0518280e9ad91fa9e4f6d6bb3">当时看到的关键信息是：</div><div class="notion-text notion-block-3521f2f0518280f19f58f397290e1543">Windows：</div><div class="notion-text notion-block-3521f2f051828085b739f9a5599b671d">Mac mini：</div><div class="notion-text notion-block-3521f2f0518280d3ac85c545da1fe4c8">这里几个信息很重要：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3521f2f0518280ac8229e96ef66a4178" data-id="3521f2f0518280ac8229e96ef66a4178"><span><div id="3521f2f0518280ac8229e96ef66a4178" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280ac8229e96ef66a4178" title="1. UDP 是 true，不代表一定能直连"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. UDP 是 true，不代表一定能直连</span></span></h4><div class="notion-text notion-block-3521f2f05182805e8044ebbcf383cf70"><code class="notion-inline-code">UDP: true</code> 只能说明 UDP 可用，但 Tailscale 直连还要看两端 NAT、防火墙、运营商网络、公司网络策略等。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3521f2f05182809dbf2fc07c2ca8eb5f" data-id="3521f2f05182809dbf2fc07c2ca8eb5f"><span><div id="3521f2f05182809dbf2fc07c2ca8eb5f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f05182809dbf2fc07c2ca8eb5f" title="2. MappingVariesByDestIP=true 会增加打洞难度"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. MappingVariesByDestIP=true 会增加打洞难度</span></span></h4><div class="notion-text notion-block-3521f2f0518280e18782c73a619853e9">Mac mini 这边显示：</div><div class="notion-text notion-block-3521f2f051828027b34ec39d060ca3a9">这表示家里网络的 NAT 映射会根据目标地址变化（坑爹的电信把网络改成大内网了，NAT4）。这样的 NAT 对打洞不太友好，可能出现：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3521f2f0518280b8b11de165d19bad50" data-id="3521f2f0518280b8b11de165d19bad50"><span><div id="3521f2f0518280b8b11de165d19bad50" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280b8b11de165d19bad50" title="3. 公司电脑没有 IPv6"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 公司电脑没有 IPv6</span></span></h4><div class="notion-text notion-block-3521f2f0518280f0acc3fbf0d5b8711b">Windows 这边显示：</div><div class="notion-text notion-block-3521f2f05182801da936e4914fbd6781">所以它没法像服务器一样通过 IPv6 和 Mac mini 建立快速直连，只能依赖 IPv4 打洞。IPv4 打洞失败后，就会退回 DERP。</div><hr class="notion-hr notion-block-3521f2f051828050921eec976e5dfcb4"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3521f2f05182800184daeded6e064a3a" data-id="3521f2f05182800184daeded6e064a3a"><span><div id="3521f2f05182800184daeded6e064a3a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f05182800184daeded6e064a3a" title="四、为什么 Mac mini 连服务器很快，但连公司电脑很慢？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">四、为什么 Mac mini 连服务器很快，但连公司电脑很慢？</span></span></h3><div class="notion-text notion-block-3521f2f05182802d9f24c28f5ea12d40">这个问题的核心是：<b>Tailscale 的直连不是按设备判断，而是按“每一对设备”判断。</b></div><div class="notion-text notion-block-3521f2f051828081b7faf9dfe56a50b7">可以理解成三条链路：</div><div class="notion-text notion-block-3521f2f05182803da174fff4877173dd">云服务器通常有公网 IP，网络环境简单，所以很容易直连。</div><div class="notion-text notion-block-3521f2f0518280c182e7f100463240aa">而公司电脑在公司网络后面，家里 Mac mini 也在家庭 NAT 后面。两边都不是公网直连环境，中间又有公司网络、家庭路由器、运营商 NAT，就很容易打洞失败。</div><hr class="notion-hr notion-block-3521f2f0518280c78892c3ab53206d74"/><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3521f2f051828052a76ece94adab9e4e" data-id="3521f2f051828052a76ece94adab9e4e"><span><div id="3521f2f051828052a76ece94adab9e4e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f051828052a76ece94adab9e4e" title="五、尝试过的方向：UDP 端口映射"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">五、尝试过的方向：UDP 端口映射</span></span></h3><div class="notion-text notion-block-3521f2f05182808f9715fa20ce30b598">Tailscale 默认常见端口是 UDP 41641，所以一开始考虑在家里路由器上做端口映射：</div><div class="notion-text notion-block-3521f2f0518280d3b325f62caf2bb40f">但是 macOS 图形版 Tailscale 当前没有 <code class="notion-inline-code">tailscale up --port=41641</code> 参数：</div><div class="notion-text notion-block-3521f2f05182803ea2c4d6f7810d37ff">没有看到 <code class="notion-inline-code">--port</code>。</div><div class="notion-text notion-block-3521f2f051828087befac647988596fd">同时 <code class="notion-inline-code">netcheck</code> 里看到的公网端口是随机的，例如：</div><div class="notion-text notion-block-3521f2f051828060afe8fc2f44842afa">这说明单纯映射 41641 未必一定生效。</div><div class="notion-text notion-block-3521f2f05182807eabcbd9748c801971">所以最后没有继续折腾固定端口，而是选择更稳定的方案：<b>自建 DERP</b>。</div><hr class="notion-hr notion-block-3521f2f051828043bd60fff0b754058e"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3521f2f051828045835afb39c29e0bbc" data-id="3521f2f051828045835afb39c29e0bbc"><span><div id="3521f2f051828045835afb39c29e0bbc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f051828045835afb39c29e0bbc" title="六、自建 DERP"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">六、自建 DERP</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f0518280589a4fe810be5e7d0a" data-id="3521f2f0518280589a4fe810be5e7d0a"><span><div id="3521f2f0518280589a4fe810be5e7d0a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280589a4fe810be5e7d0a" title="1. DERP 的作用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. DERP 的作用</span></span></h3><div class="notion-text notion-block-3521f2f05182807caf9ee74d330a24f7">DERP 是 Tailscale 的中继服务器。</div><div class="notion-text notion-block-3521f2f0518280dd9930e16da5df25c9">当两台设备无法直连时，Tailscale 会通过 DERP 转发加密后的 WireGuard 流量。</div><div class="notion-text notion-block-3521f2f05182803ebf01c6334c02cda8">默认 DERP 节点大多在海外，所以国内使用时可能出现：</div><div class="notion-text notion-block-3521f2f05182801a93fce59ac6e5be19">如果自己在国内服务器上搭一个 DERP，就可以让无法直连的设备走自己的中继：</div><hr class="notion-hr notion-block-3521f2f0518280a097a0faea8f85ccd2"/><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f0518280bc9d9fe86005388105" data-id="3521f2f0518280bc9d9fe86005388105"><span><div id="3521f2f0518280bc9d9fe86005388105" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280bc9d9fe86005388105" title="2. 准备条件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 准备条件</span></span></h3><div class="notion-text notion-block-3521f2f0518280c8bb37efd5c00800f2">需要一台有公网 IP 的服务器，以及一个域名。</div><div class="notion-text notion-block-3521f2f0518280eeab11ebc43d65e041">我的域名示例：</div><div class="notion-text notion-block-3521f2f05182809aa3e7c1bed1ba5142">需要把 DNS 解析到这台服务器 IP。</div><div class="notion-text notion-block-3521f2f0518280b58622e56fd1c8048b">服务器需要放行：</div><div class="notion-text notion-block-3521f2f051828079a8a4d624e2381ee4">其中：</div><hr class="notion-hr notion-block-3521f2f05182804a8cf4ce0ac7a4f043"/><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f0518280f09593d2512538ce5a" data-id="3521f2f0518280f09593d2512538ce5a"><span><div id="3521f2f0518280f09593d2512538ce5a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280f09593d2512538ce5a" title="3. 安装 derper"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. 安装 derper</span></span></h3><div class="notion-text notion-block-3521f2f0518280dcb5e4fb8c3ab41233">服务器上安装 Go。</div><div class="notion-text notion-block-3521f2f0518280919c95c56e933b0f10">如果系统自带 Go 太老，可能会报错：</div><div class="notion-text notion-block-3521f2f051828031af9beb6e0d51a826">这说明 Go 版本太旧，需要安装新版 Go。</div><div class="notion-text notion-block-3521f2f0518280ca8550f1234de9bdcc">然后安装 derper：</div><div class="notion-text notion-block-3521f2f0518280ee91cce6c64c4e172e">安装后一般在：</div><div class="notion-text notion-block-3521f2f0518280f787e6ebbc6aedbe4d">确认：</div><hr class="notion-hr notion-block-3521f2f0518280ffb323d6a0dbfee350"/><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f0518280d8a0e3cac0efed6ce9" data-id="3521f2f0518280d8a0e3cac0efed6ce9"><span><div id="3521f2f0518280d8a0e3cac0efed6ce9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280d8a0e3cac0efed6ce9" title="4. 启动 derper"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. 启动 derper</span></span></h3><div class="notion-text notion-block-3521f2f051828035a803c1912574b705">执行：</div><div class="notion-text notion-block-3521f2f051828094bcfafc87df1e45d9">正常输出类似：</div><div class="notion-text notion-block-3521f2f0518280c69f79c4506ef99f4b">其中：</div><div class="notion-text notion-block-3521f2f05182800da7d9fd5469000f31">说明启动成功。</div><div class="notion-text notion-block-3521f2f0518280308923d3ceb8b82889"><code class="notion-inline-code">No mesh key configured</code> 对单台 DERP 来说没问题，可以忽略。</div><hr class="notion-hr notion-block-3521f2f051828029bbb5c9adc9789323"/><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f0518280f8837fe547aef56b51" data-id="3521f2f0518280f8837fe547aef56b51"><span><div id="3521f2f0518280f8837fe547aef56b51" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280f8837fe547aef56b51" title="5. 如果访问域名看到 Nginx 404"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 如果访问域名看到 Nginx 404</span></span></h3><div class="notion-text notion-block-3521f2f05182806f9379d4675d5d6030">一开始我访问域名看到：</div><div class="notion-text notion-block-3521f2f051828013b691f57a58f5df34">这说明访问到的是 Nginx，不是 derper。</div><div class="notion-text notion-block-3521f2f051828034b69afcc0000585a7">原因可能是：</div><div class="notion-text notion-block-3521f2f0518280c3a924e4bb838e3f2e">可以查看端口占用：</div><div class="notion-text notion-block-3521f2f0518280959297d882117db161">正常 derper 应该是：</div><div class="notion-text notion-block-3521f2f051828019804dec28fb0cec3d">如果看到 Nginx 占用 80/443，可以停止并卸载 Nginx：</div><div class="notion-text notion-block-3521f2f0518280fdb4f5f28d733c29e3">我这次实际还有一个问题：<b>DNS 配错了服务器 IP</b>。修正 DNS 后就正常了。</div><hr class="notion-hr notion-block-3521f2f0518280e2b61fc200d891ad3e"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3521f2f0518280a096b9f59f09598cdf" data-id="3521f2f0518280a096b9f59f09598cdf"><span><div id="3521f2f0518280a096b9f59f09598cdf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280a096b9f59f09598cdf" title="七、配置 Tailscale derpMap"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">七、配置 Tailscale derpMap</span></span></h2><div class="notion-text notion-block-3521f2f05182808788c0eb5b6cfc20cc">进入 Tailscale 管理后台：</div><div class="notion-text notion-block-3521f2f05182800fa140c14c1be17ec5">在 ACL JSON 顶层添加 <code class="notion-inline-code">derpMap</code>：</div><div class="notion-text notion-block-3521f2f05182808c9fdacd99e63a66d7">注意：不要覆盖原来的 <code class="notion-inline-code">acls</code>、<code class="notion-inline-code">grants</code> 等内容，只是在顶层增加一个 <code class="notion-inline-code">derpMap</code> 字段。</div><hr class="notion-hr notion-block-3521f2f0518280b399b0fc3a5addef6b"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3521f2f0518280efbd41c1b0c47e3ae8" data-id="3521f2f0518280efbd41c1b0c47e3ae8"><span><div id="3521f2f0518280efbd41c1b0c47e3ae8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280efbd41c1b0c47e3ae8" title="八、刷新客户端"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">八、刷新客户端</span></span></h2><div class="notion-text notion-block-3521f2f0518280cabdeacbb76f7a716f">配置完后，Windows 和 Mac mini 都需要刷新 Tailscale。</div><div class="notion-text notion-block-3521f2f0518280d991f3c4e766ad6200">Windows：</div><div class="notion-text notion-block-3521f2f05182805fbfaafd8143c34d16">如果还没刷新，可以重启服务：</div><div class="notion-text notion-block-3521f2f05182808795d1f9ea2f323009">Mac mini：</div><div class="notion-text notion-block-3521f2f051828025a96ae847e8688cfe">然后分别执行：</div><div class="notion-text notion-block-3521f2f0518280a5b035d4ef088a030d">以及：</div><div class="notion-text notion-block-3521f2f0518280d797f0d7e289247363">成功后会看到：</div><div class="notion-text notion-block-3521f2f05182805ebf28d5559cc6507d">我这里 Windows 看到：</div><div class="notion-text notion-block-3521f2f051828071adc9c58b59702c20">Mac mini 看到：</div><hr class="notion-hr notion-block-3521f2f0518280cbba84fc026b0d99ef"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3521f2f0518280e78c37cad565217ba5" data-id="3521f2f0518280e78c37cad565217ba5"><span><div id="3521f2f0518280e78c37cad565217ba5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280e78c37cad565217ba5" title="九、最终效果"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">九、最终效果</span></span></h2><div class="notion-text notion-block-3521f2f0518280848865ffda32224a19">公司电脑执行：</div><div class="notion-text notion-block-3521f2f0518280b1bfebf29f27384f99">最终结果：</div><div class="notion-text notion-block-3521f2f05182807c9c4cce68195e404b">对比之前：</div><div class="notion-text notion-block-3521f2f051828037bb7ddfc40b300491">效果非常明显。</div><div class="notion-text notion-block-3521f2f05182801a9e98ee27db1cc7f4">VNC 也明显变快了，鼠标、键盘、页面刷新都舒服很多。</div><hr class="notion-hr notion-block-3521f2f051828097aa19e3e3e592929b"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3521f2f051828096a365d5eebcc4ab36" data-id="3521f2f051828096a365d5eebcc4ab36"><span><div id="3521f2f051828096a365d5eebcc4ab36" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f051828096a365d5eebcc4ab36" title="十、配置 derper 开机自启"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">十、配置 derper 开机自启</span></span></h2><div class="notion-text notion-block-3521f2f0518280e2b46fd2e85aeecd6a">为了避免服务器重启后 derper 停掉，需要配置 systemd。</div><div class="notion-text notion-block-3521f2f0518280328cbbc5adbea8c475">创建服务：</div><div class="notion-text notion-block-3521f2f05182806b9d94e28c2b4163d3">写入：</div><div class="notion-text notion-block-3521f2f0518280979b59c88eeec73f1d">启用：</div><div class="notion-text notion-block-3521f2f0518280c7838bfda7b43c17ca">查看日志：</div><hr class="notion-hr notion-block-3521f2f0518280a1afa5ed204e3d4f97"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3521f2f0518280e69382c8ec12b23d08" data-id="3521f2f0518280e69382c8ec12b23d08"><span><div id="3521f2f0518280e69382c8ec12b23d08" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f0518280e69382c8ec12b23d08" title="十一、排查命令汇总"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">十一、排查命令汇总</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f051828043a13bdd8dd71537f1" data-id="3521f2f051828043a13bdd8dd71537f1"><span><div id="3521f2f051828043a13bdd8dd71537f1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f051828043a13bdd8dd71537f1" title="Windows"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Windows</span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f051828072a162f3f64ceae1d2" data-id="3521f2f051828072a162f3f64ceae1d2"><span><div id="3521f2f051828072a162f3f64ceae1d2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f051828072a162f3f64ceae1d2" title="Mac mini"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Mac mini</span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3521f2f051828056b61ad27a5c57ea11" data-id="3521f2f051828056b61ad27a5c57ea11"><span><div id="3521f2f051828056b61ad27a5c57ea11" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f051828056b61ad27a5c57ea11" title="DERP 服务器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">DERP 服务器</span></span></h3><div class="notion-text notion-block-3521f2f051828031b186df521bee4e13">检查 DNS：</div><hr class="notion-hr notion-block-3521f2f0518280599900dfd9394e818b"/><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3521f2f051828050bd5fe307d380016d" data-id="3521f2f051828050bd5fe307d380016d"><span><div id="3521f2f051828050bd5fe307d380016d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3521f2f051828050bd5fe307d380016d" title="十二、总结"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">十二、总结</span></span></h2><div class="notion-text notion-block-3521f2f051828070a730cb64414c4975">这次问题的根因不是 Mac mini 网络坏了，而是：</div><div class="notion-text notion-block-3521f2f051828021a880e6c807f11dce">排查时要重点看：</div><div class="notion-text notion-block-3521f2f05182805f9822e39cf47c0249">最终通过自建国内 DERP，把中继路径从：</div><div class="notion-text notion-block-3521f2f05182804ca7afe4bb878a2737">优化成：</div><div class="notion-text notion-block-3521f2f05182803cac67ddce0885e8e1">延迟从几百毫秒降到 30～40ms，VNC 体验明显改善。</div><div class="notion-blank notion-block-3521f2f051828043b6d4fdefaf5648d4"> </div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>