与AI共生20250326:想建构自己的MCP服务

I:

你好,我在本地离线部署了一些人工智能大模型,用我电脑上的显卡运行,使用ollama作为启动工具,可以通过API调用在自己写的应用程序中与这些大模型进行交互。现在我想在本地电脑上离线(也可以访问网络)构建自己 MCP服务,以自动化操纵指定的网站为例子:我的想法是,先向本地大模型提供要操纵的网页的内容(实时的html源内容),要求本地大模型提供一个可以执行的javascript或者python脚本文件代码,用于操纵这个网页指定的部分(比如抓取主要内容),如果执行这一步之后,网页内容又有了新的变化 ,又提供新的实时Html源代码给大模型,要求继续完成后续操作。我的设想的主要部分在于:让本地大模型写出调用Playwright库的js代码脚本或python代码脚本,我也不清楚,Playwright库是否用js可用的库以上是我的初步设想,没有经过验证,或者你有更好的想法?

Gemini2.0Flash:

你的想法很有意思,可行性较高,并且结合了本地大模型和 Playwright 的优势,可以在一定程度上实现自动化网页操作。下面我将分析你的设想,提出一些建议和补充,并探讨更好的方法:

对你设想的分析:

  • 优势:

    • 离线部署: 保护数据隐私,降低对网络依赖。

    • 大模型驱动: 利用大模型的理解和生成能力,自动生成脚本。

    • Playwright: 提供可靠的网页控制能力,支持多种浏览器。

    • 动态适应: 能够根据网页内容变化动态调整操作。

  • 可能遇到的问题:

    • 大模型能力: 大模型能否准确理解网页结构和需求,并生成正确的 Playwright 代码?这取决于模型的训练数据和提示词设计。

    • 错误处理: 大模型生成的代码可能存在错误,需要进行测试和调试,并设计相应的错误处理机制。

    • 网页复杂度: 对于复杂的网页,大模型可能难以生成完整的操作脚本,需要进行分解和逐步完成。

    • 安全性: 执行大模型生成的代码可能存在安全风险,需要进行代码审计和沙箱环境隔离。

    • Playwright 的学习曲线: 大模型可能需要经过一定的训练才能掌握 Playwright 的 API 和最佳实践。

    • 状态管理: 如何维护网页操作的状态,例如登录状态、Cookie 等,需要在设计中考虑。

建议和补充:

  1. 细化提示词: 提示词的设计至关重要,需要明确指示大模型生成 Playwright 代码,并提供足够的上下文信息,例如:

    • 明确指定编程语言(JavaScript 或 Python)。

    • 提供要操作的网页的 HTML 源代码。

    • 详细描述要完成的任务,例如“抓取商品名称和价格”,“点击“加入购物车”按钮”。

    • 提供示例代码片段,帮助大模型理解你的期望。

    • 指定代码风格和格式要求。

  2. 分步执行: 将复杂的任务分解成多个简单的步骤,逐步执行,并根据每一步的结果调整后续操作。

  3. 验证机制: 在执行大模型生成的代码之前,进行初步的验证,例如检查代码的语法是否正确,是否包含敏感操作。

  4. 错误处理: 在执行代码时,捕获异常,并提供错误信息给大模型,让其进行自我修复。

  5. 人工干预: 对于难以自动完成的任务,允许人工干预,并记录人工操作,用于训练大模型。

  6. 使用 Prompt Engineering 技巧:

    • Few-shot learning: 提供几个示例输入和对应的 Playwright 代码,让大模型学习。

    • Chain-of-thought prompting: 引导大模型一步一步地思考,并解释每一步的决策过程。

    • Self-consistency: 让大模型生成多个代码片段,然后选择最可靠的一个。

关于 Playwright 和 JavaScript:

  • Playwright 支持 JavaScript 和 Python。 你可以使用 JavaScript (Node.js) 或 Python 来编写 Playwright 脚本。

  • JavaScript 是前端的通用语言,Playwright 本身也是用 JavaScript 编写的,因此使用 JavaScript 更加自然。

  • Python 具有更强大的生态系统,例如数据分析、机器学习等,如果你需要对抓取的数据进行处理,Python 可能更适合。

  • Ollama 可以使用 Javascript 和 Python。

更好的想法:

  1. 结合视觉信息: 除了 HTML 源代码,还可以将网页的截图提供给大模型,帮助其更准确地理解网页的布局和内容。

  2. 使用选择器辅助工具: 开发一个辅助工具,让用户手动选择要操作的网页元素,然后将选择器信息提供给大模型,减少大模型理解网页结构的难度。

  3. 构建领域特定语言 (DSL): 定义一种简单的 DSL,用于描述网页操作,然后让大模型将 DSL 代码转换成 Playwright 代码。

  4. 使用更强大的大模型: 考虑使用专门针对代码生成的模型,例如 Codex (现在集成到 GitHub Copilot 中)。

  5. 反馈循环: 建立一个反馈循环,根据代码的执行结果,不断调整提示词和模型参数,提高代码生成的准确率。

  6. 使用记录回放工具 + 大模型重构: Playwright 本身就带有代码生成工具,可以录制用户的操作,然后生成 playwright 的代码。你可以先手动操作一遍,然后使用 Playwright 代码生成工具导出代码,然后将导出的代码给大模型,让大模型做优化和改造,并添加容错逻辑。

总结:

你的想法很有潜力,但是需要进行仔细的设计和测试,才能实现自动化网页操作。关键在于如何有效地利用大模型的能力,并结合 Playwright 的功能,最终构建一个可靠、灵活的 MCP 服务。

