Articraft 完整教學 — Agentic 系統做 articulated 3D asset 生成

⚠️ 重要資安提醒:Articraft 會把 LLM 生成的 model.py 當 Python 程式碼直接執行(local compile + probe + viewer materialization)。絕對不要直接跑來源不明的 record / 對抗性 prompt 生成的 record。建議用 disposable VM / Docker container / 雲端隔離環境。詳見第 6 節。

對應 metadata 報告:2026-05-17-github-mattzh72-articraft.md 對應 HTML:projects/articraft/quarkdown-out/02-tutorial/index.html


1. 專案定位

1.1 一句話定位

articulated 3D asset (具關節 3D 物件,如桌燈、風扇、書櫃) 的生成,從「人工在 Blender 拉了好幾天」變成「LLM 寫一段 Python 程式 → 跑出 URDF + mesh」,並把這個 loop 做成可規模化的 dataset 生成 pipeline。

1.2 為什麼這個專案值得關注

一般 3D 生成(Trellis / Hunyuan3D / DreamFusion 等)Articraft 走的路
直接學從 prompt → 3D mesh(NeRF / GS / mesh decoder)LLM 寫 Python 程式 → SDK 編譯成 URDF
通常產出 rigid mesh(一塊整體)產出 articulated 物件(有可動關節 + 物理)
Dataset 通常從 ShapeNet / Objaverse 抓自己 agentic 生,paper 宣稱 final 4-5 star set 「over 10K」
不易 audit / edit因為是程式碼,可 git diff / fork / 重編

💡 對「想做 robot manipulation / sim2real / SAPIEN-style task」的人,articulated dataset 比 rigid mesh 重要 100 倍。

1.3 系統長相(4 層)

 1┌─────────────────────────────────────────────────────────────┐
 2│ Layer 4: Frontend                                           │
 3│  └─ viewer/web (React + TypeScript + Three.js + shadcn/ui)  │
 4│                                                             │
 5│  Layer 3: Local API                                         │
 6│  └─ viewer/api (FastAPI, port 8765)                         │
 7├─────────────────────────────────────────────────────────────┤
 8│ Layer 2: Generation Runtime                                 │
 9│  ├─ agent/harness.py + single_run.py (multi-turn tool loop) │
10│  ├─ agent/compiler.py (model.py → URDF + mesh)              │
11│  ├─ agent/batch_runner.py (CSV-driven 並行)                 │
12│  ├─ agent/feedback.py (compile error → 餵回 LLM)            │
13│  └─ agent/providers/ (OpenAI / Gemini / Anthropic / OR)     │
14├─────────────────────────────────────────────────────────────┤
15│ Layer 1: SDK + Storage                                      │
16│  ├─ sdk/v0 (LLM 寫程式用的 articulated SDK)                │
17│  ├─ sdk/_docs + _examples (餵 agent 的上下文)              │
18│  └─ storage/ (canonical layout + SQLite search index)       │
19└─────────────────────────────────────────────────────────────┘
2021              data/records/<record_id>/
22              ├─ record.json
23              ├─ revisions/<revision_id>/
24              │   └─ model.py
25              └─ collections/...

1.4 何時該用、何時不該

