Open source · Agent skill
Archify
เครื่องมือที่แปลงโค้ดเบสหรือคำอธิบายระบบให้เป็นแผนผังสถาปัตยกรรมแบบโต้ตอบได้ — โดยที่ AI ไม่ได้วาดรูป แต่เขียนข้อมูลที่มีชนิดกำกับ แล้วปล่อยให้ตัวตรวจสอบเป็นคนตัดสินว่าผลลัพธ์ใช้ได้หรือไม่
ทำไมต้องมีอีกเครื่องมือหนึ่ง
ปัญหาที่มันพยายามแก้
ถ้าเคยขอให้ AI วาดไดอะแกรมสถาปัตยกรรม จะเจอสองอาการเสมอ อย่างแรกคือได้ Mermaid ที่ถูกต้องเชิงตรรกะ แต่ auto-layout จับวางกล่องมั่ว เส้นตัดกันไปมา อ่านไม่รู้เรื่อง อย่างที่สองคือถ้าให้มันเขียน SVG เอง มันจะวางพิกัดผิด ตัวหนังสือทับเส้น กล่องซ้อนกัน และมันไม่มีทางรู้ตัว เพราะมันมองไม่เห็นสิ่งที่ตัวเองวาด
Archify แยกงานสองอย่างนี้ออกจากกันชัดเจน AI รับผิดชอบการตัดสินใจ — อะไรสำคัญ อะไรควรอยู่ตรงกลาง เส้นทางหลักคือเส้นไหน ควรเน้นตรงไหน — แล้วเขียนออกมาเป็น JSON ที่มี schema กำกับ ส่วนการแปลง JSON เป็นภาพเป็นหน้าที่ของคอมไพเลอร์ที่ทำงานแบบ deterministic และมีตัวตรวจสอบคอยกันไม่ให้ผลลัพธ์ที่อ่านไม่ออกหลุดออกไป
Generate → Validate → Preview → Deliver → Iterate
ไปป์ไลน์ทั้งเส้น
ขั้นที่ 03 เป็นทางเลือก · ขั้นที่ 04 ถ้าไม่ผ่าน ไฟล์เดิมที่ดีอยู่แล้วจะไม่ถูกแตะเลย
Typed intermediate representation
JSON IR หน้าตาเป็นอย่างไร
หัวใจของ Archify คือรูปแบบข้อมูลกลางที่ไดอะแกรมทั้ง 5 ชนิดมี schema ของตัวเอง ตัวอย่างข้างล่างตัดมาจากไฟล์จริงที่ผมใช้วาดระบบหนึ่ง จะเห็นว่า node บอกทั้งชนิดเชิงความหมาย ตำแหน่ง ขนาด และป้ายกำกับ ส่วนเส้นเชื่อมบอกต้นทางปลายทาง ข้อความ และระดับความสำคัญ
// architecture.schema.json — ตัดมาบางส่วน "components": [ { "id": "sheets", "type": "database", "label": "Google Sheets", "sublabel": "Marketing Hub", "pos": [545, 290], "size": [175, 76] }, { "id": "metamcp", "type": "security", "label": "Meta Ads Connector", "brand": "meta", "tag": "ยืนยัน 2 ชั้น", "pos": [545, 470], "size": [185, 68] } ], "boundaries": [ { "kind": "security-group", "label": "PAUSED to confirm", "wraps": ["metamcp"] } ], "connections": [ { "id": "claude-writes-sheets", "from": "claude", "to": "sheets", "label": "เขียนหลังยืนยัน", "variant": "emphasis" } ]
สิ่งที่ทำให้รูปแบบนี้ต่างจากการให้ AI พ่น SVG คือ type กับ variant
ไม่ใช่สี แต่เป็นความหมาย ตัวเรนเดอร์เป็นคนแปลความหมายนั้นเป็นสีและน้ำหนักเส้นให้เอง
ผลคือไดอะแกรมทุกใบในโปรเจกต์เดียวกันพูดภาษาภาพเดียวกัน และไฟล์ JSON ยังเป็นสิ่งที่แก้ทีละบรรทัดได้
โดยไม่ทำให้ส่วนอื่นเพี้ยน
ชนิด node ทั้ง 7 และสีที่ผูกไว้ตายตัว
ค่าสีจาก DESIGN.md ของรีโป (โหมดมืด) — เป็น enum ปิด เพิ่มชนิดเองไม่ได้
เลือกให้ตรงกับสิ่งที่อยากอธิบาย
ห้าชนิด ห้าคำถาม
| ชนิด | ตอบคำถามว่า |
|---|---|
| architecture | ระบบประกอบด้วยอะไร อะไรคุยกับอะไร ขอบเขตความปลอดภัยอยู่ตรงไหน |
| workflow | งานไหลผ่านใครบ้าง แตกกิ่งตรงไหน ข้อยกเว้นคืออะไร — CI/CD, การอนุมัติ, runbook |
| sequence | การเรียกหนึ่งครั้งเกิดอะไรขึ้นตามลำดับเวลา — API call, cache miss, auth |
| dataflow | ข้อมูลมาจากไหน ถูกแปลงอย่างไร ไปจบที่ไหน ข้อมูลอ่อนไหวข้ามเส้นตรงไหน |
| lifecycle | สถานะมีอะไรบ้าง retry กี่ครั้ง จบได้กี่แบบ |
ถ้าไม่แน่ใจว่าควรใช้อันไหน CLI มีคำสั่ง guide ที่รับคำถามเป็นภาษาคน
แล้วตอบว่าควรใช้ชนิดไหน พร้อมบอกว่าต้องเตรียมข้อมูลอะไรบ้าง
node bin/archify.mjs guide "Show an API request with Redis cache miss"
Deterministic validation
ส่วนที่น่าสนใจที่สุด คือตัวที่บอกว่าไม่ผ่าน
เครื่องมือ AI ส่วนใหญ่ส่งผลลัพธ์ออกมาแล้วหวังว่าจะดี Archify ไม่ทำแบบนั้น มันเรนเดอร์เป็นไฟล์ candidate ก่อน แล้วเอาไฟล์นั้นมาตรวจ 9 ข้อ ถ้าไม่ผ่านครบทุกข้อ ไฟล์เป้าหมายจะไม่ถูกเขียนทับ
และมันไม่ได้บอกแค่ว่าไม่ผ่าน — มันคืนรหัสกฎ ระบุ subject ที่ผิด แนบหลักฐานเป็นตัวเลขที่วัดได้จริง แล้วบอกว่าวิธีแก้ที่รองรับมีอะไรบ้าง ไม่ใช่โยน Node stack trace มาให้เดาเอง
[composition/ambiguous-corridor] connections[6] "metamcp" -> "marketingapi" shares a 73px corridor with connections[10] "appsscript" -> "line" at [1075, 411] -> [1075, 484] (minimum 8px) [composition/label-route-clearance] label "create-adjust-close" is 0px from another route (minimum 4px) Suggested fix: labelAt [810, 380] or labelDy +62 (below); or labelAt [810, 286] or labelDy -32 (above)
กฎที่โหดที่สุดคือ composition/desktop-readability มันจำลองว่าถ้าเปิดไฟล์นี้บนจอกว้าง
1440px ตัวหนังสือในกล่องจะเหลือขนาดกี่พิกเซลจริง ๆ แล้วบังคับว่าต้องไม่ต่ำกว่า 6px
ในการทำงานรอบหนึ่งของผม มันตีตกเพราะขาดไป 0.064 พิกเซล
"viewportWidth": 1440 "availableDiagramWidth": 930 "viewBoxWidth": 1410 "scale": 0.6595744680851063 "sourceFontPx": 9 "projectedFontPx": 5.936170212765957 "minimumProjectedFontPx": 6 supportedFixes: reduce the viewBox width · shorten node copy widen affected nodes · split the diagram
ผมย่อ viewBox จาก 1410 เหลือ 1370 แล้วรันใหม่ ครั้งนี้ receipt เปลี่ยนหน้าตาไปเลย
กลายเป็นตารางเมตริกที่บอกว่าเส้นตัดกันกี่จุด ระยะห่างต่ำสุดของป้ายกำกับเท่าไหร่
และเส้นที่หักเยอะที่สุดหักกี่ครั้ง
"status": "pass" "errors": 0 "warnings": 0 "properCrossings": 0 "ambiguousCorridors": 0 "containerBorderRuns": 0 "labelRouteClearanceIssues": 0 "minLabelRouteClearance": 6 (min 4) "desktopReadabilityIssues": 0 "maxBends": 3 (suggested 2) "maxStretch": 1.14 (suggested 1.35) "minSegmentPx": 24 (suggested 16)
Architecture Delta
เทียบสถาปัตยกรรมก่อนกับหลัง
ฟีเจอร์ที่น่าจะมีประโยชน์ที่สุดสำหรับทีมจริง ๆ คือ compare
มันรับ snapshot สองไฟล์ที่ผ่านการตรวจแล้ว สร้างมุมมอง Before / Delta / After
บอกว่ามี node ไหนถูกเพิ่ม ลบ แก้ ย้าย หรือเปลี่ยนเส้นทาง พร้อมใบเสร็จเป็น JSON
node bin/archify.mjs compare architecture base.json head.json out.html --json
จุดที่น่าชม คือมันจงใจไม่บอกว่าการเปลี่ยนแปลงนี้เสี่ยงหรือปลอดภัยพอจะ merge มันรายงานเฉพาะข้อเท็จจริงที่เขียนไว้ในไฟล์ ไม่อนุมานผลกระทบ ซึ่งเป็นท่าทีที่ถูกต้อง เพราะไดอะแกรมไม่รู้จักทราฟฟิกจริง
Self-contained artifact
ผลลัพธ์คือไฟล์ HTML ไฟล์เดียว
ไม่มี server ไม่มี CDN ไม่มี build step ส่งให้ใครก็เปิดได้ แต่มันไม่ใช่รูปนิ่ง ในไฟล์มี viewer ที่ตอบคำถามได้จากโครงสร้างที่เขียนไว้จริงเท่านั้น ไม่มีการเดาความสัมพันธ์เพิ่ม
| ปุ่ม | ทำอะไร |
|---|---|
| / | ค้นหาและโฟกัส node |
| R | ไล่เส้นทางแบบมีทิศทางระหว่างสอง node แล้วดูว่าผ่านอะไรบ้าง |
| L | เทียบทราฟฟิกระหว่างสองบทบาท เช่น backend กับ database |
| M | เปิดเรดาร์ภาพรวมสำหรับไดอะแกรมใหญ่ |
| P [ ] | เล่น guided story ทีละบท ตามที่ผู้เขียนกำหนดไว้ |
| F | โหมดพรีเซนต์เต็มจอ |
| S T E | สลับสไตล์ · สลับธีมสว่างมืด · เปิดเมนู export |
ทุกสถานะผูกกับ URL ได้ เช่น #route=web~db หรือ #focus=router&reach=downstream
ทำให้แปะลิงก์ใน PR แล้วคนเปิดมาเห็นมุมเดียวกันเป๊ะ ส่วน export มีทั้ง PNG, SVG, WebM
และ share card ขนาด 1200×630 สำหรับแปะ README โดยที่สถานะชั่วคราวของ viewer
จะไม่ติดไปกับไฟล์ที่ export
SRC n
ที่กดแล้วเปิดไปยังไฟล์และช่วงบรรทัดจริง โดยตรึงไว้กับคอมมิตเดียว
ส่วนไดอะแกรมที่ไม่ได้ขอหลักฐาน จะไม่มีป้ายนี้ปนมา
ต้องมีแค่ Node 18 ขึ้นไป
ลองเองใน 3 คำสั่ง
# ติดตั้งเป็น skill (Claude Code / Cursor / Codex CLI / opencode) npx skills add tt-a1i/archify -g # หรือ clone มาแล้วเช็คว่าพร้อมใช้ไหม git clone https://github.com/tt-a1i/archify.git node archify/bin/archify.mjs doctor # สร้างไฟล์ตัวอย่างไว้เปิดดู node archify/bin/archify.mjs demo ./out
รันไทม์ไม่พึ่งไลบรารีภายนอกเลย — ajv, parse5, saxes
และ simple-icons อยู่ใน devDependencies ใช้ตอนสร้าง validator กับ brand mark เท่านั้น
ตัวรีโปหนักราว 154 MB เพราะมี gallery ภาพประกอบ และไฟล์ทดลองรวมอยู่ ไม่ใช่ตัวโปรแกรม
ARCHIFY_UPDATE_CHECK_DISABLED=1
ขอบเขตที่ประกาศไว้ชัด
สิ่งที่มันไม่ใช่
รีโประบุตรง ๆ ว่าอะไรอยู่นอกขอบเขต ซึ่งช่วยประหยัดเวลาคนที่กำลังมองหาอย่างอื่น
- ×ไม่ใช่โปรแกรมวาดรูปแบบลากวาง ไม่มี WYSIWYG ต้องแก้ผ่านการคุยกับ agent หรือแก้ JSON เอง
- ×ไม่ parse Mermaid อัตโนมัติ (agent แปลงให้ได้ แต่ตัว CLI ไม่ได้อ่าน Mermaid)
- ×ไม่มี auto-layout แบบทั่วไป ตำแหน่งเป็นการตัดสินใจของ agent ไม่ใช่ของอัลกอริทึมจัดกราฟ
- ×ไม่มีบริการ hosting ให้แชร์ ผลลัพธ์คือไฟล์ที่ต้องเอาไปวางเอง
- ✓เหมาะกับ เอกสารสถาปัตยกรรมที่ต้องอัปเดตบ่อย · รีวิว PR ที่โครงสร้างเปลี่ยน · การอธิบายระบบให้ทีมหรือลูกค้าฟัง
จุดที่ควรรู้ก่อนใช้จริง คือคุณภาพผลลัพธ์ขึ้นกับความสามารถของ agent ที่เขียน JSON พอสมควร ตัวตรวจสอบกันเรื่องอ่านไม่ออกได้ แต่กันเรื่องข้อมูลผิดไม่ได้ ถ้า agent เข้าใจระบบผิด มันก็จะวาดผิดอย่างสวยงามและผ่านทุก check