In [1]:
from dotenv import load_dotenv
load_dotenv()
Out[1]:
True
In [3]:
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,
)
In [4]:
class CustomState(AgentState):
favourite_colour: str
Write to state¶
In [5]:
@tool
def update_favourite_colour(favourite_colour: str, runtime: ToolRuntime) -> Command:
"""Update the favourite colour of the user in the state once they've revealed it."""
return Command(update={
"favourite_colour": favourite_colour,
"messages": [ToolMessage("Successfully updated favourite colour", tool_call_id=runtime.tool_call_id)]
}
)
In [6]:
agent = create_agent(
deepseek_model(),
tools=[update_favourite_colour],
checkpointer=InMemorySaver(),
state_schema=CustomState
)
In [7]:
response = agent.invoke(
{ "messages": [HumanMessage(content="My favourite colour is green")]},
{"configurable": {"thread_id": "1"}}
)
In [9]:
print(response['messages'][-1].content)
Great! Your favourite colour has been saved as **green**. 🟢 It's a lovely colour — often associated with nature, growth, and tranquility!
In [10]:
response = agent.invoke(
{
"messages": [HumanMessage(content="Hello, how are you?")],
"favourite_colour": "green"
},
{"configurable": {"thread_id": "10"}
}
)
pprint(response)
{'favourite_colour': 'green',
'messages': [HumanMessage(content='Hello, how are you?', additional_kwargs={}, response_metadata={}, id='5e0e4745-eb8c-4f13-bad2-93925fbbdc7f'),
AIMessage(content="Hello! I'm doing well, thank you. How are you today? Is there anything I can help you with?", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 24, 'prompt_tokens': 296, 'total_tokens': 320, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 40}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': 'b52a71fe-8ba5-410c-83a4-8d4ca2caed79', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019e2483-5081-7d70-b2d1-d808febc25a4-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 296, 'output_tokens': 24, 'total_tokens': 320, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}})]}
In [11]:
print(response['messages'][-1].content)
Hello! I'm doing well, thank you. How are you today? Is there anything I can help you with?
Read state¶
In [12]:
@tool
def read_favourite_colour(runtime: ToolRuntime) -> str:
"""Read the favourite colour of the user from the state."""
try:
return runtime.state["favourite_colour"]
except KeyError:
return "No favourite colour found in state"
agent = create_agent(
deepseek_model(),
tools=[update_favourite_colour, read_favourite_colour],
checkpointer=InMemorySaver(),
state_schema=CustomState
)
In [13]:
response = agent.invoke(
{ "messages": [HumanMessage(content="My favourite colour is green")]},
{"configurable": {"thread_id": "1"}}
)
pprint(response)
{'favourite_colour': 'green',
'messages': [HumanMessage(content='My favourite colour is green', additional_kwargs={}, response_metadata={}, id='d54f6d04-3f67-4fe8-9d37-9cd43058abfc'),
AIMessage(content='Let me update your favourite colour!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 56, 'prompt_tokens': 334, 'total_tokens': 390, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 78}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': '6681a11b-f464-4138-a0c4-2b62ecc53eea', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019e2483-7eb8-7d30-9c8e-dbc5f7d77a3f-0', tool_calls=[{'name': 'update_favourite_colour', 'args': {'favourite_colour': 'green'}, 'id': 'call_00_4n2Yj29cWtC1VljCMluV7293', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 334, 'output_tokens': 56, 'total_tokens': 390, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}}),
ToolMessage(content='Successfully updated favourite colour', name='update_favourite_colour', id='8a68c7a9-ad19-4176-8ee9-22169965d663', tool_call_id='call_00_4n2Yj29cWtC1VljCMluV7293'),
AIMessage(content="Great! I've saved green as your favourite colour. 🟢", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 406, 'total_tokens': 420, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 150}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': '85324a2e-4b50-4482-a0fb-b0c7401027cf', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019e2483-8365-7ae0-bd5a-c8bbd2792fc3-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 406, 'output_tokens': 14, 'total_tokens': 420, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}})]}
In [14]:
print(response['messages'][-1].content)
Great! I've saved green as your favourite colour. 🟢
In [15]:
response = agent.invoke(
{ "messages": [HumanMessage(content="What's my favourite colour?")]},
{"configurable": {"thread_id": "1"}}
)
pprint(response)
{'favourite_colour': 'green',
'messages': [HumanMessage(content='My favourite colour is green', additional_kwargs={}, response_metadata={}, id='d54f6d04-3f67-4fe8-9d37-9cd43058abfc'),
AIMessage(content='Let me update your favourite colour!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 56, 'prompt_tokens': 334, 'total_tokens': 390, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 78}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': '6681a11b-f464-4138-a0c4-2b62ecc53eea', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019e2483-7eb8-7d30-9c8e-dbc5f7d77a3f-0', tool_calls=[{'name': 'update_favourite_colour', 'args': {'favourite_colour': 'green'}, 'id': 'call_00_4n2Yj29cWtC1VljCMluV7293', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 334, 'output_tokens': 56, 'total_tokens': 390, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}}),
ToolMessage(content='Successfully updated favourite colour', name='update_favourite_colour', id='8a68c7a9-ad19-4176-8ee9-22169965d663', tool_call_id='call_00_4n2Yj29cWtC1VljCMluV7293'),
AIMessage(content="Great! I've saved green as your favourite colour. 🟢", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 406, 'total_tokens': 420, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 150}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': '85324a2e-4b50-4482-a0fb-b0c7401027cf', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019e2483-8365-7ae0-bd5a-c8bbd2792fc3-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 406, 'output_tokens': 14, 'total_tokens': 420, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}}),
HumanMessage(content="What's my favourite colour?", additional_kwargs={}, response_metadata={}, id='4f493ab2-fd1e-478e-8c54-4fac45e19892'),
AIMessage(content='Let me check for you!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 35, 'prompt_tokens': 430, 'total_tokens': 465, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 384}, 'prompt_cache_hit_tokens': 384, 'prompt_cache_miss_tokens': 46}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': '281d7363-c1a3-4c5e-874d-7eb4b0f649c4', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019e2483-90db-76d2-881b-0d6577467263-0', tool_calls=[{'name': 'read_favourite_colour', 'args': {}, 'id': 'call_00_qVwExbWmk3Bne0ZCvmig7801', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 430, 'output_tokens': 35, 'total_tokens': 465, 'input_token_details': {'cache_read': 384}, 'output_token_details': {}}),
ToolMessage(content='green', name='read_favourite_colour', id='0008d1df-1356-4486-bb83-d55efb193c58', tool_call_id='call_00_qVwExbWmk3Bne0ZCvmig7801'),
AIMessage(content='Your favourite colour is **green**! 🟢', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 478, 'total_tokens': 489, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 384}, 'prompt_cache_hit_tokens': 384, 'prompt_cache_miss_tokens': 94}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': 'eba6efdc-fc48-4da0-8f48-bf76d9929a14', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019e2483-9496-7c01-ad12-19435f3d85fb-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 478, 'output_tokens': 11, 'total_tokens': 489, 'input_token_details': {'cache_read': 384}, 'output_token_details': {}})]}
In [16]:
print(response['messages'][-1].content)
Your favourite colour is **green**! 🟢
In [ ]: