← 全部项目

18mu-blog

一个以 Markdown 为唯一内容源的个人知识站:Astro 静态构建,一个 Cloudflare Worker 同时承载页面与语义地图快照。

文章目录[4]

项目是什么

18mu-blog 是这个站点本身的代码库:一个以 Markdown 为唯一人工内容源的个人知识站。

它要解决的问题只有一个——让「写一篇东西」成为唯一需要人来做的事。内容写成 Markdown,页面、索引、标签、RSS、站点地图和部署全部由构建流程产出,没有一份需要手工维护的列表。

站点同时承载四条内容线:完成写作的中文博客、公开的中英双语项目说明、脱敏可复用的 For Agent 记录,以及一份由结构化事实驱动的简历。

具体结构

18mu-blog Architecture A architecture diagram generated by Archify. Content sources Cloudflare Workers Semantic features Markdown Content · blog · projects · agent · Content sources Markdown Content blog · projects · agent Resume Facts · fact-base/ · Content sources Resume Facts fact-base/ Astro Build · schema + checks · Architecture component Astro Build schema + checks GitHub Actions · build · deploy · sync · Architecture component GitHub Actions build · deploy · sync Static Assets · .deploy/ · Cloudflare Workers Static Assets .deploy/ Cloudflare Worker · worker.ts · Cloudflare Workers Cloudflare Worker worker.ts Embedding Provider · 1024-dim vectors · Semantic features Embedding Provider 1024-dim vectors Readers · browser · Architecture component Readers browser Knowledge Snapshot · KV: current · Semantic features Knowledge Snapshot KV: current Map & Walk · React + D3 islands · Semantic features Map & Walk React + D3 islands Markdown facts CI pages ASSETS serves embeds vectors snapshot

站点分三层,每一层只依赖它下面那一层。

内容层。 Markdown 是唯一由人维护的公开来源。博客、项目和 For Agent 记录是三个内容集合,字段契约写在 content.config.ts 里,构建前由校验脚本检查。简历经历走另一条路:事实存放在 fact-base/,只在构建时被读取,不作为内容集合发布。

交付层。 Astro 把内容集合构建成静态站点,输出到 .deploy/;一个 Cloudflare Worker 同时承担两件事——把静态资源递给读者,以及对外提供公开 API。静态资源通过 ASSETS binding 挂在这个 Worker 上,所以整站只有一个部署单元。

语义层。 只有已发布的博客文章会进入语义处理。Worker 调用外部 embedding 服务拿到向量,算出两两余弦相似度,按阈值聚类,再把每篇文章至多六个最近邻居写进 Cloudflare KV。认知地图和随机漫步这两个 React 岛屿从公开快照接口读取结果。

优秀设计

内容契约先于内容。 每个集合的字段由 schema 定义,构建前先跑关系校验:关联字段必须指向存在且已发布的记录。写错一个 slug 会让构建失败,而不是在页面上留下一个死链。

派生数据可以随时重建。 语义快照完全由已发布的博客 Markdown 推导,不存任何手工维护的关系。清掉 KV 里的数据,跑一次同步就能复原。

密钥不进内容。 embedding 的模型端点和密钥只存在于 Worker 配置与 Cloudflare Secret 中;浏览器只读取不含密钥的公开快照,同步令牌只在 GitHub Actions 里使用。

发布路径是 Git。 生产环境只接受已经提交并验证过的 main,工作区里的未提交改动不会被发布。

解决了什么问题

  • 写内容不需要维护索引、标签页或站点地图——这些都由构建产出。
  • 项目、经历和 For Agent 记录之间用 slug 建立关系,写错会在构建阶段被拦下。
  • 文章之间不靠手工打标签建立关联,而由语义相似度自动形成主题聚类。
  • 站点没有登录、评论、支付或浏览器端凭据,一次内容更新只改动 Markdown。