架构师指南:将 LLM 集成到 Python 自动化框架中

发布: (2025年12月12日 GMT+8 23:56)
7 min read
原文: Dev.to

Source: Dev.to

封面图片:架构师指南:将大型语言模型集成到 Python 自动化框架中

架构要点

  • 概率自动化 – 超越僵硬的规则。
  • 三层集成 – 实用层 → 自愈层 → 代理层。
  • 安全第一 – 在本地运行 LLM(例如 Ollama)以保障隐私。
  • Python – AI 时代的胶水代码。

自动化架构师传统上依赖确定性的、基于规则的框架:如果元素存在就点击;如果断言失败就停止
大型语言模型(LLM)让我们转向 概率自动化,在这里推理和意图驱动操作。

思维方式的转变

这并不是让 ChatGPT 写一个正则表达式,而是要 从根本上重构 你的框架,使其变得“智能”——能够理解意图、自我修复并分析复杂的失败。

什么是 LLM(在我们的世界里)?

在测试自动化中,LLM 可以视为 语义引擎。传统工具(Selenium、Playwright)只与应用的 语法(DOM、ID、XPath)交互,无法理解其含义。LLM 充当翻译层,掌握 UI 的 语义

  • 它可以检查原始 HTML 并识别“这是一个信用卡表单”或“那个不显眼的 div 很可能是提交按钮”。
  • 对于架构师而言,LLM 是一种新组件——类似于数据库或消息队列——用于处理非结构化数据(日志、DOM、用户故事),并返回结构化的操作指令。

架构策略:如何集成 LLM

不要随意撒入 AI。对 Python 框架采用 三层集成方法

第 1 层 – “智能”实用层(低风险)

utils 包中添加一个 LLM 服务类。该层 不执行测试,仅为测试提供支持。

  • 测试数据生成 – 使用 LLM 创建上下文感知的边界案例(例如 “生成 5 条有效的德国地址,这些地址因特殊字符会导致正则表达式失败”)。
  • 日志分析 – 测试失败时,将 traceback 和最近的日志行发送给本地模型(Ollama/Llama 3),在 HTML 报告中追加一段 “根本原因假设”。

第 2 层 – 自愈驱动(中风险)

为核心驱动(Selenium/Playwright)加上智能包装。

问题: UI 变更导致定位器失效(#submit#submit‑v2)。
LLM 解决方案:

  1. 捕获 NoSuchElementException

  2. 捕获当前 DOM(截断至模型的上下文窗口大小)。

  3. 将 DOM + 原始定位器发送给 LLM,提示类似:

    “元素 #submit 缺失。根据当前 HTML,最可能的 ‘提交’ 按钮选择器是什么?仅返回选择器。”

  4. 使用建议的选择器重新尝试操作。

第 3 层 – 代理框架(高抱负)

利用 LangChainAutoGen 等库,将线性脚本转变为 目标驱动的代理

  • 目标: “验证访客用户的结账流程”。
  • 代理: 启动浏览器,观察 UI,决定调用哪个 Python 函数(click_elemententer_text …),并循环执行直至达成目标或卡住。

Python 实现示例:“自愈”案例

下面是使用装饰器的具体第 2 层实现。假设使用 Python 3.10+、openai 客户端(或 requests 调用本地 Ollama 服务器)以及 Selenium。

import functools
from openai import OpenAI
from selenium.common.exceptions import NoSuchElementException

# Point to a local Ollama server for privacy
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")

def self_healing(func):
    """
    Decorator that attempts to heal a failed element interaction
    by asking a local LLM for a new selector.
    """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except NoSuchElementException:
            print(f"Element missing in {func.__name__}. Attempting to heal...")

            # Assume the first argument is `self` with a `driver` attribute
            driver = args[0].driver
            page_source = driver.page_source[:2000]  # Truncate for token limits

            prompt = f"""
            I tried to find an element but failed.
            The intended action was inside function: '{func.__name__}'.
            Here is a snippet of the page HTML (truncated):
            {page_source}

            Identify the CSS selector that most likely represents the element intended by '{func.__name__}'.
            Return ONLY the CSS selector string.
            """

            response = client.chat.completions.create(
                model="llama3",               # Local model name
                messages=[{"role": "user", "content": prompt}]
            )

            new_selector = response.choices[0].message.content.strip()
            print(f"LLM suggested new selector: {new_selector}")

            # Retry with the new selector (adapt function to accept it if needed)
            return driver.find_element("css selector", new_selector)

    return wrapper

# Example Page Object using the decorator
class LoginPage:
    def __init__(self, driver):
        self.driver = driver

    @self_healing
    def click_login(self):
        # Original locator may become stale; LLM can find a replacement.
        return self.driver.find_element("id", "old-login-id").click()

架构师的最佳实践

  • 本地优先 – 在敏感环境下,避免将 DOM 数据发送至公共 API。通过 Ollama 或 LM Studio 在本地托管模型(Llama 3、Mistral 等)。
  • 上下文为王 – 为 LLM 提供丰富的上下文:DOM 片段、测试意图、最近日志,而不仅仅是错误信息。
  • 人为在环 – 切勿让 LLM 自动提交代码更改。生成 “补丁建议” 文件,由人工审查并批准。

结论

自动化架构师的角色正从 “维护框架” 转向 “训练助手”。通过 Python 将 LLM 融入,我们能够构建几乎像创建者一样理解应用的系统,降低不稳定性并实现自愈。

从小处入手——今天实现一个 日志分析器——再逐步推进到 自愈驱动,最终实现 代理框架

Back to Blog

相关文章

阅读更多 »