1. 为什么我要让 AI Agent 直接操作 Simulink
如果你平时用 MATLAB/Simulink 做电力电子、电机控制或者整车仿真,大概率经历过这种循环:改一个参数、点一次运行、切到 Scope 看波形、发现不对、再改回来。模型一复杂,光找某个 Gain 模块就能翻半天。Simulink Agentic Toolkit 就是冲着这个痛点来的——它是 MATLAB 官方提供的 MCP(Model Context Protocol)工具包,把模型读取、参数查询、模型编辑、代码执行这些能力封装成标准工具,让 AI Agent 通过 JSON-RPC 直接调用 MATLAB 引擎。
简单说,它能让 AI Agent 帮你读模型结构、查参数、改模块、跑仿真,而不是只能对着聊天框给你贴一段代码让你自己复制。适合两类人:一类是 MATLAB/Simulink 工程师,想让 Agent 帮忙做重复性的模型检查和批量修改;另一类是 AI Agent 开发者,想把 Simulink 当成一个可编程工具接进自己的 Agent 工作流。
但真上手你会发现,MCP 配置这一步坑不少:函数注册失效、命名空间依赖缺失、传参类型不对、路径格式不认。这篇就把我从零跑通 Simulink Agentic Toolkit MCP 的全过程拆开,包括可复制的 config.toml 和 settings.json 骨架、TaoToken 统一 Key 接入、连通性验证动作,以及一份能直接照着排的报错清单。目标只有一个:让你一次性跑通 Agent 对 Simulink 模型的读写调用。
2. TaoToken 前置:统一 Key 与 API 通道
在配 MCP 之前,先把模型通道搞定。因为 Agent 要调用大模型来理解你的指令、生成 MATLAB 代码,这一步绕不开。我这边用的是 TaoToken 的统一 Key 方案,一个 Key 走通模型对话和编码类请求,省得在多个平台之间来回切。
TaoToken 在这里的角色是模型 API 通道:你的 Agent(不管是 Hermes、Claude Code 还是自己写的客户端)通过它拿到模型能力,MCP 服务器负责把模型产出的意图翻译成 MATLAB 命令。两者是配合关系,不是替代关系。
接入步骤不复杂,按下面走:
第一步,打开模型对话页面确认通道可用:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=model_chat
第二步,进控制台创建 API Key:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=console
第三步,在 API Keys 页面复制你的 Key,后面写进 Agent 配置:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api_keys
如果你主要做长期编码和 Agent 任务,建议直接看 Coding Plan,额度模型更适合高频调用:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding_plan
注意:Key 只存在本地配置文件里,不要提交到 Git,也不要在截图里露出完整字符串。我习惯用环境变量
TAOTOKEN_API_KEY注入,配置文件里只写变量名。
拿到 Key 之后,Agent 侧的模型通道就通了。接下来才是 MCP 服务器和 Simulink 的对接。
3. 可复制配置:config.toml 与 settings.json 骨架
这一节是全文的核心,直接给可复制的配置。不同 Agent 客户端的配置文件名不一样,我按最常见的两种给:config.toml(Rust 系客户端、部分 CLI Agent 用)和settings.json(VS Code 系插件、Claude Code 类客户端用)。你按自己用的客户端挑一个。
先看config.toml骨架:
# ~/.agent/config.toml [model] provider = "taotoken" api_key_env = "TAOTOKEN_API_KEY" base_url = "https://taotoken.net/api" model = "claude-sonnet-4-20250514" [mcp_servers.matlab] command = "E:\\matlab-toolkits\\simulink\\bin\\matlab-mcp-server.exe" args = [ "--extension-file", "C:\\Users\\yourname\\.matlab\\agentic-toolkits\\simulink\\tools\\tools.json" ] env = { MATLAB_ROOT = "C:\\Program Files\\MATLAB\\R2024b" }再看settings.json骨架:
{ "model": { "provider": "taotoken", "apiKeyEnv": "TAOTOKEN_API_KEY", "baseUrl": "https://taotoken.net/api", "model": "claude-sonnet-4-20250514" }, "mcpServers": { "matlab": { "command": "E:\\matlab-toolkits\\simulink\\bin\\matlab-mcp-server.exe", "args": [ "--extension-file", "C:\\Users\\yourname\\.matlab\\agentic-toolkits\\simulink\\tools\\tools.json" ], "env": { "MATLAB_ROOT": "C:\\Program Files\\MATLAB\\R2024b" } } } }几个必须注意的点,我踩过:
matlab-mcp-server.exe是 Windows 程序,--extension-file参数必须是 Windows 路径格式(C:\Users\...)。如果你在 WSL 里跑 Agent,别写/mnt/c/...,服务器不认。这个坑我定位了很久,一开始以为是权限问题,其实是路径格式。
tools.json的路径要指向你实际安装 Simulink Agentic Toolkit 的位置。默认在%USERPROFILE%\.matlab\agentic-toolkits\simulink\tools\tools.json,但如果你手动挪过目录,记得改。
base_url写https://taotoken.net/api,不要带 UTM 参数,那是给浏览器用的,API 调用不需要。
配置写完后,重启 Agent 客户端。看到类似下面的输出,说明 MCP 服务器连上了:
MCP server 'matlab' connected 14 MCP tools available: model_overview, model_read, model_query_params, ...工具列表能出来,只是第一步。真正调用能不能通,还得看下一节的验证。
4. 验证请求:从连通性到模型读写
配置连上不代表能用。我建议按“先连通、再读、后写”的顺序验证,每一步都有明确的成功标志。
4.1 连通性验证
在 Agent 里发一条最简单的指令,让它调用model_overview:
请调用 matlab MCP 的 model_overview 工具,参数 model="Inverter3Phase.slx", scope="root", detail="tree"如果返回类似下面的结构,说明 MCP 通道和 MATLAB 引擎都通了:
model: 'Inverter3Phase' scope: 'Inverter3Phase' block_count: 30 blocks: [...]如果这一步就报未定义函数 'model_overview',别急着怀疑配置,先跳到第 5 节看函数注册失效的排查。
4.2 模型读取验证
连通之后,验证读能力。让 Agent 查一个具体模块的参数:
调用 model_query_params,查询 Inverter3Phase 里 Gain 模块的 Gain 值成功的话会返回模块路径和参数键值对。这一步能过,说明find_system、get_param这条链路是通的。
4.3 模型写入验证
写操作风险高一点,建议先用一个临时模型试。让 Agent 执行:
调用 evaluate_matlab_code,运行以下代码: new_system('mcp_test'); add_block('simulink/Sources/Sine Wave', 'mcp_test/Sine1'); save_system('mcp_test');然后在 MATLAB 里open_system('mcp_test'),能看到 Sine Wave 模块就说明写能力正常。
4.4 完整闭环验证
三步都过之后,跑一个完整闭环:让 Agent 读模型、改一个参数、跑仿真、读回结果。我用的是一个三相逆变器模型,Agent 通过 MCP 依次执行了evaluate_matlab_code检查模块库、run_matlab_file构建模型、model_overview验证结构、evaluate_matlab_code跑仿真并打开 Scope。最终 Scope 里出现四组波形:三相调制波、六路 PWM 脉冲、桥臂输出电压 uab、滤波后三相正弦波。到这一步,Agent 对 Simulink 的读写调用就算真正跑通了。
5. 本篇常见错排查清单
这一节按报错现象组织,你遇到哪个查哪个。
5.1 未定义函数 'model_overview'
现象:MCP 连接成功,14 个工具都列出来了,但调用任何一个都报未定义函数。
原因:tools.json里映射的函数名是顶层函数,但实际函数在+sage命名空间下,顶层根本不存在。
排查:在 MATLAB 里执行which sage.graph_read,如果返回+sage\graph_read.p,说明函数在命名空间里。再执行which model_overview,如果返回未找到,就是这个问题。
解决:创建原生 API 包装函数。在tools\common\下新建model_overview.m,用find_system、get_param重写。核心代码:
function result = model_overview(model, scope, detail) if isstring(model), model = char(model); end if isstring(scope), scope = char(scope); end if isstring(detail), detail = char(detail); end if endsWith(model, '.slx') model = model(1:end-4); end if ~bdIsLoaded(model) load_system(model); end if nargin < 2 || isempty(scope) || strcmp(scope, 'root') scope = model; end blocks = find_system(scope, 'SearchDepth', 1, 'Type', 'block'); result = struct(); result.model = model; result.scope = scope; result.blocks = {}; for i = 1:length(blocks) blk = struct(); blk.name = blocks{i}; blk.type = get_param(blocks{i}, 'BlockType'); result.blocks{end+1} = blk; end result.block_count = length(result.blocks); end同样方式补model_read.m、model_query_params.m、model_resolve_params.m。
5.2 无法解析名称 'sage.internal.utils.SystemComposerUtils'
现象:直接调用sage.graph_read时报内部依赖缺失。
原因:+sage\+internal\+utils目录完全缺失,SystemComposerUtils、StateflowUtils这些类找不到。根因通常是 toolkit 版本和 MATLAB 版本不匹配,比如 R2026a 的 toolkit 装在 R2024b 上。
解决:创建 stub 文件补上最小返回值。
utilsDir = 'E:\matlab-toolkits\simulink\tools\common\+sage\+internal\+utils'; mkdir(utilsDir); fid = fopen(fullfile(utilsDir, 'SystemComposerUtils.m'), 'w'); fprintf(fid, ['classdef SystemComposerUtils\n' ... ' methods(Static)\n' ... ' function result = getSystemComposerInfoFromPath(varargin)\n' ... ' result = struct();\n' ... ' result.isSystemComposer = false;\n' ... ' end\n' ... ' end\n' ... 'end\n']); fclose(fid); fid = fopen(fullfile(utilsDir, 'StateflowUtils.m'), 'w'); fprintf(fid, ['classdef StateflowUtils\n' ... ' methods(Static)\n' ... ' function result = isSFSID(varargin)\n' ... ' result = false;\n' ... ' end\n' ... ' end\n' ... 'end\n']); fclose(fid);5.3 包装函数参数类型错误
现象:包装函数写好了,但一调用就报参数类型不对。
原因:MCP 服务器传给 MATLAB 的参数可能是string类型,不是char。很多内置函数只认char。
解决:每个包装函数开头都加类型转换:
if isstring(model), model = char(model); end if isstring(scope), scope = char(scope); end if isstring(detail), detail = char(detail); end这个坑很隐蔽,因为单独在 MATLAB 里测没问题,只有走 MCP 才触发。
5.4 MCP 服务器启动失败
现象:Agent 启动时报 MCP server 连接失败。
排查顺序:先确认matlab-mcp-server.exe路径存在;再确认--extension-file指向的tools.json存在;最后检查路径格式,必须是 Windows 格式,WSL 路径不认。
5.5 Simulink 侧常见问题
MCP 通了之后,问题就转到 Simulink 本身了。我整理了几个高频的:
| 现象 | 原因 | 解决 |
|---|---|---|
| From Workspace 变量丢失 | 工作区变量被清除 | 改用 Sine Wave + MATLAB Function |
| IGBT 不导通,输出恒为 0 | R2024b powerlib 兼容性问题 | 改用 Ideal Switch |
| 电压测量输出为负 | LConn1/LConn2 极性与直觉相反 | 交换连接 |
| 开关不响应 | 比较器输出 boolean,开关需要 double | 加 Data Type Conversion |
| Scope 只显示 1 个图 | LayoutDimensions 默认 [1,1] | 设为 [4,1] |
遇到 Simulink 模块行为异常,我的经验是先用最简电路隔离:DC 源 → 开关 → 电阻 → 地。最简电路能跑通,再往复杂模型上叠。
6. 跑通之后:把 Agent 接进你的日常流程
MCP 配置和排错都过了之后,真正有价值的是把它接进日常。我现在的用法是:模型检查类任务直接让 Agent 走 MCP 读结构、查参数,批量改模块名或参数值;仿真调试类任务让 Agent 改一行、跑一次、读回波形,比手动拖模块快很多。但有一点要清醒:AI 对 Simulink 底层行为的理解不一定准,尤其是电力电子器件的导通逻辑、求解器步长这些,最终还得靠实测波形验证。
如果你还没配模型通道,先去把 TaoToken 的 Key 建好,再回来配 MCP:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api_keys
接入文档在这里,配置字段有疑问可以对照:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc
长期做编码和 Agent 任务的,Coding Plan 更划算:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding_plan
最后留一个我踩过的坑当收尾:tools.json里的函数映射和实际函数位置不一致时,不要急着改tools.json,因为它是 toolkit 自带的,改了升级会覆盖。正确做法是在tools\common\下补顶层包装函数,让映射能找到目标。这个思路在遇到其他 MCP 工具包时也通用——映射层不动,补适配层。