优昙钵从 0 到 1,再到 10
2025 年 10 月 2 日,优昙钵 v1.0.0 在 Netlify 上线。它最初只是首页、短文、日志和留言板;后来,这套简单的个人主页逐渐长成能生产、保护、验证、恢复、交接并继续生长的知识系统。
我想先说明,这篇文章不是一份持续更新的版本日志。它是一次停在 2026 年 10 月 24 日的建设复盘。那天往后的变化,不会再逐条补回这里;它要回答的不是“网站后来还加了什么”,而是另一个更稳定、也更值得保留的问题:
一个人的文章、技术积累、照片、日志和尚未成形的念头,能不能被组织成一个持续生长、可以检索、可以阅读,也经得起验证的个人知识系统?
优昙钵最初只是围绕生活记录开始,后来才一点点逼近这个问题。
“从 0 到 1,再到 10”并不是十个版本号的排列。0 是从没有网站到 v1.0.0 真正上线;1 是后来的当前架构形成一个可以长期维护的内容闭环;再往后,才是它逐渐获得知识结构、安全边界、发布纪律和恢复能力的过程。
网站可以打开,只是开始。一个系统能够长期存在,才是更难的部分。
0:先让个人主页真实存在
2025 年 10 月 2 日,优昙钵 v1.0.0 发布在 Netlify。它不是今天这套复杂系统,只是一个很朴素的中文个人主页:首页、短文、日志、留言板,加上一块旅行照片。首页副标题写的是“记录生活 · 珍藏回忆 · 分享点滴”。
这就是最初的“0 到 1”:不是先想到一个庞大的知识工程,而是先让文档里的生活真正拥有一个公开地址。旧版仍保留在 Netlify:https://youtanbohua.netlify.app/。它保留了这个项目最初的样子,也保留了我当时更直接、更简单的表达。
它当然不完整。那时没有技能树、全文搜索、服务端权限、AI 助手、内容导入流水线,也没有私密数据边界。但 v1.0.0 已经证明了一件后来所有工作都依赖的事:这些零散的记录可以被放到同一个地方,可以被别人打开,也可以在不同设备上继续被看见。
| 时间 | 优昙钵发生的变化 |
|---|---|
| 2025-10-02 | v1.0.0 在 Netlify 上线,形成第一版公开个人主页 |
| 2026-07-26 | 当前架构开始集中开发,从页面集合转向内容系统 |
| 2026-10-22 | 当前架构通过 Cloudflare Pages 部署,接入正式域名与服务端能力 |
| 2026-10-24 | 本篇文章采用的建设复盘截止日 |
后来的网站开始同时容纳三个方向:
- 工程,是面向问题的积累;
- 人文,是面向表达的积累;
- 生活,是面向时间的积累。
这不是 v1.0.0 第一天就完成的版图,而是内容逐渐增多后自然提出的要求。技术贴不该是孤立的知识点,文章也不该只是搜索结果的摘要,照片更不该只是相册里的装饰。它们应该能被彼此照亮。
v1.0.0 的视觉命题是安静、干净、容易读懂。后来这套界面被完整重做,才逐渐加上可探索的技能树、云词和阅读路径。形式换过很多轮,真正的底线却没有变:不能拿装饰冒充信息,也不能让没有真实内容支撑的节点假装自己已经长出证据。
1:从“能发布”走向“能长期维护”
v1.0.0 证明网站可以上线。到了 2026 年 7 月 26 日,当前这套架构开始集中开发,问题也从“怎样把页面发出去”变成了“怎样让它在内容越来越多以后依然可维护”。
最初几天的开发看起来非常具体:把敏感配置从前端移到后端,清理重复样式,拆分脚本,增加数据校验,修复页面跳转,让文章、技术贴、照片和日志各自落在正确的位置。这些事情并不“宏大”,但它们共同完成了当前架构的第一次质变:
本地内容
→ 数据文件
→ 页面渲染
→ 导航与搜索
→ 内容详情
→ 主题、私密入口和返回路径
新版第一次不再只是一组静态页面,而是一条能走完、也能继续往里添加内容的路径。
也正是在这里,我遇到了后来反复出现的一类问题:真正危险的不是“某个功能没做”,而是生成过程悄悄把已有结构写坏。
一个引号、一个换行、一次错误的数组插入,都可能让整站白屏;重复执行导入,会凭空多出一篇文章;照片标题与文件名模糊相近时,图片可能被配到另一段记忆里。表面上,脚本已经“成功运行”;实际上,它只是把一个不易察觉的错误写得很有秩序。
从那以后,每次更新都不再以“脚本没有报错”为完成标准。我开始依次追问:
- 写入的数据是否仍然是合法结构?
- 重复执行是否会产生第二份相同内容?
- 自动匹配错了,系统会不会告诉我?
- 即使这次写坏,是否可以回到上一个完整状态?
这些问题后来变成数据校验、状态回滚和全量备份。它们不是附在网站外面的“维护工作”,而是网站本身的一部分。
2—3:从页面工程变成内容系统
第二阶段最重要的变化,是网站不再靠手工编辑一个越来越大的数据文件来维持。
当内容只有几篇时,直接改数据没有问题;当内容、图片、分类和时间逐渐增多,手工修改就会变成一种风险。真正需要被设计的,不是“怎么再加一个页面”,而是“内容如何稳定地进入系统”。
于是有了越来越严格的导入流程:源文件必须使用明确前缀,文章和技术贴要识别日期,照片必须能确认对应资源,日志按年份归档,重复运行不能重复追加。任何无法识别的文件都会停在入口,而不是被猜着塞进某个栏目。
这背后是一个不太显眼、却非常关键的判断:
自动化不是替人做决定,而是把决定放在可检查的位置上。
同一时期,公开内容与私密内容也被分开了。文章、技术贴和照片属于公开层;日志全文、私密想法和更私人化的记录只从服务端读取。前端是否显示“已解锁”,不能成为权限判断的依据。权限必须在服务端成立,模型也不能被当成守门人。
这个边界让网站多了一层复杂度,却换来了更可靠的前提:有些内容可以被自己长期保存,不必因为放在同一个网站里就自动公开。
AI 助手也是在这个阶段从“聊天框”变成了站内检索器。
它最初只是一个能对话的窗口,后来开始知道站内有哪些文章和技术贴,能够沿着内容给出定位,在解锁状态下按日期检索日志,并把回答建立在站内资料上。它不再被期待“什么都懂”,而是被限定为站内知识的导航与解释层。
我更愿意把 AI 放在这个位置:它可以帮我找到、连接和表达,但不能替我制造事实,更不能替我判断权限。
4—5:知识需要有路径,也需要门禁
技能树经过多轮重做。最早是规则整齐的分支,后来变成有机生长的树,又试过更简约的线条和更复杂的证据叶。每一次重做都在回答同一个问题:知识结构究竟应该如何被看见?
最后的答案不是“做成一张好看的图”,而是让它具有清楚的层级:
根
→ 领域
→ 分支
→ 技能
→ 文章、技术贴、照片等真实证据
技能树不是目录的另一种画法。一个节点之所以存在,是因为它下面有可追溯的内容;一条路径之所以成立,是因为它能把原本分散的经验串成可以继续走的方向。
同样是在上线之前,阅读体验开始被认真对待。首页不再只是内容入口,文章有了分类、主题和目录;正文可以调整字号与行距;照片按年份组织;搜索结果能回到具体位置;RSS、站点地图、静态页面和结构化信息开始同步生成。
这些工作看起来分散,实际上指向同一个目标:内容要被找到,也要被舒服地读完。
而在发布之前,还必须有门禁。
我把上线前检查归纳成五道门:
| 门禁 | 要回答的问题 |
|---|---|
| 数据 | 内容、技能树和知识卡是否仍然完整、合法? |
| 安全 | 私密内容是否会进入公开目录?未授权接口是否会拒绝访问? |
| 部署 | 实际上传的文件是否经过白名单筛选? |
| 体验 | 页面在真实浏览器、真实手机上是否仍然可用? |
| 恢复 | 如果发布失败,能否退回到一个确定可用的状态? |
“本地能跑”与“可以上线”之间的差距,正是在这里被补齐的。
6:从 Netlify 到 Cloudflare
严格说,优昙钵早在 2025 年 10 月 2 日就通过 Netlify 走进了公网。2026 年 10 月 22 日发生的是另一件事:当前架构第一次通过 Cloudflare Pages 部署,随后接入主域名、备用域名、HTTPS、安全响应头和邮件通知链路。
从 Netlify 的静态页面切换到 Cloudflare Pages Functions,问题的性质也变了。
旧版主要只需要考虑页面有没有渲染;当前架构上线以后,还要考虑 DNS 传播、边缘缓存、旧部署继续响应、静态资源没有及时更新、服务端接口、邮件服务限制,以及本地测试与生产环境之间的细微差别。
有一段经历让我印象很深:代码已经修改,本地也完全正常,生产页面却仍旧加载旧版本。后来才确认,部署成功并不自动等于访客加载了最新资源。缓存版本不能凭经验手写,而应由内容本身生成,并在部署后重新核对。
订阅通知也一样。最初的通知判断过于粗略,一次样式更新或重复部署都可能打扰读者。后来它被收紧为只对实质内容变化作出反应:新增文章、技术贴,或标题、日期、正文、媒体真的变了,才发送;分类、标签和纯代码更新不打扰订阅者。
通知不是“能发出去”就算完成。它还必须理解什么事情值得被通知。
7:可信不是一句说明,而是一组边界
网站越开放,边界就越需要明确。
密钥只能存在服务端环境中;密码、Cookie、模型接口和通知令牌不能进入公开源码;私密文件必须从 Git 和公开部署目录中同时排除;未授权的私密接口默认拒绝;聊天请求需要限制角色、长度和上下文规模;管理能力与普通访问要使用不同的凭据。
这些规则听起来像一张安全清单,但它们真正解决的是“谁有资格知道什么”。
我还在生产环境里得到一个很实际的教训:写在配置文件里的能力,不代表当前平台真的提供它。某些在别的运行环境中成立的配置,到了 Pages 上并不生效。代码、文档和平台限制必须始终对齐。
从那时起,我判断一个安全措施是否有效,不再看“代码里有没有写”,而看“生产请求能不能证明它在工作”。
8:内容、分类和技能树开始一起生长
网站真正变成系统,是在一键更新成形之后。
更新的起点不再是打开数据文件,而是把一个命名清楚的源文件放进素材目录。后续流程依次完成:
源文件
→ 类型和日期识别
→ 正文结构化
→ 分类与标签
→ 知识卡
→ 技能树挂载
→ 公开检索数据
→ 静态页面与站点索引
→ 数据校验
这里有一个重要变化:文章不再只是“被发布”,它还会在知识层留下位置。
一篇关于 CAN 通信的技术贴,会沿“软件与自动化 → 总线与通信”进入技能树;一次台架验收记录,会落到台架架构与验收;一封旅行记录,会进入游记文章和对应年份的照片路径。技术内容不必与生活内容争夺同一套叙事,它们只需要各自找到合理的位置。
自动生成提高了效率,但没有取消人工判断。分类可能偏,证据强弱需要复核,技能名称也不能只因为出现频率高就成立。自动化负责让工作变得可重复,人负责决定这些工作是否真的有意义。
技术贴的生产方式也在这时候发生了变化。它们不再是从概念出发写成的泛化文章,而是从工作笔记、设备说明、调试过程和故障复盘里提炼出来。发布日期尽量对应真实事件,而不是统一写成制作网站的某一天。
这让内容有了重量:它不是为了填满栏目而写,而是某件确实发生过的事情留下来的证据。
9:真实使用会暴露源码看不见的问题
后期的很多修复,只有在真实设备上才会出现。
导航在某个宽度下看起来完整,实际整行却无法点击;复制按钮在桌面正常,手机上却没有响应;标签筛选结束后,返回路径把读者带到了错误位置;照片刚开始无法直接用键盘选择;文章从列表进入详情,再返回时,页面会先跳到顶部,然后才滚回原处。
最后一个问题尤其典型。第一次修复保存了滚动位置,看起来已经正确;真实体验里仍能看到一瞬的回跳。继续追查才发现,是全局平滑滚动覆盖了恢复动作。解决办法不是再加一个延时,而是在同一个渲染时序里临时关闭平滑、写入目标位置、再恢复设置。
这类问题让我不再相信“读代码觉得应该没问题”。移动端的触摸、缓存、字体回退、合成点击和滚动时序,都有自己的脾气。最终的验收现场只能是真实浏览器和真实手机。
运维也一样。留言、订阅、部署失败和严重异常需要提醒站主;通知服务可能被限流,邮件额度也有限,所以高优先级消息要有备用路径,低优先级消息则应该允许安静地失败。一个功能有降级路线,比它在理想状态下表现良好更重要。
10:生产系统不是“已经上线”
到今天,我更愿意用六条标准判断网站是否到了“10”:
- **内容可以持续生产**:不需要手工拼接数据文件。
- **公开与私密有清楚边界**:私密全文不会因为一次部署失误进入浏览器。
- **结果可以被验证**:数据、接口、页面和移动交互都有实际检查。
- **故障可以恢复**:有历史版本、完整备份和可返回的节点。
- **发布可以重复**:同样的输入能得到同样的结果,重复执行不制造重复内容。
- **系统可以交接**:后来者能从文档理解它为什么这样工作,以及出错时先看哪里。
这六条里,没有一条是“再加一个漂亮功能”。
它们描述的是一个更朴素的状态:网站已经不只依赖某一次临时操作才能存在。内容有入口,结构有校验,权限有位置,发布有门禁,通知有边界,故障有退路,历史有记录。
这就是这里的“10”。它不是终点,也不是成熟到无可挑剔。它只是意味着这套东西终于具备了继续生长的地基。
几次失败,比顺利时更有用
回头看,最值得保留的并不是那些一次就做对的功能,而是几次真正的失误。
| 表面现象 | 真正的根因 | 后来留下的规则 |
|---|---|---|
| 全站白屏 | 生成内容中的特殊字符破坏了数据结构 | 写入前必须在隔离副本里完成语法和结构校验 |
| 内容进了错误栏目 | 查找标记时越过了当前区域 | 脚本必须按结构边界定位,不能只凭“找得到文字” |
| 重复导入同一篇 | 去重范围只覆盖了部分区域 | 幂等必须是导入流程的底线 |
| 线上仍是旧页面 | 缓存版本没有跟着内容变化 | 部署后要核对实际资源和内容 |
| 订阅者收到无意义通知 | 只判断“部署变了”,没判断“内容实质变了” | 通知要理解变化,而不是理解事件数量 |
| 返回列表先跳再滚 | 全局平滑滚动覆盖了位置恢复 | 首帧体验也是正确性的一部分 |
这些错误共同说明了一件事:一个系统是否可靠,不在于它从未出错,而在于错误是否会被发现、是否能被定位、是否能被撤回,以及下次是否多了一道真实的防线。
仍然没有完成的部分
我也不想把“10”写成一种完成一切的姿态。
网站仍然有很长的路。自动化浏览器验收还没有形成完整体系;内容搜索与外部搜索引擎的提交还不够主动;订阅人数扩大后,通知仍需要更可靠的节流与队列;线上产生的部分数据还需要更规律的导出;有些自动分类和证据强弱仍然需要人工复核。
还有一些设想,比现在的基础设施走得更远。我希望未来的 AI 可以更理解站内上下文,也希望通知不只是一条系统消息,而能更自然地表达一个事件发生的现场。但这些想法需要更好的记忆、身份、权限与触发机制,不能只是为了“像人”而先把它做得像人。
知道哪里还没有完成,和知道哪里已经完成同样重要。
十条建设原则
如果只能把这段建设过程压缩成十句话,我会留下这些:
- **内容先于装饰**:技能树、动画和视觉必须服务真实内容。
- **权限在服务端**:前端状态只能改善体验,不能作为安全依据。
- **导入必须幂等**:重复执行不能制造重复内容。
- **通知必须理解语义**:只有实质变化才值得打扰读者。
- **失败必须有降级**:邮件、通知、AI 和动态存储都不能假设永远可用。
- **部署必须可回滚**:发布前有备份,发布后有验证。
- **敏感信息默认不公开**:不能把“应该没人访问”当成保护。
- **自动生成必须可审计**:分类、标签和知识卡都需要人工抽查。
- **真实浏览器才是验收现场**:移动触摸、滚动、字体和缓存必须实际检查。
- **文档与代码同等重要**:没有交接和恢复路径的系统,不能算真正完成。
这十条不是从书上抄下来的规范。它们几乎都对应着某一次具体的错误、犹豫和修正。
结语:数字不是高度,是获得的能力
从 0 到 1,2025 年 10 月 2 日的优昙钵完成的是一个能够被打开、被阅读、被分享的个人主页。
从 1 到 10,后来这套重构后的系统逐渐能够生产内容、保护私密、组织知识、通知读者、接受审查、从失败中恢复,并把经验交给下一步。
我仍然会对它不满意。技能树可以更准确,阅读可以更安静,自动化可以更可靠,AI 也可以更理解这里。但如果只看功能,就容易错过真正发生的变化:我不再需要考虑“这次能不能把网站改坏”,而可以把注意力放回内容本身。
一棵树不是因为枝干多才成立。它先要有根,然后每一根枝条都要能承受真实长出来的叶子。
优昙钵的“10”不是高度,而是它终于拥有了继续生长的能力。
在站点中打开 →