AI 自动生成 Mock 数据:微服务接口的 Schema 解析与 Prompt 注入机制
·
AI 自动生成 Mock 数据:微服务接口的 Schema 解析与 Prompt 注入机制

一、为什么 Mock 数据需要结构解析?
传统的微服务接口 Mock 平台通常依靠规则或简单的正则表达式来填充测试数据,生成的数据往往缺乏业务语义,导致前端联合调试与自动化测试体验不佳。虽然 AI 大模型具备根据描述生成逼真测试数据的能力,但直接把一大堆 Swagger 或 OpenAPI 的原始 JSON 甩给大模型,常常会因为上下文过长、多级嵌套对象解析错误,导致大模型生成的数据不符合类型规范,甚至出现缺失字段等问题。
因此,在大模型为我们生成 Mock 数据之前,系统必须拥有一套高精度的结构解析器。通过提取接口的底层 Schema、推导嵌套引用、提取校验约束,转化为高可读性的中间表示(IR),再精准注入到 Prompt 中,这是确保 AI 生成数据合格的唯一途径。
二、解析流程与约束提取策略
2.1 结构解析生命周期流程
从接口定义到最终被注入至大模型的 Prompt 中,数据需要经过以下解析生命周期的转换:
graph LR
A[原始接口定义] --> B[语法解析]
B --> C[Schema 树生成]
C --> D[核心约束提取]
D --> E[IR 中间表示]
E --> F[Prompt 动态构建]
2.2 核心校验约束映射策略
在语法解析阶段,我们需要将接口定义文件(如 OpenAPI)中的各种校验信息归类为五大约束,并制订出大模型在生成时必须遵守的生成限制:
| 约束维度 | Schema 源字段 | 典型示例 | 大模型生成(Mock)指导原则 |
|---|---|---|---|
| 基础类型 | type | string / integer / boolean | 强制匹配,严禁隐式转换 |
| 边界长度 | minLength / maxLength | 手机号 11-11,密码 6-20 | 生成完全符合范围的业务值 |
| 数值范围 | minimum / maximum | 年龄 0-150 | 边界值覆盖与常规数值随机生成 |
| 枚举集合 | enum | ["PENDING", "SUCCESS", "FAILED"] | 仅能在给定的集合内进行选取 |
| 语义校验 | pattern / format | 邮箱正则、手机号正则 | 根据正则生成具有真实语义的内容 |
| 递归引用 | $ref | User 关联对象 | 深度展开解析,形成层级数据 |
三、代码实战:Schema 解析与 Prompt 生成器
3.1 核心 Schema 递归解析器
用 Python 构建的解析器可以针对 OpenAPI 定义中的多重依赖、跨引用关系进行解耦和递归展开:
class SchemaParser:
def parse(self, schema: dict, spec: dict) -> dict:
ref = schema.get('$ref', '')
if ref:
# 解决引用,获取真实的类型结构
schema = self._resolve_ref(ref, spec)
result = {
'type': schema.get('type', 'object'),
'required': schema.get('required', []),
'constraints': self._extract_constraints(schema)
}
# 处理嵌套对象
if result['type'] == 'object':
result['properties'] = {}
for name, prop in schema.get('properties', {}).items():
result['properties'][name] = self.parse(prop, spec)
result['properties'][name]['name'] = name
result['properties'][name]['required'] = name in result['required']
# 处理数组集合
elif result['type'] == 'array':
result['items'] = self.parse(schema.get('items', {}), spec)
return result
def _extract_constraints(self, schema: dict) -> dict:
# 完整提取 OpenAPI 属性限制
return {
'minLength': schema.get('minLength'),
'maxLength': schema.get('maxLength'),
'minimum': schema.get('minimum'),
'maximum': schema.get('maximum'),
'enum': schema.get('enum', []),
'pattern': schema.get('pattern'),
'format': schema.get('format')
}
def _resolve_ref(self, ref: str, spec: dict) -> dict:
# 支持递归拆解组件,定位真实结构
parts = ref.replace('#/', '').split('/')
current = spec
for part in parts:
current = current.get(part, {})
return current
3.2 Prompt 构建器与上下文注入
大模型对纯结构化的 JSON 解析往往不够敏感,我们需要将中间表示(IR)转化为易于理解的伪代码描述并拼接具体的指示说明:
class PromptStrategy:
def build(self, parsed_schema: dict, business_context: str = "") -> str:
sections = []
sections.append("# 接口 Schema 定义约束(请严格遵守)")
sections.append(self._format_schema(parsed_schema, 0))
sections.append("")
sections.append("# 业务逻辑上下文")
sections.append(business_context or "通用后台管理微服务接口")
sections.append("")
sections.append("# 核心生成准则")
sections.append("1. 输出的数据结构与成员属性类型必须 100% 对应上述定义的 Schema。")
sections.append("2. 字符串类型(如姓名、地址)请根据上下文自动生成生动真实的业务数据,拒绝硬编码。")
sections.append("3. 如果属性中声明了枚举值,只能从 enum 列表中选取。")
sections.append("4. 生成的数组数据行数控制在 5 至 10 条之间,需包含典型数据、边界值及空值场景。")
sections.append("5. 仅返回标准的 JSON Array 数据,严禁包含任何 Markdown 格式前缀或注释。")
return "\n".join(sections)
def _format_schema(self, schema: dict, indent: int) -> str:
prefix = " " * indent
lines = []
t = schema.get('type', 'object')
lines.append(f"{prefix}类型: {t}")
if schema.get('constraints'):
c = schema['constraints']
parts = []
if c.get('enum'): parts.append(f"可选枚举值={c['enum']}")
if c.get('minLength'): parts.append(f"最小长度={c['minLength']}")
if c.get('maxLength'): parts.append(f"最大长度={c['maxLength']}")
if c.get('minimum'): parts.append(f"最小值={c['minimum']}")
if c.get('maximum'): parts.append(f"最大值={c['maximum']}")
if c.get('pattern'): parts.append(f"正则表达式={c['pattern']}")
if parts:
lines.append(f"{prefix}规范约束: {', '.join(parts)}")
if t == 'object' and schema.get('properties'):
for name, prop in schema['properties'].items():
req = "必填" if prop.get('required') else "非必填"
lines.append(f"{prefix}- 字段: {name} ({req})")
lines.append(self._format_schema(prop, indent + 1))
elif t == 'array' and schema.get('items'):
lines.append(f"{prefix}子项列表结构:")
lines.append(self._format_schema(schema['items'], indent + 1))
return "\n".join(lines)
四、解析与注入最佳实践
- 深度优先展开与防循环引用:在处理像
Organization嵌套User,且User内部又引用Organization的对象图时,解析器必须在递归时记录解析路径的visited集合,防止发生无限递归导致内存溢出。 - 严格的结构验证层(Guard):切忌只依赖大模型的生成结果。在接收到大模型返回的 JSON 数据后,系统必须使用刚解析生成的 Schema 对 JSON 数据进行一次强类型的 JSON Schema Validation 验证,验证不通过则自动重试或使用静态方案兜底。
- 上下文语义增强:仅提供
email类型,AI 可能会生成类似a@b.com这样无意义的数据。如果能结合business_context传入类似“电商客服反馈列表接口”,大模型就能配合生成符合该上下文的客服邮箱和反馈文字,使测试仿真度提升数倍。
五、总结
在基于大模型自动生成微服务 Mock 数据的链路中,结构解析扮演了不可或缺的基石角色。用自建解析器代替大模型的暴力直读,将繁杂的接口定义抽取为紧凑而精确的中间表示,能从根本上避免数据的类型错乱与字段遗漏。解析精准度加提示词控制,才是企业级 AI 自动化联调平台的可靠保障。
更多推荐



所有评论(0)