diff --git a/core/order_flow.py b/core/order_flow.py index 05cb93f..7a16b70 100644 --- a/core/order_flow.py +++ b/core/order_flow.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio from typing import TYPE_CHECKING, Optional from core.post_ops import record_deal_success +from core.order_helpers import parse_order_info if TYPE_CHECKING: from core.pydantic_ai_agent import AgentResponse, ConversationState, CustomerMessage, CustomerServiceAgent @@ -22,7 +23,7 @@ async def handle_order_notification( _, order_block = agent._split_customer_text(message.msg) customer_text, _ = agent._split_customer_text(message.msg) - order = agent._parse_order_info(order_block or message.msg) + order = parse_order_info(order_block or message.msg) pay_status = order.get("pay_status", "") order_status = order.get("order_status", "") diff --git a/core/order_helpers.py b/core/order_helpers.py new file mode 100644 index 0000000..f84752d --- /dev/null +++ b/core/order_helpers.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import re +from typing import Dict + + +def parse_order_info(msg: str) -> Dict[str, str]: + """从系统订单消息中提取字段。""" + info: Dict[str, str] = {} + m = re.search(r"订单号[::]\s*(\d+)", msg or "") + if m: + info["order_id"] = m.group(1) + m = re.search(r"订单状态[::]\s*([^\s\[]+)", msg or "") + if m: + info["order_status"] = m.group(1).strip() + m = re.search(r"\[状态[::]\s*([^\]]+)\]", msg or "") + if m: + info["pay_status"] = m.group(1).strip() + m = re.search(r"金额[::]\s*([\d.]+)元", msg or "") + if m: + info["amount"] = m.group(1) + m = re.search(r"数量[::]\s*(\d+)", msg or "") + if m: + info["quantity"] = m.group(1) + m = re.search(r"(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{2}:\d{2})", msg or "") + if m: + info["order_time"] = m.group(1).strip() + m = re.search(r"买家备注[::]\s*([^\n]+)", msg or "") + if m and m.group(1).strip(): + info["buyer_note"] = m.group(1).strip() + return info + + +def order_instruction(pay_status: str, order_status: str) -> str: + paid_keywords = ["等待发货", "已付款", "付款成功", "买家已付款"] + if any(kw in (pay_status or "") or kw in (order_status or "") for kw in paid_keywords): + return "【已付款-必须回复】客户已付款,立刻自然回复确认收款并告知马上安排。" + return "【仅系统通知-无需回复客户】这是系统订单通知,不需要回复客户任何内容,直接跳过。" diff --git a/core/pydantic_ai_agent.py b/core/pydantic_ai_agent.py index 767fd6a..10232cd 100755 --- a/core/pydantic_ai_agent.py +++ b/core/pydantic_ai_agent.py @@ -31,6 +31,7 @@ from core.order_flow import handle_order_notification from core.ai_reply_flow import execute_ai_turn from core.reply_finalize_flow import finalize_ai_reply from core.prompt_flow import build_prompt_bundle +from core.order_helpers import parse_order_info, order_instruction as build_order_instruction load_dotenv() @@ -443,12 +444,12 @@ class CustomerServiceAgent: if scene == "collect_ack" and len(state.pending_image_urls) == 1: first_ack = [ "收到了,我先看一下哈,稍等哈", - "这张我收到了,我先看下,等我一下哈", + "这张我收到了,我先看下,稍等我一下哈", "收到这张了,我先过一眼,稍等哈", "我先看这张哈,稍等我一下", - "图我收到了,我先看一眼,马上回你哈", + "图我收到了,我先看一眼,稍等我回你哈", "这张先记上了,我先看下细节,稍等哈", - "收到哈,我先过一遍这张,等我会儿", + "收到哈,我先过一遍这张,稍等我会儿", "我先看这张效果,稍等一下哈", "图到了,我先看下清晰度,稍等哈", "这张我先看着,稍等我一下就回你", @@ -914,7 +915,7 @@ class CustomerServiceAgent: @self.agent_order.tool async def handle_order(ctx: RunContext[AgentDeps], raw_msg: str = "") -> str: try: - info = self._parse_order_info(raw_msg or "") + info = parse_order_info(raw_msg or "") paid_kw = ["等待发货", "已付款", "付款成功", "买家已付款"] if any(k in (info.get("pay_status", "") or "") for k in paid_kw) or any(k in (info.get("order_status", "") or "") for k in paid_kw): return "已安排,稍后发你" @@ -1900,59 +1901,6 @@ class CustomerServiceAgent: except Exception as e: print(f"[Agent] 订单金额核查失败: {e}") - def _parse_order_info(self, msg: str) -> dict: - """从系统订单消息中提取所有字段""" - import re - info = {} - - m = re.search(r'订单号[::]\s*(\d+)', msg) - if m: - info['order_id'] = m.group(1) - - # 订单大状态(新订单/交易成功/交易关闭等) - m = re.search(r'订单状态[::]\s*([^\s\[]+)', msg) - if m: - info['order_status'] = m.group(1).strip() - - # 支付细状态(等待买家付款/等待发货/交易完成等) - m = re.search(r'\[状态[::]\s*([^\]]+)\]', msg) - if m: - info['pay_status'] = m.group(1).strip() - - # 金额 - m = re.search(r'金额[::]\s*([\d.]+)元', msg) - if m: - info['amount'] = m.group(1) - - # 数量 - m = re.search(r'数量[::]\s*(\d+)', msg) - if m: - info['quantity'] = m.group(1) - - # 时间(格式:2026-2-24 19:52:52) - m = re.search(r'(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{2}:\d{2})', msg) - if m: - info['order_time'] = m.group(1).strip() - - # 买家备注 - m = re.search(r'买家备注[::]\s*([^\n]+)', msg) - if m and m.group(1).strip(): - info['buyer_note'] = m.group(1).strip() - - return info - - def _get_order_instruction(self, pay_status: str, order_status: str) -> str: - """ - 根据订单状态生成 AI 指令。 - 只有「已付款」才需要回复客户,其他状态一律静默。 - """ - paid_keywords = ["等待发货", "已付款", "付款成功", "买家已付款"] - if any(kw in pay_status or kw in order_status for kw in paid_keywords): - return "【已付款-必须回复】客户已付款,立刻自然回复确认收款并告知马上安排。" - else: - # 所有其他状态(待付款、交易完成、关闭等)静默处理 - return "【仅系统通知-无需回复客户】这是系统订单通知,不需要回复客户任何内容,直接跳过。" - def _extract_image_url(self, msg: str) -> str: """从消息中提取图片URL,兼容纯URL和 text#*#url 两种格式""" urls = self._extract_image_urls(msg) @@ -2653,7 +2601,7 @@ class CustomerServiceAgent: has_order = bool(order_block) if has_order: - order = self._parse_order_info(order_block) + order = parse_order_info(order_block) if order.get('order_id'): state.last_order_id = order['order_id'] stage_info += f"\n【订单号】{order['order_id']}" @@ -2707,7 +2655,7 @@ class CustomerServiceAgent: order_paid = False order_unpaid = False if has_order: - order = self._parse_order_info(order_block) + order = parse_order_info(order_block) paid_kws = ["等待发货", "已付款", "付款成功", "买家已付款"] unpaid_kws = ["等待买家付款", "待付款", "未付款"] ps = order.get('pay_status', '') @@ -2774,8 +2722,8 @@ class CustomerServiceAgent: # ── 附加订单信息(不覆盖客户问题的优先级)── if has_order: - order = self._parse_order_info(order_block) - order_instruction = self._get_order_instruction( + order = parse_order_info(order_block) + order_instruction = build_order_instruction( order.get('pay_status', ''), order.get('order_status', '') )