Item 7: Handle Markdown-Wrapped JSON from LLMs¶
LLM 返回结构化数据时,喜欢用 markdown 包裹 JSON。你的解析代码需要处理这个。
问题¶
你让 Agent 返回纯 JSON,但它会这样:
直接 model_validate_json() 会失败。
解决方案¶
用正则提取:
def parse_json(text: str, model_cls: type[BaseModel]) -> BaseModel | None:
# 先尝试提取 markdown 包裹的 JSON
pattern = r"```(?:json)?\s*([\s\S]*?)\s*```"
match = re.search(pattern, text.strip())
json_str = match.group(1) if match else text
try:
return model_cls.model_validate_json(json_str.strip())
except Exception:
return None
完整示例¶
class Person(BaseModel):
name: str
age: int
occupation: str
response = await agent.run("李明是一名25岁的软件工程师")
person = parse_json(response.text, Person)
if person:
print(f"{person.name}, {person.age}岁, {person.occupation}")
Things to Remember¶
- LLM 喜欢用
json ...包裹 JSON,需要正则提取 model_validate_json()解析 JSON 为 Pydantic 模型- instructions 中强调"只输出 JSON,不要其他文字"可以减少 markdown 包裹
response_format参数可以指定输出格式,但兼容性不稳定