本站(SL Blog)在 2026-08-25 完成了一次大重构:从单纯的文章博客升级为「个人工程知识平台」。这篇文章完整复盘重构成因、原型图与设计文档的做法,以及用 DSH(DeepSeek Harness)讨论并落地重构的过程——对我是一次新的工作方式实验,希望对你也有启发。
为什么要重构
旧站的问题:双代码源已在分叉
重构前,站点直接跑在服务器 /opt/astropaper 上,没有 GitHub 同步:所有改动都在服务器上原地迭代,GitHub 上只有一个模板的 Initial commit。
这带来一个很实际的风险——两个代码源已经在分叉:
- 服务器
/opt/astropaper上有 5 个真实 commit(暗色主题、RAG 问答等自定义) - GitHub 上只有 AstroPaper 模板的初始提交
继续各自演进,必然丢数据、无法回滚、没有 CI。这是第一个必须解决的结构性问题(ADR-0001:给仓库一个唯一真源)。
内容模型:只有 tags,没有结构化
旧站文章全部平铺在 /posts/<slug> 下,靠自由 tags 分类:
- 没有必填的一级分类,首页无法做分类卡
- 没有**系列(series)**概念,教程类文章只能靠 tag 凑松散分组
- 项目、时间线完全没有载体
内容一多,” 信息架构 ” 就崩了——这不是排版问题,是数据模型问题(ADR-0002 / ADR-0003)。
视觉:与心理预期差距过大
- 默认暗色主题,而设计目标一直是亮色清爽
- 全站只有一种等宽字体,中文没有字体栈,靠浏览器回退
- 文章正文列约 592px,还有二次截断,观感局促
这些问题叠在一起,让我意识到:缺的不是 ” 再改改样式 “,而是一套从数据模型到视觉的完整设计(ADR-0004)。
用 GPT 生成原型图
重构之前,我先用 GPT 一次性生成了 4 张关键页面的原型图,作为讨论与验收的视觉基准:




