去年双十一凌晨三点,我被钉钉警报炸醒——店铺咨询队列积压了 8000+ 条消息,客服团队 20 人全员在线还是应付不来。那一刻我意识到,必须让 AI 真正"看懂"屏幕、主动操作,而不是只会回复文字。
这篇文章记录我从 0 到 1 搭建这套多模态 Agent 系统的完整过程,包括踩过的坑、压测数据和最终的生产级方案。
一、为什么传统 RPA 不够用
传统 RPA(机器人流程自动化)依赖预先录制的脚本和规则匹配,遇到页面改版就要重新配置。我需要的是:AI 能实时"看到"屏幕内容,自主决策下一步操作。
核心思路是通过 Vision + Function Calling 实现视觉闭环:截图 → 发送给多模态模型分析 → 返回操作指令 → 执行 → 循环。
二、系统架构设计
整个系统分为三层:
- 感知层:定时截图 + OCR 预处理,降低 token 消耗
- 决策层:多模态模型分析 + ReAct 推理框架
- 执行层:pyautogui / playwright 驱动真实浏览器
三、实战代码:基础版截图循环
import base64
import time
import pyautogui
from pathlib import Path
from openai import OpenAI
初始化 HolySheep 客户端
client = OpenAI(
api_key="YOUR_HOLYSHEEP_API_KEY",
base_url="https://api.holysheep.ai/v1"
)
def capture_screen(region=None):
"""截取屏幕指定区域"""
screenshot = pyautogui.screenshot(region=region)
temp_path = Path("temp_screen.png")
screenshot.save(temp_path)
# base64 编码用于 API 传输
with open(temp_path, "rb") as f:
return base64.b64encode(f.read()).decode()
def analyze_screen(base64_image):
"""调用多模态模型分析屏幕"""
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": f"data:image/png;base64,{base64_image}"
}
},
{
"type": "text",
"text": "分析当前屏幕,识别所有可交互元素(按钮、表单、链接),"
"返回下一步应该执行的操作。用 JSON 格式:{\"action\": \"click|input|scroll\", \"target\": \"元素描述\", \"value\": \"如果需要输入的值\"}"
}
]
}
],
max_tokens=500
)
return response.choices[0].message.content
主循环:每 3 秒分析一次屏幕
while True:
screen = capture_screen()
action = analyze_screen(screen)
print(f"决策:{action}")
time.sleep(3)
四、进阶版:集成 Function Calling 实现闭环
上面的方案需要解析文本来推断操作,容易出错。更好的方式是利用模型的 Function Calling 能力,定义好所有可能的操作函数,让模型直接返回结构化的调用指令。
import json
import pyautogui
from openai import OpenAI
client = OpenAI(
api_key="YOUR_HOLYSHEEP_API_KEY",
base_url="https://api.holysheep.ai/v1"
)
定义 Agent 可调用的工具
tools = [
{
"type": "function",
"function": {
"name": "click_element",
"description": "点击屏幕上指定位置的元素",
"parameters": {
"type": "object",
"properties": {
"x": {"type": "integer", "description": "X 坐标"},
"y": {"type": "integer", "description": "Y 坐标"}
},
"required": ["x", "y"]
}
}
},
{
"type": "function",
"function": {
"name": "type_text",
"description": "在当前焦点位置输入文本",
"parameters": {
"type": "object",
"properties": {
"text": {"type": "string", "description": "要输入的文本内容"}
},
"required": ["text"]
}
}
},
{
"type": "function",
"function": {
"name": "scroll",
"description": "滚动页面",
"parameters": {
"type": "object",
"properties": {
"direction": {"type": "string", "enum": ["up", "down"], "description": "滚动方向"}
},
"required": ["direction"]
}
}
}
]
def execute_tool_call(tool_name, arguments):
"""执行 Agent 返回的函数调用"""
if tool_name == "click_element":
pyautogui.click(arguments["x"], arguments["y"])
return f"已点击坐标 ({arguments['x']}, {arguments['y']})"
elif tool_name == "type_text":
pyautogui.write(arguments["text"])
return f"已输入:{arguments['text']}"
elif tool_name == "scroll":
pyautogui.scroll(-300 if arguments["direction"] == "down" else 300)
return f"已向上滚动"
带视觉理解的对话循环
conversation_history = []
system_prompt = """你是一个智能桌面助手,能通过视觉分析屏幕内容并执行操作。
每次分析后,请调用合适的工具完成用户请求。
如果没有需要执行的操作,返回 finish 标记。"""
conversation_history.append({"role": "system", "content": system_prompt})
while True:
# 截图并转 base64
import base64
from PIL import Image
import io
img = pyautogui.screenshot()
img_byte_arr = io.BytesIO()
img.save(img_byte_arr, format='PNG')
img_base64 = base64.b64encode(img_byte_arr.getvalue()).decode()
# 添加用户消息(带截图)
user_message = {
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img_base64}"}},
{"type": "text", "text": "分析当前屏幕,告诉我看到什么,是否需要采取行动?"}
]
}
conversation_history.append(user_message)
# 调用模型
response = client.chat.completions.create(
model="gpt-4.1",
messages=conversation_history,
tools=tools,
tool_choice="auto"
)
assistant_msg = response.choices[0].message
conversation_history.append(assistant_msg.model_dump())
# 执行函数调用
if assistant_msg.tool_calls:
for tool_call in assistant_msg.tool_calls:
result = execute_tool_call(
tool_call.function.name,
json.loads(tool_call.function.arguments)
)
print(f"[执行结果] {result}")
conversation_history.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
else:
print(f"[助手回复] {assistant_msg.content}")
import time
time.sleep(2)
五、生产级优化:降本增效实战
上线第一周,我的 Token 消耗账单让我睡不着觉。当时用的是 GPT-4 Vision,每 1000 次截图分析要 $3.2。后来切换到 HolySheep API 的 DeepSeek V3.2,价格直接降了 85%。
关键优化策略:
- 区域裁剪:只截取屏幕变化区域,不是全屏
- 帧间压缩:连续画面变化小于 5% 时跳过分析
- 异步队列:批量请求降低 API 调用频次
# 优化版:区域截图 + 变化检测
import cv2
import numpy as np
class SmartScreenCapture:
def __init__(self, watch_region=(0, 0, 800, 600)):
self.region = watch_region
self.last_hash = None
def should_analyze(self):
"""计算当前帧的感知哈希,变化超过阈值才返回 True"""
screen = pyautogui.screenshot(region=self.region)
img_array = np.array(screen)
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
# 简化的感知哈希
resized = cv2.resize(gray, (8, 8))
avg = resized.mean()
hash_val = sum(1 if pixel > avg else 0 for row in resized for pixel in row)
if self.last_hash is None:
self.last_hash = hash_val
return True
# 汉明距离判断变化
diff = bin(self.last_hash ^ hash_val).count('1')
self.last_hash = hash_val
# 变化位超过 10% 才分析
return diff > 6
使用优化后的捕获
capture = SmartScreenCapture(watch_region=(0, 0, 1920, 1080))
while True:
if capture.should_analyze():
print("检测到变化,执行分析...")
# ... 分析逻辑
else:
print("画面稳定,跳过分析")
六、电商场景:智能值守实战
我把上述方案部署到店铺客服场景,架构如下:
- 商品详情页自动回复(识别用户问题类型)
- 订单状态查询(看屏幕判断当前页面内容)
- 退换货流程引导(按页面元素逐步操作)
峰值时并发 200 个会话,API 延迟稳定在 120ms 以内(感谢 HolySheep 国内节点)。成本从原来每天 ¥800 降到 ¥120。
常见报错排查
错误 1:图像编码格式错误
# 错误写法
with open("screenshot.png", "rb") as f:
img_data = f.read()
# 直接发送字节流会被拒绝
正确写法:必须加 data URI 前缀
import base64
img_base64 = base64.b64encode(img_data).decode()
image_url = f"data:image/png;base64,{img_base64}"
症状:API 返回 400 Bad Request,提示 "Invalid image format"
错误 2:坐标点击偏移
# 常见问题:屏幕缩放比例导致坐标不准
import ctypes
获取实际 DPI 缩放
user32 = ctypes.windll.user32
user32.SetProcessDPIAware() # Windows 下必须调用
或者使用 pyautogui 的原生坐标
确保截图区域和点击坐标使用同一坐标系
x, y = pyautogui.position() # 先确认鼠标当前位置
print(f"当前坐标:{x}, {y}")
症状:AI 决策点击位置正确,但实际点击偏了几十个像素
错误 3:API 超时或限流
from tenacity import retry, stop_after_attempt, wait_exponential
from openai import RateLimitError, APIError
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10)
)
def robust_analyze(image_data):
try:
response = client.chat.completions.create(
model="deepseek-v3.2", # 换成更便宜的模型
messages=[...],
timeout=30
)
return response
except RateLimitError:
# 限流时自动降级到轻量模型
return fallback_analyze(image_data)
except APIError as e:
if "context_length" in str(e):
# 图像太大,压缩后再发
compressed = compress_image(image_data, quality=60)
return analyze(compressed)
raise
症状:促销高峰期大量请求超时,响应时间从 120ms 飙升到 8 秒
错误 4:循环终止条件缺失
# 危险代码:可能导致死循环
while True:
action = analyze(screen)
if "完成" in action:
# 这里容易漏掉,导致 Agent 一直重复操作
pass
改进:显式计数器和退出条件
max_iterations = 20
iteration = 0
while iteration < max_iterations:
iteration += 1
action = analyze(screen)
if action.get("status") == "done":
print(f"任务完成,耗时 {iteration} 次迭代")
break
if iteration == max_iterations:
print("达到最大迭代次数,强制退出")
break
症状:AI 在某个页面来回点击,形成死循环消耗大量 Token
总结与展望
这套方案让我在去年双十一扛住了 230% 的流量峰值,客服响应时间从平均 45 秒降到 3 秒。最重要的是,AI 真正能"看到"用户看到的界面,回复不再是套话,而是基于真实页面状态的精准解答。
如果你也在寻找稳定、低价的多模态 API 支持,HolySheep 确实是个不错的选择。¥1=$1 的汇率对国内开发者太友好了,而且支持微信/支付宝充值,不用折腾信用卡。
下一步我打算接入 Gemini 2.5 Flash,它的视觉理解能力更强,价格只有 $2.50/MTok,配合 HolySheep 的汇率优势,性价比直接拉满。
👉 免费注册 HolySheep AI,获取首月赠额度