適合不適合
想做 robot manipulation / RL sim 環境 的關節物件 dataset想要 photo-realistic texture(Articraft 偏 geometry,texture 較簡單)
想學「LLM 自我修正 code」的工程範本(feedback loop)想直接拿來商業生產(Alpha 階段,#56 待解:dataset 還在 git 內)
想用 多 provider(OpenAI / Gemini / Claude / OpenRouter)做生成沒有 disposable VM / 容器(生成的 code 會在你機器上 exec)
想用 Claude Code 等外部 agent 貢獻資料(不需 API key)沒有 Python 3.11 / 3.12 環境(3.13+ 不支援)

2. 安裝指南

2.1 Prerequisites

  • Python 3.12(recommended,3.11 也可;3.13+ 暫不支援)
  • uv ≥ 0.9.17(justfile 強制 version 檢查)
  • just (command runner)
  • npm + Node.js(optional,但要 viewer 前端必需)
  • Provider API key 任一OPENAI_API_KEY / GEMINI_API_KEYS / ANTHROPIC_API_KEYS / OPENROUTER_API_KEY(或都不用:走 EXTERNAL_AGENT_DATA.md 走 Claude Code)

2.2 安裝步驟

 1# 1. clone
 2git clone https://github.com/mattzh72/articraft.git
 3cd articraft
 4
 5# 2. 一鍵 setup(會檢查 uv 版本、sync deps、裝 pre-commit、init)
 6just setup
 7
 8# 3. 設 API key
 9cp .env.example .env
10vi .env
11# OPENAI_API_KEY=sk-...
12# 或 GEMINI_API_KEYS=AIza...,AIza...
13# 或 ANTHROPIC_API_KEYS=sk-ant-...

2.3 沒 API key?走外部 agent 路線

把這個 repo 給 Claude Code / Codex / Cursor,提示:

Create a realistic articulated [object name] and add it to the Articraft dataset. Follow EXTERNAL_AGENT_DATA.md.

外部 agent 會走 uv run articraft external ... 指令鏈完成 record 寫入。

2.4 驗證安裝

1uv run articraft status         # 顯示目前 dataset / hooks / env 狀態
2uv run articraft env bootstrap  # 重建 .env 模板(不會覆蓋既有 secrets)
3uv run articraft hooks check    # 檢查 git hooks 是否正確安裝
4just smoke-tests                # 跑核心 pytest 子集

3. 核心架構解析

3.1 agent/ — 27 個 .py,是整套系統的心臟

檔案大小角色
harness.py56 KBmulti-turn LLM tool loop;最重要的一個檔
single_run.py26 KB單一 generation run 的 orchestrator
batch_runner.py62 KBCSV-driven 批次(資源/併發/resume)
compiler.py44 KB執行 model.py → 產 URDF + mesh
feedback.py47 KBcompile 失敗時把錯誤訊息結構化餵回 LLM
record_persistence.py33 KBrecord 寫盤 / 版本管理 / fork
examples.py23 KBLLM 上下文裡的範例組裝
providers/OpenAI / Gemini / Anthropic / OpenRouter adapter
tools/LLM 可呼叫的 tool schemas(含 probe_model 子程序)
prompts/各 provider / profile 的 system prompts

3.2 sdk/ — 給 LLM 寫程式用的 SDK

1sdk/
2├── v0/              # 公開 import surface(agent 程式碼 import 這層)
3├── _core/           # 內部 geometry / export / 共用邏輯
4├── _docs/           # LLM 看的 SDK 教學(auto-injected to prompt)
5├── _examples/       # LLM 看的範例(auto-injected to prompt)
6├── _extensions/     # 擴展點
7└── _profiles.py     # 多個 profile(不同 abstraction level)

💡 設計亮點:sdk/_docs/ 是 LLM 的「閱讀材料」。要改 LLM 寫程式的行為,去改 _docs/ 比改 prompt 有效。

3.3 cli/ — 11 個 .py

檔案大小角色
main.py31 KBarticraft CLI 入口(subcommand router)
dataset.py55 KBarticraft dataset run / batch / validate / manifest / category / record
compile_all.py50 KBarticraft compile-all(並行重編所有 record)
external.py36 KBarticraft external ...(外部 agent 用的安全包裝)
workbench.py14 KBworkbench search-index
hooks.py10 KBgit hooks 安裝與檢查
pre_commit.py5.8 KBpre-commit 內部用:forbidden-paths / secrets / data-check
env.py3.0 KB.env 模板與 provider key 名單

3.4 storage/ — canonical layout

  • data/records/<record_id>/:canonical(內含 record.json + revisions/<revision_id>/model.py + 可選 collections/
  • data/categories/ / data/supercategories.json:分類層級
  • data/batch_specs/<batch-id>.csv:tracked 批次規格
  • data/cache/manifests/ + record_materialization/<record_id>/:可重新生成的快取(URDF / 編譯報告 / viewer assets)
  • data/cache/search/:SQLite 搜尋索引

3.5 viewer/ — 136 檔,React + TS + Tailwind + Three.js

  • viewer/api/ — FastAPI(app.pyfile_manager.pystore_stats.py
  • viewer/web/ — React + TS + Tailwind v4 + shadcn/ui,bundler 用 Vite
  • just viewer → 一次性 build + serve;just viewer-dev → Vite dev server + uvicorn 並存

3.6 LLM tool loop 內部運作(簡化版)

11. harness  prompt + sdk/_docs + 既有 record 範例 組成 system prompt
22. provider adapter 呼叫 LLMOpenAI / Gemini / Anthropic / OpenRouter
33. LLM tool call  例如 probe_model(試跑一段 code
44. probe_model 在「子程序」內 exec(code),回傳結果或錯誤
55. feedback.py 把錯誤結構化(tracebackSDK 違規、URDF 警告)
66. 回到 step 2,給 LLM 修正
77. 收斂後  compiler.py  model.py 編譯成 URDF + mesh
88. record_persistence.py 寫到 data/records/<id>/
99. (可選)viewer materialization:產 viewer assets

💡 這個 loop 的 feedback structure 是 paper 的關鍵貢獻之一;不只是「compile failed」,而是分類成 SDK error / URDF warning / geometry issue 等,方便 LLM 修正。


4. Helper Scripts 詳細用法

4.1 articraft generate — 最常用

1uv run articraft generate "Create a realistic articulated desk lamp with a weighted base, two hinged arms, and an adjustable lamp head."

預設 --model gpt-5.5-2026-04-23 --thinking-level high。可改:

1uv run articraft generate --model gemini-3-flash-preview --max-cost-usd 1.5 "Create a compact desk fan with adjustable tilt."
2uv run articraft generate --image reference.png --provider anthropic "..."

4.2 articraft fork — 編輯既有 record

1uv run articraft fork data/records/<record_id> "make the handle longer"

不會改原 record,只生成 child record。

4.3 articraft dataset batch — 大規模生成

 1# 建一個批次規格
 2uv run articraft dataset batch-new my-batch-001
 3
 4# 編輯 data/batch_specs/my-batch-001.csv(required columns: category_slug / prompt / provider / model_id / thinking_level / max_turns)
 5
 6# 跑
 7uv run articraft dataset batch data/batch_specs/my-batch-001.csv \
 8  --row-concurrency 8 --subprocess-concurrency auto
 9
10# 失敗中斷後 resume
11uv run articraft dataset batch data/batch_specs/my-batch-001.csv --resume
12uv run articraft dataset batch data/batch_specs/my-batch-001.csv --resume --resume-policy failed_only

💡 Batch CSV v1 不支援 image_path;要圖片條件得走單一 generate 命令。

4.4 articraft compile-all — 重編所有 record

1uv run articraft compile-all                           # 全部 visual-only
2uv run articraft compile-all --target full             # 包含 collision-inclusive URDF
3uv run articraft compile-all --target full --strict    # 驗證重的,會失敗整個批次
4uv run articraft compile-all --target visual --force --limit 50  # 強制重編前 50 個

4.5 articraft viewer — 開瀏覽器看

1just viewer              # build + serve,瀏覽器開 http://127.0.0.1:8765
2just viewer-dev          # uvicorn + vite dev server

4.6 articraft env / hooks / status / data check

維護用:env 模板、git hooks 安裝、整體狀態、data canonical 驗證。


5. 應用場景

5.1 跑一張桌燈當 hello world

1just setup
2echo "OPENAI_API_KEY=sk-xxx" >> .env
3uv run articraft generate "Create a realistic articulated desk lamp with a weighted base, two hinged arms, and an adjustable lamp head."
4just viewer

打開瀏覽器到 http://127.0.0.1:8765,能看到 desk lamp + joint controls + dataset metadata。

5.2 用 Claude Code 貢獻 dataset(不需 API key)

把 repo 給 Claude Code,提示:

Create a realistic articulated office chair (with adjustable height, tilting back, rotating base) and add it to the Articraft dataset. Follow EXTERNAL_AGENT_DATA.md.

Claude Code 會走 uv run articraft external ... 指令鏈完成 record。

5.3 跑 1000 個物件的大批次

  1. articraft dataset category upsert 建好分類
  2. data/batch_specs/batch-001.csv(1000 行)
  3. articraft dataset batch ... --row-concurrency 8
  4. 中斷後 --resume
  5. articraft dataset validate + articraft dataset manifest
  6. articraft compile-all --target full

5.4 把 SDK 抽出來給自己用

1from sdk.v0 import Cylinder, Box, RevoluteJoint  # 概念示意
2# 自己寫 articulated object,不走 LLM

sdk/v0/ 是穩定的公開介面;sdk/_core/ 是 internal。

5.5 接 RL / sim 環境

生成完的 data/cache/record_materialization/<id>/ 內含 URDF,可以直接餵 PyBullet / MuJoCo / Isaac Sim / SAPIEN。


6. 資安掃描報告

掃描範圍:agent/sdk/cli/viewer/articraft/;方法:grep -rnE 對 eval/exec/subprocess/secrets/http;資料夾 data/ 已排除(86,803 檔,是 dataset 不是程式碼)。

🔴 整體:中–高風險(核心模型就是 LLM 生程式 + 本機 exec)

項目風險證據緩解
compiler.pyimportlib.import_module()model.py🔴 agent/compiler.py:69 直接 import LLM 生成的 module;compile-all 會跑全 dataset必須在 disposable VM / Docker 內跑;不要本機跑陌生 record
probe_model/runner.pyexec(compiled, ns, ns)🟡 中LLM tool call 試跑 code;在 subprocess 內(有 timeout、redirect stdout/stderr)但沒有 namespace / capability 限制subprocess 隔離不等於 sandbox;應加 firejail / Docker / seccomp
subprocess 廣泛使用🟢 低agent/run_context.pycli/main.pyviewer/api/cli/hooks.py全部 argv form,無 shell=TrueOK
viewer/api/file_manager.pyopen / xdg-open 開檔案🟢 低argv form;只開 local file 路徑OK;確認傳給 file_manager 的 path 是已驗證的 record path
無對外 HTTP 呼叫🟢 低urllib.request / requests.get/post / httpx 在生產碼中 0 hit(只在 LLM provider SDK 內,由 SDK 自己管)OK
API key 處理🟢 低cli/env.py 只列名單;agent/providers/factory.py 從 env 讀;無寫死值OK
Pre-commit hooks🟢 低內建 forbid-sensitive-pathsscan-staged-secretsdata-check、ruff format/check、viewer lint/typecheck;pre-push 跑 smoke tests已完善;新貢獻者請 just setup 後再 commit
SECURITY.md 明確警告🟢 文件直白告知 model.py 會被 exec;建議 disposable VM文件做得好

重點觀察

  1. 這個專案的安全邊界是「使用者本機 / VM」,不是「runtime sandbox」。也就是說,所有信任都建立在「你選擇要不要跑這個 record」
  2. 跟其他「LLM 寫 code」專案比(如 OpenInterpreter、code_executor):Articraft 沒有 docker-sandbox 預設;probe_model 雖然在子程序內,但沒有限制 import / fs / network。
  3. pre-commit 機制完整:forbidden-paths 阻擋 .envdata/cache/、workbench-only records 等;secret scanner 掃 staged content。
  4. 沒有 outbound HTTP 漏洞:核心碼沒打外部 IP / 服務(LLM provider 走官方 SDK)。

給導入團隊的清單

  • 第一條鐵律:跑任何陌生 record / 對抗性 prompt 生成的 record 前,先進 Docker / VM
  • 在 disposable container 內:限 network(--network none 跑 compile)、限 fs(read-only mount,/tmp 為 tmpfs)、限 CPU/memory
  • 公司部署:把 agent/tools/probe_model/tool.py 的 subprocess 換成 docker runfirejail
  • data/records/ 來自外部貢獻者:先在 CI 內隔離環境跑 compile,pass 再 merge
  • CI 啟用 secret scanner(pre-commit 已含,CI 也跑一遍)
  • viewer/web 對外開放前先審 viewer/api/file_manager.py,避免 path traversal

7. FAQ

Q1. Articraft 跟「直接用 Trellis / Hunyuan3D」差在哪? A:Trellis 系列產 rigid mesh(一塊整體);Articraft 產 articulated 物件(有關節 + URDF + 物理)。Articraft 對 機器人 / sim 場景 是降維打擊。

Q2. 沒 GPU 跑得起來嗎? A:跑得起來。Articraft 主要計算在 LLM(雲端 API)+ CadQuery / trimesh(CPU geometry);viewer 走 Three.js 在瀏覽器跑。

Q3. 一個 record 大概要花多少? A:取決於 provider + model。一張桌燈用 gpt-5.5 thinking=high 大概 1–3 USD;用 gemini-3-flash-preview --max-cost-usd 1.5 可以壓到 $1 內。

Q4. 為什麼 Python 3.13 不能用? A:依賴 cadquery / manifold3d / python-fcl 等 C 擴展套件,當前 release 還沒對 3.13 提供 wheel。請用 3.12。

Q5. 怎麼把 dataset 抽出去用? A:直接讀 data/records/<id>/revisions/<rev>/model.py 拿 source code;data/cache/record_materialization/<id>/ 拿 URDF + meshes。注意:dataset 採 CC-BY 4.0,需標註原作者。

Q6. Issue #56「Move dataset outside of git」是 blocker 嗎? A:對 clone 速度有影響(87,328 個檔,clone 時要 update files 走進度條好幾秒),但目前 still works。等他們搬到 git-lfs / 外部 hosting 後速度會好很多。

Q7. 我可以只用 SDK 不用 LLM 嗎? A:可以!sdk/v0/ 是穩定公開 API;直接 from sdk.v0 import ... 自己寫 articulated object,然後 articraft compile data/records/<id> 編譯。


8. 進階技巧

8.1 自訂 system prompt / authoring docs

agent/prompts/sdk/_docs/sdk/_docs/ 會被自動拼進 LLM 上下文,是改 LLM 行為最有效的點。

8.2 加新 provider

agent/providers/ 下加 <name>.py(模仿 openai.py / anthropic.py 結構:<name>_api_key_from_env + LLM client class),然後在 factory.py 加 router 分支。

8.3 加新 tool 給 LLM

agent/tools/<name>/tool.py + runner.py(runner 跑在子程序),然後在 tool schema 註冊。probe_model/ 是現成範本。

8.4 把 compile 放進 Docker(資安強化)

1# Dockerfile.articraft-sandbox
2FROM python:3.12-slim
3RUN pip install uv
4WORKDIR /work
5COPY pyproject.toml uv.lock ./
6RUN uv sync --frozen
7COPY . .
8USER nobody
9ENTRYPOINT ["uv", "run", "articraft", "compile"]
1docker run --rm --network none --read-only --tmpfs /tmp \
2  -v "$(pwd)/data:/work/data:rw" \
3  articraft-sandbox data/records/<id>

8.5 把 viewer 部署到內網

viewer/api/ 是 FastAPI;把 viewer/web/ build 成靜態檔(npm --prefix viewer/web run build),用 nginx serve,FastAPI 跑 backend。注意:file_manager 的 open / xdg-open 在 server 環境不會 work,要拿掉或改成只下載。

8.6 接其他下游

  • PyBullet / MuJoCo:用 data/cache/record_materialization/<id>/<id>.urdf
  • Isaac Sim:URDF → USD(用 omni.importer.urdf
  • SAPIEN:直接吃 URDF

9. 整合進其他工作流

9.1 與本知識系統的關係

上層 skill整合方式
ai-gh-save / gh-tutorial-qd本教學的產出 skill
graphifyagent/ + cli/ + sdk/ 整包跑 graphify,看 tool 之間呼叫
paper-searchpaper read: doi:10.48550/arXiv.2605.15187 拿完整 paper 對照看設計
ai-notebooklm把 paper + CLAUDE.md + AGENTS.md 餵 NotebookLM 做 Q&A
kami把 viewer 截圖整成 demo one-pager 給 PM

9.2 一個 demo 流程

  1. paper read: arxiv:2605.15187 → 看 paper 設計
  2. gh-tutorial-qd: https://github.com/mattzh72/articraft → 看完本教學
  3. Docker 內 just setup + articraft generate "..." 試跑一張
  4. graphify .agent/ 跑知識圖,看 harness/compiler/feedback 連結
  5. 想加新 provider → 找 agent/providers/factory.py

10. 重點摘要 Checklist

  • Articraft = LLM 寫 Python → 編譯成 URDF + mesh 的 agentic 系統
  • 安全模型基於「使用者選擇要不要跑」,沒有預設 sandbox;陌生 record 進 Docker / VM
  • 4 大子系統:agent/(runtime)+ sdk/(SDK 給 LLM 寫程式用)+ cli/(指令)+ viewer/(瀏覽器)
  • 4 個 provider:OpenAI / Gemini / Anthropic / OpenRouter
  • 無 API key 也能跑:用 Claude Code / Codex 走 EXTERNAL_AGENT_DATA.md
  • Python 3.12 only(3.13+ 暫不支援)
  • dataset CC-BY 4.0;code Apache-2.0
  • 大批次走 articraft dataset batch <csv>,可 resume
  • viewer 在 127.0.0.1:8765(React + Three.js)
  • pre-commit 機制完整:forbidden-paths + secret scan + data validation + ruff
  • 已知工程議題:data/ 太大(#56)、setup 不可選 root(#5)

11. 進一步閱讀


教學完成日:2026-05-17 | 對應 commit:20fff89(2026-05-15 main HEAD)| Generated by gh-tutorial-qd skill