人工智能大模型AI AgentRAG工具调用MCP 服务MCP Clients多智能体【免费下载链接】CangjieMagic基于仓颉编程语言构建的 LLM Agent DSL其主要特点包括声明式 DSL、支持 MCP 协议支持任务智能规划等。项目地址https://gitcode.com/Cangjie-TPC/CangjieMagic点击查看免费下载magic.jsonable是 CangjieMagic 中负责数据与 JSON 双向转换、类型模式描述与语义约束校验的基础包。它通过JsonableT接口、TypeSchema类型模式体系和jsonable宏把任意class/struct/enum声明式地变成可序列化、可反序列化、可校验、可被 LLM 结构化输出解析的数据类型。读完本文你将掌握该包全部公开 API 的语义、jsonable/field/alias/constraint宏的组合用法以及它在 Agent 结构化输出chatGetT中的约束修复闭环原理。一、包定位LLM 结构化数据的地基在 CangjieMagic 的架构里magic.jsonable位于最底层被多个上层模块依赖Agent 的chatGetTabs_agent.cj通过T.getTypeSchema()拿到类型模式要求模型按此输出 JSON再用T.fromJsonValue解析成强类型对象Agent Executor 会把outputSchema注入一个answer工具opertors.cj引导模型以指定结构作答工具参数定义ToolParameter直接以TypeSchema作为参数类型模式tool_parameter.cjagent的 DSL 层在生成 AI 函数声明时也用getTypeSchema()描述返回值ai.cj。也就是说只要理解jsonable就理解了 CangjieMagic 中如何让模型输出可信的结构化数据的完整链路。二、核心 API 全景六大构件文档定义的六个公开类型全部位于 src/jsonable/jsonable.cj 与 src/jsonable/type_schema.cj 中先看一张全景类型作用ToJsonValue将实现类型转换为JsonValue序列化方向FromJsonValueT从JsonValue还原出T反序列化方向JsonableT同时继承上述两者并补充类型模式与语义校验ConstraintValidation校验结果Pass或携带失败消息的Fail(String)JsonableException序列化/反序列化/校验失败时抛出的异常FieldSchema/TypeSchema描述字段与对象/数组/枚举的结构化类型模式2.1 序列化接口 ToJsonValuepublic interface ToJsonValue { func toJsonValue(): JsonValue }任何实现了toJsonValue()的类型都可以把自己变成一个JsonValueJsonString、JsonInt、JsonArray、JsonObject等来自stdx.encoding.json。后续可继续调用toJsonString()输出标准 JSON 文本。2.2 反序列化接口 FromJsonValuepublic interface FromJsonValueT { static func fromJsonValue(json: JsonValue): T }注意它是静态方法由 JSON 值构造一个T。实现方必须处理类型不匹配的情况——通常抛JsonableException。2.3 综合接口 Jsonablepublic interface JsonableT : FromJsonValueT ToJsonValue { static func getTypeSchema(): TypeSchema func validate(): ConstraintValidation }JsonableT把三个能力合并在一起getTypeSchema()返回T的类型模式validate()对当前值执行语义约束校验返回Pass或Fail(消息)继承的fromJsonValue/toJsonValue完成双向转换。文档特别强调了三点实现约定在 jsonable.cj 中均有对应jsonable宏生成的类型会自动实现该接口constraint[...]声明的约束会在validate()中被求值fromJsonValue在反序列化后必须调用validate()校验失败要拒绝该值抛异常——这正是LLM 输出不可信问题在数据层的兜底。另外源码中注释了一处平台限制jsonable.cj由于 cjc 0.53.x 存在 bugJsonable暂时无法提供fromJsonStr(String)便捷静态方法反序列化需先JsonValue.fromStr(...)再走fromJsonValue。2.4 校验结果 ConstraintValidationpublic enum ConstraintValidation { | Pass | Fail(String) }Pass表示校验通过Fail携带一条人类可读的失败消息例如Constraint violation in ConstrainedData.number: number 0该消息会原样出现在后续的修复提示语中。2.5 异常类型 JsonableExceptionpublic class JsonableException : Exception { public init(msg: String) { super(msg) } }所有 JSON 转换失败统一抛此异常例如Convert to Int error. Value: ...类型不匹配Get JSON object error.非对象Get JSON object field \score error必填字段缺失Constraint violation in ...约束校验失败三、FieldSchema 与 TypeSchema类型模式的完整描述3.1 struct FieldSchemapublic struct FieldSchema { public FieldSchema ( public let name: String, public let description: String, public let typeSchema: TypeSchema, public let required!: Bool true, public let constraints!: ArrayString [] ) { } }一个字段包含五个要素type_schema.cjnameJSON 中的字段名可能不同于仓颉成员名如alias之后description人类可读的字段说明由field注入会写入 schema 供 LLM 参考typeSchema字段值的类型模式required是否必填默认 trueOptionT字段会自动置为 falseconstraints挂在字段上的语义约束表达式字符串数组由constraint注入。3.2 enum TypeSchemapublic enum TypeSchema : ToJsonValue ToString { | Str | Int | Float | Boolean | Arr(TypeSchema) | Enum(ArrayString) | Obj(ArrayFieldSchema) }七种模式完整覆盖了 JSON 的基本类型type_schema.cj变体含义序列化结果Str字符串{type: string}Int整数{type: integer}Float浮点数{type: number}Boolean布尔{type: boolean}Arr(TypeSchema)数组元素为指定模式{type: array, items: ...}Enum(ArrayString)枚举限定可选字符串{type: string, enum: [...]}Obj(ArrayFieldSchema)对象含字段清单{type: object, properties: ..., required: [...]}3.3 关键实现toJsonValue 生成 JSON SchemaTypeSchema的toJsonValue()实现type_schema.cj将自身递归转换为近似 JSON Schema 的结构这正是喂给 LLM 的输出格式说明书对象模式会为每个字段生成properties条目并合并description与constraints两个扩展键当它们非空时只有必填字段field.required true进入required数组若对象没有字段如TypeSchema.Obj([])则不输出properties/required键。toString()直接复用toJsonValue().toJsonString()因此TypeSchema也可以被当作字符串直接拼进提示语。四、jsonable 宏从声明到实现的代码变换jsonable是 CangjieMagic DSL 层宏包magic.dsl提供的声明式入口jsonable.cj支持class、struct和穷举enumjsonable.cj还支持dump属性用于打印生成代码调试jsonable[dump: true] class Foo { ... }4.1 宏生成了什么transformJsonableTypejsonable.cj把jsonable class F { let a: String let b: Int64 }变换为等价于class F : JsonableF { let a: String let b: Int64 public init(...) { ... } // 全字段构造器 static func getTypeSchema(): TypeSchema { ... } // 收集 FieldSchema返回 TypeSchema.Obj static func fromJsonValue(json: JsonValue): F { ... } // 逐字段反序列化 validate func toJsonValue(): JsonValue { ... } // 逐字段序列化 func validate(): ConstraintValidation { ... } // 逐约束求值 }各生成方法的实现要点构造器L215-L246为每个成员变量生成带!的命名参数有默认初始化表达式的成员参数带默认值可选参数排在最后。getTypeSchemaL248-L285为每个字段构造FieldSchema其中required !isOption(fieldType)并把field描述、alias别名、constraint约束字符串都填入。fromJsonValueL287-L355按三种情况取字段值——有默认值则缺失时用默认值OptionT缺失时用JsonNull()其余必填字段缺失时抛JsonableException消息带字段的 JSON 名别名也会出现在消息里。构造完成后立刻value.validate()失败则抛JsonableException。toJsonValueL357-L393OptionT字段若序列化为JsonNull则跳过不输出其余字段全部写入。validateL395-L414按字段声明顺序、字段内约束声明顺序逐个求值一旦某个约束为假立即返回Fail消息格式为Constraint violation in 类型.字段: 约束表达式——所以返回第一个失败的约束是有意设计测试 testConstraintValidateReturnsFirstFailureInDeclarationOrder 专门验证了这一点。4.2 枚举的自动支持jsonable也支持穷举枚举L416-L507getTypeSchema()返回TypeSchema.Enum([ctorName, ...])fromJsonValue要求输入必须是 JSON 字符串且匹配某个构造器名否则抛异常toJsonValue把枚举值映射回其名字符串带类型参数的构造器与 ellipsis 枚举会被宏拒绝抛DslException。五、配套宏field、alias、constraint三个字段级宏都通过assertParentContext(jsonable)强制只能用在jsonable类型内部。5.1 field给字段写说明field.cj 接受一个字符串字面量作为字段的人类可读描述会进入FieldSchema.description最终写入 schema 供 LLM 理解字段含义支持多段字符串拼接时以换行连接jsonable class MyDateTime { field[Year of the foundation] let year: Int64 }5.2 aliasJSON 字段别名alias.cj 把仓颉成员名映射为 JSON 中实际使用的键名。别名同时作用于序列化、反序列化和 schema 输出jsonable class AliasedOptionalData { alias[user_name] let name: String }测试 testAliasAndOptionalRoundTrip 证实序列化结果含user_name而不含name反序列化时也按user_name取键schema 中required列表输出的是别名。5.3 constraint语义约束constraint.cj 接收一个布尔表达式支持任意合法的仓颉表达式包括字段间引用this指向当前对象jsonable class ConstrainedData { constraint[number 0] constraint[number limit] let number: Int64 let limit: Int64 constraint[name.size 10] constraint[this.alias.size this.name.size] let name: String let alias: String }同一字段可以叠加多条约束validate()按声明顺序求值并返回第一个失败项。测试 testConstraintValidate 验证了合法值返回Pass、非法值返回Fail(Constraint violation in ConstrainedData.number: number 0)testConstraintSchema 还验证了约束表达式会原样写入 schema 的constraints键供 LLM 在生成时提前规避。六、内置类型适配开箱即用的 Jsonablemagic.jsonable为常用类型提供了现成的Jsonable扩展jsonable.cj无需任何额外声明类型类型模式反序列化规则备注StringStrJSON 字符串null视为L52-L70Int64IntJSON 整数null视为0L72-L90Float64FloatJSON 浮点或整数null视为0.0L92-L110BoolBooleanJSON 布尔null视为falseL112-L130ArrayTArr(T的schema)JSON 数组逐元素转换L132-L159ArrayListTArr(T的schema)同上L163-L193OptionT与T相同JSONnull→None否则Some(T)L197-L226HashMapString, T无抛异常JSON 对象键值转换L228-L261JsonObjectObj([])直接透传L263-L279几个值得注意的设计OptionT的类型模式就是T本身因为可选是通过requiredfalse表达的见 3.1而不是引入新的模式变体HashMapString, T拒绝提供 schemagetTypeSchema()直接throw JsonableException(HashMap has no type schema)因为它字段不确定、无法用固定 schema 描述——但它仍可序列化/反序列化为 JSON 对象所有内置类型的validate()都返回Pass语义约束只对jsonable声明的类型生效。七、实战chatGet 与约束修复闭环jsonable 在 Agent 中最典型的应用是chatGetTabs_agent.cjpublic func chatGetT(request: AgentRequest): OptionT where T : JsonableT { request.outputSchema T.getTypeSchema() // 1. 注入类型模式 ... }调用流程如下将T.getTypeSchema()设为request.outputSchemaExecutor 据此注入answer工具、要求模型按 schema 输出模型返回文本后用ParserUtils.extractFirstValueT解析成T若解析失败ParserException把Output does not follow the type schema: ${schema}追加进对话并让模型重试修复若fromJsonValue内部约束校验失败抛JsonableException把Output violates semantic constraints. Validation error: ${ex.message}追加进对话重试修复重试次数受Config.outputRepairRetryNumber控制默认 3config.cj耗尽后chatGet返回None而不是抛出异常。仓库中的 jsonable_constraint_verifier 示例完整演示了这一闭环jsonable private class ScoreCard { constraint[score 0] constraint[score maxScore] let score: Int64 let maxScore: Int64 } let scoreCard agent.chatGetScoreCard(generate a score card).getOrThrow()该示例覆盖了约束失败触发修复并记录校验提示非 JSON 输出触发 schema 修复混合修复必填字段缺失修复重试耗尽返回 None上游模型失败原样抛出等场景main.cj并可通过LLM_API_KEY、LLM_MODEL、LLM_BASE_URL环境变量对接真实模型跑端到端验证L289-L452。配套的 json_output_test.cj 还用chatGetMyDateTime实测了模型返回结构化年份数据。八、使用建议与注意事项把业务数据模型声明为jsonable即可同时获得序列化、类型模式与约束校验无需手写样板代码用field写清字段语义、用constraint表达跨字段业务规则两者都会进入 schema让 LLM 在生成阶段就尽量合规减少修复轮次用OptionT表达可选字段序列化时None会被省略反序列化时缺失或显式null都会还原为NoneHashMap可作容器但不能作chatGetT的返回类型无 schema需要结构化输出时请定义jsonable类重试次数可调Config.outputRepairRetryNumber默认 3对强约束场景可适当调大对延迟敏感场景可调小涉及枚举时确保是穷举枚举否则jsonable宏会拒绝编译。九、总结magic.jsonable以接口 枚举模式 宏变换三层结构把 JSON 序列化、类型模式生成与语义约束校验统一到JsonableT一个契约之下。它既是chatGetT结构化输出的数据契约来源也是 LLM 输出可靠性兜底的第一道防线schema 指导生成、约束拦截非法值、修复闭环让模型自纠。理解这一层你就能在 CangjieMagic 中轻松构建模型输出 → 强类型可信数据的完整管线。延伸阅读包级 API 总览见 package_docs/jsonable.mdDSL 宏定义见 package_docs/dsl.md完整测试见 jsonable_test.cj端到端示例见 jsonable_constraint_verifier。赞分享人工智能大模型AI AgentRAG工具调用MCP 服务MCP Clients多智能体【免费下载链接】CangjieMagic基于仓颉编程语言构建的 LLM Agent DSL其主要特点包括声明式 DSL、支持 MCP 协议支持任务智能规划等。项目地址https://gitcode.com/Cangjie-TPC/CangjieMagic点击查看免费下载相关推荐API Star 类型系统Type System完全指南用声明式约束搞定接口输入验证与输出序列化API Star 类型系统Type System完全指南用声明式约束搞定接口输入验证与输出序列化 API Star当前仓库版本 0.7.2自带一套类型开发工具API设计Todo Tree终极指南VSCode中高效管理TODO标签的完整解决方案Todo Tree终极指南VSCode中高效管理TODO标签的完整解决方案 Todo Tree是一款基于ripgrep的VSCode扩展能够快速扫描项目中的开发工具CangjieMagic 声明式 DSL 宏指南magic.dsl 包全解析CangjieMagic 声明式 DSL 宏指南magic.dsl 包全解析 magic.dsl 是 CangjieMagic 中基于仓颉Cangjie宏人工智能大模型AI AgentRAG工具调用MCP 服务MCP Clients多智能体上一篇魔兽争霸3终极兼容性修复指南告别卡顿乱码解锁现代游戏体验下一篇ComfyUI-VideoHelperSuite终极指南3步构建AI视频工作流创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考