写作与更新流程
所有书籍页面统一放在 docs/books/:英文放在 en/,完整的简体中文版本放在 zh/,使用相同的相对路径。例如,docs/books/en/chapters/01-terminal-chat.md 对应 docs/books/zh/chapters/01-terminal-chat.md。不要直接在 docs/ 下新增书籍页面。
网站默认语言仍为英文。VitePress 以 docs/books 为内容源目录,将 en/ 重写到站点根路径,中文网址则保留 zh/。因此本地入口仍是 /mino/ 和 /mino/zh/。网站配置保留在 docs/.vitepress/,Mermaid 图表源码保留在 Markdown 页面内。
专门负责写作的 subagent
项目在 .codex/agents/book_writer.toml 中定义了名为 book_writer 的 Codex 专用 agent。支持此功能的 Codex 客户端会在受信任项目中发现这份独立定义,无需再在 .codex/config.toml 中显式注册。它沿用主任务的模型和权限。在 Codex 中打开并信任这个项目;已有任务若尚未发现该定义,开启一个新任务即可重新加载。
Claude Code 使用 .claude/agents/book-writer.md 中的项目 subagent book-writer,会话启动时自动加载。这个文件不复制写作要求:subagent 会先读取 .codex/agents/book_writer.toml 并照此执行,因此两个客户端共用同一份写作约定。修改写作规则时只改 TOML 文件。
仓库规则 要求主编码 agent 在完成代码改动及相关检查后、最终交付和提交完整改动前,主动调用写作 agent。每次代码改动都要检查文档影响,包括新增功能、修改已有功能、修复问题和重构,无需另行提出更新文档的请求。写作 agent 阅读差异和实际实现,在同一次改动中同步受影响的中英文章节、示例、图表、安装配置说明及章节规划,然后交回主任务审核。
这是 Codex 和 Claude Code 开发流程中的一个步骤。它不是独立后台服务,也不会在每次手工 Git push 时自行运行。GitHub Actions 负责构建已经写好的页面,不调用模型生成文章。不需要额外配置云端 AI 密钥或定时任务。
较宽的图可以左右滚动,保持图中文字清晰可读。
主 agent 负责最终的事实审核。网站构建成功可以证明页面能够编译、内部链接可以找到,但不能代替对“原理是否符合代码”的检查。
章节统一写作规范
所有编号教程章节遵循同一套约定。完整写作要求见写作 agent 定义,第 01 章是实际样例。安装、发布和维护等辅助页面可以使用不编号的标题。
按下面的层级组织标题,具体知识点名称应贴合本章内容:
# 第 01 章:标题
## 1. 第一个知识点
### 1.1 第一个小知识点
### 1.2 第二个小知识点
## 2. 第二个知识点
### 2.1 第一个小知识点
## 3. 可观察的小实验
## 4. 本章小结与下一步每章只有一个 H1,章号使用两位数字。所有 H2、H3 都连续编号,实验和结尾也不例外;每个大知识点下的小节从 1 重新开始。独立知识点另起 H2,不跳级、不混用编号格式。确实需要第三层时才使用 2.1.1 形式的 H4,不再向下细分。英文标题只将首词及专有名词首字母大写,标题末尾不加标点。普通有序列表用于操作步骤,不代替标题层级。
- 展开顺序:标题后保留适用版本和源码版本行,再用一两段说明问题与成果。前置条件只链接一次,随后展示交互、解释交换了什么信息及下一步由谁行动,再验证可观察的结果。结尾统一为一个有编号的“本章小结与下一步”,不反复罗列目标和总结。
- 交互优先:源码用于核对行为,不作为章节提纲。省略仓库导览、程序入口讲解、文件或函数调用链、SDK 构造与辅助方法说明、依赖版本清单。解释读者能观察到的变化:提交问题后,程序发送当前输入和指令;收到的片段成为回答;完成或报错后,控制权回到读者。逐段检查它说明了什么输入、提供了什么上下文、如何处理响应、下一步由谁行动,或解释了哪个直接相关的工程选择。保留选择理由、代价、边界和验证依据,删除无关的实现说明。不要把读者不需要的代码导览搬到附录。
- 语气与密度:称读者为“你”,用“Mino”“程序”“模型”明确动作主体。每段围绕一个意思,使用主动句和自然亲切的语气,句子长短有变化,不把每句话都拆成一段。先说明原因,再解释做法,首次出现的术语和缩写要定义。可以用一个真实疑问连接观察与解释。避免闲话、宣传语、刻意制造悬念、未经解释的行话和大段加粗。
- 术语:遵循写作要求中的统一词汇表。“响应”指服务返回的结构化数据,“回答”指显示的文本;“一轮问答”从一次用户输入持续到最终回答,后续章节可包含中间的工具步骤。上下文、对话历史和持久化会话须区分。中文首次使用 Agent(智能体),之后写 Agent;标识符、字段、命令和文件名保持原样。区分 Mino 的运行能力与 Codex 的开发流程。
- 示例:围绕一个小场景展开,只选择有助于说明它的交互记录、请求示例或图表。代码片段不是必需内容;只有理解交互确实需要时才加入,并说明它带来的行为,而不是讲解语法。虚构输出在代码块前标明“交互示意” / “Illustrative output”,只有证据支持时才声称实际观察。代码块标注语言,可复制命令使用
bash且不带提示符,交互记录使用text;JSON 必须有效,占位符需说明。必要时交代工作目录,伪代码和不完整片段须明确标注,不放入密钥或私人日志。 - 图表:优先使用聚焦的图,通常按“读者 → Mino → 模型服务”排列角色。保留 Mermaid 无障碍信息和可读标签。图下紧接
图 01-1:说明/Figure 01-1. Caption,表格上方放表 01-1:说明/Table 01-1. Caption;图和表分别在每章内编号,说明读者应观察什么。辅助页面无需使用章节式图注。表格用于对比,有序列表用于步骤,无序列表用于并列要点。 - 实验与边界:说明操作、可观察结果和它证明的结论。区分确定的程序行为、由模型决定的措辞和未来计划;错误、取消或授权影响当前交互时再展开。猜中答案不证明有记忆,终端输入循环也不意味着能执行工具。
- 双语检查:标题层级与编号、图表编号、示例含义、适用版本和能力状态必须对应。两种语言保留相同的推理、取舍、证据边界和亲切感,各自自然表达,不机械翻译口头禅或复制断句。示例问题、指令和回答使用自然译文,固定程序提示和 API 字段保持不变。站内链接指向对应语言的相对路径。保留少量不可变的源码链接作为证据,链接文字说明它支持的行为,不为提供链接而引入符号或单设小节;标题变化后检查指向它的锚点链接。
安装、API Key 设置、环境与配置细节、打包和较长的排错清单,集中放在准备与安装、发布说明或本指南。安全或操作细节直接影响当前交互的理解时,再放进章节。
同章的小修复更新原章节,新能力按章节规划归入对应章节。写作 agent 只修改 docs/books/ 下的书籍正文与示意资源;应用代码、网站配置、工作流、agent 设置、README 和更新记录由主 agent 负责。若某项改动不影响读者,写作 agent 应说明无需更新正文的原因。
叙事风格与工程取舍
写作 agent 借用 khazix-writer 的部分技巧:具体场景开头、逐步发现问题、有用的追问、长短句变化、自然衔接,以及结尾对开头交互的呼应。优先级是:事实与证据 → 教学清晰度、工程推理和书籍规范 → 叙事表达。起草或润色前,从当前技能目录或主 agent 提供的位置找到已安装的技能,阅读其说明和相关参考资料。若技能不可用,应说明情况并使用写作定义中的适配规则,不自行安装,也不声称已经加载。仓库不依赖个人机器上的安装路径。
适配后保留标题编号、有用的表格和列表、准确的代码与 API 字段,以及正常标点。不设篇幅、口头禅或独句成段的配额,也不要求脏话、自嘲、情绪化标点、哲学延伸或推广结尾。Mino 的作者仍是 qqling | AI Builder,不借用原技能作者的身份、经历、署名和联系方式。作者故事和当时的设计动机,只能来自用户提供或确认的材料。代码能证明当前行为,不能证明作者当时怎么想;agent 运行测试得到的是测试证据,不是作者的亲身经历。推断出的理由须明确作为分析,未确认的个人细节应省略;确实不可缺少时,请主 agent 先向用户确认再写。可以使用明确标注的交互示意。
每章在解释相关行为的位置,让主要工程取舍可见:当前问题、合理的可选方法、现在的选择及有依据的理由,以及代价或适用边界。把它连接到一项检查,说明检查能证明什么、不能证明什么。通常补进现有小节的几个短段落即可,小修复不必编造新取舍,也不另加一遍总结。例如,检查请求内容能看清程序提供了哪些历史,回答合理本身不能证明记忆处理正确;单个 JSONL 文件是当前对话范围的选择,不是格式的限制;存储失败后停止聊天,可以避免在历史无法可靠保存时继续运行,代价是中断聊天,但这不会撤回已显示的文字,也不保证部分记录已经落盘。使用这些例子前,须核对章节对应版本。
写作分三轮:先确认事实和证据边界,再组织交互、取舍与可观察的检查,最后润色叙事,不改变事实和必要结构。交稿前检查四项:事实与结构准确;读者能跟上并验证交互;选择的理由、代价和边界可见;表达自然简洁。小修复或辅助页面只检查与之相关的章节要求。将简短依据及技能加载或缺失情况报告给主 agent,不把风格报告附在章节末尾。这是 Mino 适配后的检查方式,不沿用原技能的评分表。
本地预览与检查
网站工具与 Go 程序互相独立。使用 .node-version 中记录的 Node.js 24。要审阅当前检出的书籍内容,在仓库根目录运行一条命令:
./book_review.sh如果本地缺少可执行的 VitePress 或 Vite,脚本会通过 npm ci --ignore-scripts 安装网站依赖。每次运行都会重新构建书籍,然后用系统默认浏览器打开中文第 01 章;可以通过语言菜单切换到英文。预览只监听 127.0.0.1,从端口 4173 开始,遇到占用时依次选择可用端口;实际地址会显示在终端中。
审阅时保持终端打开,在该终端按 Ctrl+C 即可停止预览。预览显示的是构建后的页面,因此修改书籍后,需要先停止预览,再运行 ./book_review.sh 才能看到改动。
写作时如果希望修改后实时更新页面,可以使用开发服务器:
npm ci --ignore-scripts
npm run book:dev打开 VitePress 输出的本地地址,通常为 http://127.0.0.1:5173/mino/。默认显示英文,可以通过语言菜单切换到简体中文。
提交前运行:
npm audit --audit-level=moderate
npm run book:build
npm run book:preview检查两种语言、章节页语言切换、站内搜索、浅色与深色图表、小屏阅读和内部链接。构建产物及依赖目录由 Git 忽略。
锁文件固定网站依赖版本。VitePress 1.6.4 默认依赖的 Vite 存在已知安全公告,因此项目覆盖使用已修补的 Vite 6.4.5,与当前 Vue 插件兼容。升级工具时需重新检查这个覆盖、依赖审计、正式构建和浏览器表现,不能为消除报错而取消检查。
当前书籍配置还在 vite.optimizeDeps.include 中显式包含 mermaid。开发服务器会预构建插件注入的 Mermaid 导入,将 fastdom 等 CommonJS 依赖转换为浏览器可用的格式。没有这一步,当前锁定的 Mermaid 11.17.2 依赖可能让本地预览显示空白页,并报告缺少默认导出。升级依赖后,除了运行正式构建,还要在浏览器中检查 npm run book:dev 的效果。
每张图由 VitePress 组件负责渲染。为避免 Mermaid 的页面加载处理器再次扫描 .mermaid 元素,docs/.vitepress/theme/index.ts 在 Vue 挂载前以 startOnLoad: false 初始化 Mermaid;docs/.vitepress/config.mts 保留同一选项,供插件之后初始化时使用。插件异步读取配置,仅在插件配置中设置可能来不及阻止自动扫描,导致图表偶发显示 Syntax error。修改后,分别强制刷新一个英文和中文图表页面,再通过菜单切换语言;确认图表正常显示,没有 Syntax error 文本。
发布教程网站
教程已发布到 GitHub Pages:英文版和简体中文版。项目路径为 /mino/,不需要另设域名或服务器。
所有者已开启发布。Tutorial book 工作流 会构建两种语言、检查站内链接,并保存可下载的工作流产物。当仓库 Actions 变量 BOOK_PUBLISH_ENABLED 为 true 时,main 上成功的构建会发布网站。PR 只构建和检查书籍。
仓库的 Pages 来源已设为 GitHub Actions。更新网站时,向 main 推送书籍改动,或者在 main 上手动运行 Tutorial book。保持 BOOK_PUBLISH_ENABLED 为 true,即可自动发布。
删除该变量会停止之后的部署,但不会下线已经发布的网站。如果需要下线,请在仓库的 Pages 设置中取消发布。
用 Umami 统计书站访问
你可以通过 Umami Cloud 查看读者访问了哪些章节、从哪里进入书站。中英文共用 Umami 中的一个网站,中文页面保留 /mino/zh/ 路径。本次接入中,Views 对应页面浏览量(PV),Visitors 用于估算独立访客数(UV)。这些指标反映记录到的浏览器访问,不是精确的自然人数;统计脚本被拦截时,部分访问会漏记。具体口径见 Umami 指标说明。
使用托管的 Hobby 方案,无需维护统计服务器。截至 2026 年 9 月 25 日,该免费方案支持 1 个网站、每月最多 10 万个事件,数据保留 6 个月。页面浏览会消耗事件额度。本次接入不会自动归档旧数据;需要比较更长时间的趋势时,先核对当前方案。
配置与发布
- 登录 Umami Cloud,选择 Hobby,添加名为
Mino的网站。Domain 填qshine.github.io,不带/mino/。 - 按照采集说明,打开该网站的 Tracking code,将下面两个值填入 GitHub 仓库的 Settings → Secrets and variables → Actions → Variables。
| 仓库变量 | 跟踪代码中的值 |
|---|---|
UMAMI_SCRIPT_URL | src 中完整的 HTTPS 地址 |
UMAMI_WEBSITE_ID | data-website-id 的值 |
这两个值是公开的统计标识,不是账户密码。将它们保存为 Actions 变量即可,仓库不需要 Umami 登录凭据。
- 保持
BOOK_PUBLISH_ENABLED=true,在main上运行 Tutorial book。发布工作流会启用统计,本地构建和 PR 构建不包含统计脚本。采集域名还被限定为qshine.github.io。
两个 Umami 变量都不配置时,书站可以正常构建,但不启用统计。只配置一个会让构建失败,并显示要求同时配置两项的英文错误。修改变量不会更新已发布页面,每次修改后都要重新运行工作流。需要停用时,删除两个变量并重新发布。
排除自己的访问
打开已发布的书站,在浏览器开发者控制台中执行下面的代码,然后刷新页面:
localStorage.setItem('umami.disabled', 1);此设置对当前浏览器中的 https://qshine.github.io 生效,包含中英文页面。换用其他浏览器时需分别设置。恢复统计时,执行下面的代码并刷新。具体操作见 Umami 排除本人访问说明。
localStorage.removeItem('umami.disabled');发布后检查采集
使用未设置访问排除、也未拦截统计脚本的浏览器,打开线上首页,进入一个章节,依次后退、前进,再切换语言。在浏览器的 Network 面板中检查每次页面导航是否只发送一次页面浏览事件,并在 Umami 中核对对应路径。同一页面内跳转标题不应增加 PV:章节锚点已被排除。
同时检查本地预览没有统计请求。拦截统计脚本并刷新书站,阅读和导航仍应正常。这些检查能验证当前浏览器的采集与导航行为,不能证明所有访客都会被统计。仅有构建成功,也不能确认数据已进入你的 Umami 账户。