更新紀錄(2 筆,最後更新 2026年09月04日)
本文的修改紀錄。已保存的更新前版本,可透過附有 DOI 的永久連結閱讀。
引用本文(DOI: 10.5281/zenodo.21616235)
本文保存於 Zenodo。以下同時提供一律指向最新版本的 DOI,以及固定於您正在閱讀版本的 DOI。
Go Komura(2026)。〈HCP 圖表與 MakingHCPChartSkill 入門〉。小村軟體有限公司。https://doi.org/10.5281/zenodo.21616235 https://comcomponent.com/zh-TW/blog/2026/02/22/000-what-is-hcp-chart-and-making-hcp-chart-skill/
- DOI(最新版本)
- 10.5281/zenodo.21616235
- DOI(此版本)
- 10.5281/zenodo.22297066
目錄
想把 HCP 圖表變成「能當成規格來讀的圖」時,只靠手繪的圖會很難維運。
MakingHCPChartSkill 是一個 Skill 儲存庫,用途是依照規格解讀 HCP-DSL(純文字),並回傳決定性的 SVG(意思是同樣的輸入永遠會產生同樣的 SVG)。
本文從 HCP 圖表的基本概念開始,一路帶到實際跑起來為止。
圖中實線表示始終成立的關係,虛線表示附帶條件的關係(成立條件寫在詳細頁面中各關係的說明中)。關係的完整清單(共 14 條,附依據與可信度)以及主要概念的定義,彙整在知識地圖詳細頁面(日文)。資料:JSON-LD / Turtle
1. 什麼是 HCP 圖表
HCP 圖表是一種以階層方式描述處理流程的表達方式。 在這個儲存庫裡,下列寫法被當成必須遵守的規則。
- 左側是「要達成什麼(目的)」
- 右側(較深的縮排)是「如何達成(手段與細節)」
- 最上層(第 0 層)寫目的標籤
依照這個規則撰寫文字,設計意圖與實作細節之間的對應關係就會變得容易讀出來。
flowchart TB
accTitle: HCP 圖表撰寫的基本規則
accDescr: 顯示最上層的第 0 層只寫目的標籤,左側寫要達成什麼的目的,右側較深的縮排寫如何達成的手段,藉此讀出設計意圖與實作細節之間對應關係的圖。
l0["第 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) - 「第 0 層只寫目的標籤,指派或比較這類接近程式碼的寫法一律下移到子節點」的 描述粒度規範。這是儲存庫這一側訂為必須遵守的規則,並不是 HCP 圖表通用的規定
flowchart TB
accTitle: 區分通用記法與儲存庫特有的部分
accDescr: 顯示 HCP 圖表這種圖法本身是橫須賀電氣通訊研究所做出來的既有記法,而這個儲存庫特有的只有 HCP-DSL 與其解讀規格,以及描述粒度規範這兩項的圖。
general["HCP 圖表(既有的圖法)"] --> repo["MakingHCPChartSkill 特有的部分"]
repo --> dsl["HCP-DSL 與解讀規格"]
repo --> conv["描述粒度的規範"]
conv -.-> rule["第 0 層只寫目的標籤"]
圖 2: 記法本身是早就存在的圖法,這個儲存庫特有的只有 HCP-DSL 與描述粒度規範這兩項。
1.2. HCP-DSL 的寫法(語法速查表)
寫法的全貌,用下面幾張表大致就夠了。詳細規格整理在 references/hcpchartspec.md,只要重點的話則在 references/hcp-chart-schema.md。
行的種類
| 行的形式 | 處理方式 |
|---|---|
| 空行 | 會被忽略 |
開頭(不含空白)為 # 的行 |
視為註解並忽略 |
開頭(不含空白)為 \ 或 ¥ 的行 |
指令行。指令名稱到第一個半形空格為止,之後的部分是引數 |
| 上述以外 | 畫成一般的處理節點(圓形) |
縮排(階層)
| 規則 | 內容 |
|---|---|
| 1 個階層的單位 | 一個 Tab,或是 4 個半形空格 |
| 不完整的縮排 | 像 2 個空格這種縮排單位會變成 error |
| 一口氣加深 | 比前一行深 2 階以上會變成 error。要一階一階往下 |
指令
| 指令 | 意義 | 注意 |
|---|---|---|
\title / \author / \date / \version |
標頭資訊 | 寫在 \module 之前就是所有模組共用,寫在之後則只覆寫該模組 |
\module <名稱> |
模組的開始 | 必填。只能寫在第 0 層。同名的模組會是 error |
\mod <標籤> |
呼叫模組或函式 | 在圖上畫成雙圓 |
\repeat <標籤> |
重複 | 要重複的內容往下寫一階 |
\fork <標籤> |
分支(分派)的父節點 | 分支的去向放在正下方 |
\true <標籤> / \false <標籤> |
真假二選一的分支 | 只能放在 \fork 的正下方(只深一階的位置)。祖先中沒有 \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["把 HCP-DSL 以 JSON 請求傳入"] --> 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.mdSkill 的使用方式與限制(例如禁止同時指定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 使用方式與限制的 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 要以 Skill 形式放置時才需要。不使用 Codex 的話,4.2 可以跳過(4.3 之後只靠指令碼本身就能執行) |
4.1. 取得儲存庫
git clone https://github.com/gomurin0428/MakingHCPChartSkill.git
cd .\MakingHCPChartSkill
4.2. 把 Skill 放到本機的 Codex
這裡說的 Codex,是指 OpenAI 的程式開發代理程式(coding agent)。$HOME\.codex(在 Windows 上是 C:\Users\<使用者名稱>\.codex)就是它的設定目錄,而儲存庫的 README 說明的步驟,是把整個目錄複製到底下的 skills\<Skill 名稱>。這樣安排之後,當你請代理程式「畫一張 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 ...
多執行緒實務最佳實踐 C 語言篇 ── 以 Win32 API 的方式安全撰寫
C 語言 × Win32 的多執行緒有其定石:以 _beginthreadex 建立執行緒、SRW 鎖與條件變數、Interlocked、以停止事件 + WaitForMultipleObjects 設計停止流程。本文一併整理 TerminateThread 的危險性與 D...
多執行緒實務最佳實踐 C++ 篇 ── 以 RAII 與 jthread 從結構上消除事故
C++ 的多執行緒是資料競爭會變成未定義行為的世界。本文整理 std::thread 解構函式的陷阱、以 jthread 與 stop_token 設計停止機制、scoped_lock 的死結迴避、atomic 的正確定位,以及與 Win32 同步 API 的使用區分。
多執行緒的實務最佳實踐 .NET篇 ── 在增加執行緒之前先決定的事
針對 .NET/C# 整理能防止「建立執行緒後偶爾當機、卡死」的設計定石。內容涵蓋不自行建立執行緒而改用 Task、減少共享可變狀態、鎖的紀律、以 CancellationToken 設計停止機制,以及 UI 執行緒的處理方式。
不能直接使用QR Code的讀取值 ── 錯誤更正通過不代表值就正確
QR Code的錯誤更正,並不是一套「只要更正通過就保證值正確」的機制。本文以樣本圖片與兩種解碼器的實測為依據,說明髒污落點不同就會被讀成另一個值的原因,以及業務系統端必須做的驗證。
相關主題
與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。
Windows 技術主題
彙整 KomuraSoft LLC 關於 Windows 開發、故障調查與既有資產活用文章的主題中心。
常見問題
整理諮詢這個主題時常見的問題。
- HCP 圖表是什麼?
- 這是一種以階層方式描述處理流程的表達方式。左側寫「要達成什麼(目的)」,右側較深的縮排寫「如何達成(手段與細節)」,最上層(第 0 層)則寫目的標籤。依照這個規則撰寫文字,設計意圖與實作細節之間的對應關係就會變得容易讀出來。
- MakingHCPChartSkill 是做什麼的工具?
- 它是一個 Skill 儲存庫,負責依照規格解讀 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。