行动建议:

  1. 选择编程语言: 根据你的需求和熟悉程度,选择 JavaScript 或 Python。

  2. 设计提示词: 从简单的任务开始,逐步增加复杂度,不断优化提示词。

  3. 测试和调试: 编写测试用例,对大模型生成的代码进行充分的测试和调试。

  4. 收集数据: 记录失败的案例,分析原因,并用于改进模型。

  5. 迭代开发: 不断迭代,逐步完善 MCP 服务的功能和性能。

祝你成功!

I:

谢谢你,你的建议与鼓励对我很有帮助。我对上面你提到的构建领域特定语言 (DSL): 定义一种简单的 DSL,用于描述网页操作,然后让大模型将 DSL 代码转换成 Playwright 代码。这一部分不是很了解,没有听说过这方面的内容,你能简单介绍一下什么是DSL吗?

Gemini2.0Flash:

当然,很乐意为你详细介绍一下领域特定语言(DSL):

什么是领域特定语言 (DSL)?

领域特定语言(Domain-Specific Language,简称 DSL)是一种专门为解决特定领域问题而设计的编程语言或标记语言。与通用编程语言(如 Python、Java、C++)不同,DSL 专注于特定的领域,并提供针对该领域的概念、语法和操作。

DSL 的特点:

  • 目标明确: DSL 旨在解决特定领域的问题,而不是像通用语言那样适用于各种场景。

  • 语法简洁: DSL 的语法通常比通用语言更简洁、更易于理解,因为它只包含该领域所需的元素。

  • 表达力强: DSL 能够以更自然、更直观的方式表达领域内的概念和操作。

  • 易于学习: 由于语法简单,DSL 通常比通用语言更容易学习和使用。

  • 提高效率: 使用 DSL 可以减少代码量,提高开发效率,并降低出错的风险。

DSL 的类型:

  • 内部 DSL (Internal DSL): 内部 DSL 是基于现有通用语言实现的,利用该语言的语法和特性来定义领域特定的语法和操作。例如,使用 Ruby 的元编程能力来创建内部 DSL。

  • 外部 DSL (External DSL): 外部 DSL 是一种独立的语言,具有自己的语法和解析器。例如,SQL 是一种用于数据库查询的外部 DSL。

DSL 的用途:

DSL 可以用于各种领域,例如:

  • 网页开发: 用于描述网页布局、样式和交互行为,例如 HTML、CSS、JavaScript。

  • 数据查询: 用于查询和操作数据库,例如 SQL。

  • 构建自动化: 用于描述软件构建过程,例如 Maven、Gradle。

  • 规则引擎: 用于定义业务规则,例如 Drools。

  • 模型驱动开发: 用于描述软件模型,例如 UML。

在你的场景中,如何使用 DSL?

你可以设计一种 DSL,用于描述网页操作,例如:

// DSL 示例
操作 登录 {
  类型: 点击
  目标: 元素("id=login_button")
}

操作 输入用户名 {
  类型: 输入
  目标: 元素("id=username")
  内容: "your_username"
}

操作 输入密码 {
  类型: 输入
  目标: 元素("id=password")
  内容: "your_password"
}

操作 提交 {
  类型: 点击
  目标: 元素("id=submit_button")
}

操作 抓取商品信息 {
  类型: 抓取
  目标: 元素(".product-item")
  属性: ["名称", "价格"]
}
post image

这个 DSL 使用简单的键值对来描述网页操作,例如 操作、类型、目标、内容 等。你可以根据你的需求定义更多的操作类型和属性。

使用 DSL 的好处:

  • 简化大模型的工作: 大模型只需要将 DSL 代码转换成 Playwright 代码,而不需要理解复杂的网页结构和操作逻辑。

  • 提高代码的可读性和可维护性: DSL 代码比 Playwright 代码更易于理解和修改。

  • 降低出错的风险: DSL 的语法更简单,可以减少编写错误代码的可能性。

  • 更容易进行自动化测试: 可以使用 DSL 代码来描述测试用例,并自动执行测试。

如何实现 DSL?

  1. 定义 DSL 语法: 确定 DSL 的关键字、操作类型、属性等。

  2. 编写解析器: 使用工具(如 ANTLR、PLY)或手动编写解析器,将 DSL 代码转换成抽象语法树 (AST)。

  3. 编写代码生成器: 遍历 AST,生成 Playwright 代码。

与大模型结合:

  1. 提示词: 提供 DSL 语法和示例代码给大模型。

  2. 任务分解: 将任务分解成 DSL 代码生成和 Playwright 代码生成两个步骤。

  3. 训练数据: 收集 DSL 代码和对应的 Playwright 代码,用于训练大模型。

总结:

DSL 是一种强大的工具,可以帮助你简化网页自动化任务,并提高效率。虽然实现 DSL 需要一定的工作量,但它可以带来长期的收益。通过将 DSL 与大模型结合,你可以构建一个更加智能、灵活的 MCP 服务。

I:

谢谢你,你解释得非常仔细,我一下子就看懂了,原来我早就使用过DSL语言了,像SQL语言是早就用过的了。你的解释又给了我更多的想法与灵感,谢谢你。我现在开始去尝试实践。有新问题或新想法再来与你交流。

Gemini2.0Flash:

很高兴我的解释对你有所帮助! 实践是检验真理的唯一标准,期待你的实践成果。 非常欢迎你随时来交流新的问题和想法。 祝你一切顺利!

Play Video