xxx
This commit is contained in:
@@ -179,6 +179,33 @@ _PARTING_USER = """请评估以下候选分模方向并推荐最优方案:
|
||||
请综合评估制造可行性、成本和风险,给出推荐。"""
|
||||
|
||||
|
||||
_COST_ESTIMATE_SYSTEM = """你是一位资深模具报价工程师,擅长根据产品几何与模具设计方案估算模具造价与单件成本。
|
||||
|
||||
要求:
|
||||
1. 使用中文,金额用人民币(¥)
|
||||
2. 基于给定数据合理估算,数据不足时给出区间并标注假设
|
||||
3. 综合考虑:模具材料、加工复杂度(滑块/斜顶/镶件)、型腔数、产品材料用量、成型周期
|
||||
|
||||
严格输出 JSON,不要输出其他内容。JSON 格式:
|
||||
{
|
||||
"mold_cost": {
|
||||
"material": "¥XX(P20 钢,约 XX kg)",
|
||||
"machining": "¥XX(含 CNC/EDM/线切割)",
|
||||
"complexity_factor": "1.2(含 X 个滑块/斜顶)",
|
||||
"subtotal": "¥XX"
|
||||
},
|
||||
"part_cost": {
|
||||
"material": "¥XX(ABS,约 XX g)",
|
||||
"cycle_time": "30 s",
|
||||
"cost_per_part": "¥XX"
|
||||
},
|
||||
"total_mold_cost": "¥XX",
|
||||
"cost_per_part": "¥XX",
|
||||
"confidence": 0.7,
|
||||
"assumptions": ["假设模具寿命 50 万模次", "假设..."]
|
||||
}"""
|
||||
|
||||
|
||||
class LLMService:
|
||||
"""LLM 增强分析服务(单例)"""
|
||||
|
||||
@@ -308,6 +335,61 @@ class LLMService:
|
||||
logger.warning("LLM 分型推荐失败(不影响主流程): %s", e)
|
||||
return None
|
||||
|
||||
async def estimate_cost(
|
||||
self,
|
||||
analysis_result: Dict[str, Any],
|
||||
detailed_cavity_json: Optional[Dict[str, Any]] = None,
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""估算模具造价与单件成本 (结构化 JSON)"""
|
||||
if not self._enabled:
|
||||
return None
|
||||
try:
|
||||
prompt = self._build_cost_estimate_prompt(analysis_result, detailed_cavity_json)
|
||||
response = await self._chat(
|
||||
_COST_ESTIMATE_SYSTEM,
|
||||
prompt,
|
||||
min(self._max_tokens, 1200),
|
||||
expect_json=True,
|
||||
)
|
||||
if not response:
|
||||
return None
|
||||
result = self._parse_json_response(response)
|
||||
if result:
|
||||
logger.info("LLM 成本估算生成成功: total=%s", result.get("total_mold_cost"))
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.warning("LLM 成本估算失败(不影响主流程): %s", e)
|
||||
return None
|
||||
|
||||
def _build_cost_estimate_prompt(self, analysis_result: Dict[str, Any], detailed_cavity_json: Optional[Dict[str, Any]]) -> str:
|
||||
geometry_data = analysis_result.get("geometry_data", {}) or (detailed_cavity_json or {}).get("geometry_data", {})
|
||||
volume = geometry_data.get("volume", 0) or 0
|
||||
bbox = geometry_data.get("bounding_box", {}) or {}
|
||||
dims = bbox.get("dimensions", [0, 0, 0])
|
||||
meta = (detailed_cavity_json or {}).get("metadata", {}) or {}
|
||||
material = meta.get("selected_material") or analysis_result.get("material") or "ABS"
|
||||
schemes = (detailed_cavity_json or {}).get("candidate_schemes", []) or []
|
||||
best = schemes[0] if schemes else {}
|
||||
cd = best.get("cavity_data", {}) if isinstance(best, dict) else {}
|
||||
mfg = cd.get("manufacturing_info", {}) if isinstance(cd, dict) else {}
|
||||
features = analysis_result.get("detected_features", []) or []
|
||||
complexity_hints = [
|
||||
f.get("description", f.get("feature_type", ""))
|
||||
for f in features
|
||||
if f.get("feature_type") in ("undercut", "side_action", "insert")
|
||||
]
|
||||
return (
|
||||
f"产品材料:{material}\n"
|
||||
f"体积:{float(volume):.1f} mm³\n"
|
||||
f"边界框尺寸(长×宽×高):{float(dims[0]):.1f} × {float(dims[1]):.1f} × {float(dims[2]):.1f} mm\n"
|
||||
f"预估锁模力:{mfg.get('estimated_clamping_force', '未知')}\n"
|
||||
f"预估模具尺寸:{json.dumps(mfg.get('estimated_mold_size', {}), ensure_ascii=False)}\n"
|
||||
f"预估成型周期:{mfg.get('estimated_cycle_time', '未知')}\n"
|
||||
f"型腔数:{best.get('cavity_count', 1) if isinstance(best, dict) else 1}\n"
|
||||
f"模具结构:{best.get('mold_structure_type', '未知') if isinstance(best, dict) else '未知'}\n"
|
||||
f"复杂度线索:{', '.join(complexity_hints) if complexity_hints else '无明显倒扣/滑块'}\n"
|
||||
)
|
||||
|
||||
def _build_design_report_prompt(self, analysis_result, detailed_cavity_json) -> str:
|
||||
features = json.dumps(analysis_result.get("detected_features", []), ensure_ascii=False, indent=2)
|
||||
if len(features) > 4000:
|
||||
|
||||
Reference in New Issue
Block a user