fix: 修复 JSON 解析导致的 tool_name 丢失问题
## 问题 商品搜索时工具名丢失,导致 404 错误: ``` HTTP Request: POST http://product_mcp:8004/tools/ "HTTP/1.1 404 Not Found" ``` URL 应该是 `/tools/search_products` 但实际是 `/tools/`(工具名丢失) ## 根本原因 当 LLM 返回带 ```json``` 代码块格式的 JSON 时: ``` ```json { "action": "call_tool", "tool_name": "search_products", "arguments": {"keyword": "ring"} } ``` ``` 解析逻辑处理后: 1. 移除 ```` → 得到 `json\n{\n...` 2. 移除 `json` → 得到 `\n{\n...` 3. 内容以换行符开头,不是 `{` 4. 被误判为非 JSON 格式(`tool_name\n{args}`) 5. 按换行符分割,第一行为空 → `tool_name = ""` ## 解决方案 **第 189 行**:添加 `content.strip()` 去除前后空白 ```python if content.startswith("```"): content = content.split("```")[1] if content.startswith("json"): content = content[4:] # Remove leading/trailing whitespace after removing code block markers content = content.strip() # ← 新增 ``` ## 额外改进 **第 217-224 行**:添加工具调用日志 ```python logger.info( "Product agent calling tool", tool_name=tool_name, arguments=arguments, conversation_id=state["conversation_id"] ) ``` 便于调试工具调用问题。 ## 测试验证 修复前: ``` tool_name = "" (空字符串) URL: /tools/ (缺少工具名) ``` 修复后: ``` tool_name = "search_products" (正确) URL: /tools/search_products (完整路径) ``` Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -185,6 +185,8 @@ async def product_agent(state: AgentState) -> AgentState:
|
|||||||
content = content.split("```")[1]
|
content = content.split("```")[1]
|
||||||
if content.startswith("json"):
|
if content.startswith("json"):
|
||||||
content = content[4:]
|
content = content[4:]
|
||||||
|
# Remove leading/trailing whitespace after removing code block markers
|
||||||
|
content = content.strip()
|
||||||
|
|
||||||
# Handle non-JSON format: "tool_name\n{args}"
|
# Handle non-JSON format: "tool_name\n{args}"
|
||||||
if '\n' in content and not content.startswith('{'):
|
if '\n' in content and not content.startswith('{'):
|
||||||
@@ -214,9 +216,17 @@ async def product_agent(state: AgentState) -> AgentState:
|
|||||||
|
|
||||||
if action == "call_tool":
|
if action == "call_tool":
|
||||||
arguments = result.get("arguments", {})
|
arguments = result.get("arguments", {})
|
||||||
|
tool_name = result.get("tool_name", "")
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"Product agent calling tool",
|
||||||
|
tool_name=tool_name,
|
||||||
|
arguments=arguments,
|
||||||
|
conversation_id=state["conversation_id"]
|
||||||
|
)
|
||||||
|
|
||||||
# Inject context for product search (Mall API)
|
# Inject context for product search (Mall API)
|
||||||
if result["tool_name"] == "search_products":
|
if tool_name == "search_products":
|
||||||
arguments["user_token"] = state.get("user_token")
|
arguments["user_token"] = state.get("user_token")
|
||||||
arguments["user_id"] = state["user_id"]
|
arguments["user_id"] = state["user_id"]
|
||||||
arguments["account_id"] = state["account_id"]
|
arguments["account_id"] = state["account_id"]
|
||||||
@@ -230,12 +240,12 @@ async def product_agent(state: AgentState) -> AgentState:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Inject context for recommendation
|
# Inject context for recommendation
|
||||||
if result["tool_name"] == "recommend_products":
|
if tool_name == "recommend_products":
|
||||||
arguments["user_id"] = state["user_id"]
|
arguments["user_id"] = state["user_id"]
|
||||||
arguments["account_id"] = state["account_id"]
|
arguments["account_id"] = state["account_id"]
|
||||||
|
|
||||||
# Inject context for quote
|
# Inject context for quote
|
||||||
if result["tool_name"] == "get_quote":
|
if tool_name == "get_quote":
|
||||||
arguments["account_id"] = state["account_id"]
|
arguments["account_id"] = state["account_id"]
|
||||||
|
|
||||||
# Use entity if available
|
# Use entity if available
|
||||||
@@ -247,7 +257,7 @@ async def product_agent(state: AgentState) -> AgentState:
|
|||||||
|
|
||||||
state = add_tool_call(
|
state = add_tool_call(
|
||||||
state,
|
state,
|
||||||
tool_name=result["tool_name"],
|
tool_name=tool_name,
|
||||||
arguments=arguments,
|
arguments=arguments,
|
||||||
server="product"
|
server="product"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user