关于 AnkusDrive
AnkusDrive 是 CLI 和 MCP 服务,让大模型及终端用户通过 Python API 操作 FreeCAD。它结合 CAD 建模、工程仿真、迭代工具和多 Agent 组件装配。
主要功能
- 01用于脚本和单次命令的 CLI
- 02结构化 FreeCAD 建模工具
- 03FEM 分析与结果读取
- 04覆盖多个领域的仿真工具
- 05设计修订与变更单
- 06多 Agent 组件装配
适用场景
- 01生成并检查机械零件
- 02对设计运行 FEM 分析
- 03协调多个 Agent 构建产品组件
MCP 相关
MCP 服务提供 280 多个结构化工具,用于建模、检查和仿真。Agent 可借此迭代 FreeCAD 设计。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
286收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
AnkusDrive
一款 CLI + MCP 服务,通过 FreeCAD 的 Python API 驱动它,让大模型(以及在终端中操作的人类)无需在 GUI 中逐步点击,即可设计机械零件并运行 FEM 仿真。
为什么要用
FreeCAD 几乎所有功能都通过 Python API 暴露出来——创建文档、构建草图、拉伸实体、生成网格、运行 CalculiX/Elmer FEM 求解,并读取应力/位移场。但该 API 位于 FreeCAD 内嵌的 Python(freecadcmd)中,从其他地方调用并不方便。AnkusDrive 提供了两个接口:
- CLI — 一次性命令(
ankusdrive run script.py、ankusdrive box --w 10 --d 20 --h 5 -o part.FCStd),适用于脚本、CI 和快速迭代。 - MCP 服务 — 280 多种结构化工具(
new_document、add_primitive、boolean_op、pad、add_gear、fem_new_analysis、fem_run、fem_results),让 LLM Agent 能够迭代地建模、检查和仿真。除了核心 CAD/FEM 功能,现在还涵盖广泛的仿真领域(热学、CFD/CHT、电磁、声学、FSI、注塑成型、颗粒/DEM、光学、多体系统)以及设计管控层(物料/零件编号、配方、变体系列、生命周期/修订、ECO 变更单、版本化接口)。 - 多 Agent 编排 — 主机端参考层,让一组 Agent 将一个产品拆分为多个组件,并行构建后再合并部件,且接合处能够实际契合(参见多 Agent 设计)。
目标环境
- FreeCAD 1.1.x。
freecadcmd二进制文件会按操作系统自动发现(macOS.appbundle、Linux/usr/bin等、WindowsC:\Program Files\FreeCAD 1.1\bin\freecadcmd.exe— 按版本匹配);可通过$ANKUSDRIVE_FREECADCMD覆盖,或依靠 PATH。运行ankusdrive doctor可查看具体解析结果。 - 内置 Python、
ccx(CalculiX)和gmsh已随每个 FreeCAD 安装提供——包括 macOS.app、Linux 软件包和 Windowsbin\——因此三种系统上都无需额外安装,即可使用核心 CAD 和结构 FEM 功能。 - 主机端渲染需要
Pillow和numpy;AnkusDrive 会将二者作为常规 pip 依赖安装。 - 一个可选例外:工程图的 PDF/SVG 导出(
export_drawing)在 FreeCAD 的内置 Python 中渲染,因此需要在该环境中安装reportlab+svglib——参见工程图导出(PDF/SVG)。DXF 导出及其他所有功能都不会改动 FreeCAD 的 Python 环境。
安装
AnkusDrive 是可通过 pip 安装的软件包;只有 FreeCAD 需要单独安装。主机端依赖项(mcp、Pillow、numpy)会随安装一并提供。freecadcmd 会作为子进程启动,并使用其自带的 Python——AnkusDrive 不会修改它。
# 1. Install FreeCAD 1.1.x from https://www.freecad.org/
# (macOS: drag to /Applications; Linux: distro package or AppImage;
# Windows: run the installer — default C:\Program Files\FreeCAD 1.1)
# 2. Install AnkusDrive. Pick one:
pipx install ankusdrive # from PyPI — isolated app, `ankusdrive` on PATH
pip install ankusdrive # or into an env you manage yourself
# unreleased main, or for development from a clone:
pipx install git+https://github.com/gchen19/AnkusDrive.git
git clone https://github.com/gchen19/AnkusDrive.git && cd AnkusDrive
python3 -m venv .venv && .venv/bin/pip install -e . # `.venv/bin/ankusdrive`
# 3. Smoke-test that the worker can reach FreeCAD, and see the full setup report
ankusdrive ping # → ping=pong freecad=1.1.1
ankusdrive doctor # per-item FreeCAD + solver checklist with the exact fix each
在 Windows 上,请勿手动执行上面的代码块——有一条脚本化安装路径可以完成所有操作,包括 MCP 注册: Windows 快速入门(PowerShell)。
AnkusDrive 已发布到 PyPI,地址为
pypi.org/project/ankusdrive;后续分发路线图(市场列表、托管传输)已记录在
epic #303;原始阶段计划作为设计记录保存在
docs/archive/PUBLISHING_PLAN.md。
macOS 快速入门 — 容器中的求解器
FreeCAD、CalculiX、SU2、PrusaSlicer 以及所有 pip wheel 系列都可以在 Mac 上原生运行;上面的代码块就是你运行它们所需的一切。Linux 求解器堆栈则没有实用的 macOS 构建版本,包括 OpenFOAM、Elmer、YADE、openEMS、Bempp、preCICE 和 openInjMoldSim。这些程序在容器中运行,AnkusDrive 则留在主机上并访问容器。该镜像支持多架构,因此在 Apple Silicon 上运行时是原生运行,而非模拟运行。
# 1. A container engine: Docker Desktop, OrbStack, colima or podman.
# 2. Pull the solver image (0.88 GB on Apple Silicon, 1.15 GB on Intel).
docker pull ghcr.io/gchen19/ankusdrive-solvers:latest
# 3. Check it is ours before running your geometry through it (see below).
bash scripts/verify-container-image.sh
# 4. Point AnkusDrive at the container substrate.
export ANKUSDRIVE_SUBSTRATE=container
# optional: ANKUSDRIVE_CONTAINER_ENGINE=podman|nerdctl (default docker)
# optional: ANKUSDRIVE_CONTAINER=<name> (default ankusdrive-solvers)
# 5. Create the container. $TMPDIR must be mounted at the SAME path inside, because a
# case directory has to mean the same thing on both sides. On macOS $TMPDIR is a
# per-user /var/folders/... path — mount THAT, not /tmp.
docker run -d --name ankusdrive-solvers \
--user "$(id -u):$(id -g)" -e HOME=/tmp \
--network none --cap-drop ALL --security-opt no-new-privileges \
--read-only --tmpfs /tmp:rw,exec,size=2g \
-v "$TMPDIR:$TMPDIR" \
ghcr.io/gchen19/ankusdrive-solvers sleep infinity
# 6. Export the in-container paths for the OpenFOAM-backed families. The image
# publishes them; YADE, Elmer, openEMS and Bempp need no export — AnkusDrive finds
# them by asking the container.
docker exec ankusdrive-solvers env | grep -E \
'^ANKUSDRIVE_(OPENFOAM_PATH|OPENFOAM_BASHRC|FSI_OPENFOAM_BASHRC|CCX_PRECICE|PRECICE_LIB|OPENFOAM_ADAPTER_LIB|OPENINJMOLDSIM|OPENINJMOLDSIM_BASHRC)='
# 7. Confirm.
ankusdrive doctor # each family: ready via <solver> (in container)
ankusdrive doctor --verify-image # …and that the image is signed by this repo
run 标志遵循最小权限原则;每个标志都对应求解器确实不需要的功能——我们已在启用这些标志的情况下运行实际求解器套件并验证过这一点。尤其是 --network none:网格中的任何内容都没有理由连接互联网。
不要复制镜像中的 ANKUSDRIVE_FREECADCMD 或 ANKUSDRIVE_CALCULIX_PATH——它们指向容器内的路径,而 FreeCAD 和 ccx 都在你的 Mac 上运行。
这里有个容易踩的坑:为原生安装编写的 config.toml 中的绝对路径会被视为容器内的路径。现在,ankusdrive doctor 会检测到这一点并告知你。
macOS 上的另一种运行环境是 Multipass VM,需要你自行配置——docs/MACOS.md 详细介绍了各个求解器在 Mac 上的实际情况,docs/CONTAINER_SUBSTRATE.md 则深入介绍了容器方案。
求解器镜像及如何验证其来源
| 镜像 | 内容 | 大小 |
|---|---|---|
ghcr.io/gchen19/ankusdrive-solvers | 你需要的镜像:仅包含求解器及其运行时库 | 1.15 GB amd64 / 0.88 GB arm64 |
ghcr.io/gchen19/ankusdrive-heavy | CI 镜像——还包含 FreeCAD、驱动程序 venv 和所有构建工具链,因为整个测试套件都在其中运行 | 5.3 GB / 4.5 GB |
两个镜像均为公开的多架构镜像(linux/amd64 + linux/arm64,均为原生构建),并带有 latest 和 sha-<commit> 标签。
每个已发布的清单都通过签名的 Sigstore 进行签名,使用短期 GitHub OIDC 身份——无需存储或泄露密钥——并附带来源信息,注明构建镜像的仓库、工作流和提交,以及描述镜像内容的 CycloneDX SBOM:
bash scripts/verify-container-image.sh # the slim image, :latest
bash scripts/verify-container-image.sh ghcr.io/gchen19/ankusdrive-solvers@sha256:<digest>
需要 GitHub CLI(gh ≥ 2.49,且已通过身份验证)。先验证摘要,再运行该摘要对应的镜像:今天验证 :latest,下周再拉取 :latest,拿到的是两个不同的镜像。ankusdrive doctor 会打印运行中容器所用镜像的摘要,--verify-image 则会对其进行验证。
验证结果有三种,只有一种值得警惕:已验证;未签名(自行构建的镜像,或在支持签名之前发布的镜像——设置 ANKUSDRIVE_ALLOW_UNVERIFIED_IMAGE=1 可忽略此提示);以及不匹配,即镜像携带了来自其他来源的来源信息,任何设置都无法忽略。验证绝不会阻止求解。
自行构建——构建子集或加入自己的修改——只需几分钟,因为无需编译任何内容(直接复制预构建的求解器目录):
tools/build_solver_image.sh --solvers "openfoam fsi" -t my-solvers:dev # 0.69 GB
Windows 快速入门(PowerShell)
Windows 是一流支持平台(核心 CAD 和 CalculiX FEM 可原生运行于标准 FreeCAD 1.1 安装),整个核心安装只需一个脚本——venv、固定版本依赖、doctor,以及包含已解析绝对路径的 MCP 注册行:
# 1. Install FreeCAD 1.1.x from https://www.freecad.org/ (default C:\Program Files\FreeCAD 1.1).
# Nothing needs to go on PATH — AnkusDrive globs the versioned install dir itself.
# 2. Clone and run the core installer. Windows PowerShell 5.1 is enough; no admin needed.
git clone https://github.com/gchen19/AnkusDrive.git
cd AnkusDrive
powershell -ExecutionPolicy Bypass -File scripts\install-core.ps1
该脚本会创建 .venv,安装带有必要固定版本的 AnkusDrive(尤其是 mcp<2——mcp 2.x 可以顺利安装,但之后会导致 ankusdrive mcp 出错),验证已解析的 mcp/numpy/Pillow,运行 ankusdrive doctor 和 ankusdrive ping,完成真实的 MCP stdio 握手,最后打印注册代码块。实用选项:
-Python 'C:\Program Files\Python313\python.exe' 用于选择解释器,
-Extras mbd,fluids 用于选择 pip wheel 求解器系列,-Persist 用于将 FreeCAD 路径写入 %APPDATA%\ankusdrive\config.toml(MCP 主机启动时使用精简环境,因此在终端中设置的 $env: 不会传递给它们)。
3. 在 MCP 主机中注册。 脚本会打印以下内容,并填入实际路径——GUI 主机不会继承你的 shell PATH,因此绝对路径很重要:
# Claude Code
claude mcp add ankusdrive -- C:\Users\you\AnkusDrive\.venv\Scripts\ankusdrive.exe mcp
# Claude Desktop: %APPDATA%\Claude\claude_desktop_config.json
# { "mcpServers": { "ankusdrive": {
# "command": "C:\\Users\\you\\AnkusDrive\\.venv\\Scripts\\ankusdrive.exe",
# "args": ["mcp"] } } }
然后重启主机;你应该会看到 ankusdrive__* 工具出现。
支持的 Python 版本:3.10 – 3.14(已在 Windows 11 上端到端验证 3.14——pip install、MCP stdio 握手,以及 ankusdrive ping → freecad=1.1.1)。脚本会在运行 pip 之前检查解释器,因此如果 CPython 版本过新,会明确提示,而不是在依赖解析器中失败。
可选求解器(SU2、Elmer、PrusaSlicer、由 WSL 支持的 OpenFOAM)可稍后通过 scripts\install-solvers.ps1 安装。对于仅限 Linux 的求解器(OpenFOAM、FSI、注塑成型、YADE、openEMS、Bempp),安装 WSL 后运行一次 ankusdrive container setup --install-engine。它会在 WSL 内通过 Docker 使用预构建映像运行这些求解器
(方法)。有关各求解器的实际情况、测试套件和 WSL2 方案:docs/WINDOWS.md。
Ubuntu 24.04+ / 容器(apt 没有 FreeCAD)
FreeCAD 已从 Ubuntu 24.04 的 universe 仓库中移除,因此 apt install freecad 在那里找不到可用版本,而上游的 snap/flatpak 在容器或沙盒化 Agent 环境中都会失败(没有 snapd 会话,也没有 FUSE)。适用于各种环境的方案是官方 AppImage,解压使用:
scripts/install-freecad-appimage.sh # or: scripts/install-solvers.sh freecad
它会下载固定版本的 AppImage,校验其 SHA-256,使用 --appimage-extract 解包(在用户空间解包 squashfs——无需 FUSE、无需 root、无需
snapd,因此能在容器中运行),将 freecadcmd、freecad、
ccx 和 gmsh 符号链接到 /usr/local/bin,然后通过 ankusdrive ping 和实际的 CalculiX 求解(ankusdrive fem cantilever)实时验证结果。如果 /opt 不可写,它会改为安装到 ~/.local/opt/freecad;--prefix /
--bindir 可覆盖这两个路径,--appimage FILE 则可复用你已有的下载文件。
符号链接步骤是可选的:AnkusDrive 也会直接检查
/opt/freecad/squashfs-root/usr/bin(以及 ~/.local/opt/freecad*/…),因此无论在哪个前缀下手动解压 AppImage,都会自动发现。ccx 和 gmsh
也包含在 AppImage 中,因此只需这一次下载即可运行结构 FEM。
告诉 AnkusDrive FreeCAD 的位置
AnkusDrive 按以下顺序自动发现 freecadcmd:$ANKUSDRIVE_FREECADCMD,
然后通过 PATH 上的 shutil.which(...) 查找(依次尝试 freecadcmd、FreeCADCmd 和
freecad.cmd),最后搜索一份按操作系统区分的标准安装位置列表:
| 操作系统 | 自动发现的位置(优先选择最新版本) |
|---|---|
| macOS | /Applications/FreeCAD.app/Contents/Resources/bin/freecadcmd |
| Linux | /usr/bin、/usr/local/bin、/snap/bin/freecad.cmd、/opt/freecad*/squashfs-root/usr/bin 或 ~/.local/opt/freecad*/… 下解压的 AppImage、~/.local/bin |
| Windows | C:\Program Files\FreeCAD *\bin\freecadcmd.exe(按版本匹配)、C:\Program Files (x86)\…、%LOCALAPPDATA%\Programs\FreeCAD *\bin\… |
因此,这三个操作系统上的标准安装程序都无需配置。对于非默认安装,请将 AnkusDrive 指向二进制文件:
export ANKUSDRIVE_FREECADCMD=/path/to/freecadcmd # macOS/Linux
$env:ANKUSDRIVE_FREECADCMD = "D:\Apps\FreeCAD\bin\freecadcmd.exe" # Windows
ankusdrive doctor 会显示实际通过哪一层(环境变量 / PATH / 自动发现)找到了 FreeCAD,以及检查过的所有候选项——这是在新设备上排查“未找到 FreeCAD”最快的方法。
图纸导出(PDF/SVG)
export_drawing 完全以无头模式构建二维机械图纸(包含尺寸标注的多视图 PDF/SVG/DXF)。DXF 使用 FreeCAD 自带的写入器,无需额外依赖。PDF 和 SVG 使用 reportlab + svglib 进行合成和栅格化;由于这些操作在 worker 中运行——使用的是 FreeCAD 自带的 Python,而非主机的虚拟环境——因此必须将这两个包安装到 FreeCAD 的 Python 中:
# Resolve FreeCAD's bundled Python from freecadcmd itself (portable across the
# macOS .app, a Linux distro package, and an extracted AppImage). freecadcmd
# prints a startup banner after the script output, so match a marker line
# rather than taking the last line:
printf 'import sys; print("DPREFIX="+sys.prefix)\n' > /tmp/_fcprefix.py
FREECAD_PREFIX="$(freecadcmd /tmp/_fcprefix.py 2>/dev/null | sed -n 's/^DPREFIX=//p')"
FREECAD_PY="$FREECAD_PREFIX/bin/python" # some builds: $FREECAD_PREFIX/bin/python3
# Pin svglib<1.6 — newer svglib pulls rlPyCairo -> pycairo, a native build we
# don't use (our drawings are line art, no gradients).
"$FREECAD_PY" -m pip install reportlab "svglib<1.6"
# Verify:
"$FREECAD_PY" -c "import reportlab, svglib; print('drawing export ready')"
如果不安装这些包,export_drawing 仍会生成 .dxf;导出 .pdf/.svg 时会抛出明确的 ModuleNotFoundError。FreeCAD 已自带 Pillow(reportlab 需要它),因此无需单独安装。
将其接入 MCP 主机
MCP 服务使用 stdio 通信。让主机调用 ankusdrive 二进制文件,
并运行 mcp 子命令。
Claude Desktop — 添加到 ~/Library/Application Support/Claude/claude_desktop_config.json
(macOS)或 %APPDATA%\Claude\claude_desktop_config.json(Windows):
{
"mcpServers": {
"ankusdrive": {
"command": "ankusdrive",
"args": ["mcp"]
}
}
}
如果主机进程的 PATH 中没有 ankusdrive,请使用绝对路径 —
例如 /Users/<you>/.local/bin/ankusdrive(pipx 默认路径)或
/absolute/path/to/AnkusDrive/.venv/bin/ankusdrive(克隆并创建 venv)。
Claude Desktop,一键安装 — 从
最新版本下载 ankusdrive-<version>.mcpb 并打开。
Claude Desktop 会使用 uv 配置其 Python 环境,因此无需执行 pipx 步骤,
但仍需要 FreeCAD 1.1。安装对话框中有一个可选字段,用于填写 FreeCAD
命令路径,以指定自动发现无法找到的 FreeCAD。
Claude Code — 注册一次即可:
claude mcp add ankusdrive -- ankusdrive mcp
其他主机(Cursor、Continue、自定义 MCP 客户端) — 配置方式相同:stdio
传输,命令 = ankusdrive,参数 = ["mcp"]。
重启主机后,你应该能看到 280 多个 ankusdrive__* 工具可用。如果启动卡住,或主机报告连接已关闭,请直接运行
ankusdrive ping — 它会使用相同的工作进程启动路径,并提供更清晰的错误消息。
工具系列(工具集)。 每个工具定义都会占用客户端的上下文,全部 283 个工具总计约 114k 个 token。工具按系列分组,你可以按需启用或停用:core(始终启用)、drawings、fem、components、sheet_metal、assembly、
intent、manufacturing、hand_calcs、simulation、plm、rendering。
- pip / pipx / uvx / 克隆: 除非设置了
ANKUSDRIVE_TOOLSETS,否则所有系列均启用;例如设置为ANKUSDRIVE_TOOLSETS=drawings,fem,simulation,或在config.toml中设置toolsets = "..."。 - Claude Desktop 扩展: 默认启用
core、drawings和fem(约 31k 个 token);其他系列可在扩展的设置中启用。
setup_status 会列出已停用的系列,并准确说明如何启用每个系列。
run_script 会执行 Agent 编写的 Python 代码,并可完全访问你的文件和
进程。可通过 ANKUSDRIVE_ALLOW_RUN_SCRIPT 控制(环境变量,或 config.toml 中的
allow_run_script):
- pip / pipx / uvx / 克隆: 除非设为
false,否则允许使用。 - Claude Desktop 扩展: 默认关闭;可在扩展的设置中启用。
关闭时,不会提供此工具,且 setup_status 会说明如何启用它。
仿真求解器与评审视频演示
基础安装(FreeCAD + pip install ankusdrive)涵盖几何、解析预言机和 MCP 接口。每个重量级仿真系列都会调用一个外部求解器,运行时通过 ankusdrive/solvers.py 查找
($ANKUSDRIVE_<SOLVER>_PATH → PATH → 标准安装目录)。缺少求解器的系列会返回格式清晰的 {ok: false, reason, install} 字典,而不会崩溃 — 可通过 ankusdrive doctor(跨平台,无需启动服务)、solve_capabilities MCP 工具,或安装脚本的 list 查看当前可用的求解器。安装脚本会安装 pip wheel 求解器并配置原生求解器 —
Linux/macOS 上使用 scripts/install-solvers.sh(apt/conda + 源码构建),Windows 上使用
scripts/install-solvers.ps1(pip extras +
便携版 SU2/Elmer/PrusaSlicer 下载;从 FreeCAD 的程序包中自动检测 CalculiX)。
持久化配置: 每个 ANKUSDRIVE_* 路径都可以改为保存在
~/.config/ankusdrive/config.toml 中(Windows 上为 %APPDATA%\ankusdrive\config.toml;
ANKUSDRIVE_CONFIG 可覆盖此路径):顶层使用 freecadcmd = "...",在 [solvers] 下为每个求解器变量设置一个小写键
(su2_path、elmer_path、openfoam_bashrc 等)。设置环境变量时仍以环境变量为准;配置文件则可在 MCP 宿主启动环境精简时保留配置。ankusdrive doctor 会报告配置文件,以及每个值由哪个层级解析得出。
求解文件的存放位置: 每个内置求解器都会将其计算文件——.sif 和网格、OpenFOAM 算例目录树、.inp、切片后的 .gcode——写入 <system temp>/ankusdrive-cases 下各自的目录,并将该目录报告为 case_dir。这些文件会保留,因为结果会引用它们,后续工具也会使用它们(翘曲求解会使用填充求解写入的冷却算例);当根目录超过 64 个目录或 4 GB 时,系统会按从旧到新的顺序清理文件——不会触及最近一小时内写入的文件,以免正在运行的求解被中途移除。solve_capabilities 会在 cases 下报告根目录和实时数量。可通过 ANKUSDRIVE_CASE_ROOT、ANKUSDRIVE_CASE_KEEP、ANKUSDRIVE_CASE_MAX_GB、ANKUSDRIVE_CASE_GRACE_S 调整设置,也可使用 ANKUSDRIVE_KEEP_SCRATCH=1 关闭清理。无论你提供的 case_dir 位于何处,系统都不会触碰它。
每个求解结果还包含 deck——求解器实际收到内容的清单,在求解器启动第一步时立即生成,早于它向同一目录写入任何输出:{digest, count, bytes, files: {path: hash}}。session_transcript 会在执行该求解的检查前,将清单与 s.deck(...) 进行比较。因此,重放时发生偏移的数值会附带说明:如果失败检查上方显示 ~ case.sif,就表示问题发生了变化;如果显示 deck matches the recording,则表示问题没变,变化来自求解器或环境。CalculiX FEM 结果也会以相同方式包含其 .inp。
平台说明: 求解器的发现层完全跨平台(按操作系统区分的安装目录、Windows PATHEXT/.exe、环境变量覆盖),因此 ankusdrive doctor 在 macOS/Linux/Windows 上都会给出准确报告。pip-wheel 系列(MBD、拓扑、光学、流体)在各个平台上的安装方式相同。原生二进制系列因操作系统而异——每个 FreeCAD 安装都自带 CalculiX;SU2 和 PrusaSlicer 提供良好的 Windows/macOS 二进制文件;Elmer 提供可移植的 Windows zip,但没有 macOS 二进制文件;基于 OpenFOAM 的系列(CFD、FSI、注塑成型)以及 YADE、openEMS 和 Bempp 则依赖 Linux shell 和链接器衔接层。在 macOS 上,它们通过已签名的求解器容器运行,在 Apple Silicon 上原生运行,且无需从源码构建:请参阅 macOS 快速入门——在容器中运行求解器。在 Windows 上,它们通过 WSL 运行。有关各操作系统上每个求解器的实际情况和设置方法,请参阅
docs/WINDOWS.md 和 docs/MACOS.md。
scratch/ 下的评审视频演示会将求解结果转成 GIF,供人观看——让实际导出的几何体动起来,并在画面上叠加对应的 oracle(写入 artifacts/)。每个演示都需要相应系列的求解器和 matplotlib;CFD 演示还需要 meshio(以及基础依赖 numpy/Pillow):
pip install matplotlib meshio # frame rendering + reading OpenFOAM's VTK output
审查视频演示(scratch/…) | 驱动的求解器 | 安装 |
|---|---|---|
dog_clutch_cad_sim.py — 通过 p.vhacd 实现刚体接触 | PyBullet(pip wheel) | pip install 'ankusdrive[mbd]' |
meshing_gears_video.py — 多体动力学齿轮传动 | PyBullet(pip wheel) | pip install 'ankusdrive[mbd]' |
modal_shape_video.py — FEM 模态形状 | CalculiX ccx(FreeCAD FEM) | apt install calculix-ccx(Linux);FreeCAD 会在 PATH 中查找 ccx |
thermal_field_video.py — 瞬态热场 | Elmer | apt install elmerfem-csc;确保 ElmerSolver 位于 PATH 中(或设置 ANKUSDRIVE_ELMER_PATH) |
cfd_field_video.py — CFD 流场(顶盖驱动方腔) | OpenFOAM + meshio | 通过 apt/conda 安装 OpenFOAM,然后执行 source <install>/etc/bashrc(或设置 ANKUSDRIVE_OPENFOAM_BASHRC);pip install meshio |
它们都使用 FreeCAD 进行几何建模/网格划分,因此请使用启动工作进程的同一解释器运行每个脚本,例如 .venv/bin/python3 scratch/cfd_field_video.py。
光学
MCP 接口背后有两种光学引擎,分别属于两种许可/运行时通道:
| 通道 | 工具 | 引擎 | 安装 |
|---|---|---|---|
| 顺序式 — 镜头设计 + 优化 | optics_lens_design、optics_lens_optimize、optics_raytrace | optiland / rayoptics(MIT/BSD,在进程内运行) | pip install 'ankusdrive[optics]' — 或 scripts/install-solvers.sh optics |
| 非顺序式 — 追踪穿过 STL 实体的光线 | optics_solid_trace | KrakenOS(GPL-3.0,仅限进程外运行) | pip install 'ankusdrive[optics_gpl]' — 或 scripts/install-solvers.sh optics_gpl |
顺序式引擎会在进程内导入,因此请将 optics extra 安装到启动工作进程的同一解释器中(与其他 wheel 一样)。非顺序式引擎采用 GPL-3.0 许可,因此 AnkusDrive 绝不会导入它——它会在单独的子进程中运行(ankusdrive/optics_gpl_runner.py),与 GPL 许可的 Elmer/OpenFOAM 二进制文件采用相同的独立边界。工作进程会自动定位可导入 KrakenOS 的 Python(即安装 wheel 的位置);可通过 ANKUSDRIVE_OPTICS_GPL_PYTHON=/path/to/python 覆盖。由于这种隔离,GPL extra 需选择启用:不带参数运行 install-solvers.sh 只会安装宽松许可的 extras,并提示如何添加 optics_gpl。两个通道的渲染示例(镜头布局、光斑图、优化、棱镜全反射,以及球面镜头球差研究)位于 examples/optics/optics_gallery/ — 使用 .venv/bin/python examples/optics/optics_gallery.py(以及 …_3d.py、optics_ball_lens.py)重新生成,或者一次性完成所有初始化(安装两个通道,然后渲染所有图像):
scripts/install-solvers.sh --optics-gallery
架构示意
┌────────────┐ ┌────────────┐ ┌──────────────────────┐
│ MCP host │ ───► │ AnkusDrive │ ───► │ freecadcmd worker │
│ (Claude) │ │ (Python) │ IPC │ (long-lived Python) │
└────────────┘ └────────────┘ └──────────────────────┘
▲ ▲ │
│ │ ▼
└── CLI user ────────┘ .FCStd / .inp / .vtk
关键决策:采用通过标准输入/输出传递 JSON 的长驻工作进程,而不是每次调用都启动一个子进程。FreeCAD 启动约需 1–2 秒;对于交互式 Agent 来说,每次工具调用都付出这笔开销是不可接受的。工作进程是在 freecadcmd 下启动的一个小型 Python 循环,负责读取命令、分派给处理程序,并返回结构化结果(包括对象 ID,以便后续调用引用已创建的几何体)。
我们关注的 FreeCAD API 范围
摘自脚本编写文档和 FEM Python 教程的笔记:
核心(App):
App.newDocument(name)/App.ActiveDocument/doc.recompute()/doc.save(path)doc.addObject("Part::Box", "name")— 创建指定类型的对象;之后设置属性(box.Height = 5)- 使用
doc.supportedTypes()进行内省;obj.TypeId、obj.isDerivedFrom("Part::Feature")
建模:
Part—makeBox、makeCylinder、makeSphere、布尔运算cut/common/fuse、圆角、放样(底层使用 OpenCASCADE)Draft— 2D 基本图元、move、阵列Sketcher+PartDesign— 由参数化草图驱动的实体(大多数「真正的」机械设计都在这里完成)- 使用
FreeCAD.Vector、Placement进行定位
FEM(ObjectsFem + femtools):
ObjectsFem.makeAnalysis(doc, "Analysis")— 容器makeSolverCalculixCcxTools/makeSolverElmer— 带可调参数的求解器对象(GeometricalNonlinearity、ThermoMechSteadyState,……)makeMaterialSolid— 设置YoungsModulus、PoissonRatio、Density- 约束:
makeConstraintFixed、makeConstraintForce、makeConstraintPressure、makeConstraintDisplacement、接触/绑定/弹簧、热约束 - 网格:
makeMeshGmsh+femmesh.gmshtools.GmshTools(...).create_mesh()(或 Netgen) - 运行:
femtools.ccxtools.FemToolsCcx().run() - 结果:遍历
analysis.Group查找Fem::FemResultObject;读取.DisplacementVectors、应力场
无头调用:
freecadcmd script.py— 运行脚本后退出- 不带参数运行
freecadcmd— 交互式 Python REPL(工作进程将驱动此环境) --console、-M <moddir>、-P <pypath>、--pass <args>、FreeCAD.ConfigGet(...),用于获取环境信息- 无头模式下无法使用
FreeCADGui— 仅在App/Part/Fem中编写设计逻辑
Agent 如何访问 FreeCAD:三个层
AnkusDrive 通过三个层提供 FreeCAD 功能,每层面向不同的受众, 使用成本也各不相同。了解某项功能属于哪一层,就知道如何调用它。
第 1 层 — 类型化 MCP 工具(Agent 接口)
280 多个一流 MCP 工具涵盖核心机械设计功能、广泛的 工程分析/仿真功能以及设计控制(PLM) 层。这些工具具有经过验证的参数、结构化返回值,以及用于串联调用的稳定句柄。这是首选方式 — 适用于 Agent 日常执行的任务。
| Domain | 涵盖内容 |
|---|---|
| 文档生命周期 | new_document、open_document、save_document、list_documents、set_active_document、close_document、restart_worker |
| 几何基元 | add_primitive(box/cyl/sphere)、boolean_op、export_shape(STEP/IGES/BREP/STL) |
| 选择(稳定引用) | list_faces、list_edges、query_faces、resolve_face、resolve_edge、register_handle、verify_feature |
| PartDesign | make_body、make_datum_plane、make_sketch、add_sketch_geometry、add_sketch_constraint、add_sketch_external、close_sketch、pad、pocket、revolve、hole、loft、sweep、helix、partdesign_fillet、partdesign_chamfer、linear_pattern、polar_pattern、mirrored、thickness、draft |
| 直接建模与特征操作 | fillet_edges、chamfer_edges、shell_solid、add_rib、engrave_text、oring_groove、transform、scale_shape、copy_shape |
| 参数化组件 | add_gear、add_rack、add_sprocket、add_pulley、add_spring、add_fastener、add_bearing、add_thread、list_thread_options |
| 计量与检测 | measure_distance、measure_angle、bounding_box、check_shape、section_view、min_clearance、envelope_check、interference_check |
| 通用属性访问 | get_object、set_property |
| 功能意图与不变量 | annotate_face、list_face_roles、classify_face_sides、check_airtight_path、declare_intent、verify_intent |
| 性能契约 | declare_performance、verify_performance — 定量规格(“Cd ≤ 0.30,速度为 30 m/s”、“Δp ≤ 50 Pa”、“第一阶模态 ≥ 200 Hz”)会持久化保存在零件上,并在每次编辑后重新验证;判定有三种状态:如果测量的不确定性范围跨越限值,则结果为 indeterminate(需升级处理),绝不算通过。该契约会在关卡中检查(#261):merge_assembly、substitutability_check 和 component_contract_check 会读取最后记录的判定结果,因此未满足的规格会阻止合并,而未经验证的规格会作为单独结果报告,不会悄然视为通过 |
| 设计空间研究(DOE) | study_submit — 在完整网格或拉丁超立方体上遍历配方/工具参数,并将整个搜索过程保留为表格,而不只是最后一个点。响应可以是任意 AnkusDrive 工具加一个度量路径(包括完整的 verify_performance 判定,因此不同保真度层级的点仍可进行比较);筛选响应会内联计算,求解器响应则会并发分发,由一个收集器任务统一处理。采样由 seed 决定,因此重新提交崩溃或扩展后的研究时,只会重新运行新点,其余点会报告为缓存命中 |
| 优化以满足规格 | optimize_submit — 调整有界参数,直到所有约束均通过,然后报告是否已证明。使用有界 Nelder-Mead(无导数;CFD 求解中不存在伴随法)在契约层使用的相同目标/约束映射上进行优化,并采用从筛选到求解器的保真度阶梯。契约层规定了两条规则:indeterminate 约束属于测量问题,而非失败步骤(它既不会吸引也不会排斥搜索);收敛不等于证明——如果裕量窄于其自身的不确定性范围,就会报告为未证明,无论单纯形收敛得多么漂亮 |
| 装配体与接口 | make_assembly、add_part、list_assembly_parts、merge_assembly、publish_interface、interface_align_check、assembly_lock、assembly_lock_check、bom_extract |
| 工程图(TechDraw,无头模式) | make_drawing_page、add_projection_group、add_section_view、add_thumbnail、add_dimension、add_annotation、add_feature_note、add_gdt_callout(形位公差框)、set_title_block、fit_page、export_drawing(PDF/SVG/DXF),以及完整性/可读性关卡 drawing_gate、drawing_legibility |
| 检验(首件) | balloon_drawing(修订版稳定的气泡编号)、inspection_plan(特性清单,每行包含一种测量方法,遵循量具制造商的 10:1 规则)、fai_report(采用 AS9102-Form-3-格式的 CSV/SVG/PDF——不是经认证的提交文件);drawing_gate(require_ballooned=True) 可将带气泡标注的图纸设为发布要求 |
| 发布包(供应商 / RFQ) | release_package — 为某个修订版的项目一键生成交付包:STEP + 工程图(PDF/SVG/DXF)+ 递归 BOM + 检验包 + blake2b 校验和清单。写入任何内容前都会执行关卡检查:项目必须处于可发布的生命周期状态(或使用 draft=True,此时每个产物都会加上 PRELIMINARY 水印),每张包含的页面都必须通过 drawing_gate,且标题栏中的零件号/修订版/材料必须与项目注册表相符——不匹配时会失败并提供命名差异,绝不会静默修正。字节可复现(同一修订版再次发布会生成校验和完全相同的文件),ECO 会记录在清单和图纸上;rfq=True 会添加分档数量和 cost_estimate 汇总,同时剔除仅供内部使用的产物 |
| 现成零件(可采购性) | catalog_search(有哪些标准组件、尺寸及有库存的长度)、catalog_nearest(将所需尺寸匹配到实际规格——询问 M4×13 时会返回 12 和 16)、catalog_check、standard_part_designate(规范标记:ISO 4762 M4×12 A2、608-2RS、AS568-214 NBR70,创建时标记在零件上)、designation_check、bom_extract(orderable=True)(逐行标明有库存/无库存及替代品) |
| 视觉反馈 | render_view、render_views(8 种预设视图、多视图图纸)、render_photoreal / render_photoreal_submit(Blender 摄影棚场景,可为完整装配体中的每个零件设置外观;或使用 FreeCAD Render 插件渲染器;renderer="auto")、render_capabilities |
| FEM(FreeCAD/CalculiX/Elmer) | fem_new_analysis、fem_set_solver、fem_set_material、fem_set_nonlinear_material、fem_add_constraint(固定/力/压力/位移/温度/热流/初始温度)、contact_setup、fem_mesh、fem_mesh_refinement、fem_modal、fem_buckling、fem_run、fem_run_submit(在 MCP 通道之外运行相同的 CalculiX 求解;结果读取器接受其 job_id)、fem_results、fem_result_probe(某点或某面的应力/位移/温度)、fem_modal_results、fem_buckling_results、fem_thermal_results,以及旧版 fem_cantilever_demo |
| 工程计算器与手算 | 机械元件(gear_rating、bearing_life、belt_drive、spring_check、bolted_joint_check、press_fit_stress、seal_check)、结构(beam_modal、beam_buckling、plate_check、hertz_contact、elastica_deflection、plastic_collapse、random_vibration、harmonic_response)、耐久性(fatigue_check、fracture_check、creep_flag、wear_estimate)、热学(thermal_lumped、thermal_transient_1d、thermal_composite_wall、h_estimate)、公差/GD&T(tolerance_stackup、fit_check、fit_class、gdt_check) |
| 仿真系列(外部求解器、异步) | 通过 shell 调用 OpenFOAM/Elmer/CalculiX/openEMS/YADE/KrakenOS 的筛选与完整求解,大多数采用提交→轮询任务模式:热学/CHT(cht_channel_submit、cht_graetz_submit、thermal_transient_submit、thermal_radiation_submit)、CFD(cfd_pipe_flow、cfd_body_drag、cfd_internal_flow_submit、cfd_external_flow_submit——包括虚拟风洞:输入实体即可通过积分力得到 Cd/Cl/Cm,并根据球体阻力曲线进行关卡检查;每次稳态求解都会附带可信度信息块(收敛性、checkMesh、测得的 y+),cfd_mesh_independence_submit/grid_convergence 则会为没有解析解对照的几何体给出 Richardson/GCI 误差范围)、电磁(em_skin_depth、em_dc_resistance、em_field、em_conduction_submit、em_induction_submit、em_fullwave_submit)、声学(acoustic_screen、acoustic_fem_submit、acoustic_radiation_submit)、FSI(fsi_*)、成型(molding_screen、molding_fill_submit、molding_warpage_submit)、跌落/冲击(drop_impact、bar_impact、impact_dynamics_submit——将网格化零件飞向刚性地面,可按平面/边缘/角落着地,并根据精确的 Saint-Venant 杆件模型进行关卡检查)、颗粒/DEM(granular_screen、dem_pack_submit、dem_flow_submit)、光学(optics_lens_design、optics_lens_optimize、optics_raytrace、optics_solid_trace)、多体(mechanism_kinematics、mechanism_simulate_submit)、拓扑(topology_optimize_submit、topology_to_solid) |
| 异步任务 | job_status、job_result、job_list — 轮询/收集任意长时间运行的 *_submit 求解;solve_capabilities 报告当前可用的求解器 |
| 材料与流体 | material_list、material_get、material_select、fluid_props — 通过类型化查询访问机械性能/成型/CoolProp 热物性数据集 |
| 钣金 | sheet_base(底板法兰)、sheet_flange / sheet_tab / sheet_hem(通过稳定的边标签放置折弯)、sheet_unfold(K 系数展开图案 + 每个折弯的展开长度/扣除量;每个结果都会回显实际采用的 K 值及其来源)、sheet_refold(与折弯实体进行往返验证)、sheet_flat_export(分层 DXF——CUT / BEND_UP / BEND_DOWN,即激光/折弯加工厂用于报价的文件)、sheet_check(按材料检查最小折弯半径、最小法兰、孔到折弯的距离、回折碰撞) |
| 制造与面向 X 的设计 | dfm_check(输入钣金零件时也会运行钣金折弯机规则)、dfa_check、moldability_check、optics_moldability_check、pack_check、cost_estimate、slice_estimate、slice_gcode_submit、laminate_properties、drop_impact |
| CNC(可加工性与加工时间) | cnc_machinability_check(根据刀具可达性普查结果判断装夹次数、倒扣、刀具长径比、尖锐/狭小的内角、薄壁——纯几何检查,不使用 CAM 引擎)、cnc_time_estimate(材料去除率模型:去除体积 / MRR 加上精加工面积;相比平面表格的 ±100 %,误差为 ±50 %;结果作为 machine_time_hr=… 输入 cost_estimate) |
| 公差 ↔ 成本 | tolerance_cost_check(逐尺寸给出 IT 等级、自然满足该公差的最低成本工艺、相对成本指数,并在尺寸要求严于所声明工艺无需二次加工即可达到的能力时发出标记)、suggest_loosening(可行的最宽松公差——采用贪心放宽,每一步都会根据 tolerance_stackup 的 cpk 重新验证);cost_estimate(tolerance_class=…) 会在汇总中提供相同的曲线 |
| 设计控制 / PLM | 项目与零件号(items_new、items_validate、items_resolve、items_check_manifest)、配方(recipe、recipe_list、recipe_schema、recipe_validate)、特征模板(feature_instantiate、feature_list、feature_schema、feature_validate)、变体系列(family_materialize、family_validate)、生命周期/修订版(lifecycle_transition、lifecycle_editable、lifecycle_classify_change、lifecycle_apply_change)、变更控制(eco_create、eco_validate、change_impact、where_used、baseline_create、baseline_verify)、接口注册表与可替代性(get_interface、substitutability_check)、项目(scaffold_project、project_validate、project_check_references、project_resolve_manifest) |
| 操作 | transaction_open、transaction_commit、transaction_abort |
| 会话记录 | session_transcript:将截至目前的会话内容作为 Python 脚本返回,通过这些相同的工具重新生成内容(模型、工程图、仿真)。句柄会成为变量,任务轮询会成为一个 s.wait(job),测量结果会成为可阻止偏离重放的 s.check() 语句,路径则相对于 WORKDIR。它也是分析溯源记录:所有手算和求解都会完整保留并接受检查,run_script 会携带其 SHA-256,PROVENANCE 块会列出 AnkusDrive / FreeCAD / 平台 / 基础环境,以及会话访问过的每个求解器——路径、基础环境和探测到的版本。只读:以文本形式返回脚本。除非选择启用持久化日志,否则工具调用会保存在服务端内存中:ANKUSDRIVE_JOURNAL_DIR 会将每次调用追加到每个会话对应的 JSONL 文件中,journal_export / ankusdrive journal export 可将过往会话转换为相同的记录(PRIVACY.md) |
所有工具均返回 JSON;创建几何体的工具会返回一个 handle(例如 | |
pad_1),供后续调用引用。如果未安装求解器,重量级仿真系列会返回 | |
{ok: false, reason, install} 字典,而不会崩溃——请参阅仿真求解器。 |
第 2 层 — 通用属性反射
对于“我只需要调整这个属性”这类没有专用工具的需求:
get_object(handle)— 转储obj.PropertiesList中的每个条目,并将 Quantities 转换为 float(mm/deg)、Vectors 转换为列表、Placements 转换为字典。set_property(handle, name, value)— 按名称设置任意单个属性。
如果对象类型有对应的专用工具,但该工具没有公开你需要的确切属性,请使用此功能(例如 Pad 的 Refine、Loft 的 Sections 排序、CCX 求解器的内部可调参数)。
第 3 层 — run_script(通用逃生通道)
对于完全没有一流 MCP 工具的功能——例如 Path 工作台(CAM 刀具路径)、Surface 工作台、Arch/BIM、Spreadsheet、TechDraw 尺寸标注、接触/弹簧 FEM 约束、B 样条草图操作、表达式引擎绑定,以及 AnkusDrive 未封装的任何工作台。
run_script(code='''
import Path
job = Path.Job.Create("Job", [_resolve("pad_1")])
__result__ = {"job_name": job.Name}
''')
在脚本中,工作进程会预先注入:App / FreeCAD、Part、
ObjectsFem,以及 _register(prefix, obj) / _resolve(handle) /
_handles,以便脚本可以将新对象注册到专用工具使用的同一 handle 注册表中。将
__result__ = ... 设为可序列化为 JSON 的值即可返回数据;print 语句会被发送到 /dev/null。
这种逃生通道的成本更高(Agent 必须编写 FreeCAD Python),但 能让你访问整个 FreeCAD API。第 2 阶段计划的“第 2 阶段之后”部分指出了哪些 run_script 模式值得提升为专用工具——功能就是这样逐步扩展的。
重新生成会话
session_transcript() 会将目前为止的会话作为脚本返回:
with Session() as s:
r2 = s.add_primitive(kind='box', w=40.0, d=20.0, h=5.0)
box_1 = r2['handle']
r3 = s.add_primitive(kind='cylinder', h=5.0, r=3.0)
cylinder_1 = r3['handle']
r4 = s.boolean_op(op='cut', base=box_1, tool=cylinder_1)
s.check(r4, 'volume', 3964.657082647114)
s.save_document(path=str(WORKDIR / 'bracket.FCStd'))
保存该脚本,然后运行 python transcript.py [WORKDIR],即可在全新的
工作进程中重建会话。ankusdrive.replay.Session 调用的函数与 MCP 服务提供的相同,
因此转录脚本无法调用服务不具备的工具。run_script 仍受其开关控制,缺少求解器会导致运行在该步骤停止。每个
s.check() 都会在结果与录制结果首次不同时停止运行。脚本头部会列出无法重现的内容:失败的调用、run_script 代码,以及会话读取过的文件;你需要先将这些文件复制到 WORKDIR。
审计分析
同一工具也回答了转录脚本的另一个用途:这个数值究竟是如何得出的? 仿真会话导出时会保留其推导过程——闭式估算不会作为“检查”而被丢弃,每个分析或求解报告的数值都会成为 s.check(),判定字段则会成为 s.expect()。因此,如果重放时使用了不同的求解器,或回退到不同的相关式,就会在该处停止,而不是返回一个看似合理的数值:
PROVENANCE = {'env': {'ankusdrive': '0.5.5', 'freecad': {'version': '1.1.0'},
'substrate': 'container', ...},
'solvers': {'elmer': {'version': '26.2', 'via': 'container',
'path': '/usr/bin/ElmerSolver', ...}}}
with Session() as s:
s.provenance(PROVENANCE) # prints every difference from the recording
r1 = s.h_estimate(geometry='vertical_plate', characteristic_mm=100.0, t_surface_c=200.0)
s.check(r1, 'h_total_w_m2k', 8.4111, rel=0.001)
s.expect(r1, 'correlation', 'churchill_chu_vertical_plate')
r2 = s.thermal_transient_submit(half_thickness_mm=1.5, h_conv=8.0, duration_s=600.0, ...)
r5 = s.wait(r2['job_id'])
s.check(r5, ('result', 't_center_c'), 45.49120518934, rel=0.001)
s.expect(r5, ('result', 'solver'), 'elmer')
s.provenance() 会在重放机器上重新解析整个环境,并打印发生变化的内容:不同的 Elmer 版本、基底改变后迁移位置的求解器,以及并非用于构建模型的 FreeCAD。使用不同求解器进行重放并不代表失败——这正是发现。$HOME 下的求解器路径会缩写为 ~/…,因此记录会指出使用的是哪个安装版本,但不会泄露用户身份。session_transcript 也会将记录作为 provenance 返回,以便附加到报告中;传入 provenance=False 可跳过该记录及其运行的版本探测。
保留记录:持久化日志
转录记录会一直保留到服务退出。对于需要为设计决策提供依据的分析,请启用持久化日志——它默认关闭,只需设置一个选项即可启用:
export ANKUSDRIVE_JOURNAL_DIR=~/ankusdrive-journal # or journal_dir = "..." in config.toml
之后,每次工具调用都会追加到该目录下的 session-<start>-<pid>-<id>.jsonl:文件头包含环境信息(AnkusDrive / Python / 平台 / 基础设施)、每个工作进程启动时使用的 FreeCAD,以及每次调用各占一行——完整参数(run_script 代码原样记录,并附带其 SHA-256)、经过截断的结果、每次求解最终使用的求解器,以及对完整结果计算的 SHA-256 result_digest,因此即使日志不得不截断结果,该结果仍有摘要可供核验。写入采用尽力而为的方式:如果无法写入日志,只会记录一条警告,不会导致工具调用失败,也不会改变工具调用。
服务退出后,该文件会转换回 session_transcript 原本会返回的内容——重放脚本、记录的环境,以及按顺序排列并带有摘要的调用记录:
ankusdrive journal list
ankusdrive journal export latest -o transcript.py # --json for the whole record
或者,在 Agent 中调用 journal_export(session="latest")(省略 session 即可列出日志)。
保留策略明确规定,而非交由操作系统决定:最多保留 50 个会话文件和 512 MB(ANKUSDRIVE_JOURNAL_KEEP、ANKUSDRIVE_JOURNAL_MAX_MB),优先删除最旧的文件,但绝不删除当前活动会话的文件或最近一小时内写入的文件(ANKUSDRIVE_JOURNAL_GRACE_S);单个会话超过 64 MB(ANKUSDRIVE_JOURNAL_FILE_MAX_MB)时,会保留参数和摘要,但丢弃结果正文。ANKUSDRIVE_JOURNAL_REDACT=1 会对参数、结果和错误中的路径与名称(文档名称、标签、标题栏字段)进行哈希处理——但不会处理 run_script 代码或句柄。这样做的代价是:脱敏后的日志可通过摘要审计,但其中导出的脚本无法运行。
要让记录随模型一起保存,请使用 save_document(path, attach_provenance=True) 保存(默认关闭)。这样,文档的 Meta 映射中就会包含相同的记录——重放脚本、环境和求解器标识,以及每项结果均带 SHA-256 的调用记录;即使 FreeCAD 重新保存文件,这些记录也会保留。记录涵盖构建该文档的调用:从创建该文档的 new_document / open_document 开始,到保存工作区的当前工作进程为止;期间该文档必须保持活动状态,且只记录成功的调用。ANKUSDRIVE_JOURNAL_REDACT 同样适用于此记录。未启用该选项进行保存会移除之前的记录。无需启动 FreeCAD 即可读取记录:
ankusdrive journal export bracket.FCStd -o transcript.py # --json for the whole record
CLI 的用途与限制
CLI 不是 Agent 接口,而是用于人工调试和传输的工具。它有七个子命令:
| 命令 | 用途 |
|---|---|
ankusdrive ping / version | 健康检查——启动工作进程,确认 FreeCAD 可访问 |
ankusdrive box / cylinder | 单次生成基本几何体 → .FCStd(手动冒烟测试) |
ankusdrive export <in.FCStd> -o <out.step> | 无界面格式转换 |
ankusdrive run <script.py> | 在运行中的工作进程内执行任意 FreeCAD Python 代码(设置 __result__ 以返回 JSON) |
ankusdrive mcp | 通过 stdio 启动 MCP 服务——MCP 宿主通过此命令启动 AnkusDrive |
ankusdrive fem cantilever | 运行内置的预设演示 |
ankusdrive journal list / export <session|latest|file> | 读取选择启用的持久化日志:列出过往会话,或将某个会话导出为重放脚本和来源记录 |
Agent 不会调用 CLI。宿主启动 ankusdrive mcp 后,Agent 会通过 stdio 使用 MCP。CLI 的作用是:(a) 启动该服务;(b) 为用户提供一种无需编写 MCP 客户端即可试用工作进程的方式。
决策规则
| 需求 | 使用 |
|---|---|
| 标准 CAD/FEM 操作 | 一流 MCP 工具(第 1 层) |
| 工具已存在,但我需要属性 X | get_object / set_property(第 2 层) |
| 工作台 / API 完全未封装 | run_script(第 3 层) |
| 在 shell 中进行冒烟测试,或启动 MCP | CLI |
多 Agent 设计
上面的路线图旨在深化单个 Agent 的能力。
orchestration/ 层则关注多个 Agent 如何共享
工作:将产品拆分为组件和子组件,并行构建(每个 Agent 都是冷启动的,只能看到自己的契约部分),然后将整体合并
起来,确保接合处确实吻合。设计详情见
docs/MULTI_AGENT.md;其目标是拆分 + 合并,
而不是多人共同编辑同一份实时文档(单个工作进程对应一个
App.ActiveDocument,因此目前不考虑并发修改)。
在一个 MCP 服务上运行并发 Agent — 工作区。 FastMCP 会在线程池中运行同步工具,因此主机可以同时处理多个工具调用。服务维护一个由命名工作区组成的池,每个工作区都有自己的 freecadcmd 进程、App.ActiveDocument 和句柄注册表。每个并发 Agent 在会话开始时通过 use_workspace(name) 认领自己的工作区;
句柄和文档不会跨工作区共享。从未调用 use_workspace 的客户端会逐字节保持以往的单工作进程行为
(所有内容都路由到 default 工作区)。Worker.call() 内部会串行执行,因此两个线程绝不会在同一个进程上交错使用 stdin/stdout 协议。工作区池有数量上限(ANKUSDRIVE_MAX_WORKSPACES,默认值为 4),并会清理空闲工作区(ANKUSDRIVE_WORKSPACE_IDLE_S,默认值为 900s),避免废弃会话泄漏进程;可通过 list_workspaces / close_workspace 管理工作区。
职责划分经过刻意设计:
- AnkusDrive 提供与工具无关的轻量基础工具,使合并结果可验证 —
publish_interface(声明组件的配合基准框架)、merge_assembly(将组件文件合并为一个装配体),以及用于判断合并是否可靠的 关卡:interface_align_check(已发布的基准框架是否对齐?)、interference_check(实体是否相互碰撞?)、envelope_check(是否符合外包络预算?),以及assembly_lock/assembly_lock_check契约锁定文件。这些都是真正的 MCP 工具,任何主机都可以使用。 orchestration/是主机侧的参考协调器 — 明确不属于ankusdrive包。给定一段自由文本需求,它会将其decompose为经过验证的清单,为每个组件分派一个构建 Agent,将它们merge_assembly,读取各关卡结果,并在失败时重新协商 — 仅重新分派失败关卡所涉及的组件 — 最多进行指定轮次。它既可使用真正的 Anthropic 客户端运行,也可使用脚本化存根 (ScriptedClient)进行免费试运行;无论哪种方式,合并和关卡检查都是真正的工作进程调用。任何主机(Claude、其他工具或人工) 都可以使用、替换或忽略它 — 唯一重要的契约是清单和磁盘上的组件文件。
专门的评估阶梯用于衡量拆分 + 合并的表现(tests/test_multiagent_m1.py / _m2.py,可在 CI 中运行),其中包含严格的判定式合并关卡和单 Agent 基线 — 参见
tests/MULTI_AGENT_EVAL.md。早期实验表明,在较难的测试案例中,拆分方案的表现达到或超过单 Agent 基线。
设计,而不只是零件——设计控制层
多 Agent 编排将一个产品划分给团队。另一条独立的轴线,则让设计(而不只是某个零件)成为可参数化、可变化并受控演进的对象——这套机制是 PLM/PDM 工作流所期望的,并映射到 AnkusDrive 确定性、无头且可通过 Git 差异比对的设计粒度上。关键洞见是:构建配方就是特征树;参数是它的输入;重新生成就是再次运行配方——因此,AnkusDrive 无需实时的文件内表达式引擎,也能实现参数化再生和系列表。完整的范围界定与依据见 docs/DESIGN_HIERARCHY.md;面向 Agent 的判断指南位于 design-modularly 技能中。
- 参数化层级 — 配方(
recipe、recipe_validate)是具有命名和声明式输入的构建模板(既是 AnkusDrive 的 PowerCopy/UDF,也是零件内部的参数化模型);relations DAG 通过公式从主参数驱动从动尺寸(pitch_d = module * teeth,仅支持算术运算——不进行迭代求解,也不允许重复驱动);特征模板(feature_instantiate)通过名称将可复用特征移植到参考几何上;带类型的units层会在入口处拒绝量纲错误的输入(长度使用"5 N"会报错,而不会悄悄缩放错误)。 - 变体系列 —
family_materialize以确定性方式将行 × 列设计表展开为一组变体,逐行运行配方,并按表格顺序分配零件编号。 - 标识与生命周期 — items(
items_new)为零件赋予稳定的零件编号标识,使其与文件路径解耦;生命周期状态机(lifecycle_transition:in_work → in_review → released → obsolete)强制已发布状态不可变,并通过外形/配合/功能判定来决定更改时是升级修订版还是分配新的零件编号。 - 变更控制 — ECO(
eco_create)是一等变更记录;在提交前,where_used/change_impact会通过依赖图计算影响范围;baseline_create/baseline_verify用于固定可复现的快照。 - 版本化接口 — 接口类型注册表(
get_interface、nema17_face@1样式的命名/版本化类型)以及 Liskovsubstitutability_check门禁以代码形式强制执行外形/配合/功能兼容性,从而验证替换的零件确实能够配合。 - 项目 —
scaffold_project+project_validate/project_check_references将多 Agent 目录约定提升为一等project.json(清单的清单),其中包含主控/骨架单一事实来源槽位和引用完整性保护机制。
与合并门禁类似,这些都是轻量、确定性且大多无需 FreeCAD 的基础组件——逻辑层可在不启动工作进程的情况下导入和测试。
状态
第三阶段于 2026-05-10 收官(v0.3.0)。第二阶段(2026-04-25)的核心机械设计功能保持完整;第三阶段在其上叠加了意图编码 API。此后,工具集已从约 100 个扩展至 280+ 个工具,经历了多个阶段的扩充:命令层扩展(参数化组件 + 直接特征操作 + 计量)、多 Agent 编排层、广泛的工程分析 + 外部求解器仿真功能(热、CFD/CHT、电磁、声学、FSI、成型、颗粒、光学、多体),以及设计控制(PLM)层(items、配方、变体系列、生命周期、ECO/变更、版本化接口、项目)。
- Worker + 传输 — 长期运行的
freecadcmdworker,通过 stdio 使用逐行 JSON,并确保 stdio 干净(将 FreeCAD C++ 输出重定向到协议 fd 之外)。 - CLI —
ping、version、box、cylinder、export、run、mcp、fem cantilever,以及顶层--version。 - MCP 服务 — 基于 stdio 的 FastMCP,提供 280 多个类型化工具,涵盖文档生命周期、基本体、选择(面/边标签)、完整的 PartDesign(草图器 + 拉伸/凹槽/旋转/孔/放样/扫掠/螺旋/圆角/倒角/阵列/镜像/加厚/拔模)、直接建模特征操作、参数化组件、计量/检查、通用属性反射、质量属性、装配 + 接口门控、TechDraw(包括无头 PDF/SVG/DXF 导出、尺寸、门控)、多视图 + 照片级渲染、FEM(静态 + 模态 + 屈曲 + 热 + 非线性 + 结果探针)、工程分析预言机和外部求解器仿真系列(同步 + 异步
*_submit/job_*)、材料/流体数据库、Design-for-X / 制造检查、设计控制(PLM)层,以及事务。 - 命令层级 1–3 — 新增 21 个工具:参数化组件(
add_gear、add_rack、add_sprocket、add_pulley、add_spring、add_fastener、add_bearing、add_thread)、直接特征操作(fillet_edges、chamfer_edges、shell_solid、add_rib、engrave_text、oring_groove、transform、scale_shape、copy_shape),以及计量/检查(measure_distance、measure_angle、bounding_box、check_shape、section_view、min_clearance)。 - 多 Agent 编排 — AnkusDrive 提供精简的合并原语 + 门控(
publish_interface、merge_assembly、interface_align_check、envelope_check、assembly_lock/_check);主机端参考协调器(orchestration/)会拆解需求、分派各组件构建器、执行合并与门控,并重新协商。参见多 Agent 设计和docs/MULTI_AGENT.md。 - Phase 3 意图编码新增项 — 在 pocket/hole 上提供
direction='into_body'|'away_from_body'和through='wall'|'body'(射线投射墙深度可正确处理中空壳体);intended_for='print'|'machine'|'drawing'可用于孔,并驱动 ModelThread;verify_feature会对比实际与预期的体积变化,以捕获静默失败;保存时通过可见性清理隐藏已消耗的输入;register_handle+run_script的 auto_register 可避免逃生口单向陷阱;list_thread_options会动态显示相互关联的 ThreadType/ThreadSize 枚举;旋转操作包含 OCCT 预检,可标记与轴重合的边并给出可执行的错误提示。 - 选择层 —
list_faces/list_edges/query_faces/resolve_*可生成编辑后仍稳定的几何标签;FEM 约束可直接使用这些标签。 - 渲染 — 主机端软件光栅器(
ankusdrive/render.py)使用逐像素 z 缓冲区(render_view/render_views以 MCPImageContent返回 PNG),另可通过 FreeCAD Render 插件 + 外部渲染器(POV-Ray / LuxCore / Appleseed / Cycles / OSPRay / PBRT)进行照片级渲染render_photoreal。支持矩阵、安装方式和限制:docs/RENDERING.md。 - 仿真能力 — 工程分析预言机(机械元件、结构、耐久性、热、尺寸公差/GD&T),以及会调用 OpenFOAM / Elmer / CalculiX / openEMS / YADE / KrakenOS 的外部求解器系列;这些求解器由
ankusdrive/solvers.py在运行时发现,缺失时会平稳降级。耗时较长的求解使用异步提交→轮询任务模式(*_submit+job_status/job_result/job_list)。目录和结果架构:docs/SIMULATION_TOOLS.md;验证测试套件:docs/SIMULATION_EXAMPLES.md。材料/流体功能通过material_*和fluid_props(机械属性/成型/CoolProp 数据库)提供支持。 - 设计控制(PLM)层 — 配方 + 关系 DAG(参数化再生成)、特征模板、从设计表生成的变体系列、项目/零件编号标识、生命周期/修订状态机、包含使用位置/影响 + 基线的 ECO 更改记录、带版本控制的接口注册表 + Liskov 可替换性门控,以及带引用完整性防护的项目容器。范围与设计依据:
docs/DESIGN_HIERARCHY.md。参见设计,而不只是零件。 - 测试 — 约 90 个文件中共有约 980 个测试函数(worker / MCP / CLI / 渲染 / 确定性 / 编辑稳定性 / 负向路径 / 性能 / 多 Agent / 仿真系列 / 成型 / PLM 层),可通过
tests/run_all.sh(Linux/macOS)或tests/run_all.ps1(Windows — 单解释器,跳过仅适用于 Linux 的求解器系列;参见docs/WINDOWS.md)运行。可靠性测试套件(A 层分类、B 层差异检测、C 层 Agent 循环闭合)需通过RUN_RELIABILITY=1启用;参见tests/RELIABILITY.md。 请参阅docs/ROADMAP.md,了解 Phase 1/2 各切片的记录——其中记录了上文所述功能的构建过程,并在 Phase 2 结束时定稿。尚待处理的工作(FEM 接触/弹簧/绑定细化、feature_tree内省、更深入的外部求解器集成)都在 问题跟踪器中,而不在该文件里。
已提交的展示内容——文档中引用的所有 GIF、渲染图、工程图和导出实体,以及用于重新生成每项内容的脚本——都列在
artifacts/README.md中。
未决问题
- 错误模型:FreeCAD 从 C++ 抛出普通 Python 异常;工作进程会捕获并序列化这些异常,但跨越 JSON 边界后,堆栈上下文仍会丢失一部分。
- 异步/并发:已支持多文档(
list_documents/set_active_document/close_document),所有长时间运行的求解——包括通过fem_run_submit运行的 CalculiX 求解——都可以通过*_submit+job_*模式脱离通道运行。同步的fem_run仍适用于小型求解。一个工作进程仍意味着只有一个主线程:任务中 FreeCAD 侧的步骤(写入求解器输入文件、导入结果)会在该线程上运行,并穿插在各请求之间。
隐私政策
AnkusDrive 完全在你的计算机上运行,不会收集任何信息:没有遥测、分析、账户,也不会从自身代码发起网络请求。它只会读取和写入你指定的文件,以及其配置文件和临时工作目录。你的 MCP 主机(例如 Claude Desktop)会根据主机自身的政策,将工具输入和结果发送给其 AI 模型提供商。完整政策(包括明确说明各项内容的存储位置)见
PRIVACY.md。
正在评估 Claude Desktop 扩展?审核者指南 介绍了安装、设置检查,以及三个附有预期结果的示例提示词。
许可证
本项目根据 Apache License, Version 2.0 授权。提交到本项目的贡献也根据相同条款授权(Apache 2.0 §5:传入 = 传出),这意味着贡献者保留版权,但授予本项目及所有下游用户永久、不可撤销的使用许可,其中包括专利授权。此举旨在让本项目对贡献者保持开放友好,同时确保任何人都不能在日后重新将他人贡献的内容据为专有。
代码采用 Apache-2.0 许可;名称则不然。Apache-2.0 §6 不授予商标权,因此 AnkusDrive 文字商标和
logo/中的品牌素材另行保护——请参阅
TRADEMARKS.md,了解无需征求许可即可进行的行为(提及本项目、声明兼容性、再分发、打包和分叉均符合要求);再分发者必须附带的归属声明见
NOTICE。
参考资料
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。