You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON Schema中$dynamicRef与$dynamicAnchor的作用、原理及与$ref、$anchor的区别

$dynamicRef 与 $dynamicAnchor 核心概念及运行机制

1. 与普通$ref/$anchor的差异

普通$ref和$anchor是静态解析的:

  • 解析时机是Schema加载阶段,和实际运行时的校验上下文无关
  • $ref只会在它当前所在的Schema的作用域内查找匹配的$anchor,无论这个Schema被谁引用、作为哪个根Schema的子模块,引用指向的位置永远固定。

$dynamicRef和$dynamicAnchor是运行时动态解析的:

  • 解析时机是实际执行数据校验的阶段,会根据当前使用的根Schema上下文调整指向
  • 同一个$dynamicAnchor名称可以在多个Schema中声明,支持外层覆盖。

2. $dynamicRef的运行规则

当解析$dynamicRef: "#锚点名"时,执行顺序如下:

  • 第一步:从当前校验任务使用的根Schema开始查找是否有匹配名称的$dynamicAnchor,如果找到就直接用根Schema的锚点对应的规则
  • 第二步:如果根Schema没有匹配的锚点,再回退到$dynamicRef所在的Schema自身作用域查找对应的$dynamicAnchor

3. 元模式示例的逻辑解读

你给出的JSON Schema官方2020-12元模式的设计,就是典型的动态引用适用场景:

基础背景

meta/core是元模式的核心基础模块,其中定义了$defs的校验规则:additionalProperties: { "$dynamicRef": "#meta" },要求$defs中的每一个子Schema都要符合#meta锚点对应的元模式规则。

两种使用场景的不同表现

  1. 直接用meta/core作为根Schema校验
    此时根Schema就是meta/core本身,根上有$dynamicAnchor: "meta",所以$dynamicRef: "#meta"会指向meta/core自身的规则,$defs下的子Schema只会被核心元规则校验。
  2. 用完整的2020-12元模式作为根Schema校验
    完整的根元模式通过allOf引入了meta/core,同时自身也声明了$dynamicAnchor: "meta"。此时meta/core里的$dynamicRef: "#meta"会优先匹配根Schema的锚点,也就是用包含所有校验词汇、格式词汇等完整能力的元规则来校验$defs下的子Schema,不需要修改meta/core的任何代码。

4. 设计的合理性

这个设计是为了实现无侵入的Schema扩展能力,尤其适配元模式这类需要灵活扩展的场景:
如果用普通的静态$ref实现,meta/core里的引用永远指向自身的锚点,如果你要做自定义元模式(比如新增自定义校验关键字、扩展词汇表),就必须修改meta/core模块的所有相关引用代码,复用成本极高。用动态引用后,你只需要在自定义的元模式根节点声明同名的$dynamicAnchor: "meta",底层所有复用模块的动态引用都会自动适配你扩展后的规则,不需要修改原有底层代码。


内容的提问来源于stack exchange,提问作者Andreas H.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 19:24:04