问题出现得很突然,日志倒是留得挺全。CrewAI 0.8 的三段式流程,第一个 task 要求输出 JSON,模型回了一段带三个反引号 json 围栏的 markdown,第二个 task 的 context 直接拿到这段文本,pydantic 校验抛 ValidationError,提示 expected value at line 1 column 1。

刚开始盯着「上游 task 的输出被当成字符串塞进 context,没有反序列化」,折腾了半个多小时,排掉了。

把日志和配置对完,能解释这个现象的基本就这几处。task 只写了描述没设 output_json 或 output_pydantic。另一种情况是模型习惯性加代码围栏,字符串首字符是反引号。

少数情况下是temperature 偏高,同一 prompt 偶尔多出解释性前缀。

先看第一个 task 的原始输出前两百个字符

python -c "print(repr(open('task1_raw.txt',encoding='utf-8').read()[:200]))"

给 task 指定 pydantic 输出模型

python -c "from pydantic import BaseModel;print(BaseModel.model_json_schema())"

接着在解析前剥掉代码围栏再校验

python -c "import json,re;t=open('task1_raw.txt',encoding='utf-8').read();t=re.sub(r'^```[a-z]*|```$','',t.strip());print(json.loads(t))"

再往下把校验失败样本单独落盘复盘

python -c "import json;print(json.dumps({'fence': True, 'prefix': 'Here is the JSON'},ensure_ascii=False))"

调整任务描述要求只输出 JSON 本体

python -c "print('Return raw JSON only, no markdown fence, no explanation.')"

别只看报错消失,验证要多做一步。第二个 task 能直接拿到已校验的对象,连续跑十次不再出现 ValidationError,失败样本目录保持为空。

这里还有个坑。结构化输出要靠框架的 output_pydantic 兜住,靠提示词要求只是降低概率,模型换个版本习惯就变了。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189