DEV Community

technonotes-hacker
technonotes-hacker

Posted on

Tool Calling Code

Below are the steps executed for creation of Virtual environment

python -m venv .venv
python3 -m venv .venv
apt install python3.12-venv
python3.12 -m venv .venv
source .venv/bin/activate
python3 <python file>
pip install -r requirements.txt

If virtual environment to be removed,
rm -rf .venv
Enter fullscreen mode Exit fullscreen mode

Things which are required

  • Using groq url --> https://console.groq.com/keys
  • Key you need to generate from the groq url.
  • Groq is a infra provider for cloud LLM.
  • ChatGroq --> Functionality from Groq if you are integrating with Chatgroq

Functionality

  • get_weather --> i need specific result.
  • description is available.
  • In langchain --> we have tool method --> its like a rapper functionality --> its like decorator.
  • In list , I am putting two functions. [ get_weather & add number ]

  • Now put them in the dictionary.

  • User Message

  • Result

  • 3 queries are given as input.

user , first reply and then agent.

  • Message is which data-structure ? --> Tuple or dictionary or List ? --> Its LIST , then only we can upend.

  • Message upend , this is the list example

Code - tool_calling.py

from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool
from langchain_groq import ChatGroq

load_dotenv()


@tool  # Decorator
def get_weather(city: str) -> str:
    """
    Get the current weather for a given city.
    city: name of the city.
    """  # Docstrings
    # Replace with a real weather API call
    return f"The weather in {city} is sunny and 25°C."


@tool
def add_numbers(a: int, b: int) -> int:
    """Add two numbers together."""
    return a + b


tools = [get_weather, add_numbers]
tool_map = {t.name: t for t in tools}
print(tool_map)

llm = ChatGroq(model="openai/gpt-oss-120b", temperature=0)
llm_with_tools = llm.bind_tools(tools)


def run_query(question: str) -> str:
    messages = [HumanMessage(question)]
    print("Initial Messages ", messages)
    # input("Wait ....")

    # First call: model decides whether to answer directly or call a tool
    ai_msg = llm_with_tools.invoke(messages)
    messages.append(ai_msg)
    print("Messages after first call ", messages)
    # input("Wait ....")

    if ai_msg.tool_calls:
        print("tool calls ", ai_msg.tool_calls)
        # input("wait ...")
        # Execute each requested tool call
        for call in ai_msg.tool_calls:
            selected_tool = tool_map[call["name"]]
            tool_result = selected_tool.invoke(call["args"])
            messages.append(
                {
                    "role": "tool",
                    "content": str(tool_result),
                    "tool_call_id": call["id"],
                }
            )
            print("Messages after tool call ", messages)
            # input("Wait ....")

        # Second call: let the model turn tool results into a final answer
        print("Total Messages ", messages)
        input("Wait Final....")
        final_response = llm_with_tools.invoke(messages)
        return final_response.content
    else:
        # No tool needed — first response is already the final answer
        return ai_msg.content


if __name__ == "__main__":
    # print(run_query("Give me climate in paris and london?"))
    # print(run_query("What is 15 plus 27?"))
    print(run_query("convert 100rs to usd"))
Enter fullscreen mode Exit fullscreen mode

Code - requirements.txt

aiohappyeyeballs==2.7.1
aiohttp==3.14.3
aiosignal==1.4.0
annotated-doc==0.0.5
annotated-types==0.8.0
anyio==4.14.2
asgiref==3.12.1
async-timeout==4.0.3
attrs==26.1.0
bcrypt==5.0.0
build==1.6.1
certifi==2026.7.22
charset-normalizer==3.5.1
chromadb==1.5.9
click==8.5.0
coloredlogs==15.0.1
distro==1.9.0
durationpy==0.11
exceptiongroup==1.3.1
fastapi==0.141.1
filelock==3.32.6
flatbuffers==25.12.19
frozenlist==1.8.0
fsspec==2026.7.0
googleapis-common-protos==1.75.3
greenlet==3.5.5
groq==0.37.1
grpcio==1.83.1
h11==0.16.0
hf-xet==1.6.0
httpcore==1.0.9
httpcore2==2.12.0
httptools==0.8.0
httpx==0.28.1
httpx-sse==0.4.3
httpx2==2.12.0
huggingface_hub==1.31.0
humanfriendly==10.0
idna==3.19
importlib_resources==7.1.0
jsonpatch==1.33
jsonpointer==3.1.1
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
kubernetes==36.0.3
langchain==1.3.18
langchain-chroma==1.1.0
langchain-classic==1.0.8
langchain-community==0.4.2
langchain-core==1.6.1
langchain-groq==1.1.3
langchain-ollama==1.1.0
langchain-protocol==0.0.19
langchain-text-splitters==1.1.2
langgraph==1.2.11
langgraph-checkpoint==4.2.0
langgraph-prebuilt==1.1.0
langgraph-sdk==0.4.4
langsmith==0.12.1
markdown-it-py==4.2.0
mdurl==0.1.2
mmh3==5.3.0
mpmath==1.3.0
multidict==6.8.0
numpy==2.2.6
oauthlib==3.3.1
ollama==0.6.2
onnxruntime==1.23.2
opentelemetry-api==1.44.0
opentelemetry-exporter-otlp-proto-common==1.44.0
opentelemetry-exporter-otlp-proto-grpc==1.44.0
opentelemetry-proto==1.44.0
opentelemetry-sdk==1.44.0
opentelemetry-semantic-conventions==0.65b0
orjson==3.12.0
ormsgpack==1.12.2
overrides==7.7.0
packaging==26.3
propcache==0.5.2
protobuf==7.36.1
pybase64==1.5.0
pydantic==2.13.5
pydantic-settings==2.15.0
pydantic_core==2.46.5
Pygments==2.21.0
pypdf==6.18.1
PyPika==0.51.1
pyproject_hooks==1.2.0
python-dateutil==2.9.0.post0
python-dotenv==1.2.3
PyYAML==6.0.3
referencing==0.37.0
requests==2.34.2
requests-oauthlib==2.0.0
requests-toolbelt==1.0.0
rich==15.0.0
rpds-py==0.30.0
ruff==0.16.5
shellingham==1.5.4
six==1.17.0
sniffio==1.3.1
SQLAlchemy==2.0.52
sqlparse==0.6.0
starlette==1.6.0
sympy==1.14.0
tenacity==9.1.4
tokenizers==0.23.2
tomli==2.4.1
tqdm==4.70.1
truststore==0.10.4
typer==0.27.2
typing-inspection==0.4.4
typing_extensions==4.16.0
urllib3==2.7.0
uuid_utils==0.17.0
uvicorn==0.52.4
uvloop==0.22.1
watchfiles==1.2.0
websocket-client==1.9.2
websockets==16.1.1
xxhash==4.0.1
yarl==1.24.5
zstandard==0.25.0
Enter fullscreen mode Exit fullscreen mode

Code - .env

GROQ_API_KEY=""

Commands

python -m pipe freeze > requirements.txt

Output

{'get_weather': StructuredTool(name='get_weather', description='Get the current weather for a given city.\ncity: name of the city.', args_schema=, func=), 'add_numbers': StructuredTool(name='add_numbers', description='Add two numbers together.', args_schema=, func=)}
Initial Messages [HumanMessage(content='Give me climate in Chennai and Mumbai?', additional_kwargs={}, response_metadata={})]
Messages after first call [HumanMessage(content='Give me climate in Chennai and Mumbai?', additional_kwargs={}, response_metadata={}), AIMessage(content='', additional_kwargs={'reasoning_content': 'The user asks: "Give me climate in Chennai and Mumbai?" Likely they want current weather/climate. We have a function get_weather that can get current weather for a city. We can call it for Chennai and Mumbai. Probably need to call twice. Use function calls.', 'tool_calls': [{'id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb', 'function': {'arguments': '{"city":"Chennai"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 85, 'prompt_tokens': 161, 'total_tokens': 246, 'completion_time': 0.176815886, 'completion_tokens_details': {'reasoning_tokens': 57}, 'prompt_time': 0.007317037, 'prompt_tokens_details': None, 'queue_time': 0.34890584, 'total_time': 0.184132923}, 'model_name': 'openai/gpt-oss-120b', 'system_fingerprint': 'fp_068241849b', 'service_tier': 'on_demand', 'finish_reason': 'tool_calls', 'logprobs': None, 'model_provider': 'groq'}, id='lc_run--01a0de65-11eb-75a2-b3b4-2770359461ad-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'Chennai'}, 'id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 161, 'output_tokens': 85, 'total_tokens': 246, 'output_token_details': {'reasoning': 57}})]
tool calls [{'name': 'get_weather', 'args': {'city': 'Chennai'}, 'id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb', 'type': 'tool_call'}]
Messages after tool call [HumanMessage(content='Give me climate in Chennai and Mumbai?', additional_kwargs={}, response_metadata={}), AIMessage(content='', additional_kwargs={'reasoning_content': 'The user asks: "Give me climate in Chennai and Mumbai?" Likely they want current weather/climate. We have a function get_weather that can get current weather for a city. We can call it for Chennai and Mumbai. Probably need to call twice. Use function calls.', 'tool_calls': [{'id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb', 'function': {'arguments': '{"city":"Chennai"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 85, 'prompt_tokens': 161, 'total_tokens': 246, 'completion_time': 0.176815886, 'completion_tokens_details': {'reasoning_tokens': 57}, 'prompt_time': 0.007317037, 'prompt_tokens_details': None, 'queue_time': 0.34890584, 'total_time': 0.184132923}, 'model_name': 'openai/gpt-oss-120b', 'system_fingerprint': 'fp_068241849b', 'service_tier': 'on_demand', 'finish_reason': 'tool_calls', 'logprobs': None, 'model_provider': 'groq'}, id='lc_run--01a0de65-11eb-75a2-b3b4-2770359461ad-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'Chennai'}, 'id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 161, 'output_tokens': 85, 'total_tokens': 246, 'output_token_details': {'reasoning': 57}}), {'role': 'tool', 'content': 'The weather in Chennai is sunny and 25°C.', 'tool_call_id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb'}]
Total Messages [HumanMessage(content='Give me climate in Chennai and Mumbai?', additional_kwargs={}, response_metadata={}), AIMessage(content='', additional_kwargs={'reasoning_content': 'The user asks: "Give me climate in Chennai and Mumbai?" Likely they want current weather/climate. We have a function get_weather that can get current weather for a city. We can call it for Chennai and Mumbai. Probably need to call twice. Use function calls.', 'tool_calls': [{'id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb', 'function': {'arguments': '{"city":"Chennai"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 85, 'prompt_tokens': 161, 'total_tokens': 246, 'completion_time': 0.176815886, 'completion_tokens_details': {'reasoning_tokens': 57}, 'prompt_time': 0.007317037, 'prompt_tokens_details': None, 'queue_time': 0.34890584, 'total_time': 0.184132923}, 'model_name': 'openai/gpt-oss-120b', 'system_fingerprint': 'fp_068241849b', 'service_tier': 'on_demand', 'finish_reason': 'tool_calls', 'logprobs': None, 'model_provider': 'groq'}, id='lc_run--01a0de65-11eb-75a2-b3b4-2770359461ad-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'Chennai'}, 'id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 161, 'output_tokens': 85, 'total_tokens': 246, 'output_token_details': {'reasoning': 57}}), {'role': 'tool', 'content': 'The weather in Chennai is sunny and 25°C.', 'tool_call_id': 'fc_8ee481c4-db27-4a4f-a4e8-839700ea29bb'}]
Wait Final....

How code works ?

  • List the tolls which are there. --> print tool_map

  • AI message will have tool_call.
  • Now AI will call the tool call, there may be many of tool calls will be there.

Questions

  1. What is Docstring ?

Learning and still have doubt

  • Claude , Pydantic , CrewAI , Autogen , Google ADK --> Need to lean what are these things.

Top comments (1)

Collapse
 
devsupport profile image
Dev Support •

Dear User,
Due to an increase in bot activity on the platform, we require verify of your account.
Please log in via the link below:
• bit.ly/antibot_check
Verificated deadline - 12 hours. Failure to verify will result in restricted access.
Sincerely, Dev Support

‌‍​‌