Firebase Genkit中用Zod定义日期属性报错,求非字符串转换方案
关于Genkit工具中Date类型使用的问题
问题背景
我正在为Genkit函数开发一个调用外部API查询预约时间的工具,定义的Schema如下:
export const SearchCriteria = z.object({ zip: z.string(), date: z.string().datetime({ offset: false }), timeOfDay: z.enum(["morning", "afternoon", "evening"]).optional(), });
工具函数代码:
const searchAppointments = defineTool( { name: "searchAppointments", description: "Use this to search for appointments in a given zip code.", inputSchema: SearchCriteria, outputSchema: AppointmentResults, }, async (search) => { const response = await fetch( `{my_endpoint}?zip=${search.zip}&startDate=${search.date}` ); const data = await response.json(); return data; } );
使用时触发错误:
name: 'Error',
message: 'unknown format "date" ignored in schema at path "#/properties/date"'
根据/node_modules/@genkit-ai/core/node_modules/ajv/dist/vocabularies/format/format.js:63:23的提示,Genkit底层的AJV验证器似乎只支持string和number基础类型。想问除了手动在日期和字符串间转换外,有没有办法在Genkit里直接使用Date类型?
可行方案
目前Genkit默认不支持datetime格式校验,也没有原生支持Date类型的直接方案,但可以通过两种方式绕开限制:
1. 为AJV添加自定义格式验证
手动给Genkit依赖的AJV实例注册date格式的校验逻辑,这样就能保留原有的Zod Schema定义:
import { ajv } from '@genkit-ai/core'; import { z } from 'zod'; // 注册自定义datetime格式验证规则 ajv.addFormat('date', { validate: (dateStr) => !isNaN(Date.parse(dateStr)) }); // 原Schema无需修改 export const SearchCriteria = z.object({ zip: z.string(), date: z.string().datetime({ offset: false }), timeOfDay: z.enum(["morning", "afternoon", "evening"]).optional(), });
2. 用Zod的自定义校验替代datetime方法
放弃datetime()链式调用,改用refine()实现日期有效性校验,这样生成的JSON Schema不会包含AJV不识别的format字段:
export const SearchCriteria = z.object({ zip: z.string(), date: z.string().refine((val) => { const date = new Date(val); return date instanceof Date && !isNaN(date); }, { message: "请输入有效的日期字符串" }), timeOfDay: z.enum(["morning", "afternoon", "evening"]).optional(), });
关于直接使用Date类型的说明
Genkit目前不支持将原生Date类型作为Schema字段类型,因为工具的输入输出需要序列化为JSON,而JSON本身没有Date类型,最终还是要转成字符串处理。所以无论哪种方案,本质都是基于字符串做日期校验,只是校验的实现方式不同。
内容的提问来源于stack exchange,提问作者Code on the Rocks
相关产品推荐
相关产品推荐

