ERDL 技术白皮书
Enterprise Resource Definition Language — 企业资源定义语言
AI 时代,人类用 YAML,数字系统用 ERDL。
人类可读 · 机器可读 · 机器与机器可读
1. 概述
1.1 什么是 ERDL
ERDL(Enterprise Resource Definition Language,企业资源定义语言)是 OpenOBA 自研的一套声明式业务语义描述体系。它基于 YAML 规范,完全兼容标准 YAML 语法,让企业用自己所在行业的语言来定义业务实体、字段、别名、枚举、规则和可执行操作。
ERDL 的核心突破在于:它不是给开发者看的配置文件,而是 LLM 与业务系统之间的协议层。Agent 读取 ERDL 定义后,获得对业务模型的确定性理解——不是概率推测,而是结构化的语义认知。人类可读、机器可读、机器与机器可读,三读合一。
定位:ERDL 是 OpenOBA 的"语义语言中枢"——向上对接 LLM 自然语言理解,向下对接数据库和 API,横向连接行业知识库。它是实现企业数字系统与 LLM 自由联通的基础设施。
1.2 解决的问题
传统企业软件开发中,"业务需求 → 技术实现"之间存在巨大的翻译鸿沟。眼镜行业的"框形"、服装行业的"版型"、美妆行业的"色号"——业务术语千差万别,但传统软件要求开发者将这些术语逐个翻译为数据库列名。这种翻译依赖人工沟通、会议文档,成本高、易出错、不可复用。
ERDL 将这些映射声明化、结构化、可验证。AI 读到 ERDL,就像工程师读到完整的业务数据字典和规则手册——无需猜测,确定性理解。
1.3 文件格式
ERDL 文件使用 .erdl 扩展名,基于 YAML 规范,完全兼容 YAML 语法。一个行业通常包含两个文件:
行业名.erdl— 实体定义、别名映射、规则集、语义层配置行业名.actions.erdl— 可执行操作(Action)定义
2. 核心设计理念
2.1 声明式,零代码
定义即实现。在 ERDL 文件中声明 Entity、属性、约束,系统自动生成对应的数据库表、API 端点、前端表单。不需要写一行 CRUD 代码。
2.2 别名系统:行业黑话翻译器
每个行业有自己的"黑话",同一个概念在不同行业用不同词汇表达。ERDL 的别名(Alias)机制将行业口语映射到标准字段名。用户说"框形",Agent 自动翻译为 shapeCode;用户说"卖价",Agent 自动翻译为 retailPrice。
别名是 ERDL 消除 LLM 歧义的核心机制——不是靠 Prompt 提示"请注意这些同义词",而是在协议层面建立确定性映射。
2.3 Hot Reload:保存即生效
修改 .erdl 文件后立即生效,无需重启系统。ERDL Registry 监听文件变更 → 自动校验语义 → 热替换内存中的 Schema → Agent 即刻获得最新定义。业务规则从"排期发布"变成"改完就用"。
2.4 物理映射:语义到存储的直通车
ERDL 不仅描述业务语义,还直接声明物理存储映射——table(数据表名)、dbColumn(列名)、primaryKey(主键)。Agent 理解业务意图后,ERDL 实体代理引擎自动翻译为 SQL,无需人工编写数据访问层。
2.5 规则驱动,而非 Prompt 约束
ERDL 中的 Rulesets(规则集)定义了业务边界条件——价格必须大于 0、会员折扣自动计算、库存不能为负。这些规则不是给 LLM 看的"建议",而是在 Agent 执行前由 Action Guard 进行协议级硬校验。不满足规则的输出直接拒绝,不进入执行链路。
3. 语法参考
3.1 文件头
# 命名空间:全局唯一标识
namespace: industry.eyewear
# 模块元信息
module:
version: "1.5.0"
extends: "erd.base" # 继承基础 ERDL 定义
# 描述信息(可选)
name: "眼镜行业 ERP 定义"
description: "涵盖眼镜行业商品、订单、客户、库存等核心业务实体"
3.2 实体定义(Entity)
Entity 是 ERDL 的核心构建块,对应一个业务对象。每个 Entity 声明后,系统自动生成:
- 数据库表(含列定义、主键、索引)
- REST API(CRUD + 列表查询)
- 前端表单与表格列配置
- Agent 可操作上下文
entities:
ProductSpu:
table: "product_spu" # 数据库表名
primaryKey: "spu_id" # 主键列名
properties:
spuId:
type: "UUID" # 数据类型
dbColumn: "spu_id" # 数据库列名
required: true # 是否必填
spuCode:
type: "String"
dbColumn: "spu_code"
required: true
maxLength: 64 # 最大长度
spuName:
type: "String"
dbColumn: "spu_name"
required: true
maxLength: 256
gender:
type: "Enum"
dbColumn: "gender"
enum: ["female","male","unisex","limited"] # 枚举值
retailPrice:
type: "Money(CNY)" # 货币类型(带币种)
dbColumn: "retail_price"
attributes:
type: "JSON" # JSON 类型
dbColumn: "attributes"
createdAt:
type: "DateTime"
dbColumn: "created_at"
autoGenerate: true # 自动生成
metadata:
knowledge: "product-knowledge" # 关联知识库
icon: "glasses" # UI 图标
category: "product" # 业务分类
3.3 类型系统
| 类型 | 说明 | 示例 | 数据库映射 |
|---|---|---|---|
String | 字符串 | 商品名称 | VARCHAR |
UUID | 唯一标识符 | 主键 | UUID / CHAR(36) |
Integer | 整数 | 库存数量 | INTEGER |
Decimal | 小数(高精度) | 重量、尺寸 | DECIMAL |
Float | 浮点数 | 价格 | FLOAT / DOUBLE |
Money(CNY) | 货币(含币种) | 零售价、成本价 | DECIMAL + 货币标识 |
Boolean | 布尔值 | 是否上架 | BOOLEAN / TINYINT |
Enum | 枚举(限定可选值) | 性别、状态 | VARCHAR + CHECK |
DateTime | 时间戳 | 创建时间 | DATETIME / TIMESTAMP |
JSON | JSON 对象/数组 | 属性集、标签 | JSON / JSONB |
3.4 属性约束
| 约束 | 说明 | 示例 |
|---|---|---|
required: true | 字段必填 | 商品名称不可为空 |
maxLength: 256 | 最大字符长度 | 名称不超过 256 字符 |
enum: [...] | 限定枚举值 | 性别只能是 female/male |
autoGenerate: true | 系统自动生成 | UUID 主键、时间戳 |
unique: true | 唯一约束 | 商品编码不可重复 |
3.5 别名映射(Aliases)
别名系统将行业术语映射到标准字段名。支持一个字段对应多个行业别名:
aliases:
ProductSpu:
"框形": "seriesCode"
"框型": "seriesCode"
"镜框形状": "seriesCode"
"款式": "spuName"
"款": "spuName"
"等级": "productTier"
"档次": "productTier"
ProductSku:
"色号": "colorCode"
"花色": "colorCode"
"售价": "retailPrice"
"卖价": "retailPrice"
"成本": "costPrice"
"进货价": "costPrice"
"库存": "stockQuantity"
Customer:
"姓名": "contactName"
"电话": "phone"
"级别": "customerLevel"
Order:
"订单号": "orderNo"
"单号": "orderNo"
"总价": "totalAmount"
"实付": "actualAmount"
别名运行时行为:Agent 解析用户输入时,先通过别名表查找匹配 → 命中则翻译为标准字段名 → 未命中则作为模糊语义交由 LLM 推理。系统持续积累新的别名映射,运行时自动沉淀。
3.6 规则集(Rulesets)
规则集定义业务逻辑边界,在 Agent 执行前进行硬校验。规则分为两种类型:
- Validation(校验规则):数据合法性检查,不通过则拒绝执行
- Policy(策略规则):自动化计算逻辑,如会员折扣
rulesets:
PricingRules:
# ── 策略:会员折扣自动计算 ──
policies:
- name: "VIP会员8折"
priority: 1
entity: ProductSku
condition:
field: "customer.tier"
operator: eq
value: "VIP"
actions:
- type: calculate
params:
formula: "retailPrice * 0.8"
# ── 校验:价格合法性 ──
validations:
- name: "零售价必须大于0"
priority: 10
entity: ProductSku
condition:
field: "retailPrice"
operator: gte
value: 1
actions:
- type: validate
params:
error: "零售价必须大于 0"
- name: "售价不低于成本1.2倍"
priority: 10
entity: ProductSku
condition:
field: "retailPrice"
operator: gte
formula: "costPrice * 1.2"
actions:
- type: validate
params:
error: "零售价必须至少是成本价的1.2倍"
3.7 可执行操作(Actions)
Action 定义 Agent 可执行的操作,声明参数类型、枚举约束、是否需要人工审批:
actions:
erdl_crud:
description: "读写 ERDL Entity 数据"
params:
action:
required: true
enum: [create, read, update, delete]
entity:
required: true
values:
type: object
where:
type: object
select:
type: string_array
promote_drafts:
description: "将草稿池中的草稿入库——转为正式 SPU/SKU 商品"
params:
draftIds:
required: true
type: string_array
description: "要入库的草稿ID列表"
taskId:
description: "关联的 Agent 任务ID"
query_erp_data:
description: "查询 ERP 系统数据"
params:
data_type:
type: enum
values: [all, spu, sku, shapes, colors, materials, effects, series, rules]
aesthetics_check:
description: "美学校验——判定商品美学评分"
params:
shapeCode: { required: true }
colorCode: { required: true }
gender: {}
skinToneEffect: {}
faceShapeEffect: {}
read_file:
description: "读取工作区内文件内容——支持 .md .txt .json .csv .xlsx .docx .pdf .html .sql .erdl"
params:
path: { required: true }
maxLines: { type: number, default: 0 }
3.8 语义层(Semantic Layer)
语义层是 ERDL 为 LLM 准备的"字典数据快照"——将数据库中的字典表内容以结构化的方式注入到 Agent 的 System Prompt 中,让 Agent 不需要每次查询就能理解业务上下文:
semantic_layer:
dictionaries:
- name: "效果词映射"
source: "dict_effect_tag"
mapping_engine: "llm_bridge"
hotword_rules:
detect_from: ["social_listener", "search_log"]
normalize_to: "effect_tag"
confidence_threshold: 0.7
3.9 同步策略(Sync Policy)
控制字典数据如何同步到 Agent 上下文:
sync_policy:
dict_pulse:
mode: "on-demand" # on-demand | scheduled | real-time
source:
type: "dict"
table: "dict_effect_tag"
fields: ["effect_code", "effect_name", "effect_type"]
transform: "passthrough"
target: "system_prompt"
4. 工具链
围绕 ERDL 的完整开发-验证-部署工具链,覆盖从编写到上线的每一个环节。
4.1 ERDL Registry 核心
ERDL Registry 是运行时引擎,负责:
- 文件发现:监听
erdl/目录,自动发现所有.erdl文件 - 解析加载:基于 YAML 规范解析 → 语义校验 → 注册到内存
- Hot Reload:检测文件变更 → 增量更新 → 即时生效,无需重启
- 多文件合并:主定义文件 + Actions 文件自动合并为一个完整 Schema
- 版本管理:跟踪每次加载的版本号,支持回退
- 状态查询:提供 API 查询当前已加载的行业列表、Entity 列表、Schema 详情
4.2 Schema 解析器
将 ERDL 声明转换为运行时可用的数据结构。完成以下转换:
- Entity 定义 → TypeORM Entity 类 + 数据库迁移 SQL
- 属性约束 → DTO 校验规则(class-validator)
- 枚举定义 → TypeScript enum + 数据库 CHECK 约束
- 别名表 → 快速查找哈希映射
- 规则集 → Action Guard 校验链
4.3 Action Guard 核心
协议级执行校验引擎。在 Agent 的任何输出进入系统执行之前,Action Guard 进行以下拦截:
- Action 识别:解析 LLM 输出(FC/XML/文本),提取操作名和参数
- 参数校验:检查参数类型、必填项、枚举值是否在 ERDL 声明的范围内
- 规则校验:执行 Rulesets 中的 validation 规则——任何一条不通过即拒绝
- 策略应用:执行 Rulesets 中的 policy 规则——如会员折扣自动计算
- 审计记录:记录本次操作的完整链路(输入 → 校验结果 → 执行结果)
Action Guard 的核心价值:不是 Prompt 约束,是代码级硬校验。LLM 输出不可控,但 Action Guard 在协议层确保只有合法的操作能进入执行。
4.4 Schema API
对外暴露 REST API,供前端和管理后台使用:
| 端点 | 方法 | 说明 |
|---|---|---|
/schema | GET | 获取当前行业的完整 Schema |
/schema/industries | GET | 列出所有可用行业 |
/schema/spu-attributes | GET | 获取 SPU 属性列表(前端动态表单用) |
/schema/sku-attributes | GET | 获取 SKU 属性列表 |
/schema/effect-thesaurus | GET | 获取效果词库 |
/schema/pricing-rules | GET | 获取定价规则 |
/schema/display-name | GET | 按 Schema 模板生成展示名 |
4.5 元镜引擎(Meta-Mirror)
双向一致性守护:
- 正向扫描:扫描后端 DTO/Entity,自动生成或更新 ERDL 定义
- 反向审计:对比 ERDL 声明与实际 DTO 代码,发现不一致立即报告
- 质量门禁:类型完整性、枚举一致性、字段覆盖率自动检查
- 版本守护:版本号一致性 + Commit 审计 + CHANGELOG 追踪
4.6 开发辅助
- ERDL Playground:在线 ERDL 编辑器,即时语法校验 + 预览
- VS Code 扩展(即将推出):语法高亮、自动补全、错误提示、别名查找
- CLI 工具:
erdl validate校验语法、erdl diff对比版本差异
5. 运行时架构
ERDL 在 OpenOBA 运行时中的位置和数据流:
┌──────────────────────────────────────────────────────┐
│ 用户输入 │
│ "把所有VIP会员眼镜售价打八折" │
└──────────────────┬───────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ ① LLM 理解 + ERDL 别名系统 │
│ "VIP" → Customer.customerLevel │
│ "眼镜" → ProductSpu │
│ "售价" → ProductSku.retailPrice (别名翻译) │
│ "打八折" → pricing_policy │
└──────────────────┬───────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ ② Action Guard 拦截 │
│ × 参数校验:retailPrice 必须 > 0 │
│ × 规则校验:PricingRules.validation 通过 │
│ × 策略应用:PricingRules.policy → 0.8 折扣 │
└──────────────────┬───────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ ③ ERDL 实体代理引擎 → SQL 翻译 │
│ UPDATE product_sku │
│ SET retail_price = retail_price * 0.8 │
│ WHERE spu_id IN (SELECT spu_id FROM ...) │
│ AND sku_id IN (SELECT sku_id FROM customer...) │
└──────────────────┬───────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ ④ 审计日志 + 结果返回 │
│ { │
│ affected: 247, │
│ audit_id: "ck-...", │
│ rollback_available: true │
│ } │
└──────────────────────────────────────────────────────┘
关键路径:
- ERDL 文件 → Registry 加载 → Schema 解析 → Agent System Prompt 注入
- 用户自然语言 → 别名系统翻译 → Action Guard 校验 → 实体代理引擎生成 SQL → 执行
- 字典数据 → Sync Policy → System Prompt 语义层 → Agent 上下文
6. 完整代码示例
6.1 最小可运行 ERDL 文件
以下是一个完整的最小化 ERDL 文件,定义了一个简单的商品管理系统:
# 文件: my-erp.erdl
namespace: industry.my_erp
module:
version: "1.0.0"
entities:
Product:
table: "product"
primaryKey: "id"
properties:
id:
type: "UUID"
dbColumn: "id"
autoGenerate: true
productCode:
type: "String"
dbColumn: "product_code"
required: true
maxLength: 64
unique: true
productName:
type: "String"
dbColumn: "product_name"
required: true
maxLength: 256
category:
type: "Enum"
dbColumn: "category"
enum: ["ELECTRONICS","CLOTHING","FOOD","OTHER"]
retailPrice:
type: "Money(CNY)"
dbColumn: "retail_price"
required: true
stockQuantity:
type: "Integer"
dbColumn: "stock_quantity"
isActive:
type: "Boolean"
dbColumn: "is_active"
createdAt:
type: "DateTime"
dbColumn: "created_at"
autoGenerate: true
metadata:
category: "product"
knowledge: "product-management"
aliases:
Product:
"商品名": "productName"
"品名": "productName"
"名称": "productName"
"售价": "retailPrice"
"价格": "retailPrice"
"卖价": "retailPrice"
"库存": "stockQuantity"
"库存量": "stockQuantity"
"分类": "category"
"品类": "category"
rulesets:
ProductRules:
validations:
- name: "价格必须大于0"
priority: 10
entity: Product
condition:
field: "retailPrice"
operator: gt
value: 0
actions:
- type: validate
params:
error: "商品价格必须大于 0"
- name: "库存不能为负"
priority: 10
entity: Product
condition:
field: "stockQuantity"
operator: gte
value: 0
actions:
- type: validate
params:
error: "库存数量不能为负数"
6.2 对应的 Actions 文件
# 文件: my-erp.actions.erdl
namespace: industry.my_erp
module:
version: "1.0.0"
extends: my-erp
actions:
erdl_crud:
description: "读写 ERDL Entity 数据——创建、查询、更新、删除"
params:
action:
required: true
enum: [create, read, update, delete]
entity:
required: true
values:
type: object
where:
type: object
select:
type: string_array
query_inventory:
description: "查询商品库存状态"
params:
productCode: {}
category: {}
lowStock:
type: boolean
description: "仅显示低库存商品"
batch_update_price:
description: "批量调整商品价格"
params:
category: {}
discountPercent:
type: number
description: "折扣百分比,如 20 表示打八折"
requireApproval: true
6.3 眼镜行业完整示例(摘录)
OpenOBA 首发案例——眼镜行业 ERP——的完整 ERDL 定义包含 20 个 Entity、150+ 别名、12 条业务规则。以下摘录核心部分:
# 文件: eyewear.erdl
namespace: industry.eyewear
module:
version: "1.5.0"
extends: "erd.base"
entities:
ProductSpu:
table: "product_spu"
primaryKey: "spu_id"
properties:
spuId: { type: "UUID", dbColumn: "spu_id", required: true }
spuCode: { type: "String", dbColumn: "spu_code", required: true, maxLength: 64 }
spuName: { type: "String", dbColumn: "spu_name", required: true, maxLength: 256 }
gender: { type: "Enum", dbColumn: "gender", enum: ["female","male","unisex","limited"] }
structureCode: { type: "String", dbColumn: "structure_standard_code", maxLength: 64 }
seriesCode: { type: "String", dbColumn: "series_code", maxLength: 64 }
productTier: { type: "String", dbColumn: "product_tier", maxLength: 20 }
sceneTags: { type: "JSON", dbColumn: "scene_tags" }
attributes: { type: "JSON", dbColumn: "attributes" }
metadata:
knowledge: "product-knowledge"
category: "product"
ProductSku:
table: "product_sku"
primaryKey: "sku_id"
properties:
skuId: { type: "UUID", dbColumn: "sku_id", required: true }
skuCode: { type: "String", dbColumn: "sku_code", required: true, maxLength: 128 }
spuId: { type: "UUID", dbColumn: "spu_id", required: true }
colorCode: { type: "String", dbColumn: "color_code", maxLength: 64 }
retailPrice: { type: "Money(CNY)", dbColumn: "retail_price" }
costPrice: { type: "Money(CNY)", dbColumn: "cost_price" }
stockQuantity: { type: "Integer", dbColumn: "stock_quantity" }
skinToneEffect: { type: "String", dbColumn: "skin_tone_effect", maxLength: 32 }
faceShapeEffect: { type: "String", dbColumn: "face_shape_effect", maxLength: 32 }
frameShape: { type: "String", dbColumn: "frame_material", maxLength: 32 }
weightG: { type: "Decimal", dbColumn: "weight_g" }
barcode: { type: "String", dbColumn: "barcode", maxLength: 128 }
metadata:
knowledge: "product-knowledge"
category: "product"
# (Customer, Order, OrderItem, Inventory, StructureStandard,
# DictEffectTag, DictSkuColor, KnowledgeEntry, AgentMemory,
# DraftSpu, SubSku 等 Entity 完整定义请参阅源码仓库)
aliases:
ProductSpu:
"框形": "seriesCode"
"框型": "seriesCode"
"镜框形状": "seriesCode"
"款式": "spuName"
"等级": "productTier"
"档次": "productTier"
ProductSku:
"色号": "colorCode"
"配色": "colorCode"
"卖价": "retailPrice"
"售价": "retailPrice"
"成本": "costPrice"
"进货价": "costPrice"
"库存": "stockQuantity"
"重量": "weightG"
Customer:
"姓名": "contactName"
"电话": "phone"
"级别": "customerLevel"
Order:
"订单号": "orderNo"
"总价": "totalAmount"
"实付": "actualAmount"
rulesets:
PricingRules:
policies:
- name: "VIP会员8折"
entity: ProductSku
condition:
field: "customer.tier"
operator: eq
value: "VIP"
actions:
- type: calculate
params:
formula: "retailPrice * 0.8"
validations:
- name: "零售价必须大于0"
entity: ProductSku
condition:
field: "retailPrice"
operator: gte
value: 1
actions:
- type: validate
params:
error: "零售价必须大于 0"
7. 行业生态
7.1 已发布行业
| 行业 | ERDL 文件 | Entity 数量 | 别名数量 | 状态 |
|---|---|---|---|---|
| 眼镜零售 | eyewear.erdl | 20 | 150+ | 已开放 |
7.2 贡献你的行业
有行业专长?只需提供以下内容即可参与 EDP Market:
- 行业 Entity 定义:描述你所在行业的核心业务对象和字段
- 行业别名表:行业中常用的术语、"黑话"及其对应的标准字段
- 业务规则:行业特有的校验规则和计算逻辑
- 可执行操作:该行业常用的 Agent 操作定义
提交后,OpenOBA 会自动生成完整的行业系统原型——包括数据库、API、前端界面。MIT 协议开源,自由商用,共享生态收益。
7.3 规划中行业
| 行业 | ERDL 文件 | 预计开放 |
|---|---|---|
| 服装/纺织 | apparel.erdl | 2026 Q3 |
| 美妆/日化 | beauty.erdl | 2026 Q3 |
| 3C 数码 | 3c.erdl | 2026 Q4 |
| 电商/零售 | retail.erdl | 2026 Q4 |
8. 与 OpenOBA 的关系
ERDL 是 OpenOBA 平台的核心基础设施,承担"语义理解"环节。在 OpenOBA 的三层架构中:
| 架构层 | 职责 | ERDL 的角色 |
|---|---|---|
| ERDL 协议层 | 企业业务语义的定义与传递 | 核心——Entity + Alias + Rulesets + Actions |
| Agent 执行引擎 | ReAct 推理链 + Action Guard 安全拦截 | Action Guard 从 ERDL 加载校验规则 |
| 认知审计日志 | 全链路可追溯、可回滚 | 审计日志中记录每个操作对应的 ERDL Entity/Action |
ERDL 是独立可复用的——它不绑定特定的 LLM 或 Agent 框架。任何需要"让 AI 确定性理解业务"的场景,都可以独立使用 ERDL 作为语义协议层。
愿景:ERDL 的长期目标是成为企业 AI 应用的通用语义标准——就像 YAML 定义了配置、Markdown 定义了文档,ERDL 定义企业业务语义。人类可读、机器可读、机器与机器可读。ERDL 源代码 MIT 开源,全栈技术工具链支持,生态开放,共创共享。
下一步:阅读 ERDL 快速入门指南 开始编写你的第一份 ERDL 文件,或访问 GitHub 浏览完整源码。