datawhalechina/hello-agents · warning · ValueError
响应中未找到JSON数据
Error message
响应中未找到JSON数据
What it means
ValueError raised by the trip planner's response parser when the LLM reply contains none of the expected JSON carriers: no ```json fence, no bare ``` fence, and no { ... } braces. It is the terminal branch of a three-way extraction strategy; the outer except then logs '解析响应失败' and falls back to a template-based plan.
Source
Thrown at code/chapter13/helloagents-trip-planner/backend/app/agents/trip_planner_agent.py:356
"""
try:
# 尝试从响应中提取JSON
# 查找JSON代码块
if "```json" in response:
json_start = response.find("```json") + 7
json_end = response.find("```", json_start)
json_str = response[json_start:json_end].strip()
elif "```" in response:
json_start = response.find("```") + 3
json_end = response.find("```", json_start)
json_str = response[json_start:json_end].strip()
elif "{" in response and "}" in response:
# 直接查找JSON对象
json_start = response.find("{")
json_end = response.rfind("}") + 1
json_str = response[json_start:json_end]
else:
raise ValueError("响应中未找到JSON数据")
# 解析JSON
data = json.loads(json_str)
# 转换为TripPlan对象
trip_plan = TripPlan(**data)
return trip_plan
except Exception as e:
print(f"⚠️ 解析响应失败: {str(e)}")
print(f" 将使用备用方案生成计划")
return self._create_fallback_plan(request)
def _create_fallback_plan(self, request: TripRequest) -> TripPlan:
"""创建备用计划(当Agent失败时)"""
from datetime import datetime, timedelta
View on GitHub (pinned to 606a07d341)
Solutions
- Check what the model actually returned (print the raw response) — this decides everything
- Make the prompt demand pure JSON with no prose and include a schema/few-shot example; consider response_format={'type':'json_object'} if the provider supports it
- Retry once with the failed output quoted back and 'respond ONLY with JSON' instruction
- If fallbacks are acceptable, rely on the existing fallback path but log the raw response for diagnosis
Example fix
# before system = '你是旅行规划助手' # vague -> prose replies -> ValueError # after system = '你是旅行规划助手。你必须只输出一个JSON对象,不要输出任何其他文字,顶层键为: title, days, budget, itinerary.'
Defensive patterns
Strategy: fallback
Validate before calling
import json, re
def try_extract_json(text: str):
m = re.search(r'\{.*\}', text, re.S)
if not m:
return None
try:
return json.loads(m.group(0))
except json.JSONDecodeError:
return None Try / catch
try:
plan = parse_trip_plan(response)
except (ValueError, json.JSONDecodeError, TypeError):
print('falling back to template plan')
plan = template_plan(request) # existing fallback path Prevention
- Demand JSON-only output in the system prompt with a concrete schema
- Use response_format={'type':'json_object'} where the provider supports it
- Keep the fallback path, but log raw responses so fallback frequency is observable
When it happens
Trigger: The model answers entirely in prose ('I cannot plan this trip...'); refusal or safety preamble with no braces; response truncated before any JSON object appeared; model outputting a JSON array only ([...]) which contains no braces.
Common situations: Weak base model ignoring the structured-output instruction; context overflow truncating the reply; API error text captured as the 'response'; non-English reply with no structured section.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/3222be80058260cc.
Report an issue: GitHub.