当前位置: 首页 > news >正文

LangGraph实战:整合MCP(本地模式

LangGraph实战:整合MCP(本地模式)

概述

本文介绍在langgraph 的Agent中,使用MCP Client连接和调用MCP server的工具(函数),实现Agent的各个步骤的功能。本文使用stdio模式,没有使用sse协议。

我这里使用本地ollama,基础模型使用llama3.2:latest。

先安装Ollama服务,并下载对应的大模型。创建一个.env文件,并配置参数:

LLM_TEMPERATURE=0.2
OLLAMA_MODEL='llama3.2:latest'
OLLAMA_BASE_URL='http://127.0.0.1:11434'
PY_PROJECT_DIR='/root/do_langmcp/'
SSE_BASE_URL='http://172.16.1.3:8000/sse'

开发MCP Server

开发一个MCP Server,定义2个函数,用来计算简单interest和复合interest。这里我们使用FastMCP来开发MCP服务。其代码文件mcp-interest-server1.py如下:

from mcp.server.fastmcp import FastMCP
import logginglogging.basicConfig(format='%(levelname)s %(asctime)s - %(message)s', level=logging.INFO)
logger = logging.getLogger('interest_mcp_server')mcp = FastMCP('InterestCalculator')# 定义计算简单interest的工具函数
@mcp.tool()
def yearly_simple_interest(principal: float, rate:float) -> float:"""Tool to compute simple interest rate for a year."""logger.info(f'Simple interest -> Principal: {principal}, Rate: {rate}')return principal * rate / 100.00# 定义计算复合interest的工具函数
@mcp.tool()
def yearly_compound_interest(principal: float, rate:float) -> float:"""Tool to compute compound interest rate for a year."""logger.info(f'Compound interest -> Principal: {principal}, Rate: {rate}')return principal * (1 + rate / 100.0)# 定义运行工具的入口
if __name__ == '__main__':logger.info(f'Starting the interest MCP server...')mcp.run(transport='stdio')

使用langgraph开发agent来使用MCP Server

打开一个文件,使用langgraph创建一个最简单的agent,代码文件命名为mcp-client-inerest1.py,内容如下:

from dotenv import load_dotenv, find_dotenv
from langchain_ollama import ChatOllama
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_clientimport asyncio
import logging
import oslogging.basicConfig(format='%(levelname)s %(asctime)s - %(message)s', level=logging.INFO)logger = logging.getLogger('interest_mcp_client')load_dotenv(find_dotenv())home_dir = os.getenv('HOME')
llm_temperature = float(os.getenv('LLM_TEMPERATURE'))
ollama_model = os.getenv('OLLAMA_MODEL')
ollama_base_url = os.getenv('OLLAMA_BASE_URL')
py_project_dir = os.getenv('PY_PROJECT_DIR')server_params = StdioServerParameters(command='python',# Full absolute path to mcp server#args=[home_dir + py_project_dir + 'interest_mcp_server.py'],args=[py_project_dir + 'interest_mcp_server.py'],
)ollama_chat_llm = ChatOllama(base_url=ollama_base_url, model=ollama_model, temperature=llm_temperature)async def main():# 调用 MCP server,使用stdio/stdout,本地模式async with stdio_client(server_params) as (read, write):# 创建MCP client sessionasync with ClientSession(read, write) as session:# 链接到MCP serverawait session.initialize()# 获取工具列表tools = await load_mcp_tools(session)logger.info(f'Loaded MCP Tools -> {tools}')# 创建一个ReACT agentagent = create_react_agent(ollama_chat_llm, tools)# Case - 1 : 定义简单interestagent_response_1 = await agent.ainvoke({'messages': 'explain the definition of simple interest ?'})logger.info(agent_response_1['messages'][::-1])# Case - 2 : 计算简单interestagent_response_2 = await agent.ainvoke({'messages': 'compute the simple interest for a principal of 1000 at rate 3.75 ?'})logger.info(agent_response_2['messages'][::-1])# Case - 3 : 计算复合interestagent_response_3 = await agent.ainvoke({'messages': 'compute the compound interest for a principal of 1000 at rate 4.25 ?'})logger.info(agent_response_3['messages'][::-1])if __name__ == '__main__':asyncio.run(main())

运行代码

在运行之前要安装好对应的依赖包。然后执行以下命令:

python mcp-interest-server1.py

再运行client端

python mcp-interest-client1.py

此时,Langgraph定义的Agent将会根据问答来调用对应的工具完成功能。

输出如下:

(langx) root@tra:~/do_langmcp# python interest_mcp_client.py 
INFO 2025-07-27 21:29:34,733 - Starting the interest MCP server...
INFO 2025-07-27 21:29:34,748 - Processing request of type ListToolsRequest
INFO 2025-07-27 21:29:34,752 - Loaded MCP Tools -> [StructuredTool(name='yearly_simple_interest', description='Tool to compute simple interest rate for a year.', args_schema={'properties': {'principal': {'title': 'Principal', 'type': 'number'}, 'rate': {'title': 'Rate', 'type': 'number'}}, 'required': ['principal', 'rate'], 'title': 'yearly_simple_interestArguments', 'type': 'object'}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x7f1e5bebd080>), StructuredTool(name='yearly_compound_interest', description='Tool to compute compound interest rate for a year.', args_schema={'properties': {'principal': {'title': 'Principal', 'type': 'number'}, 'rate': {'title': 'Rate', 'type': 'number'}}, 'required': ['principal', 'rate'], 'title': 'yearly_compound_interestArguments', 'type': 'object'}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x7f1e5bebd1c0>)]INFO 2025-07-27 21:29:42,622 - HTTP Request: POST http://127.0.0.1:11434/api/chat "HTTP/1.1 200 OK"
INFO 2025-07-27 21:29:42,722 - Processing request of type CallToolRequest
INFO 2025-07-27 21:29:42,722 - Simple interest -> Principal: 1000.0, Rate: 5.0
INFO 2025-07-27 21:30:05,234 - HTTP Request: POST http://127.0.0.1:11434/api/chat "HTTP/1.1 200 OK"
INFO 2025-07-27 21:30:05,237 - [AIMessage(content='Simple interest is a type of interest calculated on the initial principal amount (also known as the principal) that is borrowed or invested. It is a fixed rate of interest that is applied to the principal amount over a specific period of time, usually expressed in years.\n\nThe formula for calculating simple interest is:\n\nSimple Interest = Principal x Rate x Time\n\nWhere:\n\n* Principal is the initial amount borrowed or invested\n* Rate is the annual interest rate (in decimal form)\n* Time is the number of years the money is borrowed or invested for\n\nFor example, if you deposit $1,000 into a savings account with an annual interest rate of 5%, and it earns simple interest over one year, your total balance at the end of the year would be:\n\n$1,000 (initial principal) + $50 (simple interest) = $1,050\n\nSimple interest is often used in loans, credit cards, and other types of borrowing, where the lender charges a fixed rate of interest on the borrowed amount.', additional_kwargs={}, response_metadata={'model': 'llama3.2:latest', 'created_at': '2025-07-27T13:30:05.231338426Z', 'done': True, 'done_reason': 'stop', 'total_duration': 22502140979, 'load_duration': 23142327, 'prompt_eval_count': 100, 'prompt_eval_duration': 610240428, 'eval_count': 205, 'eval_duration': 21867524100, 'message': Message(role='assistant', content='Simple interest is a type of interest calculated on the initial principal amount (also known as the principal) that is borrowed or invested. It is a fixed rate of interest that is applied to the principal amount over a specific period of time, usually expressed in years.\n\nThe formula for calculating simple interest is:\n\nSimple Interest = Principal x Rate x Time\n\nWhere:\n\n* Principal is the initial amount borrowed or invested\n* Rate is the annual interest rate (in decimal form)\n* Time is the number of years the money is borrowed or invested for\n\nFor example, if you deposit $1,000 into a savings account with an annual interest rate of 5%, and it earns simple interest over one year, your total balance at the end of the year would be:\n\n$1,000 (initial principal) + $50 (simple interest) = $1,050\n\nSimple interest is often used in loans, credit cards, and other types of borrowing, where the lender charges a fixed rate of interest on the borrowed amount.', images=None, tool_calls=None)}, id='run-dbb336db-62dd-4f0e-94c9-c98661b4881b-0', usage_metadata={'input_tokens': 100, 'output_tokens': 205, 'total_tokens': 305}), ToolMessage(content='50.0', name='yearly_simple_interest', id='2e4f8534-e465-40f6-9dc6-48ce9c4dcc4b', tool_call_id='3dad76eb-6f6a-4f91-81be-85816e191f3c'), AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'llama3.2:latest', 'created_at': '2025-07-27T13:29:42.717316979Z', 'done': True, 'done_reason': 'stop', 'total_duration': 7937280022, 'load_duration': 2685876507, 'prompt_eval_count': 236, 'prompt_eval_duration': 2687458417, 'eval_count': 26, 'eval_duration': 2562201643, 'message': Message(role='assistant', content='', images=None, tool_calls=None)}, id='run-d7b0b0f7-e96f-4979-97d8-4b41a7e51506-0', tool_calls=[{'name': 'yearly_simple_interest', 'args': {'principal': 1000, 'rate': 5}, 'id': '3dad76eb-6f6a-4f91-81be-85816e191f3c', 'type': 'tool_call'}], usage_metadata={'input_tokens': 236, 'output_tokens': 26, 'total_tokens': 262}), HumanMessage(content='explain the definition of simple interest ?', additional_kwargs={}, response_metadata={}, id='2d8300ee-3e5c-4be4-9f80-955bd70fd306')]
INFO 2025-07-27 21:30:10,352 - HTTP Request: POST http://127.0.0.1:11434/api/chat "HTTP/1.1 200 OK"
INFO 2025-07-27 21:30:10,451 - Processing request of type CallToolRequest
INFO 2025-07-27 21:30:10,451 - Simple interest -> Principal: 1000.0, Rate: 3.75
INFO 2025-07-27 21:30:14,101 - HTTP Request: POST http://127.0.0.1:11434/api/chat "HTTP/1.1 200 OK"
INFO 2025-07-27 21:30:14,104 - [AIMessage(content='The simple interest for a principal of $1000 at a rate of 3.75% per year is $37.50.', additional_kwargs={}, response_metadata={'model': 'llama3.2:latest', 'created_at': '2025-07-27T13:30:14.10082019Z', 'done': True, 'done_reason': 'stop', 'total_duration': 3643709262, 'load_duration': 38767002, 'prompt_eval_count': 113, 'prompt_eval_duration': 776158602, 'eval_count': 28, 'eval_duration': 2825826280, 'message': Message(role='assistant', content='The simple interest for a principal of $1000 at a rate of 3.75% per year is $37.50.', images=None, tool_calls=None)}, id='run-afa79785-5860-4fb2-9a1f-3c081512afd2-0', usage_metadata={'input_tokens': 113, 'output_tokens': 28, 'total_tokens': 141}), ToolMessage(content='37.5', name='yearly_simple_interest', id='af34b371-8376-4ca1-818c-8131ad571a8f', tool_call_id='adf2ef3f-b006-49e3-8cbc-afe02235b64a'), AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'llama3.2:latest', 'created_at': '2025-07-27T13:30:10.447072592Z', 'done': True, 'done_reason': 'stop', 'total_duration': 5206010519, 'load_duration': 22561315, 'prompt_eval_count': 247, 'prompt_eval_duration': 2285719932, 'eval_count': 28, 'eval_duration': 2896718013, 'message': Message(role='assistant', content='', images=None, tool_calls=None)}, id='run-2725f604-9b91-44b1-b67c-08ff62f97d28-0', tool_calls=[{'name': 'yearly_simple_interest', 'args': {'principal': 1000, 'rate': 3.75}, 'id': 'adf2ef3f-b006-49e3-8cbc-afe02235b64a', 'type': 'tool_call'}], usage_metadata={'input_tokens': 247, 'output_tokens': 28, 'total_tokens': 275}), HumanMessage(content='compute the simple interest for a principal of 1000 at rate 3.75 ?', additional_kwargs={}, response_metadata={}, id='d3b0c616-1b43-405e-87ed-facd7f52dd4b')]
INFO 2025-07-27 21:30:19,140 - HTTP Request: POST http://127.0.0.1:11434/api/chat "HTTP/1.1 200 OK"
INFO 2025-07-27 21:30:19,241 - Processing request of type CallToolRequest
INFO 2025-07-27 21:30:19,241 - Compound interest -> Principal: 1000.0, Rate: 4.0
INFO 2025-07-27 21:30:24,475 - HTTP Request: POST http://127.0.0.1:11434/api/chat "HTTP/1.1 200 OK"
INFO 2025-07-27 21:30:24,477 - [AIMessage(content='The compound interest for a principal of $1000 at an annual interest rate of 4.25% is approximately $40.00.', additional_kwargs={}, response_metadata={'model': 'llama3.2:latest', 'created_at': '2025-07-27T13:30:24.474433132Z', 'done': True, 'done_reason': 'stop', 'total_duration': 5227214693, 'load_duration': 29359248, 'prompt_eval_count': 113, 'prompt_eval_duration': 756218295, 'eval_count': 29, 'eval_duration': 4438660227, 'message': Message(role='assistant', content='The compound interest for a principal of $1000 at an annual interest rate of 4.25% is approximately $40.00.', images=None, tool_calls=None)}, id='run-4c8b4d63-09be-4895-9661-584846ae4040-0', usage_metadata={'input_tokens': 113, 'output_tokens': 29, 'total_tokens': 142}), ToolMessage(content='1040.0', name='yearly_compound_interest', id='c4632978-29f2-46c8-ab50-9cc88ebb5160', tool_call_id='b3f050c4-945e-4973-b4d6-d6f0487080f9'), AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'llama3.2:latest', 'created_at': '2025-07-27T13:30:19.237296128Z', 'done': True, 'done_reason': 'stop', 'total_duration': 5130142439, 'load_duration': 32479260, 'prompt_eval_count': 247, 'prompt_eval_duration': 2262897687, 'eval_count': 27, 'eval_duration': 2833620362, 'message': Message(role='assistant', content='', images=None, tool_calls=None)}, id='run-36abb871-91b7-45ad-bd79-f19d58ecba08-0', tool_calls=[{'name': 'yearly_compound_interest', 'args': {'principal': 1000, 'rate': 4}, 'id': 'b3f050c4-945e-4973-b4d6-d6f0487080f9', 'type': 'tool_call'}], usage_metadata={'input_tokens': 247, 'output_tokens': 27, 'total_tokens': 274}), HumanMessage(content='compute the compound interest for a principal of 1000 at rate 4.25 ?', additional_kwargs={}, response_metadata={}, id='72f5955d-b372-435f-86ee-1f0203486569')]

