In [1]:
from dotenv import load_dotenv
load_dotenv()
Out[1]:
True
In [2]:
import os, asyncio, json
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent, AgentState
from langchain.messages import HumanMessage, AIMessage, ToolMessage
from langchain.tools import tool, ToolRuntime
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import Command
from typing import Dict, Any
from tavily import TavilyClient
from pprint import pprint
from dataclasses import dataclass
DEEPSEEK_MODEL = "deepseek-chat"
DEEPSEEK_BASE_URL = "https://api.deepseek.com"
def deepseek_model(model: str = DEEPSEEK_MODEL, max_tokens=1000, **kwargs):
return init_chat_model(
model=model,
# DeepSeek uses LangChain's OpenAI-compatible transport.
model_provider="openai",
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url=DEEPSEEK_BASE_URL,
max_tokens=max_tokens,
**kwargs,
)
Creating subagents¶
In [3]:
@tool
def square_root(x: float) -> float:
"""Calculate the square root of a number"""
return x ** 0.5
@tool
def square(x: float) -> float:
"""Calculate the square of a number"""
return x ** 2
In [4]:
subagent_1 = create_agent(
model=deepseek_model(),
tools=[square_root]
)
subagent_2 = create_agent(
model=deepseek_model(),
tools=[square]
)
Calling subagents¶
In [5]:
@tool
def call_subagent_1(x: float) -> float:
"""Call subagent 1 in order to calculate the square root of a number"""
response = subagent_1.invoke({"messages": [HumanMessage(content=f"Calculate the square root of {x}")]})
return response["messages"][-1].content
@tool
def call_subagent_2(x: float) -> float:
"""Call subagent 2 in order to calculate the square of a number"""
response = subagent_2.invoke({"messages": [HumanMessage(content=f"Calculate the square of {x}")]})
return response["messages"][-1].content
## Creating the main agent
main_agent = create_agent(
model=deepseek_model(),
tools=[call_subagent_1, call_subagent_2],
system_prompt="You are a helpful assistant who can call subagents to calculate the square root or square of a number.")
Test¶
In [6]:
question = "What is the square root of 456?"
response = main_agent.invoke({"messages": [HumanMessage(content=question)]})
In [7]:
print(response['messages'][-1].content)
The square root of 456 is approximately **21.3542**.
In [8]:
pprint(response)
{'messages': [HumanMessage(content='What is the square root of 456?', additional_kwargs={}, response_metadata={}, id='2a19683d-9fbd-43a0-8eca-7bd42857ec22'),
AIMessage(content='Let me calculate the square root of 456 using the subagent.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 60, 'prompt_tokens': 372, 'total_tokens': 432, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}, 'prompt_cache_hit_tokens': 0, 'prompt_cache_miss_tokens': 372}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': 'bd42d300-797e-4c9f-a521-e4a2d0c5cfab', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019e24b6-3271-75c1-8a56-2cd76de58436-0', tool_calls=[{'name': 'call_subagent_1', 'args': {'x': 456}, 'id': 'call_00_pThkt1UWM2pjTwwNgApj6415', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 372, 'output_tokens': 60, 'total_tokens': 432, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}}),
ToolMessage(content='The square root of 456.0 is approximately **21.3542**.', name='call_subagent_1', id='644939fb-81cf-4513-8b87-158d7090c85c', tool_call_id='call_00_pThkt1UWM2pjTwwNgApj6415'),
AIMessage(content='The square root of 456 is approximately **21.3542**.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 458, 'total_tokens': 472, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 202}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': 'b8d1c2eb-9dfa-4d90-8a97-93f42c138b21', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019e24b6-4084-75a0-8017-a6fbd9faf380-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 458, 'output_tokens': 14, 'total_tokens': 472, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}})]}
In [9]:
pprint(response['messages'][1])
AIMessage(content='Let me calculate the square root of 456 using the subagent.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 60, 'prompt_tokens': 372, 'total_tokens': 432, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}, 'prompt_cache_hit_tokens': 0, 'prompt_cache_miss_tokens': 372}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': 'bd42d300-797e-4c9f-a521-e4a2d0c5cfab', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019e24b6-3271-75c1-8a56-2cd76de58436-0', tool_calls=[{'name': 'call_subagent_1', 'args': {'x': 456}, 'id': 'call_00_pThkt1UWM2pjTwwNgApj6415', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 372, 'output_tokens': 60, 'total_tokens': 432, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}})
In [11]:
pprint(response['messages'][0].model_dump(), sort_dicts=False)
{'content': 'What is the square root of 456?',
'additional_kwargs': {},
'response_metadata': {},
'type': 'human',
'name': None,
'id': '2a19683d-9fbd-43a0-8eca-7bd42857ec22'}
In [10]:
pprint(response['messages'][1].model_dump(), sort_dicts=False)
{'content': 'Let me calculate the square root of 456 using the subagent.',
'additional_kwargs': {'refusal': None},
'response_metadata': {'token_usage': {'completion_tokens': 60,
'prompt_tokens': 372,
'total_tokens': 432,
'completion_tokens_details': None,
'prompt_tokens_details': {'audio_tokens': None,
'cached_tokens': 0},
'prompt_cache_hit_tokens': 0,
'prompt_cache_miss_tokens': 372},
'model_provider': 'openai',
'model_name': 'deepseek-v4-flash',
'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402',
'id': 'bd42d300-797e-4c9f-a521-e4a2d0c5cfab',
'finish_reason': 'tool_calls',
'logprobs': None},
'type': 'ai',
'name': None,
'id': 'lc_run--019e24b6-3271-75c1-8a56-2cd76de58436-0',
'tool_calls': [{'name': 'call_subagent_1',
'args': {'x': 456},
'id': 'call_00_pThkt1UWM2pjTwwNgApj6415',
'type': 'tool_call'}],
'invalid_tool_calls': [],
'usage_metadata': {'input_tokens': 372,
'output_tokens': 60,
'total_tokens': 432,
'input_token_details': {'cache_read': 0},
'output_token_details': {}}}
In [12]:
pprint(response['messages'][2].model_dump(), sort_dicts=False)
{'content': 'The square root of 456.0 is approximately **21.3542**.',
'additional_kwargs': {},
'response_metadata': {},
'type': 'tool',
'name': 'call_subagent_1',
'id': '644939fb-81cf-4513-8b87-158d7090c85c',
'tool_call_id': 'call_00_pThkt1UWM2pjTwwNgApj6415',
'artifact': None,
'status': 'success'}
In [13]:
pprint(response['messages'][3].model_dump(), sort_dicts=False)
{'content': 'The square root of 456 is approximately **21.3542**.',
'additional_kwargs': {'refusal': None},
'response_metadata': {'token_usage': {'completion_tokens': 14,
'prompt_tokens': 458,
'total_tokens': 472,
'completion_tokens_details': None,
'prompt_tokens_details': {'audio_tokens': None,
'cached_tokens': 256},
'prompt_cache_hit_tokens': 256,
'prompt_cache_miss_tokens': 202},
'model_provider': 'openai',
'model_name': 'deepseek-v4-flash',
'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402',
'id': 'b8d1c2eb-9dfa-4d90-8a97-93f42c138b21',
'finish_reason': 'stop',
'logprobs': None},
'type': 'ai',
'name': None,
'id': 'lc_run--019e24b6-4084-75a0-8017-a6fbd9faf380-0',
'tool_calls': [],
'invalid_tool_calls': [],
'usage_metadata': {'input_tokens': 458,
'output_tokens': 14,
'total_tokens': 472,
'input_token_details': {'cache_read': 256},
'output_token_details': {}}}
In [ ]: