JSON 值传输:直接校验结构化结果
从输出 Schema 生成 JSON 收集与解析实现,不增加 Tool 选择 envelope,返回统一的模型回执。
缺省开启 json 模式;CompatibleModelProvider 使用 json_object。数组或标量输出需要关闭该供应商模式时,可显式 options.json=false,仍执行相同 JSON 解码和 Schema 校验。
createJsonTransport({id,outputSchema,options?}) 返回满足 Core ModelTransportDefinition<T> 的实现,保留 id 字面量。outputSchema 是 SchemaAdapter<T>,包含 JSON Schema 及同步 parser;可以是普通对象、Support 的 Schema 实现或自定义类。JSON 解码后还会调用 parser,因此 Schema 声明和模型输出均不能代替运行时验证。
每次模型调用创建新 collector,不共享分片缓存。collector 接受文本分片;函数调用分片、非法 JSON、Schema 校验失败和异步 parser 均会拒绝。Runner 继续承担输入、Schema、输出预算,取消和调用额度;该助手不会创建额外运行器或放大权限。
模型输出直接是该 Schema 的 JSON 值,调用结果仍是 {value,invocation}。它没有 tool/input envelope,不要求 Tool 目录。需要模型选择 Tool 时使用 createModelTransport/createStageModelTransport。Provider 决定 JSON wire 方式和实际支持的值类型,不按模型名称推断。
由简到繁的同业务示例
最小 JSON 摘要:Schema 和 parser 一次绑定
入门 · Node.js
import { ModelRunner, Support } from '@jangts/agent-core';
const summary = Support.createJsonTransport({ id: 'summary', outputSchema: {
jsonSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'], additionalProperties: false },
parse(value: unknown) {
if (!value || typeof value !== 'object' || !('text' in value) || typeof value.text !== 'string') throw new TypeError('需要摘要正文');
return { text: value.text };
},
} });
const provider = { async *stream() { yield '{"text":"服务运行正常。"}'; } };
const model = new ModelRunner({ provider, transports: [summary] });
const result = await model.invoke({ input: '概括服务状态', transport: summary });
console.log(result.value.text, result.invocation);import { ModelRunner, Support } from '@jangts/agent-core';
const summary = Support.createJsonTransport({ id: 'summary', outputSchema: {
jsonSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'], additionalProperties: false },
parse(value) {
if (!value || typeof value !== 'object' || !('text' in value) || typeof value.text !== 'string')
throw new TypeError('需要摘要正文');
return { text: value.text };
},
} });
const provider = { async *stream() { yield '{"text":"服务运行正常。"}'; } };
const model = new ModelRunner({ provider, transports: [summary] });
const result = await model.invoke({ input: '概括服务状态', transport: summary });
console.log(result.value.text, result.invocation);同一摘要合同增加温度、预算与自定义解析实现
扩展 · Node.js
两个示例均为离线 Provider。更换供应商时继续使用同一传输和调用合同。
import { ModelRunner, Support } from '@jangts/agent-core';
class SummarySchema {
readonly jsonSchema = { type: 'object', properties: { text: { type: 'string' } }, required: ['text'], additionalProperties: false };
#maxChars = 100;
parse(value: unknown) {
if (!value || typeof value !== 'object' || !('text' in value) || typeof value.text !== 'string'
|| !value.text.trim() || value.text.length > this.#maxChars) throw new TypeError('需要简短摘要');
return { text: value.text };
}
}
const summary = Support.createJsonTransport({ id: 'summary', outputSchema: new SummarySchema(), options: { temperature: 0.2 } });
const model = new ModelRunner({ provider: { async *stream() { yield '{"text":"服务运行正常。"}'; } },
transports: [summary], maxCalls: 2, maxOutputTokens: 256,
});
console.log((await model.invoke({ input: '概括服务状态', transport: 'summary' })).value.text);import { ModelRunner, Support } from '@jangts/agent-core';
class SummarySchema {
jsonSchema = { type: 'object', properties: { text: { type: 'string' } }, required: ['text'], additionalProperties: false };
#maxChars = 100;
parse(value) {
if (!value || typeof value !== 'object' || !('text' in value) || typeof value.text !== 'string'
|| !value.text.trim() || value.text.length > this.#maxChars)
throw new TypeError('需要简短摘要');
return { text: value.text };
}
}
const summary = Support.createJsonTransport({ id: 'summary', outputSchema: new SummarySchema(), options: { temperature: 0.2 } });
const model = new ModelRunner({ provider: { async *stream() { yield '{"text":"服务运行正常。"}'; } },
transports: [summary], maxCalls: 2, maxOutputTokens: 256,
});
console.log((await model.invoke({ input: '概括服务状态', transport: 'summary' })).value.text);