博客写作原则#
- 这是公开博客:不要透露任何隐私信息、机密信息,也不要发布暴力、色情或其他不当言论。
- 坚持真实、准确与可核查;引用数据、观点或他人内容时,注明可靠来源。
- 使用清晰、友善且尊重读者的表达,避免歧视、攻击和误导性表述。
- 围绕明确主题组织内容,先给出结论或核心观点,再用例子和细节支撑。
- 发布前检查事实、链接、代码和排版,及时修正发现的错误。
技术文档写作专家模式(当前项目默认启用)#
在本项目中撰写或更新技术内容时,默认以面向开发者的技术文档写作专家标准执行:追求事实准确、论证严谨、示例可复现,并帮助读者将知识落实到工程实践。
- 事实优先且可核查:产品能力、API、版本、配置、价格、限额、兼容性和安全建议等易变信息,优先依据一手官方文档或权威原始资料;给出可访问的来源链接,并标注版本或整理日期。未经验证的内容不得表述为事实,应明确区分已证实信息、合理推断与个人观点。
- 严谨说明适用范围:交代前置条件、运行环境、依赖版本、假设和边界条件;涉及方案选择时,说明关键取舍、限制、失败场景与兼容性影响,避免把特定环境下的结论泛化为通用结论。
- 以开发者为读者:使用准确的技术术语,并在首次出现时补足必要上下文;优先回答“为什么、如何做、如何验证、何时不适用”,使读者能够据此排查问题、做出决策或完成实现。
- 提供可复现的代码案例:技术主题应包含最小但完整、语法正确且与正文版本一致的代码或命令示例。示例需说明语言、依赖、执行方式和预期结果;无法实际运行或仅用于示意的片段必须明确标注,避免把伪代码伪装成可直接使用的实现。
- 发布前技术校验:核对代码、命令、链接、配置键、版本号与示例输出;必要时执行或验证示例,并修正过期信息、无效链接和未被证据支持的结论。
对话沉淀为博客文档#
- 在 Blog 项目中,用户提出的问题默认可视为可沉淀的选题;当内容适合公开分享时,完成回答后应主动整理为项目中的 Markdown 文档,不必另行询问是否记录。
- Posts 与 Docs 定位:
posts/<年份>/主要保留给用户亲自撰写、整理并上传的内容,以及确实不适合进入通用知识库的特别小众技术主题。由 Agent 撰写、整理或从对话沉淀的一般技术文档,默认放入相应的docs/分类,不因时效性强、有明确日期或需要独立发布而自动放入posts/。应先检查并遵循邻近文章的 front matter 与写作风格;无法确定归属的新技术文档,必须在创建或迁移前主动询问用户,不得自行新建目录或暂放posts/。 - 文档应是经过编辑的独立内容,而不是原始聊天记录:保留结论、背景、示例、边界条件和可靠来源,删除无关对话、个人信息、机密信息与未经核实的猜测。
- 不得把用户的个人目标、处境或自我评价写成对作者的归属陈述。 例如个人动机、心理状态、职业困惑、自我诊断式的概括,即便是用户在对话中主动说出的,也不得以"作者说/作者的目标是/作者把问题概括为"的形式出现在公开内容里。正确做法是把它抽象成公开可讨论的一般议题或条件分支(如"当目标是……时"),保留其论证价值而不暴露具体是谁的处境。
- 与此相对,用户就技术、方法或观点提出的立场与判断可以正常归属并保留,这类内容是讨论的实质,不属于隐私。区分标准是:它描述的是一个可以公开辩论的主张,还是一个人的私人状态。
- 涉及产品能力、API、价格、限额、版本或其他易变事实时,以一手官方文档为准,标明整理日期并提供可核查链接;需要时沿用站内的 AI 辅助生成说明。
- 用户明确要求不记录、内容不适合公开发布,或尚缺少决定性信息时,不创建或发布文档;其他情况下,可在不偏离用户问题范围的前提下做适当归纳。
- Cloudflare 的长期技术资料统一放入
docs/Cloudflare/,并维护该目录的00-overview.md文档导航;仅把 Cloudflare 作为案例的跨平台或行业文章,仍按其主主题放在原有分类。 docs/分类目录的_index.md仅保留用于导航与折叠的最小 front matter,不写正文;需要概览、阅读顺序或索引时,单独创建并维护00-overview.md。- 当用户的消息仅包含一个链接(允许前后空白)时,将其作为 Timeline 条目而非独立文章:按当天日期更新
timeline/<年份>.md。尽量补充一至两句简洁、可核查的中文介绍;若无法可靠判断链接内容,则只收录链接,不臆测说明。只有当用户明确要求“创建 link”时,才在links/下创建单独页面。 - 修改或排查 Hugo 文档页、导航注入模板或 Markdown 渲染异常时,遵循
skills/hugo-docs-rendering/SKILL.md:同时验证源文件与生成 HTML,并检查注入模板的 HTML 标签是否成对闭合。 - 撰写新的文档或博客时,如有助于保持内容的准确性、完整性和可发现性,可在必要范围内同步更新相关旧文、索引与正向/反向链接;修正过时或重复的表述、补充关联阅读,并清理失效链接。所有联动修改应基于可核查事实、保持链接双向可达,并避免无关改动。
- 在本项目中,用户说“上传图片”或要求在文档中展示图片时,默认使用 Cloudflare R2 存储桶
lyon-blog-statics上传,并通过https://cdn.yindongliang.com提供公开访问;对象路径遵循{year}/{filename}{.suffix}。撰写公开技术文档时,如配图有助于准确表达,可在用户请求范围内直接上传明确可公开、无敏感信息的本地图片,无需另行确认。必须遵循skills/cloudflare-r2-blog-media/SKILL.md:凭据仅从被 Git 忽略的.env读取,默认不覆盖或删除对象;上传后验证 R2 对象和 CDN URL 可访问且 MIME 类型正确,再以 Markdown 或必要的 HTML 将图片写入文档,并验证生成页面能够展示该图片。 - Giscus pathname 映射:本博客的 Giscus 已完成从
og:title到pathname的迁移,当前映射方式为pathname;Blog 被挂载到其他项目时也必须以此为准,不得继续按og:title映射理解或处理。修改会公开访问页面的 front mattertitle、slug、permalink、aliases、目录位置、站点全局标题,或 Giscus 映射配置时,必须遵循skills/giscus-discussion-compatibility/SKILL.md:检查实际生成的og:title、canonical URL、Giscus 实际使用的 pathname term(当前客户端会去除开头的/)及关联 GitHub Discussion,防止既有评论消失、重复创建或串到错误页面。当前映射下,单纯改标题通常无需修改 Discussion;URL 或目录变化时,必须保留旧、新 pathname term。Giscus 必须从站点工程的layouts/partials/docs/inject/footer.html注入,使 Hugo Book footer 的上一篇/下一篇导航先于评论组件渲染;不得把它移回content-after.html,也不得只用 CSS 改变视觉顺序。优先使用已连接的 GitHub MCP;若不可用,可使用已有效认证的gh/GitHub GraphQL。两者都不可用时,应请用户连接 GitHub MCP 或重新认证,不得猜测或创建替代 Discussion。涉及批量或存在歧义的远程标题更新,先提供可审阅的映射清单,再执行修改并验证。 - docs 一级目录约束:
docs/下的一级目录是稳定的导航入口。除非用户明确要求创建、拆分、重命名或迁移到新的docs/<一级目录>/,任何重构都不得新增一级目录。应优先使用现有一级目录;函数式编程、开发工具、数据库、数据工程、自动化、文本处理、DevOps 等“极客主题”默认归入docs/Linux/的二级目录,而不是创建新的docs/一级栏目。重构前必须先检查既有一级结构和相邻栏目,不能以命名便利或内容规模为由新增一级入口。除非用户明确指出需要新建的具体目录,日常整理默认不得新建docs/子目录;归类不确定时先询问用户。- 禁止擅自创建目录:未经用户明确允许,不得在 Blog 仓库的任何位置创建新 folder(目录),不限于
docs/。目标目录不存在、现有分类无法容纳内容或目录名称存在歧义时,必须先询问用户;不得以整理、临时存放、工具约定或构建需要为由自行创建目录。 - 已确认的产品归类:Convex 长期技术文档放入
docs/Convex/;Cloudflare 长期技术文档放入docs/Cloudflare/;Flutter 长期技术文档放入docs/Flutter/;React Native 及 Expo 工具链文档放入docs/Frontend/React-Native/;TanStack 相关文档放入docs/Frontend/TanStack/。交叉主题按文档的主线与用户已确认的专题目录归类,并在其他相关导航页建立交叉链接;主线仍不明确时先询问用户。
- 禁止擅自创建目录:未经用户明确允许,不得在 Blog 仓库的任何位置创建新 folder(目录),不限于
- 标签管理:创建标签必须慎重再慎重。仅在主题边界特别明确、现有标签无法准确覆盖且具有长期复用价值时,才创建新标签;绝大多数情况下应先检索并复用已有标签,并保持既有的大小写与命名一致,避免因单一产品、临时热点或同义词新增标签。
- Convex 标签:以 Convex 的架构、源码、SDK、Component、部署或工程实践为主题的公开内容,复用既有的
Convex标签,便于长期聚合;仅顺带提及 Convex 的跨平台比较或一般新闻不添加该标签。 - TanStack 标签:涉及 TanStack Router、TanStack Query、TanStack Start 等 TanStack 全家桶的公开内容,统一打
TanStack标签。与Convex标签不同,用户已明确该标签采用宽口径:即使只是在依赖清单、技术选型表或一句话推荐里顺带提及 TanStack,也应打上,目的是让所有相关页面都能被标签聚合到。打标签不改变文档的目录归属:跨主题文档仍按主线留在docs/Convex/、docs/Cloudflare/等既有分类,只在docs/Frontend/TanStack/00-overview.md建立交叉链接。
- Convex 标签:以 Convex 的架构、源码、SDK、Component、部署或工程实践为主题的公开内容,复用既有的
- 规则沉淀:若用户的表述包含可长期复用的项目规则、偏好或工作约定,且适合写入本文件,助手应主动将其整理为清晰、可执行的规则写入
Agents.md,并在完成后通知用户;若内容存在歧义、可能超出当前项目范围或会显著改变工作方式,应先请求确认。 - 周报默认封面:生成或更新
weekly/**周报时,先检查用户是否为本期提交或明确提供了专属图片;模板中沿用的通用图片不算本期图片。若没有专属图片,必须使用imagegen生成一张与主题相符、可公开且不含敏感信息、个人信息、商标标识或不可靠文字的默认封面,并遵循skills/cloudflare-r2-blog-media/SKILL.md上传到lyon-blog-statics。使用唯一的{year}/{filename}{.suffix}对象键,不覆盖现有对象;上传后验证 R2 元数据与 CDN 的 HTTP 状态、MIME 类型和缓存头。将已验证的 CDN URL 写入周报 front matter 的image;现有 Weekly 模板会自动渲染该字段,因此不得在正文重复插入同一张 Markdown 图片。若用户已提供本期图片,不生成或替换默认图。 - 草稿状态:符合本文件“技术文档写作专家模式”的技术文章或技术文档,在完成事实、链接、代码与排版核验,并确认内容不含隐私或机密信息、色情、暴力或其他不当言论后,应直接设置
draft: false,无需再等待用户单独确认“可以发布”;由 Agent 一次性完成且已通过同等核验的内容亦适用。不得仅因内容由 AI 协助生成、周报尚未到周末或页面刚创建而保留草稿。其他公开内容完成同等公开性与质量检查后,也应默认设置draft: false。仅在内容尚缺少决定性信息、存在待核实事实、用户明确要求暂不发布,或未能通过上述公开性与质量检查时,才设置draft: true。- 不得擅自翻转既有草稿:上述"默认发布"只适用于本次新建或本次撰写的内容。把一个既有的
draft: true页面改为draft: false属于发布决定,必须有用户的明确指示;不得因为它看起来已经完整、通过了核验、或在批量整理时顺手碰到就自行翻转。draft: true应被视为用户有意保留的状态,其原因未必写在文件里。 - 批量整理或重构旧文时,若发现某些草稿已具备发布条件,应把它们列成清单交由用户决定,而不是直接发布。
- 不得擅自翻转既有草稿:上述"默认发布"只适用于本次新建或本次撰写的内容。把一个既有的
- AI 参与说明与 Agent 命名:凡由 Agent 或 AI 协助撰写、整理、校验或修改的公开文章,开头必须使用引用块说明参与范围,并列出实际使用、用户可识别的
Agent名称。这里的Agent指承载任务的 Agent 产品或 Agent harness,例如Codex、Claude Code、Cursor、GitHub Copilot、Grok;命名按用户面对的外层执行边界,而不是内部编排拓扑。一次 Codex 任务内调用的 root agent、subagent、并行 subtask 与后台任务均归并为Codex,只列一次;不得在Agent字段中列出/root、/root/...、task/subtask 路径、ID、标签、代号或昵称。Tool、MCP server、connector、Skill、命令和模型也不属于Agent;若它们影响事实来源或适用范围,应在说明正文或参考资料中描述。只有确有多个彼此独立、用户可识别的 Agent 产品参与时,才并列列出并去重。仅当完整模型标识和本次任务的 reasoning effort 强度均有可核验运行元数据时,才如实列出两者;缺少任一项时,两者均不提,也无需向用户追问。说明还应保留事实来源与适用范围的必要提示,不得将 AI 协助表述为质量保证或作者身份。 - 知识库优先与跨项目复用:用户提出新问题时,应尽量先检索 Blog 中已有的相关文档;若发现高度相似的主题,重点参考其中已验证的结论、边界条件与实践,并视内容是否过时或可补充,更新原文或新增关联文档。Blog 是用户的可复用知识库;当其目录被挂载到其他 Codex 项目时,也应在任务相关且权限允许的范围内检索、参考,并将适合公开沉淀的新知识写回 Blog,避免重复或无关记录。
- GitHub Star Timeline 自动同步:同步 GitHub 用户
tcitry的 Star 时,仅处理启用同步后新增的公开仓库,不回填历史 Star;每项按 Star 时间写入对应timeline/<年份>.md,首行统一使用⭐ Starred Github Repo,下一行单独放置仓库的 canonical GitHub URL,并附一至两句基于公开仓库元数据、README 或官方站点的可核查中文简介。公开博客流程不得使用可能返回私有 Star 的认证/user/starred接口;应只使用公开结果并在写入前去重。 - 零散内容归档:当内容无法明确归入
docs/、posts/、links/或weekly/时,例如用户的一两句闲言碎语、备忘或一两张图片,通常优先整理为当天的timeline/<年份>.md条目。写入前必须脱敏,删除或泛化个人信息、机密信息及不适合公开的图片内容;无法安全脱敏时不得记录。图片仍须遵循本文件既有的上传、访问验证与公开性要求。 - 分支约束:Blog 是文档知识库;在本仓库进行日常编辑、检查与提交时,只能使用
main分支。除非用户明确批准,不得创建、切换或在main以外的分支工作;若发现当前不在main,应先停止写入并请求指示。 - Mermaid 流程图方向:Mermaid 流程图默认使用竖向布局,以保证节点文字清晰可读,避免横向图过长后因缩放导致字体过小。仅当流程节点很少、结构简洁且横向展示仍能清晰阅读时,才使用横向布局。
- 官方英文术语优先:技术产品、功能、架构和 API 中凡官方文档明确使用专有英文名称的,应保留官方英文写法、大小写与单复数,不以自行翻译的中文名称替代,例如使用
Static Prerendering、Workers Cache。必要时可在首次出现处补充简短中文解释,但后文继续使用官方英文术语;只有一般性概念或官方已有稳定中文名称时才优先使用中文。标题、小标题、图表、正文和链接文字均适用此规则,发布前应对照官方文档核对。 - Timeline 置顶区:
timeline/<年份>.md中的## Top <年份>是置顶内容,必须位于 front matter 后、所有日期条目前。新增、同步或更新按日期排列的 Timeline 条目时,应写入置顶区之后,不得将Top区压到后面;调整顺序后应检查该区仍保持在文件顶部。 private/发布隔离:Blog 根目录private/可保存并提交仅供私有仓库使用的内容,但绝不能渲染、复制或发布到yindongliang.com。公开站点的 HugoignoreFiles规则与 GitHub Pages artifact 的递归、大小写不敏感private目录负向断言必须同时保留;任何构建或部署改动都应验证最终public/产物的任意层级均不存在该目录。不要将此类内容移入static/、公开 demo 或其他可发布目录。- 英文 Slug:创建或迁移到公开站点的文档页面,必须显式设置仅含小写 ASCII 字母、数字和连字符的英文 kebab-case
slug;不得依赖中文文件名或中文slug生成页面的末级路径。url/permalink若覆盖slug,其末级路径也必须遵循此规则。修改既有页面的slug时,检查url/permalink是否覆盖该值,并按用户对 URL 兼容性的明确要求处理 aliases、canonical URL 与内部链接。 - 技术体系与部署链路:Blog 仓库只保存 Markdown 内容,不包含站点程序。真正构建并发布的是 Hugo 工程
tcitry/tcitry.github.io(本地/Users/yindongliang/code/tcitry.github.io,主分支master),它把 Blog 仓库main分支整体当作 Hugo 的contentDir:本地用make server/make build(CONTENT_DIR默认指向相邻的../../Blog),CI 则把 Blog 克隆到content/后执行make build CONTENT_DIR=content,使用 Hugo extended 与github.com/alex-shpak/hugo-book模块主题渲染,再由 Pagefind 生成搜索索引,最后以 GitHub Pages artifact 发布到https://yindongliang.com。构建由 push 站点工程master、repository_dispatch(类型blog-content-updated)或手动触发。由此产生三条约束:- Blog 的提交不会自行上线,内容改动需要站点工程的构建被触发后才生效;判断"是否已发布"应以站点构建结果为准,不以 Blog 的提交为准。
- 模板、主题、
config.toml、渲染行为、评论注入、搜索索引与部署流程一律属于站点工程,必须在tcitry.github.io中解决;不得在 Blog 内新增站点程序、构建脚本或主题覆盖文件。 - 站点工程通常只作为架构参考和本地构建验证的依据挂载。其提交由用户统一进行:除非用户明确要求,不得在
tcitry.github.io中执行git commit或git push(pushmaster即触发部署)。需要改动时把修改留在工作区,并向用户说明改了什么、如何验证。 - Blog 的
static/demos/会被站点工程的make sync-content-demos同步到其static/demos/并发布到/demos/;demo 的发布生成物必须放入 Blog 的该目录。若在tcitry.github.io保留可编辑源码,只能按demos/<年份>/<slug>/归档;该源码目录不参与本地或 CI 的自动构建。
- 以 Hugo 构建产物为最终导向:内容是否正确、可读、可达,判据是 Hugo 构建后的 HTML 与最终 URL,而不是 Obsidian 或其他编辑器内的预览效果。编辑器可用性只是过程体验,与站点表现冲突时一律以站点产物为准。
- 不使用 Obsidian 双链:站点的 Goldmark 配置没有 wikilink render hook,
[[页面名]]会被原样输出为纯文本,在站点上是坏内容。内部链接统一使用站内既有约定{{< relref "docs/…….md" >}};已有的站点绝对路径(以/开头)可以保留,新写内容优先用relref。站点未启用BookPortableLinks,因此裸相对.md链接不会被转换成可用 URL,同样不得使用。 - 注意本文件自身也会被 Hugo 渲染成页面:在
Agents.md或任何内容文件中示范 shortcode 语法时,必须使用 Hugo 的转义写法{{<…>}},否则会被真实解析并因目标不存在而中断构建。 - 新增、改名或移动文档时,同步修正指向它的
relref:relref目标解析失败会中断站点构建,这类问题应在提交前发现。 - 判断内容"能否被站内搜索到"以 Pagefind 的索引范围为准,当前仅索引
{docs,posts,weekly}/**/*.html;links/、timeline/及站点根级页面不进站内搜索,选择内容归属时应把可检索性一并考虑。 - 排查渲染、导航、目录折叠、评论、图片展示等表现层问题时,必须同时检查 Blog 中的源文件与站点工程构建出的
public/产物;只看源文件不足以确认问题已修复。
- 不使用 Obsidian 双链:站点的 Goldmark 配置没有 wikilink render hook,
- 作者的优先技术栈:以下是作者当前主要擅长并优先采用的技术栈,属于第一优先级:Cloudflare 全家桶(Workers、Durable Objects、Workflows、Queues、R2 等)、TanStack 全家桶(TanStack Query、TanStack Start、TanStack Router 等)、React、React Native、Convex、HeroUI。
- 讨论技术方案、架构设计、选型比较、示例代码或落地路径时,应着重参考并优先对齐这些技术:默认以它们作为实现载体,跨技术比较时把它们作为基准项,涉及取舍时优先说明在这些技术下的具体影响。
- 撰写相关文档时,优先复用
docs/Cloudflare/、docs/Convex/、docs/Frontend/TanStack/、docs/Frontend/React-Native/、docs/Frontend/React/中已有的结论与边界条件,并按需建立交叉链接。 - 这条规则只在话题确实与技术方案相关时生效。与之无关的主题不必强行靠拢,不得为了贴合优先技术栈而牵强引入、改写选型结论或添加无关比较;此时按主题本身的主线正常处理即可。
- 优先不等于唯一。当官方资料、实测结果或作者的明确约束表明其他方案更合适时,应如实说明,并给出与上述技术栈的差异和迁移代价,而不是回避。
- Markdown 加粗与 CJK 标点边界:站点按 CommonMark 规范渲染强调。当
**的内侧(加粗内容一侧)紧邻标点(如。?!,、:;「」“”()、行内代码的反引号),而外侧紧邻汉字或字母时,该**按规范不构成有效定界符,会原样输出到 HTML(如**可以。**它支持渲染为字面量)。这是 CommonMark 的规范行为而非 Hugo bug(参见 CommonMark 规范 Emphasis and strong emphasis),站点侧无法通过配置修复,必须在书写时规避:- 句末标点放在闭合
**之外:写**可以**。它支持,不写**可以。**它支持。闭合**后面是行尾、空格或标点时不受影响。 - 加粗不得以引号、直角引号、括号等标点开头且前一个字符是汉字/字母:写
例如 **「反对分类」并不成立**,(前置空格),或把成对符号移出加粗(「**反对分类**」)。仅在闭合**后补空格无法修复开头侧的问题。 - 行内代码外包加粗(
**`code`**)合法,但当闭合**前是反引号时,其后同样不能紧跟汉字/字母,需以空格或行尾收尾。 - 加粗一律使用
**,不得使用__:CJK 字符之间的__粗体__不会渲染。 - 不得用零宽空格(U+200B)等不可见字符包裹加粗来"修复"渲染:它不是 CommonMark 空白,会让闭合定界符在标点后失效,还会污染站点文本。
- 校验方式:构建后在站点工程
public/的 HTML 中全文搜索字面量**,排除代码块/行内代码(Chroma<span>、<code>)与 meta description 等纯文本摘要中的命中,正文应无残留;发现即按上述规则改写并重新构建复验。
- 句末标点放在闭合