""" 海运协同群文字意图:DeepSeek A 判断补字段 / 产品报价 / 解散 / 其它。 本文件职责:只分类,不写主账、不发企微。 禁止:把「解散群」写成唯一口令;私聊按钮不走这里。 """ from __future__ import annotations import logging from typing import Optional from agent.llm.extract_text import extract_collab_fields logger = logging.getLogger(__name__) INTENT_FIELDS = "collab_fields" INTENT_QUOTE = "product_quote" INTENT_DISSOLVE = "dissolve" INTENT_OTHER = "other" _VALID = {INTENT_FIELDS, INTENT_QUOTE, INTENT_DISSOLVE, INTENT_OTHER} def classify_group_text( text: str, *, injected: str = "", allow_network: Optional[bool] = None, ) -> str: """ 群里一句文字的意图。单测可注入;正式走模型。 模型不可用时:只认带标签的协同字段(键:值是合同,不是口令),其余当其它。 """ hint = (injected or "").strip() if hint in _VALID: return hint raw = (text or "").strip() if not raw: return INTENT_OTHER try: from agent.config import get_settings settings = get_settings() use_net = ( allow_network if allow_network is not None else bool(getattr(settings, "llm_allow_network", False)) ) if use_net and getattr(settings, "llm_data_usage_confirmed", False): got = _classify_with_model(raw, settings) if got in _VALID: return got except Exception: logger.exception("群意图模型失败,回退标签字段") if extract_collab_fields(raw): return INTENT_FIELDS from agent.llm.extract_text import extract_product_quote if extract_product_quote(raw): return INTENT_QUOTE return INTENT_OTHER def _classify_with_model(text: str, settings) -> str: """DeepSeek 只回一个意图词。失败空串。""" from agent.llm.http_client import LlmHttpClient from agent.llm.modes import LlmMode client = LlmHttpClient.from_settings(settings) system = ( "你是海运协同群意图分类。只回复一个英文词,不要解释。" "collab_fields=在补贸易条款/货好时间/商品海关编码/含油含电含磁;" "product_quote=产品在报价格或费用;" "dissolve=要把这个协同群解散;" "other=闲聊、问候、对询价港口的随口更正(不当改单)。" "一句话里既补字段又报价,回 product_quote。" ) data = client.chat( mode=LlmMode.ORDERED_ACTIONS, messages=[ {"role": "system", "content": system}, {"role": "user", "content": text[:2000]}, ], ) content = str(getattr(data, "content", "") or "").strip().lower() for token in (INTENT_QUOTE, INTENT_DISSOLVE, INTENT_FIELDS, INTENT_OTHER): if token in content: return token return ""