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

【原创】使用langchain与MCP 与 Chrome DevTools 打造可调用浏览器工具的 Chat Agent

本文介绍如何搭建基于Chrome开发者工具多客户端协议(MCP)的智能对话代理。通过整合chrome-devtools-mcp和LangChain框架,实现了自动注册MCP工具、支持Ollama/OpenAI双模型后端、异步非阻塞运行的Chat Agent。文章详细说明了环境配置方法,包括Chrome调试模式启动命令和Node.js环境准备,并提供了可直接运行的Python完整代码。该代理支持网页操作指令如打开网页、截图和网络请求分析等功能,通过LangGraph构建状态图实现对话流程管理。代码展示了模型绑定、工具自动发现和异步交互的实现方式,为开发者提供了开箱即用的MCP集成方案。


效果


简介 ✨

本文示例展示了一个稳定的 MCP Chat Agent:

  • 自动注册并绑定 MCP 工具(无需手动查找工具)
  • 支持Ollama / OpenAI两种模型
  • 异步运行,不会阻塞主线程

下面是使用前的准备和代码说明。


环境与准备 🔧

  1. 启动 Chrome(带远程调试端口):
    macOS
/Applications/Google\Chrome.app/Contents/MacOS/Google\Chrome --remote-debugging-port=9222--user-data-dir=/tmp/chrome-profile-stable

Linux

/usr/bin/google-chrome --remote-debugging-port=9222--user-data-dir=/tmp/chrome-profile-stable

Windows

"C:\Program Files\Google\Chrome\Application\chrome.exe"--remote-debugging-port=9222--user-data-dir="%TEMP%\chrome-profile-stable"

要安装node环境

npx -y chrome-devtools-mcp@latest --browser-url=http://127.0.0.1:9222

请确保 Chrome 已用--remote-debugging-port=9222启动,且npx -y chrome-devtools-mcp@latest能单独运行。

  1. Python 环境需要安装对应依赖(示例中使用的包有langchain_ollama,langchain_openai,langchain_mcp_adapters,langgraph等)。

完整代码(可直接保存并运行)

下面是new_chat_agent.py的完整代码:

#!/usr/bin/env python3""" 最终稳定版 MCP Chat Agent - 自动注册 MCP 工具(无需手动找) - 支持 Ollama / OpenAI 二选一 - 不会阻塞 / 不会 silent """importasynciofromtypingimportAnnotated,TypedDictfromlangchain_ollamaimportChatOllamafromlangchain_openaiimportChatOpenAIfromlangchain_mcp_adapters.clientimportMultiServerMCPClientfromlanggraph.graphimportStateGraph,STARTfromlanggraph.prebuiltimportToolNode,tools_conditionfromlanggraph.checkpoint.memoryimportMemorySaverfromlanggraph.graph.messageimportadd_messages# ================== 配置 ==================OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"OPENAI_API_BASE="https://dashscope.aliyuncs.com/compatible-mode/v1"classState(TypedDict):messages:Annotated[list,add_messages]classMCPAgent:def__init__(self,backend:str="ollama"):print("🚀 初始化 MCPAgent",flush=True)# -------- 模型选择 --------ifbackend=="ollama":self.llm=ChatOllama(model="qwen2.5:7b",temperature=0.7,)print("🔹 使用 Ollama",flush=True)else:self.llm=ChatOpenAI(model="qwen3-30b-a3b-instruct-2507",temperature=0.7,api_key=OPENAI_API_KEY,base_url=OPENAI_API_BASE,)print("🔹 使用 OpenAI API",flush=True)# -------- MCP 工具(关键)--------print("🔄 连接 chrome-devtools-mcp(不会阻塞)",flush=True)client=MultiServerMCPClient({"chrome":{"transport":"stdio","command":"npx","args":["-y","chrome-devtools-mcp@latest","--browser-url=http://127.0.0.1:9222",],}})# ⚠️ get_tools 是唯一需要等的地方self.tools=asyncio.run(client.get_tools())ifnotself.tools:raiseRuntimeError("❌ MCP 工具为空,请确认 Chrome 是否启动")print(f"✅ 已自动注册{len(self.tools)}个 MCP 工具",flush=True)# ⭐ 核心:直接 bind_tools,不要自己管工具self.llm=self.llm.bind_tools(self.tools)# -------- LangGraph --------self.graph=self._build_graph()self.history=[]def_agent(self,state:State):return{"messages":[self.llm.invoke(state["messages"])]}def_build_graph(self):g=StateGraph(State)g.add_node("agent",self._agent)g.add_node("tools",ToolNode(self.tools))g.add_edge(START,"agent")g.add_conditional_edges("agent",tools_condition)g.add_edge("tools","agent")returng.compile(checkpointer=MemorySaver())asyncdefrun(self):print("\n🤖 MCP Chat Agent 已启动",flush=True)print("示例:",flush=True)print(" 打开 https://www.baidu.com",flush=True)print(" 截图当前页面",flush=True)print(" 列出 network 里的 JSON 请求\n",flush=True)whileTrue:user=input("你: ").strip()ifuserin("exit","quit"):breakself.history.append(("user",user))asyncforeventinself.graph.astream_events({"messages":self.history},config={"configurable":{"thread_id":"default"}},version="v2",):ifevent["event"]=="on_chat_model_stream":chunk=event["data"]["chunk"]ifchunk.content:print(chunk.content,end="",flush=True)elifevent["event"]=="on_tool_start":print(f"\n🛠️ 调用工具:{event['name']}",flush=True)elifevent["event"]=="on_tool_end":print("\n✅ 工具执行完成",flush=True)print()# ================== 启动 ==================if__name__=="__main__":try:choice=input("选择模型(1=Ollama,2=OpenAI):").strip()backend="ollama"ifchoice!="2"else"openai"agent=MCPAgent(backend=backend)asyncio.run(agent.run())exceptExceptionase:print(f"\n❌ 启动失败:{e}",flush=True)print("\n排查顺序:",flush=True)print("1. Chrome 是否用 --remote-debugging-port=9222 启动",flush=True)print("2. npx -y chrome-devtools-mcp@latest 是否能单独运行",flush=True)print("3. node / npm 是否正常",flush=True)

