"""配置与提示词加载工具。 职责: - 读取 configs/countries/.yaml(该国专属种子词/权重/limit 等覆盖) - 读取 prompts//aesthetics.yaml(该国审美 hint、风格-配色 extra 规则、额外黑名单) - 读取 prompts//system_prompt.md(该国 LLM 系统提示覆盖) - 把上述合并进 country_config,供节点使用 """ from pathlib import Path from typing import Any, Dict import yaml def load_yaml_safe(path: Path) -> Dict[str, Any]: if not path.exists(): return {} try: return yaml.safe_load(path.read_text(encoding="utf-8")) or {} except Exception as e: # noqa: BLE001 print(f"[loader] 解析失败 {path}: {e}") return {} def load_text_safe(path: Path) -> str: if not path.exists(): return "" try: return path.read_text(encoding="utf-8").strip() except Exception: # noqa: BLE001 return "" def build_country_config(global_config: Dict[str, Any], country: str, project_root: Path) -> Dict[str, Any]: """合并:全局配置 + 国家专属 yaml + 国家审美 yaml。""" cc: Dict[str, Any] = load_yaml_safe(project_root / "configs" / "countries" / f"{country}.yaml") aesthetics = load_yaml_safe(project_root / "prompts" / country / "aesthetics.yaml") cc.setdefault("style_hint", aesthetics.get("style_hint", "")) cc.setdefault("extra_style_rules", aesthetics.get("extra_style_rules", []) or []) cc.setdefault("extra_blacklist", aesthetics.get("extra_blacklist", []) or []) # 国家专属趋势/风格/行业种子(若 aesthetics 里有也并入 cc 顶层,便于 source 读取) for k in ("trending", "style", "related", "timeframe"): if k in aesthetics and k not in cc: cc[k] = aesthetics[k] return cc def load_system_prompt(prompts_dir: Path, default: str) -> str: """该国 prompts//system_prompt.md 作为「补充段」叠加到默认规则之后。 这样既能按国家定制口吻/合规重点,又不丢失内置核心合规规则。若该国未提供文件则用默认。 """ text = load_text_safe(prompts_dir / "system_prompt.md") if not text: return default return default + "\n\n# 该国专属补充指令\n" + text