diff --git a/graph/llms/openai_compat_backend.py b/graph/llms/openai_compat_backend.py index 3e590d5..17300e0 100644 --- a/graph/llms/openai_compat_backend.py +++ b/graph/llms/openai_compat_backend.py @@ -593,7 +593,14 @@ class OpenAICompatBackend(LLMBackend): print(f"[pinterest_analyze] 解析失败: {e}") return [] designs = [] - for i, d in enumerate(parsed.get("designs") or []): + # 兼容 LLM 返回裸数组([...])或 {designs: [...]} 两种结构 + if isinstance(parsed, dict): + designs_raw = parsed.get("designs") or [] + elif isinstance(parsed, list): + designs_raw = parsed + else: + designs_raw = [] + for i, d in enumerate(designs_raw): if not isinstance(d, dict): continue designs.append({ diff --git a/graph/nodes/pinterest_analyze_node.py b/graph/nodes/pinterest_analyze_node.py index 4e3c05a..0740d0f 100644 --- a/graph/nodes/pinterest_analyze_node.py +++ b/graph/nodes/pinterest_analyze_node.py @@ -104,13 +104,15 @@ def pinterest_analyze_node(state: Dict[str, Any]) -> Dict[str, Any]: "message": f"term[{term}]: {e}", "trace": ""}) print(f"[pinterest_analyze] 「{term}」分析失败: {e}") - # 3) 兜底:LLM 无结果 → mock 规则简报(零 API 成本,保证有设计可生成) - if not raw_briefs and llm is not None: + # 3) 兜底:LLM 无结果 → mock 规则简报(零 API 成本,保证有设计可生成)。 + # 注意必须切到 mock 后端,不能再调回失败的 llm(否则同样报错)。 + if not raw_briefs: try: + mock = get_backend("mock") for term, paths in images.items(): sample = list(paths)[:analyze_per_term] if sample: - raw_briefs.extend(llm.analyze_pinterest_images(sample, term, country) or []) + raw_briefs.extend(mock.analyze_pinterest_images(sample, term, country) or []) print(f"[pinterest_analyze] 兜底:mock 规则简报 {len(raw_briefs)} 条") except Exception as e: # noqa: BLE001 print(f"[pinterest_analyze] mock 兜底失败: {e}")