用途
在 Simulink 项目中整理 .satk/library-kg/ 库知识索引,帮助智能体更好地选择模块。该技能从 .satk/library-cache/*.json 中的模块元数据推断分类与描述,将整理结果保存到 .satk/library-curation.json,然后重新生成知识图谱(KG)。
何时使用
- 用户希望将某些模块标记为常用或重要模块
- 用户希望修正自动分配的分类
- 用户希望改进模块描述以提升选择效果
- 用户询问“如何让智能体优先选择某些模块?”
- 从 building-simulink-models 的 Gate 3 调用
何时不使用
- 阻塞、弃用或保护模块 → configuring-block-policy
- 正在构建模型 → building-simulink-models
- 声明存在哪些库 → building-simulink-models 中的 Library Setup 门
前置条件
satk-libraries.json 或 .satk/reuse-libraries.json 必须存在,且已声明库。
整理规则
- 对于所有已声明库中所有 metadataQuality 为 "low" 和 "medium" 的模块,自定义描述是强制性的。这些模块没有有用信息,必须为每个此类模块编写简短的、面向使用意图的描述,以帮助智能体选块。不要因为文件大或看似与当前任务无关而跳过模块。
- "high" 质量模块的自定义描述是鼓励的但可选。
- 尽可能为更多模块编写自定义描述。完成 low/medium 后,再覆盖 high 模块可进一步改进 KG。
- 按分类分批处理。将模块分组,一起推断描述,以易读的块形式呈现给用户。
- 绝不写模板化或机械式描述。像 "Mathematical operation: gain" 或 "Signal routing utility: mux" 这样的描述毫无用处——它们只是重述分类和名称。每条描述必须是深思熟虑、面向意图的描述,说明何时使用该模块以及它解决什么建模问题(例如用 "Scale a signal by a constant factor — use for unit conversion, controller gains, or applying physical constants" 代替 "Mathematical operation: gain")。
模式
- 自动(来自 Gate 3 的 "Automatic" 选项)——推断所有内容,无需逐步暂停即提交,最后呈现结果供审查。
- 引导(来自 Gate 3 的 "Guided setup" 或用户直接调用)——在每一步提出建议,等待用户确认后再继续。
开始前先确定模式。未完成模式选择不得继续。
工作流程
- 如果 .satk/library-kg/index.md 已存在,从步骤 1(审查现有状态)开始;否则从步骤 2 开始。
- 审查(仅当 KG 存在时)——读取 index.md 和 common.md,向用户总结当前状态(库、模块数量、分类、常用模块)。
- 模式选择——确定 Automatic 或 Guided。未完成此步骤不得继续。
- 描述——确保缓存存在(见 API),然后完整读取所有 .satk/library-cache/*.json 文件。如果文件超出读取限制,分块读取直到每个模块都已处理。应用上述整理规则——为模块编写自定义描述,优先处理 low/medium 质量。在为所有缓存文件中每个 low/medium 质量模块编写描述之前,不要进入步骤 4。保存到 customDescriptions。
- 常用模块——提议哪些模块应标记为常用。考虑覆盖多样化分类和频繁建模工作流的模块。保存到 commonBlocks。
- 分类——最终确定分类定义(名称、描述、各 3-5 个关键词)。允许用户通过 categoryAssignments 修正单个模块的分类分配。
- 完整性检查——保存前,统计所有缓存文件中 low/medium 质量模块总数,以及已有自定义描述的数量。向用户报告覆盖率(例如 "275/275 low/medium blocks described, 120/285 high blocks described")。如果 low/medium 模块覆盖率低于 100%,不得继续。
- 保存并生成——通过 library.LibraryCuration.save(projectRoot, curation) 保存所有整理数据,然后运行 library.kg.Populate.run(projectRoot)。向用户呈现输出摘要。
API
确保缓存存在:
libConfig = library.LibraryConfig.load(projectRoot);
library.LibraryCatalog.getOrCreate(libConfig, projectRoot);
读取模块元数据:直接读取 .satk/library-cache/*.json。每个文件格式:
{
"libraryName": "MotorLib",
"description": "Motor control library",
"blocks": [
{
"name": "SpeedController",
"maskType": "SpeedCtrl",
"blockType": "SubSystem",
"maskDescription": "Closed-loop speed regulation with anti-windup",
"description": "",
"pathCategory": "Controllers",
"metadataQuality": "high",
"referenceBlock": "MotorLib/Controllers/SpeedController"
}
]
}
保存整理数据:
projectRoot = prefdir();
curation = library.LibraryCuration.load(projectRoot);
curation.commonBlocks = {'Speed Controller', 'Torque Estimator'};
curation.categories = struct('name', 'motors', 'description', 'Electric motors', 'keywords', {{'motor', 'drive'}});
% Use containers.Map — supports any block name as key
curation.customDescriptions = containers.Map('KeyType', 'char', 'ValueType', 'char');
curation.customDescriptions('Unit Delay') = 'Delay signal by one sample period';
curation.customDescriptions('1-D Lookup Table') = 'Interpolate output from breakpoint-value pairs';
curation.categoryAssignments = containers.Map('KeyType', 'char', 'ValueType', 'char');
curation.categoryAssignments('DC Current Controller') = 'motor-control';
library.LibraryCuration.save(projectRoot, curation);
library.kg.Populate.run(projectRoot);
重要:customDescriptions 和 categoryAssignments 必须使用 containers.Map(而非 struct)。struct 字段名不能包含空格或连字符,而大多数 Simulink 模块名含有它们。
磁盘上的 JSON 格式:
{
"customDescriptions": [
{"block": "Unit Delay", "value": "Delay signal by one sample period"},
{"block": "1-D Lookup Table", "value": "Interpolate output from breakpoint-value pairs"}
],
"categoryAssignments": [
{"block": "DC Current Controller", "value": "motor-control"}
]
}
整理字段
| 字段 | 类型 | 作用 |
|---|---|---|
| commonBlocks | cell array of strings | 无论质量分数如何,始终显示在 common.md 中 |
| categories | struct array with .name、.description、.keywords | 定义分类及其关键词匹配 |
| categoryAssignments | containers.Map (blockName → categoryName) | 逐模块分类分配 |
| customDescriptions | containers.Map (blockName → description) | 逐模块自定义描述(意图) |
护栏
始终:
- 仅从 .satk/library-cache/*.json 读取模块元数据。
- 通过 library.LibraryCuration.save() 持久化整理数据,并通过 library.kg.Populate.run() 重新生成 KG。
- 使用 library.kg.Query.search() 进行 KG 查询。
- 在面向用户的输出中,使用 "custom description" 或 "category assignment"——绝不使用 "override" 一词。
先询问:
- 在调用 library.LibraryCuration.save() 之前,先与用户确认提议的整理内容。
绝不:
- 绝不对库 .slx 文件调用 find_system 或 get_param。
- 绝不直接修改 .satk/library-cache/.json 或 .satk/library-kg/.md——它们是自动生成的。
- 绝不通过 library.LibraryCuration.save() 以外的任何路径持久化整理数据。
Copyright 2026 The MathWorks, Inc.