#!/usr/bin/env python3 """ Prompt 验收脚本(修改 prompts/ 后运行)。 ./310py/bin/python prompts/smoke.py # 仅校验文件加载与渲染(无需 API Key) ./310py/bin/python prompts/smoke.py --live # 调用模型跑 smoke/reviews.yaml(需 DEEPSEEK_API_KEY) """ from __future__ import annotations import argparse import json import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parent.parent if str(PROJECT_ROOT) not in sys.path: sys.path.insert(0, str(PROJECT_ROOT)) import yaml from prompts.loader import ( build_batch_extraction_system, build_batch_extraction_user, get_schema, product_feedback_categories, validate_prompt_files, ) def _load_smoke_reviews() -> dict: path = Path(__file__).resolve().parent / "smoke/reviews.yaml" with path.open(encoding="utf-8") as f: return yaml.safe_load(f) or {} def run_dry() -> int: errors = validate_prompt_files() if errors: print("❌ Prompt 文件校验失败:") for e in errors: print(f" - {e}") return 1 smoke = _load_smoke_reviews() industry = smoke.get("industry", "Test") product = smoke.get("product_name", "Test") reviews = smoke.get("reviews") or [] keys = [str(r["id"]) for r in reviews] tagged = "\n".join(f"[{r['id']}] {r['text']}" for r in reviews) keys_literal = ", ".join(json.dumps(k) for k in keys) system = build_batch_extraction_system( industry, product, n_keys=len(keys), keys_literal=keys_literal, ) user = build_batch_extraction_user( n_keys=len(keys), keys_literal=keys_literal, tagged_input=tagged, ) print("✅ 外置 Prompt 加载与渲染通过") print(f" 示例评论数: {len(reviews)}") print(f" system 长度: {len(system)} 字符") print(f" user 长度: {len(user)} 字符") return 0 def run_live() -> int: rc = run_dry() if rc != 0: return rc try: from 结构化_server import _call_dashscope_chat, _validate_extraction_strict except ImportError as e: print(f"❌ 无法导入结构化_server: {e}") return 1 smoke = _load_smoke_reviews() industry = smoke["industry"] product = smoke["product_name"] reviews = smoke["reviews"] keys = [str(r["id"]) for r in reviews] tagged = "\n".join(f"[{r['id']}] {r['text']}" for r in reviews) keys_literal = ", ".join(json.dumps(k) for k in keys) system = build_batch_extraction_system( industry, product, n_keys=len(keys), keys_literal=keys_literal, ) user = build_batch_extraction_user( n_keys=len(keys), keys_literal=keys_literal, tagged_input=tagged, ) print("⏳ 调用模型进行 smoke 结构化…") try: raw = _call_dashscope_chat( [{"role": "system", "content": system}, {"role": "user", "content": user}], max_tokens=8192, ) except Exception as e: print(f"❌ 模型调用失败: {e}") return 1 if not isinstance(raw, dict): print(f"❌ 期望 JSON 对象,得到: {type(raw).__name__}") return 1 ok = 0 for k in keys: if k not in raw: print(f"❌ 缺少键 {k}") continue try: _validate_extraction_strict(raw[k], k) ok += 1 print(f"✅ {k} 校验通过") except ValueError as e: print(f"❌ {k} 校验失败: {e}") schema_cats = product_feedback_categories(get_schema()) print(f" 锁定 category 枚举: {', '.join(sorted(schema_cats))}") return 0 if ok == len(keys) else 1 def main() -> int: parser = argparse.ArgumentParser(description="Prompt smoke 验收") parser.add_argument( "--live", action="store_true", help="调用 DashScope 跑 smoke 评论(需 API Key)", ) args = parser.parse_args() return run_live() if args.live else run_dry() if __name__ == "__main__": raise SystemExit(main())