feat: 添加物流查询功能和完善 token 传递

- 添加 get_logistics 工具查询 Mall API /mall/api/order/parcel
- 修复 Cookie token 传递到 MCP 的问题
- 增强 LLM 客户端超时处理和日志
- 移除 MALL_API_TOKEN,使用用户登录 token
- 更新测试页面使用 setUser 设置用户属性
- 增强 webhook 调试日志
This commit is contained in:
wangliang
2026-01-16 18:36:17 +08:00
parent cd787d608b
commit c4e97cf312
9 changed files with 334 additions and 111 deletions

View File

@@ -25,7 +25,11 @@ ORDER_AGENT_PROMPT = """你是一个专业的 B2B 订单服务助手。
- order_id: 订单号(必需)
- 说明:此工具会自动使用用户的身份 token 查询商城订单详情
2. **query_order** - 查询历史订单
2. **get_logistics** - 从商城 API 查询物流信息
- order_id: 订单号(必需)
- 说明:查询订单的物流轨迹和配送状态
3. **query_order** - 查询历史订单
- user_id: 用户 ID自动注入
- account_id: 账户 ID自动注入
- order_id: 订单号(可选,不填则查询最近订单)
@@ -33,10 +37,6 @@ ORDER_AGENT_PROMPT = """你是一个专业的 B2B 订单服务助手。
- date_end: 结束日期(可选)
- status: 订单状态(可选)
3. **track_logistics** - 物流跟踪
- order_id: 订单号
- tracking_number: 物流单号(可选)
4. **modify_order** - 修改订单
- order_id: 订单号
- user_id: 用户 ID自动注入
@@ -108,12 +108,25 @@ ORDER_AGENT_PROMPT = """你是一个专业的 B2B 订单服务助手。
}
```
用户: "帮我查一下订单 202071324 的物流"
回复:
```json
{
"action": "call_tool",
"tool_name": "get_logistics",
"arguments": {
"order_id": "202071324"
}
}
```
## 重要约束
- **必须返回完整的 JSON 对象**,不要只返回部分内容
- **不要添加任何 markdown 代码块标记**(如 \`\`\`json
- **不要添加任何解释性文字**,只返回 JSON
- user_id 和 account_id 会自动注入到 arguments 中,无需手动添加
- 如果用户提供了订单号,优先使用 get_mall_order 工具
- 如果用户想查询物流状态,使用 get_logistics 工具
- 对于敏感操作(取消、修改),确保有明确的订单号
"""
@@ -204,7 +217,15 @@ async def order_agent(state: AgentState) -> AgentState:
# Inject user_token if available
if state.get("user_token"):
arguments["user_token"] = state["user_token"]
logger.info("Injected user_token into tool call")
logger.info(
"Injected user_token into tool call",
token_prefix=state["user_token"][:20] if state["user_token"] else None
)
else:
logger.warning(
"No user_token available in state, MCP will use default token",
conversation_id=state["conversation_id"]
)
# Use entity if available
if "order_id" not in arguments and state["entities"].get("order_id"):
@@ -290,7 +311,15 @@ async def order_agent(state: AgentState) -> AgentState:
# Inject user_token if available (for Mall API calls)
if state.get("user_token"):
arguments["user_token"] = state["user_token"]
logger.debug("Injected user_token into tool call")
logger.debug(
"Injected user_token into tool call",
token_prefix=state["user_token"][:20] if state["user_token"] else None
)
else:
logger.warning(
"No user_token available in state, MCP will use default token",
conversation_id=state["conversation_id"]
)
# Use entity if available
if "order_id" not in arguments and state["entities"].get("order_id"):

View File

@@ -81,12 +81,27 @@ async def classify_intent(state: AgentState) -> AgentState:
# Parse JSON response
content = response.content.strip()
# Log raw response for debugging
logger.debug(
"LLM response for intent classification",
response_preview=content[:500] if content else "EMPTY",
content_length=len(content) if content else 0
)
# Handle markdown code blocks
if content.startswith("```"):
content = content.split("```")[1]
if content.startswith("json"):
content = content[4:]
# Check for empty response
if not content:
logger.warning("LLM returned empty response for intent classification")
state["intent"] = Intent.CUSTOMER_SERVICE.value # Default to customer service
state["intent_confidence"] = 0.5
return state
result = json.loads(content)
# Extract intent