落地销售调价:按自然语言改价并单独记销售价,拉群和后台不再把调后价当成 TMS 原价。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -67,6 +67,9 @@ def _prepare_model_tool_args(
|
||||
if intent == "continue_thread" or action_type == "CONTINUE_HISTORICAL_TICKET":
|
||||
data["intent"] = "continue_thread"
|
||||
action["action_type"] = "CONTINUE_HISTORICAL_TICKET"
|
||||
if intent == "quote_adjust" or action_type == "QUOTE_ADJUST":
|
||||
data["intent"] = "quote_adjust"
|
||||
action["action_type"] = "QUOTE_ADJUST"
|
||||
target = action.get("target") if isinstance(action.get("target"), dict) else {}
|
||||
wo = str(target.get("work_order_no") or "").strip()
|
||||
if data.get("intent") == "continue_thread" and not wo:
|
||||
@@ -98,9 +101,13 @@ _SYSTEM = (
|
||||
"原话在描述新的运输需求(港口/机场、货物、件数重量体积、空运海运陆运等),"
|
||||
"即使偶尔拿旧单号当参考,也走新询价,work_order_no 留空。"
|
||||
"陆运核对卡之后回复确定、确认、查价、可以查了,仍是新询价,禁止标闲聊。"
|
||||
"【调价】intent=quote_adjust,action_type=QUOTE_ADJUST。"
|
||||
"inbound_facts 里 session_quoted=true 时,销售用自然语言改当前已有报价:"
|
||||
"涨、跌、加、减、上升、上浮、往上抬、改到某金额、在现有报价基础上调整,口令不写死。"
|
||||
"只说报价/总价、没点名费用,仍是调价,不是闲聊也不是新询价。"
|
||||
"【闲聊】intent=ordinary_text_other,action_type=ORDINARY_TEXT_OTHER。"
|
||||
"问候、谢谢、无关闲聊。点卡片按钮字(生成Excel/生成PDF/不采用等)也标闲聊。"
|
||||
"禁止因为销售没说指定口令就把续办判成新询价。"
|
||||
"禁止因为销售没说指定口令就把续办或调价判成新询价或闲聊。"
|
||||
)
|
||||
|
||||
|
||||
@@ -134,22 +141,29 @@ class DeepSeekARouter:
|
||||
allow_network=allow_network,
|
||||
)
|
||||
|
||||
def build_messages(self, *, text: str, sender_id: str) -> list[dict[str, Any]]:
|
||||
"""构造仅含 inbound_facts 的 messages(不做字段抽取)。"""
|
||||
facts = {
|
||||
"sender_id": sender_id,
|
||||
"text": text,
|
||||
"text_sha256": _digest_text(text or ""),
|
||||
}
|
||||
def build_messages(
|
||||
self,
|
||||
*,
|
||||
text: str,
|
||||
sender_id: str,
|
||||
session_quoted: bool = False,
|
||||
fee_names: Optional[list[str]] = None,
|
||||
work_order_no: str = "",
|
||||
) -> list[dict[str, Any]]:
|
||||
"""构造仅含 inbound_facts 的 messages(不做字段抽取、不算价)。"""
|
||||
names = "、".join(str(x).strip() for x in (fee_names or []) if str(x).strip())
|
||||
return [
|
||||
{"role": "system", "content": _SYSTEM},
|
||||
{
|
||||
"role": "user",
|
||||
"content": (
|
||||
"inbound_facts (JSON-like):\n"
|
||||
f"sender_id={facts['sender_id']}\n"
|
||||
f"text_sha256={facts['text_sha256']}\n"
|
||||
f"text={facts['text']}\n"
|
||||
f"sender_id={sender_id}\n"
|
||||
f"text_sha256={_digest_text(text or '')}\n"
|
||||
f"text={text}\n"
|
||||
f"session_quoted={'true' if session_quoted else 'false'}\n"
|
||||
f"work_order_no={work_order_no or '-'}\n"
|
||||
f"fee_names={names or '-'}\n"
|
||||
"Call route_decision once."
|
||||
),
|
||||
},
|
||||
@@ -212,12 +226,21 @@ class DeepSeekARouter:
|
||||
logger.info("DeepSeekA stub fixture sender=%s", sender_id)
|
||||
return self.route_from_tool_args(args)
|
||||
|
||||
def route(self, *, text: str, sender_id: str) -> RouteDecision:
|
||||
def route(
|
||||
self,
|
||||
*,
|
||||
text: str,
|
||||
sender_id: str,
|
||||
session_quoted: bool = False,
|
||||
fee_names: Optional[list[str]] = None,
|
||||
work_order_no: str = "",
|
||||
) -> RouteDecision:
|
||||
"""
|
||||
执行 A 路由。
|
||||
|
||||
无 sender_id → reject;未开网络或未确认数据用途 → stub fixture;
|
||||
开网络 → tool_choice 强制 route_decision。
|
||||
session_quoted 告诉模型当前私聊已有可调报价,口令不写死。
|
||||
"""
|
||||
if not sender_id:
|
||||
return RouteDecision(intent="reject_no_sender", confidence=1.0)
|
||||
@@ -228,8 +251,20 @@ class DeepSeekARouter:
|
||||
)
|
||||
return self.route_stub_fixture(text=text, sender_id=sender_id)
|
||||
|
||||
logger.info("DeepSeekA 真网路由 sender=%s chars=%s", sender_id, len(text or ""))
|
||||
messages = self.build_messages(text=text, sender_id=sender_id)
|
||||
logger.info(
|
||||
"DeepSeekA 真网路由 sender=%s chars=%s quoted=%s wo=%s",
|
||||
sender_id,
|
||||
len(text or ""),
|
||||
session_quoted,
|
||||
work_order_no or "-",
|
||||
)
|
||||
messages = self.build_messages(
|
||||
text=text,
|
||||
sender_id=sender_id,
|
||||
session_quoted=session_quoted,
|
||||
fee_names=fee_names,
|
||||
work_order_no=work_order_no,
|
||||
)
|
||||
tools = [ordered_actions_tool_definition()]
|
||||
result: LlmHttpResult = self.http.chat(
|
||||
mode=LlmMode.ORDERED_ACTIONS,
|
||||
|
||||
Reference in New Issue
Block a user