The Agent invokes an MCP to respond to the user's query. #20710

Closed
opened 2026-02-21 20:08:35 -05:00 by yindo · 1 comment
Owner

Originally created by @ccm326143547 on GitHub (Dec 1, 2025).

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

1.10.0

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

In Dify, when an Agent invokes an MCP, the prompt includes rules and constraints for decomposing the user's query. The Agent correctly breaks down the user's question, but it ends up calling the same MCP twice. When generating the final response, the Agent only references the result from the last MCP call, failing to address the full scope of the user's original question.

{
"model": {
"completion_params": {},
"mode": "chat",
"model": "qwen2.5:32b",
"model_type": "llm",
"provider": "langgenius/ollama/ollama",
"type": "model-selector"
},
"query": "查询在2025年7月23号和平北路局前街 路口的拥堵指数情况,查询和平北路局前街 路口的经纬度",
"instruction": "你是一个专业的智能交通问答代理,能够准确理解用户提出的复合型交通查询,并基于系统已自动调用的后端 MCP 工具返回的数据,生成完整、准确、结构清晰的自然语言回答。\n\n请严格遵循以下规则:\n\n一、【任务目标】\n用户的问题可能包含多个互不相同的独立查询意图。\n系统已在前置步骤中将问题按语义拆解,并为每个唯一子意图精确调用一个 MCP 工具。\n你将收到若干 tool_response,每一个都对应一个唯一的子问题。\n⚠️ 注意:系统保证不会对同一子意图重复调用工具。若你发现多个 tool_response 内容高度相似,请视为数据冗余,仍按数量逐项回应。\n二、【强制回应原则】\n必须逐项回应每一个 tool_response,即使数据为空、重复或无效。\n若数据有效:提取关键信息,用简洁语言解释。\n若数据为空:明确说明 “未查询到【该子问题】相关信息” 或 “当前无相关数据”。\n禁止选择性回答。即使某项数据看似次要(如单个坐标值 vs 大量时间序列),也必须同等对待。\n每个工具调用 = 一个独立回答段落,不可跨工具融合描述。\n\n三、【输出格式规范】\n你的最终回答必须严格采用以下结构:\n\n根据您的查询,分项答复如下:\n\n1. 关于【<忠实还原用户原始问题中对应的子句语义>】\n\n<基于该工具返回数据的精准解读。数值类保留合理精度(如坐标6位小数);时间序列需总结峰值、谷值、典型时段特征;列表类归纳核心模式,避免逐条罗列>\n\n2. 关于【<忠实还原用户原始问题中对应的子句语义>】\n\n<同上>\n\n……\n\n如需进一步分析,请随时告知!\n\n四、【语言强制规则】\n- 输出语言:100% 简体中文。\n- 禁止行为:不得出现英文句子、英文段落、中英夹杂(如“拥堵指数为 5.208,very high”)。\n- 允许例外:仅限用户原始问题中已包含的英文专有名词(如路口名含“Road”)、或工具返回字段中的标准技术缩写(如“GPS”、“API”、“MCP”)。\n- 若不确定某词可保留英文。\n\n⚠️ 重要执行约束:\n- 系统将按顺序为你提供每个子问题的工具调用结果。\n- 每当你收到一个 tool_response,请立即在内部标记该子问题为“已完成”。\n- 即使你尚未生成最终回答,也绝不可再次请求相同工具。\n- 若你发现某个子问题已返回数据,请跳过对该子问题的任何进一步操作。\n\n📌 关键要求:\n\n“子问题语义简述”必须直接源自用户原始提问中的自然语言片段,不得自行概括或改写(例如用户说“经纬度”,你就写“经纬度”,不说“地理位置”)。\n每一段必须明确绑定一个且仅一个工具调用结果。\n回答内容需体现数据驱动:所有结论必须有 tool_response 支撑,禁止臆测或补充外部知识。\n四、【数据解析指引(通用)】\n标量数据(如坐标、ID、类别):直接呈现,注明单位或含义。\n时间序列数据:指出最大值及发生时间、最小值及时间、典型高峰/低谷时段。\n列表或统计类数据:总结主要构成、占比趋势或异常项,避免冗长枚举。\n空/错误响应:统一表述为“未查询到……”或“当前无……数据”,保持语气专业一致。\n五、【兜底与边界处理】\n若所有 tool_response 均无有效内容,回复:\n“很抱歉,未能查询到与您问题相关的任何数据。”\n\n此阶段不应出现无法映射的工具调用(因语义路由已在前序完成),你只需专注“回应已有结果”。\n 请始终记住:\n\n完整性优先于简洁性,准确性优先于流畅性。\n\n你的回答是用户获取多维交通信息的唯一出口,每一项工具结果都代表一个被承诺解答的子问题,缺一不可。",
"tools": [
{
"enabled": true,
"extra": {
"description": "调用 MCP 服务端工具。"
},
"parameters": {
"arguments": null,
"servers_config": null,
"tool_name": null
},
"provider_name": "junjiem/mcp_sse/mcp_sse",
"provider_show_name": "junjiem/mcp_sse/mcp_sse",
"settings": {
"prompts_as_tools": {
"type": "constant",
"value": false
},
"resources_as_tools": {
"type": "constant",
"value": false
}
},
"tool_description": "调用 MCP 服务端工具。",
"tool_label": "调用 MCP 工具",
"tool_name": "mcp_sse_call_tool",
"type": "builtin"
}
],
"maximum_iterations": 8,
"mcp_resources_as_tools": false,
"mcp_prompts_as_tools": false,
"mcp_servers_config": "{\n "server_name1": {\n "url": "http://10.25.103.163:9870/mcp/v5091/sse",\n "headers": {},\n "timeout": 300,\n "sse_read_timeout": 300\n },\n "server_name2": {\n "url": "http://10.25.103.163:9870/mcp/v5082/sse",\n "headers": {},\n "timeout": 300,\n "sse_read_timeout": 300\n }\n}"
}


