Force tool calling in langraph swarm

Sorry that wont be possible. I have signed a NDA and its a entire product and the company wont allow to share it

Ok, I understand. Then tell me the exact versions (langchain, langgraph) you are using - I’ll try to reproduce the code to some extent.

btw this code works for me:

import os
from typing import Optional

from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
from langgraph.prebuilt import create_react_agent
from langchain.chat_models import init_chat_model
from langgraph_swarm import create_swarm
from langchain_core.tools import tool

load_dotenv(verbose=True)

# -----------------------llm----------------------
llm = init_chat_model(
    "claude-3-7-sonnet-latest",
    model_provider="anthropic",
    api_key=os.getenv("ANTHROPIC_API_KEY", ""),
)

@tool()
def document_retriever(query: str, domain_name: str, user_folder: Optional[str] = None, website_name: Optional[str] = None) -> str:
    """
    Tool to retrieve relevant documents using hybrid search (vector + BM25) from web-scraped content.

    Args:
        query (str): The search query
        domain_name (str): Name of the domain/website for the vector store
        user_folder (str, Optional): Username to use in the path (optional)
        website_name (str, Optional): Name of the website folder (optional, defaults to "brandsmithworldwide")

    Returns:
        Retrieved content as formatted text
    """
    print(f"Retrieving `{query}` from `{domain_name}` (user: `{user_folder})`, website: `{website_name})`")
    return "His name is Paul."

def make_rag_prompt():
    return "You are an helpful assistant."

def get_all_agent_tools():
    return [document_retriever]

def create_rag_agent():
    """Create the RAG agent with all tools from ToolFactory"""
    # Get all tools for the agent
    all_tools = get_all_agent_tools()
    # llm_with_tools = llm.bind_tools(all_tools, strict=True)
    print('--' * 30)
    print(f"Creating RAG agent with {len(all_tools)} tools")
    for _tool in all_tools:
        tool_name = getattr(_tool, 'name', 'unnamed_tool')
        print(f"Tool: {tool_name}")
    print('--' * 30)
    # model_with_tools = self.model.bind_tools(tools=all_tools, tool_choice={"type": "tool", "name": "document_retriever"})
    return create_react_agent(
        model=llm.bind_tools(all_tools, tool_choice="auto"),
        tools=all_tools,
        prompt=make_rag_prompt(),
        name="rag_agent"
    )

builder = create_swarm(
            [create_rag_agent()],
            default_active_agent="rag_agent"
        )

graph = builder.compile()

answer = graph.invoke({"messages": [HumanMessage("Hi! What is the name of the main actor of \"No way!\" movie? Domain: movies. Folder: all. Website: NONE.")]})

print(answer["messages"][1])

Response:

------------------------------------------------------------
Creating RAG agent with 1 tools
Tool: document_retriever
------------------------------------------------------------
Retrieving `No way! movie main actor` from `movies` (user: `all)`, website: `None)`
content=[{'text': 'To find information about the main actor of the "No way!" movie, I can search for this in the movies domain. Let me do that for you.', 'type': 'text'}, {'id': 'toolu_01X4MuruiDVbcth48Jii2Nim', 'input': {'query': 'No way! movie main actor', 'domain_name': 'movies', 'user_folder': 'all'}, 'name': 'document_retriever', 'type': 'tool_use'}] additional_kwargs={} response_metadata={'id': 'msg_019SnJfmkSLWy9q3EPHbAU78', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'cache_creation': {'ephemeral_1h_input_tokens': 0, 'ephemeral_5m_input_tokens': 0}, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 601, 'output_tokens': 130, 'server_tool_use': None, 'service_tier': 'standard'}, 'model_name': 'claude-3-7-sonnet-20250219'} name='rag_agent' id='run--5a5c2b5d-20a2-4816-8f3d-b691c2432957-0' tool_calls=[{'name': 'document_retriever', 'args': {'query': 'No way! movie main actor', 'domain_name': 'movies', 'user_folder': 'all'}, 'id': 'toolu_01X4MuruiDVbcth48Jii2Nim', 'type': 'tool_call'}] usage_metadata={'input_tokens': 601, 'output_tokens': 130, 'total_tokens': 731, 'input_token_details': {'cache_read': 0, 'cache_creation': 0, 'ephemeral_5m_input_tokens': 0, 'ephemeral_1h_input_tokens': 0}}

When I remove Return from docstring it still works:

"""
Tool to retrieve relevant documents using hybrid search (vector + BM25) from web-scraped content.

Args:
    query (str): The search query
    domain_name (str): Name of the domain/website for the vector store
    user_folder (str, Optional): Username to use in the path (optional)
    website_name (str, Optional): Name of the website folder (optional, defaults to "brandsmithworldwide")
"""

Response:

------------------------------------------------------------
Creating RAG agent with 1 tools
Tool: document_retriever
------------------------------------------------------------
Retrieving `No way! movie main actor` from `movies` (user: `all)`, website: `None)`
content=[{'text': 'I\'ll help you find information about the main actor of the "No way!" movie. Let me search for that information using the document retriever tool.', 'type': 'text'}, {'id': 'toolu_01Bd5jGKwwFbSGsvFtzC1D5V', 'input': {'query': 'No way! movie main actor', 'domain_name': 'movies', 'user_folder': 'all'}, 'name': 'document_retriever', 'type': 'tool_use'}] additional_kwargs={} response_metadata={'id': 'msg_01GJaPJaUNYufnd99h6WrHwR', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'cache_creation': {'ephemeral_1h_input_tokens': 0, 'ephemeral_5m_input_tokens': 0}, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 586, 'output_tokens': 129, 'server_tool_use': None, 'service_tier': 'standard'}, 'model_name': 'claude-3-7-sonnet-20250219'} name='rag_agent' id='run--c77b9e43-2bf1-40fe-92a9-9459e838a36c-0' tool_calls=[{'name': 'document_retriever', 'args': {'query': 'No way! movie main actor', 'domain_name': 'movies', 'user_folder': 'all'}, 'id': 'toolu_01Bd5jGKwwFbSGsvFtzC1D5V', 'type': 'tool_call'}] usage_metadata={'input_tokens': 586, 'output_tokens': 129, 'total_tokens': 715, 'input_token_details': {'cache_read': 0, 'cache_creation': 0, 'ephemeral_5m_input_tokens': 0, 'ephemeral_1h_input_tokens': 0}}

Extactly! I know there is no issue with the code, yet i get the error.
I dont know how to fix it

Could it be magic? :slight_smile: There must be a reason somewhere :face_with_monocle:

@polo15s Could you share the versions to try to reproduce on those exact version?

Hey, I solved the issue
The issue was with the wrapper function in the class.

What was the issue?

@polo15s it would be great if you share the solution code so that it benefits others :slight_smile: