23 KiB
钉钉文档创建流程
本文只处理文档结构和排版设计。普通创建的执行入口固定为 dws doc +create,命令内置分片与回读验证;原子 doc create/read/update 仅用于 shortcut 未公开所需参数的专家路径,使用前必须读取精确 leaf Schema。
路由硬约束: 正文文件使用
--content @./相对路径 --doc-format markdown|jsonml;禁止/tmp、绝对路径、已删除的 Python 脚本以及“创建后再额外 read”固定流水。
改写已有文档见 doc-update-workflow.md。排版规范见 doc-style-guideline.md。
前置必读
同时读取 doc-style-guideline.md:
- §2.0 类型判断决策表 → 锁定文档类型(决策型 / 执行型 / 说明型 / 知识沉淀型)和骨架
- §1 硬规则 → 全程生效(
--name已是 H1、不编造 URL、Markdown 草稿不写 callout 等)
关键词速查(用户意图 → 起稿路径)
| 用户关键词 | 文档类型 | 起稿路径 |
|---|---|---|
| 汇报 / 周报 / 月报 / 复盘 / 方案选型 / 决策 / 对比 | §2.1 决策型 | → JSONML 起稿 |
| 调研 / 技术方案 / 复盘报告(含对比/数据) | §2.4 知识沉淀型 | → JSONML 起稿 |
| SOP / Runbook / 接入指南 / 升级 / 操作手册 | §2.2 执行型 | → Markdown 起稿 |
| 接口文档 / 能力清单 / 参数说明 / 错误码 | §2.3 说明型 | → Markdown 起稿 |
| 用户原文含:颜色/高亮/美观/醒目/重点突出/像PPT | 任意类型 | → JSONML 起稿 |
适用边界
进入本文前,必须已经确认用户要创建的是钉钉文档 (adoc)。如果用户要的是钉钉表格、AI表格、文件上传、知识库空间管理或消息发送,不要套用本文。
本文覆盖:
- 文档标题和创建位置确认
- 正文草稿准备
+create写入并自动回读验收- 内容缺失时的补救写入
本文不覆盖:
- 从群聊、日志、听记、表格等来源采集资料
- 生成日报、周报、月报等业务报告口径
- 文档权限分享、消息通知或待办创建
- 非钉钉文档的新建流程
创建前检查
创建前先锁定四个输入:
| 项目 | 要求 |
|---|---|
| 标题 | 用 --name 传入;正文不要再重复同名一级标题 |
| 位置 | 默认创建到我的文档;指定目录时只接受文档文件夹 nodeId 或 alidocs 文件夹 URL |
| 正文 | 多行、表格、代码块、特殊字符或长度 >= 2KB 时必须写入 UTF-8 临时 .md 文件 |
| 格式 | 按 §JSONML 起稿判定 决定起稿路径:命中 JSONML 起稿条件时直接用 JSONML 构造(跳过 markdown);未命中时用 Markdown 起稿,创建后按 doc-update-workflow.md 精修 |
禁止把纯数字 dentryId、drive parent-id 或 spaceId 填进 --folder。
JSONML 起稿判定
在正文准备之前,先判断是否直接用 JSONML 起稿。命中以下任一条件即走 JSONML 起稿路径(跳过 markdown 草稿阶段):
文档类型触发
| 类型 | 触发条件 |
|---|---|
| 决策型(§2.1) | 默认触发 — 汇报/方案/对比需要摘要 callout、彩色表头、决策时限标注 |
| 知识沉淀型(§2.4) | 含对比分析、多维度数据可视化、需要关键节点彩色 callout |
意图关键词触发
用户原文或需求描述中出现以下任一关键词:
- 颜色 / 配色 / 上色 / 高亮 / 醒目
- 字号 / 字体 / 加大 / 缩小
- 视觉效果 / 排版精美 / 好看 / 美观
- callout / 分栏 / 对比色 / 彩色表头
- "像 PPT 那样" / "有设计感" / "重点突出"
设计规划(JSONML 起稿前必做)
判定走 JSONML 路径后,禁止立即动手写 JSONML。先完成以下两阶段规划,各自产出一个持久文件作为后续阶段的锚点。
设计原则(全程生效)
- 结构即信息 — 标题层级、表格 vs 分栏 vs 列表、callout 位置都应编码内容逻辑。问自己:“去掉这个结构元素,读者会丢失信息或体验变差吗?”— 丢失信息则必保留;不丢失信息但能提升可读性或美观度(如分割线分隔章节、分栏对比排版)也应保留;既不携带信息也不提升体验的装饰元素才删除。
- 视觉层级引导阅读 — 每一屏必须让读者瞥一眼就能回答:“这块最重要的是什么?”字号/粗体/颜色形成明确梯度:标题 > 重点数据 > 正文 > 辅助信息。
- 克制产生质感 — 遵循 60-30-10 配色比例:60% 中性底色(白/浅灰)、30% 辅助色、10% 强调色。多色系共存时需保持同等饱和度并各有语义角色(如淡蓝=信息、淡黄=提示、淡红=风险),同一色系内深浅变化自由。callout 不超过 2 个。
- 设计先于执行 — 从规划阶段起每个结构块的样式就已确定,执行时(无论直接 JSONML 还是脚手架精修)只是落地已有设计,不是边写边想。
- 同类同色、一色多阶 — 同类信息必须使用相同色系;单一色系按元素角色展开为深/中/浅/极浅四级(标题文字用深色、强调用中色、高亮/表头用浅色、背景用极浅色),不要全篇只用一个 hex 值。
Phase 1:RFC — 需求理解与设计方向
目标:明确“做什么”和“为什么这样做”,形成方向性锚点。
1.1 需求提取(全量列出用户显式要求)
通读用户 prompt,抽取两类要求并编为清单:
内容要求:
- 标题、字数、章节划分
- 数据来源、受众
- 语气/风格(如“大气”“专业”“轻松”)
样式要求(每一条都必须在最终输出中体现,不得遗漏):
- 字体:映射为 font-family 名称(参照 cookbook 字体映射表),区分“全文字体”和“特定元素字体”
- 字号、行距、对齐、颜色
- 强调手段(加粗、高亮、配色…)
- 约束(如“每部分不省略”)
用户没有明确指定的维度(如未指定行距、未指定表格样式)由 Phase 2 补充设计决策。
1.2 内容-表现适配(每个章节的内容适合用什么元素)
对每个章节回答:“这个内容的核心是什么类型的信息?”→ 选择最佳元素:
块级结构元素:
| 信息类型 | 首选元素 | 不适合 |
|---|---|---|
| 多个同类实体对比(≥ 4 项或 ≥ 3 维度) | 彩色表头表格 | 纯文本段落 |
| 少量实体对比(2-3 项× 少量维度) | 分栏(每栏一个实体,可设边框/背景色) | 大宽表格 |
| 时间序列/流程(行程/步骤) | 有序列表 + 粗体时间标签 | 无序列表 |
| 单个结论/推荐/重要提示 | callout(“花大胆”的地方) | 普通段落 |
| 描述性文字(背景/说明) | 正文段落 + 关键词粗体 | 表格 |
| 分类列举(特色/亮点) | 无序列表 | 表格(数据不够多列时) |
| 数值强调(评分/价格/统计) | 加粗 + 着色 | 跳过不强调 |
| 引用原文(用户评价/网友点评/官方说明) | 引用块 | 普通段落 |
| 任务/待办清单 | checklist(- [ ]) |
普通列表 |
| 章节分隔/主题转换 | 分割线(hr) |
空行 |
| 板块内子区域分隔(同一单元格/容器内多个逻辑段) | hr 内部分隔(在 tc 或 container 内部使用) | 空行或留白 |
| 结构化元信息(人/时间/地点/属性清单) | 键值对表格(窄标签列 ~15-20% + 宽内容列) | 多行段落 |
| 分类标签/状态标记 | 标签元素(tag) | 纯文本标记 |
行内强调元素:
- emoji — 用于 callout 前缀、状态标记、H2/H3 标题前;不在普通段落和列表项中滥用
- 加粗/高亮/着色 — 强调关键数据和结论
- highlight 色带 — 在标题 span 上设
"highlight": "#浅色"形成轻量色条标记,比 callout 更轻,适合区分多个并列板块的主题色 - 灰色辅助文字 — 用浅灰色(如
#979A9B)标记示例/说明/占位文字,与正文形成明确的主次层级 - 图片 — 实景照片、截图、示意图能显著提升理解时使用
分栏选型补充:分栏栏数无上限,但推荐 2-4 栏(≥5 栏会比较拥挤),可设置边框和背景色。建议设置 fill 背景色(纯白底分栏视觉上与普通段落无异,读者不易感知分栏结构)。适合场景:
- 2-3 个同类实体并排展示(每栏一个实体,含标题 + 描述 + 关键数据)
- 轻量对比:“优点 vs 缺点”、“方案 A vs B”、“Day 1 vs Day 2”
- 网格布局:多次插入同栏数分栏可形成卡片网格(如 2×3、3×2),适合 4-9 个结构相同、内容等长的卡片式实体。约束:每个格子内容必须结构一致且长度相近,否则高低不齐会很丑;实体数不能整除栏数时不使用
例如:“5 个实体多维度对比” → 彩色表头表格;“两组信息并排” → 分栏;“6 个结构相同的卡片” → 2×3 分栏网格。
1.3 起稿策略选择
根据文档复杂度和上方适配结果,确定起稿路径:直接 JSONML / Markdown 脚手架 + JSONML 精修 / 直接 JSONML 分段构造。具体条件和流程见下方「起稿」节的策略表。
落盘
将以上内容写入 <name>-rfc.md,包括:
- 需求摘要(内容要求 + 样式要求)
- 每章展现策略 + 选择理由
- 起稿策略
Phase 2:Spec — 精确设计参数
目标:将 RFC 的方向决策转化为可直接执行的参数。
2.1 视觉体系设计(确定全局设计变量)
在以下四个维度做出明确选择,每个选择都必须能解释为什么适合这篇文档:
色彩(选定主色后展开为色阶):
用户指定颜色时(如"蓝色""绿色"),不要全篇只用一个 hex 值。将其展开为 4 级色阶,按元素角色分配:
| 角色 | 用途 | 色阶要求 |
|---|---|---|
| 深色 | 标题文字、重点数据 color |
白底上高对比可读 |
| 中色 | 正文强调、链接 color |
辨识度高但不抢标题 |
| 浅色 | highlight 色带、表头 fill | 底色柔和,上方深色文字可读 |
| 极浅 | container bgcolor、大面积背景 | 接近白色,仅提供区域感 |
规则:
- 深→浅的层级关系不可颠倒(不能用极浅色做标题文字、不能用深色做背景)
- 同类板块/同类标题必须使用完全相同的色阶组合,通过色彩的重复形成视觉韵律
- 不同类别可用不同色系区分(如:任务=蓝系、风险=红系、成果=绿系)
- 遵循 60-30-10 配色比例:60% 中性底色、30% 辅助色、10% 强调色;用户指定的颜色值优先
字体梯度(形成明确层级):
- 主标题(h2):字体 / 字号 / 粗体 / 颜色
- 正文:字体 / 字号 / 行距
- 强调文字:粗体 + 颜色或高亮
- 辅助信息(注释/来源):字号偏小 / 灰色
表格风格(有表格时):
- 表头:底色 + 文字色 + 是否粗体
- 单元格:默认对齐 / 字号
视觉重心(克制原则落地): 全篇选 1-2 处给予最强视觉处理(配色 callout / 彩色表头 / 分栏对比),其余元素保持朴素。不要处处强调 — 处处强调等于没有强调。
callout 可通过 "showstk": true, "sticker": "图标名" 配置顶部贴纸图标(如“灯泡”“火”“钉子”),增强语义标识。设置了 sticker 后,高亮块内首个段落不要再以 emoji 开头,避免紧邻的位置出现两个图标。
落盘与回验
-
将以上内容写入
<name>-design.md,包括:- 逐章元素映射(用什么标签、什么属性)
- 色阶具体 hex 值
- 字体梯度参数
- 表格风格细节
-
回验:Read
<name>-rfc.md,逐条确认:- RFC 中每条需求在 Spec 中有对应实现
- 展现策略在 Spec 中有具体参数支撑
- 配色遵循 60-30-10 比例、callout ≤ 2 个、多色系饱和度一致且有语义角色
回验通过后进入下一节开始构造 JSONML。
JSONML 起稿(命中判定时使用)
根据 RFC 中确定的起稿策略执行:
| 策略 | 条件 | 执行流程 |
|---|---|---|
| 直接 JSONML | 短文档(≤ 15 块级节点)且结构简单 | 在 ./drafts/<name>.json 编写完整 JSONML 树 → +create --content @./drafts/<name>.json --doc-format jsonml |
| Markdown 脚手架 + JSONML 精修 | 长文档且结构较线性 | ① Markdown 建立内容骨架 → +create ② 需要精修时用 +fetch --detail full 拉回 JSONML ③ 逐章执行结构变换与样式叠加 |
| 直接 JSONML 分段构造 | 长文档且含大量富结构 | 按章节分段构造 JSONML,每段写完校验通过后再写下一段,最后拼接 |
脚手架策略警示:Markdown 无法表达分栏/callout/色彩表头,拉回的 JSONML 只有纯文本骨架。精修阶段不是“在现有结构上加色”,而是“参照 RFC/Spec 重组结构”。
MUST READ:动手写 JSONML 前,必须先用 Read 工具读取 doc-jsonml-cookbook.md — 其中 §决策型文档骨架范例 有可直接复制修改的完整模板。 节点类型和属性的权威定义见 doc-jsonml-schema.md。
⚠️ JSONML 降级约束
禁止因一次校验失败就放弃 JSONML 降级为 Markdown。 当用户需求已触发 JSONML 起稿判定时,JSONML 是实现其样式要求的首选路径。失败时的处理策略:
- 校验报错 → 读取错误信息,定位具体节点,修复后重试
- JSON 语法错误 → 检查括号匹配、逗号、引号,修复后重试
- 反复失败(≥3 次) → 尝试简化结构(减少嵌套、拆分复杂节点)再试
- 仍然失败 → 退化为「Markdown 脚手架 + JSONML 精修」路径(流程同上方策略表),并告知用户当前状况
“由于 JSONML 结构复杂且容易出错,改用 Markdown” — 这不是合法降级理由。必须先充分重试,且降级后仍需通过精修补回样式。
⚠️ JSONML 结构严格约束(生成时必须遵守)
每个节点是一个 JSON 数组:[tagName, attributes?, ...children]
- 第一个元素是字符串,表示标签名(如
"p","h1","span","container") - 第二个元素(可选)是一个 JSON 对象,表示属性(如
{"uuid": "abc"})。如果无属性,可以直接进入子节点 - 随后的元素是子节点,可以是纯字符串(仅限 leaf span 内),也可以是另一个 JSONML 数组
- 所有
[必须有对应],所有{必须有对应},数组元素之间用,分隔,最后一个元素后不加,
常见 LLM 生成错误(务必避免):
| 错误类型 | 示例 | 后果 |
|---|---|---|
缺少闭合 ] |
["p", {}, ["span", ...] |
JSON 解析失败 |
| 多余逗号 | ["p", {},] |
JSON 解析失败 |
| 缺少逗号 | ["p", {} ["span"]] |
JSON 解析失败 |
| 引号不匹配 | ["p", {"uuid": "abc}] |
JSON 解析失败 |
有序列表每项都设 start:1 |
{"start":1} 在每项重复 |
所有项编号重置为 1(显示为 a/a/a) |
列表 level 从 1 开始 |
"level": 1 作为顶级 |
顶级列表项多一层缩进;建议:顶级 "level": 0,子级 "level": 1 |
用 fontFamily 设字体 |
"fontFamily": "Arial" |
校验报错;正确写法:"fonts": {"ascii": "Arial", "eastAsia": "..."} |
| 用多个 span “换行” | 同一 p 内放两个 span |
不会产生换行;每个换行必须是独立的 p 节点 |
基础结构
文件内容是一个裸 JSONML 数组,根节点为 "root":
["root", {},
["h2", {}, ["span", {"data-type": "text"}, ["span", {"data-type": "leaf"}, "章节标题"]]],
["p", {}, ["span", {"data-type": "text"}, ["span", {"data-type": "leaf"}, "正文段落"]]]
]
- 根节点固定
"root"(不是"body") --name已是 H1,JSONML 从h2开始- 表格结构是
table → tr → tc(无th/td) - 分栏是
table+"sr": true,tc建议设fill背景色 - 有序列表:仅第一项设
"start": 1,后续项不设start(系统自动递增) - 列表
level建议从 0 开始:顶级项"level": 0,子项"level": 1,以此类推 - uuid 必须显式提供(CLI 不自动生成)
- 每行内容对应一个
p节点 — 同一p内的多个span不会换行,只会横向拼接;需要换行时必须拆分为多个p
视觉设计要点
构造时主动使用这些属性实现视觉效果:
- 文字着色:leaf 上
"color": "#hex"、"highlight": "#hex" - highlight 色带:标题 leaf 上
"highlight": "#浅色"可形成色条效果(比 callout 更轻量的板块标记) - 字号:leaf 上
"sz": 14, "szUnit": "pt" - callout:
["container", {"subType": "colorBlocks", "metadata": {"bgcolor": "#E8F5E9", "border": "left"}}, ...blocks] - callout + sticker:
["container", {"subType": "colorBlocks", "metadata": {"bgcolor": "#FEF3F3", "showstk": true, "sticker": "火"}}, ...blocks] - 表格单元格底色:tc 上
"fill": "#hex"
写入
dws doc +create --name "<文档名>" --content @./drafts/<name>.json --doc-format jsonml
验收
读取 +create 返回的 verified、steps、nodeId 和验证结果。只有返回 verified=false 或结构化 partial/unknown 错误时,才进入恢复流程。
正文准备(未命中 JSONML 判定时)
正文草稿先在工作目录内的 Markdown 文件中完成,推荐路径形如 ./drafts/<name>.md。
准备规则:
- 只使用用户已提供或对话中已确认的正文素材。
- 如果正文素材不足,先补齐文档目标、受众、章节和缺口;不要在本文中临时扩展跨产品采集流程。
- 先按 doc-style-guideline.md §2.0 类型判断决策表 确定文档类型,再用对应类型的骨架样板(§2.1 决策型 / §2.2 执行型 / §2.3 说明型 / §2.4 知识沉淀型)。不要套通用三段式。
--name已是 H1,正文从##开始;正文内不要再写#一级标题(除非确实需要正文内再造一级 H1 并说明动机)。- 摘要、bullet、引用块、callout 等元素的使用边界以 style-guideline §3-§7 为准。
- 同类信息保持一致:风险、状态、行动项各用一种元素 + 一种视觉语义(style-guideline §1.2 / §5)。
- 临时文件必须保留真实换行,不能把换行写成字面量
\n。 - Markdown 草稿阶段不要写 callout / 分栏 / 附件——这些留到「创建后的精修」用
doc block insert操作(style-guideline §1.3)。 - 图片素材闭环(硬规则):正文需求含图片/截图/图文并茂时,Markdown 只写文本骨架和图片占位说明;创建后用
dws doc +media-insert --node <nodeId> --file ./相对路径插入,再用+media-list验证稳定resourceId。禁止正文临时 URL、绝对路径、curl/wget 和本地依赖安装兜底。
创建写入
优先用工作目录相对文件一次创建并写入:
dws doc +create --name "<文档名>" --content @./drafts/<name>.md --doc-format markdown
创建到指定文件夹:
dws doc +create --name "<文档名>" --content @./drafts/<name>.md --folder <DOC_FOLDER_NODE_ID> --doc-format markdown
创建到知识库:
dws doc +create --name "<文档名>" --content @./drafts/<name>.md --workspace <WS_ID> --doc-format markdown
短纯文本才允许直接传 --content:
dws doc +create --name "<文档名>" --content "短内容" --doc-format markdown
返回后立即记录:
| 字段 | 用法 |
|---|---|
nodeId |
后续 doc read、doc update、doc block、doc media 的目标 |
docUrl |
最终交付给用户的链接;缺失时用 doc info 补查 |
chunksWritten |
判断是否触发自动分片;大于 1 时重点检查章节顺序 |
内置回读验收
+create 已在同一执行内回读验证,禁止再固定追加一次 doc read。检查结构化返回:
验收要点:
- 开头摘要、关键章节、表格表头、末尾章节都存在。
- 回读文本顺序和临时 Markdown 一致。
- 没有把字面量
\n渲染成一整行。 - 如果返回
chunksWritten > 1,看degradations:为空即表示分片没有改变渲染结构,无需人工核对边界;非空时按其中的kind与line定点检查(如table_split表示该表被拆成多张、每张带重发的表头)。 - 最终回复必须给用户
docUrl;如果只拿到nodeId,说明链接字段未返回,并报告已尝试doc info。
缺失补救
DWS 写入管道会自动处理长内容分片。只有出现以下情况才手工补片:
- 返回
doc_write_commit_unknown(分片超时,提交状态未知) - 命令超时或只写入部分分片
- 回读发现后半段缺失、章节乱序或表格损坏
补救流程:
- 用
+fetch的最小 scope 确认已经写到哪个章节。 - 从原始 Markdown 中截取缺失部分,写入
./drafts/<name>-resume.md。 - 追加缺失内容:
dws doc +update --node <nodeId> --command append --content @./drafts/<name>-resume.md --doc-format markdown
- 使用
+update返回的验证结果确认缺失章节已补齐;结果未知时再定点+fetch。
创建后的精修
创建流程本身优先完成整篇正文。只有需要局部补充、插入附件、加 callout / 分栏、或无损结构调整时,才进入精修——精修路径统一走 doc-update-workflow.md。
精修常见入口(按 doc-update-workflow.md §1.3 优先级排序:JSONML 首选):
- 单 block JSONML 精修(首选):
doc block list --node <id> --content-format jsonml --block-id <uuid>取子树 →doc block update --node <id> --block-id <uuid> --content-format jsonml --element '[...]'写回(uuid 必须 == --block-id;写入端默认执行 schema validate,详见 doc-update-workflow.md §4.4) - 整篇 JSONML 无损:
doc update --content-format jsonml --mode overwrite(默认直接覆盖,适合一次改多处或改 root sectPr;担心并发覆盖时加--revision <N>触发并发检查) - 插入附件 / 图片:
+media-insert,之后用+media-list验证稳定resourceId - element JSON 次选:
doc block insert/doc block update不带--content-format jsonml时按老接口 JSON 解析;仅在 JSONML 不支持某字段时使用 - markdown 兜底:
doc update --mode append(末尾追加纯文本段落,无富结构需保留时)
字段结构以 doc.md 为准;何时用何种精修路径见 doc-update-workflow.md §3「改写路径速查」。
交付口径
只报告已经验证过的信息:
- 文档标题
docUrl或nodeId- 已写入的正文范围
- 回读验收结果
- 如有缺失,说明缺失位置和补救状态
未回读前,不要说内容完整或任务完成。