{
"output": "",
"tool_input": [
{
"args": {
"question": "查询2025年7月23号和平北路局前街路口的拥堵指数情况"
},
"name": "vanna5091"
},
{
"args": {
"question": "查询2025年7月23号和平北路局前街路口的拥堵指数情况"
},
"name": "vanna5091"
},
{
"args": {
"question": "查询和平北路局前街 路口的经纬度"
},
"name": "vanna5082"
}
],
"tool_name": "vanna5091;vanna5091;vanna5082"
}

{
"output": {
"llm_response": "根据您的查询,分项答复如下:\n\n1. 关于【经纬度】\n\n查询结果显示该位置的纬度为 31.782370,经度为 119.961800。数据重复提供了三次相同坐标值。\n\n如需进一步分析,请随时告知!",
"tool_responses": []
}
}

✔️ Expected Behavior

  1. Invoke the same MCP method only once.
  2. The LLM's response must fully cover the user's query.

Actual Behavior

  1. The same MCP method is invoked twice.
  2. The LLM's response does not fully address the user's query.
Originally created by @ccm326143547 on GitHub (Dec 1, 2025). ### Self Checks - [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542). - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit this report, otherwise it will be closed. - [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version 1.10.0 ### Cloud or Self Hosted Self Hosted (Docker) ### Steps to reproduce In Dify, when an Agent invokes an MCP, the prompt includes rules and constraints for decomposing the user's query. The Agent correctly breaks down the user's question, but it ends up calling the same MCP twice. When generating the final response, the Agent only references the result from the last MCP call, failing to address the full scope of the user's original question. { "model": { "completion_params": {}, "mode": "chat", "model": "qwen2.5:32b", "model_type": "llm", "provider": "langgenius/ollama/ollama", "type": "model-selector" }, "query": "查询在2025年7月23号和平北路局前街 路口的拥堵指数情况,查询和平北路局前街 路口的经纬度", "instruction": "你是一个专业的智能交通问答代理,能够准确理解用户提出的复合型交通查询,并基于系统已自动调用的后端 MCP 工具返回的数据,生成完整、准确、结构清晰的自然语言回答。\n\n请严格遵循以下规则:\n\n一、【任务目标】\n用户的问题可能包含多个**互不相同的**独立查询意图。\n系统已在前置步骤中将问题按语义拆解,并为**每个唯一子意图**精确调用一个 MCP 工具。\n你将收到若干 tool_response,每一个都对应一个**唯一的**子问题。\n⚠️ 注意:系统保证不会对同一子意图重复调用工具。若你发现多个 tool_response 内容高度相似,请视为数据冗余,仍按数量逐项回应。\n二、【强制回应原则】\n必须逐项回应每一个 tool_response,即使数据为空、重复或无效。\n若数据有效:提取关键信息,用简洁语言解释。\n若数据为空:明确说明 “未查询到【该子问题】相关信息” 或 “当前无相关数据”。\n禁止选择性回答。即使某项数据看似次要(如单个坐标值 vs 大量时间序列),也必须同等对待。\n每个工具调用 = 一个独立回答段落,不可跨工具融合描述。\n\n三、【输出格式规范】\n你的最终回答必须严格采用以下结构:\n\n根据您的查询,分项答复如下:\n\n1. 关于【<忠实还原用户原始问题中对应的子句语义>】\n\n<基于该工具返回数据的精准解读。数值类保留合理精度(如坐标6位小数);时间序列需总结峰值、谷值、典型时段特征;列表类归纳核心模式,避免逐条罗列>\n\n2. 关于【<忠实还原用户原始问题中对应的子句语义>】\n\n<同上>\n\n……\n\n如需进一步分析,请随时告知!\n\n四、【语言强制规则】\n- 输出语言:100% 简体中文。\n- 禁止行为:不得出现英文句子、英文段落、中英夹杂(如“拥堵指数为 5.208,very high”)。\n- 允许例外:仅限用户原始问题中已包含的英文专有名词(如路口名含“Road”)、或工具返回字段中的标准技术缩写(如“GPS”、“API”、“MCP”)。\n- 若不确定某词可保留英文。\n\n⚠️ 重要执行约束:\n- 系统将按顺序为你提供每个子问题的工具调用结果。\n- 每当你收到一个 tool_response,请立即在内部标记该子问题为“已完成”。\n- 即使你尚未生成最终回答,也绝不可再次请求相同工具。\n- 若你发现某个子问题已返回数据,请跳过对该子问题的任何进一步操作。\n\n📌 关键要求:\n\n“子问题语义简述”必须直接源自用户原始提问中的自然语言片段,不得自行概括或改写(例如用户说“经纬度”,你就写“经纬度”,不说“地理位置”)。\n每一段必须明确绑定一个且仅一个工具调用结果。\n回答内容需体现数据驱动:所有结论必须有 tool_response 支撑,禁止臆测或补充外部知识。\n四、【数据解析指引(通用)】\n标量数据(如坐标、ID、类别):直接呈现,注明单位或含义。\n时间序列数据:指出最大值及发生时间、最小值及时间、典型高峰/低谷时段。\n列表或统计类数据:总结主要构成、占比趋势或异常项,避免冗长枚举。\n空/错误响应:统一表述为“未查询到……”或“当前无……数据”,保持语气专业一致。\n五、【兜底与边界处理】\n若所有 tool_response 均无有效内容,回复:\n“很抱歉,未能查询到与您问题相关的任何数据。”\n\n此阶段不应出现无法映射的工具调用(因语义路由已在前序完成),你只需专注“回应已有结果”。\n✅ 请始终记住:\n\n完整性优先于简洁性,准确性优先于流畅性。\n\n你的回答是用户获取多维交通信息的唯一出口,每一项工具结果都代表一个被承诺解答的子问题,缺一不可。", "tools": [ { "enabled": true, "extra": { "description": "调用 MCP 服务端工具。" }, "parameters": { "arguments": null, "servers_config": null, "tool_name": null }, "provider_name": "junjiem/mcp_sse/mcp_sse", "provider_show_name": "junjiem/mcp_sse/mcp_sse", "settings": { "prompts_as_tools": { "type": "constant", "value": false }, "resources_as_tools": { "type": "constant", "value": false } }, "tool_description": "调用 MCP 服务端工具。", "tool_label": "调用 MCP 工具", "tool_name": "mcp_sse_call_tool", "type": "builtin" } ], "maximum_iterations": 8, "mcp_resources_as_tools": false, "mcp_prompts_as_tools": false, "mcp_servers_config": "{\n \"server_name1\": {\n \"url\": \"http://10.25.103.163:9870/mcp/v5091/sse\",\n \"headers\": {},\n \"timeout\": 300,\n \"sse_read_timeout\": 300\n },\n \"server_name2\": {\n \"url\": \"http://10.25.103.163:9870/mcp/v5082/sse\",\n \"headers\": {},\n \"timeout\": 300,\n \"sse_read_timeout\": 300\n }\n}" } ----------------------------------------------------------------------- <!-- Failed to upload "PixPin_2025-12-01_15-59-09.png" --> { "output": "", "tool_input": [ { "args": { "question": "查询2025年7月23号和平北路局前街路口的拥堵指数情况" }, "name": "vanna5091" }, { "args": { "question": "查询2025年7月23号和平北路局前街路口的拥堵指数情况" }, "name": "vanna5091" }, { "args": { "question": "查询和平北路局前街 路口的经纬度" }, "name": "vanna5082" } ], "tool_name": "vanna5091;vanna5091;vanna5082" } ------------------------------------------------------------------- { "output": { "llm_response": "根据您的查询,分项答复如下:\n\n1. 关于【经纬度】\n\n查询结果显示该位置的纬度为 31.782370,经度为 119.961800。数据重复提供了三次相同坐标值。\n\n如需进一步分析,请随时告知!", "tool_responses": [] } } ### ✔️ Expected Behavior 1. Invoke the same MCP method only once. 2. The LLM's response must fully cover the user's query. ### ❌ Actual Behavior 1. The same MCP method is invoked twice. 2. The LLM's response does not fully address the user's query.
yindo added the 🤖 feat:agent label 2026-02-21 20:08:35 -05:00
yindo closed this issue 2026-02-21 20:08:35 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Dec 1, 2025):

