画图方法
作用
所有图文档共用的画图方法。业务 skill 只负责说"画什么",这里负责说"怎么画"。
如果上游来自 ddev-spec,默认就是把已写出的实现架构文档细化成图,不重新讨论架构本身。
如果上游来自 ddev-plan,默认就是把已确认的计划画成支持执行的图,不反过来改计划目标。
基本规则
- 唯一产物:
.md文件,ASCII 图直接写在 fenced code block 里 - 不再经过 PlantUML:AI 按绘制规范直接手写 ASCII,不出
.puml中间文件 - 文件名格式:
YY-MM-DD_name.md - 所有图默认 ASCII;SVG 只在确实需要时才作为补充
- 图文档按固定布局组织(标题 → 用途说明 → ASCII 图 → 补充说明)
默认动作
用户表达以下任一意图时,直接在 .md 中操作:
- 新建图
- 修改图
- 调整结构、连线、节点、布局、文案
执行顺序:
- 确定图文档位置和文件名
- 按绘制规范直接画 ASCII 图到
.md - 补齐标题、用途说明、补充说明
更新策略
更新 .md 时先判断类型:
- 纯图文档(只有标题、ASCII 图、极少量备注):可整份刷新
- 带正文的图文档(含分析说明、表格、补充备注):只替换对应图块,不整文件覆盖
默认目标:图跟着改动变,正文保持稳定。
图型选择
- 架构 / 边界图:看模块边界、职责分工和主要连接关系
- 接入点图:看现有代码从哪里接入
- 流程图:看主路径、关键分支和异常出口
- 前后对照图:看修改前后行为变化
- 依赖拓扑图:看模块依赖和布局关系
在架构阶段,优先把"架构规划 + 接入点 + 主流程 + 前后对比"这四类图补齐。
ASCII 图绘制规范
制表符:用 Unicode,不用 ASCII 拼接
❌ ASCII 拼接:
+----+----+
| A | B |
+----+----+
✅ Unicode 制表符:
┌────┬────┐
│ A │ B │
└────┴────┘
| 字符 | 作用 | 字符 | 作用 |
|---|---|---|---|
┌ ┐ └ ┘ |
四角 | ├ ┤ ┬ ┴ ┼ |
T 型 / 十字 |
│ |
竖线 | ─ |
横线 |
► ▼ ▲ ◄ |
实心箭头 | ▷ ▽ △ ◁ |
空心箭头 |
先定列宽,再画框
同一列所有框宽度必须一致。先扫内容取最长标签,加边距后统一使用。
列宽 = max(框内最长行宽度) + 2 // 左右各留白一格
先定总宽,再排多列(多列框 + 连线标注图)
多列并排或带连线标注的图,先算后写,不要边写边数空格:
- 先定总宽 W — 一次算清全图所有行的最大需求宽度(各列占位宽 + 列间距 + 两侧留白),整图统一用这一个 W
- 所有行右侧补齐到 W — 边框行、横向连线行、标签行都补行尾空格到 W,使「所有含
│的行等宽」天然成立;不靠肉眼对齐 - 框和列用固定列偏移 — 先定每列起始列号(如
col1=0、col2=24、col3=48),框、竖线、转弯、箭头都从这些列号出发 - 连线标签受剩余宽度约束 — 写标签前算
剩余宽度 = W - 标签起始列 - 右侧留白;放不下时优先拆成两行或缩短标签,不向右撑超 W - 构造复杂时用一次性 Python 生成器 — 固定 W,逐行
ljust(W),按统一列号定位连线;生成结果只写入.md,不留中间产物
按以上规则构造后,再跑「绘制完成门禁」的宽度校验。
正交连线,禁止斜线
只用横线 ─ + 竖线 │,转弯用 └ ┌ ┘ ┐。
✅ 正交:
A ──> B
│
v
C
❌ 斜线:
A ──> B
╲
C
箭头约定
──> 右箭头 <── 左箭头
v 下箭头 ^ 上箭头
跨行箭头先竖线延伸到目标行再转弯:
A ─────────┐
v
B <────────┘
短标签原则
框内文字不超过 2 行。详细说明用框外标注或脚注补充。
框图标签语言:英文优先
框图 fenced code block 内的所有标签使用英文。 不在框内写中文。
原因:CJK 字符在等宽字体中的实际像素宽度 ≠ 2× ASCII 宽度(由字体渲染引擎决定,无法通过列宽计算弥补)。在框图中混用中英文会导致视觉错位("犬牙交错"),且此问题无法通过列宽算法解决。
✅ 英文标签:
┌────────────────┐
│ flash_test/ │
│ (new module) │
└────────────────┘
❌ 中文标签(对齐不可靠):
┌────────────────┐
│ 闪存测试/ │
│ (新增模块) │
└────────────────┘
规则:
- 框内标签:英文短词组,用
_或 camelCase 保留代码标识符风格 - 连线/状态/条件文字:英文缩写或短句(如
OK、FAIL、count=0) - 逻辑复杂、英文表达不清时,才在图外补中文说明(表格或段落);简单图无需图例
图外中文说明:解释图意,不是翻译术语
图外中文说明是对图中逻辑、流程或关系的中文解读,帮助读者理解"发生了什么";它不是图中英文术语的中英对照表。
✅ 正确 — 解释图意:
> 上电后 bootloader 先校验 flash_test 模块的签名,验签通过才跳转。
> 如果签名无效,回退到 recovery 分区。
❌ 错误 — 翻译术语表:
| 图中英文 | 中文 |
|----------------|---------|
| bootloader | 引导程序 |
| flash_test | 闪存测试 |
| recovery | 恢复分区 |
规则:
- 图外说明写"流程为什么这样走、关键判断是什么、边界为什么这样画",不写"这个词对应的中文叫什么"
- 英文术语已在图中出现过的,不需要在说明里重复定义
- 说明短则一两句话,长则分成小段;不写成翻译对照表
- 代码块内已存在的 C/Python 等代码不受此限制(注释中的中文正常保留)
一图一事
一张图只回答一个问题。开始拥挤就拆多张。
一张图 = 一个视角(边界 / 状态 / 数据布局 / 流程)
绘制顺序
- 先摆框 — 多列或带连线标注的图先定总宽 W、列偏移与列宽(见「先定总宽,再排多列」),再确定所有框的位置与尺寸
- 后连线 — 框定稿后再补
│─v──>等连线 - 最后补标注 — 框外注释、触发条件、条件文字最后放
文档布局
图文档按此顺序:
- 标题
- 一句话说明用途
- ASCII 图(放在 fenced code block 里)
- 需要时补一小段说明或表格
绘制完成门禁(强制)
每次写完或更新含图 .md 后,必须执行以下核对。不通过不得视为完成。
步骤
- 回读文件:用 Read 工具回读刚写入/更新的
.md文件全文 - 提取框图:定位所有 fenced code block(``` 包裹的 ASCII 图)
- 宽度自动校验:对每个框图跑 Python 宽度检查脚本(见下方「宽度自动校验」),有报错先修再继续
- 逐框检查:对每个图执行以下检查项
宽度自动校验
AI 画完框图后,必须对每个 fenced code block 内的 ASCII 图执行以下 Python 脚本进行宽度校验:
python3 -c "
import sys
block = sys.stdin.read()
for i, line in enumerate(block.split('\n'), 1):
# 跳过空行
if not line.strip():
continue
# ┌─┐ └─┘ ─ 等制表符都是单字符宽,len() 按 Unicode 字符计数是正确的
w = len(line)
# 检测右边框位置差异:所有含 │ 的行宽度应一致
if '│' in line:
print(f'L{i:3d} w={w:3d} {line}')
elif line.lstrip().startswith(('┌','└','├','┐','┘','┤')):
print(f'L{i:3d} w={w:3d} {line}')
"
用法:将框图中整个 fenced code block 的内容复制后 pipe 到该脚本。输出会列出每行的 Unicode 字符宽度 w 和行内容。检查要点:
- 所有含
│的行w值必须相同 → 否则右边框不齐 - 同框
┌─...─┐与└─...─┘的w值必须相同 → 否则上下框线不等宽 - 上框
w与内容行w的差值 = 2(左右边框各占 1 列),即w(border) == w(content)且w(border) - w(content_with_pipe) == 0(因为│就是边框本身,不额外占用边距)
检查项
| # | 检查项 | 方法 | 不通过时 |
|---|---|---|---|
| A | 右边框对齐 | 先跑「宽度自动校验」:所有含 │ 的行 w 值必须相等(即同一列);不满足时补/削空格 |
补空格或削空格,重写该行 |
| B | 上下框线等宽 | 先跑「宽度自动校验」:┌─...─┐ 与 └─...─┘ 的 w 值必须相同 |
调整横线数量 |
| C | T型/十字接合完整 | ├ ┤ ┬ ┴ ┼ 上下左右邻接位是否有对应连线 |
补连或改T型字符 |
| D | 无斜线 | grep ╲ ╱ ╳ ╱ — 必须零命中 |
改用正交转折 |
| E | 无断线 | 竖线 │ 贯穿多行时,每行同一列都有 │ 或合法转角 |
补竖线 |
示例:右边框对齐检查
写入的图(错误 — 第 3 行右边框偏右):
┌──────────────────────┐
│ AGENTS.md (global) │
│ session end hook │ ← 右边框比第 1 行右移了 2 列
└──────────────────────┘
自检发现 → 修正为:
┌──────────────────────┐
│ AGENTS.md (global) │
│ session end hook │
└──────────────────────┘
核对通过条件
- 所有检查项 A-E 全部通过
- 如果任一检查项未通过,修正后重新回读,直到全部通过
- 修正超过 3 次仍未通过 → 重画该图(从摆框步骤开始)
生成后自检
.md中的 ASCII 图是否按绘制规范执行- 节点名、连线关系、说明文字是否一致
- 是否列宽对齐、正交连线、无斜线
- 是否一图一事,未拥挤
参考文件
- 图型分类
- 模板
- 示例