# When I input a travel plan, it needs to call many tools and perform 25 steps. Does it really take that long? Is there a better solution?

**URL:** <https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384>\
**Category:** LangGraph\
**Tags:** python-help\
**Created:** [December 1, 2025, 1:41am UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384 "2025-12-01T01:41:28Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jinwater88](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jinwater88/32/1679_2.png) [@jinwater88](https://forum.langchain.com/u/jinwater88)\
**Post date:** [December 1, 2025, 1:41am UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384/1 "2025-12-01T01:41:28Z")

</div>

```auto
import asyncio  
import json  
from pathlib import Path  
from langchain_mcp_adapters.client import MultiServerMCPClient  
from langgraph.prebuilt import create_react_agent  
from langchain_openai import ChatOpenAI  
from dotenv import load_dotenv  
import os  
import time  
  
load_dotenv()

def load_mcp_config(config_path: str = "mcp_server_settings.json") -> dict:  
    """加载 MCP 服务器配置文件"""  
    config_file = Path(config_path)  
    if not config_file.exists():  
        raise FileNotFoundError(f"配置文件 {config_path} 不存在")  
      
    with open(config_file, 'r', encoding='utf-8') as f:  
        config = json.load(f)  
      
    return config.get("mcpServers", {})  

async def main():  
    try:  
        # 加载 MCP 配置  
        print("正在加载 MCP 配置...")  
        mcp_servers = load_mcp_config()  
        print(f"✓ 成功加载 {len(mcp_servers)} 个 MCP 服务器配置")  
          
        # 转换配置格式以适配 MultiServerMCPClient  
        client_config = {}  
        for server_name, server_config in mcp_servers.items():  
            server_type = server_config.pop("type")  
              
            if server_type == "streamable_http":  
                client_config[server_name] = {  
                    "url": server_config["url"],  
                    "transport": "streamable_http"  
                }  
            elif server_type == "stdio":  
                client_config[server_name] = {  
                    "command": server_config["command"],  
                    "args": server_config.get("args", []),  
                    "transport": "stdio"  
                }  
            elif server_type == "sse":  
                client_config[server_name] = {  
                    "url": server_config["url"],  
                    "transport": "sse"  
                }  
        
        # 获取 MCP 服务器提供的工具  
        print("正在连接 MCP 服务器...")  
        client = MultiServerMCPClient(client_config)  
        tools = await client.get_tools()  
        print(f"成功获取 {len(tools)} 个工具:")  
        for tool in tools:  
            print(f" - {tool.name}: {tool.description}")
        # 使用 DeepSeek 模型  
        # 使用 ChatOpenAI 模型
        print("\n正在初始化模型...")    
        model = ChatOpenAI(  
            model="deepseek-chat",  
            api_key=os.getenv("DEEPSEEK_API_KEY"),  
            base_url="https://api.deepseek.com",  
            temperature=0,  
            timeout=15,  
            request_timeout=15,
            max_retries=2 # 添加重试机制    
        ) 
        print("✓ 模型初始化成功")  
          
        print("\n正在创建 agent...")  
        model_with_tools = model.bind_tools(tools, parallel_tool_calls=True) 
        # 创建 ReAct agent  
        agent = create_react_agent(  
            model=model_with_tools,  
            tools=tools,
            debug=False # 启用调试模式    
        )  
        
        # 交互式循环  
        print("Agent 已启动。输入 'quit', 'exit' 或 'q' 退出。")  
        while True:  
            try:  
                user_input = input("\nUser: ")  
                if user_input.lower() in ["quit", "exit", "q"]:  
                    print("再见!")  
                    break  
                
                # 调用 agent  
                # 使用 astream 替代 ainvoke,可以看到中间步骤  
                print("\n[执行开始]")  
                start_time = time.time()  
                messages = []  
                step_count = 0  
                  
                try:  
                    async with asyncio.timeout(90.0):  
                        async for event in agent.astream(  
                            {"messages": [{"role": "user", "content": user_input}]},  
                            stream_mode="updates"  
                        ):  
                            step_count += 1  
                            # 只处理 agent 节点的更新  
                            if "agent" in event and "messages" in event["agent"]:  
                                messages = event["agent"]["messages"]  
                                last_msg = messages[-1]  
                                  
                                # 简化日志输出  
                                if hasattr(last_msg, 'tool_calls') and last_msg.tool_calls:  
                                    print(f"[步骤 {step_count}] 调用 {len(last_msg.tool_calls)} 个工具")           
                except asyncio.TimeoutError:  
                    print(f"\n[超时] 执行超过 90 秒,共完成 {step_count} 个步骤")  
                    continue  
                  
                if messages:  
                    elapsed = time.time() - start_time  
                    print(f"\n[完成] 总耗时: {elapsed:.1f}s")  
                    print(f"Assistant: {messages[-1].content}") 

            except KeyboardInterrupt:  
                print("\n再见!")  
                break  
            except Exception as e:  
                print(f"\n[错误] {e}")  
                import traceback  
                traceback.print_exc()    
              
    except Exception as e:  
        print(f"\n[初始化错误] {e}")  
        import traceback  
        traceback.print_exc()  
  
if __name__ == " __main__":  
    asyncio.run(main())

```

My code is shown above. I’m using Amap’s MCP (Multi-Channel Programming) to plan my trip, which requires 23 calls. However, when I use Cherry Studio to call Amap’s MCP, it responds instantly. Are there any optimization solutions for my code?

---

<div class="post-metadata">

**Author:** ![MchoneDev](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/mchonedev/32/806_2.png) [@MchoneDev](https://forum.langchain.com/u/MchoneDev)\
**Post date:** [December 2, 2025, 6:22pm UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384/2 "2025-12-02T18:22:01Z")

</div>

Hi @jinwater88 , could you elaborate on what these 25 steps are? It’s possible that the agent you have created with this code snippet is doing more digging. Have you setup instrumentation using langsmith or similar tooling?

Another thing to note is that you are using the deprecated `create_react_agent` langgraph prebuilt and you should consider moving to the new `create_agent` api from langchain 1.0.

[Deprecation notice](https://docs.langchain.com/oss/python/releases/langgraph-v1#deprecation-of-create-react-agent)

[Migration guide](https://docs.langchain.com/oss/python/migrate/langchain-v1#create-agent)

One thing I did notice about your code is that you don’t seem to be updating your system prompt, which could lead to this behavior.

---

<div class="post-metadata">

**Author:** ![jinwater88](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jinwater88/32/1679_2.png) [@jinwater88](https://forum.langchain.com/u/jinwater88)\
**Post date:** [December 3, 2025, 3:14am UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384/3 "2025-12-03T03:14:57Z")

</div>

Thank you for your reply. I am not using Langsmith for monitoring. You mean replacing `create_react_agent` with `create_agent`, which might improve things. I’ll try it when I get back. The lack of system updates means you need to write a message yourself, right? I haven’t written one yet.

---

<div class="post-metadata">

**Author:** ![MchoneDev](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/mchonedev/32/806_2.png) [@MchoneDev](https://forum.langchain.com/u/MchoneDev)\
**Post date:** [December 3, 2025, 4:47pm UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384/4 "2025-12-03T16:47:37Z")

</div>

Yes, I would suggest moving to `create_agent` but I don’t anticipate that immediately fixing your issue.

I would suggest setting up tracing (langsmith or other) to understand what decisions are being made so that you can add to your system prompt in a way that will prevent it from trying too many paths before responding.

---

<div class="post-metadata">

**Author:** ![jinwater88](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jinwater88/32/1679_2.png) [@jinwater88](https://forum.langchain.com/u/jinwater88)\
**Post date:** [December 8, 2025, 1:40am UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384/5 "2025-12-08T01:40:06Z")

</div>

When should we use `create_agent`, and when should we use custom nodes and edges? For example, in multi-agent scenarios, should we use `create_agent` or define custom nodes and edges? What is the maximum number of tools that `create_agent` can support for a single agent?

---

<div class="post-metadata">

**Author:** ![arthurdorigueto](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/arthurdorigueto/32/1924_2.png) [@arthurdorigueto](https://forum.langchain.com/u/arthurdorigueto)\
**Post date:** [December 12, 2025, 2:24am UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384/6 "2025-12-12T02:24:04Z")

</div>

In my experience, I prefer to always use `create_agent` as my “atomic” piece of work.

Meaning my graph is actually going to be either a single agent created using `create_agent`, or mutiple agents orchestrated via `Commands` and `tools` (`agent.invoke` inside a tool).

So in the end, I can do everything only using `create_agent` and Middleware.

About how many tools, I would say around 10, but it depends on the complexity and how much they fall inside the same “theme”.

---

<div class="post-metadata">

**Author:** ![jinwater88](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jinwater88/32/1679_2.png) [@jinwater88](https://forum.langchain.com/u/jinwater88)\
**Post date:** [December 12, 2025, 2:55am UTC](https://forum.langchain.com/t/when-i-input-a-travel-plan-it-needs-to-call-many-tools-and-perform-25-steps-does-it-really-take-that-long-is-there-a-better-solution/2384/7 "2025-12-12T02:55:20Z")

</div>

thanks you！LangChain’s MultiServerMCPClient re-establishes the connection with the child process every time it invokes a stdio connection. Is this correct? For example, if I write a server using Python’s FastMCP to establish a local connection, the connection to the MCP server is restarted every time it’s invoked. Why doesn’t this happen when using NPX?
