MoreRSS

site iconSeven | 小柒修改

Java 程序员,热衷自动化。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Seven | 小柒的 RSS 预览

LLM-Wiki:让知识像花园一样持续生长

2026-07-27 00:00:00

<p>自从 Karpathy 提出 <strong>llm-wiki</strong> 这套理念,我就一直想自己动手搭一个 AI 知识库——用它记录笔记、学习知识,也试着让它指引生活。</p><p>几经拖延,最后先让 AI 帮我把 llm-wiki 的生态通盘调研了一遍。结果出乎意料地详实:llm-wiki 为什么出现、解决了什么问题,理念和社区如何发展,有哪些开源实现,又该怎么亲手创建一个——都讲清楚了。</p><p>整理成文,分享至此,供君参考。</p><hr><h2 id="先用一个比喻理解-llm-wiki"><a href="#先用一个比喻理解-llm-wiki" class="headerlink" title="先用一个比喻理解 llm-wiki"></a>先用一个比喻理解 llm-wiki</h2><p>传统 RAG 像一个“临时资料员”:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">你问问题 → 它去仓库里翻几箱资料 → 抽出几页 → 临时拼一个答案</span><br></pre></td></tr></table></figure><p>llm-wiki 更像一个“长期图书管理员 + 研究助理”:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">新资料进来 → 它读懂、归档、做索引、写摘要、加交叉引用、标注冲突</span><br><span class="line">你问问题 → 它先查已经整理好的知识图谱 → 必要时再回原始资料核验</span><br><span class="line">好答案 → 继续沉淀回知识库</span><br></pre></td></tr></table></figure><p>一句话:</p><blockquote><p><strong>RAG 每次临时找资料;llm-wiki 平时就把资料整理成会复利的知识资产。</strong></p></blockquote><span id="more"></span><hr><h2 id="为什么需要-llm-wiki?"><a href="#为什么需要-llm-wiki?" class="headerlink" title="为什么需要 llm-wiki?"></a>为什么需要 llm-wiki?</h2><p>LLM 已经很会“读”,但它有几个现实问题:</p><table><thead><tr><th>问题</th><th>直观表现</th><th>后果</th></tr></thead><tbody><tr><td>上下文会丢</td><td>新 session 不知道旧结论</td><td>重复解释、重复踩坑</td></tr><tr><td>检索是临时的</td><td>每次 query 都重新找片段</td><td>推理不能复利</td></tr><tr><td>资料没有结构</td><td>文档、网页、issue、PDF 堆在一起</td><td>很难回答全局问题</td></tr><tr><td>答案不沉淀</td><td>好答案只存在聊天窗口</td><td>下次还要重来</td></tr><tr><td>冲突不显式</td><td>A 文档和 B 文档矛盾但没人记录</td><td>知识库越来越不可信</td></tr><tr><td>旧事实不失效</td><td>过期结论继续被引用</td><td>agent 可能自信地说错</td></tr></tbody></table><p>llm-wiki 试图解决的不是“怎么搜到更多资料”,而是:</p><blockquote><p><strong>怎么让 LLM 的每次阅读、问答、纠错和总结,都变成可复用、可审计、可维护的长期知识。</strong></p></blockquote><hr><h2 id="一张图看懂-llm-wiki"><a href="#一张图看懂-llm-wiki" class="headerlink" title="一张图看懂 llm-wiki"></a>一张图看懂 llm-wiki</h2><pre><code class="mermaid">flowchart TD A[Raw Sources\n网页 &#x2F; PDF &#x2F; 代码 &#x2F; issue &#x2F; transcript] --&gt; B[Ingest\n读取、理解、拆解] B --&gt; C[Wiki Knowledge Layer\nMarkdown 页面 + wikilinks + citations] C --&gt; D[Query\n基于 wiki 回答问题] D --&gt; E{答案有长期价值吗?} E -- 是 --&gt; C E -- 否 --&gt; F[只返回答案] C --&gt; G[Lint &#x2F; Maintain\n查断链、无引用、冲突、陈旧事实] G --&gt; C C --&gt; H[Derived Indexes\n全文搜索 &#x2F; 向量 &#x2F; 图索引 &#x2F; backlinks] H --&gt; D</code></pre><p>这张图的核心循环是:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">资料进入 → 知识编译 → 问答复用 → 好答案回写 → 定期维护 → 知识继续变好</span><br></pre></td></tr></table></figure><p>这就是“知识复利”。</p><hr><h2 id="三层架构:原始资料、知识层、操作手册"><a href="#三层架构:原始资料、知识层、操作手册" class="headerlink" title="三层架构:原始资料、知识层、操作手册"></a>三层架构:原始资料、知识层、操作手册</h2><pre><code class="mermaid">flowchart TB subgraph L1[第一层:Raw Sources 原始事实层] R1[网页快照] R2[PDF] R3[代码仓库] R4[会议记录] R5[issue &#x2F; PR] end subgraph L2[第二层:Wiki 知识编译层] W1[概念页] W2[实体页] W3[决策页] W4[冲突页] W5[开放问题] W6[索引页] end subgraph L3[第三层:Schema &#x2F; CLAUDE.md &#x2F; AGENTS.md 操作手册层] S1[页面模板] S2[引用规则] S3[新建&#x2F;合并规则] S4[Lint 规则] S5[审批规则] end L1 --&gt; L2 L3 --&gt; L2</code></pre><h3 id="Raw-Sources:像“证据柜”"><a href="#Raw-Sources:像“证据柜”" class="headerlink" title="Raw Sources:像“证据柜”"></a>Raw Sources:像“证据柜”</h3><p>这里保存原始资料,尽量不要改。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">raw/</span><br><span class="line"> web/</span><br><span class="line"> pdf/</span><br><span class="line"> code/</span><br><span class="line"> transcripts/</span><br><span class="line"> issues/</span><br></pre></td></tr></table></figure><p>它的职责是:</p><ul><li>保存事实来源;</li><li>让 wiki 中的 claim 可追溯;</li><li>当模型生成内容可疑时,可以回到原文核验。</li></ul><h3 id="Wiki:像“研究员写的知识图谱”"><a href="#Wiki:像“研究员写的知识图谱”" class="headerlink" title="Wiki:像“研究员写的知识图谱”"></a>Wiki:像“研究员写的知识图谱”</h3><p>这里不是简单摘要堆,而是结构化知识:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">wiki/</span><br><span class="line"> index.md</span><br><span class="line"> concepts/</span><br><span class="line"> entities/</span><br><span class="line"> decisions/</span><br><span class="line"> practices/</span><br><span class="line"> conflicts.md</span><br><span class="line"> open-questions.md</span><br></pre></td></tr></table></figure><p>它的职责是:</p><ul><li>把资料整理成概念;</li><li>把概念互相连接;</li><li>记录引用;</li><li>标注冲突;</li><li>支持后续问答。</li></ul><h3 id="Schema-Instructions:像“图书馆馆规”"><a href="#Schema-Instructions:像“图书馆馆规”" class="headerlink" title="Schema &#x2F; Instructions:像“图书馆馆规”"></a>Schema &#x2F; Instructions:像“图书馆馆规”</h3><p>没有规则,agent 会乱写;有了规则,wiki 才能长期维护。</p><p>例如:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">每个非平凡 claim 必须有 citation。</span><br><span class="line">无法验证的内容标记 [UNVERIFIED]。</span><br><span class="line">来源冲突标记 [CONFLICT]。</span><br><span class="line">删除或合并关键页面前必须人工审批。</span><br></pre></td></tr></table></figure><hr><h2 id="llm-wiki-与-RAG-的区别"><a href="#llm-wiki-与-RAG-的区别" class="headerlink" title="llm-wiki 与 RAG 的区别"></a>llm-wiki 与 RAG 的区别</h2><pre><code class="mermaid">flowchart LR subgraph RAG[传统 RAG] RQ[用户问题] --&gt; RS[检索 top-k chunks] RS --&gt; RA[LLM 临时综合答案] RA --&gt; RO[答案结束\n通常不沉淀] end subgraph WIKI[llm-wiki] S[新资料] --&gt; I[Ingest 编译] I --&gt; K[Markdown 知识图谱] Q[用户问题] --&gt; K K --&gt; A[带引用答案] A --&gt; B{有复用价值?} B -- 是 --&gt; K end</code></pre><table><thead><tr><th>维度</th><th>RAG</th><th>llm-wiki</th></tr></thead><tbody><tr><td>工作时机</td><td>问的时候搜</td><td>平时就整理,问时复用</td></tr><tr><td>知识形态</td><td>chunks + embeddings</td><td>Markdown pages + wikilinks + citations</td></tr><tr><td>是否复利</td><td>弱</td><td>强</td></tr><tr><td>可审计性</td><td>依赖检索日志</td><td>Git diff、引用、页面历史</td></tr><tr><td>冲突处理</td><td>临时判断</td><td>显式记录 conflicts</td></tr><tr><td>人类可读性</td><td>较弱</td><td>强</td></tr><tr><td>适合场景</td><td>局部事实查询、大规模原文召回</td><td>长期知识沉淀、概念图谱、决策记录、研究综合</td></tr></tbody></table><p>更准确地说,二者不是敌人:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">RAG retrieves.</span><br><span class="line">llm-wiki compiles.</span><br><span class="line">GraphRAG connects.</span><br><span class="line">MCP exposes.</span><br><span class="line">Git audits.</span><br><span class="line">Lint maintains.</span><br><span class="line">Human arbitrates.</span><br></pre></td></tr></table></figure><hr><h2 id="三个核心动作:Ingest-Query-Lint"><a href="#三个核心动作:Ingest-Query-Lint" class="headerlink" title="三个核心动作:Ingest &#x2F; Query &#x2F; Lint"></a>三个核心动作:Ingest &#x2F; Query &#x2F; Lint</h2><h3 id="Ingest:不是“摘要”,而是“入库编目”"><a href="#Ingest:不是“摘要”,而是“入库编目”" class="headerlink" title="Ingest:不是“摘要”,而是“入库编目”"></a>Ingest:不是“摘要”,而是“入库编目”</h3><pre><code class="mermaid">sequenceDiagram participant U as User participant A as Agent participant R as Raw Sources participant W as Wiki participant L as Log U-&gt;&gt;A: 导入一篇文章 &#x2F; PDF &#x2F; repo A-&gt;&gt;R: 保存原始资料 A-&gt;&gt;W: 读取 index 和相关页面 A-&gt;&gt;A: 提取概念、事实、冲突、引用 A-&gt;&gt;W: 更新多个页面 A-&gt;&gt;W: 添加 wikilinks 和 citations A-&gt;&gt;L: 记录 ingest log</code></pre><p>关键点:一篇资料不应该只生成“一篇摘要”。</p><p>更好的做法是:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">一篇新文章</span><br><span class="line"> ├─ 更新 concept A</span><br><span class="line"> ├─ 更新 concept B</span><br><span class="line"> ├─ 新建 decision C</span><br><span class="line"> ├─ 给 practice D 加一个反例</span><br><span class="line"> ├─ 在 conflicts.md 记录冲突</span><br><span class="line"> └─ 在 sources.md 记录来源</span><br></pre></td></tr></table></figure><h3 id="Query:先查-wiki,再回-raw-source"><a href="#Query:先查-wiki,再回-raw-source" class="headerlink" title="Query:先查 wiki,再回 raw source"></a>Query:先查 wiki,再回 raw source</h3><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">用户问题</span><br><span class="line"> ↓</span><br><span class="line">查 wiki/index.md</span><br><span class="line"> ↓</span><br><span class="line">读相关页面 TLDR</span><br><span class="line"> ↓</span><br><span class="line">沿 wikilinks 扩展</span><br><span class="line"> ↓</span><br><span class="line">必要时回 raw source 核验</span><br><span class="line"> ↓</span><br><span class="line">输出带引用答案</span><br><span class="line"> ↓</span><br><span class="line">有长期价值则回写 wiki</span><br></pre></td></tr></table></figure><h3 id="Lint:知识库的“体检”"><a href="#Lint:知识库的“体检”" class="headerlink" title="Lint:知识库的“体检”"></a>Lint:知识库的“体检”</h3><pre><code class="mermaid">mindmap root((Wiki Health)) Links broken links orphan pages missing backlinks Claims uncited claims unsupported claims stale claims Structure duplicate pages overlong pages index drift Trust unverified facts unresolved conflicts missing provenance Time expired facts superseded decisions stale summaries</code></pre><p>没有 Lint,wiki 会慢慢腐化。</p><hr><h2 id="2025–2026-的新演化"><a href="#2025–2026-的新演化" class="headerlink" title="2025–2026 的新演化"></a>2025–2026 的新演化</h2><p>调研显示,llm-wiki 相关理念正在与多个方向合流。</p><pre><code class="mermaid">flowchart TD K[llm-wiki\nAgent-maintained Markdown Knowledge Graph] A[Basic Memory\nLocal-first Markdown Memory] --&gt; K B[DeepWiki\nRepo-to-wiki] --&gt; K C[GraphRAG\nGlobal sensemaking] --&gt; K D[LightRAG\nGraph + Vector retrieval] --&gt; K E[Graphiti\nTemporal agent memory] --&gt; K F[MCP\nResources &#x2F; Tools] --&gt; K G[llms.txt\nLLM-facing docs entry] --&gt; K H[Docs-as-code\nGit + Markdown + Review] --&gt; K</code></pre><h3 id="Basic-Memory:Markdown-是真相层"><a href="#Basic-Memory:Markdown-是真相层" class="headerlink" title="Basic Memory:Markdown 是真相层"></a>Basic Memory:Markdown 是真相层</h3><p>启发:</p><blockquote><p>Markdown 不只是导出格式,而是 canonical store。</p></blockquote><p>派生索引可以有很多种:</p><ul><li>SQLite FTS;</li><li>embeddings;</li><li>entity&#x2F;relation table;</li><li>backlinks;</li><li>temporal facts。</li></ul><p>但它们都应该可以重建。</p><h3 id="DeepWiki:代码库可以自动长出-wiki"><a href="#DeepWiki:代码库可以自动长出-wiki" class="headerlink" title="DeepWiki:代码库可以自动长出 wiki"></a>DeepWiki:代码库可以自动长出 wiki</h3><p>启发:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GitHub repo → AI 生成 wiki → 搜索 / 聊天 / 理解架构</span><br></pre></td></tr></table></figure><p>这说明 <code>llm-wiki</code> 可以优先支持代码库:</p><ul><li>架构图;</li><li>模块职责;</li><li>调用链;</li><li>关键概念;</li><li>设计决策;</li><li>onboarding guide。</li></ul><h3 id="GraphRAG:回答全局问题"><a href="#GraphRAG:回答全局问题" class="headerlink" title="GraphRAG:回答全局问题"></a>GraphRAG:回答全局问题</h3><p>传统 RAG 擅长:</p><blockquote><p>“这个函数在哪?”<br>“这段文档怎么说?”</p></blockquote><p>GraphRAG 更适合:</p><blockquote><p>“整个项目有哪些核心模块?”<br>“这些概念之间是什么关系?”<br>“语料中有哪些冲突观点?”</p></blockquote><h3 id="LightRAG:图和向量不是二选一"><a href="#LightRAG:图和向量不是二选一" class="headerlink" title="LightRAG:图和向量不是二选一"></a>LightRAG:图和向量不是二选一</h3><p>最佳结构更像:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Markdown canonical store</span><br><span class="line"> + Full-text search</span><br><span class="line"> + Vector search</span><br><span class="line"> + Graph relations</span><br><span class="line"> + Community summaries</span><br></pre></td></tr></table></figure><h3 id="Graphiti:事实需要时间维度"><a href="#Graphiti:事实需要时间维度" class="headerlink" title="Graphiti:事实需要时间维度"></a>Graphiti:事实需要时间维度</h3><p>旧事实不失效,是 agent memory 的大坑。</p><p>所以重要事实最好有:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">valid_from:</span> <span class="number">2025-01-01</span></span><br><span class="line"><span class="attr">valid_until:</span> <span class="number">2026-03-01</span></span><br><span class="line"><span class="attr">supersedes:</span> <span class="string">old-decision.md</span></span><br><span class="line"><span class="attr">superseded_by:</span> <span class="string">new-decision.md</span></span><br></pre></td></tr></table></figure><h3 id="MCP:让知识库可被-agent-使用"><a href="#MCP:让知识库可被-agent-使用" class="headerlink" title="MCP:让知识库可被 agent 使用"></a>MCP:让知识库可被 agent 使用</h3><p>MCP 适合作为暴露层:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">list resources</span><br><span class="line">read page</span><br><span class="line">search wiki</span><br><span class="line">get backlinks</span><br><span class="line">get source metadata</span><br><span class="line">propose patch</span><br></pre></td></tr></table></figure><p>但 MCP 不解决治理问题。写回仍然需要 review、diff、approval。</p><h3 id="llms-txt:给外部-LLM-的入口"><a href="#llms-txt:给外部-LLM-的入口" class="headerlink" title="llms.txt:给外部 LLM 的入口"></a>llms.txt:给外部 LLM 的入口</h3><p><code>llm-wiki</code> 可以导出:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">/llms.txt</span><br><span class="line">/llms-full.txt</span><br><span class="line">/wiki/index.md</span><br><span class="line">/wiki/topic-map.md</span><br><span class="line">/wiki/source-map.md</span><br></pre></td></tr></table></figure><p>让外部 agent 快速理解这个知识库。</p><h3 id="新进场者:从”想法”到”工厂-城市规划标准”"><a href="#新进场者:从”想法”到”工厂-城市规划标准”" class="headerlink" title="新进场者:从”想法”到”工厂 + 城市规划标准”"></a>新进场者:从”想法”到”工厂 + 城市规划标准”</h3><p>Karpathy 的 llm-wiki 是一份<strong>想法文件</strong>——把规则塞进 CLAUDE.md&#x2F;AGENTS.md,让 agent 自己长出 wiki。2026 年的新故事是:有人开始<strong>专门造工厂</strong>(自动生成&#x2F;维护 wiki 的工具),有人开始<strong>写城市规划标准</strong>(让不同来源的 wiki 能互通)。下面这张生态图把它们按职能分组。</p><h4 id="2026-OSS-实现生态图"><a href="#2026-OSS-实现生态图" class="headerlink" title="2026 OSS 实现生态图"></a>2026 OSS 实现生态图</h4><pre><code class="mermaid">graph TD Idea[&quot;Karpathy llm-wiki&lt;br&#x2F;&gt;想法文件 (2026-04)&quot;] subgraph F1[&quot;🏭 制造工具:生成 + 维护 wiki&quot;] OW[&quot;OpenWiki (LangChain)&lt;br&#x2F;&gt;repo 文档自动测绘队&quot;] OKB[&quot;OpenKB (VectifyAI&#x2F;PageIndex)&lt;br&#x2F;&gt;多格式知识编译车间&quot;] NSU[&quot;nashsu&#x2F;llm_wiki&lt;br&#x2F;&gt;可视化桌面 app&quot;] AS[&quot;AutoSci (PKU DAIR)&lt;br&#x2F;&gt;科研全流程流水线&quot;] end subgraph F2[&quot;📐 交换标准:让 wiki 互通&quot;] OKF[&quot;OKF (Google Cloud)&lt;br&#x2F;&gt;城市规划标准 &#x2F; 知识版 HTTP&quot;] end subgraph F3[&quot;🔍 检索&#x2F;工具配件&quot;] QMD[&quot;qmd (Tobi Lütke)&lt;br&#x2F;&gt;本地混合搜索引擎&quot;] AM[&quot;AGENTS.md (Linux Foundation)&lt;br&#x2F;&gt;agent 入场须知&quot;] end Idea --&gt; OW &amp; OKB &amp; NSU &amp; AS Idea -.-&gt;|形式化| OKF OW --&gt;|注入 pointer| AM OKB --&gt;|遵循| OKF NSU --&gt;|可选调用| QMD OKF -.-&gt;|被消费| AM classDef idea fill:#fff4e6,stroke:#f59f00,color:#000 classDef factory fill:#e7f5ff,stroke:#1c7ed6,color:#000 classDef standard fill:#e6fcf5,stroke:#0ca678,color:#000 classDef tool fill:#f3f0ff,stroke:#7048e8,color:#000 class Idea idea class OW,OKB,NSU,AS factory class OKF standard class QMD,AM tool</code></pre><p>把这张图翻译成我们一直在用的<strong>城市比喻</strong>:</p><ul><li><strong>Karpathy 的想法文件</strong> &#x3D; 一份手抄的”怎么自己盖一座城”的施工笔记。</li><li><strong>OpenWiki</strong> &#x3D; 自动测绘队:扫一遍代码库就把地图(wiki)画好,还每天派 diff 巡逻队把变化补上。</li><li><strong>OpenKB</strong> &#x3D; 编译车间 + 知识炼金炉:把 PDF&#x2F;Word&#x2F;PPT&#x2F;网页统统投进去,炼成互相链接的 Markdown 知识库。</li><li><strong>nashsu&#x2F;llm_wiki</strong> &#x3D; 一座带 3D 地图、社区聚类、观光电梯的现代化知识城(桌面 app)。</li><li><strong>AutoSci</strong> &#x3D; 全自动科研流水线:从读论文到做实验、写论文、做海报一条龙。</li><li><strong>OKF (Google)</strong> &#x3D; 城市规划标准 &#x2F; 知识版 HTTP:规定每栋楼(每个概念)必须挂什么门牌(<code>type</code> 字段)、街道怎么命名(文件路径即身份),让不同城市之间能互相读懂地图。</li><li><strong>qmd</strong> &#x3D; 本地搜索引擎,相当于城里的”按意义找路”导航仪。</li><li><strong>AGENTS.md</strong> &#x3D; 给所有 agent 的入场须知,告诉它们”进城先读哪份地图”。</li></ul><blockquote><p>一句话区分:<strong>制造工具解决”怎么把 wiki 长出来”,交换标准解决”长出来的 wiki 怎么互通”。</strong> 2026 年的变化是这两件事第一次被分开做。</p></blockquote><h3 id="四位新玩家速写"><a href="#四位新玩家速写" class="headerlink" title="四位新玩家速写"></a>四位新玩家速写</h3><p>下面每个小条目都遵守同一格式:<strong>是什么 &#x2F; 与 llm-wiki 的关系 &#x2F; 一个要小心的坑</strong>。</p><h4 id="OpenWiki(LangChain)—-自动测绘队"><a href="#OpenWiki(LangChain)—-自动测绘队" class="headerlink" title="OpenWiki(LangChain)— 自动测绘队"></a>OpenWiki(LangChain)— 自动测绘队</h4><ul><li><strong>是什么</strong>:TypeScript CLI(<code>npm i -g openwiki</code>),基于 LangChain 的 DeepAgents,给代码库生成一份 <code>openwiki/</code> 目录的 Markdown wiki;再在顶层 AGENTS.md&#x2F;CLAUDE.md 里<strong>只插一小段指路牌</strong>(pointer),让已有编码 agent 按需去读 wiki,而不是把整本 wiki 塞进上下文。配套 GitHub Action 每天按 git diff 自动开 PR 保鲜。</li><li><strong>与 llm-wiki 的关系</strong>:把 Karpathy 的”人类手工 + 通用 agent 维护 wiki”升级为<strong>专用生成器 + CI 自维护器</strong>;专门解决 Karpathy 留给用户的”wiki 怎么和 agent 接线”和”怎么不腐烂”两个痛点。范围比 llm-wiki 窄——目前只面向代码库(博客说未来可能扩到其他工作流)。</li><li><strong>坑</strong>:v0.0.1、repo 仅约两周大(2026-06-22 创建)、约 7k 星基本是发布博客带起来的热度,<strong>不是耐久度</strong>。预设模型清单(constants.ts 核验)实为 GLM 5.2 &#x2F; Kimi K2.7 Code &#x2F; Claude Sonnet 5——部分二手报道误写成 K2.6。无 MCP、无 llms.txt、无任何 FTS&#x2F;向量&#x2F;图索引——“wiki for agents”的框架下,检索其实只是 agent 直接读 Markdown。</li></ul><blockquote><p><strong>比喻</strong>:OpenWiki 是”只在城门口立一块指路牌”的设计——地图(wiki)和指路牌(AGENTS.md 里那几行)分开,既避免上下文爆炸,又让 wiki 可以独立长大。</p></blockquote><h4 id="OpenKB(VectifyAI-PageIndex)—-编译车间-知识炼金炉"><a href="#OpenKB(VectifyAI-PageIndex)—-编译车间-知识炼金炉" class="headerlink" title="OpenKB(VectifyAI &#x2F; PageIndex)— 编译车间 + 知识炼金炉"></a>OpenKB(VectifyAI &#x2F; PageIndex)— 编译车间 + 知识炼金炉</h4><ul><li><strong>是什么</strong>:Apache-2.0 Python CLI(<code>pip install openkb</code>),把 PDF&#x2F;Word&#x2F;PPT&#x2F;Excel&#x2F;HTML&#x2F;CSV&#x2F;URL 等多格式原料编译成一份结构化、互相链接的 Markdown wiki(<code>summaries/ concepts/ entities/</code>),用 <code>[[wikilinks]]</code> 串联,Obsidian 可直接打开。卖点”<strong>无向量数据库</strong>“:长 PDF(默认 ≥20 页)走 PageIndex 的<strong>无向量、推理式树索引</strong>,短文档直接全文喂给 LLM。带 query&#x2F;chat&#x2F;skill factory&#x2F;可视化&#x2F;deck 等生成器。</li><li><strong>与 llm-wiki 的关系</strong>:README 明说”基于 Karpathy 描述的概念”,并逐条对比自己比 Karpathy 多做了什么——其中最关键一条是<strong>直接解决 Karpathy 自己点名的”长 PDF 难题”</strong>(Karpathy 承认长文档会上下文腐烂)。把”丢网页剪报到 .md”的输入扩到 PDF&#x2F;Office&#x2F;URL 全家桶;把手工维护概念页换成自动实体抽取(人&#x2F;组织&#x2F;地点&#x2F;产品)。</li><li><strong>坑</strong>:仍是 Alpha(pyproject 分类器写明 Development Status :: 3 - Alpha)。”长 PDF 质量”完全押在 PageIndex 引擎上,开源版能力有限,进阶功能(扫描版 PDF OCR、更快结构生成)要走付费的 PageIndex Cloud(<code>PAGEINDEX_API_KEY</code>)。PageIndex 树索引目前<strong>只支持 PDF</strong>,非 PDF 长文仍走全文读取,照样撞上下文墙。</li></ul><blockquote><p><strong>比喻</strong>:OpenKB 是”只炼不埋”的炼金炉——知识在 ingest 时就被炼成结构化页面,query 时只是去取成品,而不是每次重新淘金(这正是它对标 RAG 的核心论点)。</p></blockquote><h4 id="nashsu-llm-wiki-—-一座可视化桌面知识城"><a href="#nashsu-llm-wiki-—-一座可视化桌面知识城" class="headerlink" title="nashsu&#x2F;llm_wiki — 一座可视化桌面知识城"></a>nashsu&#x2F;llm_wiki — 一座可视化桌面知识城</h4><ul><li><strong>是什么</strong>:跨平台 Tauri v2 桌面 app(macOS&#x2F;Windows&#x2F;Linux),把文档变成互相链接的 Markdown wiki,配 GUI、4 信号知识图谱(直接链接 ×3.0 &#x2F; 来源重叠 ×4.0 &#x2F; Adamic-Adar ×1.5 &#x2F; 类型亲和 ×1.0)、Louvain 社区检测、可选 LanceDB 向量搜索、深度研究、Chrome 剪藏扩展、本地 HTTP API + MCP server + 可装 agent skill。仓库自带一份 <code>llm-wiki.md</code>,把 Karpathy 的模式文字逐字收录。</li><li><strong>与 llm-wiki 的关系</strong>:README 写明”based on Karpathy’s LLM Wiki pattern”,<strong>忠实保留</strong>三层架构(raw 不可变 &#x2F; wiki LLM 生成 &#x2F; schema 规则)、Ingest&#x2F;Query&#x2F;Lint 三操作、index.md&#x2F;log.md&#x2F;[[wikilinks]]&#x2F;YAML frontmatter&#x2F;Obsidian 兼容;<strong>大幅扩展</strong>为产品化 app:两步思维链 ingest(先分析后生成)、purpose.md(wiki 的方向意图,每次 ingest&#x2F;query 都读)、SHA256 增量缓存、持久化 ingest 队列、文件夹监听、深度研究、异步 review 队列、级联删除等。</li><li><strong>坑</strong>:GPL-3.0(copyleft,商用嵌入要留意)。仓库仅约 3 个月大(2026-04-08 创建)就有 1.37 万星,增速惊人但<strong>长期维护未经验证</strong>。README 自报的”recall 58.2%→71.4%”是自测,无第三方复现。本地 PDF 解析实际用 <code>pdfium-render</code>(README 误标为 “pdf-extract”);<strong>可选的 MinerU 云端 PDF 解析(默认关闭,失败回退本地)会把文件传第三方云</strong>,与 “local-first” 叙事略有张力。</li></ul><blockquote><p><strong>比喻</strong>:nashsu&#x2F;llm_wiki 是”带观光电梯的现代化知识城”——你既能像 Obsidian 一样在地上走,也能坐电梯(GUI + 图谱)从空中看全城分区。</p></blockquote><h4 id="Google-OKF-—-城市规划标准-知识版-HTTP"><a href="#Google-OKF-—-城市规划标准-知识版-HTTP" class="headerlink" title="Google OKF — 城市规划标准 &#x2F; 知识版 HTTP"></a>Google OKF — 城市规划标准 &#x2F; 知识版 HTTP</h4><ul><li><strong>是什么</strong>:Google Cloud 在 2026-06-12 发布的开放规范 v0.1 Draft。一个”知识包”就是一目录 Markdown 文件(一个概念一个文件),唯一<strong>必填</strong> frontmatter 字段是 <code>type</code>;推荐字段 title&#x2F;description&#x2F;resource&#x2F;tags&#x2F;timestamp。文件路径(去掉 .md)就是概念身份。保留文件名 <code>index.md</code>(渐进式目录)和 <code>log.md</code>(按日期分组的变更史)。交叉链接用普通 Markdown 链接,把目录变成比父子层级更丰富的图。<strong>显式</strong>不规定存储&#x2F;服务&#x2F;查询基础设施,不定义 FTS&#x2F;向量&#x2F;图索引——这些全部留给消费端。</li><li><strong>与 llm-wiki 的关系</strong>:Google 博客直接引 Karpathy 原话(”LLMs 不会无聊、不会忘记更新交叉引用、一次能改 15 个文件”),把 OKF 定位为”把 LLM-wiki 模式正式化为可移植、可互操作的格式”。SPEC 第 10 节把”用 Markdown + frontmatter 做 agent 可读知识库的 LLM wiki 仓库”列为最近的同类模式,区别在于 OKF 是<strong>被规范化的</strong>——钉死了最小互操作约定(必填 type、保留文件名、链接语义、宽容一致性)。可看作 Karpathy 模式的”最小公约数超集”:任何已有 wiki 只要加一个 <code>type</code> 字段就合规。</li><li><strong>坑</strong>:v0.1 Draft,会变。仓库挂 GoogleCloudPlatform 名却自带”not an official Google product”免责声明。发布会现场唯一确认的生产消费者是 Google 自家的 Knowledge Catalog(前 Dataplex)——跨生产者&#x2F;消费者的真实互操作<strong>尚未被证明</strong>。规范本身<strong>不含</strong> MCP&#x2F;llms.txt&#x2F;任何运行时协议;它只是一份文件格式契约。</li></ul><blockquote><p><strong>比喻</strong>:OKF 不盖楼,只发布”城市规划标准”——只要每栋楼挂对门牌(type),任何城市的地图(不同生产者产出的 wiki)都能被任何游客(agent)读懂。它是知识界的 HTTP:一个最小约定,换最大互通。</p></blockquote><h3 id="我该选哪个?一张决策表"><a href="#我该选哪个?一张决策表" class="headerlink" title="我该选哪个?一张决策表"></a>我该选哪个?一张决策表</h3><p>下面这张表把本章出现的新工具按”最适合干嘛”排成一列,帮你按场景对号入座。<strong>重要前提</strong>:它们大多数非常年轻(几周到几个月大),star 数 ≠ 耐久度;任何生产采用前请回源核对最新状态。</p><table><thead><tr><th>你的场景</th><th>优先考虑</th><th>为什么</th><th>一句话 caveat</th></tr></thead><tbody><tr><td>想给一个 <strong>GitHub 代码库</strong>自动生成并 CI 自维护一份给 agent 用的文档</td><td><strong>OpenWiki</strong></td><td>自动测绘队 + 每天按 git diff 开 PR,AGENTS.md 只插 pointer 不撑爆上下文</td><td>v0.0.1、仅 ~2 周大,无向量&#x2F;FTS&#x2F;图索引,检索靠 agent 直读 Markdown</td></tr><tr><td>有<strong>长 PDF &#x2F; Word &#x2F; PPT &#x2F; 网页</strong>混合资料,想编译成 Obsidian 可读的知识库</td><td><strong>OpenKB</strong></td><td>多格式 ingest + 无向量 PageIndex 树索引,专治 Karpathy 点名的长 PDF 难题</td><td>Alpha 阶段;长 PDF 质量押在 PageIndex,进阶功能走付费云;非 PDF 长文仍撞上下文墙</td></tr><tr><td>想要一个<strong>带 GUI &#x2F; 图谱 &#x2F; 可视化</strong>的桌面”第二大脑”,跨平台</td><td><strong>nashsu&#x2F;llm_wiki</strong></td><td>Tauri 桌面 app,4 信号图谱 + Louvain 社区 + 可选向量 + 深度研究 + Chrome 剪藏</td><td>GPL-3.0(copyleft);3 个月大 1.37 万星但长期维护未证;自测 recall 未第三方复现</td></tr><tr><td>要做<strong>科研全流程</strong>:读论文→点子→实验→写论文→海报</td><td><strong>AutoSci</strong></td><td>30+ Claude Code 技能覆盖全生命周期 + 双模型交叉评审 + 远程 GPU + arXiv 配套论文</td><td>仅 Claude Code 耦合;README 自承”No native MCP”是错的(实际含 llm-review MCP);3 个月大、internal beta</td></tr><tr><td>你已经有 wiki,想让<strong>不同工具&#x2F;团队&#x2F;agent</strong>能互相读懂对方的 wiki</td><td><strong>OKF</strong>(给所有页面加 <code>type</code> 字段)</td><td>最小公约数换最大互通,知识版 HTTP;Google Knowledge Catalog 已 ingest</td><td>v0.1 Draft;唯一确认生产消费者是 Google 自家;跨组织互操作未被证明</td></tr><tr><td>你只想给 agent 一个<strong>本地混合搜索</strong>(BM25 + 向量 + 重排),不换 wiki 形态</td><td><strong>qmd</strong>(Tobi Lütke)</td><td>完全本地、GGUF 模型、CLI + MCP server,Karpathy gist 亲自推荐</td><td>首跑下载 ~2GB 模型;Node.js ≥22;默认 glob 是 <code>**/*.md</code></td></tr><tr><td>你只想给 agent 一份<strong>入场须知</strong>,让它知道”进城先读哪份地图”</td><td><strong>AGENTS.md</strong>(Linux Foundation)</td><td>跨厂商事实标准,60k+ 项目在用,MCP 同基金会托管</td><td>不是知识库,只是单文件约定;60k 数字是自报营销;托管方是 Linux Foundation(非 OpenAI)</td></tr></tbody></table><h4 id="三条决策捷径"><a href="#三条决策捷径" class="headerlink" title="三条决策捷径"></a>三条决策捷径</h4><ol><li><strong>要 CI 自维护的 repo 文档 → OpenWiki。</strong> 它是唯一一个把”git diff 驱动每日 PR”做成头等公民的。</li><li><strong>要长 PDF &#x2F; 多格式知识库 → OpenKB。</strong> 它是唯一一个把”无向量长文档检索”当核心卖点的。</li><li><strong>要让多个工具互通 → 给所有输出加 OKF 的 <code>type</code> 字段。</strong> 这是成本最低的”未来兼容”保险。</li></ol><pre><code class="mermaid">flowchart LR Q1{&quot;要给代码库&lt;br&#x2F;&gt;做文档?&quot;} Q2{&quot;有长 PDF&#x2F;&lt;br&#x2F;&gt;多格式资料?&quot;} Q3{&quot;要可视化&lt;br&#x2F;&gt;桌面端?&quot;} Q4{&quot;要让多个工具&lt;br&#x2F;&gt;互通?&quot;} Q1 -- 是 --&gt; OW[OpenWiki] Q1 -- 否 --&gt; Q2 Q2 -- 是 --&gt; OKB[OpenKB] Q2 -- 否 --&gt; Q3 Q3 -- 是 --&gt; NSU[nashsu&#x2F;llm_wiki] Q3 -- 否 --&gt; Q4 Q4 -- 是 --&gt; OKF[给页面加 OKF type 字段] Q4 -- 否 --&gt; RAW[继续用 Karpathy 原版&lt;br&#x2F;&gt;+ AGENTS.md 指针] classDef pick fill:#d3f9d8,stroke:#2f9e44,color:#000 class OW,OKB,NSU,OKF pick</code></pre><blockquote><p><strong>一句话总结这一节</strong>:2026 年的变化不是”又有了一个新 llm-wiki”,而是<strong>生态开始分工</strong>——有人专做制造(OpenWiki&#x2F;OpenKB),有人专做标准(OKF),有人专做配件(qmd&#x2F;AGENTS.md)。你不再需要在”一个工具搞定一切”和”从零手搓”之间二选一。</p></blockquote><hr><h2 id="推荐的现代架构"><a href="#推荐的现代架构" class="headerlink" title="推荐的现代架构"></a>推荐的现代架构</h2><pre><code class="mermaid">flowchart TB subgraph Canonical[Markdown Canonical Store 真相层] C1[wiki pages] C2[source notes] C3[decisions] C4[observations] C5[llms.txt &#x2F; index] end subgraph Raw[Raw Source Store 原始资料层] R1[web snapshots] R2[PDFs] R3[transcripts] R4[code dumps] end subgraph Index[Derived Indexes 可重建索引层] I1[SQLite FTS] I2[Embeddings] I3[Entity &#x2F; Relation Table] I4[Backlinks] I5[Temporal Facts] I6[Community Summaries] end subgraph Interface[Agent Interface 交互层] A1[CLI] A2[MCP Resources] A3[MCP Tools] A4[Editor Integration] A5[Scheduled Workflows] end subgraph Gov[Governance 治理层] G1[Citations] G2[Provenance] G3[Confidence] G4[valid_from &#x2F; valid_until] G5[Diff Review] G6[Approval Policy] G7[Evaluation Metrics] end Raw --&gt; Canonical Canonical --&gt; Index Index --&gt; Interface Interface --&gt; Canonical Gov --&gt; Canonical Gov --&gt; Interface</code></pre><p>设计原则:</p><blockquote><p>Markdown 是真相层;索引是派生层;agent 写回必须受治理约束。</p></blockquote><hr><h2 id="一个页面应该长什么样?"><a href="#一个页面应该长什么样?" class="headerlink" title="一个页面应该长什么样?"></a>一个页面应该长什么样?</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">type: concept</span><br><span class="line">title: Agent-maintained wiki</span><br><span class="line">status: draft</span><br><span class="line">confidence: medium</span><br><span class="line">sources:</span><br><span class="line"><span class="bullet"> -</span> raw/web/karpathy-llm-wiki.md</span><br><span class="line"><span class="bullet"> -</span> raw/web/basic-memory.md</span><br><span class="line">valid<span class="emphasis">_from: 2025-01-01</span></span><br><span class="line"><span class="emphasis">valid_</span>until:</span><br><span class="line">generated<span class="emphasis">_by: claude</span></span><br><span class="line"><span class="emphasis">reviewed_</span>by:</span><br><span class="line">---</span><br><span class="line"></span><br><span class="line"><span class="section"># Agent-maintained wiki</span></span><br><span class="line"></span><br><span class="line"><span class="section">## TLDR</span></span><br><span class="line"></span><br><span class="line">Agent-maintained wiki 是由 LLM 持续维护的 Markdown 知识图谱,用于把阅读、问答、纠错沉淀为长期可复用知识。</span><br><span class="line"></span><br><span class="line"><span class="section">## Key Claims</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> 它与传统 RAG 的区别在于:知识不是只在 query-time 临时检索,而是在 ingest/maintenance 阶段持续编译。[source: raw/web/karpathy-llm-wiki.md]</span><br><span class="line"><span class="bullet">-</span> Markdown 适合作为 canonical store,因为它可读、可 diff、可迁移。[source: raw/web/basic-memory.md]</span><br><span class="line"></span><br><span class="line"><span class="section">## Relations</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> related<span class="emphasis">_to: [[RAG]]</span></span><br><span class="line"><span class="emphasis">- contrasts_</span>with: [[Vector Database]]</span><br><span class="line"><span class="bullet">-</span> enables: [[Knowledge Compounding]]</span><br><span class="line"><span class="bullet">-</span> exposed<span class="emphasis">_by: [[MCP Resources]]</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">## Open Questions</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">- 如何自动判断页面粒度?</span></span><br><span class="line"><span class="emphasis">- 哪些 agent 写回可以自动合并?</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">## Conflicts</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">- [CONFLICT] 某些实践主张纯 Markdown 足够,GraphRAG 路线主张额外构建图索引。</span></span><br></pre></td></tr></table></figure><hr><h2 id="失败模式:知识花园也会长杂草"><a href="#失败模式:知识花园也会长杂草" class="headerlink" title="失败模式:知识花园也会长杂草"></a>失败模式:知识花园也会长杂草</h2><pre><code class="mermaid">flowchart TD F[失败模式] F --&gt; A[幻觉固化\n生成内容被当事实] F --&gt; B[引用漂移\ncitation 不支持 claim] F --&gt; C[旧事实不失效\nstale knowledge] F --&gt; D[结构腐化\nindex 和页面不同步] F --&gt; E[图抽取错误\n实体重复&#x2F;关系错] F --&gt; G[写回污染\nagent 无审查改 wiki] F --&gt; H[粒度失控\n页面太粗或太碎] A --&gt; M1[claim-level citation] B --&gt; M2[source quote &#x2F; provenance] C --&gt; M3[valid_from &#x2F; valid_until] D --&gt; M4[lint &#x2F; health report] E --&gt; M5[entity resolution &#x2F; graph diff] G --&gt; M6[propose patch + review] H --&gt; M7[evolve workflow]</code></pre><p>最重要的原则:</p><blockquote><p>生成内容不是事实,带来源、可核验、可审计的内容才逐渐接近事实。</p></blockquote><hr><h2 id="评估指标:怎么知道-wiki-真的在变好?"><a href="#评估指标:怎么知道-wiki-真的在变好?" class="headerlink" title="评估指标:怎么知道 wiki 真的在变好?"></a>评估指标:怎么知道 wiki 真的在变好?</h2><h3 id="回答质量"><a href="#回答质量" class="headerlink" title="回答质量"></a>回答质量</h3><table><thead><tr><th>指标</th><th>含义</th></tr></thead><tbody><tr><td>answer groundedness</td><td>答案是否被来源支持</td></tr><tr><td>citation coverage</td><td>关键 claim 是否有引用</td></tr><tr><td>unsupported claim rate</td><td>无来源 claim 的比例</td></tr><tr><td>query success rate</td><td>用户问题是否被有效回答</td></tr><tr><td>source fallback rate</td><td>回 raw source 的频率</td></tr></tbody></table><h3 id="Wiki-健康"><a href="#Wiki-健康" class="headerlink" title="Wiki 健康"></a>Wiki 健康</h3><table><thead><tr><th>指标</th><th>含义</th></tr></thead><tbody><tr><td>broken link rate</td><td>断链比例</td></tr><tr><td>orphan page rate</td><td>孤儿页比例</td></tr><tr><td>duplicate entity rate</td><td>重复实体比例</td></tr><tr><td>stale claim count</td><td>过期 claim 数量</td></tr><tr><td>unresolved conflict count</td><td>未解决冲突数量</td></tr><tr><td>source coverage</td><td>raw source 被 wiki 表达的比例</td></tr></tbody></table><h3 id="Agent-写回治理"><a href="#Agent-写回治理" class="headerlink" title="Agent 写回治理"></a>Agent 写回治理</h3><table><thead><tr><th>指标</th><th>含义</th></tr></thead><tbody><tr><td>proposed patch count</td><td>agent 提议修改数</td></tr><tr><td>accepted patch rate</td><td>被接受比例</td></tr><tr><td>rejected patch rate</td><td>被拒绝比例</td></tr><tr><td>revert rate</td><td>回滚比例</td></tr><tr><td>human edit latency</td><td>人工审查延迟</td></tr><tr><td>high-risk write attempts</td><td>高风险写入尝试</td></tr></tbody></table><h3 id="成本"><a href="#成本" class="headerlink" title="成本"></a>成本</h3><table><thead><tr><th>指标</th><th>含义</th></tr></thead><tbody><tr><td>ingest cost per source</td><td>每个 source 的导入成本</td></tr><tr><td>query token cost</td><td>每次回答 token 成本</td></tr><tr><td>index rebuild cost</td><td>重建索引成本</td></tr><tr><td>graph extraction cost</td><td>图抽取成本</td></tr><tr><td>source-to-wiki compression ratio</td><td>原文到 wiki 的压缩比例</td></tr></tbody></table><hr><h2 id="推荐路线图"><a href="#推荐路线图" class="headerlink" title="推荐路线图"></a>推荐路线图</h2><pre><code class="mermaid">gantt title llm-wiki 路线图 dateFormat YYYY-MM-DD section Phase 0 定义目标对象 :a1, 2026-06-20, 7d section Phase 1 Markdown canonical schema :a2, after a1, 14d section Phase 2 可重建索引 :a3, after a2, 21d section Phase 3 Ingest &#x2F; Query &#x2F; Lint CLI :a4, after a3, 21d section Phase 4 MCP resources first :a5, after a4, 21d section Phase 5 Temporal provenance layer :a6, after a5, 21d section Phase 6 Evaluation and governance :a7, after a6, 21d</code></pre><h3 id="Phase-0:定义目标对象"><a href="#Phase-0:定义目标对象" class="headerlink" title="Phase 0:定义目标对象"></a>Phase 0:定义目标对象</h3><p>先决定 <code>llm-wiki</code> 优先服务什么:</p><ul><li>代码库文档;</li><li>个人知识管理;</li><li>团队决策记录;</li><li>research corpus;</li><li>agent memory。</li></ul><p>推荐先从:</p><blockquote><p>research corpus + project knowledge</p></blockquote><p>开始,最容易验证闭环。</p><h3 id="Phase-1:Markdown-canonical-schema"><a href="#Phase-1:Markdown-canonical-schema" class="headerlink" title="Phase 1:Markdown canonical schema"></a>Phase 1:Markdown canonical schema</h3><p>先定义页面结构,而不是先做复杂 UI。</p><p>必须明确:</p><ul><li>页面类型;</li><li>frontmatter;</li><li>source&#x2F;provenance;</li><li>confidence;</li><li>valid_from &#x2F; valid_until;</li><li>generated_by &#x2F; reviewed_by;</li><li>typed relations。</li></ul><h3 id="Phase-2:可重建索引"><a href="#Phase-2:可重建索引" class="headerlink" title="Phase 2:可重建索引"></a>Phase 2:可重建索引</h3><p>建立:</p><ul><li>full-text search;</li><li>backlinks;</li><li>source map;</li><li>entity&#x2F;relation table;</li><li>embeddings;</li><li>temporal fact table。</li></ul><h3 id="Phase-3:核心-CLI"><a href="#Phase-3:核心-CLI" class="headerlink" title="Phase 3:核心 CLI"></a>Phase 3:核心 CLI</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">llm-wiki ingest &lt;<span class="built_in">source</span>&gt;</span><br><span class="line">llm-wiki query <span class="string">&quot;&lt;question&gt;&quot;</span></span><br><span class="line">llm-wiki lint</span><br><span class="line">llm-wiki evolve</span><br></pre></td></tr></table></figure><h3 id="Phase-4:MCP-resources-first"><a href="#Phase-4:MCP-resources-first" class="headerlink" title="Phase 4:MCP resources first"></a>Phase 4:MCP resources first</h3><p>先做只读 MCP:</p><ul><li>list pages;</li><li>read page;</li><li>search;</li><li>backlinks;</li><li>sources;</li><li>health report。</li></ul><p>写操作只提供 propose patch,不直接改。</p><h3 id="Phase-5:Temporal-and-provenance-layer"><a href="#Phase-5:Temporal-and-provenance-layer" class="headerlink" title="Phase 5:Temporal and provenance layer"></a>Phase 5:Temporal and provenance layer</h3><p>加入:</p><ul><li>valid_from;</li><li>valid_until;</li><li>supersedes;</li><li>superseded_by;</li><li>source quote;</li><li>source trust;</li><li>stale lint。</li></ul><h3 id="Phase-6:Evaluation-and-governance"><a href="#Phase-6:Evaluation-and-governance" class="headerlink" title="Phase 6:Evaluation and governance"></a>Phase 6:Evaluation and governance</h3><p>建立:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">llm-wiki health</span><br></pre></td></tr></table></figure><p>输出 health report,让 wiki 可长期维护。</p><hr><h2 id="最终心智模型"><a href="#最终心智模型" class="headerlink" title="最终心智模型"></a>最终心智模型</h2><p>如果把知识系统比作城市:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">Raw Sources 是档案馆</span><br><span class="line">Wiki Pages 是城市街区</span><br><span class="line">Wikilinks 是道路</span><br><span class="line">Index 是地图</span><br><span class="line">Citations 是门牌和产权证明</span><br><span class="line">Lint 是城管和质检</span><br><span class="line">MCP 是城市 API</span><br><span class="line">llms.txt 是游客指南</span><br><span class="line">GraphRAG 是城市规划图</span><br><span class="line">Temporal Memory 是历史档案</span><br><span class="line">Human Review 是市政审批</span><br><span class="line">Agent 是图书管理员 + 城市维护工</span><br></pre></td></tr></table></figure><p>真正的 llm-wiki 不是“自动写几篇 Markdown”,而是:</p><blockquote><p>一个由 agent 持续维护、由 human 审查裁决、以 Markdown 为真相层、以引用和时间维度保证可信、以索引和协议连接外部工具的知识基础设施。</p></blockquote><hr><h2 id="可以直接对外讲的版本"><a href="#可以直接对外讲的版本" class="headerlink" title="可以直接对外讲的版本"></a>可以直接对外讲的版本</h2><h3 id="30-秒版本"><a href="#30-秒版本" class="headerlink" title="30 秒版本"></a>30 秒版本</h3><p><code>llm-wiki</code> 是一种让 LLM 长期维护知识库的方法。它不是每次问问题时临时 RAG,而是把资料提前整理成带引用、带链接、可审计的 Markdown 知识图谱。每次导入资料、回答问题、发现冲突,都会让知识库变得更好。</p><h3 id="2-分钟版本"><a href="#2-分钟版本" class="headerlink" title="2 分钟版本"></a>2 分钟版本</h3><p>传统 RAG 像临时翻资料:用户问问题,系统检索几个片段,然后让 LLM 拼答案。问题是,每次推理都不一定沉淀,冲突和纠错也很难长期保留。</p><p><code>llm-wiki</code> 的做法是把 LLM 变成长期图书管理员。新资料进入时,agent 把它保存为 raw source,然后更新多个 Markdown wiki 页面,添加引用、交叉链接、冲突标记和开放问题。用户提问时,agent 先读已经整理好的 wiki,必要时回原始资料核验。好的答案还可以回写进 wiki。</p><p>现代版本的 <code>llm-wiki</code> 还可以叠加全文搜索、向量检索、图索引、MCP、llms.txt 和 temporal memory。但核心原则不变:Markdown 是可读、可 diff、可迁移的真相层;索引是可重建的派生层;agent 写回必须受治理约束。</p><h3 id="一句话项目宣言"><a href="#一句话项目宣言" class="headerlink" title="一句话项目宣言"></a>一句话项目宣言</h3><blockquote><p><code>llm-wiki</code> is an agent-maintained, source-cited, Markdown-native knowledge graph with rebuildable search, graph, and vector indexes. It turns reading, reasoning, Q&amp;A, and corrections into a persistent, auditable, temporally aware compounding artifact.</p></blockquote><hr><h2 id="Sources"><a href="#Sources" class="headerlink" title="Sources"></a>Sources</h2><p>主要参考:</p><ul><li>Karpathy Gist:<span class="exturl" data-url="aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20va2FycGF0aHkvNDQyYTZiZjU1NTkxNDg5M2U5ODkxYzExNTE5ZGU5NGY=">https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f<i class="fa fa-external-link-alt"></i></span></li><li>Karpathy Gist raw:<span class="exturl" data-url="aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rYXJwYXRoeS80NDJhNmJmNTU1OTE0ODkzZTk4OTFjMTE1MTlkZTk0Zi9yYXcvbGxtLXdpa2kubWQ=">https://gist.githubusercontent.com/karpathy/442a6bf555914893e9891c11519de94f/raw/llm-wiki.md<i class="fa fa-external-link-alt"></i></span></li><li>Basic Memory:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2Jhc2ljbWFjaGluZXMtY28vYmFzaWMtbWVtb3J5">https://github.com/basicmachines-co/basic-memory<i class="fa fa-external-link-alt"></i></span></li><li>DeepWiki:<span class="exturl" data-url="aHR0cHM6Ly9jb2duaXRpb24uY29tL2Jsb2cvZGVlcHdpa2k=">https://cognition.com/blog/deepwiki<i class="fa fa-external-link-alt"></i></span></li><li>Graphiti:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2dldHplcC9ncmFwaGl0aQ==">https://github.com/getzep/graphiti<i class="fa fa-external-link-alt"></i></span></li><li>Microsoft GraphRAG:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9ncmFwaHJhZw==">https://github.com/microsoft/graphrag<i class="fa fa-external-link-alt"></i></span></li><li>GraphRAG paper:<span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvYWJzLzI0MDQuMTYxMzA=">https://arxiv.org/abs/2404.16130<i class="fa fa-external-link-alt"></i></span></li><li>LightRAG paper:<span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvYWJzLzI0MTAuMDU3Nzk=">https://arxiv.org/abs/2410.05779<i class="fa fa-external-link-alt"></i></span></li><li>LightRAG repo:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0hLVURTL0xpZ2h0UkFH">https://github.com/HKUDS/LightRAG<i class="fa fa-external-link-alt"></i></span></li><li>MCP Resources:<span class="exturl" data-url="aHR0cHM6Ly9tb2RlbGNvbnRleHRwcm90b2NvbC5pby9kb2NzL2NvbmNlcHRzL3Jlc291cmNlcw==">https://modelcontextprotocol.io/docs/concepts/resources<i class="fa fa-external-link-alt"></i></span></li><li>llms.txt:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0Fuc3dlckRvdEFJL2xsbXMtdHh0">https://github.com/AnswerDotAI/llms-txt<i class="fa fa-external-link-alt"></i></span></li><li>Claude Code memory docs:<span class="exturl" data-url="aHR0cHM6Ly9jb2RlLmNsYXVkZS5jb20vZG9jcy9lbi9tZW1vcnk=">https://code.claude.com/docs/en/memory<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="2026-07-07-增量(§6-8–6-10)新增来源"><a href="#2026-07-07-增量(§6-8–6-10)新增来源" class="headerlink" title="2026-07-07 增量(§6.8–6.10)新增来源"></a>2026-07-07 增量(§6.8–6.10)新增来源</h3><ul><li>OpenWiki(LangChain):<span class="exturl" data-url="aHR0cHM6Ly93d3cubGFuZ2NoYWluLmNvbS9ibG9nL2ludHJvZHVjaW5nLW9wZW53aWtpLWFuLW9wZW4tc291cmNlLWFnZW50LWZvci1yZXBvLWRvY3VtZW50YXRpb24=">https://www.langchain.com/blog/introducing-openwiki-an-open-source-agent-for-repo-documentation<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2xhbmdjaGFpbi1haS9vcGVud2lraQ==">https://github.com/langchain-ai/openwiki<i class="fa fa-external-link-alt"></i></span></li><li>OpenKB(VectifyAI):<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1ZlY3RpZnlBSS9PcGVuS0I=">https://github.com/VectifyAI/OpenKB<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9wYWdlaW5kZXguYWkvYmxvZy9pbnRyb2R1Y2luZy1vcGVua2I=">https://pageindex.ai/blog/introducing-openkb<i class="fa fa-external-link-alt"></i></span></li><li>nashsu&#x2F;llm_wiki:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL25hc2hzdS9sbG1fd2lraQ==">https://github.com/nashsu/llm_wiki<i class="fa fa-external-link-alt"></i></span></li><li>AutoSci(PKU DAIR):<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3NreWxsd3QvQXV0b1NjaQ==">https://github.com/skyllwt/AutoSci<i class="fa fa-external-link-alt"></i></span>、arXiv 2505.31468:<span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvYWJzLzI1MDUuMzE0Njg=">https://arxiv.org/abs/2505.31468<i class="fa fa-external-link-alt"></i></span></li><li>Karpathy 衍生实现:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0FzdHJvLUhhbi9rYXJwYXRoeS1sbG0td2lraQ==">https://github.com/Astro-Han/karpathy-llm-wiki<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1NhbXVyQUlHUFQvbGxtLXdpa2ktYWdlbnQ=">https://github.com/SamurAIGPT/llm-wiki-agent<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL252ay9sbG0td2lraQ==">https://github.com/nvk/llm-wiki<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2x1Y2FzYXN0b3JpYW4vbGxtd2lraQ==">https://github.com/lucasastorian/llmwiki<i class="fa fa-external-link-alt"></i></span></li><li>qmd(Tobi Lütke):<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RvYmkvcW1k">https://github.com/tobi/qmd<i class="fa fa-external-link-alt"></i></span></li><li>AGENTS.md:<span class="exturl" data-url="aHR0cHM6Ly9hZ2VudHMubWQv">https://agents.md/<i class="fa fa-external-link-alt"></i></span></li><li>Google Open Knowledge Format:<span class="exturl" data-url="aHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL2Jsb2cvcHJvZHVjdHMvZGF0YS1hbmFseXRpY3MvaG93LXRoZS1vcGVuLWtub3dsZWRnZS1mb3JtYXQtY2FuLWltcHJvdmUtZGF0YS1zaGFyaW5n">https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing<i class="fa fa-external-link-alt"></i></span>、SPEC <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0dvb2dsZUNsb3VkUGxhdGZvcm0va25vd2xlZGdlLWNhdGFsb2cvYmxvYi9tYWluL29rZi9TUEVDLm1k">https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md<i class="fa fa-external-link-alt"></i></span></li><li>GitHub 话题:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RvcGljcy9rYXJwYXRoeS1sbG0td2lraQ==">https://github.com/topics/karpathy-llm-wiki<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RvcGljcy9sbG0td2lraQ==">https://github.com/topics/llm-wiki<i class="fa fa-external-link-alt"></i></span></li></ul>

用 Happy 在手机上控制 Claude Code:从安装到自建服务器

2026-05-14 00:00:00

<p>VibeCoding 大半年,最大的感受是:<strong>慢</strong>。一个需求跑大半天,高峰期 API 限速更是雪上加霜。你想走开干点别的,又怕 AI 卡在权限弹窗上等你审批——走也不是,守也不是。</p><p>实践久了之后会发现: VibeCoding 需要的不是持续盯盘,而是一种<strong>间歇性、片段化的持续注意力</strong>。<br>AI 自己跑着就行,你只在关键节点出现——审批权限、纠正方向、拍板决策。<strong>你不是监控器,你是把关人。</strong></p><p><span class="exturl" data-url="aHR0cHM6Ly9oYXBweS5lbmdpbmVlcmluZy8=">Happy Coder<i class="fa fa-external-link-alt"></i></span> 恰好解决了两个问题:</p><ul><li><strong>“守”</strong>——手机随时查看进度、审批、发指令,不用守在电脑前。</li><li><strong>“等”</strong>——通勤路上掏出手机接着推需求,碎片时间变生产力。</li></ul><p>这篇文章分享一下我从零开始用 Happy 的全过程,覆盖日常使用、后台常驻、开机自启、以及自建服务器。</p><span id="more"></span><h2 id="快速上手:五分钟连上手机"><a href="#快速上手:五分钟连上手机" class="headerlink" title="快速上手:五分钟连上手机"></a>快速上手:五分钟连上手机</h2><h3 id="安装-happy-cli"><a href="#安装-happy-cli" class="headerlink" title="安装 happy-cli"></a>安装 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3Nsb3B1cy9oYXBweQ==">happy-cli<i class="fa fa-external-link-alt"></i></span></h3><p>前提是你已经装好了 <span class="exturl" data-url="aHR0cHM6Ly9kb2NzLmFudGhyb3BpYy5jb20vZW4vZG9jcy9jbGF1ZGUtY29kZQ==">Claude Code<i class="fa fa-external-link-alt"></i></span>(<code>claude</code> 命令可用)。然后一行命令搞定:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g happy</span><br></pre></td></tr></table></figure><h3 id="下载手机端-APP"><a href="#下载手机端-APP" class="headerlink" title="下载手机端 APP"></a>下载手机端 APP</h3><p>iOS 去 App Store,Android 去 <span class="exturl" data-url="aHR0cHM6Ly9wbGF5Lmdvb2dsZS5jb20vc3RvcmUvYXBwcy9kZXRhaWxzP2lkPWNvbS5leDNuZHIuaGFwcHk=">Google Play<i class="fa fa-external-link-alt"></i></span>,搜 “Happy Coder” 就能找到。APP 免费,下载安装即可。</p><h3 id="扫码连接"><a href="#扫码连接" class="headerlink" title="扫码连接"></a>扫码连接</h3><p>在电脑端运行:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">happy auth login</span><br></pre></td></tr></table></figure><p>终端里会显示一个二维码。打开手机上的 Happy Coder APP,扫码完成配对。认证信息存储在本地 <code>~/.happy/</code> 目录下,私钥不会离开你的设备。</p><h3 id="启动第一个会话"><a href="#启动第一个会话" class="headerlink" title="启动第一个会话"></a>启动第一个会话</h3><p>直接运行:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">happy</span><br></pre></td></tr></table></figure><p>和直接运行 <code>claude</code> 的区别在于,<code>happy</code> 启动的会话可以被手机端实时看到和控制。你在电脑终端输入的内容会同步显示在手机上,反过来也一样。手机端接管会话后,想切回电脑操作,在终端按任意键就行,<strong>切换是无缝的,会话不会中断</strong>。</p><p>顺便提一句,Happy 不只支持 Claude,还支持 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL29wZW5haS9jb2RleA==">Codex<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS1nZW1pbmkvZ2VtaW5pLWNsaQ==">Gemini<i class="fa fa-external-link-alt"></i></span> 等:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">happy codex # 启动 Codex 会话</span><br><span class="line">happy gemini # 启动 Gemini CLI 会话</span><br></pre></td></tr></table></figure><h2 id="后台常驻:让手机随时发起会话"><a href="#后台常驻:让手机随时发起会话" class="headerlink" title="后台常驻:让手机随时发起会话"></a>后台常驻:让手机随时发起会话</h2><p>上面 <code>happy</code> 命令需要手动启动,关掉终端会话就断了。如果我想随时随地从手机发起会话,电脑上得有个常驻后台的服务。这就是 <strong>daemon(守护进程)</strong> 的作用。</p><p>daemon 在后台持续运行,手机 APP 可以随时通过它创建新的 Claude Code 会话。创建会话时 APP 会让你选择工作目录,Claude 就在那个目录下跑,读取该项目的 <code>CLAUDE.md</code> 和上下文。</p><h3 id="基本操作"><a href="#基本操作" class="headerlink" title="基本操作"></a>基本操作</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">happy daemon start # 启动守护进程</span><br><span class="line">happy daemon stop # 停止守护进程</span><br><span class="line">happy daemon status # 查看运行状态</span><br><span class="line">happy daemon list # 列出活跃会话</span><br><span class="line">happy daemon logs # 查看日志文件路径</span><br></pre></td></tr></table></figure><h2 id="开机自启:Linux-systemd-配置"><a href="#开机自启:Linux-systemd-配置" class="headerlink" title="开机自启:Linux systemd 配置"></a>开机自启:Linux systemd 配置</h2><p>可能会高频使用 happy, 暂时设置了开机自启。<br>因为我的主力机是 Linux 系统,开机自启使用 <span class="exturl" data-url="aHR0cHM6Ly93d3cuZnJlZWRlc2t0b3Aub3JnL3dpa2kvU29mdHdhcmUvc3lzdGVtZC8=">systemd<i class="fa fa-external-link-alt"></i></span> 用户服务来实现。</p><p>创建服务文件 <code>~/.config/systemd/user/happy-daemon.service</code>:</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Unit]</span></span><br><span class="line"><span class="attr">Description</span>=Happy Coder Daemon</span><br><span class="line"><span class="attr">After</span>=network-<span class="literal">on</span>line.target</span><br><span class="line"><span class="attr">Wants</span>=network-<span class="literal">on</span>line.target</span><br><span class="line"></span><br><span class="line"><span class="section">[Service]</span></span><br><span class="line"><span class="attr">Type</span>=simple</span><br><span class="line"><span class="attr">ExecStart</span>=/path/to/happy daemon start-sync</span><br><span class="line"><span class="attr">WorkingDirectory</span>=/your/workspace</span><br><span class="line"><span class="attr">Restart</span>=always</span><br><span class="line"><span class="attr">RestartSec</span>=<span class="number">10</span></span><br><span class="line"><span class="attr">Environment</span>=PATH=/home/xxx/.local/bin:/usr/local/bin:/usr/bin:/bin</span><br><span class="line"><span class="attr">Environment</span>=HOME=/home/xxx</span><br><span class="line"></span><br><span class="line"><span class="section">[Install]</span></span><br><span class="line"><span class="attr">WantedBy</span>=default.target</span><br></pre></td></tr></table></figure><p>这里面有几个<strong>关键细节</strong>,逐一说清楚。</p><h3 id="start-sync-而不是-start"><a href="#start-sync-而不是-start" class="headerlink" title="start-sync 而不是 start"></a><code>start-sync</code> 而不是 <code>start</code></h3><p><code>happy daemon start</code> 会 spawn 一个子进程然后父进程退出,systemd 检测到主进程退出就认为服务结束了。而 <code>start-sync</code> 是前台阻塞模式,systemd 可以正确跟踪进程状态。用错了的话,daemon 会不断被 systemd 重启又退出,陷入死循环。</p><h3 id="Restart-always"><a href="#Restart-always" class="headerlink" title="Restart=always"></a><code>Restart=always</code></h3><p>不要用 <code>Restart=on-failure</code>。daemon 收到正常关机信号时退出码是 0,<code>on-failure</code> 不会重启正常退出的进程。我们需要的是无论什么原因退出都自动重启。</p><h3 id="Environment-不要包含-CLAUDECODE-变量"><a href="#Environment-不要包含-CLAUDECODE-变量" class="headerlink" title="Environment 不要包含 CLAUDECODE 变量"></a>Environment 不要包含 <code>CLAUDECODE</code> 变量</h3><p>如果 daemon 的环境里有 <code>CLAUDECODE</code> 或 <code>CLAUDE_CODE_ENTRYPOINT</code> 这类变量,从手机发起的会话会<strong>直接失败</strong>。症状是:手机上能看到会话创建成功,但一发消息就挂。排查这类问题,这里是第一个要检查的。</p><h3 id="loginctl-enable-linger"><a href="#loginctl-enable-linger" class="headerlink" title="loginctl enable-linger"></a><code>loginctl enable-linger</code></h3><p>systemd 用户服务默认只在用户登录时运行。执行 <code>loginctl enable-linger</code> 后,即使没有登录,用户服务也能启动。</p><h3 id="启用服务"><a href="#启用服务" class="headerlink" title="启用服务"></a>启用服务</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">loginctl enable-linger $(whoami)</span><br><span class="line">systemctl --user daemon-reload</span><br><span class="line">systemctl --user enable --now happy-daemon.service</span><br></pre></td></tr></table></figure><p>验证:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl --user status happy-daemon.service</span><br></pre></td></tr></table></figure><p>看到 <code>active (running)</code> 就对了。可以故意杀掉进程测试自动恢复:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">kill $(pgrep -f &quot;happy daemon start-sync&quot;)</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">等约 10 秒</span></span><br><span class="line">systemctl --user status happy-daemon.service</span><br></pre></td></tr></table></figure><p>应该看到它又自动重启了。</p><h2 id="自建-Happy-Server"><a href="#自建-Happy-Server" class="headerlink" title="自建 Happy Server"></a>自建 Happy Server</h2><p>Happy 默认使用官方中继服务器。所有通信端到端加密,服务器只能看到加密后的数据块,无法读取代码内容。用官方服务器在安全性上没问题。<br>但如果有数据合规要求、想在内网部署、或者纯粹想自己掌控基础设施,自建也很简单。</p><p><em>主要是官网真的太太太太太太太太太太太太太太太太太太太太太太太太太太太太太太太太慢了……………….</em></p><h3 id="Docker-部署(推荐)"><a href="#Docker-部署(推荐)" class="headerlink" title="Docker 部署(推荐)"></a>Docker 部署(推荐)</h3><p>Happy Server 独立模式内置了 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2VsZWN0cmljLXNxbC9wZ2xpdGU=">PGlite<i class="fa fa-external-link-alt"></i></span>(嵌入式 <span class="exturl" data-url="aHR0cHM6Ly93d3cucG9zdGdyZXNxbC5vcmcv">PostgreSQL<i class="fa fa-external-link-alt"></i></span>),<strong>不需要额外安装 Postgres、Redis 或 S3</strong>,一个容器搞定:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">构建镜像(在仓库根目录执行)</span></span><br><span class="line">docker build -t happy-server -f Dockerfile .</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">运行</span></span><br><span class="line">docker run -d \</span><br><span class="line"> --name happy-server \</span><br><span class="line"> -p 3005:3005 \</span><br><span class="line"> -e HANDY_MASTER_SECRET=your-secret-here \</span><br><span class="line"> -e PUBLIC_URL=https://happy.example.com \</span><br><span class="line"> -v happy-data:/data \</span><br><span class="line"> --restart unless-stopped \</span><br><span class="line"> happy-server</span><br></pre></td></tr></table></figure><p>几个关键说明:</p><ul><li><strong><code>HANDY_MASTER_SECRET</code> 是必须设置的</strong>,用于认证和加密。务必生成一个足够长的随机字符串</li><li><code>PUBLIC_URL</code> 设为你的公网可访问的 HTTPS 地址,影响文件链接的生成</li><li>数据持久化在 Docker volume <code>happy-data</code> 中,容器重启不丢数据</li><li><strong>服务器本身不处理 TLS</strong>,需要配合反向代理</li></ul><p>健康检查:访问 <code>GET /health</code>,返回 <code>{&quot;status&quot;:&quot;ok&quot;}</code> 说明服务正常。</p><h3 id="环境变量一览"><a href="#环境变量一览" class="headerlink" title="环境变量一览"></a>环境变量一览</h3><p><strong>必须设置:</strong></p><table><thead><tr><th>变量</th><th>说明</th></tr></thead><tbody><tr><td><code>HANDY_MASTER_SECRET</code></td><td>认证和加密的主密钥,必须设置</td></tr></tbody></table><p><strong>可选(独立部署):</strong></p><table><thead><tr><th>变量</th><th>默认值</th><th>说明</th></tr></thead><tbody><tr><td><code>PORT</code></td><td><code>3005</code></td><td>服务监听端口</td></tr><tr><td><code>PUBLIC_URL</code></td><td><code>http://localhost:3005</code></td><td>公网访问 URL</td></tr><tr><td><code>DATA_DIR</code></td><td><code>/data</code></td><td>数据存储目录</td></tr><tr><td><code>PGLITE_DIR</code></td><td><code>/data/pglite</code></td><td>PGlite 数据库目录</td></tr><tr><td><code>METRICS_ENABLED</code></td><td><code>false</code></td><td>设为 <code>true</code> 开启 Prometheus 指标</td></tr><tr><td><code>METRICS_PORT</code></td><td><code>9090</code></td><td>指标服务端口</td></tr></tbody></table><p><strong>可选(扩展部署):</strong></p><table><thead><tr><th>变量</th><th>说明</th></tr></thead><tbody><tr><td><code>DATABASE_URL</code></td><td>外部 PostgreSQL 连接地址(替代 PGlite)</td></tr><tr><td><code>REDIS_URL</code></td><td>Redis 地址(多副本扩展时使用)</td></tr><tr><td><code>S3_HOST</code> 等</td><td>S3&#x2F;MinIO 对象存储(替代本地文件存储)</td></tr></tbody></table><p>个人使用的话,设一个 <code>HANDY_MASTER_SECRET</code> 就够了。</p><h3 id="TLS-配置"><a href="#TLS-配置" class="headerlink" title="TLS 配置"></a>TLS 配置</h3><p>生产环境用 HTTPS,最省事的方式是用 <span class="exturl" data-url="aHR0cHM6Ly9jYWRkeXNlcnZlci5jb20v">Caddy<i class="fa fa-external-link-alt"></i></span> 做反向代理,它会<strong>自动申请和续期 <span class="exturl" data-url="aHR0cHM6Ly9sZXRzZW5jcnlwdC5vcmcv">Let’s Encrypt<i class="fa fa-external-link-alt"></i></span> 证书</strong>:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">happy.example.com &#123;</span><br><span class="line"> reverse_proxy localhost:3005</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>两行配置,Caddy 帮你搞定证书。用 Nginx 的话需要自己配 certbot,稍微麻烦一点。</p><h2 id="CLI-指向自建服务器"><a href="#CLI-指向自建服务器" class="headerlink" title="CLI 指向自建服务器"></a>CLI 指向自建服务器</h2><p>自建服务器部署好之后,通过 <code>HAPPY_SERVER_URL</code> 环境变量让 happy-cli 连接你的服务器:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">export HAPPY_SERVER_URL=https://happy.example.com</span><br><span class="line">happy</span><br></pre></td></tr></table></figure><p>或者写到 shell 配置文件里一劳永逸。加到 <code>~/.zshrc</code> 或 <code>~/.bashrc</code>:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">export HAPPY_SERVER_URL=https://happy.example.com</span><br></pre></td></tr></table></figure><p>如果前面用 systemd 管理 daemon,别忘了在 service 文件的 <code>Environment</code> 里也加上:</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">Environment</span>=HAPPY_SERVER_URL=https://happy.example.com</span><br></pre></td></tr></table></figure><p>改完之后 <code>systemctl --user restart happy-daemon.service</code> 让配置生效。</p><h2 id="APP-指向自建服务器"><a href="#APP-指向自建服务器" class="headerlink" title="APP 指向自建服务器"></a>APP 指向自建服务器</h2><p>Happy APP 内置了服务器配置页面,切换很方便:</p><ol><li>打开 APP,进入<strong>设置</strong></li><li>找到 <strong>Server Configuration</strong>(服务器配置)</li><li>输入自建服务器地址,比如 <code>https://happy.example.com</code></li><li>APP 会自动验证:访问这个 URL,检查是否返回 “Welcome to Happy Server!”</li><li>验证通过后保存,之后所有连接走你的自建服务器</li><li>想切回官方服务器?同一个页面重置即可</li></ol><p>切换过程不需要重新登录。</p><hr><p>Happy Coder 解决的问题很小也很具体:让你不用坐在电脑前也能用 Claude Code。但就是这个便利,改变了我跟 Claude 协作的方式。通勤路上想到什么,掏出手机就能接着聊;周末出门在外,Claude 在家里的机器上跑着任务,手机上随时查看进度。</p><p>开源、免费、端到端加密,自托管完全可选。如果你也在用 Claude Code,不妨试试。</p><h2 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h2><ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3Nsb3B1cy9oYXBweQ==">slopus&#x2F;happy - GitHub<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9oYXBweS5lbmdpbmVlcmluZy9kb2NzL2ZhcS8=">Happy Engineering - Documentation<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbGlhbWRhcm1vZHkvNGFiYTA4M2MyNmNjYjFiM2IwZjEwNjhlYzE4NWVmNjY=">How to build a 24&#x2F;7 personal AI agent with Claude Code - Liam Darmody<i class="fa fa-external-link-alt"></i></span></li></ul>

人生周报 - 202602

2026-01-21 00:00:00

<h3 id="资源"><a href="#资源" class="headerlink" title="资源"></a>资源</h3><ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2FudGhyb3BpY3Mvc2tpbGxz">Anthropic 官方 Skills 示例<i class="fa fa-external-link-alt"></i></span> Skills 示例代码仓库, 可以学习创建自己的 Skills 武器库。</li></ul><h3 id="实践"><a href="#实践" class="headerlink" title="实践"></a>实践</h3><ul><li>逐渐深入使用 ClaudeCode,开始接触 Skills,Hooks,Permissions,好工具的设计真是巧妙,流程简约且高度可定制。</li><li>尝试用 ClaudeCode + Github SpecKit,想从零到一写一个翻译工具。效果层面目前还不好说,核心翻译能力还没写。时间层面,提效感觉不明显,specify,clarify,plan,task,analyze,implement 一套流程下来,一个小需求得花费大半天。</li><li>Anthropic 发布了 code-simplifier 工具,<strong>代码优化效果极好</strong>,可以在不改变业务逻辑的前提下优化代码,感觉可以集成到 CICD 帮忙做代码 review 了。</li><li>ClaudeCode 的潜力真是无穷无尽,写确定性的代码效果很好(写整个项目经验不足还不好评价)。帮我把日报汇总成年终总结,几乎一个字都不用改。后面准备尝试用 NotionMCP 帮我做开源服务指南自动化发布的最后一公里,感觉能行。</li><li>01&#x2F;16 卸载了抖音,头脑清净了许多。卸载抖音的当天上午,上班路上写完了两周的周报草稿。</li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cuYmlnbW9kZWwuY24vZ2xtLWNvZGluZz9pYz1ST0VFQUFXTFhP">GLM Coding Plan<i class="fa fa-external-link-alt"></i></span> 5h 实践窗口居然有 2亿 token, 根本用不完。用 nginx 反代给同事接入,反馈也不错。</li></ul><h3 id="妙想"><a href="#妙想" class="headerlink" title="妙想"></a>妙想</h3><ul><li>我之前的笔记 + 知识库是用 markdown 格式 + VSCode 编辑器 + Git 版本控制 + Github 同步来实现的,后面找机会让 ClaudeCode 把我历史知识库整理发部成公共知识库,好东西就是要分享出去。</li><li>计划了 100 年的周复盘一直没有启动,想试一下让 ClaudeCode 学习我历史博客的写作风格,然后帮我写周复盘。</li></ul>

人生周报 - 202601

2026-01-20 00:00:00

<ul><li>购买了 <span class="exturl" data-url="aHR0cHM6Ly93d3cuYmlnbW9kZWwuY24vZ2xtLWNvZGluZz9pYz1ST0VFQUFXTFhP">GLM Coding Plan<i class="fa fa-external-link-alt"></i></span>,可以随意玩 ClaudeCode 了。虽然模型智能不如国外,好在量大管饱,入门 ClaudeCode 是不错的。</li><li>新买的丐版 MacMini 内存和硬盘都不多,ClaudeCode 开发过程中会用到一些开发环境(Go 语言, Podman, PostGreSQL),不想浪费 MacMini 的空间。索性就把之前淘汰下来的 Manjaro Linux 24h 开机,当作服务器用。<strong>Tmux 会话保持 + ClaudeCode 终端沟通 + VSCode 远程开发</strong>,整个流程非常顺滑。</li><li>有一个叫 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3Nsb3B1cy9oYXBweQ==">happy<i class="fa fa-external-link-alt"></i></span> 的工具,可以让你远程控制 ClaudeCode 工作,感兴趣的话可以试一下。</li><li>测试了几个 AI 编程工具(GeminiCLI,GithubCopilot),最终还是觉得 ClaudeCode 更好用。其实真没必要折腾各种免费或者白嫖的工具,<strong>免费的往往也是最贵的,时间、精力、机会这些方面的成本不是金钱能够衡量的</strong>。</li><li>之前帮同事写过一个号码认证自动拨测脚本,这次又有需求,借助 AI 编程工具把脚本升级到了 GUI。纯 VibeCoding,调测时间远大于开发时间,且 AI 经常会在实现一个新需求的时候搞出来一个旧功能的 bug。后面可能会多尝试一下 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2NvZGVydmlzb3IvbGVhbi1zcGVj">LeanSpec<i class="fa fa-external-link-alt"></i></span> 或者 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2dpdGh1Yi9zcGVjLWtpdA==">SpecKit<i class="fa fa-external-link-alt"></i></span> 这样的 SDD 框架。</li></ul>

善用 MVP 思维,5 天时间零成本搭建小报童排行榜

2024-07-20 21:03:00

<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>你好,我是小柒。<br>Java 程序员,热衷自动化。</p><p>前段时间花了 5 天左右,借助 Notion + CloudFlare Workers + Github Actions 零成本搭建了一个支持一键分销的<span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS8=">小报童排行榜<i class="fa fa-external-link-alt"></i></span>: <span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS8=">https://xiaobot.osguider.com<i class="fa fa-external-link-alt"></i></span>。在这里复盘一下过程,希望能够对你有所启发。</p><p><strong>善用 MVP 思维,用最小的成本最快地实现最核心的功能,尽早触达用户,尽早获取反馈,不断迭代,不断升级。</strong></p><h3 id="什么是小报童排行榜?"><a href="#什么是小报童排行榜?" class="headerlink" title="什么是小报童排行榜?"></a>什么是小报童排行榜?</h3><!-- TODO --><p>小报童排行榜是一个罗列了(几乎)所有小报童专栏的导航网页。可以帮助你<strong>一键分销所有小报童专栏</strong>。</p><p><img data-src="https://picgo-daily.oss-cn-guangzhou.aliyuncs.com/picgo-daily/2024/983d596c02f675ddcd74cd7261d5f2ef.png" alt="小报童排行榜-最近更新专栏"></p><span id="more"></span><h3 id="为什么要做小报童排行榜?"><a href="#为什么要做小报童排行榜?" class="headerlink" title="为什么要做小报童排行榜?"></a>为什么要做小报童排行榜?</h3><ul><li>主要是因为小报童官方没有公开的专栏索引列表,但这个痛点确实是在的。既然有需求未被实现,机会不就来了?</li><li>实现足够简单,成本足够低,做这个游刃有余。</li><li>折腾副业,没自己的产品始终感觉没底气。所以,小报童排行榜可以是我的产品支撑,也可以是我向外链接的突破口。</li><li>能给我带来收益:哪怕是最基础的小报童分销,也能带来一些收益。且不说后面依据这个产品的放大升级。</li></ul><h3 id="小报童排行榜给我带来了什么?"><a href="#小报童排行榜给我带来了什么?" class="headerlink" title="小报童排行榜给我带来了什么?"></a>小报童排行榜给我带来了什么?</h3><ul><li>我能做成一件事的信心</li><li>和我一起做事的朋友</li><li>借助小报童排行榜,链接到了更多朋友</li><li>副业生态的起点</li><li>一点点小钱</li></ul><h3 id="一些有趣的统计数据"><a href="#一些有趣的统计数据" class="headerlink" title="一些有趣的统计数据"></a>一些有趣的统计数据</h3><ul><li>迄今为止我收录了 308 位作者的 403 个小报童专栏。其中:<ul><li>有 26 位作者的 38 个专栏订阅数量超过 3000,占比 9%。<strong>只要订阅数量超过 3000 就能跻身前 10%。</strong></li><li>有 50 位作者的 72 个专栏订阅数量在 1000 和 3000 之间,占比 18%。<strong>只要订阅数量超过 1000 就能跻身前 30%。</strong></li></ul><!-- - 有 249 位作者的 293 个专栏订阅数量低于 1000,占比 72%。**你是否,能扛得住“泯然众人矣”的结果呢?** --><ul><li>有 97 位作者的 105 个专栏超过 1 年没有更新,算是已完结的状态。<strong>有人入场,有人离场。机会、永远都在那里等你,剩下的、就是你能否主动抓住它了。</strong></li><li>15 亿国人,你的竞争对手只有 308 位。<strong>其实只要开始,就已经是成功了。</strong></li></ul></li><li>有很多数据不太好看的专栏(订阅数量为 0),其中绝大部分是订阅制而非买断式。因为小报童展示的订阅数&#x3D;当前仍在订阅状态的用户数,当用户订阅到期不再续订时,这个数量就会减少。所以<strong>单从数据好看的角度考虑,买断式的专栏会更好一点。</strong></li><li>上线至今,小报童排行榜分销佣金收入 371.61 元,给朋友们定制一键分销系统(扣除返现后)收入 210 元。对于在互联网上流浪多年的我和 Huazi,这个<strong>正反馈极佳</strong>。</li></ul><p><strong>我把手上已有的小报童专栏排名数据整理成了一个 Excel 表格,如果你想要自己做一些数据分析,可以通过 <code>osguider</code> 微信我领取。</strong></p><h3 id="整体实现思路"><a href="#整体实现思路" class="headerlink" title="整体实现思路"></a>整体实现思路</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">sequenceDiagram</span><br><span class="line"> actor 小报童专栏作者</span><br><span class="line"> participant 金数据表单</span><br><span class="line"> participant paperDB AS Notion专栏数据库</span><br><span class="line"></span><br><span class="line"> 小报童专栏作者-&gt;&gt;+金数据表单: 填写表单请求专栏收录</span><br><span class="line"></span><br><span class="line"> 金数据表单-&gt;&gt;paperDB: 推送专栏信息</span><br><span class="line"> CloudFlareWorkers定时任务-&gt;&gt;+paperDB: 定时扫描专栏信息</span><br><span class="line"> paperDB--&gt;&gt;-CloudFlareWorkers定时任务: 小报童专栏信息</span><br><span class="line"> CloudFlareWorkers定时任务-&gt;&gt;+小报童: 爬取小报童专栏详细信息</span><br><span class="line"> 小报童--&gt;&gt;-CloudFlareWorkers定时任务: 小报童专栏详细信息</span><br><span class="line"> CloudFlareWorkers定时任务-&gt;&gt;paperDB: 小报童专栏详细信息写入数据库</span><br><span class="line"></span><br><span class="line"> GithubActions-&gt;&gt;+paperDB: 定时获取专栏详细信息列表</span><br><span class="line"> paperDB--&gt;&gt;-GithubActions: 专栏详细信息列表</span><br><span class="line"> GithubActions-&gt;&gt;eleventy模板引擎: 生成专栏信息列表数据文件</span><br><span class="line"> eleventy模板引擎-&gt;&gt;小报童排行榜: 编译静态文件</span><br></pre></td></tr></table></figure><h2 id="搭建一个小报童排行榜,可以有多简单?"><a href="#搭建一个小报童排行榜,可以有多简单?" class="headerlink" title="搭建一个小报童排行榜,可以有多简单?"></a>搭建一个小报童排行榜,可以有多简单?</h2><p>按照我以往程序员的思维,如果想要做一个小报童排行榜,至少要经历以下步骤:</p><ul><li>需求分析</li><li>概要设计</li><li>数据库设计</li><li>爬虫&amp;业务代码编写</li><li>前端代码编写</li><li>部署上线</li></ul><p>带着完美主义的思维,最后可能是因为设计配色不满意、可能是因为前端代码没写好,也可能是爬虫做不出来……从而不了了之,前功尽弃。</p><p>这件事情,真的需要这么复杂吗?</p><h2 id="需求分析"><a href="#需求分析" class="headerlink" title="需求分析"></a>需求分析</h2><p>需求分析需要考虑两个层面:我想做什么?我能做什么?其中:</p><p>我想做的事情很简单:把所有小报童专栏汇聚到一个网页,供用户查阅和订阅。<br>我能做什么主要取决于我能从小报童官方拿到什么样的信息。经过简单的分析,我可以从小报童官方获取到以下信息:</p><ul><li>专栏名称</li><li>专栏作者</li><li>专栏介绍</li><li>专栏订阅数量</li><li>专栏内容数量</li><li>专栏价格</li><li>专栏分销比例</li><li>专栏分销链接</li><li>专栏创建时间</li><li>专栏更新时间</li></ul><p>小报童排行榜的核心功能是<strong>列举出所有的小报童专栏信息</strong>,Notion 数据库可以完美实现这个功能!说干就干!</p><h2 id="数据库搭建"><a href="#数据库搭建" class="headerlink" title="数据库搭建"></a>数据库搭建</h2><p>按照可以从小报童官方获取到的信息搭建 Notion 数据库,这个过程就像是给 Excel 添加多个列字段,非常简单。<br><em>这里不再赘述 Notion 的使用,如果你对 Notion 感兴趣,可以通过这几个链接学习。<span class="exturl" data-url="aHR0cHM6Ly9ub3Rpb25jaGluYS5jby8=">中文用户指南<i class="fa fa-external-link-alt"></i></span> | <span class="exturl" data-url="aHR0cHM6Ly93d3cubm90aW9uLnNvL2hlbHAvbm90aW9uLWFjYWRlbXkvY291cnNlLzEwMS1pbnRyb2R1Y3Rpb24=">Notion Academy<i class="fa fa-external-link-alt"></i></span> | <span class="exturl" data-url="aHR0cHM6Ly93d3cubm90aW9uLnNvL2hlbHA=">Notion Help Center<i class="fa fa-external-link-alt"></i></span></em></p><p>一条 Notion 数据库记录长这个样子:</p><p><img data-src="https://picgo-daily.oss-cn-guangzhou.aliyuncs.com/picgo-daily/2024/4841724753dee7cd8a82acb71eee58da.png" alt="notion数据库记录-生财有术"></p><p>汇总的列表长这个样子:</p><p><img data-src="https://picgo-daily.oss-cn-guangzhou.aliyuncs.com/picgo-daily/2024/cc68f75e8dc407de4f8ae4c88e325c3c.png" alt="notion database-table-小报童专栏"></p><hr><p>Notion 极其强大!支持任意的页面嵌套,支持把任意页面发布为公网可以访问的网页,甚至可以给同一个数据库定制不同的视图!<br>那么依据这个功能,我们实际上已经完成了最简单的 MVP:<strong>手动收集小报童专栏信息,并通过 Notion 展示。</strong></p><p>小报童排行榜的第一个 MVP 长这个样子:</p><p><img data-src="https://picgo-daily.oss-cn-guangzhou.aliyuncs.com/picgo-daily/2024/c2c0108d7600038a3505d227d6382db7.png" alt="小报童排行榜 Notion Site"></p><h2 id="数据爬取"><a href="#数据爬取" class="headerlink" title="数据爬取"></a>数据爬取</h2><p>作为一个程序员、作为一名 RPA 教练,手动录数据多少有点说不过去了吧?</p><p>我们来看几个小报童专栏分销链接:</p><ul><li>生财有术项目精选:<span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm5ldC9wL3NoZW5nY2FpeW91c2h1P3JlZmVyPTZmNGVjYzJiLTcwZTktNGY1OC04MmRlLTcxZTViMWYzNTdlZQ==">https://xiaobot.net/p/shengcaiyoushu?refer=6f4ecc2b-70e9-4f58-82de-71e5b1f357ee<i class="fa fa-external-link-alt"></i></span></li><li>IP合伙人·八年成事(百问百答):<span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm5ldC9wL0lQMTA/cmVmZXI9NmY0ZWNjMmItNzBlOS00ZjU4LTgyZGUtNzFlNWIxZjM1N2Vl">https://xiaobot.net/p/IP10?refer=6f4ecc2b-70e9-4f58-82de-71e5b1f357ee<i class="fa fa-external-link-alt"></i></span></li></ul><p>稍加比较就能发现,分销链接由以下几个部分组成:</p><ul><li>域名:<code>https://xiaobot.net/</code></li><li>小报童专栏 ID: <code>shengcaiyoushu</code> &#x2F; <code>IP10</code></li><li>分销标识:<code>refer=6f4ecc2b-70e9-4f58-82de-71e5b1f357ee</code></li></ul><p>其中:域名是不变的,分销标识只跟发起分销的用户有关系,所以在收集专栏信息的时候,我们只需要收集小报童专栏 ID 即可。这一个步骤,现在确实是手动收集和录入的。<br>但在这之后,我们可以通过拼接域名和小报童专栏 ID 得到指定小报童专栏的页面地址。访问专栏页面,可以获取到我们需要的几乎所有信息,通过 RPA&#x2F;写代码 手段轻松获取(这里我的方案是通过 CloudFlare Workers 调用小报童接口获取数据,再使用 Notion API 写入数据库)。<br><em>请适当控制 RPA 运行频率,保护服务器负载。</em></p><p><img data-src="https://picgo-daily.oss-cn-guangzhou.aliyuncs.com/picgo-daily/2024/d4ed64c257add9f132fdd3660b89494f.png" alt="小报童专栏主页-生财有术项目精选"></p><p>到这里,内容的自动爬取和更新也搞定了。</p><h2 id="页面编写-自动发布"><a href="#页面编写-自动发布" class="headerlink" title="页面编写 &amp; 自动发布"></a>页面编写 &amp; 自动发布</h2><p>Notion 也有缺点。毕竟是海外的产品,国内访问速度非常不稳定,根据我自己的测试,Notion Site 在极端情况下需要 10-20 秒才能加载出来,这个速度用户肯定是无法忍受的。在我的认知体系内,写一个静态页面是比较好的解决方案。</p><p>在看过我自己写的丑得不能再丑的 HTML Table 之后,我的设计师伙伴 @Huazi 终于还是忍不住亲自上场了。他负责页面样式,我负责内容填充,完美配合。</p><p>技术选型大概是这样的:</p><ul><li>页面样式:HTML + CSS + JavaScript + Tailwind CSS</li><li>内容渲染:通过 JavaScript 脚本调用 Notion API 获取数据,再使用 eleventy 把数据渲染到 HTML。</li><li>自动化:通过 Github Actions 每天定时执行内容渲染逻辑,然后自动发布网页到服务器。</li></ul><p>至此,第二版小报童排行榜问世:<span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS8=">小报童排行榜<i class="fa fa-external-link-alt"></i></span>。</p><p><img data-src="https://picgo-daily.oss-cn-guangzhou.aliyuncs.com/picgo-daily/2024/983d596c02f675ddcd74cd7261d5f2ef.png" alt="小报童排行榜-最近更新专栏"></p><h2 id="赋能"><a href="#赋能" class="headerlink" title="赋能"></a>赋能</h2><p>前面的小报童排行榜只能帮助我自己分销所有小报童专栏,分销佣金也只能我自己拿,怎么让别人愿意帮我推广小报童排行榜呢?最简单的方法当然是让利!<br>**通过给别人定制一键分销网页,页面里所有小报童专栏全部改成别人的分销链接。**这样别人也可以通过自己的一键分销网页分销小报童专栏获取收益,我收取一定的技术维护费用,各取所需,各享其利。</p><p>实现也很简单,增加一个 Notion 数据库记录分销商信息:</p><p><img data-src="https://picgo-daily.oss-cn-guangzhou.aliyuncs.com/picgo-daily/2024/07c5dcc18be8db9e951c425a720aba23.png" alt="Notion数据库-分销商"></p><p>通过 Cloudflare Workers 读取 Notion 分销商数据库信息,然后通过 eleventy 渲染子页面并发布即可。这里有几个一键分销页面,可供参考:</p><ul><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9vc2d1aWRlci8=">https://xiaobot.osguider.com/osguider/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9IZXlIdWF6aS8=">https://xiaobot.osguider.com/HeyHuazi/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS83NjcxODQwMC8=">https://xiaobot.osguider.com/76718400/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS93aHl2aW5jZW50Lw==">https://xiaobot.osguider.com/whyvincent/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9IZWxwMDAwMDAwLw==">https://xiaobot.osguider.com/Help000000/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9meG05OTk2MC8=">https://xiaobot.osguider.com/fxm99960/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9MU0wwMjExMDIv">https://xiaobot.osguider.com/LSL021102/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS95emhtMTExLw==">https://xiaobot.osguider.com/yzhm111/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9iYW9qaWVfeG1nLw==">https://xiaobot.osguider.com/baojie_xmg/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9saXVsaXV6YWlzaC8=">https://xiaobot.osguider.com/liuliuzaish/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS95aTI1MzkwLw==">https://xiaobot.osguider.com/yi25390/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS9IWDE3NDcwMjM5NzEv">https://xiaobot.osguider.com/HX1747023971/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS81OTU2ODMwNzkv">https://xiaobot.osguider.com/595683079/<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS8xNzM4NDA3NjEwLw==">https://xiaobot.osguider.com/1738407610/<i class="fa fa-external-link-alt"></i></span></li></ul><h2 id="未来的计划"><a href="#未来的计划" class="headerlink" title="未来的计划"></a>未来的计划</h2><ul><li>表单提交自动收录:小报童专栏作者填写金数据表单,cloudflare workers 自动爬取专栏信息并收录到 Notion 数据库。</li><li>表单提交自动生成一键分销链接:想要构建一键分销系统的朋友填写金数据表单,cloudflare workers 自动构建一键分销页面。</li><li>知识星球绑定销售:做一个知识星球强化个人 IP,小报童排行榜作为赠品而不是单独销售。这样可以把认可产品的朋友带入到我的 IP 圈,逐渐影响,让他们认可我这个人,进而创造更多合作的机会。</li></ul><h2 id="后话"><a href="#后话" class="headerlink" title="后话"></a>后话</h2><p>当然,现在的小报童排行榜并不完美。<br>比如现在还不支持分页,比如现在只能用 <code>Ctrl + F</code> 做检索,比如不支持用户自定义要分销的专栏列表。<br>如果你也觉得有些不爽的地方,欢迎找我聊聊,万分感激。</p><h2 id="致谢"><a href="#致谢" class="headerlink" title="致谢"></a>致谢</h2><p>感谢我的队友 <span class="exturl" data-url="aHR0cHM6Ly9odWF6aS5zcGFjZS8=">@Huazi<i class="fa fa-external-link-alt"></i></span>,没有他,小报童排行榜不会如此美观,不会如此受人欢迎。</p><h2 id="关于我"><a href="#关于我" class="headerlink" title="关于我"></a>关于我</h2><p>重新认识一下。<br>你好,我是小柒,微信 <code>osguider</code>。<br>Java 程序员,热衷自动化。生财有术 RPA 航海教练(23 年 12 月)。</p><hr><p><span class="exturl" data-url="aHR0cHM6Ly94aWFvYm90Lm9zZ3VpZGVyLmNvbS8=">小报童排行榜<i class="fa fa-external-link-alt"></i></span> 作者,支持一键分销所有小报童专栏,也可以给你<strong>定制专属分销链接</strong>,欢迎体验。</p><hr><p><span class="exturl" data-url="aHR0cHM6Ly9vc2d1aWRlci5jb20v">开源服务指南<i class="fa fa-external-link-alt"></i></span>主理人,依托 Notion 搭建了完整的自动化工作流和图文生成体系,这个后面也会写复盘。</p><p>目前实现了:</p><ul><li>每天自动从 Github 爬取开源项目信息</li><li>自动调用 ChatGPT 开源项目简介</li><li>手动审核 ChatGPT 生成的简介并标记审核状态</li><li>借助 Pipedream 和 Notion 把已审核的开源项目自动汇总成 Markdown 格式的文章</li><li>借助 mdnice 把 Markdown 文章自动转为微信公众号图文</li><li>手动分发(等后面抽出时间这里可以用 Automa 做自动分发)</li></ul><p>了解开源服务指南:</p><ul><li><span class="exturl" data-url="aHR0cHM6Ly9vc2d1aWRlci5jb20v">官网<i class="fa fa-external-link-alt"></i></span></li><li>微信公众号:开源服务指南</li></ul><hr><p>做过一个不起眼的导航网站:<span class="exturl" data-url="aHR0cHM6Ly9rYW5qaWFuLmRpcWlnYW4uY24v">看见导航<i class="fa fa-external-link-alt"></i></span> 收藏了很多我见过且觉得值得推荐的网页和工具,可能会对你有所帮助。</p><hr><p>写过一写 Java 开发工具的使用经验:<span class="exturl" data-url="aHR0cHM6Ly9pZGVhLmRpcWlnYW4uY24v">Intellij IDEA 最佳实践<i class="fa fa-external-link-alt"></i></span></p><hr><p>也欢迎访问我的个人博客:<a href="https://blog.diqigan.cn/">Seven’s blog</a></p><hr>

给 eleventy(11ty) 添加 sitemap.xml 和 robots.txt

2024-06-14 10:09:55

<h2 id="配置过程"><a href="#配置过程" class="headerlink" title="配置过程"></a>配置过程</h2><ol><li>添加数据文件 <code>_data/site.json</code>,写入以下内容,定义站点信息和 sitemap 中的一些默认值:</li></ol> <figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line"> <span class="attr">&quot;baseUrl&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://xiaobot.osguider.com&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;robots&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/robots.txt&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;sitemap&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line"> <span class="attr">&quot;path&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sitemap.xml&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;changefreq&quot;</span><span class="punctuation">:</span> <span class="string">&quot;daily&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;priority&quot;</span><span class="punctuation">:</span> <span class="number">0.5</span></span><br><span class="line"> <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><ol><li>添加 sitemap 模板文件,写入以下内容:</li></ol> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">permalink: &quot;&#123;&#123; site.sitemap.path &#125;&#125;&quot;</span><br><span class="line">eleventyExcludeFromCollections: true</span><br><span class="line">---</span><br><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="line"></span><br><span class="line">&lt;urlset xmlns=&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;&gt;</span><br><span class="line"> &#123;% for page in collections.all %&#125;</span><br><span class="line"> &#123;% unless page.data.sitemap.ignore %&#125;</span><br><span class="line"> &lt;url&gt;</span><br><span class="line"> &lt;loc&gt;&#123;&#123; site.baseUrl &#125;&#125;&#123;&#123; page.url | url &#125;&#125;&lt;/loc&gt;</span><br><span class="line"> &lt;lastmod&gt;&#123;&#123; page.date | date: &#x27;%Y-%m-%dT%H:%M:%S.%LZ&#x27; &#125;&#125;&lt;/lastmod&gt;</span><br><span class="line"> &lt;changefreq&gt;&#123;&#123; site.sitemap.changefreq &#125;&#125;&lt;/changefreq&gt;</span><br><span class="line"> &lt;priority&gt;&#123;&#123; page.data.sitemap.priority | default: site.sitemap.priority | default: 0.5 &#125;&#125;&lt;/priority&gt;</span><br><span class="line"> &lt;/url&gt;</span><br><span class="line"> &#123;% endunless %&#125;</span><br><span class="line"> &#123;% endfor %&#125;</span><br><span class="line">&lt;/urlset&gt;</span><br></pre></td></tr></table></figure><ol><li><p>【可选】配置不同页面的 sitemap 表现:</p><ul><li>如果不希望某些页面在被包含在 sitemap 文件中,在页面元数据中添加 <code>sitemap.ignore: true</code> 即可;</li><li>可以对不同的页面设置不同的 sitemap 优先级,在页面元数据中添加 <code>sitemap.priority: 0.5</code>,取值范围 0-1;</li><li>对于分页数据,要设置 <code>pagination.addAllPagesToCollections: true</code> 才会在 <code>sitemap.xml</code> 文件中包含每一个分页页面。</li></ul></li><li><p>添加模板文件 <code>src/robots.txt</code>,写入以下内容:</p></li></ol> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">eleventyComputed:</span><br><span class="line"> permalink: &quot;&#123;&#123; site.robots &#125;&#125;&quot;</span><br><span class="line">eleventyExcludeFromCollections: true</span><br><span class="line">---</span><br><span class="line">Sitemap: &#123;&#123; site.baseUrl &#125;&#125; &#123;&#123; site.sitemap.path &#125;&#125;</span><br><span class="line"></span><br><span class="line">User-agent: *</span><br><span class="line">Disallow:</span><br></pre></td></tr></table></figure><p>重新编译,over!</p><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tLzExdHkvZWxldmVudHkvaXNzdWVzLzI0OA==">How to create sitemap.xml<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2NlcGgvY2VwaC5pby9pc3N1ZXMvMTM2">Sitemap xml<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9zaG9waWZ5LmdpdGh1Yi5pby9saXF1aWQv">liquid<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cuc2l0ZW1hcHMub3JnL3Byb3RvY29sLmh0bWw=">sitemap format<i class="fa fa-external-link-alt"></i></span></li></ul>