关键点解析 💡

  • 自动注册 MCP 工具:通过MultiServerMCPClient(...).get_tools()自动发现并注册 chrome-devtools-mcp 提供的工具集合。
  • 绑定工具到 LLM:使用self.llm.bind_tools(self.tools),让 LLM 可以直接以工具调用的方式操控浏览器。
  • LangGraph 驱动:使用StateGraphToolNode管理对话和工具调用的流程,并以MemorySaver做检查点。
  • 运行模式:交互式命令行会持续接收用户输入,并以事件流打印模型输出与工具调用状态。

使用示例 🧪

  1. 启动 Chrome(见上文命令)。
  2. 运行脚本:
python new_chat_agent.py

  1. 根据提示选择模型(1=Ollama,2=OpenAI),然后在命令行输入如:
打开 https://www.baidu.com 截图当前页面 列出 network 里的 JSON 请求

Agent 会根据工具能力返回结果并在终端打印执行过程。

参考:
https://github.com/ChromeDevTools/chrome-devtools-mcp


如果本文对你有帮助,欢迎点赞 + 关注,你的关注是我持续更新的最大动力 🙏

http://www.jsqmd.com/news/245412/

相关文章:

  • 22.C++进阶:⼆叉搜索树|手撕二叉搜索树
  • 搞定JAX高效并行训练
  • Spring家族生态深度剖析:从厨房新手到餐饮帝国的演进史
  • 写了5年C++才发现:new背后藏着两个函数,placement new让我能控制其中一个
  • 8继承多态
  • Spring Boot的约定优于配置:智能管家的“隐形”艺术
  • 大家一直催更的Agent学习路线来喽!
  • Oracle 19c入门学习教程,从入门到精通,Oracle体系结构 —— 知识点详解(2)
  • 守护能源与数据的安全防线:从UL 2075标准解析储能及数据中心氢探技术的演进
  • C++类型判断
  • Python 内置 venv 虚拟环境工具完全指南(附 uv 工具无缝升级教程)
  • 2026机器视觉同轴光源品牌甄选指南:解锁高精度检测的照明密钥
  • 如何使用`typeid`判断指针或引用所指对象的实际类型?
  • C++ RAII封装结构体成员变量自动加锁性能开销分析
  • 凤希AI提出FXPA2P:下一代点对点AI服务架构-2026年1月14日
  • 智能指针的生命周期控制
  • AI原生应用开发:相似度匹配的模型压缩技巧
  • 6款AI论文降重神器实操教程:AI率从72%降至13%
  • Python + uiautomator2 手机自动化控制教程
  • Python 学生管理系统实战:从基础功能到数据持久化(附完整源码)
  • 【Python库和代码案例:第一课】Python 标准库与第三方库实战指南:从日期处理到 Excel 操作
  • 数独优化求解C库tdoku-lib的使用
  • AI原生应用云端推理的故障排查与恢复
  • dlx求解数独duckdb插件的编写和使用
  • 我用 XinServer 做了个文件系统,比想象简单
  • 大数据领域数据产品的安全保障策略
  • 避坑指南:通义千问2.5-7B-Instruct本地部署常见问题解决
  • 【RuoYi-SpringBoot3-Pro】:使用 Dify + AI 快速生成多数据库建表语句
  • AnimeGANv2版本回滚机制:模型更新失败应急部署教程
  • 【RuoYi-SpringBoot3-Pro】:多租户功能上手指南