参考资料

  • https://langchain-ai.github.io/langgraph/concepts/mcp/
  • https://modelcontextprotocol.io/overview
http://www.dtcms.com/a/302349.html

相关文章:

  • 机器学习sklearn:不纯度与决策树构建
  • 数据中心入门学习(四):服务器概述与PCIe总线
  • 【学习笔记】AD7708/18(1)-理解官网的参考代码
  • python每日一题
  • 如何在 Apache Ignite 中创建和使用自定义 SQL 函数(Custom SQL Functions)
  • 生物信息学数据技能-学习系列001
  • 牛客网之华为机试题:坐标移动
  • 利用径向条形图探索华盛顿的徒步旅行
  • 数据分析干货| 衡石科技可视化创作之仪表盘控件如何设置
  • 开源智能体-JoyAgent集成ollama私有化模型
  • 【docker】DM8达梦数据库的docker-compose以及一些启动踩坑
  • 攻防世界-引导-Web_php_unserialize
  • Kafka单机如何多Broker实例集群搭建?
  • Python----大模型(基于Fastapi+gradio的对话机器人)
  • 降低焊接机器人保护气体消耗的措施
  • 递归算法的一些具体应用
  • 开发避坑短篇(6):Vue+window.print()打印实践
  • vue如何在data里使用this
  • android-屏幕-刷新流程
  • .NET AI从0开始入门 SemanticKernel 从基础到实践
  • 【GIS数据分享】建筑矢量数据带高度
  • 数据链路层 和 ARP协议
  • 最大连续子数组
  • Makefile if语句用法
  • 【传奇开心果系列】Flet纵向瀑布流本地图片布局排列自定义模板
  • 【硬件】LVGL
  • 15-C语言:第15天笔记
  • keepalived原理及实战部署
  • 【数据库】时序数据库选型指南:从大数据视角看IoTDB的核心优势
  • 张 LLama 多语言语义相似度计算全解析:不同语言 同义词的相似度计算