datawhalechina/hello-agents · error · ValueError
模型响应中没有完整的 JSON 对象
Error message
模型响应中没有完整的 JSON 对象
What it means
A ValueError raised by extract_json_object() when the model response contains no balanced-looking JSON object: it locates the first '{' and the last '}' and slices between them, raising if either is absent or the braces are inverted (end < start). It is the cheap pre-check before json.loads; even when it passes, json.loads can still raise JSONDecodeError on malformed interiors — and the caller treats any ValueError (both this and decode errors) as 'unparseable response'.
Source
Thrown at Co-creation-projects/Henry2513-MeetingActionAgent/main.ipynb:147
"source": [
"## 2. 解析 Agent 返回的 JSON\n",
"\n",
"模型有时会把 JSON 包在 Markdown 代码围栏中,或者在前后添加一句解释。下面的函数先提取最外层 JSON 对象,再交给 Pydantic 校验。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb68843b",
"metadata": {},
"outputs": [],
"source": [
"# 从模型响应中截取并解析 JSON 对象。\n",
"def extract_json_object(text: str) -> dict:\n",
" start = text.find(\"{\")\n",
" end = text.rfind(\"}\")\n",
" if start == -1 or end == -1 or end < start:\n",
" raise ValueError(\"模型响应中没有完整的 JSON 对象\")\n",
" return json.loads(text[start : end + 1])\n",
"\n",
"\n",
"# 将模型响应解析并验证为指定的 Pydantic 模型。\n",
"def parse_model_response(text: str, model_type: type[BaseModel]) -> BaseModel:\n",
" return model_type.model_validate(extract_json_object(text))\n"
]
},
{
"cell_type": "markdown",
"id": "ad5a8562",
"metadata": {},
"source": [
"## 3. 把结构化结果转换为 Markdown\n",
"\n",
"Markdown 由普通 Python 生成,避免让模型重复改写已经审核过的内容。\n"
]
},View on GitHub (pinned to 606a07d341)
Solutions
- Ensure prompts include the schema and an explicit 'respond with JSON only' instruction (as run_structured in the same notebook does).
- Increase max_tokens / request a compact schema so the answer is not truncated before the closing brace.
- If extraction must be lenient, strip markdown fences first and, on failure, retry with a repair prompt — the notebook's run_structured implements exactly this budgeted repair loop.
- For robustness, use the provider's structured-output / JSON mode instead of substring slicing when available.
Example fix
# before
start = text.find("{"); end = text.rfind("}")
if start == -1 or end == -1 or end < start:
raise ValueError("模型响应中没有完整的 JSON 对象")
# after
clean = text.strip().removeprefix("```json").removeprefix("```").removesuffix("```").strip()
start = clean.find("{"); end = clean.rfind("}")
if start == -1 or end == -1 or end < start:
raise ValueError("模型响应中没有完整的 JSON 对象")
return json.loads(clean[start:end + 1]) Defensive patterns
Strategy: retry
Validate before calling
def looks_like_json_object(text: str) -> bool:
return text.find("{") != -1 and text.rfind("}") != -1 and text.rfind("}") > text.find("{") Type guard
null
Try / catch
try:
data = parse_model_response(raw, Model)
except ValueError as err:
if budget.remaining:
data = parse_model_response(repair(raw, err), Model)
else:
raise Prevention
- Always include the target JSON Schema in the prompt and demand raw JSON only.
- Strip markdown fences before slicing.
- Set max_tokens large enough to avoid truncation before the closing brace.
- Use provider JSON/structured-output mode when available instead of substring extraction.
When it happens
Trigger: An LLM answer with no braces at all (plain prose, markdown table, or the model apologizing/refusing); a response truncated by max_tokens cutting off before the closing '}' so rfind returns -1; a fenced answer like "no JSON needed"; or stray '}' before any '{' making end < start. It also passes through schema-invalid JSON, which then fails in Pydantic validation one layer up.
Common situations: Forgetting to include the JSON Schema in the prompt so the model answers freely; max_tokens too small for the schema-heavy answer; models that wrap JSON in prose with unbalanced braces; refusal/safety messages instead of data; temperature too high producing creative formats.
Related errors
- Patch must start with '*** Begin Patch'
- Patch must end with '*** End Patch'
- 无法从输出解析 note_id: {output}
- 无法从输出解析 note_id: {output}
- 无法从输出解析 note_id: {output}
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/0b88d82575d88f30.
Report an issue: GitHub.