云原生架构解决了内部系统的弹性伸缩与服务治理,但企业数字化转型的最后一公里,往往卡在一个更底层的问题上:那些没有开放API的老系统、桌面端软件、第三方SaaS平台,如何被纳入统一的自动化编排体系?
过去两年,大模型的爆发让"AI写代码"成为现实。但在生产环境跑过7×24小时业务流的工程师都清楚一个事实:AI生成的脚本在demo阶段表现亮眼,一旦面对真实世界的复杂UI、异常弹窗、元素变更,稳定性会断崖式下跌。更关键的是,大模型推理需要持续消耗token,高频业务场景下的边际成本会迅速超过人力成本。
AI负责认知与决策,自动化引擎负责稳定执行。 这不是技术选型的折中,而是架构层面的职责分离。这篇文章,想从云原生架构师的视角,拆解如何设计并落地真正的跨系统非侵入式业务编排。
一、云原生架构下的自动化困境:API不是万能药
企业上云原生的核心思路,是通过容器编排和微服务治理,把内部系统拆成可独立部署、可弹性伸缩的单元。K8s能管好Pod,Service Mesh能管好调用链,但云原生再强大,也管不了别人的系统。
现实场景往往长这样:
核心ERP是十年前采购的,厂商早已停止更新,API文档缺失;
财务系统采用本地化CS架构,数据库不对外暴露;
电商运营需要同时操作后台系统、企业微信、千牛、Excel,数据散落在五六个界面;
某些敏感业务,数据根本不能出内网,连公网API调用都是合规红线。
传统的解决方案是ESB总线或API网关,但这意味着侵入式改造——要么对方系统配合开放接口,要么自己写厚重的适配层。业务等不起,对方也不愿意配合。
RPA(Robotic Process Automation)技术本质上是通过模拟人类操作界面来完成任务,不需要改造任何底层系统。 在云原生视角下,RPA应该被看作一种"自动化微服务",通过API触发的方式嵌入到更大的编排体系中,而不是一个孤立的桌面工具。
对于中小企业和开发团队而言,这种非侵入式方案意味着零改造成本接入自动化能力。更现实的一点是数据不出本地的刚性需求:金融、医疗、政务、制造业中,大量业务流程涉及敏感数据。RPA的执行逻辑天然可以做到全离线内网部署,流程应用数据全部保存在用户本地设备上,不同步到外部服务端。这种架构下,审计链路简单,所有的操作日志、录屏、执行记录都在本地闭环,符合等保和数据合规要求。
二、AI+RPA 的架构重组:认知层与执行层的分离
很多人把AI+RPA理解为"给RPA接个大模型接口",这太浅了。真正的架构级融合,应该是认知层与执行层的明确分离:
这种分工下,AI生成逻辑,RPA稳定执行就成了很自然的工作流。业务人员用自然语言描述需求,AI生成初步的自动化脚本;RPA引擎负责把脚本转化为稳定的界面操作,并在生产环境里长期运行。
以笔者实际参与的财务对账项目为例:
AI认知层:理解银行流水和报销单的匹配规则,生成对账逻辑伪代码;
RPA执行层:登录网银、下载Excel、打开OA、填写审批单。
整个流程跑下来,AI生成的元素定位不稳定问题被RPA的执行层消化掉了——执行层基于视觉+属性多重定位,可长期运行,不会因为页面微调就崩溃。这与纯AI方案形成鲜明对比:前端一个样式调整就可能导致AI生成的定位逻辑失效。
三、非侵入式编排的技术实现:当RPA学会"看"屏幕
传统的RPA依赖DOM树或控件ID来定位元素,这在现代Web应用里越来越吃力。React、Vue等前端框架一个版本更新,XPath可能就全变了。云原生架构强调弹性与容错,RPA的执行层也必须跟上这个思路。
目前比较成熟的方案是视觉自动化 + 智能元素定位的结合:
3.1 视觉颜色操作
不再死磕元素节点,而是通过计算机视觉直接识别屏幕上的颜色、文字、图标位置。基于OpenCV或PaddleOCR的视觉识别方案,无需依赖元素节点,也能实现点击、获取内容等操作。
这种方式可以轻松实现企业微信、微信、QQ、千牛各种消息的获取——这些IM软件的界面经常变,但文字和图标的视觉特征相对稳定。
import cv2
import numpy as np
import pyautogui
from mss import mss
def capture_screen():
"""截取全屏并转为OpenCV格式(BGR)"""
with mss() as sct:
monitor = sct.monitors[1] # 主显示器
screenshot = np.array(sct.grab(monitor))
# mss返回的是BGRA,需要转为BGR
return cv2.cvtColor(screenshot, cv2.COLOR_BGRA2BGR)
def find_and_click(template_path, threshold=0.8):
screenshot = capture_screen()
template = cv2.imread(template_path)
if template is None:
raise FileNotFoundError(f"模板图片不存在: {template_path}")
result = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv2.minMaxLoc(result)
if max_val >= threshold:
h, w = template.shape[:2]
center_x = max_loc[0] + w // 2
center_y = max_loc[1] + h // 2
pyautogui.click(center_x, center_y)
return True
return False
使用示例
success = find_and_click("templates/wechat_msg_icon.png", threshold=0.85)
3.2 本地智能生成元素路径
通过AI智能优化元素路径,用户无需学习晦涩难懂的XPath语法。基于自然语言描述生成对应的元素路径,本质上是将NLP意图映射到DOM树遍历策略。
比如你说"点击登录按钮旁边的蓝色确认键",系统通过以下步骤解析:
用OCR识别屏幕文字,定位"登录按钮";
在按钮邻域内搜索颜色为蓝色的可点击元素;
生成稳定的复合定位策略(文字+颜色+相对位置)。
复合定位策略配置示例(类似Selenium的Page Object模式)
elements:
login_button:
text: "登录"
color: "#1890ff"
relative: "parent > button.confirm"
fallback: "visual:login_btn.png" # 视觉兜底
3.3 指纹浏览器对接
在电商、社媒运营场景里,经常需要在多个账号间切换。通过对接紫鸟浏览器、AdsPower等指纹浏览器,实现自动化操作的同时规避平台风控。核心原理是控制浏览器的CDP(Chrome DevTools Protocol)接口,而非直接操作鼠标键盘。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def connect_to_fingerprint_browser(debugger_port=9222):
"""
连接已启动的指纹浏览器实例
注意:需先在指纹浏览器中开启"允许自动化"或"开发者模式"
"""
options = Options()
options.add_experimental_option(
"debuggerAddress", f"127.0.0.1:{debugger_port}"
)
# 禁用自动化检测特征
options.add_experimental_option(
"excludeSwitches", ["enable-automation"]
)
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)
# 抹除 webdriver 标记
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
return driver
使用示例
driver = connect_to_fingerprint_browser(debugger_port=9222)
driver.get("https://example.com")
这些技术的共同点是不侵入被操作系统的底层代码,纯粹在应用层模拟人类行为。这正是跨系统非侵入式业务编排的精髓。
四、元素自愈:让自动化流程从"脆弱"走向"抗造"
做RPA最头疼的不是开发,是维护。页面一个按钮改了class名,流程就崩了;前端发了个热更新,上周还能跑的脚本这周就报错。
元素自愈(Element Self-Healing)是解决这个问题的关键。当web元素失效时,系统基于以下策略自动修复定位:
属性降级匹配:先尝试id → name → class → tag → text的降级匹配;
视觉语义重识别:基于截图与模板库的相似度匹配,重新定位目标;
上下文推断:根据相邻稳定元素推断目标元素的新位置。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
import json
import os
class SelfHealingLocator:
def init(self, driver, selector_cache_path="selector_cache.json"):
self.driver = driver
self.cache_path = selector_cache_path
self.selector_cache = self._load_cache()
self.by_map = {
"id": By.ID,
"name": By.NAME,
"class": By.CLASS_NAME,
"tag": By.TAG_NAME,
"xpath": By.XPATH,
"css": By.CSS_SELECTOR,
"link_text": By.LINK_TEXT,
"partial_link_text": By.PARTIAL_LINK_TEXT
}
def _load_cache(self):
if os.path.exists(self.cache_path):
with open(self.cache_path, 'r', encoding='utf-8') as f:
return json.load(f)
return {}
def _save_cache(self):
with open(self.cache_path, 'w', encoding='utf-8') as f:
json.dump(self.selector_cache, f, ensure_ascii=False, indent=2)
def try_strategy(self, strategy):
"""尝试单一策略定位"""
try:
by = strategy.get("by", "xpath")
value = strategy["value"]
locator = self.by_map.get(by, By.XPATH)
return self.driver.find_element(locator, value)
except NoSuchElementException:
return None
def update_primary_selector(self, element_name, new_strategy):
"""更新主选择器缓存"""
self.selector_cache[element_name] = new_strategy
self._save_cache()
def find_element(self, element_name, primary_selector, backup_strategies):
"""
元素自愈定位入口
Args:
element_name: 元素标识名(用于缓存)
primary_selector: 主选择器策略,如 {"by": "xpath", "value": "//button[@id='login']"}
backup_strategies: 备用策略列表
Returns:
WebElement: 定位到的元素
Raises:
NoSuchElementException: 所有策略均失败时抛出
"""
# 先尝试缓存的最新成功策略
strategies = []
cached = self.selector_cache.get(element_name)
if cached:
strategies.append(cached)
strategies.append(primary_selector)
strategies.extend(backup_strategies)
# 去重去空
seen = set()
unique_strategies = []
for s in strategies:
if s and str(s) not in seen:
seen.add(str(s))
unique_strategies.append(s)
for strategy in unique_strategies:
element = self.try_strategy(strategy)
if element:
# 如果这次用的是备用策略,更新缓存
if strategy != primary_selector and strategy != cached:
self.update_primary_selector(element_name, strategy)
return element
raise NoSuchElementException(
f"元素 [{element_name}] 所有自愈策略均失败。"
f"已尝试策略数: {len(unique_strategies)}"
)
使用示例
driver = webdriver.Chrome()
locator = SelfHealingLocator(driver)
elem = locator.find_element(
element_name="login_btn",
primary_selector={"by": "xpath", "value": "//button[@id='login']"},
backup_strategies=[
{"by": "class", "value": "btn-login"},
{"by": "link_text", "value": "登录"},
{"by": "css", "value": "button[type='submit']"}
]
)
笔者在生产环境实测过:一个电商后台的商品上架流程,平均每周会有2到3次界面微调。开启自愈机制后,流程连续跑了三个月没出过元素定位问题。离线自愈更稳定——因为所有修复逻辑在本地执行,不依赖外部API,响应延迟控制在毫秒级。
五、安全与部署:数据主权时代的内网闭环
云原生架构里,安全从来不是可选项。对于金融、医疗、政务、制造业来说,数据不出本地是硬约束。
很多AI方案在这方面有天然短板——大模型推理要么需要连公网,要么需要把数据送到云端。而RPA的执行逻辑天然支持全离线内网部署:
流程应用数据全部保存在用户本地设备上,不同步到服务端;
敏感数据从头到尾不离开本地网络;
审计链路简单,所有操作日志、录屏、执行记录都在本地闭环。
这种架构对于中小企业和开发团队特别友好——不需要申请云资源,不需要过复杂的网络安全审批,一台内网机器就能跑完整套自动化。
部署架构示例:
┌─────────────────────────────────────────┐
│ 内网环境(隔离区) │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ 调度中心 │───→│ RPA执行节点集群 │ │
│ │ (K8s) │ │ (本地VM/物理机) │ │
│ └──────────┘ └──────────────────┘ │
│ │ │ │
│ └──────┬───────┘ │
│ ↓ │
│ ┌──────────┐ │
│ │ 本地数据库 │ ← 审计日志、录屏 │
│ │ (SQLite) │ │
│ └──────────┘ │
└─────────────────────────────────────────┘
六、工程化交付:从脚本到可分发的产品
云原生强调"一次构建,到处运行"。RPA的自动化流程也应该从"个人脚本"进化为"可交付的工程产物"。
6.1 开发态:AI辅助生成
业务人员用自然语言描述需求,AI生成初步脚本后,通过AST转换一键转为正式流程。这解决了"最后一公里"的开发效率问题。
AI生成伪代码 → 结构化流程描述
natural_language = "登录网银,下载最近一个月的流水Excel"
假设 ai_to_flow 是调用本地LLM API的封装
structured_flow = [
{"action": "open", "target": "chrome", "url": "https://bank.com"},
{"action": "input", "target": "#username", "value": "{
{user}}"},
{"action": "input", "target": "#password", "value": "{
{pwd}}"},
{"action": "click", "target": "#login"},
{"action": "navigate", "target": "/download"},
{"action": "download", "target": "最近30天流水", "format": "xlsx"}
]
6.2 分发与治理
RPA流程需要解决三个工程问题:封装、授权、更新。
封装层面:将流程打包为独立可执行文件(如基于PyInstaller封装),业务同事拿到文件就能直接运行,无需安装Python环境或RPA客户端。
授权层面:通过代码混淆+授权文件校验,防止源码泄露。授权文件可采用JWT格式,包含有效期、设备指纹、权限范围:
{
"iss": "rpa-platform",
"sub": "finance-dept",
"exp": 1735689600,
"device_hash": "a1b2c3d4e5f6...",
"permissions": ["run", "view_logs"],
"signature": "..."
}
调度层面:封装后的应用支持API触发、定时执行(基于APScheduler),方便嵌入到更大的调度系统里。同时支持自定义Web界面,让非技术人员也能傻瓜式使用。
更新层面:基于差分更新的机制,应用启动时检测版本号,自动下载增量补丁。这类似于云原生里的滚动更新机制,避免了"发一个版本就要重新部署一次"的痛点。
七、Agent化协同:IM场景下的智能调度
云原生架构里,服务之间的通信是通过标准协议完成的。而在业务层,人与系统的交互 increasingly 发生在IM工具里。
通过构建RPA Agent,将执行能力延伸到聊天窗口:
在钉钉、飞书、企微、个人微信内通过@机器人发送指令;
Agent解析意图,调度本地RPA引擎执行;
完成后把结果和截图回调到群里。
架构时序:
用户@机器人:"跑一下今天的对账流程"
↓
IM Webhook → 意图识别服务(本地LLM/规则引擎)
↓
生成任务ID,写入本地消息队列(Redis/RabbitMQ)
↓
RPA执行节点消费任务 → 执行流程 → 截图+结果
↓
回调IM机器人API,推送结果到群聊
这种"对话即调度"的模式,把RPA从定时任务升级成了按需响应的智能服务。更关键的是,它解决了纯AI方案的一个盲区:在流程执行过程中,按需调用AI做动态判断,再基于判断结果执行具体操作,两者各司其职。
八、AI与RPA的边界:互补而非替代
最后想聊聊一个常见的误区:AI这么强了,RPA是不是迟早被淘汰?
不会。至少在可预见的未来,两者是深度互补的关系。以下几个差异,是笔者在生产环境里反复验证过的:
AI负责思考与生成,RPA负责稳定落地执行。 想让AI+RPA真正产生价值,关键是让两者待在各自最擅长的位置,而不是强行让AI去做它不擅长的事。
云原生架构解决了内部系统的编排问题,但企业数字化转型的最后一公里,往往卡在外部系统、老系统、无API系统的连接上。跨系统非侵入式业务编排不是技术炫技,而是实实在在的生产力解放。
AI+RPA的融合,本质上是在云原生的大框架下,补上了"人机界面自动化"这一层。AI让流程的开发门槛更低,RPA让流程的执行更加稳定。当两者以"认知-执行"分离的架构协同工作时,企业才能真正把自动化从demo推进到规模化落地。
对于正在选型或规划的技术同行,笔者的建议是:不要迷信单一技术,也不要追求"All in AI"。 找到业务场景里"需要思考"和"需要执行"的边界,分别用最合适的工具解决,才是架构师该做的事。