为什么先出原型图而不是直接写代码?
- 视觉基准先行:4 张图定下 ” 亮色、无衬线、三栏文章页 ” 的整体基调,后续所有页面改动以图为准,不再凭感觉。
- 验收有锚点:重构完逐页对照原型图走查,偏差一目了然。
- 降低沟通成本:口头描述 “Hero、技术分类、最新文章、项目作品、RAG 入口 ” 远不如一张图直观。
后续我还用 AI 生成了 Hero 主视觉插画 + 5 张分类封面图(Java 生态 / AI 工程 / 工程实践 / 工具折腾 / 思考随笔),接入封面管线后,每类文章自动回退到分类默认封面,全站封面视觉统一。
设计文档:从方案到 ADR
原型图是 ” 长什么样 “,设计文档负责回答 ” 为什么这么做 “。这次重构沉淀了两层文档:
一层:二开设计方案
在动手前先写了一份 设计方案(仓库设计阶段产出),明确:
- 定位:技术探索 · 工程实践 · AI 时代思考
- 保留 AstroPaper 能力:Markdown / SEO / RSS / Sitemap / Pagefind 搜索 / 暗色模式
- 新增页面:首页(Hero + 分类 + 最新 + 项目 + RAG 入口)、文章页(系列导航 + 目录 + 相关 + 关联项目 + RAG)、项目页、时间线页、RAG 问答页
- 内容结构:新增 projects / series / timeline,文章字段补 category / series / relatedProjects
- 实施阶段:UI 视觉重构 → 内容模型扩展 → 项目展示系统 → RAG 接入
二层:ADR 决策记录
实施过程中把每次 ” 有取舍的关键决策 ” 落成 ADR(Architecture Decision Record),共 5 条:
| ADR | 决策 |
|---|---|
| ADR-0001 | 以 /home/myblog/astro-paper-blog(GitHub: github-oysl/astro-paper-blog)为唯一开发真源,替代服务器直接部署 |
| ADR-0002 | 文章必填 category,全站固定 5 个分类;series 独立内容集合 |
| ADR-0003 | 文章 URL 从 /posts/<slug> 迁移为 /<分类slug>/<slug>,旧地址全部 301 |
| ADR-0004 | 默认亮色主题 + Inter/中文系统字体栈 + 三栏文章页版心;AI 素材与封面管线落地 |
| ADR-0005 | 单语言现状下不做 i18n 抽象层 |
为什么要写 ADR?因为重构中很容易出现 ” 当时为什么这么选 ” 的遗忘。有了 ADR,后续任何改动都能先查决策上下文,避免推翻或重复争论。
用 DSH 讨论与重新设计
这次重构最特别的一点:设计讨论和大部分实现,是跟 DSH(DeepSeek Harness)一起完成的。
DSH 是什么
DSH 是一个围绕 AI agent 的协作开发环境:可以在里面读代码、看架构、提出候选方案、批量实施修改,并且把讨论产物落成文档。它带来的直接改变是:” 讨论 - 设计 - 落地 ” 的反馈循环从以天为单位,压缩到以分钟为单位。
讨论式设计:先圈候选,再收敛
重构不是一上来就改代码。第一阶段是架构巡检:根据 git 热点(封面管线 / RAG 问答 / 三栏文章页 / 内容模型)圈定范围,产出一份巡检报告,列出 7 个深化候选,并标注强度(Strong / Weak):
- 加深文章定位 module:
getPostUrl(post)一次改签名,14 处调用点同步受益 - 收口「可见文章」查询:一个
getVisiblePosts()统一过滤 + 排序,修复定时文章在生产环境泄漏的潜在 bug - RAG 问答 seam 显式化:postMap 改为 prop 内嵌 JSON,移除 window 全局
- OG 图渲染收口为
renderOgCardmodule:字体/框架/编码单点所有 - 封面渲染收敛到
PostCover.astro渲染点 - 文章页客户端行为拆分为
src/scripts/modules(进度条 / 标题锚点 / 代码复制 / lightbox) - 面包屑走
getRelativeLocaleUrl+ 单语言不抽象(ADR-0005)
每一条都先讨论 ” 为什么要改、备选方案是什么、影响面多大 “,再实施。这种先讨论后动手的节奏,让重构不是大规模推倒重来,而是有明确收益的逐步收敛。
分阶段落地:Phase 0 → 3
讨论收敛后,实现按阶段推进(git 历史可见):
| 阶段 | 内容 |
|---|---|
| Phase 0 | 全量移植线上站点现状到基准仓库(唯一真源成立) |
| Phase 1 | 内容模型扩展:45 篇文章逐篇补 category;URL 分类化 /posts/ → /<分类>/<slug> |
| Phase 2 | UI 重构:首页 / 文章页三栏 / 项目页 / 系列页 / 时间线 / 导航 |
| Phase 3 | 站内 RAG 问答页 + 文章页内嵌问答 |
配套工程一起落地:
- Nginx 301 映射:45×2 条旧地址全部重定向到新分类地址(ADR-0003 的强制配套)
- Obsidian 发布流水线改指向新仓库(38 篇文章由流水线托管)
- RAG 服务:FastAPI + pgvector,站内问答页通过 HTTP API 集成,访客配额制
构建验收
每次阶段完成都执行 pnpm build(astro check + build + Pagefind 索引),并对照原型图逐页走查。最终亮色模式全页面截图走查通过,旧 URL 301 验证通过。
结果与复盘
重构后的样子
- 45+ 篇文章全部迁移到 5 大分类,4 个系列(Kafka / Flink / n8n / RAG)有结构化导航
- 首页:Hero + 技术分类卡 + 最新文章 + 项目作品 + RAG 入口
- 文章页:三栏布局(系列导航 / 正文 / TOC · 相关 · RAG)
- 项目页、时间线页、站内 RAG 问答页全部上线
- 全站默认亮色,暗色保留切换;AI 生成的 Hero 与分类封面统一视觉
我的几点复盘
- 原型图先行是这次最划算的投资:4 张图把 ” 目标 ” 钉死,后面所有验收都省了口舌。
- 决策要留痕:5 条 ADR 让 ” 为什么 ” 可追溯,也防止未来推翻。
- 把 ” 讨论 ” 单独拎出来:DSH 模式下,巡检 → 候选 → 讨论 → 实施的顺序,让重构从 ” 赌一把 ” 变成 ” 有账可算 ”。
- 分阶段比一步到位稳:Phase 0-3 每步可构建、可验收、可回滚。
这次重构最大的收获不是代码,而是一套可复用的工作方式:GPT 出原型定方向 → 设计文档沉淀决策 → DSH 讨论并拆阶段落地。下一次再做类似的事,我会直接复用这套流程。