DSL 的概念模型 —— 给 Agent 建立"这是个什么世界"的心智框架:数据怎么分类型、动作怎么抽象、工序怎么组织、目的怎么分层。
实际产物是
workflow.json(结构化)+ HTML(可视化)。本文讲模型与思路;字段提取细节 → extraction/fields.md,控制流建模 → extraction/control-flow.md,字典树 → taxonomy/,workflow.json 契约 → format/case-data.schema.json。不含手写 DSL 文本的逐构造语法(那是已降级的.md交付物用的)。
DSL 表达分 5 层, 职责不同, 演化速度不同。
| 层 | 是什么 | 类比 | 演化 | 在 workflow.json 里 |
|---|---|---|---|---|
| L0 类型库 | 数据类型(字典树叶子)+ 属性 | type library | stdlib 慢, case 扩展 | IO item 的 type |
| L1 外部函数 | 绑定具体 tool 的稳定调用契约 | syscall | 只增不改 | step 的 via(工具名) |
| L2 抽象动作 | 抽象能力(动作 kind), 由 L1 实现 | interface + impl | 可演化 | step 的 action(动作树路径) |
| L3 工序模板 | 由动作组合的可复用工序 | 函数 / 类 | 高频迭代 | 一个 procedure |
| L4 工序实例 | 具体 case 的 inputs + 实际值 + trace | 调用记录 | 每 case 一份 | step 的 value 回填 |
L1 vs L2 是关键区分:L2 是工序内直接调用的抽象能力("反推提示词"),L1 是绑定具体工具的实现("via manus")。impl A via B 声明这层映射——同一个抽象动作可由多个工具实现(impl 生成图像: via nano_banana / via seedream)。workflow.json 里每 step 记选定的 via + action;若有备选实现 / 选型理由,写进 memo。
type = 数据的"制作角色",不承担调用情境或步骤属性。
workflow.json 的 procedures[i].type_registry,格式 {extends: 最近的 stdlib 叶子, desc},不污染 stdlib。每个 IO 的内容素材再按两个正交维度标注(这是内容"长什么样"的描述,与 type 的"角色"正交):
取值来自外部词表(分类库导出_{实质,形式}_*.json,走 taxonomy-lookup.py 查,不进 context)。标注对象是变量的 value(具体素材),不是变量名 / 类型 —— 例:变量"主角图"代表的那张具体图(女主特写)才是被标注对象,标 实质:/表象/视觉/人物 + 形式:/呈现/视觉/特写 (对复杂素材支持多路径标注,以 + 连接,在 workflow.json 中保存为 JSON 数组,如 ["/表象/视觉/人物", "/表象/视觉/空间"])。
一段 prompt 不是单串文本,可看作有序的块,每块有倾向:实质 | 形式 层 + 开放 tags + 角色 role(main / constraint / trick / style_preset …)。workflow.json 的 IO value 存完整 prompt 文本;这套分层思路帮你:(a) 判断该 IO 的 实质/形式 标注,(b) 把长 prompt 拆解理解。trick = 附着在某能力上、相对默认调用被验证有效的命名化偏离。
一个 step 的"怎么做"拆成正交字段(取值都受字典树 / 受控词约束):
| 字段 | 含义 | 取值 |
|---|---|---|
via |
L1 外部工具 | 具体名 nano_banana_pro / 占位 <llm> / human / 控制块用 - |
action |
L2 动作 kind | 动作树 根→叶路径,e.g. 提取/化学提取/反推 |
effect |
在工序链中的位置 | 作用树 叶子,e.g. 主体生成 |
feature |
执行特征 | 随机 / 幂等 / 人工 / 本地 / 写外部 / 读外部 |
control |
控制流 | 并行 / 遍历 / 分支 / 请求 / 等待;普通 step 留 -(详见 control-flow.md) |
caller-side 修饰(抽样 N 选 1 / 重试 / 缓存)不改动作本身,挂在 step 的
instruction里:@采样(n=4, pick=人工)/@重试/@缓存。同一动作在不同 caller 处可挂不同修饰。
procedure:头部(name / purpose / category / platform / author)+ declarations(inputs 调用方传入 / resources 跨 case 长期资产 / returns)+ steps。一篇 case 可含多个 procedure(procedures: [])。value 逐字回填(prompt 原文 / 工具配置 / N 选 1 结果);.md 输出按 inputs / bindings / extracted_values / trace 分块(见 md-structure §11)。block + nested 结构,不要拍平——详见 control-flow.md。resources)用 知识库 类型声明;读写不是独立标注维度,就是普通 step —— 写入 = action:存储/沉淀/入库 + feature:写外部,召回 = action:获取/查询/调取 + feature:读外部。"目的"不是单一属性,是按稳定性 / 颗粒度分层的链,各层不同载体:
| 实体 | 持有方式 | 颗粒度 | 稳定性 |
|---|---|---|---|
| L3 工序 | purpose + 子维度 category |
顶层产品意图 | 全局稳定 |
| L2 抽象动作 | docstring("能干啥") | 接口契约 | 跨 caller 不变 |
| L3 块(并行/遍历) | intent + 子维度 作用 |
中间策略 | 块内稳定 |
| L3 step | intent + 子维度 作用 |
此次调用情境 | 因调用而变 |
| 变量声明 | 名字(+ 可选说明) | 数据角色 | 工序全程稳定 |
MVP 最小集:工序头 purpose + 每个 step(或块)至少一个 intent。
intent / 输入 / 输出 是 caller(这次调用)的;动作的 effect / action / feature 是 callee(动作本身)的,跨 caller 稳定。生成图像 上不再挂 模态:image)。value 写数据本身的内容;上游引用 / 下游去向归 anchor。#输入 / #输出 列具体子项,不写"全维"(列 实质·人物 + 实质·场景 …,不偷懒)。| 元素 | 选择 | 例 |
|---|---|---|
| 类型名 / 动作名 / 关键字 | 中文 | 参考图 / 反推提示词 / 工序 / 输入 / 返回 |
| 变量名 | type + 工序中的稳定角色(不带步骤属性 / 工具 / 状态) | 参考视频 / 正向提示词 / 主角图 / 分镜序列 |
子维度 key:value |
中文受控词 | 作用:预处理 / 特性:随机 |
| 工具品牌名 | 英文保留 | manus / nano_banana_pro / seedream_4_5 |
变量命名归一:同一概念在不同 step 必须用同一名(lint 校验)。
字典树简称:其余文档里的 §A.1 作用 = effect.json、§A.2 动作 = action.json、§A.3 类型 = type.json(完整叶子 + 各节点
分类说明以这三个文件为 canonical,本文不附录)。