Hi @ccm326143547! I'm Dosu and I’m helping the dify team.

The duplicate MCP tool invocation and incomplete LLM response are caused by two main issues in the current implementation:

  1. No deduplication of tool calls: The agent orchestration (specifically, the FunctionCallAgentRunner) does not filter out duplicate tool calls for the same sub-question. If the LLM outputs multiple identical tool calls, each is invoked, even if they are for the same intent. This happens because deduplication is not enforced in the tool invocation pipeline—neither in the agent runner nor in the ToolEngine or MCPTool layers. Deduplication should be handled upstream, ideally right after query decomposition or before invoking tools, to ensure each unique sub-question is only called once (source).

  2. Tool response aggregation overwrites previous results: Tool responses are stored in a dictionary keyed by tool name. If the same tool is called multiple times, only the last response is kept, and earlier results are overwritten. This means the final LLM response only references the last tool call result, not all results (source).

Recommendations:

  • Implement deduplication of tool calls for identical sub-questions before invoking tools, either in the agent runner or immediately after query decomposition.
  • Change the tool response aggregation logic to store responses per call (e.g., by tool_call_id or as a list), so all results are preserved and available for the final LLM response, not just the last one.

No recent pull requests address this logic, so these changes would need to be made in your deployment. This should ensure each unique sub-question is only invoked once and all tool responses are included in the LLM's final answer.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

