""" pipeline_service/intent_classifier.py — Reusable intent classification. DSPY can call: await intent_classify(model_name, message, intents, context) Registered on ServerEnv in pipeline_service/init.py """ import json import logging logger = logging.getLogger("pipeline.intent_classifier") INTENT_PROMPT = """你是一个意图分类器。分析用户输入,返回 JSON。 可用意图: {intent_list} 当前上下文:{context_str} 返回纯 JSON(不要 markdown 包裹): {{"intent":"...","confidence":0.0-1.0,"params":{{"key":"value"...}},"missing_info":"..."}}""" async def intent_classify(intents: list, message: str, context: dict = None) -> dict: """Classify user intent. Returns {intent, confidence, params, missing_info}. Args: intents: [{"name":"new_project","description":"创建新项目"},...] message: user input text context: {"project_name":"...","iteration_name":"..."} """ if not intents: return {"intent": "chat", "confidence": 0.5, "params": {}, "missing_info": ""} intent_list = "\n".join( f"- {i['name']}: {i.get('description','')}" for i in intents ) ctx_parts = [] if context: for k, v in context.items(): if v: ctx_parts.append(f"{k}={v}") context_str = ", ".join(ctx_parts) if ctx_parts else "无上下文" prompt = INTENT_PROMPT.format(intent_list=intent_list, context_str=context_str) try: from pipeline_service.llm_bridge import llm_call raw = await llm_call( prompt=f"{prompt}\n\n用户输入:{message}", model=None, temperature=0.2, ) raw = raw.strip() if raw.startswith("```"): raw = raw.split("\n", 1)[1].rsplit("```", 1)[0] return json.loads(raw) except Exception as e: logger.warning("intent_classify failed: %s", e) return {"intent": "chat", "confidence": 0.3, "params": {}, "missing_info": ""}