关于 matlab-build-simbiology-model
用于创建和修改 SimBiology 模型的 MATLAB 技能,可配置组件、反应、规则和事件,适用于桌面、无界面、批处理及远程环境;仅在需要时处理图示布局。
主要功能
- 01创建和修改 SimBiology 模型
- 02配置区室、物种和反应
- 03添加规则、事件、剂量与观测量
- 04加载和保存模型项目
- 05排列并检查模型图示
适用场景
- 01构建药代动力学模型
- 02编辑模型组件和反应
- 03加载并保留现有 .sbproj 图示
- 04准备供审阅的模型图示
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-build-simbiology-model安装后在 Claude Code 中输入/matlab-build-simbiology-model确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreferences/api-cheatsheet-guidance.mdapp-lifecycle-guidance.mddiagram-styling-guidance.mdevacuation-procedure-guidance.mdlayout-strategy-guidance.mdpbpk-layout-guidance.mdpk-library-guidance.mdscripts/addAndPositionCompartment.mbuildLayoutContext.mcheckDiagramLayout.mcomputeSafeReactionPosition.mgetModelByUUID.misAppOpen.mlineIntersectsRect.mloadViaBuilder.mopenLiveBuilder.mpositionAncillaryBlocks.mqueryGridForLine.mrepositionAllReactions.msaveViaBuilder.mupdateContextBlock.m详细介绍
构建 SimBiology 模型
用于构建、修改和绘制 SimBiology 模型的 API 参考、辅助函数和模式。适用于所有 MATLAB 环境(桌面、无头、批处理、远程)。图表/布局功能需要 Model Builder 应用,并且仅在用户请求可视化输出时启用。
适用场景
- 构建或修改 SimBiology 模型(区室、物种、反应、参数、规则、事件、剂量、观测量、变体)
- 在 Model Builder / Analyzer 应用中打开、保存或加载模型
- 设计或调整图表布局
- 关键词:“构建”“创建”“修改”“添加区室/物种/反应”“图表”“布局”
不适用场景
- 仿真和分析(使用
matlab-simulate-simbiology-model) - 参数拟合、群体建模、NCA(使用
matlab-fit-simbiology-model)
必须遵循的规则
1. 先将辅助脚本添加到 MATLAB 路径
每次会话开始时运行:
addpath(fullfile('<WORKSPACE_ROOT>', '.claude', 'skills', 'matlab-build-simbiology-model', 'scripts'));
disp('Helper scripts added to path.')
2. 仅在需要时打开 Builder
默认情况下不要打开 Model Builder。在以下情况下打开:
- 用户明确请求图表、布局或可视化内容
- 输入文件是
.sbproj文件——使用loadViaBuilder保留图表布局/样式(sbioloadproject会丢失这些数据)
即使没有图表,模型也完全可用——只需使用 sbioroot 上的模型对象,即可进行仿真、拟合和分析。
3. 模型构建使用标准 SimBiology API
直接使用 addcompartment、addspecies、addreaction 等函数构建模型。此方法适用于所有环境:桌面、无头、批处理、远程。
model = sbiomodel('MyModel'); disp(model.uuid)
comp = addcompartment(model, 'Central', 1);
addspecies(comp, 'Drug', 100);
addparameter(model, 'ke', 0.1);
rx = addreaction(model, 'Central.Drug -> null');
kl = addkineticlaw(rx, 'MassAction');
kl.ParameterVariableNames = {'ke'};
对于标准 PK 模型(采用标准给药和消除方式的 1 或 2 区室模型),请参考 references/pk-library-guidance.md,了解正确的参数化、命名和规则。无需图表时,直接调用 PKModelDesign。用户请求图表时,按照相同的 PK 库约定手动构建模型,但使用 addAndPositionCompartment 控制布局(参见规则 8b)。
4. 按生物学正向方向编写反应
图表会在产物上绘制箭头,在反应物上绘制普通线条(依据反应字符串的正向方向)。反向编写反应会导致箭头错误,即使动力学等效也一样。
% CORRECT — L and R get plain lines, C gets an arrow
addreaction(model, 'cell.L + cell.R <-> cell.C');
% WRONG — same kinetics but L and R get arrows (they're "products" now)
addreaction(model, 'cell.C <-> cell.L + cell.R');
指南:
- **结合:**编写
A + B -> C(底物在左侧,复合物在右侧) - **降解/消除:**编写
Drug -> null(而非null -> Drug) - **合成:**编写
null -> mRNA(而非mRNA -> null) - **转运:**编写
Source.Drug -> Dest.Drug(源在左侧)
5. 始终为物种和反应作用域参数使用限定名称
始终使用物种和反应作用域参数的限定名称进行引用。如果名称中有任何部分不是有效的 MATLAB 变量名,请在构建限定名称前用方括号括起该部分。
- 物种:
CompartmentName.SpeciesName(例如,Central.Drug、Peripheral.[Drug-bound]) - 反应作用域参数:
ReactionName.ParameterName(例如,Elimination.ke)
限定名称始终恰好只有一级——仅包含直接父区室。在反应字符串中,Body.Central.Drug 这类多级路径无效。这绝不会产生歧义,因为区室名称在整个模型中必须唯一(无论嵌套深度如何,SimBiology 都会强制执行此规则)。因此,Central.Drug 始终足够。
区室命名规则:
- 名称在整个模型中必须唯一——即使位于不同的嵌套层级,也不能有两个区室同名
- 如果需要层级式命名,请使用下划线:
Body_Central(不要将多个嵌套区室都命名为Central) - 物种名称在同一区室内必须唯一,但可在不同区室中重复(通过
Compartment.Species消除歧义)
6. 使用现代属性名称(Value、Units、Constant)
SimBiology 对象(物种、区室、参数)共用统一的属性接口。请始终使用现代名称:
| 现代名称 | 已弃用(切勿使用) | 适用对象 |
|---|---|---|
Value | InitialAmount、Capacity | 物种、区室、参数 |
Units | InitialAmountUnits、CapacityUnits、ValueUnits | 物种、区室、参数 |
Constant | ConstantAmount、ConstantCapacity、ConstantValue | 物种、区室、参数 |
sp.Value = 100; % NOT sp.InitialAmount
sp.Units = 'milligram'; % NOT sp.InitialAmountUnits
sp.Constant = false; % NOT sp.ConstantAmount
comp.Value = 1; % NOT comp.Capacity
comp.Units = 'liter'; % NOT comp.CapacityUnits
comp.Constant = true; % NOT comp.ConstantCapacity
p.Value = 0.1; % NOT redundant, but never use p.ValueUnits or p.ConstantValue
p.Units = '1/hour';
p.Constant = true;
7. 在运行 sbioreset 前关闭 Builder 和 Analyzer
sbioreset 不会关闭这些应用,导致窗口遗留:
try mb = SimBiology.web.desktophandler.getModelBuilder();
if ~isempty(mb) && isfield(mb,'webWindow') && isvalid(mb.webWindow), mb.webWindow.close(); end
catch, end
try ma = SimBiology.web.desktophandler.getModelAnalyzer();
if ~isempty(ma) && isfield(ma,'webWindow') && isvalid(ma.webWindow), ma.webWindow.close(); end
catch, end
pause(1); sbioreset;
8. 图示规则(仅在用户要求绘制图示时适用)
以下规则仅在用户要求绘制图示或布局时适用。 纯模型构建时请跳过所有这些规则。
模型大小限制(前置条件): 布局辅助函数在总区块数(物种 + 反应)超过 400 时会退出。对于大型模型,请跳过自动布局,改用简单的网格定位(将反应放在相连物种的中点)。
a. 使用 addAndPositionCompartment 进行图示布局
构建图示时,请使用 addAndPositionCompartment,而不是直接使用
addcompartment + setBlock,因为它会以原子方式创建、定位并验证每个区室。
% speciesInfo: cell array of structs with .Name, .Value, .Position
speciesInfo = {
struct('Name', 'Drug', 'Value', 100, 'Position', [40, 30, 50, 16]);
struct('Name', 'DrugBound', 'Value', 0, 'Position', [140, 30, 100, 16])
};
[comp, sp] = addAndPositionCompartment(model, 'Central', 1, [20, 20, 280, 80], speciesInfo);
% sp is a SimBiology Species ARRAY — index with sp(1), sp(2), NOT sp{1}
b. 图示构建顺序
- 首先打开 Builder——只有 Builder 创建图示后,图示才会存在。未执行此步骤时,所有
simbio.diagram.*调用和addAndPositionCompartment都会失败。 - 提前规划所有区室的
[x y w h]位置(至少留出 80 px 间距) - 每次构建一个区室,使用
addAndPositionCompartment - 添加所有参数(包括规则 LHS 目标)、反应、规则、剂量和事件
- 执行
repositionAllReactions(model),然后执行checkDiagramLayout(model)——修复问题,直到违规数为零 - 执行
positionAncillaryBlocks(model)——将规则/参数区块以网格形式定位在右侧
c. 相连区室之间留出 80 px 间距
repositionAllReactions 会将区室间反应节点(15×15)放置在这些间隙中。间距不足时,反应线会穿过区室区块。对于有许多共用反应(3 个以上)的区室,请将间距增加到 120 px。
d. 必须在放置后进行验证
放置所有区块后:
repositionAllReactions(model);
results = checkDiagramLayout(model);
if results.nTotal > 0
for i = 1:numel(model.Reactions)
pos = computeSafeReactionPosition(model, model.Reactions(i));
simbio.diagram.setBlock(model.Reactions(i), 'Position', pos);
end
results = checkDiagramLayout(model);
end
positionAncillaryBlocks(model); % must run LAST, after all objects exist
e. 始终使用安全打开模式打开 Builder
调用 simBiologyModelBuilder(model) 前,务必先检查
isAppOpen('builder')。如果 Builder 已打开,请将其关闭,等待 2s 后再重新打开。
if isAppOpen('builder')
try
mb = SimBiology.web.desktophandler.getModelBuilder();
if ~isempty(mb) && isfield(mb, 'webWindow') && isvalid(mb.webWindow)
mb.webWindow.close();
end
catch, end
pause(2);
end
% If Analyzer is open, it already has a model loaded — open Builder
% without an argument so it picks up the Analyzer's active model.
% Passing a model argument when Analyzer is open can cause conflicts.
if isAppOpen('analyzer')
simBiologyModelBuilder();
else
simBiologyModelBuilder(model);
end
f. 切勿为了修改而关闭 Builder
模型句柄位于 sbioroot 上——所有代码都会对实时模型进行操作,并实时更新图示。只有在用户明确要求时才关闭。
辅助函数(scripts/)
模型构建(始终可用)
| 函数 | 签名 | 用途 |
|---|---|---|
getModelByUUID | model = getModelByUUID(uuid) | 按 UUID 查找模型 |
图表与构建器(仅在用户请求图表/布局时使用)
| 功能 | 签名 | 用途 |
|---|---|---|
addAndPositionCompartment | [comp,sp] = addAndPositionCompartment(model,name,cap,compPos,speciesInfo,Name=Value) | 原子式创建区室和物种并设置位置。**sp 是 Species 数组——使用 sp(1) 索引,而非 sp{1}。**选项:FontWeight("bold")、TextLocation("center")、Padding(20)、AutoExpand(true)、AutoFixPositions(true) |
checkDiagramLayout | results = checkDiagramLayout(model) | 检查包含关系、线条穿过方块以及重叠 |
computeSafeReactionPosition | pos = computeSafeReactionPosition(model,rxn) | 计算无交叉的反应节点位置 |
repositionAllReactions | nFixed = repositionAllReactions(model) | 批量重新定位所有反应(最多 3 轮) |
positionAncillaryBlocks | n = positionAncillaryBlocks(model) | 将规则/参数方块按网格排列在区室右侧 |
openLiveBuilder | openLiveBuilder(model) | 使用安全打开模式打开 Builder |
isAppOpen | tf = isAppOpen(appName) | 检查 Builder/Analyzer 是否已打开 |
loadViaBuilder | model = loadViaBuilder(filePath) | 加载 .sbproj 并保留图表 |
saveViaBuilder | saveViaBuilder(filePath) | 从 Builder 保存并保留图表 |
lineIntersectsRect | hit = lineIntersectsRect(x1,y1,x2,y2,rect) | 共享几何辅助函数(由布局脚本内部使用) |
checkDiagramLayout 输出
results.nTotal % total violations (must be 0 before presenting)
results.nContainment % species outside parent compartment
results.nLineThrough % connection lines through unrelated blocks
results.nOverlap % blocks <10px apart
API 快速参考
模型
sbiomodel(name)— 创建模型;model.uuid— 唯一 IDsbioloadproject('file.sbproj')— 返回以模型名称为字段的 struct;动态提取:proj = sbioloadproject('file.sbproj'); fn = fieldnames(proj); model = proj.(fn{1});copyobj(model)— 深度克隆(不会复制图表布局);verify(model)— 检查一致性sbioreset— 清除所有模型(先关闭应用!)
区室
addcompartment(model, name, value)comp.Value、comp.Constant、comp.Units、model.Compartments- **单位一致性:**如果任何组件带有单位,则所有组件都必须带有单位(区室、物种、参数)。缺少单位会在仿真/拟合时导致
'Dimensional analysis failed'错误。
物种
addspecies(comp, name, value)sp.Value、sp.Units、sp.BoundaryCondition、sp.Constantsp.Parent.Name— 父区室;model.Species
参数
addparameter(model, name, value)— 作用域为模型addparameter(kineticLaw, name, value)— 作用域为反应p.Value、p.Units、p.Constant、model.Parameters
反应
addreaction(model, 'A -> B')— 正向;'A <-> B'— 可逆kl = addkineticlaw(rx, 'MassAction'); kl.ParameterVariableNames = {'k1'}(可逆反应使用{'kf','kr'})- 多区室:
'Central.Drug -> Peripheral.Drug'
规则、事件、剂量
addrule(model, 'x = expr', ruleType)—'initialAssignment'、'repeatedAssignment'、'rate'- **规则/反应互斥:**作为速率规则或重复赋值规则左侧的物种,不能同时作为反应物或产物出现在反应中。应择一控制其动态。
- **规则左侧要求:**左侧必须是现有的物种、参数或
Constant = false的区室。应在创建规则之前创建参数(不要创建规则后再补救——这样可确保用于布局的图表方块已存在):p = addparameter(model, 'RO', 0); p.Constant = false; addrule(model, 'RO = Complex / (Target + Complex)', 'repeatedAssignment'); addevent(model, 'trigger', {'action1', 'action2'})- **事件动作要求:**事件动作中修改的任何参数都必须设置
Constant = false(参数默认为true):p = sbioselect(model, 'Type', 'parameter', 'Name', 'kgrow'); p.Constant = false; addevent(model, 'Tumor.Cancer < 1e6', {'kgrow = kgrow * 0.5'}); sbiodose(name, 'schedule')/sbiodose(name, 'repeat')- Schedule:
.TargetName、.Amount、.Time、.Rate - Repeat:
.TargetName、.Amount、.StartTime、.Interval、.RepeatCount adddose(model, d)/removedose(model, d)
可观测量与变体
addobservable(model, name, expression)— 对逐元素运算使用./和.*- StatesToLog 注意事项: 如果可观测量引用了一个常量参数(例如,
'Drug ./ Vd'),请将该参数添加到StatesToLog,否则记录结果将为 NaN。只要依赖项存在,可观测量本身就会自动记录(不要将可观测量添加到 StatesToLog — 它只接受物种、参数和区室)。 v = addvariant(model, name),然后使用addcontent(v, {'type','name','prop',val})v.Content、getvariant(model, name)
仿真配置
cs = getconfigset(model, 'active')cs.StopTime、cs.SolverType('ode15s'、'ode45'、'sundials')cs.RuntimeOptions.StatesToLog—'all'或句柄数组
选择
sbioselect(model, 'Type', type, 'Name', name)- 对于反应:使用
'Reaction'属性(而不是'Name')
核心模式
模型创建(标准 — 无图示)
model = sbiomodel('MyModel');
disp(model.uuid)
comp = addcompartment(model, 'Central', 1);
addspecies(comp, 'Drug', 100);
addparameter(model, 'ke', 0.1);
反应
% MassAction (always use qualified species names)
rx = addreaction(model, 'Central.Drug -> null');
kl = addkineticlaw(rx, 'MassAction');
kl.ParameterVariableNames = {'ke'};
% Custom rate
rx = addreaction(model, 'Central.E + Central.S <-> Central.ES');
rx.ReactionRate = 'kf*Central.E*Central.S - kr*Central.ES';
% Multi-compartment transfer
rx = addreaction(model, 'Central.Drug -> Peripheral.Drug');
% Species with invalid MATLAB variable names
rx = addreaction(model, 'Central.[Drug-bound] -> Central.[Drug-free]');
移除组件
delete(sbioselect(model, 'Type', 'species', 'Name', 'Drug'));
delete(sbioselect(model, 'Type', 'reaction', 'Reaction', 'Drug -> null'));
removedose(model, model.Doses(1)); % doses use removedose, not delete
剂量
% Bolus
d = sbiodose('Dose', 'schedule');
d.TargetName = 'Drug'; d.Amount = 100; d.Time = 0;
adddose(model, d);
% Repeat dose
d = sbiodose('RepeatDose', 'repeat');
d.TargetName = 'Drug'; d.Amount = 50;
d.StartTime = 0; d.Interval = 8; d.RepeatCount = 3;
adddose(model, d);
事件、变体、可观测量
% Event modifying a parameter — mark non-constant first
p = sbioselect(model, 'Type', 'parameter', 'Name', 'ke');
p.Constant = false;
ev = addevent(model, 'time >= 10', {'ke = ke * 2'}); ev.Name = 'EnzymeInduction';
% Event modifying a species (species default Constant=false — no extra step)
ev = addevent(model, 'time >= 10', {'Drug = 50'}); ev.Name = 'RescueDose';
v = addvariant(model, 'HighDose'); addcontent(v, {'parameter','ke','Value',0.5});
obs = addobservable(model, 'DrugConc', 'Drug ./ Central');
保存模型
- 标准方式:
save('mymodel.mat', 'model')/loaded = load('mymodel.mat'); model = loaded.model;不要使用sbiosaveproject(已弃用,且需要通过基础工作区进行变通处理)。 - 带图示(
.sbproj):saveViaBuilder('name.sbproj')/loadViaBuilder(path)(需要打开 Builder) - 切换模型: 先让用户保存 → 关闭 Builder →
pause(2)→simBiologyModelBuilder(newModel) - 完整的切换/协调模式请参阅
references/app-lifecycle-guidance.md。
图示基础(仅当用户要求图示/布局时)
坐标系
Position = [x y width height],其中 (x, y) 是左上角。
标准块大小
| 块类型 | 默认大小 | 备注 |
|---|---|---|
| 物种 | [50, 16] | 按名称长度缩放宽度:<=5 个字符 → 50,6-12 个字符 → 100,13 个字符以上 → 130 |
| 反应 | [15, 15] | |
| 规则 | [20, 20] |
根据内容设置区室大小
| 物种数量 | 大小 | 备注 |
|---|---|---|
| 1 | 160 x 100 | 单个物种,居中 |
| 2(独立) | 240 x 170 | 垂直排列 |
| 2(链式) | 400 x 100 | 并排排列 |
| 3-5 | 160+n*50 x 100+n*35 | 按内容缩放 |
| 6+ | 240+n*50 x 220+n*35 | 按行排列,必要时使用多行 |
内部边距:四周至少 30 px。
按行放置物种(3 个及以上)
在水平行中均匀分布物种,位置为 y + height/2 - 8,与区室边缘相距
40 px。按名称长度缩放物种宽度:
<=5 个字符 → 50,6-12 个字符 → 100,13 个字符以上 → 130。
按连接方向排列物种
当一个区室中的 2 个及以上物种连接到不同的外部区室时,应调整排列顺序,使每个物种朝向其连接方向。这样可以避免连接线穿过同级物种。
- 水平相邻: 将连接到左侧的物种放在左边缘,将连接到右侧的物种放在右边缘。
- 垂直堆叠: 将连接到上方/左侧的物种放在上方,将连接到下方/右侧的物种放在下方。
- 示例: Blood 中有 Neutrophil(向左连接到 Transit3)和 Lymphocyte(向左上连接到 Spleen)。将 Lymphocyte 放在上方、Neutrophil 放在下方,避免连接线交叉。
布局规则
硬性要求:
- 块之间不得重叠(区室内的物种除外)
- 标签清晰可见 — 不与其他块重叠
- 同一层级的区室应水平/垂直对齐
- 区室间反应应位于两个区室之外(间隙中)
- 连接线不得穿过无关的块
- 反应与物种之间至少相距 50 px
优先放置方式: 7. 消除/降解反应应放在其所属区室内(表示过程在本地发生,而非跨越边界)
按模型类型划分的流向
| 模型类型 | 流向 |
|---|---|
| PKPD | PD 位于左上方,PK 位于右下方 |
| 代谢模型 | 从上到下 |
| PBPK | 按循环系统分列 |
| 简单 PK | 从左到右或沿对角线 |
参考资料
按需加载以获取详细指导:
references/layout-strategy-guidance.md— 策略选择、构建前检查清单、7 种方案references/pbpk-layout-guidance.md— PBPK 循环系统和 ACAT 链式布局references/evacuation-procedure-guidance.md— 针对现有模型的 5 阶段重排流程references/api-cheatsheet-guidance.md— 完整的 simbio.diagram API(getBlock、setBlock、lines、clones)references/app-lifecycle-guidance.md— 切换模型、协调 Analyzerreferences/diagram-styling-guidance.md— 颜色、字体、克隆机制references/pk-library-guidance.md— 用于标准 PK 模型的 PKModelDesign
版权所有 2026 The MathWorks, Inc.