事情本身不复杂,线索都在日志里。crewai 0.70 用 @tool 装饰查询函数,函数返回 {"price": 19.9, "updated": datetime.now()},Agent 执行时报 Object of type datetime is not JSON serializable,任务直接中断。

第一反应是「Decimal 金额同样不能被默认序列化」,验证下来不成立。

真正麻烦的地方在于,几个原因的现象几乎一样。工具返回值要求是字符串,dict 里又混了 datetime。还有一种是用了 pydantic 模型但没有转成 JSON 字符串。

另外,任务输出被二次序列化,嵌套结构越界。

上来先把返回值统一成 JSON 字符串

python -c "import json;from datetime import datetime;print(json.dumps({'price':19.9,'updated':datetime.now().isoformat()},ensure_ascii=False))"

工具内部用 default=str 兜住剩余类型

python -c "import json;print(json.dumps({'v':object()},default=str))"

接着在工具描述里写明返回字段,减少模型误解

python -c "print({'description':'返回 JSON 字符串,字段 price 与 updated'})"

剩下的就是跑一条最小任务验证不再中断

python -c "from crewai import Agent;print('tool ok')"

怎么算真的好了,看的是同一批现象。同一工具在任务里正常返回价格与时间,Agent 能继续下一步,日志里不再出现 not JSON serializable。

补一句。工具是模型与代码的边界,返回值的形态要固定成字符串或基础类型,时间、金额先格式化再给出去,比在框架层加钩子省事。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189