@dosubot[bot] commented on GitHub (Dec 1, 2025): <!-- Greeting --> Hi @ccm326143547! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the dify team. <!-- Answer --> The duplicate MCP tool invocation and incomplete LLM response are caused by two main issues in the current implementation: 1. **No deduplication of tool calls:** The agent orchestration (specifically, the FunctionCallAgentRunner) does not filter out duplicate tool calls for the same sub-question. If the LLM outputs multiple identical tool calls, each is invoked, even if they are for the same intent. This happens because deduplication is not enforced in the tool invocation pipeline—neither in the agent runner nor in the ToolEngine or MCPTool layers. Deduplication should be handled upstream, ideally right after query decomposition or before invoking tools, to ensure each unique sub-question is only called once [(source)](https://github.com/langgenius/dify/blob/626d4f3e356fefede5937bd23551b9a2d0e5e5c0/api/core/agent/fc_agent_runner.py#L33-L378). 2. **Tool response aggregation overwrites previous results:** Tool responses are stored in a dictionary keyed by tool name. If the same tool is called multiple times, only the last response is kept, and earlier results are overwritten. This means the final LLM response only references the last tool call result, not all results [(source)](https://github.com/langgenius/dify/blob/626d4f3e356fefede5937bd23551b9a2d0e5e5c0/api/core/agent/base_agent_runner.py#L49-L495). **Recommendations:** - Implement deduplication of tool calls for identical sub-questions before invoking tools, either in the agent runner or immediately after query decomposition. - Change the tool response aggregation logic to store responses per call (e.g., by tool_call_id or as a list), so all results are preserved and available for the final LLM response, not just the last one. No recent pull requests address this logic, so these changes would need to be made in your deployment. This should ensure each unique sub-question is only invoked once and all tool responses are included in the LLM's final answer. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/428be4c2-56a1-4f80-907a-82335f764be7?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/428be4c2-56a1-4f80-907a-82335f764be7?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/428be4c2-56a1-4f80-907a-82335f764be7?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/428be4c2-56a1-4f80-907a-82335f764be7?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/428be4c2-56a1-4f80-907a-82335f764be7?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/428be4c2-56a1-4f80-907a-82335f764be7?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/428be4c2-56a1-4f80-907a-82335f764be7?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/6088a4f4-073a-43f3-b3d4-4f06fb0c05a0/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=The%20duplicate%20MCP%20tool%20invocation%20and%20incomplete%20LLM%20response%20are%20caused%20by%20two%20main%20issues%20in%20the%20current%20implementation%3A%0A%0A1.%20%2A%2ANo%20deduplication%20of%20tool%20calls%3A%2A%2A%20The%20agent%20orchestration%20%28specifically%2C%20the%20FunctionCallAgentRunner%29%20does%20not%20filter%20out%20duplicate%20tool%20calls%20for%20the%20same%20sub-question.%20If%20the%20LLM%20outputs%20multiple%20identical%20tool%20calls%2C%20each%20is%20invoked%2C%20even%20if%20they%20are%20for%20the%20same%20intent.%20This%20happens%20because%20deduplication%20is%20not%20enforced%20in%20the%20tool%20invocation%20pipeline%E2%80%94neither%20in%20the%20agent%20runner%20nor%20in%20the%20ToolEngine%20or%20MCPTool%20layers.%20Deduplication%20should%20be%20handled%20upstream%2C%20ideally%20right%20after%20query%20decomposition%20or%20before%20invoking%20tools%2C%20to%20ensure%20each%20unique%20sub-question%20is%20only%20called%20once%20%5B%28source%29%5D%28https%3A//github.com/langgenius/dify/blob/626d4f3e356fefede5937bd23551b9a2d0e5e5c0/api/core/agent/fc_agent_runner.py%23L33-L378%29.%0A%0A2.%20%2A%2ATool%20response%20aggregation%20overwrites%20previous%20results%3A%2A%2A%20Tool%20responses%20are%20stored%20in%20a%20dictionary%20keyed%20by%20tool%20name.%20If%20the%20same%20tool%20is%20called%20multiple%20times%2C%20only%20the%20last%20response%20is%20kept%2C%20and%20earlier%20results%20are%20overwritten.%20This%20means%20the%20final%20LLM%20response%20only%20references%20the%20last%20tool%20call%20result%2C%20not%20all%20results%20%5B%28source%29%5D%28https%3A//github.com/langgenius/dify/blob/626d4f3e356fefede5937bd23551b9a2d0e5e5c0/api/core/agent/base_agent_runner.py%23L49-L495%29.%0A%0A%2A%2ARecommendations%3A%2A%2A%0A-%20Implement%20deduplication%20of%20tool%20calls%20for%20identical%20sub-questions%20before%20invoking%20tools%2C%20either%20in%20the%20agent%20runner%20or%20immediately%20after%20query%20decomposition.%0A-%20Change%20the%20tool%20response%20aggregation%20logic%20to%20store%20responses%20per%20call%20%28e.g.%2C%20by%20tool_call_id%20or%20as%20a%20list%29%2C%20so%20all%20results%20are%20preserved%20and%20available%20for%20the%20final%20LLM%20response%2C%20not%20just%20the%20last%20one.%0A%0ANo%20recent%20pull%20requests%20address%20this%20logic%2C%20so%20these%20changes%20would%20need%20to%20be%20made%20in%20your%20deployment.%20This%20should%20ensure%20each%20unique%20sub-question%20is%20only%20invoked%20once%20and%20all%20tool%20responses%20are%20included%20in%20the%20LLM%27s%20final%20answer.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify/issues/28979)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#20710