引用本文(DOI: 10.5281/zenodo.21615416)
本文保存于 Zenodo。以下同时提供始终指向最新版本的 DOI,以及固定于您正在阅读版本的 DOI。
小村 豪(2026)。《HCP 图表与 MakingHCPChartSkill 入门》。小村软件有限公司。https://doi.org/10.5281/zenodo.21615416 https://comcomponent.com/zh-CN/blog/2026/02/22/000-what-is-hcp-chart-and-making-hcp-chart-skill/
- DOI(最新版本)
- 10.5281/zenodo.21615416
- DOI(此版本)
- 10.5281/zenodo.22281918
目录
当想把 HCP 图表变成“可以当作规范来阅读的图”时,仅靠手绘图表就很难维持运作。
MakingHCPChartSkill 是一个技能仓库,用于 按照规范解析 HCP-DSL(文本),并返回决定性的 SVG(意思是相同的输入总会得到相同的 SVG)。
本文将从 HCP 图表的基础讲起,一直确认到实际动手运行为止。
图中实线表示始终成立的关系,虚线表示带条件的关系(成立条件写在详情页各关系的说明中)。关系的完整列表(共 14 条,附依据与确信度)以及主要概念的定义,汇总在知识地图详情页(日文)。数据:JSON-LD / Turtle
1. 什么是 HCP 图表
HCP 图表是一种以层级方式描述处理流程的表达形式。 在这个仓库中,以下写法被当作必须遵循的规则。
- 左侧是“要达成什么(目的)”
- 右侧(更深的缩进)是“如何达成(手段与细节)”
- 最上层(level 0)写目的标签
按照这套规则书写文本,可以让设计意图与实现细节之间的对应关系变得容易阅读。
flowchart TB
accTitle: HCP 图表书写的基本规则
accDescr: 最上层的 level 0 只写目的标签,左侧写要达成什么这一目的,右侧更深的缩进写如何达成这一手段,由此可以读出设计意图与实现细节的对应关系。
l0["level 0 只写目的标签"] --> goal["左侧是目的(要达成什么)"]
goal --> means["右侧是手段(如何达成)"]
means -.-> effect["可以读出设计意图与实现细节的对应"]
图1:HCP 图表以“左侧是目的,右侧的缩进是手段”这种对应关系,按层级描述处理流程。
1.1. HCP 的由来,以及与其他图法的差异
HCP 是 Hierarchical ComPact description chart 的缩写,是日本电信电话公社(现在的 NTT)横须贺电气通信研究所设计的图法。也就是说,它并不是本文或这个仓库自创的词,而是很早以前就在日本使用的记法。它的特点包括:可以按层级书写处理流程、便于同时写出数据与处理的关系、徒手也容易绘制,以及说明文字放在符号旁边而不是框内,因此一张图里能容纳很多内容。
把它和其他图法放在一起对比,定位就更清楚了。
| 图法 | 结构的表达方式 | 与 HCP 图表的差异 |
|---|---|---|
| 流程图 | 用方框排列处理,用连线追踪流程 | 无法表达“哪个处理是哪个处理的细节”这种层级关系。分支一多,连线容易交叉 |
| NS 图(结构化图) | 用嵌套的长方形表示结构 | 说明写在方框内部,层级一深或说明一长,横向宽度就容易不够 |
| PAD | 用树结构从左向右逐层细化 | “左侧是目的,右侧是手段”的方向与 HCP 的思路接近。HCP 以圆形符号为主,说明写在符号右侧 |
在此基础上,本文讨论的 MakingHCPChartSkill 特有的东西不是记法本身,而是下面这 2 项。
- 用于以文本书写 HCP 图表的 HCP-DSL 及其解析规范(
references/hcpchartspec.md) - “level 0 只写目的标签,赋值或比较这类近似代码的描述要下放到子节点”这一 描述粒度的约定。这是仓库一侧规定的必须遵循的规则,并不是 HCP 图表通用的规定
flowchart TB
accTitle: 通用记法与仓库特有部分的区分
accDescr: HCP 图表这一图法本身是横须贺电气通信研究所设计的既有记法,这个仓库特有的只有 HCP-DSL 及其解析规范,以及描述粒度的约定这 2 项。
general["HCP 图表(既有的图法)"] --> repo["MakingHCPChartSkill 特有的部分"]
repo --> dsl["HCP-DSL 与解析规范"]
repo --> conv["描述粒度的约定"]
conv -.-> rule["level 0 只写目的标签"]
图2:记法本身是早就存在的图法,这个仓库特有的只有 HCP-DSL 和描述粒度的约定这 2 项。
1.2. HCP-DSL 的写法(语法速查表)
写法的整体面貌,用下面几张表基本就够了。完整规范在 references/hcpchartspec.md,只想看要点则整理在 references/hcp-chart-schema.md。
行的种类
| 行的形式 | 处理方式 |
|---|---|
| 空行 | 被忽略 |
去掉空白后以 # 开头的行 |
作为注释被忽略 |
去掉空白后以 \ 或 ¥ 开头的行 |
命令行。命令名截止到第一个半角空格,之后的部分是参数 |
| 上述之外 | 作为普通的处理节点(圆圈)绘制 |
缩进(层级)
| 规则 | 内容 |
|---|---|
| 1 级的单位 | 1 个制表符,或 4 个半角空格 |
| 不完整的缩进 | 像 2 个空格这样的步长会产生 error |
| 一次加深多级 | 比上一行深 2 级以上会产生 error。要每次只加深 1 级 |
命令
| 命令 | 含义 | 注意事项 |
|---|---|---|
\title / \author / \date / \version |
头部信息 | 写在 \module 之前则对所有模块通用,写在之后则只覆盖该模块 |
\module <名称> |
模块的开始 | 必需。只能写在 level 0。同名模块会产生 error |
\mod <标签> |
调用模块或函数 | 图中以双圆圈绘制 |
\repeat <标签> |
循环 | 循环的内容写到下一级 |
\fork <标签> |
分支(分流)的父节点 | 分支目标放在它的正下方 |
\true <标签> / \false <标签> |
真假二分支的分支边 | 只能放在 \fork 的正下方(只深 1 级的位置)。祖先中没有 \fork 时会产生 error |
\branch <条件> |
真假之外的多分支的分支边 | 同上 |
\return [n] |
退出 | n 是可以省略的整数 |
\ec <标签> / \ex <标签> |
错误检查 / 错误出口 | 现行版本只负责绘制,不具有控制上的含义 |
\data <名称> |
数据定义 | 名称中不能包含空白和 .(包含则产生 error) |
\in <名称> / \out <名称> |
输入输出数据的标注 | 作为上一级父节点的标注来处理 |
最小的例子如下所示。从 \module 开始,把目的放在左侧,把手段放在右侧,仅此而已。
\module main
接收输入并确认前提条件
确认值是正整数
\fork 输入是否妥当
\true 是
执行主处理
\false 否
作为错误返回给调用方
\return
返回结果
flowchart TB
accTitle: 最小示例的 DSL 所表示的处理流程
accDescr: 从 module 开始确认输入的前提条件,用 fork 按输入是否妥当分支,妥当则执行主处理并返回结果,不妥当则作为错误返回给调用方。
m["module main 的开始"] --> pre["接收输入并确认前提条件"]
pre --> fork{"输入是否妥当"}
fork -->|"是"| main["执行主处理"]
fork -->|"否"| err["作为错误返回(return)"]
main --> ret["返回结果"]
图3:最小示例的流程。从 module 开始把目的放在左侧,在 fork 的正下方并列放置 true 与 false 两个分支边。
2. 这个仓库解决的问题
如果只靠人工管理图表,容易出现下面这些问题。
- 图表与规范文本不一致
- 分支或层级的约束变得含糊
- 难以进行差异评审
在 MakingHCPChartSkill 中,把 HCP-DSL 作为 JSON 请求传入,由 hcp_render_svg.py 进行验证与绘制。
相同输入必定得到相同输出,因此这种结构很容易把图表纳入 CI 或评审流程。
flowchart TB
accTitle: 手绘图表的问题与用文本管理带来的解决
accDescr: 只靠人工管理图表会出现与规范文本不一致以及难以差异评审的问题,而把 HCP-DSL 作为 JSON 请求传入后 hcp_render_svg.py 会进行验证与绘制,相同输入可以得到相同的 SVG。
hand["只靠人工管理图表"] -.-> issue["不一致、含糊、难以差异评审"]
dsl["以 JSON 请求传入 HCP-DSL"] --> render["hcp_render_svg.py 进行验证与绘制"]
render --> svg["返回决定性的 SVG"]
svg --> ci["可以纳入 CI 与评审"]
图4:不再手工绘图,而是从文本形式的 HCP-DSL 决定性地生成 SVG,因此可以纳入差异评审和 CI。
3. 最快掌握仓库结构
目标仓库:https://github.com/gomurin0428/MakingHCPChartSkill
hcp-chart-svg-v2/SKILL.md技能的使用方法与限制(例如禁止同时指定renderAllModules与module等)。hcp-chart-svg-v2/scripts/hcp_render_svg.py验证 JSON 输入、解析 HCP-DSL 并返回 SVG 响应的主体程序。hcp-chart-svg-v2/references/规范参考、示例 request/response、示例 SVG。hcp-chart-svg-v2/scripts/hcp_xml_to_svg.py已废弃(deprecated)。目前使用hcp_render_svg.py。
flowchart TB
accTitle: 仓库的主要文件结构
accDescr: hcp-chart-svg-v2 目录下有写明技能使用方法与限制的 SKILL.md、主体脚本 hcp_render_svg.py,以及收录规范参考与示例的 references,旧脚本 hcp_xml_to_svg.py 已废弃。
root["hcp-chart-svg-v2"] --> skill["SKILL.md(使用方法与限制)"]
root --> script["scripts 下的 hcp_render_svg.py"]
root --> refs["references(规范与示例)"]
script -.-> old["hcp_xml_to_svg.py 已废弃"]
图5:入口是 SKILL.md,主体是 hcp_render_svg.py,规范与示例集中在 references 目录下。
4. 10 分钟上手(GCD 示例)
前提环境
| 项目 | 内容 |
|---|---|
| Python | hcp_render_svg.py 以 Python 3 运行。仓库中没有写明最低版本,但由于用到了 dataclasses 和 from __future__ import annotations,3.7 以上就可以运行 |
| 额外的包 | 不需要。 用到的是 argparse / json / logging / math / re / sys / dataclasses / pathlib / typing / xml.sax.saxutils,全都是标准库 |
| shell | 下面的命令以 Windows 的 PowerShell 为前提编写。如果出现乱码,请在执行前用 $env:PYTHONUTF8 = "1" 和 chcp 65001 明确指定 UTF-8 |
| Codex | 只有在 4.2 中把它部署为技能时才需要。不使用 Codex 时,4.2 可以跳过(4.3 之后只用脚本本身就能运行) |
4.1. 获取仓库
git clone https://github.com/gomurin0428/MakingHCPChartSkill.git
cd .\MakingHCPChartSkill
4.2. 将技能部署到本地 Codex
这里说的 Codex 是指 OpenAI 的编码智能体。$HOME\.codex(在 Windows 上是 C:\Users\<用户名>\.codex)是它的配置目录,仓库的 README 中介绍的步骤是把整个目录复制到它下面的 skills\<技能名>。这样处理之后,当你请求智能体“画一张 HCP 图表”时,它就会按照这份 SKILL.md 的步骤去调用渲染器。
Copy-Item -Recurse -Force .\hcp-chart-svg-v2 "$HOME\.codex\skills\hcp-chart-svg-v2"
这一步并不是必需的。 渲染器是一个接受 --input 与 --output 的独立脚本,因此不使用 Codex 的读者可以直接进入 4.3。
4.3. 从示例输入生成 SVG 响应
python .\hcp-chart-svg-v2\scripts\hcp_render_svg.py `
--input .\hcp-chart-svg-v2\references\example-gcd-request.json `
--output .\hcp-chart-svg-v2\references\example-gcd-response.json `
--pretty
4.4. 从响应 JSON 中提取 SVG
$r = Get-Content -Raw .\hcp-chart-svg-v2\references\example-gcd-response.json | ConvertFrom-Json
$r.svg | Set-Content -NoNewline -Encoding utf8 .\hcp-chart-svg-v2\references\example-gcd.svg
flowchart TB
accTitle: 上手环节中得到 SVG 之前的流程
accDescr: 把示例的请求 JSON 传给 hcp_render_svg.py 生成响应 JSON,再取出其中的 svg 属性并保存为 SVG 文件,展示这一连串的流程。
req["示例的请求 JSON"] --> py["执行 hcp_render_svg.py"]
py --> res["输出响应 JSON"]
res --> ext["取出 svg 属性"]
ext --> file["保存为 SVG 文件"]
图6:上手环节的流程。把请求 JSON 传给脚本,再把响应中的 svg 写出到文件。
4.5. 补充说明(输入限制)
- 当
renderAllModules=true时,不能指定module。 - 如果
diagnostics中存在error,svg或svgs就会为空。
5. 两个示例的读法
打开图表后,按下面的顺序移动视线就能读懂。
- 只把最左侧的一列从上往下读。 排在这里的是“要达成什么(目的)”,也就是整个处理的梗概
- 从关注的那一行往右追。 排在右侧缩进处的,是“如何达成(手段与细节)”这个目的的内容
- 用竖线(主干)确认父子关系。 主干连接同一深度的处理,并且绘制时不会穿过深度更浅的行
flowchart TB
accTitle: 阅读 HCP 图表时的视线移动方式
accDescr: 先把最左列从上往下读以把握整个处理的梗概,再从关注的行往右追去确认手段与细节,最后用竖线主干确认父子关系,展示这三个阶段的读法。
s1["把最左列从上往下读"] --> a1["把握整个处理的梗概"]
a1 --> s2["从关注的行往右追"]
s2 --> a2["确认手段与细节"]
a2 --> s3["用竖线(主干)确认父子关系"]
图7:先在最左侧的目的列把握梗概,只在需要的行往右深入到手段,这就是读法的基础。
符号的含义如下。
| 符号 | 含义 |
|---|---|
| ○(圆圈) | 普通的处理 |
| 双圆圈 | 调用模块或函数(\mod) |
| 圆圈中带循环箭头 | 循环(\repeat) |
| 圆圈中带朝右的三角形 | 分支的父节点(\fork) |
| 从主干向右伸出的箭头 | 分支的分支边(\branch / \true / \false)。条件写在箭头右侧 |
| 朝下的三角形 | 退出(\return) |
| 圆圈中带 × | 错误检查(\ec) |
| 两个小圆圈 | 错误出口(\ex) |
5.1. 欧几里得算法(GCD)
- 输入示例:
example-gcd-request.json - 输出示例:
example-gcd-response.json
“接收输入”“循环”“返回”以层级方式分离,这种结构使处理的目的与手段都很容易追踪。
只读最左侧的一列,就是“接收输入值并做好计算准备 → 在还有余数时逐步逼近最大公约数 → 把结果返回给使用者”这 3 行,仅凭这些就能看懂算法的梗概。像 r <- a mod b 这样具体的计算,则是从循环内部的“决定要传递给下一轮的值”再往右缩进一级放下去的。这种位置关系本身就是“目的(左)与手段(右)”的对应。如果最左侧突然出现 r <- a mod b,那就是违反描述粒度约定(1.1)的信号。
flowchart TB
accTitle: GCD 示例最左列所呈现的梗概
accDescr: GCD 示例最左列是接收输入值并做好计算准备、在还有余数时逐步逼近最大公约数、把结果返回给使用者这 3 行,具体的计算被放到更右侧的缩进层级。
g1["接收输入值并做好准备"] --> g2["在还有余数时逐步逼近"]
g2 --> g3["把结果返回给使用者"]
g2 -.-> d1["具体的计算放到更右侧的层级"]
图8:GCD 示例的最左列。仅 3 行就能看懂算法的梗概,计算的细节则往右下沉。
图上部的 Data: 行,以及挂在节点下方的 in: / out: 标注,也是阅读时的线索。在这张图里标着 in: a, b 和 out: a,只看图就能知道入口和出口在哪里。
5.2. 订单审批流程
- 输入示例:
example-order-approval-request.json - 输出示例:
example-order-approval-response.json
即使是业务流程,也可以用 fork 与 true/false 明确地描述分支的意图。
这张图的最左列同样只有“受理订单内容 → 判断能否发货 → 返回处理结果”这 3 行。库存查询、审批申请、发货登记这类偏实现的操作,全都放进了右侧的缩进。分支表现为从主干向右伸出的箭头,(是) / (否) 的下方分别挂着各自的处理。“缺货则退回、已审批则安排发货、否则挂起”这样的业务判断,只要沿着两处分支伸出的箭头走就能追踪清楚。
flowchart TB
accTitle: 订单审批示例中业务判断的分支
accDescr: 展示受理订单内容后判断能否发货,缺货则退回、已审批则安排发货、否则挂起这样的业务判断由两处分支表达出来。
o1["受理订单内容"] --> o2["判断能否发货"]
o2 --> f1{"是否缺货"}
f1 -->|"是"| back["退回"]
f1 -->|"否"| f2{"是否已审批"}
f2 -->|"是"| ship["安排发货"]
f2 -->|"否"| hold["挂起"]
图9:订单审批示例的业务判断。只要沿着两处分支走,就能追踪退回、安排发货、挂起各自的去向。
在评审业务规范时,可以把最左列拿来与相关方一起通读,右侧的细节则交给实现负责人去敲定,这样的分工会更容易。
6. 内部在做什么(HCP 图表)
把 execute_request 的处理流程用 HCP-DSL 写出来,会是下面这样。
\module main
接收请求并确认前提条件
验证输入 JSON 的必需字段
解析 DSL 并进行结构化
解读模块与层级
收集 diagnostics
根据诊断结果选择响应路径
\fork 是否存在 error
\true 是
返回空的 SVG 系 payload
\false 否
决定要绘制的模块
\fork renderAllModules 是否为 true
\true 是
生成所有模块的 SVG
组装包含 svgs 的响应 JSON
\false 否
生成单一模块的 SVG
组装包含 svg 的响应 JSON
将结果返回给调用方
下图是将上述 DSL 实际渲染后得到的图表。
7. 总结
HCP 图表的优势不仅在于作为图表容易阅读,更在于 可以以能够当作规范来管理的形式进行管理。
使用 MakingHCPChartSkill,可以在验证 HCP-DSL 的同时,一气呵成地生成 SVG。
如果要进一步尝试,建议把日常工作中的某一条处理规范用 HCP-DSL 写出来,边查看 diagnostics 边进行调整,这样更容易切实感受到引入它的效果。
参考资料
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
多线程实战最佳实践 Java 篇——虚拟线程时代的惯用做法
Java 多线程的惯用做法是不直接创建线程,而是交给 ExecutorService 与虚拟线程。本文梳理 synchronized 与 ReentrantLock 的取舍、基于中断的协作式停止、ConcurrentHashMap 的原子操作,直到 Swing 的 EDT ...
多线程实战最佳实践 C 语言篇——以 Win32 API 的方式安全编写
C 语言 × Win32 的多线程自有定式:用 _beginthreadex 创建线程、SRW 锁与条件变量、Interlocked,以及停止事件 + WaitForMultipleObjects 的停止设计。本文还梳理 TerminateThread 的危险与 DllMa...
多线程实战最佳实践 C++ 篇——用 RAII 和 jthread 从结构上杜绝问题
C++ 的多线程里数据竞争就是未定义行为。本文梳理 std::thread 析构函数的陷阱、jthread 与 stop_token 的停止设计、scoped_lock 的死锁规避、atomic 的正确定位,直到与 Win32 同步 API 的区分使用。
多线程实战最佳实践 .NET 篇——增加线程之前必须先定好的事
面向 .NET/C# 梳理防止“线程一开就偶尔崩溃、偶尔卡死”的设计做法,涵盖不自己创建线程而依托 Task、减少共享可变状态、加锁的纪律、用 CancellationToken 设计停止流程,直到 UI 线程的处理方式。
不要直接使用 QR 码的读取值——纠错通过也不保证值是正确的
QR 码的纠错并不是一种只要纠错通过就保证值正确的机制。本文基于样本图像和两种解码器的实测,讲解污损落点不同会被读成另一个值的原因,以及业务系统一侧必须做的验证。
相关主题
与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。
Windows 技术主题
汇整 KomuraSoft LLC 关于 Windows 开发、故障调查与既有资产活用文章的主题中心。
常见问题
汇总了咨询这一主题时常见的问题。
- 什么是 HCP 图表?
- HCP 图表是一种以层级方式描述处理流程的表达形式。左侧写“要达成什么(目的)”,右侧更深的缩进处写“如何达成(手段与细节)”,最上层(level 0)写目的标签。按照这套规则书写文本,可以让设计意图与实现细节之间的对应关系变得容易阅读。
- MakingHCPChartSkill 是做什么的工具?
- 它是一个技能仓库,按照规范解析 HCP-DSL(文本),并返回决定性的 SVG。把 HCP-DSL 作为 JSON 请求传入后,由 hcp_render_svg.py 进行验证与绘制。相同输入必定得到相同输出,因此这种结构很容易把图表纳入 CI 或代码评审流程。
- 与手工管理图表相比有什么不同?
- 如果只靠人工管理图表,容易出现图表与规范文本不一致、分支或层级的约束变得含糊、难以进行差异评审等问题。而通过 HCP-DSL 这种文本以决定性方式生成 SVG 的方式,可以把图表作为规范来管理,并可以一边查看 diagnostics 一边进行调整。
- 使用上有哪些限制?
- 当 renderAllModules=true 时,不能同时指定 module。此外,如果 diagnostics 中存在 error,svg 或 svgs 就会为空。脚本方面,hcp_xml_to_svg.py 已被标记为 deprecated,目前应使用 hcp_render_svg.py。